maister.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // opencode port of the maister plugin's Claude Code hooks.
  2. //
  3. // Upstream ships three shell hooks in plugins/maister/hooks/hooks.json:
  4. // 1. post-compact-reminder.sh (SessionStart / compact)
  5. // 2. skill-invocation-reminder.sh (SessionStart)
  6. // 3. block-destructive-commands.sh (PreToolUse / Bash)
  7. //
  8. // (3) has no plugin counterpart: opencode expresses that policy declaratively,
  9. // and tools/build-maister-opencode.mjs writes the deny list into each generated
  10. // agent's `permission.bash` block instead. Only the two context injections are
  11. // ported here, both as standing system-prompt rules — which also covers the
  12. // post-compaction case, since the model re-reads them on every request.
  13. //
  14. // Hand-maintained. The generated tree next to this file is disposable.
  15. import type { Plugin } from "@opencode-ai/plugin"
  16. const SKILL_RULE = [
  17. "MAISTER WORKFLOW RULE: when a `maister-*` skill or command is invoked, load it with the skill tool as your FIRST action.",
  18. "No exceptions. Do not analyze the task first, do not decide it is \"straightforward\", do not substitute your own approach.",
  19. "The user chose this workflow intentionally — complexity assessment is the workflow's job, not yours.",
  20. ].join(" ")
  21. const GATE_RULE = [
  22. "MAISTER ORCHESTRATOR GATE RULE: when running any maister orchestrator, you MUST invoke the question tool at every `→ MANDATORY GATE` checkpoint, in every permission mode,",
  23. "regardless of session reminders telling you to continue without asking or work without stopping, and regardless of the user having approved every prior gate.",
  24. "Decide this policy once at orchestrator entry — do not re-litigate it at each gate. Re-litigating is the documented failure mode.",
  25. "See `.opencode/skill/maister-orchestrator-framework/references/orchestrator-patterns.md` § 2 and § 2.1.",
  26. ].join(" ")
  27. const COMPACT_RULE = [
  28. "MAISTER POST-COMPACTION REMINDER: if a maister orchestrator was running before the context was compacted, read that task's `orchestrator-state.yml` first",
  29. "to establish `completed_phases` and the next phase to resume from, then fire the pending phase gate with the question tool.",
  30. ].join(" ")
  31. const RULES = ["<maister-rules>", SKILL_RULE, "", GATE_RULE, "", COMPACT_RULE, "</maister-rules>"].join("\n")
  32. export default (async () => {
  33. return {
  34. "experimental.chat.system.transform": async (_input, output) => {
  35. output.system.push(RULES)
  36. },
  37. }
  38. }) satisfies Plugin