oh-my-claudecode 0.2.3 → 0.2.4
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 +48 -1
- package/dist/cli/bind-cron.d.ts +86 -0
- package/dist/cli/bind-cron.d.ts.map +1 -0
- package/dist/cli/bind-cron.js +161 -0
- package/dist/cli/bind-cron.js.map +1 -0
- package/dist/cli/bind.d.ts +78 -0
- package/dist/cli/bind.d.ts.map +1 -0
- package/dist/cli/bind.js +417 -0
- package/dist/cli/bind.js.map +1 -0
- package/dist/cli/index.js +61 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/project-scan.d.ts +94 -0
- package/dist/cli/project-scan.d.ts.map +1 -0
- package/dist/cli/project-scan.js +387 -0
- package/dist/cli/project-scan.js.map +1 -0
- package/dist/cli/sisyphus-migrate.d.ts +50 -0
- package/dist/cli/sisyphus-migrate.d.ts.map +1 -0
- package/dist/cli/sisyphus-migrate.js +226 -0
- package/dist/cli/sisyphus-migrate.js.map +1 -0
- package/dist/cli/tui.d.ts +94 -0
- package/dist/cli/tui.d.ts.map +1 -0
- package/dist/cli/tui.js +180 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/features/yith-archive/functions/backfill.d.ts +43 -0
- package/dist/features/yith-archive/functions/backfill.d.ts.map +1 -1
- package/dist/features/yith-archive/functions/backfill.js +303 -145
- package/dist/features/yith-archive/functions/backfill.js.map +1 -1
- package/dist/features/yith-archive/functions/compress-batch.d.ts +4 -0
- package/dist/features/yith-archive/functions/compress-batch.d.ts.map +1 -0
- package/dist/features/yith-archive/functions/compress-batch.js +290 -0
- package/dist/features/yith-archive/functions/compress-batch.js.map +1 -0
- package/dist/features/yith-archive/functions/compress.d.ts +2 -1
- package/dist/features/yith-archive/functions/compress.d.ts.map +1 -1
- package/dist/features/yith-archive/functions/compress.js +1 -1
- package/dist/features/yith-archive/functions/compress.js.map +1 -1
- package/dist/features/yith-archive/functions/opencode-import.d.ts +67 -0
- package/dist/features/yith-archive/functions/opencode-import.d.ts.map +1 -0
- package/dist/features/yith-archive/functions/opencode-import.js +272 -0
- package/dist/features/yith-archive/functions/opencode-import.js.map +1 -0
- package/dist/features/yith-archive/index.d.ts.map +1 -1
- package/dist/features/yith-archive/index.js +4 -0
- package/dist/features/yith-archive/index.js.map +1 -1
- package/dist/features/yith-archive/providers/embedding/local.d.ts +22 -0
- package/dist/features/yith-archive/providers/embedding/local.d.ts.map +1 -1
- package/dist/features/yith-archive/providers/embedding/local.js +56 -2
- package/dist/features/yith-archive/providers/embedding/local.js.map +1 -1
- package/dist/features/yith-archive/state/bind-state.d.ts +84 -0
- package/dist/features/yith-archive/state/bind-state.d.ts.map +1 -0
- package/dist/features/yith-archive/state/bind-state.js +120 -0
- package/dist/features/yith-archive/state/bind-state.js.map +1 -0
- package/dist/features/yith-archive/state/schema.d.ts +14 -0
- package/dist/features/yith-archive/state/schema.d.ts.map +1 -1
- package/dist/features/yith-archive/state/schema.js +14 -0
- package/dist/features/yith-archive/state/schema.js.map +1 -1
- package/dist/hooks/cthulhu-auto.d.ts +1 -1
- package/dist/hooks/cthulhu-auto.d.ts.map +1 -1
- package/dist/hooks/cthulhu-auto.js +75 -11
- package/dist/hooks/cthulhu-auto.js.map +1 -1
- package/dist/hooks/cthulhu-preflight.d.ts +45 -0
- package/dist/hooks/cthulhu-preflight.d.ts.map +1 -0
- package/dist/hooks/cthulhu-preflight.js +91 -0
- package/dist/hooks/cthulhu-preflight.js.map +1 -0
- package/package.json +5 -2
- /package/commands/{bind-necronomicon.md → necronomicon-bind.md} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Necronomicon binding state — the durable, resumable state machine
|
|
3
|
+
* that `oh-my-claudecode bind` reads on every invocation to figure
|
|
4
|
+
* out what's left to do.
|
|
5
|
+
*
|
|
6
|
+
* Stored under KV.bindState → "current". Every phase transition goes
|
|
7
|
+
* through `markPhase()` (pure function — returns a new state object).
|
|
8
|
+
* Callers persist the result to KV after each transition so a crash
|
|
9
|
+
* mid-phase resumes cleanly on the next run.
|
|
10
|
+
*
|
|
11
|
+
* Six phases in strict order:
|
|
12
|
+
* 1. embedding_download - pre-fetch the local nomic model (~137 MB)
|
|
13
|
+
* 2. claude_transcripts - scan ~/.claude/projects/ subdirs and ingest raw obs
|
|
14
|
+
* 3. opencode_import - read ~/.local/share/opencode/opencode.db
|
|
15
|
+
* 4. sisyphus_migrate - walk .sisyphus/ dirs into .elder-gods/
|
|
16
|
+
* 5. preliminary_seed - scan each project's code tree for base memories
|
|
17
|
+
* 6. pending_compression_trigger - record marker for /cthulhu preflight
|
|
18
|
+
*
|
|
19
|
+
* Each phase independently reports pending / in_progress / completed /
|
|
20
|
+
* failed. `firstPendingPhase` returns the next phase to run, treating
|
|
21
|
+
* failed phases as retryable (they come back as pending on the next
|
|
22
|
+
* run so resume works without operator intervention).
|
|
23
|
+
*/
|
|
24
|
+
/** Strict execution order. `firstPendingPhase` walks this array. */
|
|
25
|
+
export const BIND_PHASE_ORDER = [
|
|
26
|
+
"embedding_download",
|
|
27
|
+
"claude_transcripts",
|
|
28
|
+
"opencode_import",
|
|
29
|
+
"sisyphus_migrate",
|
|
30
|
+
"preliminary_seed",
|
|
31
|
+
"pending_compression_trigger",
|
|
32
|
+
];
|
|
33
|
+
/** Build a fresh BindState with every phase pending and zero attempts. */
|
|
34
|
+
export function initialBindState() {
|
|
35
|
+
const now = new Date().toISOString();
|
|
36
|
+
const phases = {};
|
|
37
|
+
for (const phase of BIND_PHASE_ORDER) {
|
|
38
|
+
phases[phase] = { status: "pending", attempts: 0 };
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
version: 1,
|
|
42
|
+
phases,
|
|
43
|
+
startedAt: now,
|
|
44
|
+
lastUpdatedAt: now,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Transition a single phase through its state machine. Pure —
|
|
49
|
+
* returns a new BindState, never mutates input. Callers must
|
|
50
|
+
* persist the result to KV after calling.
|
|
51
|
+
*
|
|
52
|
+
* Semantic rules:
|
|
53
|
+
* - Any transition TO "in_progress" sets `startedAt` (if not already)
|
|
54
|
+
* and increments `attempts`.
|
|
55
|
+
* - Transition to "completed" sets `completedAt` and clears `error`.
|
|
56
|
+
* - Transition to "failed" sets `error` and increments `attempts`
|
|
57
|
+
* even if the phase was never in_progress — a crash before the
|
|
58
|
+
* runner could flip the flag counts as one attempt.
|
|
59
|
+
* - Details payload is shallow-merged, not replaced, so phase
|
|
60
|
+
* runners can update cursor data without clobbering other keys.
|
|
61
|
+
*/
|
|
62
|
+
export function markPhase(state, phase, update) {
|
|
63
|
+
const now = new Date().toISOString();
|
|
64
|
+
const prev = state.phases[phase];
|
|
65
|
+
const nextPhase = {
|
|
66
|
+
...prev,
|
|
67
|
+
lastAttemptedAt: now,
|
|
68
|
+
};
|
|
69
|
+
if (update.status !== undefined) {
|
|
70
|
+
nextPhase.status = update.status;
|
|
71
|
+
if (update.status === "in_progress") {
|
|
72
|
+
if (!prev.startedAt)
|
|
73
|
+
nextPhase.startedAt = now;
|
|
74
|
+
nextPhase.attempts = prev.attempts + 1;
|
|
75
|
+
}
|
|
76
|
+
if (update.status === "completed") {
|
|
77
|
+
nextPhase.completedAt = now;
|
|
78
|
+
nextPhase.error = undefined;
|
|
79
|
+
}
|
|
80
|
+
if (update.status === "failed") {
|
|
81
|
+
nextPhase.attempts = prev.attempts + 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (update.error !== undefined)
|
|
85
|
+
nextPhase.error = update.error;
|
|
86
|
+
if (update.details !== undefined) {
|
|
87
|
+
nextPhase.details = { ...(prev.details ?? {}), ...update.details };
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
...state,
|
|
91
|
+
lastUpdatedAt: now,
|
|
92
|
+
phases: { ...state.phases, [phase]: nextPhase },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return the first phase that still needs work, or null if the bind
|
|
97
|
+
* is fully complete. Failed phases are considered pending so a crash
|
|
98
|
+
* during phase N causes the next `bind` invocation to retry phase N
|
|
99
|
+
* from its cursor — no manual intervention needed.
|
|
100
|
+
*
|
|
101
|
+
* Execution order is fixed by BIND_PHASE_ORDER. Phases don't run in
|
|
102
|
+
* parallel.
|
|
103
|
+
*/
|
|
104
|
+
export function firstPendingPhase(state) {
|
|
105
|
+
for (const phase of BIND_PHASE_ORDER) {
|
|
106
|
+
const st = state.phases[phase].status;
|
|
107
|
+
if (st !== "completed")
|
|
108
|
+
return phase;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
/** True if every phase has reached "completed". */
|
|
113
|
+
export function isBindComplete(state) {
|
|
114
|
+
for (const phase of BIND_PHASE_ORDER) {
|
|
115
|
+
if (state.phases[phase].status !== "completed")
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=bind-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind-state.js","sourceRoot":"","sources":["../../../../src/features/yith-archive/state/bind-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,20 @@ export declare const KV: {
|
|
|
47
47
|
/** History of backfill runs for debugging / auditing. Key = runId,
|
|
48
48
|
* value = `{ startedAt, completedAt, projectCwd, stats, errors }`. */
|
|
49
49
|
readonly backfillRuns: "mem:backfill:runs";
|
|
50
|
+
/** Binding ritual state. Single entry under key "current" holds the
|
|
51
|
+
* BindState object (phase completion, cursors, errors). The CLI's
|
|
52
|
+
* `oh-my-claudecode bind` command reads this on start and resumes
|
|
53
|
+
* from the first incomplete phase. See state/bind-state.ts. */
|
|
54
|
+
readonly bindState: "mem:bind-state";
|
|
55
|
+
/** Pending-compression counter. Key "state" holds `{ count, updatedAt }`.
|
|
56
|
+
* Incremented on raw observation writes by mem::backfill-sessions,
|
|
57
|
+
* decremented on compressed-observation writes by mem::compress-step.
|
|
58
|
+
* The /cthulhu preflight reads this to tell the user how much work
|
|
59
|
+
* is waiting to be processed via the work-packet loop. */
|
|
60
|
+
readonly pendingCompression: "mem:pending-compression";
|
|
61
|
+
/** Per-session cursors for the opencode SQLite importer. Key =
|
|
62
|
+
* `${db_path}|${opencode_session_id}`, value = `{ lastPartId }`. */
|
|
63
|
+
readonly opencodeImportCursors: "mem:opencode-import:cursors";
|
|
50
64
|
};
|
|
51
65
|
export declare const STREAM: {
|
|
52
66
|
readonly name: "mem-live";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/features/yith-archive/state/schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,EAAE;;uCAEa,MAAM;;;;;;iCAMZ,MAAM;;;;;;;;;kCASL,MAAM;iCACP,MAAM,UAAU,MAAM;mCAEpB,MAAM;;;;;;;;;;;;;;;;;yCAiBA,MAAM;uCACR,MAAM;;;;IAIhC;;;0DAGsD;;IAEtD;2EACuE;;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/features/yith-archive/state/schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,EAAE;;uCAEa,MAAM;;;;;;iCAMZ,MAAM;;;;;;;;;kCASL,MAAM;iCACP,MAAM,UAAU,MAAM;mCAEpB,MAAM;;;;;;;;;;;;;;;;;yCAiBA,MAAM;uCACR,MAAM;;;;IAIhC;;;0DAGsD;;IAEtD;2EACuE;;IAEvE;;;oEAGgE;;IAEhE;;;;+DAI2D;;IAE3D;yEACqE;;CAE7D,CAAC;AAEX,eAAO,MAAM,MAAM;;gCAEE,MAAM;;CAEjB,CAAC;AAEX,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU9D"}
|
|
@@ -48,6 +48,20 @@ export const KV = {
|
|
|
48
48
|
/** History of backfill runs for debugging / auditing. Key = runId,
|
|
49
49
|
* value = `{ startedAt, completedAt, projectCwd, stats, errors }`. */
|
|
50
50
|
backfillRuns: "mem:backfill:runs",
|
|
51
|
+
/** Binding ritual state. Single entry under key "current" holds the
|
|
52
|
+
* BindState object (phase completion, cursors, errors). The CLI's
|
|
53
|
+
* `oh-my-claudecode bind` command reads this on start and resumes
|
|
54
|
+
* from the first incomplete phase. See state/bind-state.ts. */
|
|
55
|
+
bindState: "mem:bind-state",
|
|
56
|
+
/** Pending-compression counter. Key "state" holds `{ count, updatedAt }`.
|
|
57
|
+
* Incremented on raw observation writes by mem::backfill-sessions,
|
|
58
|
+
* decremented on compressed-observation writes by mem::compress-step.
|
|
59
|
+
* The /cthulhu preflight reads this to tell the user how much work
|
|
60
|
+
* is waiting to be processed via the work-packet loop. */
|
|
61
|
+
pendingCompression: "mem:pending-compression",
|
|
62
|
+
/** Per-session cursors for the opencode SQLite importer. Key =
|
|
63
|
+
* `${db_path}|${opencode_session_id}`, value = `{ lastPartId }`. */
|
|
64
|
+
opencodeImportCursors: "mem:opencode-import:cursors",
|
|
51
65
|
};
|
|
52
66
|
export const STREAM = {
|
|
53
67
|
name: "mem-live",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/features/yith-archive/state/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,QAAQ,EAAE,cAAc;IACxB,YAAY,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,WAAW,SAAS,EAAE;IAC3D,QAAQ,EAAE,cAAc;IACxB,SAAS,EAAE,eAAe;IAC1B,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,YAAY;IACpB,UAAU,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,WAAW,KAAK,EAAE;IACjD,SAAS,EAAE,gBAAgB;IAC3B,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAE,cAAc;IACxB,YAAY,EAAE,mBAAmB;IACjC,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,iBAAiB;IAC7B,QAAQ,EAAE,cAAc;IACxB,UAAU,EAAE,gBAAgB;IAC5B,UAAU,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,YAAY,MAAM,SAAS;IAC3D,SAAS,EAAE,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE,CAC5C,YAAY,MAAM,UAAU,MAAM,EAAE;IACtC,WAAW,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,YAAY,MAAM,UAAU;IAC7D,KAAK,EAAE,WAAW;IAClB,OAAO,EAAE,aAAa;IACtB,WAAW,EAAE,kBAAkB;IAC/B,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,cAAc;IACxB,WAAW,EAAE,kBAAkB;IAC/B,OAAO,EAAE,aAAa;IACtB,WAAW,EAAE,iBAAiB;IAC9B,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAE,cAAc;IACxB,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,cAAc;IACxB,gBAAgB,EAAE,wBAAwB;IAC1C,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,gBAAgB,SAAS,EAAE;IAClE,gBAAgB,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,cAAc,KAAK,EAAE;IAC1D,eAAe,EAAE,eAAe;IAChC,SAAS,EAAE,gBAAgB;IAC3B,WAAW,EAAE,kBAAkB;IAC/B;;;0DAGsD;IACtD,eAAe,EAAE,sBAAsB;IACvC;2EACuE;IACvE,YAAY,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/features/yith-archive/state/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
* Projects without `.elder-gods/` are left untouched — the hook exits silently
|
|
10
10
|
* so ordinary Claude Code sessions stay unchanged.
|
|
11
11
|
*/
|
|
12
|
-
export declare const CTHULHU_AUTO_HOOK_SCRIPT = "#!/usr/bin/env bash\n# oh-my-claudecode: Cthulhu Auto-Activation SessionStart Hook\n# If .elder-gods/ is found in cwd or any parent, injects Cthulhu orchestrator mode.\n\nset -euo pipefail\n\ndir=\"${CLAUDE_PROJECT_DIR:-$PWD}\"\nfound=\"\"\nwhile [ \"$dir\" != \"/\" ] && [ -n \"$dir\" ]; do\n if [ -d \"$dir/.elder-gods\" ]; then\n found=\"$dir/.elder-gods\"\n break\n fi\n dir=\"$(dirname \"$dir\")\"\ndone\n\n[ -z \"$found\" ] && exit 0\n\ncat <<'PROMPT'\n[oh-my-claudecode: Cthulhu orchestrator auto-activated \u2014 .elder-gods/ detected]\n\nYou are now operating as Cthulhu, the Great Dreamer \u2014 primary orchestrator of the\noh-my-claudecode system. Every user message in this session passes through the\nCthulhu intent gate before any action is taken.\n\nOperating principles:\n1. Intent gate first \u2014 verbalize what the user actually wants before doing anything\n2. Delegate aggressively \u2014 never work alone when a specialist is available\n3. Parallelize everything \u2014 independent searches and reads happen simultaneously\n4. Plan before implement \u2014 todos BEFORE touching files\n5. Verify before completing \u2014 diagnostics, tests, evidence required\n6. Agent-speed time framing \u2014 you are not a human team. NEVER estimate work in\n human units (days, weeks, sprints, story points, \"a few hours of dev time\").\n Agents operate in tool-call budgets, not calendars. If asked \"how long\", answer\n in concrete units you actually control: number of steps, files touched, tool\n calls, parallel agent fires, or verification passes. If pressed for wall-clock,\n give a seconds-to-minutes range for the current session and say so explicitly.\n Reject any framing that treats this work as human-scale engineering time.\n\nAvailable Elder God specialists (use via Agent tool subagent_type):\n- \"shoggoth\" \u2014 codebase search (fire 3+ in parallel for exploration)\n- \"dagon\" \u2014 external docs, GitHub source, library research\n- \"yog-sothoth\" \u2014 architecture decisions, hard debugging after 2+ failed attempts\n- \"tsathoggua\" \u2014 review .elder-gods/plans/*.md files for executability\n- \"ithaqua\" \u2014 pre-planning consultant for complex or ambiguous requests\n- \"hastur\" \u2014 bounded sub-tasks and nested orchestration\n- \"nyarlathotep\" \u2014 end-to-end autonomous execution of whole goals\n- \"shub-niggurath\" \u2014 strategic planning flow (interview \u2192 plan \u2192 review)\n- \"the-deep-one\" \u2014 image/screenshot/diagram analysis\n\nClassification flow for each user message:\n- Trivial \u2192 direct tools, no delegation\n- Exploratory \u2192 parallel Shoggoth agents\n- Implementation \u2192 plan with todos, then delegate or execute\n- Ambiguous \u2192 exactly one clarifying question\n\
|
|
12
|
+
export declare const CTHULHU_AUTO_HOOK_SCRIPT = "#!/usr/bin/env bash\n# oh-my-claudecode: Cthulhu Auto-Activation SessionStart Hook\n# If .elder-gods/ is found in cwd or any parent, injects Cthulhu orchestrator mode.\n\nset -euo pipefail\n\ndir=\"${CLAUDE_PROJECT_DIR:-$PWD}\"\nfound=\"\"\nwhile [ \"$dir\" != \"/\" ] && [ -n \"$dir\" ]; do\n if [ -d \"$dir/.elder-gods\" ]; then\n found=\"$dir/.elder-gods\"\n break\n fi\n dir=\"$(dirname \"$dir\")\"\ndone\n\n[ -z \"$found\" ] && exit 0\n\n# --- Necronomicon preflight ---\n# Extract bindState + pending-compression count from the user's\n# necronomicon.json (Yith Archive's on-disk file). The flags drive\n# the preflight text block the hook injects below.\nNECRONOMICON=\"${HOME}/.oh-my-claudecode/yith/necronomicon.json\"\nBIND_EXISTS=\"false\"\nALL_COMPLETE=\"false\"\nPENDING_COUNT=\"0\"\nFAILED_PHASES=\"\"\nPENDING_PHASES=\"\"\nif [ -f \"$NECRONOMICON\" ] && command -v jq >/dev/null 2>&1; then\n if jq -e '.\"mem:bind-state\".current' \"$NECRONOMICON\" >/dev/null 2>&1; then\n BIND_EXISTS=\"true\"\n ALL_COMPLETE=$(jq -r '\n [.\"mem:bind-state\".current.phases | to_entries[] | .value.status]\n | all(. == \"completed\")\n ' \"$NECRONOMICON\" 2>/dev/null || echo \"false\")\n FAILED_PHASES=$(jq -r '\n [.\"mem:bind-state\".current.phases\n | to_entries[]\n | select(.value.status == \"failed\")\n | .key] | join(\",\")\n ' \"$NECRONOMICON\" 2>/dev/null || echo \"\")\n PENDING_PHASES=$(jq -r '\n [.\"mem:bind-state\".current.phases\n | to_entries[]\n | select(.value.status == \"pending\" or .value.status == \"in_progress\")\n | .key] | join(\",\")\n ' \"$NECRONOMICON\" 2>/dev/null || echo \"\")\n fi\n PENDING_COUNT=$(jq -r '\n .\"mem:pending-compression\".state.count // 0\n ' \"$NECRONOMICON\" 2>/dev/null || echo \"0\")\nfi\n\ncat <<'PROMPT'\n[oh-my-claudecode: Cthulhu orchestrator auto-activated \u2014 .elder-gods/ detected]\n\nYou are now operating as Cthulhu, the Great Dreamer \u2014 primary orchestrator of the\noh-my-claudecode system. Every user message in this session passes through the\nCthulhu intent gate before any action is taken.\n\nOperating principles:\n1. Intent gate first \u2014 verbalize what the user actually wants before doing anything\n2. Delegate aggressively \u2014 never work alone when a specialist is available\n3. Parallelize everything \u2014 independent searches and reads happen simultaneously\n4. Plan before implement \u2014 todos BEFORE touching files\n5. Verify before completing \u2014 diagnostics, tests, evidence required\n6. Agent-speed time framing \u2014 you are not a human team. NEVER estimate work in\n human units (days, weeks, sprints, story points, \"a few hours of dev time\").\n Agents operate in tool-call budgets, not calendars. If asked \"how long\", answer\n in concrete units you actually control: number of steps, files touched, tool\n calls, parallel agent fires, or verification passes. If pressed for wall-clock,\n give a seconds-to-minutes range for the current session and say so explicitly.\n Reject any framing that treats this work as human-scale engineering time.\n\nAvailable Elder God specialists (use via Agent tool subagent_type):\n- \"shoggoth\" \u2014 codebase search (fire 3+ in parallel for exploration)\n- \"dagon\" \u2014 external docs, GitHub source, library research\n- \"yog-sothoth\" \u2014 architecture decisions, hard debugging after 2+ failed attempts\n- \"tsathoggua\" \u2014 review .elder-gods/plans/*.md files for executability\n- \"ithaqua\" \u2014 pre-planning consultant for complex or ambiguous requests\n- \"hastur\" \u2014 bounded sub-tasks and nested orchestration\n- \"nyarlathotep\" \u2014 end-to-end autonomous execution of whole goals\n- \"shub-niggurath\" \u2014 strategic planning flow (interview \u2192 plan \u2192 review)\n- \"the-deep-one\" \u2014 image/screenshot/diagram analysis\n\nClassification flow for each user message:\n- Trivial \u2192 direct tools, no delegation\n- Exploratory \u2192 parallel Shoggoth agents\n- Implementation \u2192 plan with todos, then delegate or execute\n- Ambiguous \u2192 exactly one clarifying question\n\n[END cthulhu orchestrator injection]\nPROMPT\n\n# --- Dynamic Necronomicon preflight ---\n# Emit a tailored preflight block based on the bindState flags we\n# extracted above. The text here drives Cthulhu's first-user-message\n# behavior: hard-block on unbound Necronomicon, nag on failures,\n# offer to drain pending compression when the queue is non-empty.\necho\necho \"[Necronomicon preflight]\"\nif [ \"$BIND_EXISTS\" = \"false\" ]; then\n echo\n echo \"The Necronomicon has not been bound on this machine yet. The Yith\"\n echo \"Archive is empty and no past Claude Code sessions have been ingested.\"\n echo\n echo \"**Action required**: tell the user to run \\`oh-my-claudecode bind\\`\"\n echo \"in their terminal OR \\`/necronomicon-bind\\` inside this session\"\n echo \"before proceeding with any memory-dependent work.\"\nelif [ -n \"$FAILED_PHASES\" ]; then\n echo\n echo \"The binding ritual has failed phases: $FAILED_PHASES\"\n echo \"Re-run \\`/necronomicon-bind\\` (or \\`oh-my-claudecode bind --resume\\`\"\n echo \"in a terminal) to retry from the failed phase \u2014 the state machine\"\n echo \"resumes automatically without redoing completed work.\"\nelif [ \"$ALL_COMPLETE\" != \"true\" ]; then\n echo\n echo \"The Necronomicon is partially bound. Pending phases: $PENDING_PHASES\"\n echo \"Run \\`/necronomicon-bind\\` to continue the ritual from where it stopped.\"\nelif [ \"$PENDING_COUNT\" != \"0\" ]; then\n echo\n echo \"\u2713 Necronomicon bound. $PENDING_COUNT raw observations are queued for\"\n echo \"compression into searchable memories.\"\n echo\n echo \"**Offer the user**: \"Process pending compression now (runs via the\"\n echo \"work-packet loop using this session's LLM)? It takes one commit round\"\n echo \"per batch.\" If they accept, call yith_trigger with\"\n echo \"mem::compress-batch-step and drive the needs_llm_work -> yith_commit_work\"\n echo \"loop until terminal. Render an ASCII progress bar per round.\"\nelse\n echo\n echo \"\u2713 Necronomicon is bound and every phase is complete. Nothing pending.\"\nfi\n";
|
|
13
13
|
export declare function getCthulhuAutoHookConfig(): object;
|
|
14
14
|
//# sourceMappingURL=cthulhu-auto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cthulhu-auto.d.ts","sourceRoot":"","sources":["../../src/hooks/cthulhu-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"cthulhu-auto.d.ts","sourceRoot":"","sources":["../../src/hooks/cthulhu-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,4rMAqIpC,CAAA;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAUjD"}
|
|
@@ -27,6 +27,41 @@ done
|
|
|
27
27
|
|
|
28
28
|
[ -z "\$found" ] && exit 0
|
|
29
29
|
|
|
30
|
+
# --- Necronomicon preflight ---
|
|
31
|
+
# Extract bindState + pending-compression count from the user's
|
|
32
|
+
# necronomicon.json (Yith Archive's on-disk file). The flags drive
|
|
33
|
+
# the preflight text block the hook injects below.
|
|
34
|
+
NECRONOMICON="\${HOME}/.oh-my-claudecode/yith/necronomicon.json"
|
|
35
|
+
BIND_EXISTS="false"
|
|
36
|
+
ALL_COMPLETE="false"
|
|
37
|
+
PENDING_COUNT="0"
|
|
38
|
+
FAILED_PHASES=""
|
|
39
|
+
PENDING_PHASES=""
|
|
40
|
+
if [ -f "\$NECRONOMICON" ] && command -v jq >/dev/null 2>&1; then
|
|
41
|
+
if jq -e '."mem:bind-state".current' "\$NECRONOMICON" >/dev/null 2>&1; then
|
|
42
|
+
BIND_EXISTS="true"
|
|
43
|
+
ALL_COMPLETE=\$(jq -r '
|
|
44
|
+
[."mem:bind-state".current.phases | to_entries[] | .value.status]
|
|
45
|
+
| all(. == "completed")
|
|
46
|
+
' "\$NECRONOMICON" 2>/dev/null || echo "false")
|
|
47
|
+
FAILED_PHASES=\$(jq -r '
|
|
48
|
+
[."mem:bind-state".current.phases
|
|
49
|
+
| to_entries[]
|
|
50
|
+
| select(.value.status == "failed")
|
|
51
|
+
| .key] | join(",")
|
|
52
|
+
' "\$NECRONOMICON" 2>/dev/null || echo "")
|
|
53
|
+
PENDING_PHASES=\$(jq -r '
|
|
54
|
+
[."mem:bind-state".current.phases
|
|
55
|
+
| to_entries[]
|
|
56
|
+
| select(.value.status == "pending" or .value.status == "in_progress")
|
|
57
|
+
| .key] | join(",")
|
|
58
|
+
' "\$NECRONOMICON" 2>/dev/null || echo "")
|
|
59
|
+
fi
|
|
60
|
+
PENDING_COUNT=\$(jq -r '
|
|
61
|
+
."mem:pending-compression".state.count // 0
|
|
62
|
+
' "\$NECRONOMICON" 2>/dev/null || echo "0")
|
|
63
|
+
fi
|
|
64
|
+
|
|
30
65
|
cat <<'PROMPT'
|
|
31
66
|
[oh-my-claudecode: Cthulhu orchestrator auto-activated — .elder-gods/ detected]
|
|
32
67
|
|
|
@@ -65,19 +100,48 @@ Classification flow for each user message:
|
|
|
65
100
|
- Implementation → plan with todos, then delegate or execute
|
|
66
101
|
- Ambiguous → exactly one clarifying question
|
|
67
102
|
|
|
68
|
-
First-run Necronomicon preflight (do this ONCE per session, on first user
|
|
69
|
-
message, not before every message):
|
|
70
|
-
- Try calling yith_context({ project: "." }). It's a cheap reachability probe.
|
|
71
|
-
- If the yith_context tool does NOT exist in your available tool list, OR the
|
|
72
|
-
call errors with an MCP-not-connected message, the Necronomicon has not
|
|
73
|
-
been bound on this machine. Tell the user: "The Necronomicon is not yet
|
|
74
|
-
bound. Run /bind-necronomicon to run the first-time setup ritual, then
|
|
75
|
-
start a new session — or proceed without persistent memory for this one."
|
|
76
|
-
Wait for the user's decision before acting on their original request.
|
|
77
|
-
- If the call succeeds (even with empty context), proceed silently.
|
|
78
|
-
|
|
79
103
|
[END cthulhu orchestrator injection]
|
|
80
104
|
PROMPT
|
|
105
|
+
|
|
106
|
+
# --- Dynamic Necronomicon preflight ---
|
|
107
|
+
# Emit a tailored preflight block based on the bindState flags we
|
|
108
|
+
# extracted above. The text here drives Cthulhu's first-user-message
|
|
109
|
+
# behavior: hard-block on unbound Necronomicon, nag on failures,
|
|
110
|
+
# offer to drain pending compression when the queue is non-empty.
|
|
111
|
+
echo
|
|
112
|
+
echo "[Necronomicon preflight]"
|
|
113
|
+
if [ "\$BIND_EXISTS" = "false" ]; then
|
|
114
|
+
echo
|
|
115
|
+
echo "The Necronomicon has not been bound on this machine yet. The Yith"
|
|
116
|
+
echo "Archive is empty and no past Claude Code sessions have been ingested."
|
|
117
|
+
echo
|
|
118
|
+
echo "**Action required**: tell the user to run \\\`oh-my-claudecode bind\\\`"
|
|
119
|
+
echo "in their terminal OR \\\`/necronomicon-bind\\\` inside this session"
|
|
120
|
+
echo "before proceeding with any memory-dependent work."
|
|
121
|
+
elif [ -n "\$FAILED_PHASES" ]; then
|
|
122
|
+
echo
|
|
123
|
+
echo "The binding ritual has failed phases: \$FAILED_PHASES"
|
|
124
|
+
echo "Re-run \\\`/necronomicon-bind\\\` (or \\\`oh-my-claudecode bind --resume\\\`"
|
|
125
|
+
echo "in a terminal) to retry from the failed phase — the state machine"
|
|
126
|
+
echo "resumes automatically without redoing completed work."
|
|
127
|
+
elif [ "\$ALL_COMPLETE" != "true" ]; then
|
|
128
|
+
echo
|
|
129
|
+
echo "The Necronomicon is partially bound. Pending phases: \$PENDING_PHASES"
|
|
130
|
+
echo "Run \\\`/necronomicon-bind\\\` to continue the ritual from where it stopped."
|
|
131
|
+
elif [ "\$PENDING_COUNT" != "0" ]; then
|
|
132
|
+
echo
|
|
133
|
+
echo "✓ Necronomicon bound. \$PENDING_COUNT raw observations are queued for"
|
|
134
|
+
echo "compression into searchable memories."
|
|
135
|
+
echo
|
|
136
|
+
echo "**Offer the user**: \"Process pending compression now (runs via the"
|
|
137
|
+
echo "work-packet loop using this session's LLM)? It takes one commit round"
|
|
138
|
+
echo "per batch.\" If they accept, call yith_trigger with"
|
|
139
|
+
echo "mem::compress-batch-step and drive the needs_llm_work -> yith_commit_work"
|
|
140
|
+
echo "loop until terminal. Render an ASCII progress bar per round."
|
|
141
|
+
else
|
|
142
|
+
echo
|
|
143
|
+
echo "✓ Necronomicon is bound and every phase is complete. Nothing pending."
|
|
144
|
+
fi
|
|
81
145
|
`;
|
|
82
146
|
export function getCthulhuAutoHookConfig() {
|
|
83
147
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cthulhu-auto.js","sourceRoot":"","sources":["../../src/hooks/cthulhu-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG
|
|
1
|
+
{"version":3,"file":"cthulhu-auto.js","sourceRoot":"","sources":["../../src/hooks/cthulhu-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqIvC,CAAA;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,OAAO,EAAE,EAAE;QACX,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,iCAAiC;aAC3C;SACF;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cthulhu preflight text generator.
|
|
3
|
+
*
|
|
4
|
+
* Called from the cthulhu-auto hook shell script (indirectly — the
|
|
5
|
+
* shell script reads bindState from necronomicon.json via jq and
|
|
6
|
+
* passes the extracted flags to this helper to produce the prompt
|
|
7
|
+
* fragment to inject into the session). Also called directly from
|
|
8
|
+
* the /cthulhu slash command docs.
|
|
9
|
+
*
|
|
10
|
+
* The function is pure: no file I/O, no process.env reads. Callers
|
|
11
|
+
* provide a snapshot of the relevant state and get back a markdown
|
|
12
|
+
* block to drop into the activation prompt.
|
|
13
|
+
*
|
|
14
|
+
* The generated block is split into three concerns, in priority order:
|
|
15
|
+
* 1. Hard block: Necronomicon not bound at all → tell user to run
|
|
16
|
+
* /necronomicon-bind before doing anything else.
|
|
17
|
+
* 2. Soft alert: bind partially done or phases failed → offer retry.
|
|
18
|
+
* 3. Nag: compression queue has entries → offer to drain via WP loop.
|
|
19
|
+
*
|
|
20
|
+
* If none of the above apply (everything bound, no pending work), the
|
|
21
|
+
* output is a short one-liner confirming the archive is ready — NOT
|
|
22
|
+
* an empty string, so the injected prompt always has a visible status.
|
|
23
|
+
*/
|
|
24
|
+
export type BindPhaseName = "embedding_download" | "claude_transcripts" | "opencode_import" | "sisyphus_migrate" | "preliminary_seed" | "pending_compression_trigger";
|
|
25
|
+
export interface PreflightInput {
|
|
26
|
+
/** True if `KV.bindState → "current"` exists on disk. */
|
|
27
|
+
bindStateExists: boolean;
|
|
28
|
+
/** True if every phase has status "completed". */
|
|
29
|
+
allPhasesComplete: boolean;
|
|
30
|
+
/** Current raw-observation count pending compression. */
|
|
31
|
+
pendingCompressionCount: number;
|
|
32
|
+
/** Phases in the "failed" status, in execution order. */
|
|
33
|
+
failedPhases: BindPhaseName[];
|
|
34
|
+
/** Phases in "pending" or "in_progress" (not counting failed).
|
|
35
|
+
* Used to display a hint when the bind is partially done. */
|
|
36
|
+
pendingPhases?: BindPhaseName[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build the preflight markdown block. Always returns non-empty text —
|
|
40
|
+
* the calling hook injects whatever this returns into the session's
|
|
41
|
+
* activation prompt, and an empty injection would make the hook's
|
|
42
|
+
* behavior indistinguishable from "no hook ran."
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildPreflightSection(input: PreflightInput): string;
|
|
45
|
+
//# sourceMappingURL=cthulhu-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cthulhu-preflight.d.ts","sourceRoot":"","sources":["../../src/hooks/cthulhu-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,MAAM,aAAa,GACrB,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,6BAA6B,CAAA;AAEjC,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,eAAe,EAAE,OAAO,CAAA;IACxB,kDAAkD;IAClD,iBAAiB,EAAE,OAAO,CAAA;IAC1B,yDAAyD;IACzD,uBAAuB,EAAE,MAAM,CAAA;IAC/B,yDAAyD;IACzD,YAAY,EAAE,aAAa,EAAE,CAAA;IAC7B;kEAC8D;IAC9D,aAAa,CAAC,EAAE,aAAa,EAAE,CAAA;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAmFnE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cthulhu preflight text generator.
|
|
3
|
+
*
|
|
4
|
+
* Called from the cthulhu-auto hook shell script (indirectly — the
|
|
5
|
+
* shell script reads bindState from necronomicon.json via jq and
|
|
6
|
+
* passes the extracted flags to this helper to produce the prompt
|
|
7
|
+
* fragment to inject into the session). Also called directly from
|
|
8
|
+
* the /cthulhu slash command docs.
|
|
9
|
+
*
|
|
10
|
+
* The function is pure: no file I/O, no process.env reads. Callers
|
|
11
|
+
* provide a snapshot of the relevant state and get back a markdown
|
|
12
|
+
* block to drop into the activation prompt.
|
|
13
|
+
*
|
|
14
|
+
* The generated block is split into three concerns, in priority order:
|
|
15
|
+
* 1. Hard block: Necronomicon not bound at all → tell user to run
|
|
16
|
+
* /necronomicon-bind before doing anything else.
|
|
17
|
+
* 2. Soft alert: bind partially done or phases failed → offer retry.
|
|
18
|
+
* 3. Nag: compression queue has entries → offer to drain via WP loop.
|
|
19
|
+
*
|
|
20
|
+
* If none of the above apply (everything bound, no pending work), the
|
|
21
|
+
* output is a short one-liner confirming the archive is ready — NOT
|
|
22
|
+
* an empty string, so the injected prompt always has a visible status.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Build the preflight markdown block. Always returns non-empty text —
|
|
26
|
+
* the calling hook injects whatever this returns into the session's
|
|
27
|
+
* activation prompt, and an empty injection would make the hook's
|
|
28
|
+
* behavior indistinguishable from "no hook ran."
|
|
29
|
+
*/
|
|
30
|
+
export function buildPreflightSection(input) {
|
|
31
|
+
const lines = [];
|
|
32
|
+
lines.push("[Necronomicon preflight]");
|
|
33
|
+
// Priority 1: hard block.
|
|
34
|
+
if (!input.bindStateExists) {
|
|
35
|
+
lines.push("");
|
|
36
|
+
lines.push("The Necronomicon has not been bound on this machine yet. The Yith " +
|
|
37
|
+
"Archive is empty and no past Claude Code sessions have been ingested.");
|
|
38
|
+
lines.push("");
|
|
39
|
+
lines.push("**Action required**: ask the user to run `oh-my-claudecode bind` in " +
|
|
40
|
+
"their terminal OR `/necronomicon-bind` inside this session before " +
|
|
41
|
+
"proceeding with any memory-dependent work.");
|
|
42
|
+
return lines.join("\n");
|
|
43
|
+
}
|
|
44
|
+
// Priority 2: failures.
|
|
45
|
+
if (input.failedPhases.length > 0) {
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push(`The binding ritual has ${input.failedPhases.length} failed ` +
|
|
48
|
+
`phase(s): ${input.failedPhases.join(", ")}.`);
|
|
49
|
+
lines.push("Re-run `/necronomicon-bind` (or `oh-my-claudecode bind --resume` in a " +
|
|
50
|
+
"terminal) to retry from the failed phase — the state machine resumes " +
|
|
51
|
+
"automatically without redoing completed work.");
|
|
52
|
+
return lines.join("\n");
|
|
53
|
+
}
|
|
54
|
+
// Priority 3: partial bind.
|
|
55
|
+
const pendingPhases = input.pendingPhases ?? [];
|
|
56
|
+
if (!input.allPhasesComplete) {
|
|
57
|
+
lines.push("");
|
|
58
|
+
lines.push(`The Necronomicon is partially bound. Pending phases: ` +
|
|
59
|
+
(pendingPhases.length > 0
|
|
60
|
+
? pendingPhases.join(", ")
|
|
61
|
+
: "(unknown — check bindState)") +
|
|
62
|
+
".");
|
|
63
|
+
lines.push("Run `/necronomicon-bind` to continue the ritual from where it stopped.");
|
|
64
|
+
if (input.pendingCompressionCount > 0) {
|
|
65
|
+
lines.push("");
|
|
66
|
+
lines.push(`${input.pendingCompressionCount} raw observations are already ` +
|
|
67
|
+
"ingested and waiting for compression. See pending-compression note below.");
|
|
68
|
+
}
|
|
69
|
+
return lines.join("\n");
|
|
70
|
+
}
|
|
71
|
+
// Priority 4: nag for pending compression (bind complete, queue non-empty).
|
|
72
|
+
if (input.pendingCompressionCount > 0) {
|
|
73
|
+
lines.push("");
|
|
74
|
+
lines.push(`✓ Necronomicon bound. ${input.pendingCompressionCount} raw ` +
|
|
75
|
+
"observations are queued for compression into searchable memories.");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("**Offer the user**: \"Process pending compression now (runs via the " +
|
|
78
|
+
"work-packet loop using this session's LLM)? It takes one commit " +
|
|
79
|
+
"round per batch.\" If they accept, call " +
|
|
80
|
+
"`yith_trigger({ name: 'mem::compress-batch-step', args: { limit: 100 } })` " +
|
|
81
|
+
"and drive the `needs_llm_work` → `yith_commit_work` loop until terminal. " +
|
|
82
|
+
"Render an ASCII progress bar per round so the user sees forward motion.");
|
|
83
|
+
return lines.join("\n");
|
|
84
|
+
}
|
|
85
|
+
// All clear.
|
|
86
|
+
lines.push("");
|
|
87
|
+
lines.push("✓ Necronomicon is bound and every phase is complete. The Great " +
|
|
88
|
+
"Race of Yith answers. Nothing pending.");
|
|
89
|
+
return lines.join("\n");
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=cthulhu-preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cthulhu-preflight.js","sourceRoot":"","sources":["../../src/hooks/cthulhu-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAwBH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;IAEtC,0BAA0B;IAC1B,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,oEAAoE;YAClE,uEAAuE,CAC1E,CAAA;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,sEAAsE;YACpE,oEAAoE;YACpE,4CAA4C,CAC/C,CAAA;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,0BAA0B,KAAK,CAAC,YAAY,CAAC,MAAM,UAAU;YAC3D,aAAa,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAChD,CAAA;QACD,KAAK,CAAC,IAAI,CACR,wEAAwE;YACtE,uEAAuE;YACvE,+CAA+C,CAClD,CAAA;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,4BAA4B;IAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,CAAA;IAC/C,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,uDAAuD;YACrD,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;gBACvB,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC1B,CAAC,CAAC,6BAA6B,CAAC;YAClC,GAAG,CACN,CAAA;QACD,KAAK,CAAC,IAAI,CACR,wEAAwE,CACzE,CAAA;QACD,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,uBAAuB,gCAAgC;gBAC9D,2EAA2E,CAC9E,CAAA;QACH,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,4EAA4E;IAC5E,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,yBAAyB,KAAK,CAAC,uBAAuB,OAAO;YAC3D,mEAAmE,CACtE,CAAA;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CACR,sEAAsE;YACpE,kEAAkE;YAClE,0CAA0C;YAC1C,6EAA6E;YAC7E,2EAA2E;YAC3E,yEAAyE,CAC5E,CAAA;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,aAAa;IACb,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,IAAI,CAAC,iEAAiE;QAC1E,wCAAwC,CAAC,CAAA;IAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-claudecode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Cthulhu-themed agentic harness for Claude Code — 11 Elder God agents, lifecycle hooks, skill system, and multi-tier orchestration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"smoke": "node -e \"import('./dist/index.js').then(() => console.log('ok'))\"",
|
|
24
24
|
"dev": "tsc --watch",
|
|
25
25
|
"install-plugin": "bun src/cli/index.ts install",
|
|
26
|
-
"doctor": "bun src/cli/index.ts doctor"
|
|
26
|
+
"doctor": "bun src/cli/index.ts doctor",
|
|
27
|
+
"test": "node --import tsx --test --test-reporter=spec 'tests/**/*.test.ts'",
|
|
28
|
+
"test:watch": "node --import tsx --test --watch 'tests/**/*.test.ts'"
|
|
27
29
|
},
|
|
28
30
|
"repository": {
|
|
29
31
|
"type": "git",
|
|
@@ -50,6 +52,7 @@
|
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@types/node": "^22.0.0",
|
|
55
|
+
"tsx": "^4.21.0",
|
|
53
56
|
"typescript": "^5.5.0"
|
|
54
57
|
},
|
|
55
58
|
"engines": {
|
|
File without changes
|