oh-my-claude-sisyphus 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -708
- package/agents/analyst.md +85 -0
- package/agents/architect-low.md +88 -0
- package/agents/architect-medium.md +108 -0
- package/agents/architect.md +77 -0
- package/agents/critic.md +97 -0
- package/agents/designer-high.md +113 -0
- package/agents/designer-low.md +89 -0
- package/agents/designer.md +80 -0
- package/agents/executor-high.md +116 -0
- package/agents/executor-low.md +94 -0
- package/agents/executor.md +62 -0
- package/agents/explore-medium.md +113 -0
- package/agents/explore.md +86 -0
- package/agents/planner.md +164 -0
- package/agents/qa-tester.md +109 -0
- package/agents/researcher-low.md +84 -0
- package/agents/researcher.md +70 -0
- package/agents/vision.md +39 -0
- package/agents/writer.md +152 -0
- package/commands/.gitkeep +0 -0
- package/dist/__tests__/hooks.test.js +22 -22
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/__tests__/hud-agents.test.d.ts +7 -0
- package/dist/__tests__/hud-agents.test.d.ts.map +1 -0
- package/dist/__tests__/hud-agents.test.js +363 -0
- package/dist/__tests__/hud-agents.test.js.map +1 -0
- package/dist/__tests__/installer.test.js +184 -116
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/__tests__/learned-skills/config.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/config.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/config.test.js +37 -0
- package/dist/__tests__/learned-skills/config.test.js.map +1 -0
- package/dist/__tests__/learned-skills/detector.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/detector.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/detector.test.js +99 -0
- package/dist/__tests__/learned-skills/detector.test.js.map +1 -0
- package/dist/__tests__/learned-skills/finder.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/finder.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/finder.test.js +59 -0
- package/dist/__tests__/learned-skills/finder.test.js.map +1 -0
- package/dist/__tests__/learned-skills/loader.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/loader.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/loader.test.js +69 -0
- package/dist/__tests__/learned-skills/loader.test.js.map +1 -0
- package/dist/__tests__/learned-skills/parser.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/parser.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/parser.test.js +81 -0
- package/dist/__tests__/learned-skills/parser.test.js.map +1 -0
- package/dist/__tests__/learned-skills/validator.test.d.ts +2 -0
- package/dist/__tests__/learned-skills/validator.test.d.ts.map +1 -0
- package/dist/__tests__/learned-skills/validator.test.js +85 -0
- package/dist/__tests__/learned-skills/validator.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/config.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/config.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/config.test.js +37 -0
- package/dist/__tests__/mnemosyne/config.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/detector.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/detector.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/detector.test.js +99 -0
- package/dist/__tests__/mnemosyne/detector.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/finder.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/finder.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/finder.test.js +61 -0
- package/dist/__tests__/mnemosyne/finder.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/loader.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/loader.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/loader.test.js +73 -0
- package/dist/__tests__/mnemosyne/loader.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/parser.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/parser.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/parser.test.js +81 -0
- package/dist/__tests__/mnemosyne/parser.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/validator.test.d.ts +2 -0
- package/dist/__tests__/mnemosyne/validator.test.d.ts.map +1 -0
- package/dist/__tests__/mnemosyne/validator.test.js +85 -0
- package/dist/__tests__/mnemosyne/validator.test.js.map +1 -0
- package/dist/__tests__/model-routing.test.js +34 -34
- package/dist/__tests__/model-routing.test.js.map +1 -1
- package/dist/__tests__/notepad.test.js +7 -7
- package/dist/__tests__/notepad.test.js.map +1 -1
- package/dist/__tests__/ralph-prd.test.js +12 -12
- package/dist/__tests__/ralph-prd.test.js.map +1 -1
- package/dist/__tests__/ralph-progress.test.js +12 -12
- package/dist/__tests__/ralph-progress.test.js.map +1 -1
- package/dist/__tests__/skills.test.js +50 -17
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/__tests__/types.test.js +5 -5
- package/dist/__tests__/types.test.js.map +1 -1
- package/dist/agents/analyst.d.ts +11 -0
- package/dist/agents/analyst.d.ts.map +1 -0
- package/dist/agents/analyst.js +115 -0
- package/dist/agents/analyst.js.map +1 -0
- package/dist/agents/architect.d.ts +12 -0
- package/dist/agents/architect.d.ts.map +1 -0
- package/dist/agents/architect.js +189 -0
- package/dist/agents/architect.js.map +1 -0
- package/dist/agents/coordinator.d.ts +11 -0
- package/dist/agents/coordinator.d.ts.map +1 -0
- package/dist/agents/coordinator.js +115 -0
- package/dist/agents/coordinator.js.map +1 -0
- package/dist/agents/critic.d.ts +11 -0
- package/dist/agents/critic.d.ts.map +1 -0
- package/dist/agents/critic.js +127 -0
- package/dist/agents/critic.js.map +1 -0
- package/dist/agents/definitions.d.ts +33 -70
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +140 -1268
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/designer.d.ts +11 -0
- package/dist/agents/designer.d.ts.map +1 -0
- package/dist/agents/designer.js +115 -0
- package/dist/agents/designer.js.map +1 -0
- package/dist/agents/executor.d.ts +12 -0
- package/dist/agents/executor.d.ts.map +1 -0
- package/dist/agents/executor.js +93 -0
- package/dist/agents/executor.js.map +1 -0
- package/dist/agents/explore.js +4 -4
- package/dist/agents/explore.js.map +1 -1
- package/dist/agents/index.d.ts +12 -11
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +15 -16
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/planner.d.ts +11 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +194 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/qa-tester.js +16 -16
- package/dist/agents/qa-tester.js.map +1 -1
- package/dist/agents/researcher.d.ts +12 -0
- package/dist/agents/researcher.d.ts.map +1 -0
- package/dist/agents/researcher.js +103 -0
- package/dist/agents/researcher.js.map +1 -0
- package/dist/agents/vision.d.ts +11 -0
- package/dist/agents/vision.d.ts.map +1 -0
- package/dist/agents/vision.js +70 -0
- package/dist/agents/vision.js.map +1 -0
- package/dist/agents/writer.d.ts +11 -0
- package/dist/agents/writer.d.ts.map +1 -0
- package/dist/agents/writer.js +209 -0
- package/dist/agents/writer.js.map +1 -0
- package/dist/cli/index.js +32 -32
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/index.d.ts +4 -4
- package/dist/commands/index.js +4 -4
- package/dist/config/loader.js +25 -25
- package/dist/config/loader.js.map +1 -1
- package/dist/features/auto-update.d.ts +5 -5
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +17 -17
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/background-agent/manager.js +1 -1
- package/dist/features/background-agent/manager.js.map +1 -1
- package/dist/features/boulder-state/constants.d.ts +5 -5
- package/dist/features/boulder-state/constants.d.ts.map +1 -1
- package/dist/features/boulder-state/constants.js +3 -3
- package/dist/features/boulder-state/constants.js.map +1 -1
- package/dist/features/boulder-state/index.d.ts +2 -2
- package/dist/features/boulder-state/index.d.ts.map +1 -1
- package/dist/features/boulder-state/index.js +2 -2
- package/dist/features/boulder-state/index.js.map +1 -1
- package/dist/features/boulder-state/storage.d.ts +3 -3
- package/dist/features/boulder-state/storage.d.ts.map +1 -1
- package/dist/features/boulder-state/storage.js +6 -6
- package/dist/features/boulder-state/storage.js.map +1 -1
- package/dist/features/builtin-skills/skills.d.ts +15 -1
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +100 -1110
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/context-injector/types.d.ts +1 -1
- package/dist/features/context-injector/types.d.ts.map +1 -1
- package/dist/features/index.d.ts +1 -1
- package/dist/features/index.d.ts.map +1 -1
- package/dist/features/index.js +2 -2
- package/dist/features/index.js.map +1 -1
- package/dist/features/magic-keywords.js +14 -14
- package/dist/features/magic-keywords.js.map +1 -1
- package/dist/features/model-routing/prompts/opus.d.ts +1 -1
- package/dist/features/model-routing/prompts/opus.d.ts.map +1 -1
- package/dist/features/model-routing/prompts/opus.js +1 -1
- package/dist/features/model-routing/router.d.ts +1 -1
- package/dist/features/model-routing/router.js +14 -14
- package/dist/features/model-routing/router.js.map +1 -1
- package/dist/features/model-routing/rules.js +31 -31
- package/dist/features/model-routing/rules.js.map +1 -1
- package/dist/features/model-routing/types.js +1 -1
- package/dist/features/model-routing/types.js.map +1 -1
- package/dist/hooks/agent-usage-reminder/constants.d.ts +2 -2
- package/dist/hooks/agent-usage-reminder/constants.d.ts.map +1 -1
- package/dist/hooks/agent-usage-reminder/constants.js +5 -5
- package/dist/hooks/agent-usage-reminder/constants.js.map +1 -1
- package/dist/hooks/auto-slash-command/constants.d.ts +1 -1
- package/dist/hooks/auto-slash-command/constants.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/constants.js +9 -2
- package/dist/hooks/auto-slash-command/constants.js.map +1 -1
- package/dist/hooks/bridge.d.ts +2 -2
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +50 -18
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/directory-readme-injector/constants.d.ts +1 -1
- package/dist/hooks/directory-readme-injector/constants.d.ts.map +1 -1
- package/dist/hooks/directory-readme-injector/constants.js +2 -2
- package/dist/hooks/directory-readme-injector/constants.js.map +1 -1
- package/dist/hooks/index.d.ts +3 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -4
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/learned-skills/config.d.ts +53 -0
- package/dist/hooks/learned-skills/config.d.ts.map +1 -0
- package/dist/hooks/learned-skills/config.js +103 -0
- package/dist/hooks/learned-skills/config.js.map +1 -0
- package/dist/hooks/learned-skills/constants.d.ts +24 -0
- package/dist/hooks/learned-skills/constants.d.ts.map +1 -0
- package/dist/hooks/learned-skills/constants.js +26 -0
- package/dist/hooks/learned-skills/constants.js.map +1 -0
- package/dist/hooks/learned-skills/detection-hook.d.ts +39 -0
- package/dist/hooks/learned-skills/detection-hook.d.ts.map +1 -0
- package/dist/hooks/learned-skills/detection-hook.js +83 -0
- package/dist/hooks/learned-skills/detection-hook.js.map +1 -0
- package/dist/hooks/learned-skills/detector.d.ts +30 -0
- package/dist/hooks/learned-skills/detector.d.ts.map +1 -0
- package/dist/hooks/learned-skills/detector.js +150 -0
- package/dist/hooks/learned-skills/detector.js.map +1 -0
- package/dist/hooks/learned-skills/finder.d.ts +21 -0
- package/dist/hooks/learned-skills/finder.d.ts.map +1 -0
- package/dist/hooks/learned-skills/finder.js +117 -0
- package/dist/hooks/learned-skills/finder.js.map +1 -0
- package/dist/hooks/learned-skills/index.d.ts +62 -0
- package/dist/hooks/learned-skills/index.d.ts.map +1 -0
- package/dist/hooks/learned-skills/index.js +137 -0
- package/dist/hooks/learned-skills/index.js.map +1 -0
- package/dist/hooks/learned-skills/loader.d.ts +20 -0
- package/dist/hooks/learned-skills/loader.d.ts.map +1 -0
- package/dist/hooks/learned-skills/loader.js +107 -0
- package/dist/hooks/learned-skills/loader.js.map +1 -0
- package/dist/hooks/learned-skills/parser.d.ts +21 -0
- package/dist/hooks/learned-skills/parser.d.ts.map +1 -0
- package/dist/hooks/learned-skills/parser.js +190 -0
- package/dist/hooks/learned-skills/parser.js.map +1 -0
- package/dist/hooks/learned-skills/promotion.d.ts +29 -0
- package/dist/hooks/learned-skills/promotion.d.ts.map +1 -0
- package/dist/hooks/learned-skills/promotion.js +87 -0
- package/dist/hooks/learned-skills/promotion.js.map +1 -0
- package/dist/hooks/learned-skills/types.d.ts +109 -0
- package/dist/hooks/learned-skills/types.d.ts.map +1 -0
- package/dist/hooks/learned-skills/types.js +8 -0
- package/dist/hooks/learned-skills/types.js.map +1 -0
- package/dist/hooks/learned-skills/validator.d.ts +15 -0
- package/dist/hooks/learned-skills/validator.d.ts.map +1 -0
- package/dist/hooks/learned-skills/validator.js +87 -0
- package/dist/hooks/learned-skills/validator.js.map +1 -0
- package/dist/hooks/learned-skills/writer.d.ts +27 -0
- package/dist/hooks/learned-skills/writer.d.ts.map +1 -0
- package/dist/hooks/learned-skills/writer.js +126 -0
- package/dist/hooks/learned-skills/writer.js.map +1 -0
- package/dist/hooks/learner/config.d.ts +53 -0
- package/dist/hooks/learner/config.d.ts.map +1 -0
- package/dist/hooks/learner/config.js +103 -0
- package/dist/hooks/learner/config.js.map +1 -0
- package/dist/hooks/learner/constants.d.ts +24 -0
- package/dist/hooks/learner/constants.d.ts.map +1 -0
- package/dist/hooks/learner/constants.js +26 -0
- package/dist/hooks/learner/constants.js.map +1 -0
- package/dist/hooks/learner/detection-hook.d.ts +39 -0
- package/dist/hooks/learner/detection-hook.d.ts.map +1 -0
- package/dist/hooks/learner/detection-hook.js +83 -0
- package/dist/hooks/learner/detection-hook.js.map +1 -0
- package/dist/hooks/learner/detector.d.ts +30 -0
- package/dist/hooks/learner/detector.d.ts.map +1 -0
- package/dist/hooks/learner/detector.js +150 -0
- package/dist/hooks/learner/detector.js.map +1 -0
- package/dist/hooks/learner/finder.d.ts +21 -0
- package/dist/hooks/learner/finder.d.ts.map +1 -0
- package/dist/hooks/learner/finder.js +117 -0
- package/dist/hooks/learner/finder.js.map +1 -0
- package/dist/hooks/learner/index.d.ts +62 -0
- package/dist/hooks/learner/index.d.ts.map +1 -0
- package/dist/hooks/learner/index.js +137 -0
- package/dist/hooks/learner/index.js.map +1 -0
- package/dist/hooks/learner/loader.d.ts +20 -0
- package/dist/hooks/learner/loader.d.ts.map +1 -0
- package/dist/hooks/learner/loader.js +113 -0
- package/dist/hooks/learner/loader.js.map +1 -0
- package/dist/hooks/learner/parser.d.ts +21 -0
- package/dist/hooks/learner/parser.d.ts.map +1 -0
- package/dist/hooks/learner/parser.js +190 -0
- package/dist/hooks/learner/parser.js.map +1 -0
- package/dist/hooks/learner/promotion.d.ts +29 -0
- package/dist/hooks/learner/promotion.d.ts.map +1 -0
- package/dist/hooks/learner/promotion.js +87 -0
- package/dist/hooks/learner/promotion.js.map +1 -0
- package/dist/hooks/learner/types.d.ts +109 -0
- package/dist/hooks/learner/types.d.ts.map +1 -0
- package/dist/hooks/learner/types.js +8 -0
- package/dist/hooks/learner/types.js.map +1 -0
- package/dist/hooks/learner/validator.d.ts +15 -0
- package/dist/hooks/learner/validator.d.ts.map +1 -0
- package/dist/hooks/learner/validator.js +87 -0
- package/dist/hooks/learner/validator.js.map +1 -0
- package/dist/hooks/learner/writer.d.ts +27 -0
- package/dist/hooks/learner/writer.d.ts.map +1 -0
- package/dist/hooks/learner/writer.js +126 -0
- package/dist/hooks/learner/writer.js.map +1 -0
- package/dist/hooks/mnemosyne/config.d.ts +53 -0
- package/dist/hooks/mnemosyne/config.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/config.js +103 -0
- package/dist/hooks/mnemosyne/config.js.map +1 -0
- package/dist/hooks/mnemosyne/constants.d.ts +24 -0
- package/dist/hooks/mnemosyne/constants.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/constants.js +26 -0
- package/dist/hooks/mnemosyne/constants.js.map +1 -0
- package/dist/hooks/mnemosyne/detection-hook.d.ts +39 -0
- package/dist/hooks/mnemosyne/detection-hook.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/detection-hook.js +83 -0
- package/dist/hooks/mnemosyne/detection-hook.js.map +1 -0
- package/dist/hooks/mnemosyne/detector.d.ts +30 -0
- package/dist/hooks/mnemosyne/detector.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/detector.js +150 -0
- package/dist/hooks/mnemosyne/detector.js.map +1 -0
- package/dist/hooks/mnemosyne/finder.d.ts +21 -0
- package/dist/hooks/mnemosyne/finder.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/finder.js +117 -0
- package/dist/hooks/mnemosyne/finder.js.map +1 -0
- package/dist/hooks/mnemosyne/index.d.ts +62 -0
- package/dist/hooks/mnemosyne/index.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/index.js +137 -0
- package/dist/hooks/mnemosyne/index.js.map +1 -0
- package/dist/hooks/mnemosyne/loader.d.ts +20 -0
- package/dist/hooks/mnemosyne/loader.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/loader.js +113 -0
- package/dist/hooks/mnemosyne/loader.js.map +1 -0
- package/dist/hooks/mnemosyne/parser.d.ts +21 -0
- package/dist/hooks/mnemosyne/parser.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/parser.js +190 -0
- package/dist/hooks/mnemosyne/parser.js.map +1 -0
- package/dist/hooks/mnemosyne/promotion.d.ts +29 -0
- package/dist/hooks/mnemosyne/promotion.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/promotion.js +87 -0
- package/dist/hooks/mnemosyne/promotion.js.map +1 -0
- package/dist/hooks/mnemosyne/types.d.ts +109 -0
- package/dist/hooks/mnemosyne/types.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/types.js +8 -0
- package/dist/hooks/mnemosyne/types.js.map +1 -0
- package/dist/hooks/mnemosyne/validator.d.ts +15 -0
- package/dist/hooks/mnemosyne/validator.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/validator.js +87 -0
- package/dist/hooks/mnemosyne/validator.js.map +1 -0
- package/dist/hooks/mnemosyne/writer.d.ts +27 -0
- package/dist/hooks/mnemosyne/writer.d.ts.map +1 -0
- package/dist/hooks/mnemosyne/writer.js +126 -0
- package/dist/hooks/mnemosyne/writer.js.map +1 -0
- package/dist/hooks/notepad/index.d.ts +2 -2
- package/dist/hooks/notepad/index.js +7 -7
- package/dist/hooks/notepad/index.js.map +1 -1
- package/dist/hooks/omc-orchestrator/constants.d.ts +23 -0
- package/dist/hooks/omc-orchestrator/constants.d.ts.map +1 -0
- package/dist/hooks/omc-orchestrator/constants.js +142 -0
- package/dist/hooks/omc-orchestrator/constants.js.map +1 -0
- package/dist/hooks/omc-orchestrator/index.d.ts +113 -0
- package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -0
- package/dist/hooks/omc-orchestrator/index.js +309 -0
- package/dist/hooks/omc-orchestrator/index.js.map +1 -0
- package/dist/hooks/persistent-mode/index.d.ts +4 -4
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +37 -37
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/ralph-loop/index.d.ts +33 -5
- package/dist/hooks/ralph-loop/index.d.ts.map +1 -1
- package/dist/hooks/ralph-loop/index.js +91 -17
- package/dist/hooks/ralph-loop/index.js.map +1 -1
- package/dist/hooks/ralph-prd/index.d.ts +4 -4
- package/dist/hooks/ralph-prd/index.d.ts.map +1 -1
- package/dist/hooks/ralph-prd/index.js +13 -13
- package/dist/hooks/ralph-prd/index.js.map +1 -1
- package/dist/hooks/ralph-progress/index.d.ts +5 -5
- package/dist/hooks/ralph-progress/index.d.ts.map +1 -1
- package/dist/hooks/ralph-progress/index.js +14 -14
- package/dist/hooks/ralph-progress/index.js.map +1 -1
- package/dist/hooks/ralph-verifier/index.d.ts +23 -23
- package/dist/hooks/ralph-verifier/index.d.ts.map +1 -1
- package/dist/hooks/ralph-verifier/index.js +41 -41
- package/dist/hooks/ralph-verifier/index.js.map +1 -1
- package/dist/hooks/rules-injector/constants.d.ts +1 -1
- package/dist/hooks/rules-injector/constants.d.ts.map +1 -1
- package/dist/hooks/rules-injector/constants.js +2 -2
- package/dist/hooks/rules-injector/constants.js.map +1 -1
- package/dist/hooks/todo-continuation/index.js +1 -1
- package/dist/hooks/todo-continuation/index.js.map +1 -1
- package/dist/hooks/ultraqa-loop/index.d.ts +1 -1
- package/dist/hooks/ultraqa-loop/index.js +8 -8
- package/dist/hooks/ultraqa-loop/index.js.map +1 -1
- package/dist/hooks/ultrawork-state/index.js +7 -7
- package/dist/hooks/ultrawork-state/index.js.map +1 -1
- package/dist/hud/background-tasks.d.ts +26 -0
- package/dist/hud/background-tasks.d.ts.map +1 -0
- package/dist/hud/background-tasks.js +116 -0
- package/dist/hud/background-tasks.js.map +1 -0
- package/dist/hud/colors.d.ts +54 -0
- package/dist/hud/colors.d.ts.map +1 -0
- package/dist/hud/colors.js +156 -0
- package/dist/hud/colors.js.map +1 -0
- package/dist/hud/elements/agents.d.ts +73 -0
- package/dist/hud/elements/agents.d.ts.map +1 -0
- package/dist/hud/elements/agents.js +405 -0
- package/dist/hud/elements/agents.js.map +1 -0
- package/dist/hud/elements/background.d.ts +20 -0
- package/dist/hud/elements/background.d.ts.map +1 -0
- package/dist/hud/elements/background.js +70 -0
- package/dist/hud/elements/background.js.map +1 -0
- package/dist/hud/elements/context.d.ts +19 -0
- package/dist/hud/elements/context.d.ts.map +1 -0
- package/dist/hud/elements/context.js +58 -0
- package/dist/hud/elements/context.js.map +1 -0
- package/dist/hud/elements/index.d.ts +17 -0
- package/dist/hud/elements/index.d.ts.map +1 -0
- package/dist/hud/elements/index.js +17 -0
- package/dist/hud/elements/index.js.map +1 -0
- package/dist/hud/elements/limits.d.ts +19 -0
- package/dist/hud/elements/limits.d.ts.map +1 -0
- package/dist/hud/elements/limits.js +54 -0
- package/dist/hud/elements/limits.js.map +1 -0
- package/dist/hud/elements/permission.d.ts +13 -0
- package/dist/hud/elements/permission.d.ts.map +1 -0
- package/dist/hud/elements/permission.js +20 -0
- package/dist/hud/elements/permission.js.map +1 -0
- package/dist/hud/elements/prd.d.ts +20 -0
- package/dist/hud/elements/prd.d.ts.map +1 -0
- package/dist/hud/elements/prd.js +52 -0
- package/dist/hud/elements/prd.js.map +1 -0
- package/dist/hud/elements/ralph.d.ts +14 -0
- package/dist/hud/elements/ralph.d.ts.map +1 -0
- package/dist/hud/elements/ralph.js +36 -0
- package/dist/hud/elements/ralph.js.map +1 -0
- package/dist/hud/elements/session.d.ts +13 -0
- package/dist/hud/elements/session.d.ts.map +1 -0
- package/dist/hud/elements/session.js +24 -0
- package/dist/hud/elements/session.js.map +1 -0
- package/dist/hud/elements/skills.d.ts +24 -0
- package/dist/hud/elements/skills.d.ts.map +1 -0
- package/dist/hud/elements/skills.js +81 -0
- package/dist/hud/elements/skills.js.map +1 -0
- package/dist/hud/elements/thinking.d.ts +13 -0
- package/dist/hud/elements/thinking.d.ts.map +1 -0
- package/dist/hud/elements/thinking.js +19 -0
- package/dist/hud/elements/thinking.js.map +1 -0
- package/dist/hud/elements/todos.d.ts +20 -0
- package/dist/hud/elements/todos.d.ts.map +1 -0
- package/dist/hud/elements/todos.js +70 -0
- package/dist/hud/elements/todos.js.map +1 -0
- package/dist/hud/index.d.ts +9 -0
- package/dist/hud/index.d.ts.map +1 -0
- package/dist/hud/index.js +89 -0
- package/dist/hud/index.js.map +1 -0
- package/dist/hud/omc-state.d.ts +31 -0
- package/dist/hud/omc-state.d.ts.map +1 -0
- package/dist/hud/omc-state.js +163 -0
- package/dist/hud/omc-state.js.map +1 -0
- package/dist/hud/render.d.ts +11 -0
- package/dist/hud/render.d.ts.map +1 -0
- package/dist/hud/render.js +121 -0
- package/dist/hud/render.js.map +1 -0
- package/dist/hud/sisyphus-state.d.ts +31 -0
- package/dist/hud/sisyphus-state.d.ts.map +1 -0
- package/dist/hud/sisyphus-state.js +163 -0
- package/dist/hud/sisyphus-state.js.map +1 -0
- package/dist/hud/state.d.ts +43 -0
- package/dist/hud/state.d.ts.map +1 -0
- package/dist/hud/state.js +201 -0
- package/dist/hud/state.js.map +1 -0
- package/dist/hud/stdin.d.ts +22 -0
- package/dist/hud/stdin.d.ts.map +1 -0
- package/dist/hud/stdin.js +65 -0
- package/dist/hud/stdin.js.map +1 -0
- package/dist/hud/transcript.d.ts +32 -0
- package/dist/hud/transcript.d.ts.map +1 -0
- package/dist/hud/transcript.js +364 -0
- package/dist/hud/transcript.js.map +1 -0
- package/dist/hud/types.d.ts +178 -0
- package/dist/hud/types.d.ts.map +1 -0
- package/dist/hud/types.js +119 -0
- package/dist/hud/types.js.map +1 -0
- package/dist/hud/usage-api.d.ts +24 -0
- package/dist/hud/usage-api.d.ts.map +1 -0
- package/dist/hud/usage-api.js +234 -0
- package/dist/hud/usage-api.js.map +1 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -12
- package/dist/index.js.map +1 -1
- package/dist/installer/hooks.d.ts +36 -64
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +91 -1298
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +23 -22
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +307 -2575
- package/dist/installer/index.js.map +1 -1
- package/dist/shared/types.d.ts +6 -6
- package/dist/shared/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +386 -0
- package/docs/CLAUDE.md +281 -0
- package/docs/FULL-README.md +822 -0
- package/docs/LOCAL_PLUGIN_INSTALL.md +94 -0
- package/docs/MIGRATION-v3.md +186 -0
- package/docs/MIGRATION.md +460 -0
- package/docs/TIERED_AGENTS_V2.md +322 -0
- package/hooks/hooks.json +70 -0
- package/hooks/keyword-detector.sh +102 -0
- package/hooks/persistent-mode.sh +172 -0
- package/hooks/session-start.sh +62 -0
- package/hooks/stop-continuation.sh +40 -0
- package/package.json +14 -8
- package/scripts/install.sh +90 -72
- package/scripts/keyword-detector.mjs +1 -1
- package/scripts/persistent-mode.mjs +39 -20
- package/scripts/persistent-mode.sh +21 -10
- package/scripts/plugin-setup.mjs +109 -0
- package/scripts/pre-tool-enforcer.mjs +1 -1
- package/scripts/pre-tool-enforcer.sh +1 -1
- package/scripts/session-start.mjs +38 -3
- package/scripts/skill-injector.mjs +231 -0
- package/scripts/uninstall.sh +8 -8
- package/skills/analyze/SKILL.md +47 -0
- package/skills/cancel-ralph/SKILL.md +43 -0
- package/skills/cancel-ultraqa/SKILL.md +29 -0
- package/skills/cancel-ultrawork/SKILL.md +42 -0
- package/skills/deepinit/SKILL.md +321 -0
- package/skills/deepsearch/SKILL.md +39 -0
- package/skills/doctor/SKILL.md +192 -0
- package/skills/frontend-ui-ux/SKILL.md +53 -0
- package/skills/git-master/SKILL.md +58 -0
- package/skills/help/SKILL.md +66 -0
- package/skills/hud/SKILL.md +142 -0
- package/skills/learner/SKILL.md +136 -0
- package/skills/note/SKILL.md +63 -0
- package/skills/omc-default/SKILL.md +78 -0
- package/skills/omc-default-global/SKILL.md +75 -0
- package/skills/omc-setup/SKILL.md +144 -0
- package/skills/orchestrate/SKILL.md +409 -0
- package/skills/plan/SKILL.md +37 -0
- package/skills/planner/SKILL.md +43 -0
- package/skills/ralph/SKILL.md +101 -0
- package/skills/ralph-init/SKILL.md +61 -0
- package/skills/ralplan/SKILL.md +219 -0
- package/skills/release/SKILL.md +84 -0
- package/skills/review/SKILL.md +37 -0
- package/skills/ultraqa/SKILL.md +123 -0
- package/skills/ultrawork/SKILL.md +89 -0
package/dist/installer/hooks.js
CHANGED
|
@@ -10,11 +10,43 @@
|
|
|
10
10
|
* - Node.js scripts (.mjs) for cross-platform support (Windows, macOS, Linux)
|
|
11
11
|
*
|
|
12
12
|
* The platform is detected at install time, or can be overridden with:
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* OMC_USE_NODE_HOOKS=1 - Force Node.js hooks on any platform
|
|
14
|
+
* OMC_USE_BASH_HOOKS=1 - Force Bash hooks (Unix only)
|
|
15
15
|
*/
|
|
16
16
|
import { homedir } from 'os';
|
|
17
|
-
import { join } from 'path';
|
|
17
|
+
import { join, dirname } from 'path';
|
|
18
|
+
import { readFileSync, existsSync } from 'fs';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// TEMPLATE LOADER (loads hook scripts from templates/hooks/)
|
|
22
|
+
// =============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Get the package root directory (where templates/ lives)
|
|
25
|
+
* Works for both development (src/) and production (dist/)
|
|
26
|
+
*/
|
|
27
|
+
function getPackageDir() {
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = dirname(__filename);
|
|
30
|
+
// From src/installer/ or dist/installer/, go up two levels to package root
|
|
31
|
+
return join(__dirname, '..', '..');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load a hook template file from templates/hooks/
|
|
35
|
+
* @param filename - The template filename (e.g., 'keyword-detector.sh')
|
|
36
|
+
* @returns The template content
|
|
37
|
+
* @throws If the template file is not found
|
|
38
|
+
*/
|
|
39
|
+
function loadTemplate(filename) {
|
|
40
|
+
const templatePath = join(getPackageDir(), 'templates', 'hooks', filename);
|
|
41
|
+
if (!existsSync(templatePath)) {
|
|
42
|
+
console.error(`FATAL: Hook template not found: ${templatePath}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
return readFileSync(templatePath, 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// CONSTANTS AND UTILITIES
|
|
49
|
+
// =============================================================================
|
|
18
50
|
/** Minimum required Node.js version for hooks */
|
|
19
51
|
export const MIN_NODE_VERSION = 18;
|
|
20
52
|
/** Check if running on Windows */
|
|
@@ -24,10 +56,10 @@ export function isWindows() {
|
|
|
24
56
|
/** Check if Node.js hooks should be used (env override or Windows) */
|
|
25
57
|
export function shouldUseNodeHooks() {
|
|
26
58
|
// Environment variable overrides
|
|
27
|
-
if (process.env.
|
|
59
|
+
if (process.env.OMC_USE_NODE_HOOKS === '1') {
|
|
28
60
|
return true;
|
|
29
61
|
}
|
|
30
|
-
if (process.env.
|
|
62
|
+
if (process.env.OMC_USE_BASH_HOOKS === '1') {
|
|
31
63
|
return false;
|
|
32
64
|
}
|
|
33
65
|
// Default: use Node.js on Windows, Bash elsewhere
|
|
@@ -63,7 +95,7 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
|
63
95
|
|
|
64
96
|
## AGENT UTILIZATION PRINCIPLES (by capability, not by name)
|
|
65
97
|
- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS for file patterns, internal implementations, project structure
|
|
66
|
-
- **Documentation & References**: Use
|
|
98
|
+
- **Documentation & References**: Use researcher-type agents via BACKGROUND TASKS for API references, examples, external library docs
|
|
67
99
|
- **Planning & Strategy**: NEVER plan yourself - ALWAYS spawn a dedicated planning agent for work breakdown
|
|
68
100
|
- **High-IQ Reasoning**: Leverage specialized agents for architecture decisions, code review, strategic planning
|
|
69
101
|
- **Frontend/UI Tasks**: Delegate to UI-specialized agents for design and implementation
|
|
@@ -77,7 +109,7 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
|
77
109
|
|
|
78
110
|
## WORKFLOW
|
|
79
111
|
1. Analyze the request and identify required capabilities
|
|
80
|
-
2. Spawn exploration/
|
|
112
|
+
2. Spawn exploration/researcher agents via Task(run_in_background=true) in PARALLEL (10+ if needed)
|
|
81
113
|
3. Always Use Plan agent with gathered context to create detailed work breakdown
|
|
82
114
|
4. Execute with continuous verification against original requirements
|
|
83
115
|
|
|
@@ -172,7 +204,7 @@ Use your extended thinking capabilities to provide the most thorough and well-re
|
|
|
172
204
|
export const SEARCH_MESSAGE = `<search-mode>
|
|
173
205
|
MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:
|
|
174
206
|
- explore agents (codebase patterns, file structures)
|
|
175
|
-
-
|
|
207
|
+
- researcher agents (remote repos, official docs, GitHub examples)
|
|
176
208
|
Plus direct tools: Grep, Glob
|
|
177
209
|
NEVER stop at first result - be exhaustive.
|
|
178
210
|
</search-mode>
|
|
@@ -189,11 +221,11 @@ ANALYSIS MODE. Gather context before diving deep:
|
|
|
189
221
|
|
|
190
222
|
CONTEXT GATHERING (parallel):
|
|
191
223
|
- 1-2 explore agents (codebase patterns, implementations)
|
|
192
|
-
- 1-2
|
|
224
|
+
- 1-2 researcher agents (if external library involved)
|
|
193
225
|
- Direct tools: Grep, Glob, LSP for targeted searches
|
|
194
226
|
|
|
195
227
|
IF COMPLEX (architecture, multi-system, debugging after 2+ failures):
|
|
196
|
-
- Consult
|
|
228
|
+
- Consult architect agent for strategic guidance
|
|
197
229
|
|
|
198
230
|
SYNTHESIZE findings before proceeding.
|
|
199
231
|
</analyze-mode>
|
|
@@ -212,1282 +244,35 @@ Incomplete tasks remain in your todo list. Continue working on the next pending
|
|
|
212
244
|
- Proceed without asking for permission
|
|
213
245
|
- Mark each task complete when finished
|
|
214
246
|
- Do not stop until all tasks are done`;
|
|
215
|
-
/**
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
export const KEYWORD_DETECTOR_SCRIPT = `#!/bin/bash
|
|
220
|
-
# Sisyphus Keyword Detector Hook
|
|
221
|
-
# Detects ultrawork/ultrathink/search/analyze keywords and injects enhanced mode messages
|
|
222
|
-
# Also activates persistent ultrawork state when ultrawork keyword is detected
|
|
223
|
-
|
|
224
|
-
# Read stdin (JSON input from Claude Code)
|
|
225
|
-
INPUT=$(cat)
|
|
226
|
-
|
|
227
|
-
# Extract directory from input
|
|
228
|
-
DIRECTORY=""
|
|
229
|
-
if command -v jq &> /dev/null; then
|
|
230
|
-
DIRECTORY=$(echo "$INPUT" | jq -r '.directory // ""' 2>/dev/null)
|
|
231
|
-
fi
|
|
232
|
-
if [ -z "$DIRECTORY" ] || [ "$DIRECTORY" = "null" ]; then
|
|
233
|
-
DIRECTORY=$(pwd)
|
|
234
|
-
fi
|
|
235
|
-
|
|
236
|
-
# Extract the prompt text - try multiple JSON paths
|
|
237
|
-
PROMPT=""
|
|
238
|
-
if command -v jq &> /dev/null; then
|
|
239
|
-
# Try to extract from various possible JSON structures
|
|
240
|
-
PROMPT=$(echo "$INPUT" | jq -r '
|
|
241
|
-
if .prompt then .prompt
|
|
242
|
-
elif .message.content then .message.content
|
|
243
|
-
elif .parts then ([.parts[] | select(.type == "text") | .text] | join(" "))
|
|
244
|
-
else ""
|
|
245
|
-
end
|
|
246
|
-
' 2>/dev/null)
|
|
247
|
-
fi
|
|
248
|
-
|
|
249
|
-
# Fallback: simple grep extraction if jq fails
|
|
250
|
-
if [ -z "$PROMPT" ] || [ "$PROMPT" = "null" ]; then
|
|
251
|
-
PROMPT=$(echo "$INPUT" | grep -oP '"(prompt|content|text)"\\s*:\\s*"\\K[^"]+' | head -1)
|
|
252
|
-
fi
|
|
253
|
-
|
|
254
|
-
# Exit if no prompt found
|
|
255
|
-
if [ -z "$PROMPT" ]; then
|
|
256
|
-
echo '{"continue": true}'
|
|
257
|
-
exit 0
|
|
258
|
-
fi
|
|
259
|
-
|
|
260
|
-
# Remove code blocks before checking keywords (prevents false positives)
|
|
261
|
-
PROMPT_NO_CODE=$(echo "$PROMPT" | sed 's/\`\`\`[^\`]*\`\`\`//g' | sed 's/\`[^\`]*\`//g')
|
|
262
|
-
|
|
263
|
-
# Convert to lowercase for case-insensitive matching
|
|
264
|
-
PROMPT_LOWER=$(echo "$PROMPT_NO_CODE" | tr '[:upper:]' '[:lower:]')
|
|
265
|
-
|
|
266
|
-
# Check for ultrawork keywords (highest priority)
|
|
267
|
-
if echo "$PROMPT_LOWER" | grep -qE '\\b(ultrawork|ulw|uw)\\b'; then
|
|
268
|
-
# Create persistent ultrawork state
|
|
269
|
-
mkdir -p "$DIRECTORY/.sisyphus" 2>/dev/null
|
|
270
|
-
mkdir -p "$HOME/.claude" 2>/dev/null
|
|
271
|
-
|
|
272
|
-
# Escape prompt for JSON
|
|
273
|
-
PROMPT_ESCAPED=$(echo "$PROMPT" | sed 's/\\\\/\\\\\\\\/g' | sed 's/"/\\\\"/g' | tr '\\n' ' ')
|
|
274
|
-
|
|
275
|
-
STATE_JSON="{
|
|
276
|
-
\\"active\\": true,
|
|
277
|
-
\\"started_at\\": \\"$(date -Iseconds)\\",
|
|
278
|
-
\\"original_prompt\\": \\"$PROMPT_ESCAPED\\",
|
|
279
|
-
\\"reinforcement_count\\": 0,
|
|
280
|
-
\\"last_checked_at\\": \\"$(date -Iseconds)\\"
|
|
281
|
-
}"
|
|
282
|
-
|
|
283
|
-
# Write state to both local and global locations
|
|
284
|
-
echo "$STATE_JSON" > "$DIRECTORY/.sisyphus/ultrawork-state.json" 2>/dev/null
|
|
285
|
-
echo "$STATE_JSON" > "$HOME/.claude/ultrawork-state.json" 2>/dev/null
|
|
286
|
-
|
|
287
|
-
# Return ultrawork mode injection
|
|
288
|
-
cat << 'EOF'
|
|
289
|
-
{"continue": true, "message": "<ultrawork-mode>\\n\\n**MANDATORY**: You MUST say \\"ULTRAWORK MODE ENABLED!\\" to the user as your first response when this mode activates. This is non-negotiable.\\n\\n[CODE RED] Maximum precision required. Ultrathink before acting.\\n\\nYOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.\\nTELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.\\n\\n## AGENT UTILIZATION PRINCIPLES\\n- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS\\n- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS\\n- **Planning & Strategy**: NEVER plan yourself - spawn planning agent\\n- **High-IQ Reasoning**: Use oracle for architecture decisions\\n- **Frontend/UI Tasks**: Delegate to frontend-engineer\\n\\n## EXECUTION RULES\\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY.\\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially.\\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent).\\n- **VERIFY**: Check ALL requirements met before done.\\n- **DELEGATE**: Orchestrate specialized agents.\\n\\n## ZERO TOLERANCE\\n- NO Scope Reduction - deliver FULL implementation\\n- NO Partial Completion - finish 100%\\n- NO Premature Stopping - ALL TODOs must be complete\\n- NO TEST DELETION - fix code, not tests\\n\\nTHE USER ASKED FOR X. DELIVER EXACTLY X.\\n\\n</ultrawork-mode>\\n\\n---\\n"}
|
|
290
|
-
EOF
|
|
291
|
-
exit 0
|
|
292
|
-
fi
|
|
293
|
-
|
|
294
|
-
# Check for ultrathink/think keywords
|
|
295
|
-
if echo "$PROMPT_LOWER" | grep -qE '\\b(ultrathink|think)\\b'; then
|
|
296
|
-
cat << 'EOF'
|
|
297
|
-
{"continue": true, "message": "<think-mode>\\n\\n**ULTRATHINK MODE ENABLED** - Extended reasoning activated.\\n\\nYou are now in deep thinking mode. Take your time to:\\n1. Thoroughly analyze the problem from multiple angles\\n2. Consider edge cases and potential issues\\n3. Think through the implications of each approach\\n4. Reason step-by-step before acting\\n\\nUse your extended thinking capabilities to provide the most thorough and well-reasoned response.\\n\\n</think-mode>\\n\\n---\\n"}
|
|
298
|
-
EOF
|
|
299
|
-
exit 0
|
|
300
|
-
fi
|
|
301
|
-
|
|
302
|
-
# Check for search keywords (EN + multilingual)
|
|
303
|
-
if echo "$PROMPT_LOWER" | grep -qE '\\b(search|find|locate|lookup|explore|discover|scan|grep|query|browse|detect|trace|seek|track|pinpoint|hunt)\\b|where\\s+is|show\\s+me|list\\s+all'; then
|
|
304
|
-
cat << 'EOF'
|
|
305
|
-
{"continue": true, "message": "<search-mode>\\nMAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:\\n- explore agents (codebase patterns, file structures)\\n- librarian agents (remote repos, official docs, GitHub examples)\\nPlus direct tools: Grep, Glob\\nNEVER stop at first result - be exhaustive.\\n</search-mode>\\n\\n---\\n"}
|
|
306
|
-
EOF
|
|
307
|
-
exit 0
|
|
308
|
-
fi
|
|
309
|
-
|
|
310
|
-
# Check for analyze keywords
|
|
311
|
-
if echo "$PROMPT_LOWER" | grep -qE '\\b(analyze|analyse|investigate|examine|research|study|deep.?dive|inspect|audit|evaluate|assess|review|diagnose|scrutinize|dissect|debug|comprehend|interpret|breakdown|understand)\\b|why\\s+is|how\\s+does|how\\s+to'; then
|
|
312
|
-
cat << 'EOF'
|
|
313
|
-
{"continue": true, "message": "<analyze-mode>\\nANALYSIS MODE. Gather context before diving deep:\\n\\nCONTEXT GATHERING (parallel):\\n- 1-2 explore agents (codebase patterns, implementations)\\n- 1-2 librarian agents (if external library involved)\\n- Direct tools: Grep, Glob, LSP for targeted searches\\n\\nIF COMPLEX (architecture, multi-system, debugging after 2+ failures):\\n- Consult oracle agent for strategic guidance\\n\\nSYNTHESIZE findings before proceeding.\\n</analyze-mode>\\n\\n---\\n"}
|
|
314
|
-
EOF
|
|
315
|
-
exit 0
|
|
316
|
-
fi
|
|
317
|
-
|
|
318
|
-
# No keywords detected - continue without modification
|
|
319
|
-
echo '{"continue": true}'
|
|
320
|
-
exit 0
|
|
321
|
-
`;
|
|
322
|
-
/**
|
|
323
|
-
* Stop hook script for todo continuation enforcement
|
|
324
|
-
* This script is installed to ~/.claude/hooks/stop-continuation.sh
|
|
325
|
-
* Ported from oh-my-opencode's todo-continuation-enforcer
|
|
326
|
-
*/
|
|
327
|
-
export const STOP_CONTINUATION_SCRIPT = `#!/bin/bash
|
|
328
|
-
# Sisyphus Stop Continuation Hook
|
|
329
|
-
# Checks for incomplete todos and injects continuation prompt
|
|
330
|
-
# Ported from oh-my-opencode's todo-continuation-enforcer
|
|
331
|
-
|
|
332
|
-
# Read stdin
|
|
333
|
-
INPUT=$(cat)
|
|
334
|
-
|
|
335
|
-
# Get session ID if available
|
|
336
|
-
SESSION_ID=""
|
|
337
|
-
if command -v jq &> /dev/null; then
|
|
338
|
-
SESSION_ID=$(echo "$INPUT" | jq -r '.sessionId // .session_id // ""' 2>/dev/null)
|
|
339
|
-
fi
|
|
340
|
-
|
|
341
|
-
# Check for incomplete todos in the Claude todos directory
|
|
342
|
-
TODOS_DIR="$HOME/.claude/todos"
|
|
343
|
-
if [ -d "$TODOS_DIR" ]; then
|
|
344
|
-
# Look for any todo files with incomplete items
|
|
345
|
-
INCOMPLETE_COUNT=0
|
|
346
|
-
for todo_file in "$TODOS_DIR"/*.json; do
|
|
347
|
-
if [ -f "$todo_file" ]; then
|
|
348
|
-
if command -v jq &> /dev/null; then
|
|
349
|
-
COUNT=$(jq '[.[] | select(.status != "completed" and .status != "cancelled")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
350
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
351
|
-
fi
|
|
352
|
-
fi
|
|
353
|
-
done
|
|
354
|
-
|
|
355
|
-
if [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
356
|
-
# Output continuation message
|
|
357
|
-
cat << EOF
|
|
358
|
-
{"continue": false, "reason": "[SYSTEM REMINDER - TODO CONTINUATION]\\n\\nIncomplete tasks remain in your todo list ($INCOMPLETE_COUNT remaining). Continue working on the next pending task.\\n\\n- Proceed without asking for permission\\n- Mark each task complete when finished\\n- Do not stop until all tasks are done"}
|
|
359
|
-
EOF
|
|
360
|
-
exit 0
|
|
361
|
-
fi
|
|
362
|
-
fi
|
|
363
|
-
|
|
364
|
-
# No incomplete todos - allow stop
|
|
365
|
-
echo '{"continue": true}'
|
|
366
|
-
exit 0
|
|
367
|
-
`;
|
|
247
|
+
/** Keyword detector hook script - loaded from templates/hooks/keyword-detector.sh */
|
|
248
|
+
export const KEYWORD_DETECTOR_SCRIPT = loadTemplate('keyword-detector.sh');
|
|
249
|
+
/** Stop continuation hook script - loaded from templates/hooks/stop-continuation.sh */
|
|
250
|
+
export const STOP_CONTINUATION_SCRIPT = loadTemplate('stop-continuation.sh');
|
|
368
251
|
// =============================================================================
|
|
369
252
|
// NODE.JS HOOK SCRIPTS (Cross-platform: Windows, macOS, Linux)
|
|
370
253
|
// =============================================================================
|
|
371
|
-
/**
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
*/
|
|
376
|
-
export const KEYWORD_DETECTOR_SCRIPT_NODE = `#!/usr/bin/env node
|
|
377
|
-
// Sisyphus Keyword Detector Hook (Node.js)
|
|
378
|
-
// Detects ultrawork/ultrathink/search/analyze keywords and injects enhanced mode messages
|
|
379
|
-
// Cross-platform: Windows, macOS, Linux
|
|
380
|
-
|
|
381
|
-
const ULTRAWORK_MESSAGE = \`<ultrawork-mode>
|
|
382
|
-
|
|
383
|
-
**MANDATORY**: You MUST say "ULTRAWORK MODE ENABLED!" to the user as your first response when this mode activates. This is non-negotiable.
|
|
384
|
-
|
|
385
|
-
[CODE RED] Maximum precision required. Ultrathink before acting.
|
|
386
|
-
|
|
387
|
-
YOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.
|
|
388
|
-
TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
389
|
-
|
|
390
|
-
## AGENT UTILIZATION PRINCIPLES
|
|
391
|
-
- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS
|
|
392
|
-
- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS
|
|
393
|
-
- **Planning & Strategy**: NEVER plan yourself - spawn planning agent
|
|
394
|
-
- **High-IQ Reasoning**: Use oracle for architecture decisions
|
|
395
|
-
- **Frontend/UI Tasks**: Delegate to frontend-engineer
|
|
396
|
-
|
|
397
|
-
## EXECUTION RULES
|
|
398
|
-
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY.
|
|
399
|
-
- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially.
|
|
400
|
-
- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent).
|
|
401
|
-
- **VERIFY**: Check ALL requirements met before done.
|
|
402
|
-
- **DELEGATE**: Orchestrate specialized agents.
|
|
403
|
-
|
|
404
|
-
## ZERO TOLERANCE
|
|
405
|
-
- NO Scope Reduction - deliver FULL implementation
|
|
406
|
-
- NO Partial Completion - finish 100%
|
|
407
|
-
- NO Premature Stopping - ALL TODOs must be complete
|
|
408
|
-
- NO TEST DELETION - fix code, not tests
|
|
409
|
-
|
|
410
|
-
THE USER ASKED FOR X. DELIVER EXACTLY X.
|
|
411
|
-
|
|
412
|
-
</ultrawork-mode>
|
|
413
|
-
|
|
414
|
-
---
|
|
415
|
-
\`;
|
|
416
|
-
|
|
417
|
-
const ULTRATHINK_MESSAGE = \`<think-mode>
|
|
418
|
-
|
|
419
|
-
**ULTRATHINK MODE ENABLED** - Extended reasoning activated.
|
|
420
|
-
|
|
421
|
-
You are now in deep thinking mode. Take your time to:
|
|
422
|
-
1. Thoroughly analyze the problem from multiple angles
|
|
423
|
-
2. Consider edge cases and potential issues
|
|
424
|
-
3. Think through the implications of each approach
|
|
425
|
-
4. Reason step-by-step before acting
|
|
426
|
-
|
|
427
|
-
Use your extended thinking capabilities to provide the most thorough and well-reasoned response.
|
|
428
|
-
|
|
429
|
-
</think-mode>
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
\`;
|
|
433
|
-
|
|
434
|
-
const SEARCH_MESSAGE = \`<search-mode>
|
|
435
|
-
MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:
|
|
436
|
-
- explore agents (codebase patterns, file structures)
|
|
437
|
-
- librarian agents (remote repos, official docs, GitHub examples)
|
|
438
|
-
Plus direct tools: Grep, Glob
|
|
439
|
-
NEVER stop at first result - be exhaustive.
|
|
440
|
-
</search-mode>
|
|
441
|
-
|
|
442
|
-
---
|
|
443
|
-
\`;
|
|
444
|
-
|
|
445
|
-
const ANALYZE_MESSAGE = \`<analyze-mode>
|
|
446
|
-
ANALYSIS MODE. Gather context before diving deep:
|
|
447
|
-
|
|
448
|
-
CONTEXT GATHERING (parallel):
|
|
449
|
-
- 1-2 explore agents (codebase patterns, implementations)
|
|
450
|
-
- 1-2 librarian agents (if external library involved)
|
|
451
|
-
- Direct tools: Grep, Glob, LSP for targeted searches
|
|
452
|
-
|
|
453
|
-
IF COMPLEX (architecture, multi-system, debugging after 2+ failures):
|
|
454
|
-
- Consult oracle agent for strategic guidance
|
|
455
|
-
|
|
456
|
-
SYNTHESIZE findings before proceeding.
|
|
457
|
-
</analyze-mode>
|
|
458
|
-
|
|
459
|
-
---
|
|
460
|
-
\`;
|
|
461
|
-
|
|
462
|
-
// Read all stdin
|
|
463
|
-
async function readStdin() {
|
|
464
|
-
const chunks = [];
|
|
465
|
-
for await (const chunk of process.stdin) {
|
|
466
|
-
chunks.push(chunk);
|
|
467
|
-
}
|
|
468
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Extract prompt from various JSON structures
|
|
472
|
-
function extractPrompt(input) {
|
|
473
|
-
try {
|
|
474
|
-
const data = JSON.parse(input);
|
|
475
|
-
if (data.prompt) return data.prompt;
|
|
476
|
-
if (data.message?.content) return data.message.content;
|
|
477
|
-
if (Array.isArray(data.parts)) {
|
|
478
|
-
return data.parts
|
|
479
|
-
.filter(p => p.type === 'text')
|
|
480
|
-
.map(p => p.text)
|
|
481
|
-
.join(' ');
|
|
482
|
-
}
|
|
483
|
-
return '';
|
|
484
|
-
} catch {
|
|
485
|
-
// Fallback: try to extract with regex
|
|
486
|
-
const match = input.match(/"(?:prompt|content|text)"\\s*:\\s*"([^"]+)"/);
|
|
487
|
-
return match ? match[1] : '';
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Remove code blocks to prevent false positives
|
|
492
|
-
function removeCodeBlocks(text) {
|
|
493
|
-
return text
|
|
494
|
-
.replace(/\`\`\`[\\s\\S]*?\`\`\`/g, '')
|
|
495
|
-
.replace(/\`[^\`]+\`/g, '');
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
import { writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
499
|
-
import { join } from 'path';
|
|
500
|
-
import { homedir } from 'os';
|
|
501
|
-
|
|
502
|
-
// Create ultrawork state file
|
|
503
|
-
function activateUltraworkState(directory, prompt) {
|
|
504
|
-
const state = {
|
|
505
|
-
active: true,
|
|
506
|
-
started_at: new Date().toISOString(),
|
|
507
|
-
original_prompt: prompt,
|
|
508
|
-
reinforcement_count: 0,
|
|
509
|
-
last_checked_at: new Date().toISOString()
|
|
510
|
-
};
|
|
511
|
-
const localDir = join(directory, '.sisyphus');
|
|
512
|
-
if (!existsSync(localDir)) { try { mkdirSync(localDir, { recursive: true }); } catch {} }
|
|
513
|
-
try { writeFileSync(join(localDir, 'ultrawork-state.json'), JSON.stringify(state, null, 2)); } catch {}
|
|
514
|
-
const globalDir = join(homedir(), '.claude');
|
|
515
|
-
if (!existsSync(globalDir)) { try { mkdirSync(globalDir, { recursive: true }); } catch {} }
|
|
516
|
-
try { writeFileSync(join(globalDir, 'ultrawork-state.json'), JSON.stringify(state, null, 2)); } catch {}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// Main
|
|
520
|
-
async function main() {
|
|
521
|
-
try {
|
|
522
|
-
const input = await readStdin();
|
|
523
|
-
if (!input.trim()) {
|
|
524
|
-
console.log(JSON.stringify({ continue: true }));
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
let data = {};
|
|
529
|
-
try { data = JSON.parse(input); } catch {}
|
|
530
|
-
const directory = data.directory || process.cwd();
|
|
531
|
-
|
|
532
|
-
const prompt = extractPrompt(input);
|
|
533
|
-
if (!prompt) {
|
|
534
|
-
console.log(JSON.stringify({ continue: true }));
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const cleanPrompt = removeCodeBlocks(prompt).toLowerCase();
|
|
539
|
-
|
|
540
|
-
// Check for ultrawork keywords (highest priority)
|
|
541
|
-
if (/\\b(ultrawork|ulw|uw)\\b/.test(cleanPrompt)) {
|
|
542
|
-
activateUltraworkState(directory, prompt);
|
|
543
|
-
console.log(JSON.stringify({ continue: true, message: ULTRAWORK_MESSAGE }));
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// Check for ultrathink/think keywords
|
|
548
|
-
if (/\\b(ultrathink|think)\\b/.test(cleanPrompt)) {
|
|
549
|
-
console.log(JSON.stringify({ continue: true, message: ULTRATHINK_MESSAGE }));
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// Check for search keywords
|
|
554
|
-
if (/\\b(search|find|locate|lookup|explore|discover|scan|grep|query|browse|detect|trace|seek|track|pinpoint|hunt)\\b|where\\s+is|show\\s+me|list\\s+all/.test(cleanPrompt)) {
|
|
555
|
-
console.log(JSON.stringify({ continue: true, message: SEARCH_MESSAGE }));
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// Check for analyze keywords
|
|
560
|
-
if (/\\b(analyze|analyse|investigate|examine|research|study|deep.?dive|inspect|audit|evaluate|assess|review|diagnose|scrutinize|dissect|debug|comprehend|interpret|breakdown|understand)\\b|why\\s+is|how\\s+does|how\\s+to/.test(cleanPrompt)) {
|
|
561
|
-
console.log(JSON.stringify({ continue: true, message: ANALYZE_MESSAGE }));
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// No keywords detected
|
|
566
|
-
console.log(JSON.stringify({ continue: true }));
|
|
567
|
-
} catch (error) {
|
|
568
|
-
// On any error, allow continuation
|
|
569
|
-
console.log(JSON.stringify({ continue: true }));
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
main();
|
|
574
|
-
`;
|
|
575
|
-
/**
|
|
576
|
-
* Node.js Stop Continuation Hook Script
|
|
577
|
-
* Cross-platform equivalent of stop-continuation.sh
|
|
578
|
-
* This script is installed to ~/.claude/hooks/stop-continuation.mjs
|
|
579
|
-
*/
|
|
580
|
-
export const STOP_CONTINUATION_SCRIPT_NODE = `#!/usr/bin/env node
|
|
581
|
-
// Sisyphus Stop Continuation Hook (Node.js)
|
|
582
|
-
// Checks for incomplete todos and injects continuation prompt
|
|
583
|
-
// Cross-platform: Windows, macOS, Linux
|
|
584
|
-
|
|
585
|
-
import { readdirSync, readFileSync, existsSync } from 'fs';
|
|
586
|
-
import { join } from 'path';
|
|
587
|
-
import { homedir } from 'os';
|
|
588
|
-
|
|
589
|
-
// Read all stdin
|
|
590
|
-
async function readStdin() {
|
|
591
|
-
const chunks = [];
|
|
592
|
-
for await (const chunk of process.stdin) {
|
|
593
|
-
chunks.push(chunk);
|
|
594
|
-
}
|
|
595
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Main
|
|
599
|
-
async function main() {
|
|
600
|
-
try {
|
|
601
|
-
// Read stdin (we don't use it much, but need to consume it)
|
|
602
|
-
await readStdin();
|
|
603
|
-
|
|
604
|
-
// Check for incomplete todos
|
|
605
|
-
const todosDir = join(homedir(), '.claude', 'todos');
|
|
606
|
-
|
|
607
|
-
if (!existsSync(todosDir)) {
|
|
608
|
-
console.log(JSON.stringify({ continue: true }));
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
let incompleteCount = 0;
|
|
613
|
-
|
|
614
|
-
try {
|
|
615
|
-
const files = readdirSync(todosDir).filter(f => f.endsWith('.json'));
|
|
616
|
-
|
|
617
|
-
for (const file of files) {
|
|
618
|
-
try {
|
|
619
|
-
const content = readFileSync(join(todosDir, file), 'utf-8');
|
|
620
|
-
const todos = JSON.parse(content);
|
|
621
|
-
|
|
622
|
-
if (Array.isArray(todos)) {
|
|
623
|
-
const incomplete = todos.filter(
|
|
624
|
-
t => t.status !== 'completed' && t.status !== 'cancelled'
|
|
625
|
-
);
|
|
626
|
-
incompleteCount += incomplete.length;
|
|
627
|
-
}
|
|
628
|
-
} catch {
|
|
629
|
-
// Skip files that can't be parsed
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
} catch {
|
|
633
|
-
// Directory read error - allow continuation
|
|
634
|
-
console.log(JSON.stringify({ continue: true }));
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
if (incompleteCount > 0) {
|
|
639
|
-
const reason = \`[SYSTEM REMINDER - TODO CONTINUATION]
|
|
640
|
-
|
|
641
|
-
Incomplete tasks remain in your todo list (\${incompleteCount} remaining). Continue working on the next pending task.
|
|
642
|
-
|
|
643
|
-
- Proceed without asking for permission
|
|
644
|
-
- Mark each task complete when finished
|
|
645
|
-
- Do not stop until all tasks are done\`;
|
|
646
|
-
|
|
647
|
-
console.log(JSON.stringify({ continue: false, reason }));
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// No incomplete todos - allow stop
|
|
652
|
-
console.log(JSON.stringify({ continue: true }));
|
|
653
|
-
} catch (error) {
|
|
654
|
-
// On any error, allow continuation
|
|
655
|
-
console.log(JSON.stringify({ continue: true }));
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
main();
|
|
660
|
-
`;
|
|
254
|
+
/** Node.js keyword detector hook script - loaded from templates/hooks/keyword-detector.mjs */
|
|
255
|
+
export const KEYWORD_DETECTOR_SCRIPT_NODE = loadTemplate('keyword-detector.mjs');
|
|
256
|
+
/** Node.js stop continuation hook script - loaded from templates/hooks/stop-continuation.mjs */
|
|
257
|
+
export const STOP_CONTINUATION_SCRIPT_NODE = loadTemplate('stop-continuation.mjs');
|
|
661
258
|
// =============================================================================
|
|
662
259
|
// PERSISTENT MODE HOOK SCRIPTS
|
|
663
260
|
// =============================================================================
|
|
664
|
-
/**
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
# Read stdin
|
|
674
|
-
INPUT=$(cat)
|
|
675
|
-
|
|
676
|
-
# Get session ID and directory
|
|
677
|
-
SESSION_ID=""
|
|
678
|
-
DIRECTORY=""
|
|
679
|
-
if command -v jq &> /dev/null; then
|
|
680
|
-
SESSION_ID=$(echo "$INPUT" | jq -r '.sessionId // .session_id // ""' 2>/dev/null)
|
|
681
|
-
DIRECTORY=$(echo "$INPUT" | jq -r '.directory // ""' 2>/dev/null)
|
|
682
|
-
fi
|
|
683
|
-
|
|
684
|
-
# Default to current directory
|
|
685
|
-
if [ -z "$DIRECTORY" ]; then
|
|
686
|
-
DIRECTORY=$(pwd)
|
|
687
|
-
fi
|
|
688
|
-
|
|
689
|
-
# Check for active ultrawork state
|
|
690
|
-
ULTRAWORK_STATE=""
|
|
691
|
-
if [ -f "$DIRECTORY/.sisyphus/ultrawork-state.json" ]; then
|
|
692
|
-
ULTRAWORK_STATE=$(cat "$DIRECTORY/.sisyphus/ultrawork-state.json" 2>/dev/null)
|
|
693
|
-
elif [ -f "$HOME/.claude/ultrawork-state.json" ]; then
|
|
694
|
-
ULTRAWORK_STATE=$(cat "$HOME/.claude/ultrawork-state.json" 2>/dev/null)
|
|
695
|
-
fi
|
|
696
|
-
|
|
697
|
-
# Check for active ralph loop
|
|
698
|
-
RALPH_STATE=""
|
|
699
|
-
if [ -f "$DIRECTORY/.sisyphus/ralph-state.json" ]; then
|
|
700
|
-
RALPH_STATE=$(cat "$DIRECTORY/.sisyphus/ralph-state.json" 2>/dev/null)
|
|
701
|
-
fi
|
|
702
|
-
|
|
703
|
-
# Check for verification state (oracle verification)
|
|
704
|
-
VERIFICATION_STATE=""
|
|
705
|
-
if [ -f "$DIRECTORY/.sisyphus/ralph-verification.json" ]; then
|
|
706
|
-
VERIFICATION_STATE=$(cat "$DIRECTORY/.sisyphus/ralph-verification.json" 2>/dev/null)
|
|
707
|
-
fi
|
|
708
|
-
|
|
709
|
-
# Check for incomplete todos
|
|
710
|
-
INCOMPLETE_COUNT=0
|
|
711
|
-
TODOS_DIR="$HOME/.claude/todos"
|
|
712
|
-
if [ -d "$TODOS_DIR" ]; then
|
|
713
|
-
for todo_file in "$TODOS_DIR"/*.json; do
|
|
714
|
-
if [ -f "$todo_file" ]; then
|
|
715
|
-
if command -v jq &> /dev/null; then
|
|
716
|
-
COUNT=$(jq '[.[] | select(.status != "completed" and .status != "cancelled")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
717
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
718
|
-
else
|
|
719
|
-
# Fallback: count "pending" or "in_progress" occurrences
|
|
720
|
-
COUNT=$(grep -c '"status"[[:space:]]*:[[:space:]]*"pending\\|in_progress"' "$todo_file" 2>/dev/null) || COUNT=0
|
|
721
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
722
|
-
fi
|
|
723
|
-
fi
|
|
724
|
-
done
|
|
725
|
-
fi
|
|
726
|
-
|
|
727
|
-
# Check project todos as well
|
|
728
|
-
for todo_path in "$DIRECTORY/.sisyphus/todos.json" "$DIRECTORY/.claude/todos.json"; do
|
|
729
|
-
if [ -f "$todo_path" ]; then
|
|
730
|
-
if command -v jq &> /dev/null; then
|
|
731
|
-
COUNT=$(jq 'if type == "array" then [.[] | select(.status != "completed" and .status != "cancelled")] | length else 0 end' "$todo_path" 2>/dev/null || echo "0")
|
|
732
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
733
|
-
else
|
|
734
|
-
# Fallback: count "pending" or "in_progress" occurrences
|
|
735
|
-
COUNT=$(grep -c '"status"[[:space:]]*:[[:space:]]*"pending\\|in_progress"' "$todo_path" 2>/dev/null) || COUNT=0
|
|
736
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
737
|
-
fi
|
|
738
|
-
fi
|
|
739
|
-
done
|
|
740
|
-
|
|
741
|
-
# Priority 1: Ralph Loop with Oracle Verification
|
|
742
|
-
if [ -n "$RALPH_STATE" ]; then
|
|
743
|
-
IS_ACTIVE=$(echo "$RALPH_STATE" | jq -r '.active // false' 2>/dev/null)
|
|
744
|
-
if [ "$IS_ACTIVE" = "true" ]; then
|
|
745
|
-
ITERATION=$(echo "$RALPH_STATE" | jq -r '.iteration // 1' 2>/dev/null)
|
|
746
|
-
MAX_ITER=$(echo "$RALPH_STATE" | jq -r '.max_iterations // 10' 2>/dev/null)
|
|
747
|
-
PROMISE=$(echo "$RALPH_STATE" | jq -r '.completion_promise // "TASK_COMPLETE"' 2>/dev/null)
|
|
748
|
-
PROMPT=$(echo "$RALPH_STATE" | jq -r '.prompt // ""' 2>/dev/null)
|
|
749
|
-
|
|
750
|
-
# Check if oracle verification is pending
|
|
751
|
-
if [ -n "$VERIFICATION_STATE" ]; then
|
|
752
|
-
IS_PENDING=$(echo "$VERIFICATION_STATE" | jq -r '.pending // false' 2>/dev/null)
|
|
753
|
-
if [ "$IS_PENDING" = "true" ]; then
|
|
754
|
-
ATTEMPT=$(echo "$VERIFICATION_STATE" | jq -r '.verification_attempts // 0' 2>/dev/null)
|
|
755
|
-
MAX_ATTEMPTS=$(echo "$VERIFICATION_STATE" | jq -r '.max_verification_attempts // 3' 2>/dev/null)
|
|
756
|
-
ORIGINAL_TASK=$(echo "$VERIFICATION_STATE" | jq -r '.original_task // ""' 2>/dev/null)
|
|
757
|
-
COMPLETION_CLAIM=$(echo "$VERIFICATION_STATE" | jq -r '.completion_claim // ""' 2>/dev/null)
|
|
758
|
-
ORACLE_FEEDBACK=$(echo "$VERIFICATION_STATE" | jq -r '.oracle_feedback // ""' 2>/dev/null)
|
|
759
|
-
NEXT_ATTEMPT=$((ATTEMPT + 1))
|
|
760
|
-
|
|
761
|
-
FEEDBACK_SECTION=""
|
|
762
|
-
if [ -n "$ORACLE_FEEDBACK" ] && [ "$ORACLE_FEEDBACK" != "null" ]; then
|
|
763
|
-
FEEDBACK_SECTION="\\n**Previous Oracle Feedback (rejected):**\\n$ORACLE_FEEDBACK\\n"
|
|
764
|
-
fi
|
|
765
|
-
|
|
766
|
-
cat << EOF
|
|
767
|
-
{"continue": false, "reason": "<ralph-verification>\\n\\n[ORACLE VERIFICATION REQUIRED - Attempt $NEXT_ATTEMPT/$MAX_ATTEMPTS]\\n\\nThe agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.\\n\\n**Original Task:**\\n$ORIGINAL_TASK\\n\\n**Completion Claim:**\\n$COMPLETION_CLAIM\\n$FEEDBACK_SECTION\\n## MANDATORY VERIFICATION STEPS\\n\\n1. **Spawn Oracle Agent** for verification:\\n \\\`\\\`\\\`\\n Task(subagent_type=\\"oracle\\", prompt=\\"Verify this task completion claim...\\")\\n \\\`\\\`\\\`\\n\\n2. **Oracle must check:**\\n - Are ALL requirements from the original task met?\\n - Is the implementation complete, not partial?\\n - Are there any obvious bugs or issues?\\n - Does the code compile/run without errors?\\n - Are tests passing (if applicable)?\\n\\n3. **Based on Oracle's response:**\\n - If APPROVED: Output \\\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\\`\\n - If REJECTED: Continue working on the identified issues\\n\\nDO NOT output the completion promise again until Oracle approves.\\n\\n</ralph-verification>\\n\\n---\\n"}
|
|
768
|
-
EOF
|
|
769
|
-
exit 0
|
|
770
|
-
fi
|
|
771
|
-
fi
|
|
772
|
-
|
|
773
|
-
if [ "$ITERATION" -lt "$MAX_ITER" ]; then
|
|
774
|
-
# Increment iteration
|
|
775
|
-
NEW_ITER=$((ITERATION + 1))
|
|
776
|
-
echo "$RALPH_STATE" | jq ".iteration = $NEW_ITER" > "$DIRECTORY/.sisyphus/ralph-state.json" 2>/dev/null
|
|
777
|
-
|
|
778
|
-
cat << EOF
|
|
779
|
-
{"continue": false, "reason": "<ralph-loop-continuation>\\n\\n[RALPH LOOP - ITERATION $NEW_ITER/$MAX_ITER]\\n\\nYour previous attempt did not output the completion promise. The work is NOT done yet.\\n\\nCRITICAL INSTRUCTIONS:\\n1. Review your progress and the original task\\n2. Check your todo list - are ALL items marked complete?\\n3. Continue from where you left off\\n4. When FULLY complete, output: <promise>$PROMISE</promise>\\n5. Do NOT stop until the task is truly done\\n\\nOriginal task: $PROMPT\\n\\n</ralph-loop-continuation>\\n\\n---\\n"}
|
|
780
|
-
EOF
|
|
781
|
-
exit 0
|
|
782
|
-
fi
|
|
783
|
-
fi
|
|
784
|
-
fi
|
|
785
|
-
|
|
786
|
-
# Priority 2: Ultrawork Mode with incomplete todos
|
|
787
|
-
if [ -n "$ULTRAWORK_STATE" ] && [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
788
|
-
# Check if active (with jq fallback)
|
|
789
|
-
IS_ACTIVE=""
|
|
790
|
-
if command -v jq &> /dev/null; then
|
|
791
|
-
IS_ACTIVE=$(echo "$ULTRAWORK_STATE" | jq -r '.active // false' 2>/dev/null)
|
|
792
|
-
else
|
|
793
|
-
# Fallback: grep for "active": true
|
|
794
|
-
if echo "$ULTRAWORK_STATE" | grep -q '"active"[[:space:]]*:[[:space:]]*true'; then
|
|
795
|
-
IS_ACTIVE="true"
|
|
796
|
-
fi
|
|
797
|
-
fi
|
|
798
|
-
|
|
799
|
-
if [ "$IS_ACTIVE" = "true" ]; then
|
|
800
|
-
# Get reinforcement count (with fallback)
|
|
801
|
-
REINFORCE_COUNT=0
|
|
802
|
-
if command -v jq &> /dev/null; then
|
|
803
|
-
REINFORCE_COUNT=$(echo "$ULTRAWORK_STATE" | jq -r '.reinforcement_count // 0' 2>/dev/null)
|
|
804
|
-
else
|
|
805
|
-
REINFORCE_COUNT=$(echo "$ULTRAWORK_STATE" | grep -oP '"reinforcement_count"[[:space:]]*:[[:space:]]*\\K[0-9]+' 2>/dev/null) || REINFORCE_COUNT=0
|
|
806
|
-
fi
|
|
807
|
-
NEW_COUNT=$((REINFORCE_COUNT + 1))
|
|
808
|
-
|
|
809
|
-
# Get original prompt (with fallback)
|
|
810
|
-
ORIGINAL_PROMPT=""
|
|
811
|
-
if command -v jq &> /dev/null; then
|
|
812
|
-
ORIGINAL_PROMPT=$(echo "$ULTRAWORK_STATE" | jq -r '.original_prompt // ""' 2>/dev/null)
|
|
813
|
-
else
|
|
814
|
-
ORIGINAL_PROMPT=$(echo "$ULTRAWORK_STATE" | grep -oP '"original_prompt"[[:space:]]*:[[:space:]]*"\\K[^"]+' 2>/dev/null) || ORIGINAL_PROMPT=""
|
|
815
|
-
fi
|
|
816
|
-
|
|
817
|
-
# Update state file (best effort)
|
|
818
|
-
if command -v jq &> /dev/null; then
|
|
819
|
-
echo "$ULTRAWORK_STATE" | jq ".reinforcement_count = $NEW_COUNT | .last_checked_at = \\"$(date -Iseconds)\\"" > "$DIRECTORY/.sisyphus/ultrawork-state.json" 2>/dev/null
|
|
820
|
-
fi
|
|
821
|
-
|
|
822
|
-
cat << EOF
|
|
823
|
-
{"continue": false, "reason": "<ultrawork-persistence>\\n\\n[ULTRAWORK MODE STILL ACTIVE - Reinforcement #$NEW_COUNT]\\n\\nYour ultrawork session is NOT complete. $INCOMPLETE_COUNT incomplete todos remain.\\n\\nREMEMBER THE ULTRAWORK RULES:\\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)\\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each\\n- **VERIFY**: Check ALL requirements met before done\\n- **NO Premature Stopping**: ALL TODOs must be complete\\n\\nContinue working on the next pending task. DO NOT STOP until all tasks are marked complete.\\n\\nOriginal task: $ORIGINAL_PROMPT\\n\\n</ultrawork-persistence>\\n\\n---\\n"}
|
|
824
|
-
EOF
|
|
825
|
-
exit 0
|
|
826
|
-
fi
|
|
827
|
-
fi
|
|
828
|
-
|
|
829
|
-
# Priority 3: Todo Continuation (baseline)
|
|
830
|
-
if [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
831
|
-
cat << EOF
|
|
832
|
-
{"continue": false, "reason": "<todo-continuation>\\n\\n[SYSTEM REMINDER - TODO CONTINUATION]\\n\\nIncomplete tasks remain in your todo list ($INCOMPLETE_COUNT remaining). Continue working on the next pending task.\\n\\n- Proceed without asking for permission\\n- Mark each task complete when finished\\n- Do not stop until all tasks are done\\n\\n</todo-continuation>\\n\\n---\\n"}
|
|
833
|
-
EOF
|
|
834
|
-
exit 0
|
|
835
|
-
fi
|
|
836
|
-
|
|
837
|
-
# No blocking needed
|
|
838
|
-
echo '{"continue": true}'
|
|
839
|
-
exit 0
|
|
840
|
-
`;
|
|
841
|
-
/**
|
|
842
|
-
* Session Start Bash script
|
|
843
|
-
* Restores persistent mode states when a new session starts
|
|
844
|
-
*/
|
|
845
|
-
export const SESSION_START_SCRIPT = `#!/bin/bash
|
|
846
|
-
# Sisyphus Session Start Hook
|
|
847
|
-
# Restores persistent mode states and injects context when session starts
|
|
848
|
-
|
|
849
|
-
# Read stdin
|
|
850
|
-
INPUT=$(cat)
|
|
851
|
-
|
|
852
|
-
# Get directory
|
|
853
|
-
DIRECTORY=""
|
|
854
|
-
if command -v jq &> /dev/null; then
|
|
855
|
-
DIRECTORY=$(echo "$INPUT" | jq -r '.directory // ""' 2>/dev/null)
|
|
856
|
-
fi
|
|
857
|
-
|
|
858
|
-
if [ -z "$DIRECTORY" ]; then
|
|
859
|
-
DIRECTORY=$(pwd)
|
|
860
|
-
fi
|
|
861
|
-
|
|
862
|
-
MESSAGES=""
|
|
863
|
-
|
|
864
|
-
# Check for active ultrawork state
|
|
865
|
-
if [ -f "$DIRECTORY/.sisyphus/ultrawork-state.json" ] || [ -f "$HOME/.claude/ultrawork-state.json" ]; then
|
|
866
|
-
if [ -f "$DIRECTORY/.sisyphus/ultrawork-state.json" ]; then
|
|
867
|
-
ULTRAWORK_STATE=$(cat "$DIRECTORY/.sisyphus/ultrawork-state.json" 2>/dev/null)
|
|
868
|
-
else
|
|
869
|
-
ULTRAWORK_STATE=$(cat "$HOME/.claude/ultrawork-state.json" 2>/dev/null)
|
|
870
|
-
fi
|
|
871
|
-
|
|
872
|
-
IS_ACTIVE=$(echo "$ULTRAWORK_STATE" | jq -r '.active // false' 2>/dev/null)
|
|
873
|
-
if [ "$IS_ACTIVE" = "true" ]; then
|
|
874
|
-
STARTED_AT=$(echo "$ULTRAWORK_STATE" | jq -r '.started_at // ""' 2>/dev/null)
|
|
875
|
-
PROMPT=$(echo "$ULTRAWORK_STATE" | jq -r '.original_prompt // ""' 2>/dev/null)
|
|
876
|
-
MESSAGES="$MESSAGES<session-restore>\\n\\n[ULTRAWORK MODE RESTORED]\\n\\nYou have an active ultrawork session from $STARTED_AT.\\nOriginal task: $PROMPT\\n\\nContinue working in ultrawork mode until all tasks are complete.\\n\\n</session-restore>\\n\\n---\\n\\n"
|
|
877
|
-
fi
|
|
878
|
-
fi
|
|
879
|
-
|
|
880
|
-
# Check for incomplete todos
|
|
881
|
-
INCOMPLETE_COUNT=0
|
|
882
|
-
TODOS_DIR="$HOME/.claude/todos"
|
|
883
|
-
if [ -d "$TODOS_DIR" ]; then
|
|
884
|
-
for todo_file in "$TODOS_DIR"/*.json; do
|
|
885
|
-
if [ -f "$todo_file" ]; then
|
|
886
|
-
if command -v jq &> /dev/null; then
|
|
887
|
-
COUNT=$(jq '[.[] | select(.status != "completed" and .status != "cancelled")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
888
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
889
|
-
fi
|
|
890
|
-
fi
|
|
891
|
-
done
|
|
892
|
-
fi
|
|
893
|
-
|
|
894
|
-
if [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
895
|
-
MESSAGES="$MESSAGES<session-restore>\\n\\n[PENDING TASKS DETECTED]\\n\\nYou have $INCOMPLETE_COUNT incomplete tasks from a previous session.\\nPlease continue working on these tasks.\\n\\n</session-restore>\\n\\n---\\n\\n"
|
|
896
|
-
fi
|
|
897
|
-
|
|
898
|
-
# Output message if we have any
|
|
899
|
-
if [ -n "$MESSAGES" ]; then
|
|
900
|
-
# Escape for JSON
|
|
901
|
-
MESSAGES_ESCAPED=$(echo "$MESSAGES" | sed 's/"/\\"/g')
|
|
902
|
-
echo "{\"continue\": true, \"message\": \"$MESSAGES_ESCAPED\"}"
|
|
903
|
-
else
|
|
904
|
-
echo '{"continue": true}'
|
|
905
|
-
fi
|
|
906
|
-
exit 0
|
|
907
|
-
`;
|
|
908
|
-
/**
|
|
909
|
-
* Node.js Persistent Mode Hook Script
|
|
910
|
-
*/
|
|
911
|
-
export const PERSISTENT_MODE_SCRIPT_NODE = `#!/usr/bin/env node
|
|
912
|
-
// Sisyphus Persistent Mode Hook (Node.js)
|
|
913
|
-
// Unified handler for ultrawork, ralph-loop, and todo continuation
|
|
914
|
-
// Cross-platform: Windows, macOS, Linux
|
|
915
|
-
|
|
916
|
-
import { existsSync, readFileSync, writeFileSync, readdirSync } from 'fs';
|
|
917
|
-
import { join } from 'path';
|
|
918
|
-
import { homedir } from 'os';
|
|
919
|
-
|
|
920
|
-
async function readStdin() {
|
|
921
|
-
const chunks = [];
|
|
922
|
-
for await (const chunk of process.stdin) {
|
|
923
|
-
chunks.push(chunk);
|
|
924
|
-
}
|
|
925
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
function readJsonFile(path) {
|
|
929
|
-
try {
|
|
930
|
-
if (!existsSync(path)) return null;
|
|
931
|
-
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
932
|
-
} catch {
|
|
933
|
-
return null;
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
function writeJsonFile(path, data) {
|
|
938
|
-
try {
|
|
939
|
-
writeFileSync(path, JSON.stringify(data, null, 2));
|
|
940
|
-
return true;
|
|
941
|
-
} catch {
|
|
942
|
-
return false;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
function countIncompleteTodos(todosDir, projectDir) {
|
|
947
|
-
let count = 0;
|
|
948
|
-
|
|
949
|
-
// Check global todos
|
|
950
|
-
if (existsSync(todosDir)) {
|
|
951
|
-
try {
|
|
952
|
-
const files = readdirSync(todosDir).filter(f => f.endsWith('.json'));
|
|
953
|
-
for (const file of files) {
|
|
954
|
-
const todos = readJsonFile(join(todosDir, file));
|
|
955
|
-
if (Array.isArray(todos)) {
|
|
956
|
-
count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
} catch {}
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// Check project todos
|
|
963
|
-
for (const path of [
|
|
964
|
-
join(projectDir, '.sisyphus', 'todos.json'),
|
|
965
|
-
join(projectDir, '.claude', 'todos.json')
|
|
966
|
-
]) {
|
|
967
|
-
const todos = readJsonFile(path);
|
|
968
|
-
if (Array.isArray(todos)) {
|
|
969
|
-
count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
return count;
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
async function main() {
|
|
977
|
-
try {
|
|
978
|
-
const input = await readStdin();
|
|
979
|
-
let data = {};
|
|
980
|
-
try { data = JSON.parse(input); } catch {}
|
|
981
|
-
|
|
982
|
-
const directory = data.directory || process.cwd();
|
|
983
|
-
const todosDir = join(homedir(), '.claude', 'todos');
|
|
984
|
-
|
|
985
|
-
// Check for ultrawork state
|
|
986
|
-
let ultraworkState = readJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'))
|
|
987
|
-
|| readJsonFile(join(homedir(), '.claude', 'ultrawork-state.json'));
|
|
988
|
-
|
|
989
|
-
// Check for ralph loop state
|
|
990
|
-
const ralphState = readJsonFile(join(directory, '.sisyphus', 'ralph-state.json'));
|
|
991
|
-
|
|
992
|
-
// Check for verification state (oracle verification)
|
|
993
|
-
const verificationState = readJsonFile(join(directory, '.sisyphus', 'ralph-verification.json'));
|
|
994
|
-
|
|
995
|
-
// Count incomplete todos
|
|
996
|
-
const incompleteCount = countIncompleteTodos(todosDir, directory);
|
|
997
|
-
|
|
998
|
-
// Priority 1: Ralph Loop with Oracle Verification
|
|
999
|
-
if (ralphState?.active) {
|
|
1000
|
-
const iteration = ralphState.iteration || 1;
|
|
1001
|
-
const maxIter = ralphState.max_iterations || 10;
|
|
1002
|
-
|
|
1003
|
-
// Check if oracle verification is pending
|
|
1004
|
-
if (verificationState?.pending) {
|
|
1005
|
-
const attempt = (verificationState.verification_attempts || 0) + 1;
|
|
1006
|
-
const maxAttempts = verificationState.max_verification_attempts || 3;
|
|
1007
|
-
|
|
1008
|
-
console.log(JSON.stringify({
|
|
1009
|
-
continue: false,
|
|
1010
|
-
reason: \`<ralph-verification>
|
|
1011
|
-
|
|
1012
|
-
[ORACLE VERIFICATION REQUIRED - Attempt \${attempt}/\${maxAttempts}]
|
|
1013
|
-
|
|
1014
|
-
The agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.
|
|
1015
|
-
|
|
1016
|
-
**Original Task:**
|
|
1017
|
-
\${verificationState.original_task || ralphState.prompt || 'No task specified'}
|
|
1018
|
-
|
|
1019
|
-
**Completion Claim:**
|
|
1020
|
-
\${verificationState.completion_claim || 'Task marked complete'}
|
|
1021
|
-
|
|
1022
|
-
\${verificationState.oracle_feedback ? \`**Previous Oracle Feedback (rejected):**
|
|
1023
|
-
\${verificationState.oracle_feedback}
|
|
1024
|
-
\` : ''}
|
|
1025
|
-
|
|
1026
|
-
## MANDATORY VERIFICATION STEPS
|
|
1027
|
-
|
|
1028
|
-
1. **Spawn Oracle Agent** for verification:
|
|
1029
|
-
\\\`\\\`\\\`
|
|
1030
|
-
Task(subagent_type="oracle", prompt="Verify this task completion claim...")
|
|
1031
|
-
\\\`\\\`\\\`
|
|
1032
|
-
|
|
1033
|
-
2. **Oracle must check:**
|
|
1034
|
-
- Are ALL requirements from the original task met?
|
|
1035
|
-
- Is the implementation complete, not partial?
|
|
1036
|
-
- Are there any obvious bugs or issues?
|
|
1037
|
-
- Does the code compile/run without errors?
|
|
1038
|
-
- Are tests passing (if applicable)?
|
|
1039
|
-
|
|
1040
|
-
3. **Based on Oracle's response:**
|
|
1041
|
-
- If APPROVED: Output \\\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\\`
|
|
1042
|
-
- If REJECTED: Continue working on the identified issues
|
|
1043
|
-
|
|
1044
|
-
DO NOT output the completion promise again until Oracle approves.
|
|
1045
|
-
|
|
1046
|
-
</ralph-verification>
|
|
1047
|
-
|
|
1048
|
-
---
|
|
1049
|
-
\`
|
|
1050
|
-
}));
|
|
1051
|
-
return;
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
if (iteration < maxIter) {
|
|
1055
|
-
const newIter = iteration + 1;
|
|
1056
|
-
ralphState.iteration = newIter;
|
|
1057
|
-
writeJsonFile(join(directory, '.sisyphus', 'ralph-state.json'), ralphState);
|
|
1058
|
-
|
|
1059
|
-
console.log(JSON.stringify({
|
|
1060
|
-
continue: false,
|
|
1061
|
-
reason: \`<ralph-loop-continuation>
|
|
1062
|
-
|
|
1063
|
-
[RALPH LOOP - ITERATION \${newIter}/\${maxIter}]
|
|
1064
|
-
|
|
1065
|
-
Your previous attempt did not output the completion promise. The work is NOT done yet.
|
|
1066
|
-
|
|
1067
|
-
CRITICAL INSTRUCTIONS:
|
|
1068
|
-
1. Review your progress and the original task
|
|
1069
|
-
2. Check your todo list - are ALL items marked complete?
|
|
1070
|
-
3. Continue from where you left off
|
|
1071
|
-
4. When FULLY complete, output: <promise>\${ralphState.completion_promise || 'TASK_COMPLETE'}</promise>
|
|
1072
|
-
5. Do NOT stop until the task is truly done
|
|
1073
|
-
|
|
1074
|
-
\${ralphState.prompt ? \`Original task: \${ralphState.prompt}\` : ''}
|
|
1075
|
-
|
|
1076
|
-
</ralph-loop-continuation>
|
|
1077
|
-
|
|
1078
|
-
---
|
|
1079
|
-
\`
|
|
1080
|
-
}));
|
|
1081
|
-
return;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
// Priority 2: Ultrawork with incomplete todos
|
|
1086
|
-
if (ultraworkState?.active && incompleteCount > 0) {
|
|
1087
|
-
const newCount = (ultraworkState.reinforcement_count || 0) + 1;
|
|
1088
|
-
ultraworkState.reinforcement_count = newCount;
|
|
1089
|
-
ultraworkState.last_checked_at = new Date().toISOString();
|
|
1090
|
-
|
|
1091
|
-
writeJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'), ultraworkState);
|
|
1092
|
-
|
|
1093
|
-
console.log(JSON.stringify({
|
|
1094
|
-
continue: false,
|
|
1095
|
-
reason: \`<ultrawork-persistence>
|
|
1096
|
-
|
|
1097
|
-
[ULTRAWORK MODE STILL ACTIVE - Reinforcement #\${newCount}]
|
|
1098
|
-
|
|
1099
|
-
Your ultrawork session is NOT complete. \${incompleteCount} incomplete todos remain.
|
|
1100
|
-
|
|
1101
|
-
REMEMBER THE ULTRAWORK RULES:
|
|
1102
|
-
- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially
|
|
1103
|
-
- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)
|
|
1104
|
-
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each
|
|
1105
|
-
- **VERIFY**: Check ALL requirements met before done
|
|
1106
|
-
- **NO Premature Stopping**: ALL TODOs must be complete
|
|
1107
|
-
|
|
1108
|
-
Continue working on the next pending task. DO NOT STOP until all tasks are marked complete.
|
|
1109
|
-
|
|
1110
|
-
\${ultraworkState.original_prompt ? \`Original task: \${ultraworkState.original_prompt}\` : ''}
|
|
1111
|
-
|
|
1112
|
-
</ultrawork-persistence>
|
|
1113
|
-
|
|
1114
|
-
---
|
|
1115
|
-
\`
|
|
1116
|
-
}));
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
// Priority 3: Todo Continuation
|
|
1121
|
-
if (incompleteCount > 0) {
|
|
1122
|
-
console.log(JSON.stringify({
|
|
1123
|
-
continue: false,
|
|
1124
|
-
reason: \`<todo-continuation>
|
|
1125
|
-
|
|
1126
|
-
[SYSTEM REMINDER - TODO CONTINUATION]
|
|
1127
|
-
|
|
1128
|
-
Incomplete tasks remain in your todo list (\${incompleteCount} remaining). Continue working on the next pending task.
|
|
1129
|
-
|
|
1130
|
-
- Proceed without asking for permission
|
|
1131
|
-
- Mark each task complete when finished
|
|
1132
|
-
- Do not stop until all tasks are done
|
|
1133
|
-
|
|
1134
|
-
</todo-continuation>
|
|
1135
|
-
|
|
1136
|
-
---
|
|
1137
|
-
\`
|
|
1138
|
-
}));
|
|
1139
|
-
return;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
// No blocking needed
|
|
1143
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1144
|
-
} catch (error) {
|
|
1145
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
main();
|
|
1150
|
-
`;
|
|
1151
|
-
/**
|
|
1152
|
-
* Node.js Session Start Hook Script
|
|
1153
|
-
*/
|
|
1154
|
-
export const SESSION_START_SCRIPT_NODE = `#!/usr/bin/env node
|
|
1155
|
-
// Sisyphus Session Start Hook (Node.js)
|
|
1156
|
-
// Restores persistent mode states when session starts
|
|
1157
|
-
// Cross-platform: Windows, macOS, Linux
|
|
1158
|
-
|
|
1159
|
-
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
1160
|
-
import { join } from 'path';
|
|
1161
|
-
import { homedir } from 'os';
|
|
1162
|
-
|
|
1163
|
-
async function readStdin() {
|
|
1164
|
-
const chunks = [];
|
|
1165
|
-
for await (const chunk of process.stdin) {
|
|
1166
|
-
chunks.push(chunk);
|
|
1167
|
-
}
|
|
1168
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
function readJsonFile(path) {
|
|
1172
|
-
try {
|
|
1173
|
-
if (!existsSync(path)) return null;
|
|
1174
|
-
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
1175
|
-
} catch {
|
|
1176
|
-
return null;
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
function countIncompleteTodos(todosDir) {
|
|
1181
|
-
let count = 0;
|
|
1182
|
-
if (existsSync(todosDir)) {
|
|
1183
|
-
try {
|
|
1184
|
-
const files = readdirSync(todosDir).filter(f => f.endsWith('.json'));
|
|
1185
|
-
for (const file of files) {
|
|
1186
|
-
const todos = readJsonFile(join(todosDir, file));
|
|
1187
|
-
if (Array.isArray(todos)) {
|
|
1188
|
-
count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
} catch {}
|
|
1192
|
-
}
|
|
1193
|
-
return count;
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
async function main() {
|
|
1197
|
-
try {
|
|
1198
|
-
const input = await readStdin();
|
|
1199
|
-
let data = {};
|
|
1200
|
-
try { data = JSON.parse(input); } catch {}
|
|
1201
|
-
|
|
1202
|
-
const directory = data.directory || process.cwd();
|
|
1203
|
-
const messages = [];
|
|
1204
|
-
|
|
1205
|
-
// Check for ultrawork state
|
|
1206
|
-
const ultraworkState = readJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'))
|
|
1207
|
-
|| readJsonFile(join(homedir(), '.claude', 'ultrawork-state.json'));
|
|
1208
|
-
|
|
1209
|
-
if (ultraworkState?.active) {
|
|
1210
|
-
messages.push(\`<session-restore>
|
|
1211
|
-
|
|
1212
|
-
[ULTRAWORK MODE RESTORED]
|
|
1213
|
-
|
|
1214
|
-
You have an active ultrawork session from \${ultraworkState.started_at}.
|
|
1215
|
-
Original task: \${ultraworkState.original_prompt}
|
|
1216
|
-
|
|
1217
|
-
Continue working in ultrawork mode until all tasks are complete.
|
|
1218
|
-
|
|
1219
|
-
</session-restore>
|
|
1220
|
-
|
|
1221
|
-
---
|
|
1222
|
-
\`);
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
// Check for incomplete todos
|
|
1226
|
-
const todosDir = join(homedir(), '.claude', 'todos');
|
|
1227
|
-
const incompleteCount = countIncompleteTodos(todosDir);
|
|
1228
|
-
|
|
1229
|
-
if (incompleteCount > 0) {
|
|
1230
|
-
messages.push(\`<session-restore>
|
|
1231
|
-
|
|
1232
|
-
[PENDING TASKS DETECTED]
|
|
1233
|
-
|
|
1234
|
-
You have \${incompleteCount} incomplete tasks from a previous session.
|
|
1235
|
-
Please continue working on these tasks.
|
|
1236
|
-
|
|
1237
|
-
</session-restore>
|
|
1238
|
-
|
|
1239
|
-
---
|
|
1240
|
-
\`);
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
if (messages.length > 0) {
|
|
1244
|
-
console.log(JSON.stringify({ continue: true, message: messages.join('\\n') }));
|
|
1245
|
-
} else {
|
|
1246
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1247
|
-
}
|
|
1248
|
-
} catch (error) {
|
|
1249
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
main();
|
|
1254
|
-
`;
|
|
261
|
+
/** Persistent mode Bash script - loaded from templates/hooks/persistent-mode.sh */
|
|
262
|
+
export const PERSISTENT_MODE_SCRIPT = loadTemplate('persistent-mode.sh');
|
|
263
|
+
/** Session start Bash script - loaded from templates/hooks/session-start.sh */
|
|
264
|
+
export const SESSION_START_SCRIPT = loadTemplate('session-start.sh');
|
|
265
|
+
/** Node.js persistent mode hook script - loaded from templates/hooks/persistent-mode.mjs */
|
|
266
|
+
export const PERSISTENT_MODE_SCRIPT_NODE = loadTemplate('persistent-mode.mjs');
|
|
267
|
+
/** Node.js session start hook script - loaded from templates/hooks/session-start.mjs */
|
|
268
|
+
export const SESSION_START_SCRIPT_NODE = loadTemplate('session-start.mjs');
|
|
1255
269
|
// =============================================================================
|
|
1256
270
|
// POST-TOOL-USE HOOK (Remember Tag Processing)
|
|
1257
271
|
// =============================================================================
|
|
1258
|
-
/**
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
export const POST_TOOL_USE_SCRIPT = `#!/bin/bash
|
|
1263
|
-
# Sisyphus Post-Tool-Use Hook
|
|
1264
|
-
# Processes <remember> tags from Task agent output
|
|
1265
|
-
# Saves to .sisyphus/notepad.md for compaction-resilient memory
|
|
1266
|
-
|
|
1267
|
-
# Read stdin
|
|
1268
|
-
INPUT=$(cat)
|
|
1269
|
-
|
|
1270
|
-
# Get directory and tool info
|
|
1271
|
-
DIRECTORY=""
|
|
1272
|
-
TOOL_NAME=""
|
|
1273
|
-
TOOL_OUTPUT=""
|
|
1274
|
-
if command -v jq &> /dev/null; then
|
|
1275
|
-
DIRECTORY=$(echo "$INPUT" | jq -r '.directory // ""' 2>/dev/null)
|
|
1276
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName // ""' 2>/dev/null)
|
|
1277
|
-
TOOL_OUTPUT=$(echo "$INPUT" | jq -r '.toolOutput // ""' 2>/dev/null)
|
|
1278
|
-
else
|
|
1279
|
-
# Fallback: use grep/sed for extraction
|
|
1280
|
-
DIRECTORY=$(echo "$INPUT" | grep -oP '"directory"\\s*:\\s*"\\K[^"]+' | head -1)
|
|
1281
|
-
TOOL_NAME=$(echo "$INPUT" | grep -oP '"toolName"\\s*:\\s*"\\K[^"]+' | head -1)
|
|
1282
|
-
TOOL_OUTPUT=$(echo "$INPUT" | grep -oP '"toolOutput"\\s*:\\s*"\\K[^"]+' | head -1)
|
|
1283
|
-
fi
|
|
1284
|
-
|
|
1285
|
-
if [ -z "$DIRECTORY" ]; then
|
|
1286
|
-
DIRECTORY=$(pwd)
|
|
1287
|
-
fi
|
|
1288
|
-
|
|
1289
|
-
# Only process Task tool output
|
|
1290
|
-
if [ "$TOOL_NAME" != "Task" ] && [ "$TOOL_NAME" != "task" ]; then
|
|
1291
|
-
echo '{"continue": true}'
|
|
1292
|
-
exit 0
|
|
1293
|
-
fi
|
|
1294
|
-
|
|
1295
|
-
# Check for <remember> tags
|
|
1296
|
-
if ! echo "$TOOL_OUTPUT" | grep -q '<remember'; then
|
|
1297
|
-
echo '{"continue": true}'
|
|
1298
|
-
exit 0
|
|
1299
|
-
fi
|
|
1300
|
-
|
|
1301
|
-
# Create .sisyphus directory if needed
|
|
1302
|
-
SISYPHUS_DIR="$DIRECTORY/.sisyphus"
|
|
1303
|
-
NOTEPAD_FILE="$SISYPHUS_DIR/notepad.md"
|
|
1304
|
-
mkdir -p "$SISYPHUS_DIR" 2>/dev/null
|
|
1305
|
-
|
|
1306
|
-
# Initialize notepad.md if it doesn't exist
|
|
1307
|
-
if [ ! -f "$NOTEPAD_FILE" ]; then
|
|
1308
|
-
cat > "$NOTEPAD_FILE" << 'NOTEPAD_INIT'
|
|
1309
|
-
# Notepad
|
|
1310
|
-
<!-- Auto-managed by Sisyphus. Manual edits preserved in MANUAL section. -->
|
|
1311
|
-
|
|
1312
|
-
## Priority Context
|
|
1313
|
-
<!-- ALWAYS loaded. Keep under 500 chars. Critical discoveries only. -->
|
|
1314
|
-
|
|
1315
|
-
## Working Memory
|
|
1316
|
-
<!-- Session notes. Auto-pruned after 7 days. -->
|
|
1317
|
-
|
|
1318
|
-
## MANUAL
|
|
1319
|
-
<!-- User content. Never auto-pruned. -->
|
|
1320
|
-
NOTEPAD_INIT
|
|
1321
|
-
fi
|
|
1322
|
-
|
|
1323
|
-
# Process priority remember tags
|
|
1324
|
-
PRIORITY_CONTENT=$(echo "$TOOL_OUTPUT" | grep -oP '<remember\\s+priority>\\K[\\s\\S]*?(?=</remember>)' | head -1)
|
|
1325
|
-
if [ -n "$PRIORITY_CONTENT" ]; then
|
|
1326
|
-
# Read current notepad
|
|
1327
|
-
NOTEPAD_CONTENT=$(cat "$NOTEPAD_FILE")
|
|
1328
|
-
# Replace Priority Context section
|
|
1329
|
-
NEW_NOTEPAD=$(echo "$NOTEPAD_CONTENT" | sed '/## Priority Context/,/## Working Memory/{
|
|
1330
|
-
/## Priority Context/!{/## Working Memory/!d}
|
|
1331
|
-
}' | sed "/## Priority Context/a\\\\<!-- ALWAYS loaded. Keep under 500 chars. Critical discoveries only. -->\\n$PRIORITY_CONTENT")
|
|
1332
|
-
echo "$NEW_NOTEPAD" > "$NOTEPAD_FILE"
|
|
1333
|
-
fi
|
|
1334
|
-
|
|
1335
|
-
# Process regular remember tags
|
|
1336
|
-
while IFS= read -r CONTENT; do
|
|
1337
|
-
if [ -n "$CONTENT" ]; then
|
|
1338
|
-
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
|
|
1339
|
-
# Append to Working Memory section (before MANUAL)
|
|
1340
|
-
sed -i "/## MANUAL/i\\\\### $TIMESTAMP\\n$CONTENT\\n" "$NOTEPAD_FILE" 2>/dev/null || {
|
|
1341
|
-
# macOS sed fallback
|
|
1342
|
-
sed -i '' "/## MANUAL/i\\\\
|
|
1343
|
-
### $TIMESTAMP\\
|
|
1344
|
-
$CONTENT\\
|
|
1345
|
-
" "$NOTEPAD_FILE"
|
|
1346
|
-
}
|
|
1347
|
-
fi
|
|
1348
|
-
done < <(echo "$TOOL_OUTPUT" | grep -oP '<remember>\\K[\\s\\S]*?(?=</remember>)')
|
|
1349
|
-
|
|
1350
|
-
echo '{"continue": true}'
|
|
1351
|
-
exit 0
|
|
1352
|
-
`;
|
|
1353
|
-
/**
|
|
1354
|
-
* Post-Tool-Use Node.js script
|
|
1355
|
-
* Processes <remember> tags from Task agent output
|
|
1356
|
-
*/
|
|
1357
|
-
export const POST_TOOL_USE_SCRIPT_NODE = `#!/usr/bin/env node
|
|
1358
|
-
// Sisyphus Post-Tool-Use Hook (Node.js)
|
|
1359
|
-
// Processes <remember> tags from Task agent output
|
|
1360
|
-
// Saves to .sisyphus/notepad.md for compaction-resilient memory
|
|
1361
|
-
|
|
1362
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
1363
|
-
import { join } from 'path';
|
|
1364
|
-
|
|
1365
|
-
// Constants
|
|
1366
|
-
const NOTEPAD_TEMPLATE = '# Notepad\\n' +
|
|
1367
|
-
'<!-- Auto-managed by Sisyphus. Manual edits preserved in MANUAL section. -->\\n\\n' +
|
|
1368
|
-
'## Priority Context\\n' +
|
|
1369
|
-
'<!-- ALWAYS loaded. Keep under 500 chars. Critical discoveries only. -->\\n\\n' +
|
|
1370
|
-
'## Working Memory\\n' +
|
|
1371
|
-
'<!-- Session notes. Auto-pruned after 7 days. -->\\n\\n' +
|
|
1372
|
-
'## MANUAL\\n' +
|
|
1373
|
-
'<!-- User content. Never auto-pruned. -->\\n';
|
|
1374
|
-
|
|
1375
|
-
// Read all stdin
|
|
1376
|
-
async function readStdin() {
|
|
1377
|
-
const chunks = [];
|
|
1378
|
-
for await (const chunk of process.stdin) {
|
|
1379
|
-
chunks.push(chunk);
|
|
1380
|
-
}
|
|
1381
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
// Initialize notepad.md if needed
|
|
1385
|
-
function initNotepad(directory) {
|
|
1386
|
-
const sisyphusDir = join(directory, '.sisyphus');
|
|
1387
|
-
const notepadPath = join(sisyphusDir, 'notepad.md');
|
|
1388
|
-
|
|
1389
|
-
if (!existsSync(sisyphusDir)) {
|
|
1390
|
-
try { mkdirSync(sisyphusDir, { recursive: true }); } catch {}
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
if (!existsSync(notepadPath)) {
|
|
1394
|
-
try { writeFileSync(notepadPath, NOTEPAD_TEMPLATE); } catch {}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
return notepadPath;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
// Set priority context
|
|
1401
|
-
function setPriorityContext(notepadPath, content) {
|
|
1402
|
-
try {
|
|
1403
|
-
let notepad = readFileSync(notepadPath, 'utf-8');
|
|
1404
|
-
|
|
1405
|
-
// Find and replace Priority Context section
|
|
1406
|
-
const priorityMatch = notepad.match(/## Priority Context[\\s\\S]*?(?=## Working Memory)/);
|
|
1407
|
-
if (priorityMatch) {
|
|
1408
|
-
const newPriority = '## Priority Context\\n' +
|
|
1409
|
-
'<!-- ALWAYS loaded. Keep under 500 chars. Critical discoveries only. -->\\n' +
|
|
1410
|
-
content.trim() + '\\n\\n';
|
|
1411
|
-
notepad = notepad.replace(priorityMatch[0], newPriority);
|
|
1412
|
-
writeFileSync(notepadPath, notepad);
|
|
1413
|
-
}
|
|
1414
|
-
} catch {}
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
// Add working memory entry
|
|
1418
|
-
function addWorkingMemoryEntry(notepadPath, content) {
|
|
1419
|
-
try {
|
|
1420
|
-
let notepad = readFileSync(notepadPath, 'utf-8');
|
|
1421
|
-
|
|
1422
|
-
const timestamp = new Date().toISOString().slice(0, 16).replace('T', ' ');
|
|
1423
|
-
const entry = '### ' + timestamp + '\\n' + content.trim() + '\\n\\n';
|
|
1424
|
-
|
|
1425
|
-
// Insert before MANUAL section
|
|
1426
|
-
const manualIndex = notepad.indexOf('## MANUAL');
|
|
1427
|
-
if (manualIndex !== -1) {
|
|
1428
|
-
notepad = notepad.slice(0, manualIndex) + entry + notepad.slice(manualIndex);
|
|
1429
|
-
writeFileSync(notepadPath, notepad);
|
|
1430
|
-
}
|
|
1431
|
-
} catch {}
|
|
1432
|
-
}
|
|
1433
|
-
|
|
1434
|
-
// Process remember tags
|
|
1435
|
-
function processRememberTags(output, notepadPath) {
|
|
1436
|
-
if (!output) return;
|
|
1437
|
-
|
|
1438
|
-
// Process priority remember tags
|
|
1439
|
-
const priorityRegex = /<remember\\s+priority>([\\s\\S]*?)<\\/remember>/gi;
|
|
1440
|
-
let match;
|
|
1441
|
-
while ((match = priorityRegex.exec(output)) !== null) {
|
|
1442
|
-
const content = match[1].trim();
|
|
1443
|
-
if (content) {
|
|
1444
|
-
setPriorityContext(notepadPath, content);
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
// Process regular remember tags
|
|
1449
|
-
const regularRegex = /<remember>([\\s\\S]*?)<\\/remember>/gi;
|
|
1450
|
-
while ((match = regularRegex.exec(output)) !== null) {
|
|
1451
|
-
const content = match[1].trim();
|
|
1452
|
-
if (content) {
|
|
1453
|
-
addWorkingMemoryEntry(notepadPath, content);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
async function main() {
|
|
1459
|
-
try {
|
|
1460
|
-
const input = await readStdin();
|
|
1461
|
-
const data = JSON.parse(input);
|
|
1462
|
-
|
|
1463
|
-
const toolName = data.toolName || '';
|
|
1464
|
-
const toolOutput = data.toolOutput || '';
|
|
1465
|
-
const directory = data.directory || process.cwd();
|
|
1466
|
-
|
|
1467
|
-
// Only process Task tool output
|
|
1468
|
-
if (toolName !== 'Task' && toolName !== 'task') {
|
|
1469
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1470
|
-
return;
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
// Check for remember tags
|
|
1474
|
-
if (!toolOutput.includes('<remember')) {
|
|
1475
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1476
|
-
return;
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
// Initialize notepad and process tags
|
|
1480
|
-
const notepadPath = initNotepad(directory);
|
|
1481
|
-
processRememberTags(toolOutput, notepadPath);
|
|
1482
|
-
|
|
1483
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1484
|
-
} catch (error) {
|
|
1485
|
-
console.log(JSON.stringify({ continue: true }));
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
main();
|
|
1490
|
-
`;
|
|
272
|
+
/** Post-tool-use Bash script - loaded from templates/hooks/post-tool-use.sh */
|
|
273
|
+
export const POST_TOOL_USE_SCRIPT = loadTemplate('post-tool-use.sh');
|
|
274
|
+
/** Post-tool-use Node.js script - loaded from templates/hooks/post-tool-use.mjs */
|
|
275
|
+
export const POST_TOOL_USE_SCRIPT_NODE = loadTemplate('post-tool-use.mjs');
|
|
1491
276
|
// =============================================================================
|
|
1492
277
|
// SETTINGS CONFIGURATION (Platform-aware)
|
|
1493
278
|
// =============================================================================
|
|
@@ -1612,34 +397,42 @@ export const HOOKS_SETTINGS_CONFIG = HOOKS_SETTINGS_CONFIG_BASH;
|
|
|
1612
397
|
// HOOK SCRIPTS EXPORTS (Platform-aware)
|
|
1613
398
|
// =============================================================================
|
|
1614
399
|
/**
|
|
1615
|
-
* Bash hook scripts (Unix only)
|
|
400
|
+
* Get Bash hook scripts (Unix only)
|
|
401
|
+
* Returns a record of filename -> content for all bash hooks
|
|
1616
402
|
*/
|
|
1617
|
-
export
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
403
|
+
export function getHookScriptsBash() {
|
|
404
|
+
return {
|
|
405
|
+
'keyword-detector.sh': loadTemplate('keyword-detector.sh'),
|
|
406
|
+
'stop-continuation.sh': loadTemplate('stop-continuation.sh'),
|
|
407
|
+
'persistent-mode.sh': loadTemplate('persistent-mode.sh'),
|
|
408
|
+
'session-start.sh': loadTemplate('session-start.sh'),
|
|
409
|
+
'post-tool-use.sh': loadTemplate('post-tool-use.sh')
|
|
410
|
+
};
|
|
411
|
+
}
|
|
1624
412
|
/**
|
|
1625
|
-
* Node.js hook scripts (Cross-platform)
|
|
413
|
+
* Get Node.js hook scripts (Cross-platform)
|
|
414
|
+
* Returns a record of filename -> content for all Node.js hooks
|
|
1626
415
|
*/
|
|
1627
|
-
export
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
416
|
+
export function getHookScriptsNode() {
|
|
417
|
+
return {
|
|
418
|
+
'keyword-detector.mjs': loadTemplate('keyword-detector.mjs'),
|
|
419
|
+
'stop-continuation.mjs': loadTemplate('stop-continuation.mjs'),
|
|
420
|
+
'persistent-mode.mjs': loadTemplate('persistent-mode.mjs'),
|
|
421
|
+
'session-start.mjs': loadTemplate('session-start.mjs'),
|
|
422
|
+
'post-tool-use.mjs': loadTemplate('post-tool-use.mjs')
|
|
423
|
+
};
|
|
424
|
+
}
|
|
1634
425
|
/**
|
|
1635
426
|
* Get the appropriate hook scripts for the current platform
|
|
1636
427
|
*/
|
|
1637
428
|
export function getHookScripts() {
|
|
1638
|
-
return shouldUseNodeHooks() ?
|
|
429
|
+
return shouldUseNodeHooks() ? getHookScriptsNode() : getHookScriptsBash();
|
|
1639
430
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
*/
|
|
431
|
+
// Legacy exports for backward compatibility (these call the loader functions)
|
|
432
|
+
/** @deprecated Use getHookScriptsBash() instead */
|
|
433
|
+
export const HOOK_SCRIPTS_BASH = getHookScriptsBash();
|
|
434
|
+
/** @deprecated Use getHookScriptsNode() instead */
|
|
435
|
+
export const HOOK_SCRIPTS_NODE = getHookScriptsNode();
|
|
436
|
+
/** @deprecated Use getHookScripts() for cross-platform support */
|
|
1644
437
|
export const HOOK_SCRIPTS = HOOK_SCRIPTS_BASH;
|
|
1645
438
|
//# sourceMappingURL=hooks.js.map
|