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.
Files changed (64) hide show
  1. package/README.md +48 -1
  2. package/dist/cli/bind-cron.d.ts +86 -0
  3. package/dist/cli/bind-cron.d.ts.map +1 -0
  4. package/dist/cli/bind-cron.js +161 -0
  5. package/dist/cli/bind-cron.js.map +1 -0
  6. package/dist/cli/bind.d.ts +78 -0
  7. package/dist/cli/bind.d.ts.map +1 -0
  8. package/dist/cli/bind.js +417 -0
  9. package/dist/cli/bind.js.map +1 -0
  10. package/dist/cli/index.js +61 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/project-scan.d.ts +94 -0
  13. package/dist/cli/project-scan.d.ts.map +1 -0
  14. package/dist/cli/project-scan.js +387 -0
  15. package/dist/cli/project-scan.js.map +1 -0
  16. package/dist/cli/sisyphus-migrate.d.ts +50 -0
  17. package/dist/cli/sisyphus-migrate.d.ts.map +1 -0
  18. package/dist/cli/sisyphus-migrate.js +226 -0
  19. package/dist/cli/sisyphus-migrate.js.map +1 -0
  20. package/dist/cli/tui.d.ts +94 -0
  21. package/dist/cli/tui.d.ts.map +1 -0
  22. package/dist/cli/tui.js +180 -0
  23. package/dist/cli/tui.js.map +1 -0
  24. package/dist/features/yith-archive/functions/backfill.d.ts +43 -0
  25. package/dist/features/yith-archive/functions/backfill.d.ts.map +1 -1
  26. package/dist/features/yith-archive/functions/backfill.js +303 -145
  27. package/dist/features/yith-archive/functions/backfill.js.map +1 -1
  28. package/dist/features/yith-archive/functions/compress-batch.d.ts +4 -0
  29. package/dist/features/yith-archive/functions/compress-batch.d.ts.map +1 -0
  30. package/dist/features/yith-archive/functions/compress-batch.js +290 -0
  31. package/dist/features/yith-archive/functions/compress-batch.js.map +1 -0
  32. package/dist/features/yith-archive/functions/compress.d.ts +2 -1
  33. package/dist/features/yith-archive/functions/compress.d.ts.map +1 -1
  34. package/dist/features/yith-archive/functions/compress.js +1 -1
  35. package/dist/features/yith-archive/functions/compress.js.map +1 -1
  36. package/dist/features/yith-archive/functions/opencode-import.d.ts +67 -0
  37. package/dist/features/yith-archive/functions/opencode-import.d.ts.map +1 -0
  38. package/dist/features/yith-archive/functions/opencode-import.js +272 -0
  39. package/dist/features/yith-archive/functions/opencode-import.js.map +1 -0
  40. package/dist/features/yith-archive/index.d.ts.map +1 -1
  41. package/dist/features/yith-archive/index.js +4 -0
  42. package/dist/features/yith-archive/index.js.map +1 -1
  43. package/dist/features/yith-archive/providers/embedding/local.d.ts +22 -0
  44. package/dist/features/yith-archive/providers/embedding/local.d.ts.map +1 -1
  45. package/dist/features/yith-archive/providers/embedding/local.js +56 -2
  46. package/dist/features/yith-archive/providers/embedding/local.js.map +1 -1
  47. package/dist/features/yith-archive/state/bind-state.d.ts +84 -0
  48. package/dist/features/yith-archive/state/bind-state.d.ts.map +1 -0
  49. package/dist/features/yith-archive/state/bind-state.js +120 -0
  50. package/dist/features/yith-archive/state/bind-state.js.map +1 -0
  51. package/dist/features/yith-archive/state/schema.d.ts +14 -0
  52. package/dist/features/yith-archive/state/schema.d.ts.map +1 -1
  53. package/dist/features/yith-archive/state/schema.js +14 -0
  54. package/dist/features/yith-archive/state/schema.js.map +1 -1
  55. package/dist/hooks/cthulhu-auto.d.ts +1 -1
  56. package/dist/hooks/cthulhu-auto.d.ts.map +1 -1
  57. package/dist/hooks/cthulhu-auto.js +75 -11
  58. package/dist/hooks/cthulhu-auto.js.map +1 -1
  59. package/dist/hooks/cthulhu-preflight.d.ts +45 -0
  60. package/dist/hooks/cthulhu-preflight.d.ts.map +1 -0
  61. package/dist/hooks/cthulhu-preflight.js +91 -0
  62. package/dist/hooks/cthulhu-preflight.js.map +1 -0
  63. package/package.json +5 -2
  64. /package/commands/{bind-necronomicon.md → necronomicon-bind.md} +0 -0
