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