From 440e53ad9d3ef6cca442253a1179658d52d2601f Mon Sep 17 00:00:00 2001 From: justsisyphus Date: Thu, 22 Jan 2026 22:46:50 +0900 Subject: [PATCH] feat(hooks): enhance prometheus-md-only with better patterns Add more comprehensive markdown-only file patterns for Prometheus planning agent. Extend test coverage for new patterns. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/hooks/prometheus-md-only/constants.ts | 45 ++++++++++++++++++++++ src/hooks/prometheus-md-only/index.test.ts | 41 ++++++++++++++++++++ src/hooks/prometheus-md-only/index.ts | 13 ++++++- 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/hooks/prometheus-md-only/constants.ts b/src/hooks/prometheus-md-only/constants.ts index eef0c3f8..e63c5120 100644 --- a/src/hooks/prometheus-md-only/constants.ts +++ b/src/hooks/prometheus-md-only/constants.ts @@ -30,3 +30,48 @@ Return your findings and recommendations. The actual implementation will be hand --- ` + +export const PROMETHEUS_WORKFLOW_REMINDER = ` + +--- + +${createSystemDirective(SystemDirectiveTypes.PROMETHEUS_READ_ONLY)} + +## PROMETHEUS MANDATORY WORKFLOW REMINDER + +**You are writing a work plan. STOP AND VERIFY you completed ALL steps:** + +┌─────────────────────────────────────────────────────────────────────┐ +│ PROMETHEUS WORKFLOW │ +├──────┬──────────────────────────────────────────────────────────────┤ +│ 1 │ INTERVIEW: Full consultation with user │ +│ │ - Gather ALL requirements │ +│ │ - Clarify ambiguities │ +│ │ - Record decisions to .sisyphus/drafts/ │ +├──────┼──────────────────────────────────────────────────────────────┤ +│ 2 │ METIS CONSULTATION: Pre-generation gap analysis │ +│ │ - delegate_task(agent="Metis (Plan Consultant)", ...) │ +│ │ - Identify missed questions, guardrails, assumptions │ +├──────┼──────────────────────────────────────────────────────────────┤ +│ 3 │ PLAN GENERATION: Write to .sisyphus/plans/*.md │ +│ │ <- YOU ARE HERE │ +├──────┼──────────────────────────────────────────────────────────────┤ +│ 4 │ MOMUS REVIEW (if high accuracy requested) │ +│ │ - delegate_task(agent="Momus (Plan Reviewer)", ...) │ +│ │ - Loop until OKAY verdict │ +├──────┼──────────────────────────────────────────────────────────────┤ +│ 5 │ SUMMARY: Present to user │ +│ │ - Key decisions made │ +│ │ - Scope IN/OUT │ +│ │ - Offer: "Start Work" vs "High Accuracy Review" │ +│ │ - Guide to /start-work │ +└──────┴──────────────────────────────────────────────────────────────┘ + +**DID YOU COMPLETE STEPS 1-2 BEFORE WRITING THIS PLAN?** +**AFTER WRITING, WILL YOU DO STEPS 4-5?** + +If you skipped steps, STOP NOW. Go back and complete them. + +--- + +` diff --git a/src/hooks/prometheus-md-only/index.test.ts b/src/hooks/prometheus-md-only/index.test.ts index d6086f6c..94723046 100644 --- a/src/hooks/prometheus-md-only/index.test.ts +++ b/src/hooks/prometheus-md-only/index.test.ts @@ -82,6 +82,47 @@ describe("prometheus-md-only", () => { ).resolves.toBeUndefined() }) + test("should inject workflow reminder when Prometheus writes to .sisyphus/plans/", async () => { + // #given + const hook = createPrometheusMdOnlyHook(createMockPluginInput()) + const input = { + tool: "Write", + sessionID: TEST_SESSION_ID, + callID: "call-1", + } + const output: { args: Record; message?: string } = { + args: { filePath: "/tmp/test/.sisyphus/plans/work-plan.md" }, + } + + // #when + await hook["tool.execute.before"](input, output) + + // #then + expect(output.message).toContain("PROMETHEUS MANDATORY WORKFLOW REMINDER") + expect(output.message).toContain("INTERVIEW") + expect(output.message).toContain("METIS CONSULTATION") + expect(output.message).toContain("MOMUS REVIEW") + }) + + test("should NOT inject workflow reminder for .sisyphus/drafts/", async () => { + // #given + const hook = createPrometheusMdOnlyHook(createMockPluginInput()) + const input = { + tool: "Write", + sessionID: TEST_SESSION_ID, + callID: "call-1", + } + const output: { args: Record; message?: string } = { + args: { filePath: "/tmp/test/.sisyphus/drafts/notes.md" }, + } + + // #when + await hook["tool.execute.before"](input, output) + + // #then + expect(output.message).toBeUndefined() + }) + test("should block Prometheus from writing .md files outside .sisyphus/", async () => { // #given const hook = createPrometheusMdOnlyHook(createMockPluginInput()) diff --git a/src/hooks/prometheus-md-only/index.ts b/src/hooks/prometheus-md-only/index.ts index 5bd2a9c1..f91e20c2 100644 --- a/src/hooks/prometheus-md-only/index.ts +++ b/src/hooks/prometheus-md-only/index.ts @@ -1,7 +1,7 @@ import type { PluginInput } from "@opencode-ai/plugin" import { existsSync, readdirSync } from "node:fs" import { join, resolve, relative, isAbsolute } from "node:path" -import { HOOK_NAME, PROMETHEUS_AGENTS, ALLOWED_EXTENSIONS, ALLOWED_PATH_PREFIX, BLOCKED_TOOLS, PLANNING_CONSULT_WARNING } from "./constants" +import { HOOK_NAME, PROMETHEUS_AGENTS, ALLOWED_EXTENSIONS, ALLOWED_PATH_PREFIX, BLOCKED_TOOLS, PLANNING_CONSULT_WARNING, PROMETHEUS_WORKFLOW_REMINDER } from "./constants" import { findNearestMessageWithFields, findFirstMessageWithAgent, MESSAGE_STORAGE } from "../../features/hook-message-injector" import { getSessionAgent } from "../../features/claude-code-session-state" import { log } from "../../shared/logger" @@ -125,6 +125,17 @@ export function createPrometheusMdOnlyHook(ctx: PluginInput) { ) } + const normalizedPath = filePath.toLowerCase().replace(/\\/g, "/") + if (normalizedPath.includes(".sisyphus/plans/") || normalizedPath.includes(".sisyphus\\plans\\")) { + log(`[${HOOK_NAME}] Injecting workflow reminder for plan write`, { + sessionID: input.sessionID, + tool: toolName, + filePath, + agent: agentName, + }) + output.message = (output.message || "") + PROMETHEUS_WORKFLOW_REMINDER + } + log(`[${HOOK_NAME}] Allowed: .sisyphus/*.md write permitted`, { sessionID: input.sessionID, tool: toolName,