@@ -0,0 +1,417 @@
1
+ /**
2
+ * oh-my-claudecode bind — the CLI subcommand that drives the
3
+ * Necronomicon binding ritual.
4
+ *
5
+ * Architecture: a state-machine runner (`runBind`) reads `KV.bindState`,
6
+ * walks through each phase in `BIND_PHASE_ORDER`, invokes the matching
7
+ * `PhaseRunner`, and persists progress after every transition. Phases
8
+ * are injectable — tests pass fakes; production passes the real
9
+ * runners defined in `defaultPhaseRunners()`.
10
+ *
11
+ * Failure semantics: if any phase throws, `runBind` records the error
12
+ * into bindState, halts (does NOT run subsequent phases), and returns.
13
+ * The CLI entry point surfaces the error via the TUI and exits with
14
+ * a non-zero code. A re-run picks up from the failed phase and retries
15
+ * it — the state machine treats `failed` the same as `pending`.
16
+ *
17
+ * Cron-friendly: the same entry point is called from `bind --resume`
18
+ * which prints to stdout and exits, so a crontab can invoke it on
19
+ * an interval without an interactive session.
20
+ */
21
+ import { existsSync, readdirSync, statSync } from "node:fs";
22
+ import { homedir } from "node:os";
23
+ import { join } from "node:path";
24
+ import { KV } from "../features/yith-archive/state/schema.js";
25
+ import { migrateSisyphusDir } from "./sisyphus-migrate.js";
26
+ import { projectSummaryToObservations, scanProject, } from "./project-scan.js";
27
+ import { BIND_PHASE_ORDER, firstPendingPhase, initialBindState, markPhase, } from "../features/yith-archive/state/bind-state.js";
28
+ import { renderProgressBar, renderSectionHeader, renderStatusLine, formatBytes, formatDuration, } from "./tui.js";
29
+ // ============================================================================
30
+ // Phase label + runner
31
+ // ============================================================================
32
+ /** Human-readable label for each phase — what the user sees in the TUI. */
33
+ function phaseLabel(phase) {
34
+ switch (phase) {
35
+ case "embedding_download":
36
+ return "Phase I: The Embedding Sigil";
37
+ case "claude_transcripts":
38
+ return "Phase II: Claude Code Transcripts";
39
+ case "opencode_import":
40
+ return "Phase III: Opencode Grimoire";
41
+ case "sisyphus_migrate":
42
+ return "Phase IV: Sisyphus Migration";
43
+ case "preliminary_seed":
44
+ return "Phase V: Project Code Scan";
45
+ case "pending_compression_trigger":
46
+ return "Phase VI: Sealing the Tome";
47
+ }
48
+ }
49
+ /**
50
+ * State-machine driver. Reads bindState, runs pending phases in order,
51
+ * persists progress after each, halts on first failure.
52
+ *
53
+ * Returns the final BindState so callers (the CLI entry point) can
54
+ * summarize what happened and exit with the right code.
55
+ */
56
+ export async function runBind(opts) {
57
+ const { archive, tui, phases = defaultPhaseRunners(), force } = opts;
58
+ const kv = archive.kv;
59
+ // Load or create bindState.
60
+ let state = (await kv.get(KV.bindState, "current").catch(() => null)) ??
61
+ initialBindState();
62
+ // If the user asked for a forced re-run of specific phases, reset
63
+ // them to pending before walking the state machine.
64
+ if (force && force.length > 0) {
65
+ for (const phase of force) {
66
+ state = markPhase(state, phase, { status: "pending" });
67
+ }
68
+ await kv.set(KV.bindState, "current", state);
69
+ await kv.persist();
70
+ }
71
+ tui.line(renderSectionHeader("Necronomicon Binding Ritual"));
72
+ tui.line(renderStatusLine("info", `Necronomicon: ${necronomiconPath()}`));
73
+ // Report any already-completed phases so the user sees resume state.
74
+ for (const phase of BIND_PHASE_ORDER) {
75
+ if (state.phases[phase].status === "completed") {
76
+ tui.line(renderStatusLine("ok", `${phaseLabel(phase)} (already bound)`));
77
+ }
78
+ }
79
+ const started = Date.now();
80
+ while (true) {
81
+ const phase = firstPendingPhase(state);
82
+ if (phase === null)
83
+ break;
84
+ const runner = phases.find((p) => p.name === phase);
85
+ if (!runner) {
86
+ // No runner registered for this phase — treat as completed
87
+ // (phase isn't implemented yet). Mark it completed so we don't
88
+ // block forever, and note it in the details.
89
+ tui.line(renderStatusLine("warn", `${phaseLabel(phase)} — no runner registered, skipping`));
90
+ state = markPhase(state, phase, {
91
+ status: "completed",
92
+ details: { skipped: true, reason: "no runner registered" },
93
+ });
94
+ await kv.set(KV.bindState, "current", state);
95
+ await kv.persist();
96
+ continue;
97
+ }
98
+ // Mark in_progress, persist, announce.
99
+ state = markPhase(state, phase, { status: "in_progress" });
100
+ await kv.set(KV.bindState, "current", state);
101
+ await kv.persist();
102
+ tui.line(renderSectionHeader(phaseLabel(phase)));
103
+ const phaseStarted = Date.now();
104
+ try {
105
+ const result = await runner.run({ archive, tui });
106
+ const elapsed = formatDuration(Date.now() - phaseStarted);
107
+ state = markPhase(state, phase, {
108
+ status: "completed",
109
+ details: result.details,
110
+ });
111
+ await kv.set(KV.bindState, "current", state);
112
+ await kv.persist();
113
+ tui.line(renderStatusLine("ok", `${phaseLabel(phase)} — complete in ${elapsed}`));
114
+ }
115
+ catch (err) {
116
+ const msg = err instanceof Error ? err.message : String(err);
117
+ state = markPhase(state, phase, { status: "failed", error: msg });
118
+ await kv.set(KV.bindState, "current", state);
119
+ await kv.persist();
120
+ tui.line(renderStatusLine("error", `${phaseLabel(phase)} — ${msg}`));
121
+ tui.line(renderStatusLine("info", "Re-run `oh-my-claudecode bind` to retry from this phase."));
122
+ return state;
123
+ }
124
+ }
125
+ const totalElapsed = formatDuration(Date.now() - started);
126
+ tui.line(renderSectionHeader("Binding Complete"));
127
+ tui.line(renderStatusLine("ok", `The Necronomicon is bound. Ritual elapsed: ${totalElapsed}`));
128
+ // Pending-compression teaser so the user knows what comes next.
129
+ const pending = await kv
130
+ .get(KV.pendingCompression, "state")
131
+ .catch(() => null);
132
+ if (pending && pending.count > 0) {
133
+ tui.line(renderStatusLine("info", `${pending.count} raw observations awaiting compression — ` +
134
+ `processed in the background or via /necronomicon-bind in a session.`));
135
+ }
136
+ return state;
137
+ }
138
+ // ============================================================================
139
+ // Default phase runners
140
+ // ============================================================================
141
+ /** Path where the Necronomicon file lives on this machine. */
142
+ function necronomiconPath() {
143
+ return join(homedir(), ".oh-my-claudecode", "yith", "necronomicon.json");
144
+ }
145
+ /**
146
+ * Walk the given root directory up to `maxDepth` levels deep looking
147
+ * for `.sisyphus/` subdirectories. Used by the sisyphus migration
148
+ * phase to find every legacy project that needs translating without
149
+ * requiring the user to enumerate them. Excludes well-known heavy
150
+ * paths (node_modules, .git, .cache) to keep the walk bounded.
151
+ */
152
+ function findSisyphusDirs(root, maxDepth) {
153
+ const skip = new Set([
154
+ "node_modules",
155
+ ".git",
156
+ ".cache",
157
+ ".next",
158
+ "dist",
159
+ ".oh-my-claudecode",
160
+ ".claude",
161
+ ".npm",
162
+ ".npm-global",
163
+ ]);
164
+ const out = [];
165
+ const walk = (dir, depth) => {
166
+ if (depth > maxDepth)
167
+ return;
168
+ let entries;
169
+ try {
170
+ entries = readdirSync(dir);
171
+ }
172
+ catch {
173
+ return;
174
+ }
175
+ for (const entry of entries) {
176
+ if (skip.has(entry))
177
+ continue;
178
+ const full = join(dir, entry);
179
+ let s;
180
+ try {
181
+ s = statSync(full);
182
+ }
183
+ catch {
184
+ continue;
185
+ }
186
+ if (!s.isDirectory())
187
+ continue;
188
+ if (entry === ".sisyphus") {
189
+ out.push(full);
190
+ continue; // don't recurse into .sisyphus itself
191
+ }
192
+ walk(full, depth + 1);
193
+ }
194
+ };
195
+ walk(root, 0);
196
+ return out;
197
+ }
198
+ /**
199
+ * Production phase runners. Tests inject fakes; the CLI entry point
200
+ * uses these defaults.
201
+ *
202
+ * Each runner is a thin wrapper that calls the underlying feature
203
+ * (provider warmup, backfill function, opencode importer, etc.) and
204
+ * reports progress via the context's TUI writer.
205
+ *
206
+ * Phases B, C, and D (opencode_import, sisyphus_migrate,
207
+ * preliminary_seed) currently register placeholders that log a
208
+ * "pending implementation" status and complete without work. They
209
+ * get real implementations in their respective phase files.
210
+ */
211
+ export function defaultPhaseRunners() {
212
+ return [
213
+ {
214
+ name: "embedding_download",
215
+ async run({ archive, tui }) {
216
+ const provider = archive.embeddingProvider;
217
+ if (!provider || typeof provider.warmUp !== "function") {
218
+ tui.line(renderStatusLine("info", "No embedding provider configured — BM25-only mode, skipping model download."));
219
+ return { details: { skipped: true, reason: "no embedding provider" } };
220
+ }
221
+ tui.line(renderStatusLine("pending", `Fetching ${provider.name ?? "embedding model"}...`));
222
+ let lastLoaded = 0;
223
+ let lastTotal = 0;
224
+ await provider.warmUp({
225
+ onProgress: (e) => {
226
+ if (e.phase === "downloading" && e.loaded && e.total) {
227
+ lastLoaded = e.loaded;
228
+ lastTotal = e.total;
229
+ tui.replaceLastLine(renderProgressBar({
230
+ current: e.loaded,
231
+ total: e.total,
232
+ label: `${formatBytes(e.loaded)} / ${formatBytes(e.total)}`,
233
+ }));
234
+ }
235
+ else if (e.phase === "loading") {
236
+ tui.line(renderStatusLine("pending", e.message ?? "Loading..."));
237
+ }
238
+ else if (e.phase === "ready") {
239
+ tui.line(renderStatusLine("ok", e.message ?? "Embedding model ready"));
240
+ }
241
+ },
242
+ });
243
+ return {
244
+ details: {
245
+ bytesDownloaded: lastLoaded,
246
+ totalBytes: lastTotal,
247
+ },
248
+ };
249
+ },
250
+ },
251
+ {
252
+ name: "claude_transcripts",
253
+ async run({ archive, tui }) {
254
+ tui.line(renderStatusLine("pending", "Scanning ~/.claude/projects/ for transcripts..."));
255
+ const result = (await archive.sdk.trigger("mem::backfill-sessions", {
256
+ allProjects: true,
257
+ dryRun: false,
258
+ }));
259
+ const projects = result.totalProjects ?? 0;
260
+ const obs = result.totalObservationsCreated ?? 0;
261
+ const transcripts = result.totalTranscriptsScanned ?? 0;
262
+ tui.line(renderStatusLine("ok", `Ingested ${obs} raw observations from ${transcripts} transcripts across ${projects} projects`));
263
+ // Per-project breakdown — lets the user see which projects
264
+ // contributed what at a glance. Truncate at 10 to keep the
265
+ // output manageable for users with many projects.
266
+ const perProject = result.perProject ?? [];
267
+ for (const p of perProject.slice(0, 10)) {
268
+ if (p.observationsCreated > 0) {
269
+ tui.line(renderStatusLine("info", `${p.projectCwd}: ${p.observationsCreated} obs`));
270
+ }
271
+ }
272
+ if (perProject.length > 10) {
273
+ tui.line(renderStatusLine("info", `... and ${perProject.length - 10} more projects`));
274
+ }
275
+ return { details: { projects, observations: obs, transcripts } };
276
+ },
277
+ },
278
+ {
279
+ name: "opencode_import",
280
+ async run({ archive, tui }) {
281
+ // Check if an opencode database exists at the default path.
282
+ // The function handles "not found" gracefully, but we short-
283
+ // circuit here so the TUI output is clearer.
284
+ const defaultDb = join(homedir(), ".local", "share", "opencode", "opencode.db");
285
+ if (!existsSync(defaultDb)) {
286
+ tui.line(renderStatusLine("info", "No opencode.db found — skipping opencode import."));
287
+ return { details: { skipped: true, reason: "no opencode db" } };
288
+ }
289
+ tui.line(renderStatusLine("pending", `Reading opencode history from ${defaultDb}...`));
290
+ const result = (await archive.sdk.trigger("mem::import-opencode", {
291
+ dbPath: defaultDb,
292
+ }));
293
+ if (!result.success) {
294
+ throw new Error(result.error ?? "opencode import failed");
295
+ }
296
+ tui.line(renderStatusLine("ok", `Imported ${result.observationsCreated} opencode observations ` +
297
+ `(${result.observationsSkipped} duplicates skipped) from ` +
298
+ `${result.sessionsScanned} sessions across ${result.projectsScanned} projects.`));
299
+ return {
300
+ details: {
301
+ created: result.observationsCreated,
302
+ skipped: result.observationsSkipped,
303
+ sessions: result.sessionsScanned,
304
+ projects: result.projectsScanned,
305
+ },
306
+ };
307
+ },
308
+ },
309
+ {
310
+ name: "sisyphus_migrate",
311
+ async run({ tui }) {
312
+ // Walk the user's home for any `.sisyphus/` dirs to migrate.
313
+ // We don't go deeper than 5 levels — sisyphus dirs were always
314
+ // project-root-scoped.
315
+ tui.line(renderStatusLine("pending", "Scanning for .sisyphus directories..."));
316
+ const discovered = findSisyphusDirs(homedir(), 5);
317
+ if (discovered.length === 0) {
318
+ tui.line(renderStatusLine("info", "No .sisyphus directories found."));
319
+ return { details: { dirs: 0 } };
320
+ }
321
+ let migrated = 0;
322
+ for (const dir of discovered) {
323
+ const projectRoot = join(dir, "..");
324
+ const dest = join(projectRoot, ".elder-gods");
325
+ const result = migrateSisyphusDir({ source: dir, dest });
326
+ const copied = result.plansCopied +
327
+ result.handoffsCopied +
328
+ result.evidenceCopied +
329
+ result.legacyCopied;
330
+ if (copied > 0) {
331
+ tui.line(renderStatusLine("ok", `${dir} → ${dest}: ${result.plansCopied} plans, ` +
332
+ `${result.handoffsCopied} handoffs, ` +
333
+ `${result.evidenceCopied} evidence files`));
334
+ migrated++;
335
+ }
336
+ }
337
+ return { details: { discovered: discovered.length, migrated } };
338
+ },
339
+ },
340
+ {
341
+ name: "preliminary_seed",
342
+ async run({ archive, tui }) {
343
+ // Scan every project directory we already know about (from
344
+ // the Claude Code transcripts phase) and emit synthesized
345
+ // preliminary observations. If the project dir no longer
346
+ // exists on disk, skip it with a warning.
347
+ tui.line(renderStatusLine("pending", "Scanning project code for preliminary memories..."));
348
+ // Re-enumerate sessions to find the set of project cwds.
349
+ const sessions = await archive.kv
350
+ .list(KV.sessions)
351
+ .catch(() => []);
352
+ const projectCwds = new Set();
353
+ for (const s of sessions) {
354
+ if (s.project && s.project.startsWith("/")) {
355
+ projectCwds.add(s.project);
356
+ }
357
+ }
358
+ let scanned = 0;
359
+ let created = 0;
360
+ for (const cwd of projectCwds) {
361
+ if (!existsSync(cwd))
362
+ continue;
363
+ try {
364
+ const summary = await scanProject(cwd);
365
+ const obs = projectSummaryToObservations(summary);
366
+ const sessionId = `proj:${cwd}`;
367
+ // Upsert a synthetic "project-scan" session so the
368
+ // observations land somewhere the search index can find.
369
+ await archive.kv.set(KV.sessions, sessionId, {
370
+ id: sessionId,
371
+ project: cwd,
372
+ cwd,
373
+ startedAt: new Date().toISOString(),
374
+ status: "completed",
375
+ observationCount: obs.length,
376
+ });
377
+ for (const o of obs) {
378
+ const existing = await archive.kv
379
+ .get(KV.observations(sessionId), o.id)
380
+ .catch(() => null);
381
+ if (existing)
382
+ continue;
383
+ await archive.kv.set(KV.observations(sessionId), o.id, { ...o, sessionId });
384
+ created++;
385
+ }
386
+ scanned++;
387
+ }
388
+ catch (err) {
389
+ tui.line(renderStatusLine("warn", `${cwd}: ${err instanceof Error ? err.message : String(err)}`));
390
+ }
391
+ }
392
+ tui.line(renderStatusLine("ok", `Scanned ${scanned} projects, seeded ${created} preliminary observations.`));
393
+ return { details: { scanned, created } };
394
+ },
395
+ },
396
+ {
397
+ name: "pending_compression_trigger",
398
+ async run({ archive, tui }) {
399
+ const pending = await archive.kv
400
+ .get(KV.pendingCompression, "state")
401
+ .catch(() => null);
402
+ const count = pending?.count ?? 0;
403
+ if (count > 0) {
404
+ tui.line(renderStatusLine("info", `${count} raw observations queued for compression. ` +
405
+ `Run /necronomicon-bind inside Claude Code to process them, ` +
406
+ `or install the cron entry with \`oh-my-claudecode bind --install-cron\` ` +
407
+ `for unattended background compression via \`claude -p\`.`));
408
+ }
409
+ else {
410
+ tui.line(renderStatusLine("ok", "No observations pending compression."));
411
+ }
412
+ return { details: { pendingCompression: count } };
413
+ },
414
+ },
415
+ ];
416
+ }
417
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.js","sourceRoot":"","sources":["../../src/cli/bind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,EAAE,EAAE,MAAM,0CAA0C,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EACL,4BAA4B,EAC5B,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,GAGV,MAAM,8CAA8C,CAAA;AACrD,OAAO,EAEL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,cAAc,GACf,MAAM,UAAU,CAAA;AAuCjB,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,2EAA2E;AAC3E,SAAS,UAAU,CAAC,KAAgB;IAClC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,oBAAoB;YACvB,OAAO,8BAA8B,CAAA;QACvC,KAAK,oBAAoB;YACvB,OAAO,mCAAmC,CAAA;QAC5C,KAAK,iBAAiB;YACpB,OAAO,8BAA8B,CAAA;QACvC,KAAK,kBAAkB;YACrB,OAAO,8BAA8B,CAAA;QACvC,KAAK,kBAAkB;YACrB,OAAO,4BAA4B,CAAA;QACrC,KAAK,6BAA6B;YAChC,OAAO,4BAA4B,CAAA;IACvC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAoB;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,mBAAmB,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IACpE,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAA;IAErB,4BAA4B;IAC5B,IAAI,KAAK,GACP,CAAC,MAAM,EAAE,CAAC,GAAG,CAAY,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpE,gBAAgB,EAAE,CAAA;IAEpB,kEAAkE;IAClE,oDAAoD;IACpD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QACxD,CAAC;QACD,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;QAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;IACpB,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,6BAA6B,CAAC,CAAC,CAAA;IAC5D,GAAG,CAAC,IAAI,CACN,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,gBAAgB,EAAE,EAAE,CAAC,CAChE,CAAA;IAED,qEAAqE;IACrE,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CACN,gBAAgB,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAC/D,CAAA;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE1B,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;QACtC,IAAI,KAAK,KAAK,IAAI;YAAE,MAAK;QAEzB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,2DAA2D;YAC3D,+DAA+D;YAC/D,6CAA6C;YAC7C,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,GAAG,UAAU,CAAC,KAAK,CAAC,mCAAmC,CACxD,CACF,CAAA;YACD,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE;gBAC9B,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE;aAC3D,CAAC,CAAA;YACF,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;YAClB,SAAQ;QACV,CAAC;QAED,uCAAuC;QACvC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;QAC1D,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;QAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;QAElB,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;YACjD,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,CAAA;YACzD,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE;gBAC9B,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAA;YACF,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;YAClB,GAAG,CAAC,IAAI,CACN,gBAAgB,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CACxE,CAAA;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;YACjE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;YAClB,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAA;YACpE,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,0DAA0D,CAC3D,CACF,CAAA;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAA;IACzD,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,CAAA;IACjD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,8CAA8C,YAAY,EAAE,CAC7D,CACF,CAAA;IACD,gEAAgE;IAChE,MAAM,OAAO,GAAG,MAAM,EAAE;SACrB,GAAG,CAAoB,EAAE,CAAC,kBAAkB,EAAE,OAAO,CAAC;SACtD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IACpB,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,GAAG,OAAO,CAAC,KAAK,2CAA2C;YACzD,qEAAqE,CACxE,CACF,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,8DAA8D;AAC9D,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAA;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,QAAgB;IACtD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC;QACnB,cAAc;QACd,MAAM;QACN,QAAQ;QACR,OAAO;QACP,MAAM;QACN,mBAAmB;QACnB,SAAS;QACT,MAAM;QACN,aAAa;KACd,CAAC,CAAA;IACF,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,KAAa,EAAQ,EAAE;QAChD,IAAI,KAAK,GAAG,QAAQ;YAAE,OAAM;QAC5B,IAAI,OAAiB,CAAA;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAQ;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YAC7B,IAAI,CAAC,CAAA;YACL,IAAI,CAAC;gBACH,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,SAAQ;YAC9B,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;gBAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACd,SAAQ,CAAC,sCAAsC;YACjD,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IACD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACb,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL;YACE,IAAI,EAAE,oBAAoB;YAC1B,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;gBACxB,MAAM,QAAQ,GAAI,OAYhB,CAAC,iBAAiB,CAAA;gBACpB,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACvD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,6EAA6E,CAC9E,CACF,CAAA;oBACD,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,uBAAuB,EAAE,EAAE,CAAA;gBACxE,CAAC;gBAED,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,SAAS,EACT,YAAY,QAAQ,CAAC,IAAI,IAAI,iBAAiB,KAAK,CACpD,CACF,CAAA;gBACD,IAAI,UAAU,GAAG,CAAC,CAAA;gBAClB,IAAI,SAAS,GAAG,CAAC,CAAA;gBACjB,MAAM,QAAQ,CAAC,MAAM,CAAC;oBACpB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;wBAChB,IAAI,CAAC,CAAC,KAAK,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;4BACrD,UAAU,GAAG,CAAC,CAAC,MAAM,CAAA;4BACrB,SAAS,GAAG,CAAC,CAAC,KAAK,CAAA;4BACnB,GAAG,CAAC,eAAe,CACjB,iBAAiB,CAAC;gCAChB,OAAO,EAAE,CAAC,CAAC,MAAM;gCACjB,KAAK,EAAE,CAAC,CAAC,KAAK;gCACd,KAAK,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;6BAC5D,CAAC,CACH,CAAA;wBACH,CAAC;6BAAM,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;4BACjC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,CAAA;wBAClE,CAAC;6BAAM,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;4BAC/B,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,CAAC,CAAC,OAAO,IAAI,uBAAuB,CACrC,CACF,CAAA;wBACH,CAAC;oBACH,CAAC;iBACF,CAAC,CAAA;gBACF,OAAO;oBACL,OAAO,EAAE;wBACP,eAAe,EAAE,UAAU;wBAC3B,UAAU,EAAE,SAAS;qBACtB;iBACF,CAAA;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;gBACxB,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,SAAS,EACT,iDAAiD,CAClD,CACF,CAAA;gBACD,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE;oBAClE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,KAAK;iBACd,CAAC,CAQD,CAAA;gBACD,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,IAAI,CAAC,CAAA;gBAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,wBAAwB,IAAI,CAAC,CAAA;gBAChD,MAAM,WAAW,GAAG,MAAM,CAAC,uBAAuB,IAAI,CAAC,CAAA;gBACvD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,YAAY,GAAG,0BAA0B,WAAW,uBAAuB,QAAQ,WAAW,CAC/F,CACF,CAAA;gBACD,2DAA2D;gBAC3D,2DAA2D;gBAC3D,kDAAkD;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAA;gBAC1C,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,CAAC,mBAAmB,GAAG,CAAC,EAAE,CAAC;wBAC9B,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,GAAG,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,mBAAmB,MAAM,CAChD,CACF,CAAA;oBACH,CAAC;gBACH,CAAC;gBACD,IAAI,UAAU,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBAC3B,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,WAAW,UAAU,CAAC,MAAM,GAAG,EAAE,gBAAgB,CAClD,CACF,CAAA;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,CAAA;YAClE,CAAC;SACF;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;gBACxB,4DAA4D;gBAC5D,6DAA6D;gBAC7D,6CAA6C;gBAC7C,MAAM,SAAS,GAAG,IAAI,CACpB,OAAO,EAAE,EACT,QAAQ,EACR,OAAO,EACP,UAAU,EACV,aAAa,CACd,CAAA;gBACD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC3B,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,kDAAkD,CACnD,CACF,CAAA;oBACD,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAA;gBACjE,CAAC;gBACD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,SAAS,EACT,iCAAiC,SAAS,KAAK,CAChD,CACF,CAAA;gBACD,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,sBAAsB,EAAE;oBAChE,MAAM,EAAE,SAAS;iBAClB,CAAC,CAOD,CAAA;gBACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAA;gBAC3D,CAAC;gBACD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,YAAY,MAAM,CAAC,mBAAmB,yBAAyB;oBAC7D,IAAI,MAAM,CAAC,mBAAmB,4BAA4B;oBAC1D,GAAG,MAAM,CAAC,eAAe,oBAAoB,MAAM,CAAC,eAAe,YAAY,CAClF,CACF,CAAA;gBACD,OAAO;oBACL,OAAO,EAAE;wBACP,OAAO,EAAE,MAAM,CAAC,mBAAmB;wBACnC,OAAO,EAAE,MAAM,CAAC,mBAAmB;wBACnC,QAAQ,EAAE,MAAM,CAAC,eAAe;wBAChC,QAAQ,EAAE,MAAM,CAAC,eAAe;qBACjC;iBACF,CAAA;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;gBACf,6DAA6D;gBAC7D,+DAA+D;gBAC/D,uBAAuB;gBACvB,GAAG,CAAC,IAAI,CACN,gBAAgB,CAAC,SAAS,EAAE,uCAAuC,CAAC,CACrE,CAAA;gBACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;gBACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC5B,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC,CAAA;oBACrE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAA;gBACjC,CAAC;gBACD,IAAI,QAAQ,GAAG,CAAC,CAAA;gBAChB,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;oBAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;oBACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA;oBAC7C,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;oBACxD,MAAM,MAAM,GACV,MAAM,CAAC,WAAW;wBAClB,MAAM,CAAC,cAAc;wBACrB,MAAM,CAAC,cAAc;wBACrB,MAAM,CAAC,YAAY,CAAA;oBACrB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;wBACf,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,GAAG,GAAG,MAAM,IAAI,KAAK,MAAM,CAAC,WAAW,UAAU;4BAC/C,GAAG,MAAM,CAAC,cAAc,aAAa;4BACrC,GAAG,MAAM,CAAC,cAAc,iBAAiB,CAC5C,CACF,CAAA;wBACD,QAAQ,EAAE,CAAA;oBACZ,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAA;YACjE,CAAC;SACF;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;gBACxB,2DAA2D;gBAC3D,0DAA0D;gBAC1D,yDAAyD;gBACzD,0CAA0C;gBAC1C,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,SAAS,EACT,mDAAmD,CACpD,CACF,CAAA;gBACD,yDAAyD;gBACzD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE;qBAC9B,IAAI,CAAkC,EAAE,CAAC,QAAQ,CAAC;qBAClD,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;gBAClB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;gBACrC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACzB,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC3C,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;oBAC5B,CAAC;gBACH,CAAC;gBACD,IAAI,OAAO,GAAG,CAAC,CAAA;gBACf,IAAI,OAAO,GAAG,CAAC,CAAA;gBACf,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;oBAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;wBAAE,SAAQ;oBAC9B,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAA;wBACtC,MAAM,GAAG,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAA;wBACjD,MAAM,SAAS,GAAG,QAAQ,GAAG,EAAE,CAAA;wBAC/B,mDAAmD;wBACnD,yDAAyD;wBACzD,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE;4BAC3C,EAAE,EAAE,SAAS;4BACb,OAAO,EAAE,GAAG;4BACZ,GAAG;4BACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;4BACnC,MAAM,EAAE,WAAW;4BACnB,gBAAgB,EAAE,GAAG,CAAC,MAAM;yBAC7B,CAAC,CAAA;wBACF,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;4BACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE;iCAC9B,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;iCACrC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;4BACpB,IAAI,QAAQ;gCAAE,SAAQ;4BACtB,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,CAClB,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAC1B,CAAC,CAAC,EAAE,EACJ,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,CACpB,CAAA;4BACD,OAAO,EAAE,CAAA;wBACX,CAAC;wBACD,OAAO,EAAE,CAAA;oBACX,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,GAAG,GAAG,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC9D,CACF,CAAA;oBACH,CAAC;gBACH,CAAC;gBACD,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,IAAI,EACJ,WAAW,OAAO,qBAAqB,OAAO,4BAA4B,CAC3E,CACF,CAAA;gBACD,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAA;YAC1C,CAAC;SACF;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;gBACxB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,EAAE;qBAC7B,GAAG,CAAoB,EAAE,CAAC,kBAAkB,EAAE,OAAO,CAAC;qBACtD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;gBACpB,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,CAAA;gBACjC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,GAAG,CAAC,IAAI,CACN,gBAAgB,CACd,MAAM,EACN,GAAG,KAAK,4CAA4C;wBAClD,6DAA6D;wBAC7D,0EAA0E;wBAC1E,0DAA0D,CAC7D,CACF,CAAA;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CACN,gBAAgB,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAC/D,CAAA;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,CAAA;YACnD,CAAC;SACF;KACF,CAAA;AACH,CAAC"}
package/dist/cli/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  import { Command } from "commander";
2
2
  import * as path from "path";
