oh-my-claude-sisyphus 3.8.15 → 3.9.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/README.md +9 -11
- package/agents/analyst.md +41 -0
- package/agents/architect.md +45 -0
- package/agents/critic.md +42 -0
- package/agents/deep-executor.md +193 -0
- package/agents/planner.md +82 -0
- package/bridge/mcp-server.cjs +1 -1
- package/commands/autopilot.md +2 -6
- package/commands/hud.md +7 -2
- package/commands/ralph.md +3 -3
- package/commands/ultrapilot.md +2 -6
- package/dist/__tests__/agent-registry.test.js +1 -1
- package/dist/__tests__/delegation-enforcement-levels.test.js +0 -1
- package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -1
- package/dist/__tests__/hooks/learner/parser.test.d.ts +5 -0
- package/dist/__tests__/hooks/learner/parser.test.d.ts.map +1 -0
- package/dist/__tests__/hooks/learner/parser.test.js +201 -0
- package/dist/__tests__/hooks/learner/parser.test.js.map +1 -0
- package/dist/__tests__/hud/cwd.test.d.ts +2 -0
- package/dist/__tests__/hud/cwd.test.d.ts.map +1 -0
- package/dist/__tests__/hud/cwd.test.js +62 -0
- package/dist/__tests__/hud/cwd.test.js.map +1 -0
- package/dist/__tests__/hud/defaults.test.d.ts +2 -0
- package/dist/__tests__/hud/defaults.test.d.ts.map +1 -0
- package/dist/__tests__/hud/defaults.test.js +21 -0
- package/dist/__tests__/hud/defaults.test.js.map +1 -0
- package/dist/__tests__/hud/render.test.d.ts +2 -0
- package/dist/__tests__/hud/render.test.d.ts.map +1 -0
- package/dist/__tests__/hud/render.test.js +141 -0
- package/dist/__tests__/hud/render.test.js.map +1 -0
- package/dist/__tests__/hud/thinking.test.d.ts +2 -0
- package/dist/__tests__/hud/thinking.test.d.ts.map +1 -0
- package/dist/__tests__/hud/thinking.test.js +32 -0
- package/dist/__tests__/hud/thinking.test.js.map +1 -0
- package/dist/__tests__/installer.test.js +8 -8
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/__tests__/mnemosyne/parser.test.js +1 -1
- package/dist/__tests__/mnemosyne/parser.test.js.map +1 -1
- package/dist/__tests__/omc-tools-server.test.js +2 -2
- package/dist/__tests__/omc-tools-server.test.js.map +1 -1
- package/dist/__tests__/skills.test.js +5 -4
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/agents/deep-executor.d.ts +15 -0
- package/dist/agents/deep-executor.d.ts.map +1 -0
- package/dist/agents/deep-executor.js +47 -0
- package/dist/agents/deep-executor.js.map +1 -0
- package/dist/agents/definitions.d.ts +15 -0
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +25 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/cli/commands/doctor-conflicts.d.ts +55 -0
- package/dist/cli/commands/doctor-conflicts.d.ts.map +1 -0
- package/dist/cli/commands/doctor-conflicts.js +261 -0
- package/dist/cli/commands/doctor-conflicts.js.map +1 -0
- package/dist/cli/index.js +16 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/features/auto-update.d.ts +12 -0
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +4 -1
- package/dist/features/auto-update.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/continuation-enforcement.js +1 -1
- package/dist/features/state-manager/index.d.ts.map +1 -1
- package/dist/features/state-manager/index.js +7 -4
- package/dist/features/state-manager/index.js.map +1 -1
- package/dist/features/verification/example.d.ts.map +1 -1
- package/dist/features/verification/example.js +4 -2
- package/dist/features/verification/example.js.map +1 -1
- package/dist/hooks/__tests__/bridge.test.d.ts +2 -0
- package/dist/hooks/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/bridge.test.js +199 -0
- package/dist/hooks/__tests__/bridge.test.js.map +1 -0
- package/dist/hooks/beads-context/__tests__/index.test.d.ts +2 -0
- package/dist/hooks/beads-context/__tests__/index.test.d.ts.map +1 -0
- package/dist/hooks/beads-context/__tests__/index.test.js +150 -0
- package/dist/hooks/beads-context/__tests__/index.test.js.map +1 -0
- package/dist/hooks/beads-context/constants.d.ts +3 -0
- package/dist/hooks/beads-context/constants.d.ts.map +1 -0
- package/dist/hooks/beads-context/constants.js +35 -0
- package/dist/hooks/beads-context/constants.js.map +1 -0
- package/dist/hooks/beads-context/index.d.ts +21 -0
- package/dist/hooks/beads-context/index.d.ts.map +1 -0
- package/dist/hooks/beads-context/index.js +62 -0
- package/dist/hooks/beads-context/index.js.map +1 -0
- package/dist/hooks/beads-context/types.d.ts +7 -0
- package/dist/hooks/beads-context/types.d.ts.map +1 -0
- package/dist/hooks/beads-context/types.js +2 -0
- package/dist/hooks/beads-context/types.js.map +1 -0
- package/dist/hooks/bridge.d.ts +4 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +80 -47
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/learner/parser.d.ts.map +1 -1
- package/dist/hooks/learner/parser.js +12 -5
- package/dist/hooks/learner/parser.js.map +1 -1
- package/dist/hooks/mode-registry/index.d.ts +2 -0
- package/dist/hooks/mode-registry/index.d.ts.map +1 -1
- package/dist/hooks/mode-registry/index.js +8 -19
- package/dist/hooks/mode-registry/index.js.map +1 -1
- package/dist/hooks/permission-handler/index.d.ts.map +1 -1
- package/dist/hooks/permission-handler/index.js +3 -1
- package/dist/hooks/permission-handler/index.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts +1 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +5 -33
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/ralph/index.d.ts +1 -1
- package/dist/hooks/ralph/index.d.ts.map +1 -1
- package/dist/hooks/ralph/index.js +1 -1
- package/dist/hooks/ralph/index.js.map +1 -1
- package/dist/hooks/ralph/loop.d.ts +1 -9
- package/dist/hooks/ralph/loop.d.ts.map +1 -1
- package/dist/hooks/ralph/loop.js +1 -37
- package/dist/hooks/ralph/loop.js.map +1 -1
- package/dist/hooks/ralph/prd.js +1 -1
- package/dist/hooks/ralph/verifier.d.ts +4 -5
- package/dist/hooks/ralph/verifier.d.ts.map +1 -1
- package/dist/hooks/ralph/verifier.js +7 -10
- package/dist/hooks/ralph/verifier.js.map +1 -1
- package/dist/hooks/session-end/index.d.ts +13 -0
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +69 -0
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/setup/index.d.ts.map +1 -1
- package/dist/hooks/setup/index.js +12 -5
- package/dist/hooks/setup/index.js.map +1 -1
- package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +25 -9
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/hooks/ultrawork/index.d.ts +2 -2
- package/dist/hooks/ultrawork/index.d.ts.map +1 -1
- package/dist/hooks/ultrawork/index.js +2 -46
- package/dist/hooks/ultrawork/index.js.map +1 -1
- package/dist/hud/elements/cwd.d.ts +15 -0
- package/dist/hud/elements/cwd.d.ts.map +1 -0
- package/dist/hud/elements/cwd.js +39 -0
- package/dist/hud/elements/cwd.js.map +1 -0
- package/dist/hud/elements/index.d.ts +1 -0
- package/dist/hud/elements/index.d.ts.map +1 -1
- package/dist/hud/elements/index.js +1 -0
- package/dist/hud/elements/index.js.map +1 -1
- package/dist/hud/elements/thinking.d.ts +7 -5
- package/dist/hud/elements/thinking.d.ts.map +1 -1
- package/dist/hud/elements/thinking.js +18 -6
- package/dist/hud/elements/thinking.js.map +1 -1
- package/dist/hud/index.js +5 -3
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/omc-state.d.ts +1 -1
- package/dist/hud/omc-state.d.ts.map +1 -1
- package/dist/hud/omc-state.js +14 -31
- package/dist/hud/omc-state.js.map +1 -1
- package/dist/hud/render.d.ts +9 -0
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +27 -7
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +2 -2
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +4 -33
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/transcript.d.ts +4 -1
- package/dist/hud/transcript.d.ts.map +1 -1
- package/dist/hud/transcript.js +4 -9
- package/dist/hud/transcript.js.map +1 -1
- package/dist/hud/types.d.ts +20 -1
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +38 -9
- package/dist/hud/types.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer/__tests__/claude-md-merge.test.d.ts +6 -0
- package/dist/installer/__tests__/claude-md-merge.test.d.ts.map +1 -0
- package/dist/installer/__tests__/claude-md-merge.test.js +220 -0
- package/dist/installer/__tests__/claude-md-merge.test.js.map +1 -0
- package/dist/installer/__tests__/safe-installer.test.d.ts +6 -0
- package/dist/installer/__tests__/safe-installer.test.d.ts.map +1 -0
- package/dist/installer/__tests__/safe-installer.test.js +172 -0
- package/dist/installer/__tests__/safe-installer.test.js.map +1 -0
- package/dist/installer/hooks.d.ts +1 -1
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +4 -2
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +27 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +209 -85
- package/dist/installer/index.js.map +1 -1
- package/dist/mcp/omc-tools-server.d.ts +1 -1
- package/dist/mcp/omc-tools-server.d.ts.map +1 -1
- package/dist/mcp/omc-tools-server.js +3 -3
- package/dist/mcp/omc-tools-server.js.map +1 -1
- package/dist/mcp/standalone-server.js +1 -1
- package/dist/mcp/standalone-server.js.map +1 -1
- package/dist/verification/tier-selector.d.ts +40 -0
- package/dist/verification/tier-selector.d.ts.map +1 -0
- package/dist/verification/tier-selector.js +95 -0
- package/dist/verification/tier-selector.js.map +1 -0
- package/dist/verification/tier-selector.test.d.ts +2 -0
- package/dist/verification/tier-selector.test.d.ts.map +1 -0
- package/dist/verification/tier-selector.test.js +282 -0
- package/dist/verification/tier-selector.test.js.map +1 -0
- package/docs/AGENTS.md +100 -0
- package/docs/ARCHITECTURE.md +11 -7
- package/docs/CLAUDE.md +89 -379
- package/docs/DELEGATION-ENFORCER.md +1 -2
- package/docs/MIGRATION.md +1 -1
- package/docs/REFERENCE.md +29 -9
- package/docs/SYNC-SYSTEM.md +0 -2
- package/docs/partials/agent-tiers.md +165 -0
- package/docs/partials/features.md +131 -0
- package/docs/partials/mode-hierarchy.md +120 -0
- package/docs/partials/mode-selection-guide.md +82 -0
- package/docs/partials/verification-tiers.md +107 -0
- package/docs/shared/agent-tiers.md +165 -0
- package/docs/shared/features.md +131 -0
- package/docs/shared/mode-hierarchy.md +120 -0
- package/docs/shared/mode-selection-guide.md +82 -0
- package/docs/shared/verification-tiers.md +107 -0
- package/package.json +4 -3
- package/scripts/compose-docs.mjs +44 -0
- package/scripts/keyword-detector.mjs +13 -3
- package/scripts/persistent-mode.mjs +78 -47
- package/scripts/test-mutual-exclusion.ts +3 -3
- package/skills/AGENTS.md +59 -44
- package/skills/autopilot/SKILL.md +0 -2
- package/skills/cancel/SKILL.md +13 -32
- package/skills/deep-executor/SKILL.md +50 -0
- package/skills/ecomode/SKILL.md +58 -104
- package/skills/hud/SKILL.md +3 -2
- package/skills/omc-setup/SKILL.md +197 -20
- package/skills/plan/SKILL.md +62 -0
- package/skills/project-session-manager/SKILL.md +87 -4
- package/skills/project-session-manager/lib/config.sh +54 -5
- package/skills/project-session-manager/lib/parse.sh +65 -11
- package/skills/project-session-manager/lib/providers/github.sh +52 -0
- package/skills/project-session-manager/lib/providers/interface.sh +76 -0
- package/skills/project-session-manager/lib/providers/jira.sh +79 -0
- package/skills/project-session-manager/lib/session.sh +49 -12
- package/skills/project-session-manager/lib/worktree.sh +37 -4
- package/skills/project-session-manager/psm.sh +116 -51
- package/skills/ralph/SKILL.md +48 -44
- package/skills/ultrawork/SKILL.md +56 -67
- package/templates/hooks/keyword-detector.mjs +21 -13
- package/templates/hooks/lib/stdin.mjs +62 -0
- package/templates/hooks/persistent-mode.mjs +75 -34
- package/templates/hooks/post-tool-use.mjs +8 -10
- package/templates/hooks/pre-tool-use.mjs +9 -6
- package/templates/hooks/session-start.mjs +7 -8
- package/agents/AGENTS.md +0 -144
|
@@ -9,16 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs';
|
|
12
|
-
import { join } from 'path';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
13
|
import { homedir } from 'os';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
21
|
-
}
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = dirname(__filename);
|
|
18
|
+
|
|
19
|
+
// Dynamic import for the shared stdin module
|
|
20
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
22
21
|
|
|
23
22
|
function readJsonFile(path) {
|
|
24
23
|
try {
|
|
@@ -43,6 +42,31 @@ function writeJsonFile(path, data) {
|
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Staleness threshold for mode states (2 hours in milliseconds).
|
|
47
|
+
* States older than this are treated as inactive to prevent stale state
|
|
48
|
+
* from causing the stop hook to malfunction in new sessions.
|
|
49
|
+
*/
|
|
50
|
+
const STALE_STATE_THRESHOLD_MS = 2 * 60 * 60 * 1000; // 2 hours
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if a state is stale based on its timestamps.
|
|
54
|
+
* A state is considered stale if it hasn't been updated recently.
|
|
55
|
+
* We check both `last_checked_at` and `started_at` - using whichever is more recent.
|
|
56
|
+
*/
|
|
57
|
+
function isStaleState(state) {
|
|
58
|
+
if (!state) return true;
|
|
59
|
+
|
|
60
|
+
const lastChecked = state.last_checked_at ? new Date(state.last_checked_at).getTime() : 0;
|
|
61
|
+
const startedAt = state.started_at ? new Date(state.started_at).getTime() : 0;
|
|
62
|
+
const mostRecent = Math.max(lastChecked, startedAt);
|
|
63
|
+
|
|
64
|
+
if (mostRecent === 0) return true; // No valid timestamps
|
|
65
|
+
|
|
66
|
+
const age = Date.now() - mostRecent;
|
|
67
|
+
return age > STALE_STATE_THRESHOLD_MS;
|
|
68
|
+
}
|
|
69
|
+
|
|
46
70
|
/**
|
|
47
71
|
* Read state file from local or global location, tracking the source.
|
|
48
72
|
*/
|
|
@@ -206,34 +230,37 @@ async function main() {
|
|
|
206
230
|
const totalIncomplete = taskCount + todoCount;
|
|
207
231
|
|
|
208
232
|
// Priority 1: Ralph Loop (explicit persistence mode)
|
|
209
|
-
if (
|
|
233
|
+
// Skip if state is stale (older than 2 hours) - prevents blocking new sessions
|
|
234
|
+
if (ralph.state?.active && !isStaleState(ralph.state)) {
|
|
210
235
|
const iteration = ralph.state.iteration || 1;
|
|
211
236
|
const maxIter = ralph.state.max_iterations || 100;
|
|
212
237
|
|
|
213
238
|
if (iteration < maxIter) {
|
|
214
239
|
ralph.state.iteration = iteration + 1;
|
|
240
|
+
ralph.state.last_checked_at = new Date().toISOString();
|
|
215
241
|
writeJsonFile(ralph.path, ralph.state);
|
|
216
242
|
|
|
217
243
|
console.log(JSON.stringify({
|
|
218
244
|
decision: 'block',
|
|
219
|
-
reason: `[RALPH LOOP - ITERATION ${iteration + 1}/${maxIter}] Work is NOT done. Continue
|
|
245
|
+
reason: `[RALPH LOOP - ITERATION ${iteration + 1}/${maxIter}] Work is NOT done. Continue working.\nWhen FULLY complete (after Architect verification), run /oh-my-claudecode:cancel to cleanly exit ralph mode and clean up all state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.\n${ralph.state.prompt ? `Task: ${ralph.state.prompt}` : ''}`
|
|
220
246
|
}));
|
|
221
247
|
return;
|
|
222
248
|
}
|
|
223
249
|
}
|
|
224
250
|
|
|
225
251
|
// Priority 2: Autopilot (high-level orchestration)
|
|
226
|
-
if (autopilot.state?.active) {
|
|
252
|
+
if (autopilot.state?.active && !isStaleState(autopilot.state)) {
|
|
227
253
|
const phase = autopilot.state.phase || 'unknown';
|
|
228
254
|
if (phase !== 'complete') {
|
|
229
255
|
const newCount = (autopilot.state.reinforcement_count || 0) + 1;
|
|
230
256
|
if (newCount <= 20) {
|
|
231
257
|
autopilot.state.reinforcement_count = newCount;
|
|
258
|
+
autopilot.state.last_checked_at = new Date().toISOString();
|
|
232
259
|
writeJsonFile(autopilot.path, autopilot.state);
|
|
233
260
|
|
|
234
261
|
console.log(JSON.stringify({
|
|
235
262
|
decision: 'block',
|
|
236
|
-
reason: `[AUTOPILOT - Phase: ${phase}] Autopilot not complete. Continue working.`
|
|
263
|
+
reason: `[AUTOPILOT - Phase: ${phase}] Autopilot not complete. Continue working. When all phases are complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`
|
|
237
264
|
}));
|
|
238
265
|
return;
|
|
239
266
|
}
|
|
@@ -241,18 +268,19 @@ async function main() {
|
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
// Priority 3: Ultrapilot (parallel autopilot)
|
|
244
|
-
if (ultrapilot.state?.active) {
|
|
271
|
+
if (ultrapilot.state?.active && !isStaleState(ultrapilot.state)) {
|
|
245
272
|
const workers = ultrapilot.state.workers || [];
|
|
246
273
|
const incomplete = workers.filter(w => w.status !== 'complete' && w.status !== 'failed').length;
|
|
247
274
|
if (incomplete > 0) {
|
|
248
275
|
const newCount = (ultrapilot.state.reinforcement_count || 0) + 1;
|
|
249
276
|
if (newCount <= 20) {
|
|
250
277
|
ultrapilot.state.reinforcement_count = newCount;
|
|
278
|
+
ultrapilot.state.last_checked_at = new Date().toISOString();
|
|
251
279
|
writeJsonFile(ultrapilot.path, ultrapilot.state);
|
|
252
280
|
|
|
253
281
|
console.log(JSON.stringify({
|
|
254
282
|
decision: 'block',
|
|
255
|
-
reason: `[ULTRAPILOT] ${incomplete} workers still running. Continue.`
|
|
283
|
+
reason: `[ULTRAPILOT] ${incomplete} workers still running. Continue working. When all workers complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`
|
|
256
284
|
}));
|
|
257
285
|
return;
|
|
258
286
|
}
|
|
@@ -260,17 +288,18 @@ async function main() {
|
|
|
260
288
|
}
|
|
261
289
|
|
|
262
290
|
// Priority 4: Swarm (coordinated agents with SQLite)
|
|
263
|
-
if (swarmMarker && swarmSummary?.active) {
|
|
291
|
+
if (swarmMarker && swarmSummary?.active && !isStaleState(swarmSummary)) {
|
|
264
292
|
const pending = (swarmSummary.tasks_pending || 0) + (swarmSummary.tasks_claimed || 0);
|
|
265
293
|
if (pending > 0) {
|
|
266
294
|
const newCount = (swarmSummary.reinforcement_count || 0) + 1;
|
|
267
295
|
if (newCount <= 15) {
|
|
268
296
|
swarmSummary.reinforcement_count = newCount;
|
|
297
|
+
swarmSummary.last_checked_at = new Date().toISOString();
|
|
269
298
|
writeJsonFile(join(stateDir, 'swarm-summary.json'), swarmSummary);
|
|
270
299
|
|
|
271
300
|
console.log(JSON.stringify({
|
|
272
301
|
decision: 'block',
|
|
273
|
-
reason: `[SWARM ACTIVE] ${pending} tasks remain. Continue working.`
|
|
302
|
+
reason: `[SWARM ACTIVE] ${pending} tasks remain. Continue working. When all tasks are done, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`
|
|
274
303
|
}));
|
|
275
304
|
return;
|
|
276
305
|
}
|
|
@@ -278,18 +307,19 @@ async function main() {
|
|
|
278
307
|
}
|
|
279
308
|
|
|
280
309
|
// Priority 5: Pipeline (sequential stages)
|
|
281
|
-
if (pipeline.state?.active) {
|
|
310
|
+
if (pipeline.state?.active && !isStaleState(pipeline.state)) {
|
|
282
311
|
const currentStage = pipeline.state.current_stage || 0;
|
|
283
312
|
const totalStages = pipeline.state.stages?.length || 0;
|
|
284
313
|
if (currentStage < totalStages) {
|
|
285
314
|
const newCount = (pipeline.state.reinforcement_count || 0) + 1;
|
|
286
315
|
if (newCount <= 15) {
|
|
287
316
|
pipeline.state.reinforcement_count = newCount;
|
|
317
|
+
pipeline.state.last_checked_at = new Date().toISOString();
|
|
288
318
|
writeJsonFile(pipeline.path, pipeline.state);
|
|
289
319
|
|
|
290
320
|
console.log(JSON.stringify({
|
|
291
321
|
decision: 'block',
|
|
292
|
-
reason: `[PIPELINE - Stage ${currentStage + 1}/${totalStages}] Pipeline not complete. Continue.`
|
|
322
|
+
reason: `[PIPELINE - Stage ${currentStage + 1}/${totalStages}] Pipeline not complete. Continue working. When all stages complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`
|
|
293
323
|
}));
|
|
294
324
|
return;
|
|
295
325
|
}
|
|
@@ -297,16 +327,17 @@ async function main() {
|
|
|
297
327
|
}
|
|
298
328
|
|
|
299
329
|
// Priority 6: UltraQA (QA cycling)
|
|
300
|
-
if (ultraqa.state?.active) {
|
|
330
|
+
if (ultraqa.state?.active && !isStaleState(ultraqa.state)) {
|
|
301
331
|
const cycle = ultraqa.state.cycle || 1;
|
|
302
332
|
const maxCycles = ultraqa.state.max_cycles || 10;
|
|
303
333
|
if (cycle < maxCycles && !ultraqa.state.all_passing) {
|
|
304
334
|
ultraqa.state.cycle = cycle + 1;
|
|
335
|
+
ultraqa.state.last_checked_at = new Date().toISOString();
|
|
305
336
|
writeJsonFile(ultraqa.path, ultraqa.state);
|
|
306
337
|
|
|
307
338
|
console.log(JSON.stringify({
|
|
308
339
|
decision: 'block',
|
|
309
|
-
reason: `[ULTRAQA - Cycle ${cycle + 1}/${maxCycles}] Tests not all passing. Continue fixing.`
|
|
340
|
+
reason: `[ULTRAQA - Cycle ${cycle + 1}/${maxCycles}] Tests not all passing. Continue fixing. When all tests pass, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`
|
|
310
341
|
}));
|
|
311
342
|
return;
|
|
312
343
|
}
|
|
@@ -314,7 +345,7 @@ async function main() {
|
|
|
314
345
|
|
|
315
346
|
// Priority 7: Ultrawork - ALWAYS continue while active (not just when tasks exist)
|
|
316
347
|
// This prevents false stops from bash errors, transient failures, etc.
|
|
317
|
-
if (ultrawork.state?.active) {
|
|
348
|
+
if (ultrawork.state?.active && !isStaleState(ultrawork.state)) {
|
|
318
349
|
const newCount = (ultrawork.state.reinforcement_count || 0) + 1;
|
|
319
350
|
const maxReinforcements = ultrawork.state.max_reinforcements || 50;
|
|
320
351
|
|
|
@@ -328,24 +359,29 @@ async function main() {
|
|
|
328
359
|
ultrawork.state.last_checked_at = new Date().toISOString();
|
|
329
360
|
writeJsonFile(ultrawork.path, ultrawork.state);
|
|
330
361
|
|
|
331
|
-
let reason = `[ULTRAWORK #${newCount}] Mode active
|
|
362
|
+
let reason = `[ULTRAWORK #${newCount}/${maxReinforcements}] Mode active.`;
|
|
363
|
+
|
|
332
364
|
if (totalIncomplete > 0) {
|
|
333
365
|
const itemType = taskCount > 0 ? 'Tasks' : 'todos';
|
|
334
|
-
reason
|
|
366
|
+
reason += ` ${totalIncomplete} incomplete ${itemType} remain. Continue working.`;
|
|
367
|
+
} else if (newCount >= 3) {
|
|
368
|
+
// Only suggest cancel after minimum iterations (guard against no-tasks-created scenario)
|
|
369
|
+
reason += ` If all work is complete, run /oh-my-claudecode:cancel to cleanly exit ultrawork mode and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force. Otherwise, continue working.`;
|
|
370
|
+
} else {
|
|
371
|
+
// Early iterations with no tasks yet - just tell LLM to continue
|
|
372
|
+
reason += ` Continue working - create Tasks to track your progress.`;
|
|
335
373
|
}
|
|
374
|
+
|
|
336
375
|
if (ultrawork.state.original_prompt) {
|
|
337
376
|
reason += `\nTask: ${ultrawork.state.original_prompt}`;
|
|
338
377
|
}
|
|
339
378
|
|
|
340
|
-
console.log(JSON.stringify({
|
|
341
|
-
decision: 'block',
|
|
342
|
-
reason: reason
|
|
343
|
-
}));
|
|
379
|
+
console.log(JSON.stringify({ decision: 'block', reason }));
|
|
344
380
|
return;
|
|
345
381
|
}
|
|
346
382
|
|
|
347
383
|
// Priority 8: Ecomode - ALWAYS continue while active
|
|
348
|
-
if (ecomode.state?.active) {
|
|
384
|
+
if (ecomode.state?.active && !isStaleState(ecomode.state)) {
|
|
349
385
|
const newCount = (ecomode.state.reinforcement_count || 0) + 1;
|
|
350
386
|
const maxReinforcements = ecomode.state.max_reinforcements || 50;
|
|
351
387
|
|
|
@@ -356,18 +392,23 @@ async function main() {
|
|
|
356
392
|
}
|
|
357
393
|
|
|
358
394
|
ecomode.state.reinforcement_count = newCount;
|
|
395
|
+
ecomode.state.last_checked_at = new Date().toISOString();
|
|
359
396
|
writeJsonFile(ecomode.path, ecomode.state);
|
|
360
397
|
|
|
361
|
-
let reason = `[ECOMODE #${newCount}] Mode active
|
|
398
|
+
let reason = `[ECOMODE #${newCount}/${maxReinforcements}] Mode active.`;
|
|
399
|
+
|
|
362
400
|
if (totalIncomplete > 0) {
|
|
363
401
|
const itemType = taskCount > 0 ? 'Tasks' : 'todos';
|
|
364
|
-
reason
|
|
402
|
+
reason += ` ${totalIncomplete} incomplete ${itemType} remain. Continue working.`;
|
|
403
|
+
} else if (newCount >= 3) {
|
|
404
|
+
// Only suggest cancel after minimum iterations (guard against no-tasks-created scenario)
|
|
405
|
+
reason += ` If all work is complete, run /oh-my-claudecode:cancel to cleanly exit ecomode and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force. Otherwise, continue working.`;
|
|
406
|
+
} else {
|
|
407
|
+
// Early iterations with no tasks yet - just tell LLM to continue
|
|
408
|
+
reason += ` Continue working - create Tasks to track your progress.`;
|
|
365
409
|
}
|
|
366
410
|
|
|
367
|
-
console.log(JSON.stringify({
|
|
368
|
-
decision: 'block',
|
|
369
|
-
reason: reason
|
|
370
|
-
}));
|
|
411
|
+
console.log(JSON.stringify({ decision: 'block', reason }));
|
|
371
412
|
return;
|
|
372
413
|
}
|
|
373
414
|
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
// Saves to .omc/notepad.md for compaction-resilient memory
|
|
5
5
|
|
|
6
6
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
// Dynamic import for the shared stdin module
|
|
14
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
8
15
|
|
|
9
16
|
// Constants
|
|
10
17
|
const NOTEPAD_TEMPLATE = '# Notepad\n' +
|
|
@@ -16,15 +23,6 @@ const NOTEPAD_TEMPLATE = '# Notepad\n' +
|
|
|
16
23
|
'## MANUAL\n' +
|
|
17
24
|
'<!-- User content. Never auto-pruned. -->\n';
|
|
18
25
|
|
|
19
|
-
// Read all stdin
|
|
20
|
-
async function readStdin() {
|
|
21
|
-
const chunks = [];
|
|
22
|
-
for await (const chunk of process.stdin) {
|
|
23
|
-
chunks.push(chunk);
|
|
24
|
-
}
|
|
25
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
26
|
// Initialize notepad.md if needed
|
|
29
27
|
function initNotepad(directory) {
|
|
30
28
|
const sisyphusDir = join(directory, '.omc');
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as path from 'path';
|
|
8
|
+
import { dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Dynamic import for the shared stdin module
|
|
15
|
+
const { readStdin } = await import(path.join(__dirname, 'lib', 'stdin.mjs'));
|
|
8
16
|
|
|
9
17
|
// Allowed path patterns (no warning)
|
|
10
18
|
const ALLOWED_PATH_PATTERNS = [
|
|
@@ -70,12 +78,7 @@ This is a soft warning. Operation will proceed.`;
|
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
async function main() {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// Read stdin
|
|
76
|
-
for await (const chunk of process.stdin) {
|
|
77
|
-
input += chunk;
|
|
78
|
-
}
|
|
81
|
+
const input = await readStdin();
|
|
79
82
|
|
|
80
83
|
let data;
|
|
81
84
|
try {
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
// Cross-platform: Windows, macOS, Linux
|
|
5
5
|
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
16
|
-
}
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Dynamic import for the shared stdin module
|
|
15
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
17
16
|
|
|
18
17
|
function readJsonFile(path) {
|
|
19
18
|
try {
|
package/agents/AGENTS.md
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
<!-- Parent: ../AGENTS.md -->
|
|
2
|
-
<!-- Generated: 2026-01-28 | Updated: 2026-01-28 -->
|
|
3
|
-
|
|
4
|
-
# agents (Prompt Templates)
|
|
5
|
-
|
|
6
|
-
Markdown prompt templates for all 32 agents in oh-my-claudecode.
|
|
7
|
-
|
|
8
|
-
## Purpose
|
|
9
|
-
|
|
10
|
-
This directory contains the prompt templates that define agent behavior. Each file is a markdown document with YAML frontmatter for metadata, loaded dynamically by `src/agents/definitions.ts`.
|
|
11
|
-
|
|
12
|
-
## Key Files
|
|
13
|
-
|
|
14
|
-
| File | Agent | Model | Purpose |
|
|
15
|
-
|------|-------|-------|---------|
|
|
16
|
-
| `architect.md` | architect | opus | Architecture, debugging, root cause analysis |
|
|
17
|
-
| `architect-medium.md` | architect-medium | sonnet | Moderate analysis tasks |
|
|
18
|
-
| `architect-low.md` | architect-low | haiku | Quick code questions |
|
|
19
|
-
| `executor.md` | executor | sonnet | Focused task implementation |
|
|
20
|
-
| `executor-high.md` | executor-high | opus | Complex multi-file changes |
|
|
21
|
-
| `executor-low.md` | executor-low | haiku | Simple single-file tasks |
|
|
22
|
-
| `explore.md` | explore | haiku | Fast codebase search |
|
|
23
|
-
| `explore-medium.md` | explore-medium | sonnet | Thorough search with reasoning |
|
|
24
|
-
| `explore-high.md` | explore-high | opus | Architectural discovery |
|
|
25
|
-
| `designer.md` | designer | sonnet | UI/UX, component design |
|
|
26
|
-
| `designer-high.md` | designer-high | opus | Complex UI architecture |
|
|
27
|
-
| `designer-low.md` | designer-low | haiku | Simple styling tweaks |
|
|
28
|
-
| `researcher.md` | researcher | sonnet | Documentation research |
|
|
29
|
-
| `researcher-low.md` | researcher-low | haiku | Quick doc lookups |
|
|
30
|
-
| `writer.md` | writer | haiku | Technical documentation |
|
|
31
|
-
| `vision.md` | vision | sonnet | Image/screenshot analysis |
|
|
32
|
-
| `critic.md` | critic | opus | Critical plan review |
|
|
33
|
-
| `analyst.md` | analyst | opus | Pre-planning requirements |
|
|
34
|
-
| `planner.md` | planner | opus | Strategic planning |
|
|
35
|
-
| `qa-tester.md` | qa-tester | sonnet | Interactive CLI testing |
|
|
36
|
-
| `qa-tester-high.md` | qa-tester-high | opus | Production-ready QA |
|
|
37
|
-
| `scientist.md` | scientist | sonnet | Data analysis |
|
|
38
|
-
| `scientist-high.md` | scientist-high | opus | Complex ML/research |
|
|
39
|
-
| `scientist-low.md` | scientist-low | haiku | Quick data inspection |
|
|
40
|
-
| `security-reviewer.md` | security-reviewer | opus | Security audits |
|
|
41
|
-
| `security-reviewer-low.md` | security-reviewer-low | haiku | Quick security scans |
|
|
42
|
-
| `build-fixer.md` | build-fixer | sonnet | Build error resolution |
|
|
43
|
-
| `build-fixer-low.md` | build-fixer-low | haiku | Simple type errors |
|
|
44
|
-
| `tdd-guide.md` | tdd-guide | sonnet | TDD workflow |
|
|
45
|
-
| `tdd-guide-low.md` | tdd-guide-low | haiku | Test suggestions |
|
|
46
|
-
| `code-reviewer.md` | code-reviewer | opus | Expert code review |
|
|
47
|
-
| `code-reviewer-low.md` | code-reviewer-low | haiku | Quick code checks |
|
|
48
|
-
|
|
49
|
-
## For AI Agents
|
|
50
|
-
|
|
51
|
-
### Working In This Directory
|
|
52
|
-
|
|
53
|
-
#### Prompt Template Format
|
|
54
|
-
|
|
55
|
-
Each file follows this structure:
|
|
56
|
-
```markdown
|
|
57
|
-
---
|
|
58
|
-
name: agent-name
|
|
59
|
-
description: Brief description of what this agent does
|
|
60
|
-
model: opus | sonnet | haiku
|
|
61
|
-
tools: [Read, Glob, Grep, ...]
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
# Agent Name
|
|
65
|
-
|
|
66
|
-
## Role
|
|
67
|
-
What this agent is and its expertise.
|
|
68
|
-
|
|
69
|
-
## Instructions
|
|
70
|
-
Detailed instructions for how the agent should behave.
|
|
71
|
-
|
|
72
|
-
## Constraints
|
|
73
|
-
What the agent should NOT do.
|
|
74
|
-
|
|
75
|
-
## Output Format
|
|
76
|
-
How results should be formatted.
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
#### Creating a New Agent Prompt
|
|
80
|
-
|
|
81
|
-
1. Create `new-agent.md` with YAML frontmatter
|
|
82
|
-
2. Define clear role, instructions, and constraints
|
|
83
|
-
3. Reference in `src/agents/definitions.ts`
|
|
84
|
-
|
|
85
|
-
#### Tiered Variants
|
|
86
|
-
|
|
87
|
-
For model routing, create variants with complexity-appropriate instructions:
|
|
88
|
-
|
|
89
|
-
| Tier | File Suffix | Instructions Focus |
|
|
90
|
-
|------|-------------|-------------------|
|
|
91
|
-
| LOW (Haiku) | `-low.md` | Quick, simple tasks, minimal reasoning |
|
|
92
|
-
| MEDIUM (Sonnet) | Base file or `-medium.md` | Standard complexity |
|
|
93
|
-
| HIGH (Opus) | `-high.md` | Complex reasoning, deep analysis |
|
|
94
|
-
|
|
95
|
-
### Common Patterns
|
|
96
|
-
|
|
97
|
-
**Frontmatter parsing** (in `definitions.ts`):
|
|
98
|
-
```typescript
|
|
99
|
-
function loadAgentPrompt(agentName: string): string {
|
|
100
|
-
const content = readFileSync(`agents/${agentName}.md`, 'utf-8');
|
|
101
|
-
const match = content.match(/^---[\s\S]*?---\s*([\s\S]*)$/);
|
|
102
|
-
return match ? match[1].trim() : content.trim();
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**Tool assignment by agent type:**
|
|
107
|
-
- Read-only: `[Read, Glob, Grep]`
|
|
108
|
-
- Analysis: `[Read, Glob, Grep, WebSearch, WebFetch]`
|
|
109
|
-
- Execution: `[Read, Glob, Grep, Edit, Write, Bash, TodoWrite]`
|
|
110
|
-
- Data: `[Read, Glob, Grep, Bash, python_repl]`
|
|
111
|
-
|
|
112
|
-
### Testing Requirements
|
|
113
|
-
|
|
114
|
-
Agent prompts are tested via integration tests that spawn agents and verify behavior.
|
|
115
|
-
|
|
116
|
-
## Dependencies
|
|
117
|
-
|
|
118
|
-
### Internal
|
|
119
|
-
- Loaded by `src/agents/definitions.ts`
|
|
120
|
-
- Referenced by skill definitions in `skills/`
|
|
121
|
-
|
|
122
|
-
### External
|
|
123
|
-
None - pure markdown files.
|
|
124
|
-
|
|
125
|
-
## Agent Categories
|
|
126
|
-
|
|
127
|
-
| Category | Agents | Common Tools |
|
|
128
|
-
|----------|--------|--------------|
|
|
129
|
-
| Analysis | architect, architect-medium, architect-low | Read, Glob, Grep, lsp_diagnostics |
|
|
130
|
-
| Execution | executor, executor-low, executor-high | Read, Glob, Grep, Edit, Write, Bash, lsp_diagnostics |
|
|
131
|
-
| Search | explore, explore-medium, explore-high | Read, Glob, Grep, ast_grep_search, lsp_document_symbols, lsp_workspace_symbols |
|
|
132
|
-
| Research | researcher, researcher-low | WebSearch, WebFetch |
|
|
133
|
-
| Frontend | designer, designer-low, designer-high | Edit, Write, Bash |
|
|
134
|
-
| Docs | writer | Edit, Write |
|
|
135
|
-
| Visual | vision | Read, Glob, Grep |
|
|
136
|
-
| Planning | planner, analyst, critic | Read, Glob, Grep |
|
|
137
|
-
| Testing | qa-tester, qa-tester-high | Bash, Read, Grep, Glob, TodoWrite, lsp_diagnostics |
|
|
138
|
-
| Security | security-reviewer, security-reviewer-low | Read, Grep, Bash |
|
|
139
|
-
| Build | build-fixer, build-fixer-low | Read, Glob, Grep, Edit, Write, Bash, lsp_diagnostics, lsp_diagnostics_directory |
|
|
140
|
-
| TDD | tdd-guide, tdd-guide-low | Read, Grep, Glob, Bash, lsp_diagnostics |
|
|
141
|
-
| Review | code-reviewer, code-reviewer-low | Read, Grep, Glob, Bash, lsp_diagnostics |
|
|
142
|
-
| Data | scientist, scientist-low, scientist-high | Read, Glob, Grep, Bash, python_repl |
|
|
143
|
-
|
|
144
|
-
<!-- MANUAL: -->
|