3
3
  import { fileURLToPath } from "url";
4
+ import { execFileSync } from "node:child_process";
4
5
  import { runInstall } from "./install.js";
5
6
  import { runDoctor, printYithFunctionCatalog } from "./doctor.js";
7
+ import { runBind } from "./bind.js";
8
+ import { buildClaudePSpawnCommand, buildCrontabLine, installCrontabEntry, parseIntervalSpec, } from "./bind-cron.js";
9
+ import { TuiWriter } from "./tui.js";
6
10
  const __filename = fileURLToPath(import.meta.url);
7
11
  const __dirname = path.dirname(__filename);
8
12
  const PACKAGE_ROOT = path.resolve(__dirname, "../..");
@@ -54,5 +58,62 @@ program
54
58
  }
55
59
  console.log();
56
60
  });
61
+ program
62
+ .command("bind")
63
+ .description("Run the Necronomicon binding ritual — download embedding model, " +
64
+ "ingest past transcripts, import opencode history, migrate sisyphus " +
65
+ "dirs, seed preliminary memories. Resumable.")
66
+ .option("--resume", "Cron-friendly: run only pending work and exit")
67
+ .option("--install-cron", "Install a system crontab entry that runs `bind --resume` on an interval")
68
+ .option("--interval <spec>", "Interval for the cron entry (e.g. 1h, 30m, 1d). Used with --install-cron.", "1h")
69
+ .option("--force <phase>", "Re-run a specific phase even if already completed")
70
+ .action(async (options) => {
71
+ if (options.installCron) {
72
+ // Install the crontab entry that runs `bind --resume`.
73
+ const schedule = parseIntervalSpec(options.interval ?? "1h");
74
+ const binCmd = process.argv[1] ?? "oh-my-claudecode";
75
+ const crontabBody = buildCrontabLine({
76
+ schedule,
77
+ command: `${binCmd} bind --resume`,
78
+ });
79
+ let current = "";
80
+ try {
81
+ current = execFileSync("crontab", ["-l"], {
82
+ encoding: "utf-8",
83
+ stdio: ["ignore", "pipe", "ignore"],
84
+ });
85
+ }
86
+ catch {
87
+ current = "";
88
+ }
89
+ const updated = installCrontabEntry(current, crontabBody);
90
+ execFileSync("crontab", ["-"], { input: updated });
91
+ console.log(`Installed crontab entry on schedule '${schedule}'. The cron ` +
92
+ `tick will run \`${binCmd} bind --resume\` to ingest new data ` +
93
+ `and drive compression via \`claude -p\`.`);
94
+ console.log(`Spawn command preview:\n ${buildClaudePSpawnCommand({})}`);
95
+ return;
96
+ }
97
+ const { createYithArchive } = await import("../features/yith-archive/index.js");
98
+ const archive = createYithArchive();
99
+ const tui = new TuiWriter({
100
+ write: (s) => process.stdout.write(s),
101
+ isTTY: process.stdout.isTTY ?? false,
102
+ });
103
+ try {
104
+ await runBind({
105
+ archive,
106
+ tui,
107
+ force: options.force
108
+ ? [
109
+ options.force,
110
+ ]
111
+ : undefined,
112
+ });
113
+ }
114
+ finally {
115
+ await archive.shutdown();
116
+ }
117
+ });
57
118
  program.parse();
58
119
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { RawObservation } from "../features/yith-archive/types.js";
2
+ /**
3
+ * Deep project scanner — Phase D of the binding ritual.
4
+ *
5
+ * Walks a project's directory tree (respecting .gitignore), parses
6
+ * the well-known package-manager metadata files, extracts README
7
+ * structure, counts language files by extension, and synthesizes a
8
+ * set of RawObservations summarizing the project. These observations
9
+ * get compressed into searchable memories later via the work-packet
10
+ * loop, so even brand-new projects with zero session history land in
11
+ * the Necronomicon with a useful baseline of context.
12
+ *
13
+ * Scope notes:
14
+ * - Walk depth is capped at 6 to avoid pathological directory trees.
15
+ * - File count is capped at 2000 so a leaked node_modules doesn't
16
+ * hang the scan.
17
+ * - Gitignore parsing is intentionally shallow — only the top-level
18
+ * .gitignore is respected, and only literal and glob-star patterns.
19
+ * Nested .gitignore files are skipped. This is a preliminary
20
+ * scan, not a perfect build tool.
21
+ * - Config file parsers cover the common cases (package.json,
22
+ * Cargo.toml, pyproject.toml, go.mod, composer.json, Gemfile).
23
+ * Rarer ones fall through to a "config file of unknown type"
24
+ * observation with the filename only.
25
+ */
26
+ export interface LanguageStats {
27
+ byExt: Record<string, number>;
28
+ primary: string;
29
+ total: number;
30
+ }
31
+ export interface ReadmeSections {
32
+ title: string | null;
33
+ firstParagraph: string | null;
34
+ headings: string[];
35
+ }
36
+ export interface PackageInfo {
37
+ name?: string;
38
+ version?: string;
39
+ description?: string;
40
+ runtimeDependencies: string[];
41
+ devDependencies: string[];
42
+ scripts: Record<string, string>;
43
+ entryPoint?: string;
44
+ }
45
+ export interface ProjectSummary {
46
+ path: string;
47
+ files: string[];
48
+ languages: LanguageStats;
49
+ packageInfo: PackageInfo | null;
50
+ readme: ReadmeSections | null;
51
+ configFiles: string[];
52
+ directoryTree: string;
53
+ }
54
+ /**
55
+ * Parse a .gitignore body into a flat list of patterns. Drops
56
+ * comment lines (# prefix) and empty lines. Trailing slashes on
57
+ * directory patterns are preserved so `isIgnored` can match them.
58
+ */
59
+ export declare function parseGitignore(body: string): string[];
60
+ /**
61
+ * Check whether a relative path matches any gitignore pattern.
62
+ * Supports literal names, `*.ext` globs, and trailing-slash
63
+ * directory patterns.
64
+ */
65
+ export declare function isIgnored(relPath: string, patterns: string[]): boolean;
66
+ /**
67
+ * Count file paths by extension and return the most-common one as
68
+ * the primary language indicator. Extensions include the leading dot
69
+ * so callers can distinguish `.ts` / `.tsx` / `.js` etc.
70
+ */
71
+ export declare function summarizeLanguages(files: string[]): LanguageStats;
72
+ /**
73
+ * Extract the top-level title, first paragraph, and H2 headings from
74
+ * a README markdown body. Used for the project-summary observation
75
+ * so downstream search has something to match against even when the
76
+ * README is the only source of truth about what the project does.
77
+ */
78
+ export declare function extractReadmeSections(body: string): ReadmeSections;
79
+ /**
80
+ * Parse a package.json body into a simplified PackageInfo summary.
81
+ * Returns null on malformed JSON — callers should handle the null
82
+ * case (e.g., emit a "malformed package.json" observation).
83
+ */
84
+ export declare function parsePackageJson(body: string): PackageInfo | null;
85
+ export declare function scanProject(root: string): Promise<ProjectSummary>;
86
+ /**
87
+ * Emit a set of RawObservations synthesized from the scan results.
88
+ * Every observation gets a stable ID derived from the project path
89
+ * plus the observation kind, so re-running the scan produces the
90
+ * same IDs and the idempotent-upsert path in the write layer
91
+ * dedupes automatically.
92
+ */
93
+ export declare function projectSummaryToObservations(summary: ProjectSummary): RawObservation[];
94
+ //# sourceMappingURL=project-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-scan.d.ts","sourceRoot":"","sources":["../../src/cli/project-scan.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAEjF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,SAAS,EAAE,aAAa,CAAA;IACxB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAA;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAgBtE;AAMD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,aAAa,CAiBjE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAoBlE;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA4BjE;AAgFD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAoEvE;AAiCD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,cAAc,GACtB,cAAc,EAAE,CA2FlB"}