@cleocode/cleo 2026.4.67 → 2026.4.68

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 (29) hide show
  1. package/dist/cli/index.js +640 -220
  2. package/dist/cli/index.js.map +4 -4
  3. package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/migration.sql +12 -0
  4. package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/snapshot.json +1232 -0
  5. package/migrations/drizzle-brain/20260408000001_t417-agent-field/migration.sql +13 -0
  6. package/migrations/drizzle-brain/20260408000001_t417-agent-field/snapshot.json +28 -0
  7. package/migrations/drizzle-brain/20260411000001_t528-graph-schema-expansion/migration.sql +47 -0
  8. package/migrations/drizzle-brain/20260412000001_t531-quality-score-typed-tables/migration.sql +23 -0
  9. package/migrations/drizzle-brain/20260413000001_t549-tiered-typed-memory/migration.sql +195 -0
  10. package/migrations/drizzle-brain/20260415000001_t626-normalize-co-retrieved-edge-type/migration.sql +14 -0
  11. package/migrations/drizzle-brain/20260416000001_t673-retrieval-log-plasticity-columns/migration.sql +57 -0
  12. package/migrations/drizzle-brain/20260416000002_t673-plasticity-events-expand/migration.sql +44 -0
  13. package/migrations/drizzle-brain/20260416000003_t673-page-edges-plasticity-columns/migration.sql +44 -0
  14. package/migrations/drizzle-brain/20260416000004_t673-new-plasticity-tables/migration.sql +73 -0
  15. package/migrations/drizzle-brain/20260416000005_t726-dedup-tier-columns/migration.sql +77 -0
  16. package/migrations/drizzle-nexus/20260412000001_t529-nexus-graph-tables/migration.sql +49 -0
  17. package/migrations/drizzle-nexus/20260415000001_t622-project-registry-paths/migration.sql +12 -0
  18. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/migration.sql +84 -0
  19. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/snapshot.json +4060 -0
  20. package/migrations/drizzle-tasks/20260320020000_agent-dimension/migration.sql +35 -0
  21. package/migrations/drizzle-tasks/20260320020000_agent-dimension/snapshot.json +4312 -0
  22. package/migrations/drizzle-tasks/20260321000000_t033-connection-health/migration.sql +518 -0
  23. package/migrations/drizzle-tasks/20260321000000_t033-connection-health/snapshot.json +4312 -0
  24. package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/migration.sql +82 -0
  25. package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/snapshot.json +9 -0
  26. package/migrations/drizzle-tasks/20260324000000_assignee-column/migration.sql +6 -0
  27. package/migrations/drizzle-tasks/20260324000000_assignee-column/snapshot.json +9 -0
  28. package/migrations/drizzle-tasks/20260327000000_agent-credentials/migration.sql +23 -0
  29. package/package.json +8 -8
package/dist/cli/index.js CHANGED
@@ -1931,7 +1931,7 @@ var init_sql = __esm({
1931
1931
  return new SQL([new StringChunk(str)]);
1932
1932
  }
1933
1933
  _sql.raw = raw;
1934
- function join144(chunks, separator) {
1934
+ function join146(chunks, separator) {
1935
1935
  const result = [];
1936
1936
  for (const [i, chunk] of chunks.entries()) {
1937
1937
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -1939,7 +1939,7 @@ var init_sql = __esm({
1939
1939
  }
1940
1940
  return new SQL(result);
1941
1941
  }
1942
- _sql.join = join144;
1942
+ _sql.join = join146;
1943
1943
  function identifier(value) {
1944
1944
  return new Name(value);
1945
1945
  }
@@ -6713,7 +6713,7 @@ var init_select2 = __esm({
6713
6713
  const baseTableName = this.tableName;
6714
6714
  const tableName = getTableLikeName(table);
6715
6715
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
6716
- if (typeof tableName === "string" && this.config.joins?.some((join144) => join144.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6716
+ if (typeof tableName === "string" && this.config.joins?.some((join146) => join146.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6717
6717
  if (!this.isPartialSelect) {
6718
6718
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
6719
6719
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -7998,7 +7998,7 @@ var init_dialect = __esm({
7998
7998
  if (!joins2) return;
7999
7999
  const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
8000
8000
  if (!withEntries.length) return;
8001
- return sql.join(withEntries.map(([k2, join144]) => {
8001
+ return sql.join(withEntries.map(([k2, join146]) => {
8002
8002
  const relation = tableConfig.relations[k2];
8003
8003
  const isSingle2 = is(relation, One3);
8004
8004
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -8009,7 +8009,7 @@ var init_dialect = __esm({
8009
8009
  table: targetTable,
8010
8010
  mode: isSingle2 ? "first" : "many",
8011
8011
  schema,
8012
- queryConfig: join144,
8012
+ queryConfig: join146,
8013
8013
  tableConfig: schema[relation.targetTableName],
8014
8014
  relationWhere: filter,
8015
8015
  isNested: true,
@@ -8023,7 +8023,7 @@ var init_dialect = __esm({
8023
8023
  key: k2,
8024
8024
  selection: innerQuery.selection,
8025
8025
  isArray: !isSingle2,
8026
- isOptional: (relation.optional ?? false) || join144 !== true && !!join144.where
8026
+ isOptional: (relation.optional ?? false) || join146 !== true && !!join146.where
8027
8027
  });
8028
8028
  const jsonColumns = sql.join(innerQuery.selection.map((s3) => {
8029
8029
  return sql`${sql.raw(this.escapeString(s3.key))}, ${s3.selection ? sql`${jsonb2}(${sql.identifier(s3.key)})` : sql.identifier(s3.key)}`;
@@ -8422,7 +8422,7 @@ var init_update = __esm({
8422
8422
  createJoin(joinType) {
8423
8423
  return ((table, on) => {
8424
8424
  const tableName = getTableLikeName(table);
8425
- if (typeof tableName === "string" && this.config.joins.some((join144) => join144.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8425
+ if (typeof tableName === "string" && this.config.joins.some((join146) => join146.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8426
8426
  if (typeof on === "function") {
8427
8427
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
8428
8428
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -15396,6 +15396,7 @@ function runBrainMigrations(nativeDb, db) {
15396
15396
  reconcileJournal(nativeDb, migrationsFolder, "brain_decisions", "brain");
15397
15397
  migrateWithRetry(db, migrationsFolder, nativeDb, "brain_decisions", "brain");
15398
15398
  if (tableExists(nativeDb, "brain_page_edges")) {
15399
+ ensureColumns(nativeDb, "brain_page_edges", [{ name: "provenance", ddl: "text" }], "brain");
15399
15400
  nativeDb.prepare(
15400
15401
  `UPDATE brain_page_edges
15401
15402
  SET edge_type = 'co_retrieved'
@@ -66796,10 +66797,10 @@ async function readProjectMeta(projectPath) {
66796
66797
  }
66797
66798
  async function readProjectId(projectPath) {
66798
66799
  try {
66799
- const { readFileSync: readFileSync108, existsSync: existsSync136 } = await import("node:fs");
66800
+ const { readFileSync: readFileSync110, existsSync: existsSync137 } = await import("node:fs");
66800
66801
  const infoPath = join65(projectPath, ".cleo", "project-info.json");
66801
- if (!existsSync136(infoPath)) return "";
66802
- const data = JSON.parse(readFileSync108(infoPath, "utf-8"));
66802
+ if (!existsSync137(infoPath)) return "";
66803
+ const data = JSON.parse(readFileSync110(infoPath, "utf-8"));
66803
66804
  return typeof data.projectId === "string" ? data.projectId : "";
66804
66805
  } catch {
66805
66806
  return "";
@@ -78436,8 +78437,8 @@ async function initializeSpawnAdapters(manifests) {
78436
78437
  if (!manifest.capabilities?.supportsSpawn) continue;
78437
78438
  if (spawnRegistry.hasAdapterForProvider(manifest.provider)) continue;
78438
78439
  try {
78439
- const { join: join144 } = await import("node:path");
78440
- const modulePath = join144(manifest.packagePath, manifest.entryPoint);
78440
+ const { join: join146 } = await import("node:path");
78441
+ const modulePath = join146(manifest.packagePath, manifest.entryPoint);
78441
78442
  const adapterModule = await import(modulePath);
78442
78443
  let SpawnProviderClass;
78443
78444
  for (const [exportName, exportValue] of Object.entries(adapterModule)) {
@@ -118807,6 +118808,17 @@ var init_registry5 = __esm({
118807
118808
  sessionRequired: false,
118808
118809
  requiredParams: ["chain"]
118809
118810
  },
118811
+ // T646: Canon drift detection — CI gate
118812
+ {
118813
+ gateway: "query",
118814
+ domain: "check",
118815
+ operation: "canon",
118816
+ description: "check.canon (query) \u2014 CI gate: detects canon drift between docs and live code (CANONICAL_DOMAINS count, forbidden phrases, required assertions)",
118817
+ tier: 1,
118818
+ idempotent: true,
118819
+ sessionRequired: false,
118820
+ requiredParams: []
118821
+ },
118810
118822
  // T065: Agent workflow compliance telemetry
118811
118823
  {
118812
118824
  gateway: "query",
@@ -120539,6 +120551,24 @@ var init_registry5 = __esm({
120539
120551
  sessionRequired: false,
120540
120552
  requiredParams: []
120541
120553
  },
120554
+ {
120555
+ gateway: "query",
120556
+ domain: "admin",
120557
+ operation: "smoke.provider",
120558
+ description: "admin.smoke.provider (query) \u2014 ADR-049 harness sovereignty probe: verify adapter shape, DB locality, hooks, spawn, and agent folder for a named provider",
120559
+ tier: 1,
120560
+ idempotent: true,
120561
+ sessionRequired: false,
120562
+ requiredParams: ["provider"],
120563
+ params: [
120564
+ {
120565
+ name: "provider",
120566
+ type: "string",
120567
+ required: true,
120568
+ description: "Provider ID to probe (claude-code | claude-sdk | codex | cursor | gemini-cli | kimi | openai-sdk | opencode | pi)"
120569
+ }
120570
+ ]
120571
+ },
120542
120572
  {
120543
120573
  gateway: "query",
120544
120574
  domain: "admin",
@@ -124045,10 +124075,10 @@ async function systemLog(projectRoot, filters) {
124045
124075
  }
124046
124076
  async function queryAuditLogSqlite(projectRoot, filters) {
124047
124077
  try {
124048
- const { join: join144 } = await import("node:path");
124049
- const { existsSync: existsSync136 } = await import("node:fs");
124050
- const dbPath = join144(projectRoot, ".cleo", "tasks.db");
124051
- if (!existsSync136(dbPath)) {
124078
+ const { join: join146 } = await import("node:path");
124079
+ const { existsSync: existsSync137 } = await import("node:fs");
124080
+ const dbPath = join146(projectRoot, ".cleo", "tasks.db");
124081
+ if (!existsSync137(dbPath)) {
124052
124082
  const offset = filters?.offset ?? 0;
124053
124083
  const limit = filters?.limit ?? 20;
124054
124084
  return {
@@ -126160,6 +126190,210 @@ var init_job_manager_accessor = __esm({
126160
126190
  }
126161
126191
  });
126162
126192
 
126193
+ // packages/cleo/src/dispatch/domains/admin/smoke-provider.ts
126194
+ var smoke_provider_exports = {};
126195
+ __export(smoke_provider_exports, {
126196
+ smokeProvider: () => smokeProvider
126197
+ });
126198
+ import { existsSync as existsSync129, readFileSync as readFileSync99 } from "node:fs";
126199
+ import { join as join126 } from "node:path";
126200
+ function isLocal(dbPath, projectCleoDir, cleoHome) {
126201
+ return dbPath.startsWith(projectCleoDir) || dbPath.startsWith(cleoHome);
126202
+ }
126203
+ function classifySpawn(spawnSrcPath) {
126204
+ if (!existsSync129(spawnSrcPath)) return "no";
126205
+ let src;
126206
+ try {
126207
+ src = readFileSync99(spawnSrcPath, "utf-8");
126208
+ } catch {
126209
+ return "no";
126210
+ }
126211
+ const hasImpl = /\bspawn\b|\bexec\b|\bfork\b|\bchild_process\b|\bspawnSync\b/.test(src);
126212
+ if (!hasImpl && /\bthrow\b/.test(src)) return "stub";
126213
+ return "yes";
126214
+ }
126215
+ function countHookEvents(hooksSrcPath, canonicalEvents) {
126216
+ if (!existsSync129(hooksSrcPath)) return 0;
126217
+ let src;
126218
+ try {
126219
+ src = readFileSync99(hooksSrcPath, "utf-8");
126220
+ } catch {
126221
+ return 0;
126222
+ }
126223
+ let count5 = 0;
126224
+ for (const event of canonicalEvents) {
126225
+ if (src.includes(event)) count5++;
126226
+ }
126227
+ return count5;
126228
+ }
126229
+ function buildReport(partial2) {
126230
+ const sep3 = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
126231
+ const lines = [
126232
+ `CLEO Smoke Probe \u2014 provider: ${partial2.providerId}`,
126233
+ sep3,
126234
+ ` Adapter loaded: ${partial2.adapterLoaded ? "yes" : "no"}`
126235
+ ];
126236
+ for (const db of partial2.dbChecks) {
126237
+ const label = ` ${db.name} local:`.padEnd(24);
126238
+ lines.push(`${label}${db.local ? "yes" : "NO"} (${db.path})`);
126239
+ }
126240
+ lines.push(` Hooks declared: ${partial2.hooksDeclared}`);
126241
+ lines.push(` Spawn implementation: ${partial2.spawnStatus}`);
126242
+ lines.push(` Agent folder: ${partial2.agentFolder ?? "(none \u2014 unknown provider)"}`);
126243
+ lines.push("");
126244
+ lines.push(
126245
+ partial2.passed ? "Result: PASS" : `Result: FAIL (${partial2.failureReason ?? "invariant violated"})`
126246
+ );
126247
+ return lines.join("\n");
126248
+ }
126249
+ async function smokeProvider(providerId) {
126250
+ if (!VALID_PROVIDER_IDS.includes(providerId)) {
126251
+ return engineError(
126252
+ "E_INVALID_INPUT",
126253
+ `Unknown provider ID: "${providerId}". Valid IDs: ${VALID_PROVIDER_IDS.join(", ")}`
126254
+ );
126255
+ }
126256
+ const coreInternal = await Promise.resolve().then(() => (init_internal(), internal_exports));
126257
+ const projectRoot = (() => {
126258
+ try {
126259
+ return coreInternal.getProjectRoot();
126260
+ } catch {
126261
+ return process.env["CLEO_ROOT"] ?? process.cwd();
126262
+ }
126263
+ })();
126264
+ const monorepoRoot = projectRoot;
126265
+ const adapterDistPath = join126(
126266
+ monorepoRoot,
126267
+ "packages",
126268
+ "adapters",
126269
+ "dist",
126270
+ "providers",
126271
+ providerId,
126272
+ "index.js"
126273
+ );
126274
+ let adapterLoaded = false;
126275
+ if (existsSync129(adapterDistPath)) {
126276
+ try {
126277
+ const mod = await import(adapterDistPath);
126278
+ const defaultExport = mod["default"];
126279
+ if (typeof defaultExport === "function") {
126280
+ const ctor = defaultExport;
126281
+ try {
126282
+ const instance = new ctor();
126283
+ adapterLoaded = typeof instance.id === "string" && typeof instance.name === "string" && typeof instance.version === "string";
126284
+ } catch {
126285
+ adapterLoaded = existsSync129(adapterDistPath);
126286
+ }
126287
+ } else {
126288
+ adapterLoaded = typeof mod["id"] === "string" && typeof mod["name"] === "string";
126289
+ }
126290
+ } catch {
126291
+ adapterLoaded = false;
126292
+ }
126293
+ }
126294
+ const cleoHome = coreInternal.getCleoHome();
126295
+ const projectCleoDir = join126(projectRoot, ".cleo");
126296
+ const taskDbPath = coreInternal.getTaskPath(projectRoot);
126297
+ const brainPath = join126(projectCleoDir, "brain.db");
126298
+ const conduitDbPath = coreInternal.getConduitDbPath(projectRoot);
126299
+ const nexusDbPath = coreInternal.getNexusDbPath();
126300
+ const dbChecks = [
126301
+ { name: "brain.db", local: isLocal(brainPath, projectCleoDir, cleoHome), path: brainPath },
126302
+ { name: "nexus.db", local: isLocal(nexusDbPath, projectCleoDir, cleoHome), path: nexusDbPath },
126303
+ {
126304
+ name: "conduit.db",
126305
+ local: isLocal(conduitDbPath, projectCleoDir, cleoHome),
126306
+ path: conduitDbPath
126307
+ },
126308
+ { name: "tasks.db", local: isLocal(taskDbPath, projectCleoDir, cleoHome), path: taskDbPath }
126309
+ ];
126310
+ let canonicalEvents = [];
126311
+ try {
126312
+ const caamp = await import("@cleocode/caamp");
126313
+ canonicalEvents = caamp.CANONICAL_HOOK_EVENTS;
126314
+ } catch {
126315
+ canonicalEvents = [];
126316
+ }
126317
+ const hooksSrcPath = join126(
126318
+ monorepoRoot,
126319
+ "packages",
126320
+ "adapters",
126321
+ "src",
126322
+ "providers",
126323
+ providerId,
126324
+ "hooks.ts"
126325
+ );
126326
+ const hooksDeclared = countHookEvents(hooksSrcPath, canonicalEvents);
126327
+ const spawnSrcPath = join126(
126328
+ monorepoRoot,
126329
+ "packages",
126330
+ "adapters",
126331
+ "src",
126332
+ "providers",
126333
+ providerId,
126334
+ "spawn.ts"
126335
+ );
126336
+ const spawnStatus = classifySpawn(spawnSrcPath);
126337
+ let agentFolder = null;
126338
+ try {
126339
+ const { getProviderAgentFolder } = await import("@cleocode/caamp");
126340
+ agentFolder = getProviderAgentFolder(providerId);
126341
+ } catch {
126342
+ agentFolder = null;
126343
+ }
126344
+ const dbsLocal = dbChecks.every((c) => c.local);
126345
+ const failReasons = [];
126346
+ if (!adapterLoaded) failReasons.push("adapter did not load or missing id/name/version");
126347
+ if (!dbsLocal) {
126348
+ const nonLocal = dbChecks.filter((c) => !c.local).map((c) => c.name).join(", ");
126349
+ failReasons.push(`non-local DB paths: ${nonLocal}`);
126350
+ }
126351
+ if (agentFolder === null) failReasons.push("agent folder unresolvable (unknown provider)");
126352
+ const passed = failReasons.length === 0;
126353
+ const partial2 = {
126354
+ providerId,
126355
+ adapterLoaded,
126356
+ dbChecks,
126357
+ hooksDeclared,
126358
+ spawnStatus,
126359
+ agentFolder,
126360
+ passed,
126361
+ ...passed ? {} : { failureReason: failReasons.join("; ") }
126362
+ };
126363
+ const report = buildReport(partial2);
126364
+ const result = { ...partial2, report };
126365
+ if (!passed) {
126366
+ return {
126367
+ success: false,
126368
+ data: result,
126369
+ error: {
126370
+ code: "E_SMOKE_PROVIDER_FAIL",
126371
+ message: `ADR-049 probe FAILED for provider "${providerId}": ${partial2.failureReason}`,
126372
+ exitCode: 1
126373
+ }
126374
+ };
126375
+ }
126376
+ return engineSuccess(result);
126377
+ }
126378
+ var VALID_PROVIDER_IDS;
126379
+ var init_smoke_provider = __esm({
126380
+ "packages/cleo/src/dispatch/domains/admin/smoke-provider.ts"() {
126381
+ "use strict";
126382
+ init_error3();
126383
+ VALID_PROVIDER_IDS = [
126384
+ "claude-code",
126385
+ "claude-sdk",
126386
+ "codex",
126387
+ "cursor",
126388
+ "gemini-cli",
126389
+ "kimi",
126390
+ "openai-sdk",
126391
+ "opencode",
126392
+ "pi"
126393
+ ];
126394
+ }
126395
+ });
126396
+
126163
126397
  // packages/cleo/src/dispatch/domains/admin.ts
126164
126398
  var AdminHandler;
126165
126399
  var init_admin2 = __esm({
@@ -126655,6 +126889,22 @@ var init_admin2 = __esm({
126655
126889
  const result = await systemSmoke();
126656
126890
  return wrapResult(result, "query", "admin", operation, startTime);
126657
126891
  }
126892
+ case "smoke.provider": {
126893
+ const providerIdParam = params?.provider;
126894
+ if (!providerIdParam || typeof providerIdParam !== "string") {
126895
+ return errorResult(
126896
+ "query",
126897
+ "admin",
126898
+ operation,
126899
+ "E_INVALID_INPUT",
126900
+ "provider is required (e.g. claude-code, pi, opencode)",
126901
+ startTime
126902
+ );
126903
+ }
126904
+ const { smokeProvider: smokeProvider2 } = await Promise.resolve().then(() => (init_smoke_provider(), smoke_provider_exports));
126905
+ const result = await smokeProvider2(providerIdParam);
126906
+ return wrapResult(result, "query", "admin", operation, startTime);
126907
+ }
126658
126908
  case "hooks.matrix": {
126659
126909
  const result = await systemHooksMatrix({
126660
126910
  providerIds: params?.providerIds,
@@ -127161,6 +127411,7 @@ var init_admin2 = __esm({
127161
127411
  "map",
127162
127412
  "roadmap",
127163
127413
  "smoke",
127414
+ "smoke.provider",
127164
127415
  "hooks.matrix"
127165
127416
  ],
127166
127417
  mutate: [
@@ -127189,6 +127440,139 @@ var init_admin2 = __esm({
127189
127440
  }
127190
127441
  });
127191
127442
 
127443
+ // packages/cleo/src/dispatch/domains/check/canon.ts
127444
+ var canon_exports = {};
127445
+ __export(canon_exports, {
127446
+ runCanonCheck: () => runCanonCheck
127447
+ });
127448
+ import { readFileSync as readFileSync100 } from "node:fs";
127449
+ import { join as join127 } from "node:path";
127450
+ function readLines(filePath) {
127451
+ try {
127452
+ return readFileSync100(filePath, "utf8").split("\n");
127453
+ } catch {
127454
+ return [];
127455
+ }
127456
+ }
127457
+ function scanForbiddenPhrases(filePath, lines) {
127458
+ const results = [];
127459
+ for (let i = 0; i < lines.length; i++) {
127460
+ const line2 = lines[i];
127461
+ for (const phrase of FORBIDDEN_PHRASES) {
127462
+ if (line2.includes(phrase)) {
127463
+ results.push({ file: filePath, line: i + 1, phrase });
127464
+ }
127465
+ }
127466
+ }
127467
+ return results;
127468
+ }
127469
+ function countCanonicalDomains(typesFilePath) {
127470
+ const lines = readLines(typesFilePath);
127471
+ let inArray8 = false;
127472
+ let count5 = 0;
127473
+ for (const line2 of lines) {
127474
+ if (!inArray8) {
127475
+ if (line2.includes("CANONICAL_DOMAINS") && line2.includes("[")) {
127476
+ inArray8 = true;
127477
+ }
127478
+ continue;
127479
+ }
127480
+ if (line2.includes("] as const")) {
127481
+ break;
127482
+ }
127483
+ const trimmed = line2.trim();
127484
+ if (trimmed.startsWith("'") && trimmed.includes("'")) {
127485
+ count5++;
127486
+ }
127487
+ }
127488
+ return count5;
127489
+ }
127490
+ function countOperations(registryFilePath) {
127491
+ const lines = readLines(registryFilePath);
127492
+ let count5 = 0;
127493
+ for (const line2 of lines) {
127494
+ if (/^\s*gateway:/.test(line2)) {
127495
+ count5++;
127496
+ }
127497
+ }
127498
+ return count5;
127499
+ }
127500
+ function runCanonCheck(params) {
127501
+ const { projectRoot } = params;
127502
+ const typesFile = join127(projectRoot, "packages/cleo/src/dispatch/types.ts");
127503
+ const registryFile = join127(projectRoot, "packages/cleo/src/dispatch/registry.ts");
127504
+ const archGuide = join127(projectRoot, "docs/concepts/CLEO-ARCHITECTURE-GUIDE.md");
127505
+ const visionDoc = join127(projectRoot, "docs/concepts/CLEO-VISION.md");
127506
+ const constitution = join127(projectRoot, "docs/specs/CLEO-OPERATION-CONSTITUTION.md");
127507
+ const domainsInCode = countCanonicalDomains(typesFile);
127508
+ const operationsInCode = countOperations(registryFile);
127509
+ const excludedSet = new Set(EXCLUDED_FILENAMES);
127510
+ const auditedDocs = [archGuide, visionDoc, constitution].filter((f2) => {
127511
+ const basename19 = f2.split("/").pop() ?? "";
127512
+ return !excludedSet.has(basename19);
127513
+ });
127514
+ const allViolations = [];
127515
+ for (const docPath of auditedDocs) {
127516
+ const lines = readLines(docPath);
127517
+ allViolations.push(...scanForbiddenPhrases(docPath, lines));
127518
+ }
127519
+ const assertions = [];
127520
+ const archLines = readLines(archGuide);
127521
+ const archText = archLines.join("\n");
127522
+ assertions.push({
127523
+ file: archGuide,
127524
+ assertion: 'Contains "Six Great Systems"',
127525
+ passed: archText.includes("Six Great Systems")
127526
+ });
127527
+ assertions.push({
127528
+ file: archGuide,
127529
+ assertion: 'Contains "Circle of Eleven"',
127530
+ passed: archText.includes("Circle of Eleven")
127531
+ });
127532
+ const visionLines = readLines(visionDoc);
127533
+ const visionText = visionLines.join("\n");
127534
+ assertions.push({
127535
+ file: visionDoc,
127536
+ assertion: "Contains reference to six systems",
127537
+ passed: visionText.includes("six systems") || visionText.includes("Six systems") || visionText.includes("6 systems") || visionText.includes("six canonical systems")
127538
+ });
127539
+ const constLines = readLines(constitution);
127540
+ const constText = constLines.join("\n");
127541
+ assertions.push({
127542
+ file: constitution,
127543
+ assertion: 'Contains "11 canonical domains"',
127544
+ passed: constText.includes("11 canonical domains") || constText.includes("eleven canonical domains")
127545
+ });
127546
+ const allAssertionsPassed = assertions.every((a) => a.passed);
127547
+ const passed = allViolations.length === 0 && allAssertionsPassed;
127548
+ return {
127549
+ domainsInCode,
127550
+ operationsInCode,
127551
+ violations: allViolations,
127552
+ assertions,
127553
+ passed
127554
+ };
127555
+ }
127556
+ var FORBIDDEN_PHRASES, EXCLUDED_FILENAMES;
127557
+ var init_canon = __esm({
127558
+ "packages/cleo/src/dispatch/domains/check/canon.ts"() {
127559
+ "use strict";
127560
+ FORBIDDEN_PHRASES = [
127561
+ "Four Great Systems",
127562
+ "Four systems",
127563
+ "Circle of Ten",
127564
+ "exactly 10 domains",
127565
+ "exactly ten domains"
127566
+ ];
127567
+ EXCLUDED_FILENAMES = [
127568
+ "CLEO-CANT.md",
127569
+ "CLEO-AWAKENING-STORY.md",
127570
+ "CLEO-FOUNDING-STORY.md",
127571
+ "CLEO-MANIFESTO.md"
127572
+ ];
127573
+ }
127574
+ });
127575
+
127192
127576
  // packages/cleo/src/dispatch/domains/check.ts
127193
127577
  var CheckHandler;
127194
127578
  var init_check = __esm({
@@ -127538,6 +127922,22 @@ var init_check = __esm({
127538
127922
  page: page.page
127539
127923
  };
127540
127924
  }
127925
+ // T646: Canon drift detection — compares docs to live code
127926
+ case "canon": {
127927
+ const { runCanonCheck: runCanonCheck2 } = await Promise.resolve().then(() => (init_canon(), canon_exports));
127928
+ const result = runCanonCheck2({ projectRoot });
127929
+ return {
127930
+ meta: dispatchMeta("query", "check", operation, startTime),
127931
+ success: result.passed,
127932
+ data: result,
127933
+ ...!result.passed ? {
127934
+ error: {
127935
+ code: "E_CANON_DRIFT",
127936
+ message: `Canon drift detected: ${result.violations.length} forbidden phrase(s), ${result.assertions.filter((a) => !a.passed).length} failed assertion(s)`
127937
+ }
127938
+ } : {}
127939
+ };
127940
+ }
127541
127941
  // T065: Workflow compliance telemetry — WF-001 through WF-005
127542
127942
  case "workflow.compliance": {
127543
127943
  const since = params?.since;
@@ -127666,7 +128066,8 @@ var init_check = __esm({
127666
128066
  "archive.stats",
127667
128067
  "grade",
127668
128068
  "grade.list",
127669
- "chain.validate"
128069
+ "chain.validate",
128070
+ "canon"
127670
128071
  ],
127671
128072
  mutate: ["compliance.record", "compliance.sync", "test.run", "gate.set"]
127672
128073
  };
@@ -129654,16 +130055,16 @@ var init_nexus2 = __esm({
129654
130055
  async function orchestrateClassify(request, context, projectRoot) {
129655
130056
  try {
129656
130057
  const { getCleoCantWorkflowsDir: getCleoCantWorkflowsDir2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
129657
- const { readFileSync: readFileSync108, readdirSync: readdirSync43, existsSync: existsSync136 } = await import("node:fs");
129658
- const { join: join144 } = await import("node:path");
130058
+ const { readFileSync: readFileSync110, readdirSync: readdirSync43, existsSync: existsSync137 } = await import("node:fs");
130059
+ const { join: join146 } = await import("node:path");
129659
130060
  const workflowsDir = getCleoCantWorkflowsDir2();
129660
130061
  const combined = `${request} ${context ?? ""}`.toLowerCase();
129661
130062
  const matches = [];
129662
- if (existsSync136(workflowsDir)) {
130063
+ if (existsSync137(workflowsDir)) {
129663
130064
  const files = readdirSync43(workflowsDir).filter((f2) => f2.endsWith(".cant"));
129664
130065
  for (const file2 of files) {
129665
130066
  try {
129666
- const src = readFileSync108(join144(workflowsDir, file2), "utf-8");
130067
+ const src = readFileSync110(join146(workflowsDir, file2), "utf-8");
129667
130068
  const teamMatch = /^team\s+(\S+):/m.exec(src);
129668
130069
  if (!teamMatch) continue;
129669
130070
  const teamName = teamMatch[1];
@@ -129678,12 +130079,12 @@ async function orchestrateClassify(request, context, projectRoot) {
129678
130079
  }
129679
130080
  }
129680
130081
  }
129681
- const localCantDir = join144(projectRoot, ".cleo", "workflows");
129682
- if (existsSync136(localCantDir)) {
130082
+ const localCantDir = join146(projectRoot, ".cleo", "workflows");
130083
+ if (existsSync137(localCantDir)) {
129683
130084
  const files = readdirSync43(localCantDir).filter((f2) => f2.endsWith(".cant"));
129684
130085
  for (const file2 of files) {
129685
130086
  try {
129686
- const src = readFileSync108(join144(localCantDir, file2), "utf-8");
130087
+ const src = readFileSync110(join146(localCantDir, file2), "utf-8");
129687
130088
  const teamMatch = /^team\s+(\S+):/m.exec(src);
129688
130089
  if (!teamMatch) continue;
129689
130090
  const teamName = teamMatch[1];
@@ -132391,7 +132792,7 @@ var init_tasks4 = __esm({
132391
132792
  });
132392
132793
 
132393
132794
  // packages/cleo/src/dispatch/engines/code-engine.ts
132394
- import { join as join126 } from "node:path";
132795
+ import { join as join128 } from "node:path";
132395
132796
  async function codeOutline(params) {
132396
132797
  const { smartOutline: smartOutline2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
132397
132798
  const filePath = params?.file;
@@ -132401,7 +132802,7 @@ async function codeOutline(params) {
132401
132802
  error: { code: "E_INVALID_INPUT", message: "file parameter required" }
132402
132803
  };
132403
132804
  const root = getProjectRoot();
132404
- const absPath = filePath.startsWith("/") ? filePath : join126(root, filePath);
132805
+ const absPath = filePath.startsWith("/") ? filePath : join128(root, filePath);
132405
132806
  return { success: true, data: smartOutline2(absPath, root) };
132406
132807
  }
132407
132808
  async function codeSearch(params) {
@@ -132433,7 +132834,7 @@ async function codeUnfold(params) {
132433
132834
  error: { code: "E_INVALID_INPUT", message: "file and symbol parameters required" }
132434
132835
  };
132435
132836
  const root = getProjectRoot();
132436
- const absPath = filePath.startsWith("/") ? filePath : join126(root, filePath);
132837
+ const absPath = filePath.startsWith("/") ? filePath : join128(root, filePath);
132437
132838
  return { success: true, data: smartUnfold2(absPath, symbol2, root) };
132438
132839
  }
132439
132840
  async function codeParse(params) {
@@ -132445,7 +132846,7 @@ async function codeParse(params) {
132445
132846
  error: { code: "E_INVALID_INPUT", message: "file parameter required" }
132446
132847
  };
132447
132848
  const root = getProjectRoot();
132448
- const absPath = filePath.startsWith("/") ? filePath : join126(root, filePath);
132849
+ const absPath = filePath.startsWith("/") ? filePath : join128(root, filePath);
132449
132850
  return { success: true, data: parseFile3(absPath, root) };
132450
132851
  }
132451
132852
  var init_code_engine = __esm({
@@ -133608,8 +134009,8 @@ var init_defaults = __esm({
133608
134009
  });
133609
134010
 
133610
134011
  // packages/cleo/src/dispatch/lib/config-loader.ts
133611
- import { existsSync as existsSync129, readFileSync as readFileSync99 } from "fs";
133612
- import { join as join127 } from "path";
134012
+ import { existsSync as existsSync130, readFileSync as readFileSync101 } from "fs";
134013
+ import { join as join129 } from "path";
133613
134014
  function loadFromEnv(key) {
133614
134015
  const envKey = `${ENV_PREFIX}${key.toUpperCase()}`;
133615
134016
  return process.env[envKey];
@@ -133630,12 +134031,12 @@ function parseEnvValue2(key, value) {
133630
134031
  }
133631
134032
  function loadFromFile(projectRoot) {
133632
134033
  const root = projectRoot || process.cwd();
133633
- const configPath = join127(root, ".cleo", "config.json");
133634
- if (!existsSync129(configPath)) {
134034
+ const configPath = join129(root, ".cleo", "config.json");
134035
+ if (!existsSync130(configPath)) {
133635
134036
  return {};
133636
134037
  }
133637
134038
  try {
133638
- const content = readFileSync99(configPath, "utf-8");
134039
+ const content = readFileSync101(configPath, "utf-8");
133639
134040
  const config2 = JSON.parse(content);
133640
134041
  const result = {};
133641
134042
  if (config2.lifecycleEnforcement) {
@@ -134085,9 +134486,9 @@ __export(cli_exports, {
134085
134486
  resetCliDispatcher: () => resetCliDispatcher
134086
134487
  });
134087
134488
  import { randomUUID as randomUUID14 } from "node:crypto";
134088
- import { existsSync as existsSync130 } from "node:fs";
134489
+ import { existsSync as existsSync131 } from "node:fs";
134089
134490
  import { createRequire as createRequire19 } from "node:module";
134090
- import { dirname as dirname27, join as join128 } from "node:path";
134491
+ import { dirname as dirname27, join as join130 } from "node:path";
134091
134492
  import { fileURLToPath as fileURLToPath7 } from "node:url";
134092
134493
  import { catalog as catalog4, registerSkillLibraryFromPath } from "@cleocode/caamp";
134093
134494
  function ensureCaampLibrary() {
@@ -134098,16 +134499,16 @@ function ensureCaampLibrary() {
134098
134499
  const req = createRequire19(import.meta.url);
134099
134500
  const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
134100
134501
  const candidate = dirname27(skillsPkgJson);
134101
- if (existsSync130(join128(candidate, "skills.json"))) {
134502
+ if (existsSync131(join130(candidate, "skills.json"))) {
134102
134503
  skillsRoot = candidate;
134103
134504
  }
134104
134505
  } catch {
134105
134506
  }
134106
134507
  if (!skillsRoot) {
134107
134508
  const thisFile = fileURLToPath7(import.meta.url);
134108
- const packageRoot = join128(dirname27(thisFile), "..", "..", "..", "..", "..");
134109
- const candidate = join128(packageRoot, "packages", "skills");
134110
- if (existsSync130(join128(candidate, "skills.json"))) {
134509
+ const packageRoot = join130(dirname27(thisFile), "..", "..", "..", "..", "..");
134510
+ const candidate = join130(packageRoot, "packages", "skills");
134511
+ if (existsSync131(join130(candidate, "skills.json"))) {
134111
134512
  skillsRoot = candidate;
134112
134513
  }
134113
134514
  }
@@ -134328,8 +134729,8 @@ var init_cli = __esm({
134328
134729
 
134329
134730
  // packages/cleo/src/cli/index.ts
134330
134731
  init_internal();
134331
- import { readFileSync as readFileSync107 } from "node:fs";
134332
- import { dirname as dirname32, join as join143 } from "node:path";
134732
+ import { readFileSync as readFileSync109 } from "node:fs";
134733
+ import { dirname as dirname32, join as join145 } from "node:path";
134333
134734
  import { fileURLToPath as fileURLToPath9 } from "node:url";
134334
134735
 
134335
134736
  // node_modules/.pnpm/citty@0.2.1/node_modules/citty/dist/_chunks/libs/scule.mjs
@@ -135486,7 +135887,7 @@ function registerAddCommand(program) {
135486
135887
  // packages/cleo/src/cli/commands/add-batch.ts
135487
135888
  init_cli();
135488
135889
  init_renderers();
135489
- import { existsSync as existsSync131, readFileSync as readFileSync100 } from "node:fs";
135890
+ import { existsSync as existsSync132, readFileSync as readFileSync102 } from "node:fs";
135490
135891
  function registerAddBatchCommand(program) {
135491
135892
  program.command("add-batch").description("Create multiple tasks atomically from a JSON file").option("--file <path>", "Path to JSON file (array of task objects). Use - for stdin.").option("--parent <parentId>", "Default parent for all tasks (overridden by per-task parent)").option("--dry-run", "Preview what would be created without making changes").action(async (opts) => {
135492
135893
  const filePath = opts["file"];
@@ -135513,7 +135914,7 @@ function registerAddBatchCommand(program) {
135513
135914
  return;
135514
135915
  }
135515
135916
  } else {
135516
- if (!existsSync131(filePath)) {
135917
+ if (!existsSync132(filePath)) {
135517
135918
  cliError(
135518
135919
  `File not found: ${filePath}`,
135519
135920
  "E_NOT_FOUND",
@@ -135526,7 +135927,7 @@ function registerAddBatchCommand(program) {
135526
135927
  process.exit(2);
135527
135928
  return;
135528
135929
  }
135529
- raw = readFileSync100(filePath, "utf-8");
135930
+ raw = readFileSync102(filePath, "utf-8");
135530
135931
  }
135531
135932
  let tasks2;
135532
135933
  try {
@@ -135646,8 +136047,24 @@ function registerAdminCommand(program) {
135646
136047
  { command: "admin" }
135647
136048
  );
135648
136049
  });
135649
- admin.command("smoke").description("Run operational smoke tests across all domains").action(async () => {
135650
- await dispatchFromCli("query", "admin", "smoke", {}, { command: "admin" });
136050
+ admin.command("smoke").description(
136051
+ "Run operational smoke tests across all domains, or probe ADR-049 invariants for a named provider (--provider)"
136052
+ ).option(
136053
+ "--provider <id>",
136054
+ "Probe harness sovereignty invariants for a specific provider adapter (ADR-049)"
136055
+ ).action(async (opts) => {
136056
+ const provider = opts["provider"];
136057
+ if (provider) {
136058
+ await dispatchFromCli(
136059
+ "query",
136060
+ "admin",
136061
+ "smoke.provider",
136062
+ { provider },
136063
+ { command: "admin smoke", operation: "admin.smoke.provider" }
136064
+ );
136065
+ } else {
136066
+ await dispatchFromCli("query", "admin", "smoke", {}, { command: "admin" });
136067
+ }
135651
136068
  });
135652
136069
  admin.command("paths").description("Report all CleoOS paths (project + global hub) and scaffolding status").action(async () => {
135653
136070
  await dispatchFromCli("query", "admin", "paths", {}, { command: "admin" });
@@ -135831,12 +136248,12 @@ function registerAgentCommand(program) {
135831
136248
  transportConfig: {},
135832
136249
  isActive: true
135833
136250
  });
135834
- const { existsSync: existsSync136, mkdirSync: mkdirSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
135835
- const { join: join144 } = await import("node:path");
135836
- const cantDir = join144(".cleo", "agents");
135837
- const cantPath = join144(cantDir, `${agentId}.cant`);
136251
+ const { existsSync: existsSync137, mkdirSync: mkdirSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
136252
+ const { join: join146 } = await import("node:path");
136253
+ const cantDir = join146(".cleo", "agents");
136254
+ const cantPath = join146(cantDir, `${agentId}.cant`);
135838
136255
  let cantScaffolded = false;
135839
- if (!existsSync136(cantPath)) {
136256
+ if (!existsSync137(cantPath)) {
135840
136257
  mkdirSync36(cantDir, { recursive: true });
135841
136258
  const role = classification ?? "specialist";
135842
136259
  const cantContent = `---
@@ -135896,7 +136313,7 @@ agent ${agentId}:
135896
136313
  data: {
135897
136314
  agentId: credential.agentId,
135898
136315
  displayName: credential.displayName,
135899
- cantFile: cantScaffolded ? cantPath : existsSync136(cantPath) ? cantPath : null,
136316
+ cantFile: cantScaffolded ? cantPath : existsSync137(cantPath) ? cantPath : null,
135900
136317
  cantScaffolded
135901
136318
  }
135902
136319
  },
@@ -135976,8 +136393,8 @@ agent ${agentId}:
135976
136393
  try {
135977
136394
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
135978
136395
  const { createRuntime } = await import("@cleocode/runtime");
135979
- const { existsSync: existsSync136, readFileSync: readFileSync108 } = await import("node:fs");
135980
- const { join: join144 } = await import("node:path");
136396
+ const { existsSync: existsSync137, readFileSync: readFileSync110 } = await import("node:fs");
136397
+ const { join: join146 } = await import("node:path");
135981
136398
  await getDb4();
135982
136399
  const registry2 = new AgentRegistryAccessor2(process.cwd());
135983
136400
  const credential = await registry2.get(agentId);
@@ -135997,9 +136414,9 @@ agent ${agentId}:
135997
136414
  }
135998
136415
  let profile = null;
135999
136416
  let cantValidation = null;
136000
- const cantPath = opts["cant"] ?? join144(".cleo", "agents", `${agentId}.cant`);
136001
- if (existsSync136(cantPath)) {
136002
- profile = readFileSync108(cantPath, "utf-8");
136417
+ const cantPath = opts["cant"] ?? join146(".cleo", "agents", `${agentId}.cant`);
136418
+ if (existsSync137(cantPath)) {
136419
+ profile = readFileSync110(cantPath, "utf-8");
136003
136420
  try {
136004
136421
  const cantModule = await import("@cleocode/cant");
136005
136422
  const validate = "validate" in cantModule ? cantModule.validate : null;
@@ -136394,8 +136811,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
136394
136811
  try {
136395
136812
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
136396
136813
  const { createRuntime } = await import("@cleocode/runtime");
136397
- const { existsSync: existsSync136 } = await import("node:fs");
136398
- const { join: join144 } = await import("node:path");
136814
+ const { existsSync: existsSync137 } = await import("node:fs");
136815
+ const { join: join146 } = await import("node:path");
136399
136816
  const { execFile: execFile9 } = await import("node:child_process");
136400
136817
  const { promisify: promisify9 } = await import("node:util");
136401
136818
  const execFileAsync6 = promisify9(execFile9);
@@ -136415,8 +136832,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
136415
136832
  }
136416
136833
  await registry2.update(agentId, { isActive: true });
136417
136834
  await registry2.markUsed(agentId);
136418
- const cantPath = join144(".cleo", "agents", `${agentId}.cant`);
136419
- const hasProfile = existsSync136(cantPath);
136835
+ const cantPath = join146(".cleo", "agents", `${agentId}.cant`);
136836
+ const hasProfile = existsSync137(cantPath);
136420
136837
  const runtime = await createRuntime(registry2, {
136421
136838
  agentId,
136422
136839
  pollIntervalMs: 5e3,
@@ -137039,12 +137456,12 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137039
137456
  });
137040
137457
  agent.command("install <path>").description("Install an agent from a .cantz archive or agent directory").option("--global", "Install to global tier (~/.local/share/cleo/cant/agents/)").action(async (sourcePath, opts) => {
137041
137458
  try {
137042
- const { existsSync: existsSync136, mkdirSync: mkdirSync36, cpSync, readFileSync: readFileSync108, rmSync: rmSync2, statSync: statSync22 } = await import("node:fs");
137043
- const { join: join144, basename: basename19, resolve: resolve17 } = await import("node:path");
137459
+ const { existsSync: existsSync137, mkdirSync: mkdirSync36, cpSync, readFileSync: readFileSync110, rmSync: rmSync2, statSync: statSync22 } = await import("node:fs");
137460
+ const { join: join146, basename: basename19, resolve: resolve17 } = await import("node:path");
137044
137461
  const { homedir: homedir15 } = await import("node:os");
137045
137462
  const { tmpdir: tmpdir2 } = await import("node:os");
137046
137463
  const resolvedPath = resolve17(sourcePath);
137047
- if (!existsSync136(resolvedPath)) {
137464
+ if (!existsSync137(resolvedPath)) {
137048
137465
  cliOutput(
137049
137466
  {
137050
137467
  success: false,
@@ -137064,7 +137481,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137064
137481
  const isCantzArchive = resolvedPath.endsWith(".cantz") && statSync22(resolvedPath).isFile();
137065
137482
  if (isCantzArchive) {
137066
137483
  const { execFileSync: execFileSync19 } = await import("node:child_process");
137067
- tempDir = join144(tmpdir2(), `cleo-agent-install-${Date.now()}`);
137484
+ tempDir = join146(tmpdir2(), `cleo-agent-install-${Date.now()}`);
137068
137485
  mkdirSync36(tempDir, { recursive: true });
137069
137486
  try {
137070
137487
  execFileSync19("unzip", ["-o", "-q", resolvedPath, "-d", tempDir], {
@@ -137088,7 +137505,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137088
137505
  }
137089
137506
  const { readdirSync: readdirSync43 } = await import("node:fs");
137090
137507
  const topLevel = readdirSync43(tempDir).filter((entry) => {
137091
- const entryPath = join144(tempDir, entry);
137508
+ const entryPath = join146(tempDir, entry);
137092
137509
  return statSync22(entryPath).isDirectory();
137093
137510
  });
137094
137511
  if (topLevel.length !== 1) {
@@ -137107,7 +137524,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137107
137524
  return;
137108
137525
  }
137109
137526
  agentName = topLevel[0];
137110
- agentDir = join144(tempDir, agentName);
137527
+ agentDir = join146(tempDir, agentName);
137111
137528
  } else if (statSync22(resolvedPath).isDirectory()) {
137112
137529
  agentDir = resolvedPath;
137113
137530
  agentName = basename19(resolvedPath);
@@ -137125,8 +137542,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137125
137542
  process.exitCode = 6;
137126
137543
  return;
137127
137544
  }
137128
- const personaPath = join144(agentDir, "persona.cant");
137129
- if (!existsSync136(personaPath)) {
137545
+ const personaPath = join146(agentDir, "persona.cant");
137546
+ if (!existsSync137(personaPath)) {
137130
137547
  if (tempDir) rmSync2(tempDir, { recursive: true, force: true });
137131
137548
  cliOutput(
137132
137549
  {
@@ -137145,12 +137562,12 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137145
137562
  let targetRoot;
137146
137563
  if (isGlobal) {
137147
137564
  const home = homedir15();
137148
- const xdgData = process.env["XDG_DATA_HOME"] ?? join144(home, ".local", "share");
137149
- targetRoot = join144(xdgData, "cleo", "cant", "agents");
137565
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join146(home, ".local", "share");
137566
+ targetRoot = join146(xdgData, "cleo", "cant", "agents");
137150
137567
  } else {
137151
- targetRoot = join144(process.cwd(), ".cleo", "cant", "agents");
137568
+ targetRoot = join146(process.cwd(), ".cleo", "cant", "agents");
137152
137569
  }
137153
- const targetDir = join144(targetRoot, agentName);
137570
+ const targetDir = join146(targetRoot, agentName);
137154
137571
  mkdirSync36(targetRoot, { recursive: true });
137155
137572
  cpSync(agentDir, targetDir, { recursive: true, force: true });
137156
137573
  if (tempDir) {
@@ -137158,7 +137575,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137158
137575
  }
137159
137576
  let registered = false;
137160
137577
  try {
137161
- const persona = readFileSync108(join144(targetDir, "persona.cant"), "utf-8");
137578
+ const persona = readFileSync110(join146(targetDir, "persona.cant"), "utf-8");
137162
137579
  const descMatch = persona.match(/description:\s*"([^"]+)"/);
137163
137580
  const displayName = descMatch?.[1] ?? agentName;
137164
137581
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
@@ -137205,11 +137622,11 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137205
137622
  });
137206
137623
  agent.command("pack <dir>").description("Package an agent directory as a .cantz archive").action(async (dir) => {
137207
137624
  try {
137208
- const { existsSync: existsSync136, statSync: statSync22 } = await import("node:fs");
137625
+ const { existsSync: existsSync137, statSync: statSync22 } = await import("node:fs");
137209
137626
  const { resolve: resolve17, basename: basename19, dirname: dirname33 } = await import("node:path");
137210
137627
  const { execFileSync: execFileSync19 } = await import("node:child_process");
137211
137628
  const resolvedDir = resolve17(dir);
137212
- if (!existsSync136(resolvedDir) || !statSync22(resolvedDir).isDirectory()) {
137629
+ if (!existsSync137(resolvedDir) || !statSync22(resolvedDir).isDirectory()) {
137213
137630
  cliOutput(
137214
137631
  {
137215
137632
  success: false,
@@ -137223,9 +137640,9 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137223
137640
  process.exitCode = 4;
137224
137641
  return;
137225
137642
  }
137226
- const { join: join144 } = await import("node:path");
137227
- const personaPath = join144(resolvedDir, "persona.cant");
137228
- if (!existsSync136(personaPath)) {
137643
+ const { join: join146 } = await import("node:path");
137644
+ const personaPath = join146(resolvedDir, "persona.cant");
137645
+ if (!existsSync137(personaPath)) {
137229
137646
  cliOutput(
137230
137647
  {
137231
137648
  success: false,
@@ -137272,7 +137689,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137272
137689
  if (entry.isFile()) {
137273
137690
  fileCount++;
137274
137691
  } else if (entry.isDirectory()) {
137275
- countFiles2(join144(dirPath, entry.name));
137692
+ countFiles2(join146(dirPath, entry.name));
137276
137693
  }
137277
137694
  }
137278
137695
  };
@@ -137299,8 +137716,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137299
137716
  });
137300
137717
  agent.command("create").description("Scaffold a new agent package with persona.cant and manifest.json").requiredOption("--name <name>", "Agent name (kebab-case)").requiredOption("--role <role>", "Agent role: orchestrator, lead, worker, or docs-worker").option("--tier <tier>", "Agent tier: low, mid, or high (defaults based on role)").option("--team <teamName>", "Team this agent belongs to").option("--domain <description>", "Domain description for file permissions and context").option("--global", "Create in global tier (~/.local/share/cleo/cant/agents/)").option("--seed-brain", "Create expertise/mental-model-seed.md and seed a BRAIN observation").option("--parent <parentAgent>", "Parent agent name in the hierarchy").action(async (opts) => {
137301
137718
  try {
137302
- const { existsSync: existsSync136, mkdirSync: mkdirSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
137303
- const { join: join144 } = await import("node:path");
137719
+ const { existsSync: existsSync137, mkdirSync: mkdirSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
137720
+ const { join: join146 } = await import("node:path");
137304
137721
  const { homedir: homedir15 } = await import("node:os");
137305
137722
  const name2 = opts["name"];
137306
137723
  const role = opts["role"];
@@ -137360,13 +137777,13 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137360
137777
  let targetRoot;
137361
137778
  if (isGlobal) {
137362
137779
  const home = homedir15();
137363
- const xdgData = process.env["XDG_DATA_HOME"] ?? join144(home, ".local", "share");
137364
- targetRoot = join144(xdgData, "cleo", "cant", "agents");
137780
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join146(home, ".local", "share");
137781
+ targetRoot = join146(xdgData, "cleo", "cant", "agents");
137365
137782
  } else {
137366
- targetRoot = join144(process.cwd(), ".cleo", "cant", "agents");
137783
+ targetRoot = join146(process.cwd(), ".cleo", "cant", "agents");
137367
137784
  }
137368
- const agentDir = join144(targetRoot, name2);
137369
- if (existsSync136(agentDir)) {
137785
+ const agentDir = join146(targetRoot, name2);
137786
+ if (existsSync137(agentDir)) {
137370
137787
  cliOutput(
137371
137788
  {
137372
137789
  success: false,
@@ -137390,29 +137807,29 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
137390
137807
  domain: domain2,
137391
137808
  parent
137392
137809
  });
137393
- writeFileSync27(join144(agentDir, "persona.cant"), personaContent, "utf-8");
137810
+ writeFileSync27(join146(agentDir, "persona.cant"), personaContent, "utf-8");
137394
137811
  const manifest = generateManifest2({ name: name2, role, tier, domain: domain2 });
137395
137812
  writeFileSync27(
137396
- join144(agentDir, "manifest.json"),
137813
+ join146(agentDir, "manifest.json"),
137397
137814
  `${JSON.stringify(manifest, null, 2)}
137398
137815
  `,
137399
137816
  "utf-8"
137400
137817
  );
137401
137818
  const createdFiles = [
137402
- join144(agentDir, "persona.cant"),
137403
- join144(agentDir, "manifest.json")
137819
+ join146(agentDir, "persona.cant"),
137820
+ join146(agentDir, "manifest.json")
137404
137821
  ];
137405
137822
  if (team) {
137406
137823
  const teamConfigContent = generateTeamConfig(name2, role, team);
137407
- writeFileSync27(join144(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
137408
- createdFiles.push(join144(agentDir, "team-config.cant"));
137824
+ writeFileSync27(join146(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
137825
+ createdFiles.push(join146(agentDir, "team-config.cant"));
137409
137826
  }
137410
137827
  if (seedBrain) {
137411
- const expertiseDir = join144(agentDir, "expertise");
137828
+ const expertiseDir = join146(agentDir, "expertise");
137412
137829
  mkdirSync36(expertiseDir, { recursive: true });
137413
137830
  const seedContent = generateMentalModelSeed(name2, role, domain2);
137414
- writeFileSync27(join144(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
137415
- createdFiles.push(join144(expertiseDir, "mental-model-seed.md"));
137831
+ writeFileSync27(join146(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
137832
+ createdFiles.push(join146(expertiseDir, "mental-model-seed.md"));
137416
137833
  try {
137417
137834
  const { execFile: execFile9 } = await import("node:child_process");
137418
137835
  const { promisify: promisify9 } = await import("node:util");
@@ -139042,8 +139459,8 @@ function registerCancelCommand(program) {
139042
139459
 
139043
139460
  // packages/cleo/src/cli/commands/cant.ts
139044
139461
  init_renderers();
139045
- import { existsSync as existsSync132, mkdirSync as mkdirSync33, readFileSync as readFileSync101, writeFileSync as writeFileSync24 } from "node:fs";
139046
- import { dirname as dirname28, isAbsolute as isAbsolute3, join as join129, resolve as resolve16 } from "node:path";
139462
+ import { existsSync as existsSync133, mkdirSync as mkdirSync33, readFileSync as readFileSync103, writeFileSync as writeFileSync24 } from "node:fs";
139463
+ import { dirname as dirname28, isAbsolute as isAbsolute3, join as join131, resolve as resolve16 } from "node:path";
139047
139464
  function registerCantCommand(program) {
139048
139465
  const cant = program.command("cant").description("CANT DSL tooling");
139049
139466
  cant.command("parse <file>").description("Parse a .cant file and emit the AST").action(async (file2) => {
@@ -139111,7 +139528,7 @@ function registerCantCommand(program) {
139111
139528
  if (!ensureExists(filePath, "cant.migrate")) return;
139112
139529
  try {
139113
139530
  const mod = await loadMigrateEngine();
139114
- const content = readFileSync101(filePath, "utf-8");
139531
+ const content = readFileSync103(filePath, "utf-8");
139115
139532
  const result = mod.migrateMarkdown(content, filePath, {
139116
139533
  write: isWrite,
139117
139534
  verbose: isVerbose,
@@ -139121,7 +139538,7 @@ function registerCantCommand(program) {
139121
139538
  const projectRoot = process.cwd();
139122
139539
  let written = 0;
139123
139540
  for (const outputFile of result.outputFiles) {
139124
- const outputPath = isAbsolute3(outputFile.path) ? outputFile.path : join129(projectRoot, outputFile.path);
139541
+ const outputPath = isAbsolute3(outputFile.path) ? outputFile.path : join131(projectRoot, outputFile.path);
139125
139542
  mkdirSync33(dirname28(outputPath), { recursive: true });
139126
139543
  writeFileSync24(outputPath, outputFile.content, "utf-8");
139127
139544
  written++;
@@ -139162,7 +139579,7 @@ function resolveFilePath(file2) {
139162
139579
  return isAbsolute3(file2) ? file2 : resolve16(process.cwd(), file2);
139163
139580
  }
139164
139581
  function ensureExists(filePath, operation) {
139165
- if (existsSync132(filePath)) return true;
139582
+ if (existsSync133(filePath)) return true;
139166
139583
  cliError(`File not found: ${filePath}`, "E_FILE_READ");
139167
139584
  process.exitCode = 3;
139168
139585
  if (process.env["CLEO_DEBUG"]) {
@@ -139204,7 +139621,7 @@ async function loadMigrateEngine() {
139204
139621
 
139205
139622
  // packages/cleo/src/cli/commands/chain.ts
139206
139623
  init_cli();
139207
- import { readFileSync as readFileSync102 } from "node:fs";
139624
+ import { readFileSync as readFileSync104 } from "node:fs";
139208
139625
  function registerChainCommand(program) {
139209
139626
  const chain = program.command("chain").description("WarpChain pipeline management (tier-2 orchestrator)");
139210
139627
  chain.command("show <chainId>").description("Show details for a WarpChain definition").action(async (chainId) => {
@@ -139214,7 +139631,7 @@ function registerChainCommand(program) {
139214
139631
  await dispatchFromCli("query", "pipeline", "chain.list", {}, { command: "chain" });
139215
139632
  });
139216
139633
  chain.command("add <file>").description("Add a new WarpChain definition from a JSON file").action(async (file2) => {
139217
- const chainJson = JSON.parse(readFileSync102(file2, "utf-8"));
139634
+ const chainJson = JSON.parse(readFileSync104(file2, "utf-8"));
139218
139635
  await dispatchFromCli(
139219
139636
  "mutate",
139220
139637
  "pipeline",
@@ -139283,10 +139700,10 @@ function registerCheckCommand(program) {
139283
139700
  );
139284
139701
  });
139285
139702
  check2.command("chain-validate <file>").description("Validate a WarpChain definition from a JSON file").action(async (file2) => {
139286
- const { readFileSync: readFileSync108 } = await import("node:fs");
139703
+ const { readFileSync: readFileSync110 } = await import("node:fs");
139287
139704
  let chain;
139288
139705
  try {
139289
- chain = JSON.parse(readFileSync108(file2, "utf8"));
139706
+ chain = JSON.parse(readFileSync110(file2, "utf8"));
139290
139707
  } catch (err) {
139291
139708
  const message = err instanceof Error ? err.message : String(err);
139292
139709
  console.error(`Failed to read or parse chain file: ${message}`);
@@ -139300,6 +139717,9 @@ function registerCheckCommand(program) {
139300
139717
  { command: "check", operation: "check.chain.validate" }
139301
139718
  );
139302
139719
  });
139720
+ check2.command("canon").description("CI gate: detect canon drift between docs and live code").action(async () => {
139721
+ await dispatchFromCli("query", "check", "canon", {}, { command: "check" });
139722
+ });
139303
139723
  check2.command("protocol <protocolType>").description(
139304
139724
  `Validate any of the 12 RCASD-IVTR+C protocols: ${SUPPORTED_PROTOCOL_TYPES.join(", ")}`
139305
139725
  ).option("--task-id <id>", "Task ID to validate (mode=task, default)").option("--manifest-file <file>", "Manifest file to validate (mode=manifest)").option("--strict", "Exit with error code on violations").option("--voting-matrix-file <file>", "consensus: voting matrix JSON file").option("--epic-id <id>", "decomposition: parent epic ID").option("--sibling-count <n>", "decomposition: actual sibling count", Number).option("--max-siblings <n>", "decomposition: configured max siblings", Number).option("--spec-file <file>", "specification: path to spec markdown").option("--has-code-changes", "research: code changes detected (forbidden)").option("--has-task-tags", "implementation: @task tags present in code").option("--has-contribution-tags", "contribution: @contribution tags present").option("--version <v>", "release: target version (semver/calver)").option("--has-changelog", "release: changelog updated").option(
@@ -139805,20 +140225,20 @@ function registerCurrentCommand(program) {
139805
140225
 
139806
140226
  // packages/cleo/src/cli/commands/daemon.ts
139807
140227
  import { homedir as homedir10 } from "node:os";
139808
- import { join as join133 } from "node:path";
140228
+ import { join as join135 } from "node:path";
139809
140229
 
139810
140230
  // packages/cleo/src/gc/daemon.ts
139811
140231
  import { spawn as spawn2 } from "node:child_process";
139812
140232
  import { createWriteStream as createWriteStream2 } from "node:fs";
139813
140233
  import { mkdir as mkdir20 } from "node:fs/promises";
139814
- import { join as join132 } from "node:path";
140234
+ import { join as join134 } from "node:path";
139815
140235
  import { fileURLToPath as fileURLToPath8 } from "node:url";
139816
140236
  import cron from "node-cron";
139817
140237
 
139818
140238
  // packages/cleo/src/gc/runner.ts
139819
140239
  import { lstat as lstat2, readdir as readdir4, rm as rm3, stat as stat4 } from "node:fs/promises";
139820
140240
  import { homedir as homedir9 } from "node:os";
139821
- import { join as join131 } from "node:path";
140241
+ import { join as join133 } from "node:path";
139822
140242
 
139823
140243
  // node_modules/.pnpm/check-disk-space@3.4.0/node_modules/check-disk-space/dist/check-disk-space.mjs
139824
140244
  import { execFile as execFile7 } from "node:child_process";
@@ -139957,7 +140377,7 @@ function checkDiskSpace(directoryPath, dependencies = {
139957
140377
 
139958
140378
  // packages/cleo/src/gc/state.ts
139959
140379
  import { mkdir as mkdir19, readFile as readFile22, rename as rename2, writeFile as writeFile14 } from "node:fs/promises";
139960
- import { dirname as dirname29, join as join130 } from "node:path";
140380
+ import { dirname as dirname29, join as join132 } from "node:path";
139961
140381
  var GC_STATE_SCHEMA_VERSION = "1.0";
139962
140382
  var DEFAULT_GC_STATE = {
139963
140383
  schemaVersion: GC_STATE_SCHEMA_VERSION,
@@ -139985,7 +140405,7 @@ async function readGCState(statePath) {
139985
140405
  async function writeGCState(statePath, state) {
139986
140406
  const dir = dirname29(statePath);
139987
140407
  await mkdir19(dir, { recursive: true });
139988
- const tmpPath = join130(dir, `.gc-state-${process.pid}.tmp`);
140408
+ const tmpPath = join132(dir, `.gc-state-${process.pid}.tmp`);
139989
140409
  const json3 = JSON.stringify(state, null, 2);
139990
140410
  await writeFile14(tmpPath, json3, "utf-8");
139991
140411
  await rename2(tmpPath, statePath);
@@ -140034,7 +140454,7 @@ async function getPathBytes(targetPath) {
140034
140454
  const entries = await readdir4(targetPath, { withFileTypes: true });
140035
140455
  let total = 0;
140036
140456
  for (const entry of entries) {
140037
- total += await getPathBytes(join131(targetPath, entry.name));
140457
+ total += await getPathBytes(join133(targetPath, entry.name));
140038
140458
  }
140039
140459
  return total;
140040
140460
  } catch {
@@ -140051,7 +140471,7 @@ async function idempotentRm(targetPath) {
140051
140471
  }
140052
140472
  }
140053
140473
  async function gatherPruneCandidates(maxAgeMs, projectsDir) {
140054
- const resolvedProjectsDir = projectsDir ?? join131(homedir9(), ".claude", "projects");
140474
+ const resolvedProjectsDir = projectsDir ?? join133(homedir9(), ".claude", "projects");
140055
140475
  const candidates = [];
140056
140476
  const now2 = Date.now();
140057
140477
  let projectSlugs;
@@ -140062,7 +140482,7 @@ async function gatherPruneCandidates(maxAgeMs, projectsDir) {
140062
140482
  return candidates;
140063
140483
  }
140064
140484
  for (const slug of projectSlugs) {
140065
- const slugDir = join131(resolvedProjectsDir, slug);
140485
+ const slugDir = join133(resolvedProjectsDir, slug);
140066
140486
  let slugEntries;
140067
140487
  try {
140068
140488
  slugEntries = await readdir4(slugDir, { withFileTypes: true });
@@ -140070,7 +140490,7 @@ async function gatherPruneCandidates(maxAgeMs, projectsDir) {
140070
140490
  continue;
140071
140491
  }
140072
140492
  for (const entry of slugEntries) {
140073
- const entryPath = join131(slugDir, entry.name);
140493
+ const entryPath = join133(slugDir, entry.name);
140074
140494
  if (entry.isFile() && entry.name.endsWith(".jsonl")) {
140075
140495
  try {
140076
140496
  const info = await stat4(entryPath);
@@ -140095,8 +140515,8 @@ async function gatherPruneCandidates(maxAgeMs, projectsDir) {
140095
140515
  return candidates;
140096
140516
  }
140097
140517
  async function runGC(opts = {}) {
140098
- const cleoDir = opts.cleoDir ?? join131(homedir9(), ".cleo");
140099
- const statePath = join131(cleoDir, "gc-state.json");
140518
+ const cleoDir = opts.cleoDir ?? join133(homedir9(), ".cleo");
140519
+ const statePath = join133(cleoDir, "gc-state.json");
140100
140520
  const dryRun = opts.dryRun ?? false;
140101
140521
  const projectsDir = opts.projectsDir;
140102
140522
  const initialState = await readGCState(statePath);
@@ -140169,13 +140589,13 @@ async function runGC(opts = {}) {
140169
140589
  // packages/cleo/src/gc/daemon.ts
140170
140590
  var GC_INTERVAL_MS = 24 * 60 * 60 * 1e3;
140171
140591
  async function spawnGCDaemon(cleoDir) {
140172
- const logsDir = join132(cleoDir, "logs");
140592
+ const logsDir = join134(cleoDir, "logs");
140173
140593
  await mkdir20(logsDir, { recursive: true });
140174
- const logPath = join132(logsDir, "gc.log");
140175
- const errPath = join132(logsDir, "gc.err");
140594
+ const logPath = join134(logsDir, "gc.log");
140595
+ const errPath = join134(logsDir, "gc.err");
140176
140596
  const outStream = createWriteStream2(logPath, { flags: "a" });
140177
140597
  const errStream = createWriteStream2(errPath, { flags: "a" });
140178
- const daemonEntry = join132(fileURLToPath8(import.meta.url), "..", "daemon-entry.js");
140598
+ const daemonEntry = join134(fileURLToPath8(import.meta.url), "..", "daemon-entry.js");
140179
140599
  const child = spawn2(process.execPath, [daemonEntry, cleoDir], {
140180
140600
  detached: true,
140181
140601
  stdio: ["ignore", outStream, errStream],
@@ -140183,14 +140603,14 @@ async function spawnGCDaemon(cleoDir) {
140183
140603
  });
140184
140604
  child.unref();
140185
140605
  const pid = child.pid ?? 0;
140186
- await patchGCState(join132(cleoDir, "gc-state.json"), {
140606
+ await patchGCState(join134(cleoDir, "gc-state.json"), {
140187
140607
  daemonPid: pid,
140188
140608
  daemonStartedAt: (/* @__PURE__ */ new Date()).toISOString()
140189
140609
  });
140190
140610
  return pid;
140191
140611
  }
140192
140612
  async function stopGCDaemon(cleoDir) {
140193
- const statePath = join132(cleoDir, "gc-state.json");
140613
+ const statePath = join134(cleoDir, "gc-state.json");
140194
140614
  const state = await readGCState(statePath);
140195
140615
  const pid = state.daemonPid;
140196
140616
  if (!pid) {
@@ -140216,7 +140636,7 @@ async function stopGCDaemon(cleoDir) {
140216
140636
  }
140217
140637
  }
140218
140638
  async function getGCDaemonStatus(cleoDir) {
140219
- const state = await readGCState(join132(cleoDir, "gc-state.json"));
140639
+ const state = await readGCState(join134(cleoDir, "gc-state.json"));
140220
140640
  const pid = state.daemonPid;
140221
140641
  let running = false;
140222
140642
  if (pid) {
@@ -140241,7 +140661,7 @@ async function getGCDaemonStatus(cleoDir) {
140241
140661
  function registerDaemonCommand(program) {
140242
140662
  const daemon = program.command("daemon").description("Manage the CLEO GC sidecar daemon for autonomous transcript cleanup");
140243
140663
  daemon.command("start").description("Spawn the GC daemon as a detached background process").option("--cleo-dir <path>", "Override .cleo/ directory path").option("--json", "Output result as JSON").action(async (opts) => {
140244
- const cleoDir = opts.cleoDir ?? join133(homedir10(), ".cleo");
140664
+ const cleoDir = opts.cleoDir ?? join135(homedir10(), ".cleo");
140245
140665
  try {
140246
140666
  const status = await getGCDaemonStatus(cleoDir);
140247
140667
  if (status.running && status.pid) {
@@ -140271,7 +140691,7 @@ function registerDaemonCommand(program) {
140271
140691
  } else {
140272
140692
  process.stdout.write(`GC daemon started (PID ${pid})
140273
140693
  `);
140274
- process.stdout.write(`Logs: ${join133(cleoDir, "logs", "gc.log")}
140694
+ process.stdout.write(`Logs: ${join135(cleoDir, "logs", "gc.log")}
140275
140695
  `);
140276
140696
  }
140277
140697
  } catch (err) {
@@ -140287,7 +140707,7 @@ function registerDaemonCommand(program) {
140287
140707
  }
140288
140708
  });
140289
140709
  daemon.command("stop").description("Stop the GC daemon by sending SIGTERM to its PID").option("--cleo-dir <path>", "Override .cleo/ directory path").option("--json", "Output result as JSON").action(async (opts) => {
140290
- const cleoDir = opts.cleoDir ?? join133(homedir10(), ".cleo");
140710
+ const cleoDir = opts.cleoDir ?? join135(homedir10(), ".cleo");
140291
140711
  try {
140292
140712
  const stopResult = await stopGCDaemon(cleoDir);
140293
140713
  const result = {
@@ -140316,11 +140736,11 @@ function registerDaemonCommand(program) {
140316
140736
  }
140317
140737
  });
140318
140738
  daemon.command("status").description("Show daemon running state, PID, last GC run, and disk usage").option("--cleo-dir <path>", "Override .cleo/ directory path").option("--json", "Output result as JSON").action(async (opts) => {
140319
- const cleoDir = opts.cleoDir ?? join133(homedir10(), ".cleo");
140739
+ const cleoDir = opts.cleoDir ?? join135(homedir10(), ".cleo");
140320
140740
  await showDaemonStatus(cleoDir, opts.json ?? false);
140321
140741
  });
140322
140742
  daemon.action(async (opts) => {
140323
- const cleoDir = opts.cleoDir ?? join133(homedir10(), ".cleo");
140743
+ const cleoDir = opts.cleoDir ?? join135(homedir10(), ".cleo");
140324
140744
  await showDaemonStatus(cleoDir, opts.json ?? false);
140325
140745
  });
140326
140746
  }
@@ -140510,12 +140930,12 @@ function registerDetectCommand(program) {
140510
140930
  // packages/cleo/src/cli/commands/detect-drift.ts
140511
140931
  init_src();
140512
140932
  init_renderers();
140513
- import { existsSync as existsSync133, readdirSync as readdirSync41, readFileSync as readFileSync103 } from "node:fs";
140514
- import { dirname as dirname30, join as join134 } from "node:path";
140933
+ import { existsSync as existsSync134, readdirSync as readdirSync41, readFileSync as readFileSync105 } from "node:fs";
140934
+ import { dirname as dirname30, join as join136 } from "node:path";
140515
140935
  function findProjectRoot() {
140516
140936
  let currentDir = process.cwd();
140517
140937
  while (currentDir !== "/") {
140518
- if (existsSync133(join134(currentDir, "package.json"))) {
140938
+ if (existsSync134(join136(currentDir, "package.json"))) {
140519
140939
  return currentDir;
140520
140940
  }
140521
140941
  const parent = dirname30(currentDir);
@@ -140527,11 +140947,11 @@ function findProjectRoot() {
140527
140947
  function registerDetectDriftCommand(program) {
140528
140948
  program.command("detect-drift").description("Detect documentation drift against TypeScript source of truth").action(async () => {
140529
140949
  const projectRoot = findProjectRoot();
140530
- const isCleoRepo = existsSync133(join134(projectRoot, "packages", "cleo", "src"));
140531
- const cleoSrcRoot = isCleoRepo ? join134(projectRoot, "packages", "cleo", "src") : join134(projectRoot, "src");
140950
+ const isCleoRepo = existsSync134(join136(projectRoot, "packages", "cleo", "src"));
140951
+ const cleoSrcRoot = isCleoRepo ? join136(projectRoot, "packages", "cleo", "src") : join136(projectRoot, "src");
140532
140952
  const safeRead = (filePath) => {
140533
140953
  try {
140534
- return readFileSync103(filePath, "utf-8");
140954
+ return readFileSync105(filePath, "utf-8");
140535
140955
  } catch {
140536
140956
  return "";
140537
140957
  }
@@ -140542,8 +140962,8 @@ function registerDetectDriftCommand(program) {
140542
140962
  checks: [],
140543
140963
  recommendations: []
140544
140964
  };
140545
- const injPath = join134(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
140546
- if (existsSync133(injPath)) {
140965
+ const injPath = join136(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
140966
+ if (existsSync134(injPath)) {
140547
140967
  const content = safeRead(injPath);
140548
140968
  userResult.checks.push({
140549
140969
  name: "Agent injection",
@@ -140594,10 +141014,10 @@ function registerDetectDriftCommand(program) {
140594
141014
  }
140595
141015
  };
140596
141016
  try {
140597
- const specPath = join134(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
140598
- const registryPath = join134(cleoSrcRoot, "dispatch", "registry.ts");
140599
- const dispatchDomainsDir = join134(cleoSrcRoot, "dispatch", "domains");
140600
- if (!existsSync133(specPath)) {
141017
+ const specPath = join136(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
141018
+ const registryPath = join136(cleoSrcRoot, "dispatch", "registry.ts");
141019
+ const dispatchDomainsDir = join136(cleoSrcRoot, "dispatch", "domains");
141020
+ if (!existsSync134(specPath)) {
140601
141021
  addCheck("Gateway-to-spec sync", "fail", "CLEO-OPERATION-CONSTITUTION.md missing", [
140602
141022
  {
140603
141023
  severity: "error",
@@ -140607,7 +141027,7 @@ function registerDetectDriftCommand(program) {
140607
141027
  recommendation: "Create docs/specs/CLEO-OPERATION-CONSTITUTION.md with canonical operation definitions"
140608
141028
  }
140609
141029
  ]);
140610
- } else if (!existsSync133(registryPath) || !existsSync133(dispatchDomainsDir)) {
141030
+ } else if (!existsSync134(registryPath) || !existsSync134(dispatchDomainsDir)) {
140611
141031
  addCheck("Gateway-to-spec sync", "fail", "Dispatch registry or domains missing", [
140612
141032
  {
140613
141033
  severity: "error",
@@ -140671,9 +141091,9 @@ function registerDetectDriftCommand(program) {
140671
141091
  ]);
140672
141092
  }
140673
141093
  try {
140674
- const cliDir = join134(cleoSrcRoot, "cli", "commands");
140675
- const coreDir = isCleoRepo ? join134(projectRoot, "packages", "core", "src") : join134(projectRoot, "src", "core");
140676
- if (!existsSync133(cliDir)) {
141094
+ const cliDir = join136(cleoSrcRoot, "cli", "commands");
141095
+ const coreDir = isCleoRepo ? join136(projectRoot, "packages", "core", "src") : join136(projectRoot, "src", "core");
141096
+ if (!existsSync134(cliDir)) {
140677
141097
  addCheck("CLI-to-core sync", "fail", "CLI commands directory missing", [
140678
141098
  {
140679
141099
  severity: "error",
@@ -140682,7 +141102,7 @@ function registerDetectDriftCommand(program) {
140682
141102
  recommendation: "Verify TypeScript source structure is intact"
140683
141103
  }
140684
141104
  ]);
140685
- } else if (!existsSync133(coreDir)) {
141105
+ } else if (!existsSync134(coreDir)) {
140686
141106
  addCheck("CLI-to-core sync", "fail", "Core directory missing", [
140687
141107
  {
140688
141108
  severity: "error",
@@ -140701,8 +141121,8 @@ function registerDetectDriftCommand(program) {
140701
141121
  addCheck("CLI-to-core sync", "fail", `Error: ${getErrorMessage(e)}`);
140702
141122
  }
140703
141123
  try {
140704
- const domainsDir = join134(cleoSrcRoot, "dispatch", "domains");
140705
- if (!existsSync133(domainsDir)) {
141124
+ const domainsDir = join136(cleoSrcRoot, "dispatch", "domains");
141125
+ if (!existsSync134(domainsDir)) {
140706
141126
  addCheck("Domain handler coverage", "fail", "Dispatch domains directory missing", [
140707
141127
  {
140708
141128
  severity: "error",
@@ -140719,8 +141139,8 @@ function registerDetectDriftCommand(program) {
140719
141139
  addCheck("Domain handler coverage", "fail", `Error: ${getErrorMessage(e)}`);
140720
141140
  }
140721
141141
  try {
140722
- const matrixPath = join134(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
140723
- if (!existsSync133(matrixPath)) {
141142
+ const matrixPath = join136(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
141143
+ if (!existsSync134(matrixPath)) {
140724
141144
  addCheck("Capability matrix", "fail", "Capability matrix missing", [
140725
141145
  {
140726
141146
  severity: "error",
@@ -140736,8 +141156,8 @@ function registerDetectDriftCommand(program) {
140736
141156
  addCheck("Capability matrix", "fail", `Error: ${getErrorMessage(e)}`);
140737
141157
  }
140738
141158
  try {
140739
- const schemaPath = join134(projectRoot, "src", "store", "schema.ts");
140740
- if (!existsSync133(schemaPath)) {
141159
+ const schemaPath = join136(projectRoot, "src", "store", "schema.ts");
141160
+ if (!existsSync134(schemaPath)) {
140741
141161
  addCheck("Schema validation", "fail", "Schema definition missing", [
140742
141162
  {
140743
141163
  severity: "error",
@@ -140771,10 +141191,10 @@ function registerDetectDriftCommand(program) {
140771
141191
  addCheck("Schema validation", "fail", `Error: ${getErrorMessage(e)}`);
140772
141192
  }
140773
141193
  try {
140774
- const visionPath = join134(projectRoot, "docs", "concepts", "CLEO-VISION.md");
140775
- const specPath = join134(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
141194
+ const visionPath = join136(projectRoot, "docs", "concepts", "CLEO-VISION.md");
141195
+ const specPath = join136(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
140776
141196
  const issues = [];
140777
- if (!existsSync133(visionPath)) {
141197
+ if (!existsSync134(visionPath)) {
140778
141198
  issues.push({
140779
141199
  severity: "error",
140780
141200
  category: "vision",
@@ -140783,7 +141203,7 @@ function registerDetectDriftCommand(program) {
140783
141203
  recommendation: "Create docs/concepts/CLEO-VISION.md with project vision"
140784
141204
  });
140785
141205
  }
140786
- if (!existsSync133(specPath)) {
141206
+ if (!existsSync134(specPath)) {
140787
141207
  issues.push({
140788
141208
  severity: "error",
140789
141209
  category: "spec",
@@ -140827,8 +141247,8 @@ function registerDetectDriftCommand(program) {
140827
141247
  addCheck("Canonical identity", "fail", `Error: ${getErrorMessage(e)}`);
140828
141248
  }
140829
141249
  try {
140830
- const injectionPath = join134(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
140831
- if (!existsSync133(injectionPath)) {
141250
+ const injectionPath = join136(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
141251
+ if (!existsSync134(injectionPath)) {
140832
141252
  addCheck("Agent injection", "fail", "Agent injection template missing", [
140833
141253
  {
140834
141254
  severity: "error",
@@ -140857,8 +141277,8 @@ function registerDetectDriftCommand(program) {
140857
141277
  addCheck("Agent injection", "fail", `Error: ${getErrorMessage(e)}`);
140858
141278
  }
140859
141279
  try {
140860
- const exitCodesPath = join134(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
140861
- if (!existsSync133(exitCodesPath)) {
141280
+ const exitCodesPath = join136(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
141281
+ if (!existsSync134(exitCodesPath)) {
140862
141282
  addCheck("Exit codes", "fail", "Exit codes definition missing", [
140863
141283
  {
140864
141284
  severity: "error",
@@ -140935,9 +141355,9 @@ function registerDiagnosticsCommand(program) {
140935
141355
  init_internal();
140936
141356
  init_renderers();
140937
141357
  import { readdir as readdir5, readFile as readFile23 } from "node:fs/promises";
140938
- import { join as join135 } from "node:path";
141358
+ import { join as join137 } from "node:path";
140939
141359
  async function getScriptNames(projectRoot) {
140940
- const scriptsDir = join135(projectRoot, "scripts");
141360
+ const scriptsDir = join137(projectRoot, "scripts");
140941
141361
  try {
140942
141362
  const files = await readdir5(scriptsDir);
140943
141363
  return files.filter((f2) => f2.endsWith(".sh")).map((f2) => f2.replace(".sh", "")).sort();
@@ -140946,7 +141366,7 @@ async function getScriptNames(projectRoot) {
140946
141366
  }
140947
141367
  }
140948
141368
  async function getIndexedCommands(projectRoot) {
140949
- const indexPath = join135(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
141369
+ const indexPath = join137(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
140950
141370
  const index2 = await readJson(indexPath);
140951
141371
  if (!index2) return [];
140952
141372
  return index2.commands.map((c) => c.name).sort();
@@ -140979,7 +141399,7 @@ async function runGapCheck(_projectRoot, filterId) {
140979
141399
  const reviewFiles = files.filter((f2) => f2.endsWith(".md"));
140980
141400
  for (const file2 of reviewFiles) {
140981
141401
  if (filterId && !file2.includes(filterId)) continue;
140982
- const filePath = join135(reviewDir, file2);
141402
+ const filePath = join137(reviewDir, file2);
140983
141403
  const content = await readFile23(filePath, "utf-8");
140984
141404
  const taskMatch = file2.match(/^(T\d+)/);
140985
141405
  const taskId = taskMatch ? taskMatch[1] : "UNKNOWN";
@@ -141528,11 +141948,11 @@ function registerFindCommand(program) {
141528
141948
 
141529
141949
  // packages/cleo/src/cli/commands/gc.ts
141530
141950
  import { homedir as homedir11 } from "node:os";
141531
- import { join as join136 } from "node:path";
141951
+ import { join as join138 } from "node:path";
141532
141952
  function registerGCCommand(program) {
141533
141953
  const gc = program.command("gc").description("Transcript garbage collection: manual trigger and status");
141534
141954
  gc.command("run").description("Run GC immediately (blocking). Prunes old transcripts based on disk pressure.").option("--cleo-dir <path>", "Override .cleo/ directory path").option("--dry-run", "Report what would be pruned without deleting anything").option("--json", "Output result as JSON").action(async (opts) => {
141535
- const cleoDir = opts.cleoDir ?? join136(homedir11(), ".cleo");
141955
+ const cleoDir = opts.cleoDir ?? join138(homedir11(), ".cleo");
141536
141956
  const dryRun = opts.dryRun ?? false;
141537
141957
  try {
141538
141958
  const gcResult = await runGC({ cleoDir, dryRun });
@@ -141570,8 +141990,8 @@ WARNING: ${gcResult.escalationReason}
141570
141990
  }
141571
141991
  });
141572
141992
  gc.command("status").description("Show last GC run stats, disk usage, and escalation state").option("--cleo-dir <path>", "Override .cleo/ directory path").option("--json", "Output result as JSON").action(async (opts) => {
141573
- const cleoDir = opts.cleoDir ?? join136(homedir11(), ".cleo");
141574
- const statePath = join136(cleoDir, "gc-state.json");
141993
+ const cleoDir = opts.cleoDir ?? join138(homedir11(), ".cleo");
141994
+ const statePath = join138(cleoDir, "gc-state.json");
141575
141995
  try {
141576
141996
  const state = await readGCState(statePath);
141577
141997
  const result = { success: true, data: state };
@@ -141624,12 +142044,12 @@ init_src();
141624
142044
  init_src3();
141625
142045
  init_renderers();
141626
142046
  import { execFileSync as execFileSync16 } from "node:child_process";
141627
- import { existsSync as existsSync134, mkdirSync as mkdirSync34, readFileSync as readFileSync104, writeFileSync as writeFileSync25 } from "node:fs";
141628
- import { dirname as dirname31, join as join137 } from "node:path";
142047
+ import { existsSync as existsSync135, mkdirSync as mkdirSync34, readFileSync as readFileSync106, writeFileSync as writeFileSync25 } from "node:fs";
142048
+ import { dirname as dirname31, join as join139 } from "node:path";
141629
142049
  function getChangelogSource(cwd) {
141630
142050
  const configPath = getConfigPath(cwd);
141631
142051
  try {
141632
- const config2 = JSON.parse(readFileSync104(configPath, "utf-8"));
142052
+ const config2 = JSON.parse(readFileSync106(configPath, "utf-8"));
141633
142053
  return config2?.release?.changelog?.source ?? "CHANGELOG.md";
141634
142054
  } catch {
141635
142055
  return "CHANGELOG.md";
@@ -141638,7 +142058,7 @@ function getChangelogSource(cwd) {
141638
142058
  function getEnabledPlatforms(cwd) {
141639
142059
  const configPath = getConfigPath(cwd);
141640
142060
  try {
141641
- const config2 = JSON.parse(readFileSync104(configPath, "utf-8"));
142061
+ const config2 = JSON.parse(readFileSync106(configPath, "utf-8"));
141642
142062
  const outputs = config2?.release?.changelog?.outputs ?? [];
141643
142063
  return outputs.filter((o) => o.enabled);
141644
142064
  } catch {
@@ -141763,11 +142183,11 @@ function registerGenerateChangelogCommand(program) {
141763
142183
  const targetPlatform = opts["platform"];
141764
142184
  const dryRun = !!opts["dryRun"];
141765
142185
  const sourceFile = getChangelogSource();
141766
- const sourcePath = join137(getProjectRoot(), sourceFile);
141767
- if (!existsSync134(sourcePath)) {
142186
+ const sourcePath = join139(getProjectRoot(), sourceFile);
142187
+ if (!existsSync135(sourcePath)) {
141768
142188
  throw new CleoError(4 /* NOT_FOUND */, `Changelog source not found: ${sourcePath}`);
141769
142189
  }
141770
- const sourceContent = readFileSync104(sourcePath, "utf-8");
142190
+ const sourceContent = readFileSync106(sourcePath, "utf-8");
141771
142191
  const repoSlug = getGitHubRepoSlug();
141772
142192
  const results = [];
141773
142193
  if (targetPlatform) {
@@ -141776,7 +142196,7 @@ function registerGenerateChangelogCommand(program) {
141776
142196
  const outputPath = platformConfig?.path ?? getDefaultOutputPath(targetPlatform);
141777
142197
  const content = generateForPlatform(targetPlatform, sourceContent, repoSlug, limit);
141778
142198
  if (!dryRun) {
141779
- const fullPath = join137(getProjectRoot(), outputPath);
142199
+ const fullPath = join139(getProjectRoot(), outputPath);
141780
142200
  mkdirSync34(dirname31(fullPath), { recursive: true });
141781
142201
  writeFileSync25(fullPath, content, "utf-8");
141782
142202
  }
@@ -141797,7 +142217,7 @@ function registerGenerateChangelogCommand(program) {
141797
142217
  limit
141798
142218
  );
141799
142219
  if (!dryRun) {
141800
- const fullPath = join137(getProjectRoot(), platformConfig.path);
142220
+ const fullPath = join139(getProjectRoot(), platformConfig.path);
141801
142221
  mkdirSync34(dirname31(fullPath), { recursive: true });
141802
142222
  writeFileSync25(fullPath, content, "utf-8");
141803
142223
  }
@@ -142384,9 +142804,9 @@ init_internal();
142384
142804
  init_cli();
142385
142805
  init_renderers();
142386
142806
  import { createHash as createHash20 } from "node:crypto";
142387
- import { existsSync as existsSync135, mkdirSync as mkdirSync35, readdirSync as readdirSync42, readFileSync as readFileSync105, writeFileSync as writeFileSync26 } from "node:fs";
142807
+ import { existsSync as existsSync136, mkdirSync as mkdirSync35, readdirSync as readdirSync42, readFileSync as readFileSync107, writeFileSync as writeFileSync26 } from "node:fs";
142388
142808
  import { homedir as homedir12 } from "node:os";
142389
- import { join as join138 } from "node:path";
142809
+ import { join as join140 } from "node:path";
142390
142810
  function parseMemoryFileFrontmatter(raw) {
142391
142811
  const lines = raw.split("\n");
142392
142812
  if (!lines[0]?.trim().startsWith("---")) {
@@ -142419,8 +142839,8 @@ ${body}`).digest("hex").slice(0, 16);
142419
142839
  }
142420
142840
  function loadImportHashes(stateFile) {
142421
142841
  try {
142422
- if (!existsSync135(stateFile)) return /* @__PURE__ */ new Set();
142423
- const raw = readFileSync105(stateFile, "utf-8");
142842
+ if (!existsSync136(stateFile)) return /* @__PURE__ */ new Set();
142843
+ const raw = readFileSync107(stateFile, "utf-8");
142424
142844
  const parsed = JSON.parse(raw);
142425
142845
  return new Set(parsed.hashes);
142426
142846
  } catch {
@@ -142429,7 +142849,7 @@ function loadImportHashes(stateFile) {
142429
142849
  }
142430
142850
  function saveImportHashes(stateFile, hashes) {
142431
142851
  const dir = stateFile.slice(0, stateFile.lastIndexOf("/"));
142432
- if (!existsSync135(dir)) mkdirSync35(dir, { recursive: true });
142852
+ if (!existsSync136(dir)) mkdirSync35(dir, { recursive: true });
142433
142853
  writeFileSync26(stateFile, JSON.stringify({ hashes: [...hashes] }, null, 2), "utf-8");
142434
142854
  }
142435
142855
  function registerMemoryBrainCommand(program) {
@@ -143128,12 +143548,12 @@ Found ${totalDups} duplicate rows across ${groups.length} groups:`);
143128
143548
  "--from <dir>",
143129
143549
  "Source directory containing *.md memory files (default: ~/.claude/projects/-mnt-projects-cleocode/memory)"
143130
143550
  ).option("--dry-run", "Print what would be imported without writing to brain.db").option("--json", "Output results as JSON").action(async (opts) => {
143131
- const sourceDir = opts.from ?? join138(homedir12(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
143551
+ const sourceDir = opts.from ?? join140(homedir12(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
143132
143552
  const isDryRun = !!opts.dryRun;
143133
143553
  const isJson = !!opts.json;
143134
143554
  const projectRoot = getProjectRoot();
143135
- const stateFile = join138(projectRoot, ".cleo", "migrate-memory-hashes.json");
143136
- if (!existsSync135(sourceDir)) {
143555
+ const stateFile = join140(projectRoot, ".cleo", "migrate-memory-hashes.json");
143556
+ if (!existsSync136(sourceDir)) {
143137
143557
  const msg = `Source directory not found: ${sourceDir}`;
143138
143558
  if (isJson) {
143139
143559
  console.log(JSON.stringify({ success: false, error: msg }));
@@ -143142,7 +143562,7 @@ Found ${totalDups} duplicate rows across ${groups.length} groups:`);
143142
143562
  }
143143
143563
  process.exit(1);
143144
143564
  }
143145
- const files = readdirSync42(sourceDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md").map((f2) => join138(sourceDir, f2));
143565
+ const files = readdirSync42(sourceDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md").map((f2) => join140(sourceDir, f2));
143146
143566
  const importedHashes = isDryRun ? /* @__PURE__ */ new Set() : loadImportHashes(stateFile);
143147
143567
  const stats2 = { total: files.length, imported: 0, skipped: 0, errors: 0 };
143148
143568
  const importedEntries = [];
@@ -143157,7 +143577,7 @@ Found ${totalDups} duplicate rows across ${groups.length} groups:`);
143157
143577
  for (const filePath of files) {
143158
143578
  const fileName = filePath.split("/").pop() ?? filePath;
143159
143579
  try {
143160
- const raw = readFileSync105(filePath, "utf-8");
143580
+ const raw = readFileSync107(filePath, "utf-8");
143161
143581
  if (!raw.trim()) {
143162
143582
  stats2.skipped++;
143163
143583
  skippedEntries.push({ file: fileName, reason: "empty file" });
@@ -145097,11 +145517,11 @@ function registerNexusCommand(program) {
145097
145517
  const rawRoots = typeof opts["roots"] === "string" && opts["roots"].trim().length > 0 ? opts["roots"].split(",").map((r) => r.trim()).filter((r) => r.length > 0).map(
145098
145518
  (r) => r.startsWith("~") ? path10.join(home, r.slice(1)) : path10.resolve(r)
145099
145519
  ) : defaultRoots;
145100
- const { existsSync: existsSync136, readdirSync: readdirSync43, statSync: statSync22 } = await import("node:fs");
145520
+ const { existsSync: existsSync137, readdirSync: readdirSync43, statSync: statSync22 } = await import("node:fs");
145101
145521
  const { Dirent } = await import("node:fs");
145102
145522
  const roots = rawRoots.filter((r) => {
145103
145523
  try {
145104
- return existsSync136(r) && statSync22(r).isDirectory();
145524
+ return existsSync137(r) && statSync22(r).isDirectory();
145105
145525
  } catch {
145106
145526
  return false;
145107
145527
  }
@@ -147518,7 +147938,7 @@ init_src();
147518
147938
  init_internal();
147519
147939
  import { execFile as execFile8 } from "node:child_process";
147520
147940
  import { readFile as readFile24 } from "node:fs/promises";
147521
- import { join as join139 } from "node:path";
147941
+ import { join as join141 } from "node:path";
147522
147942
  import * as readline2 from "node:readline";
147523
147943
  import { promisify as promisify8 } from "node:util";
147524
147944
  init_renderers();
@@ -147527,7 +147947,7 @@ var GITHUB_REPO = BUILD_CONFIG.repository.fullName;
147527
147947
  async function getCurrentVersion() {
147528
147948
  const cleoHome = getCleoHome();
147529
147949
  try {
147530
- const content = await readFile24(join139(cleoHome, "VERSION"), "utf-8");
147950
+ const content = await readFile24(join141(cleoHome, "VERSION"), "utf-8");
147531
147951
  return (content.split("\n")[0] ?? "unknown").trim();
147532
147952
  } catch {
147533
147953
  return "unknown";
@@ -147581,7 +148001,7 @@ async function writeRuntimeVersionMetadata(mode, source, version2) {
147581
148001
  ];
147582
148002
  await import("node:fs/promises").then(
147583
148003
  ({ writeFile: writeFile16, mkdir: mkdir22 }) => mkdir22(cleoHome, { recursive: true }).then(
147584
- () => writeFile16(join139(cleoHome, "VERSION"), `${lines.join("\n")}
148004
+ () => writeFile16(join141(cleoHome, "VERSION"), `${lines.join("\n")}
147585
148005
  `, "utf-8")
147586
148006
  )
147587
148007
  );
@@ -148634,10 +149054,10 @@ function registerSyncCommand(program) {
148634
149054
  "How to resolve conflicts: keep-cleo, keep-external, or newest (default: keep-cleo)",
148635
149055
  "keep-cleo"
148636
149056
  ).action(async (file2, opts) => {
148637
- const { readFileSync: readFileSync108 } = await import("node:fs");
149057
+ const { readFileSync: readFileSync110 } = await import("node:fs");
148638
149058
  let externalTasks;
148639
149059
  try {
148640
- externalTasks = JSON.parse(readFileSync108(file2, "utf8"));
149060
+ externalTasks = JSON.parse(readFileSync110(file2, "utf8"));
148641
149061
  } catch (err) {
148642
149062
  const message = err instanceof Error ? err.message : String(err);
148643
149063
  console.error(`Failed to read or parse external tasks file: ${message}`);
@@ -148733,11 +149153,11 @@ function registerTestingCommand(program) {
148733
149153
  init_internal();
148734
149154
  init_cli();
148735
149155
  init_renderers();
148736
- import { readFileSync as readFileSync106 } from "node:fs";
149156
+ import { readFileSync as readFileSync108 } from "node:fs";
148737
149157
  function readPayload(opts, textKey, fileKey) {
148738
149158
  const text3 = opts[textKey];
148739
149159
  const file2 = opts[fileKey];
148740
- if (file2) return readFileSync106(file2, "utf-8");
149160
+ if (file2) return readFileSync108(file2, "utf-8");
148741
149161
  return text3;
148742
149162
  }
148743
149163
  function registerTokenCommand(program) {
@@ -148839,12 +149259,12 @@ function registerTokenCommand(program) {
148839
149259
  // packages/cleo/src/cli/commands/transcript.ts
148840
149260
  init_src3();
148841
149261
  import { homedir as homedir14 } from "node:os";
148842
- import { join as join141 } from "node:path";
149262
+ import { join as join143 } from "node:path";
148843
149263
 
148844
149264
  // packages/cleo/src/gc/transcript.ts
148845
149265
  import { lstat as lstat3, readdir as readdir6, stat as stat5 } from "node:fs/promises";
148846
149266
  import { homedir as homedir13 } from "node:os";
148847
- import { join as join140 } from "node:path";
149267
+ import { join as join142 } from "node:path";
148848
149268
  var HOT_MAX_MS = 24 * 60 * 60 * 1e3;
148849
149269
  var WARM_MAX_MS = 7 * 24 * 60 * 60 * 1e3;
148850
149270
  function classifyTranscriptTier(ageMs) {
@@ -148856,7 +149276,7 @@ function parseSessionId(filename) {
148856
149276
  return filename.replace(/\.jsonl$/, "");
148857
149277
  }
148858
149278
  async function scanTranscripts(projectsDir) {
148859
- const resolvedProjectsDir = projectsDir ?? join140(homedir13(), ".claude", "projects");
149279
+ const resolvedProjectsDir = projectsDir ?? join142(homedir13(), ".claude", "projects");
148860
149280
  const now2 = Date.now();
148861
149281
  const hot = [];
148862
149282
  const warm = [];
@@ -148869,7 +149289,7 @@ async function scanTranscripts(projectsDir) {
148869
149289
  return { totalSessions: 0, hot, warm, totalBytes, projectsDir: resolvedProjectsDir };
148870
149290
  }
148871
149291
  for (const slug of slugs) {
148872
- const slugDir = join140(resolvedProjectsDir, slug);
149292
+ const slugDir = join142(resolvedProjectsDir, slug);
148873
149293
  let entries;
148874
149294
  try {
148875
149295
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -148878,7 +149298,7 @@ async function scanTranscripts(projectsDir) {
148878
149298
  }
148879
149299
  for (const entry of entries) {
148880
149300
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
148881
- const jsonlPath = join140(slugDir, entry.name);
149301
+ const jsonlPath = join142(slugDir, entry.name);
148882
149302
  const sessionId = parseSessionId(entry.name);
148883
149303
  let fileInfo;
148884
149304
  try {
@@ -148890,7 +149310,7 @@ async function scanTranscripts(projectsDir) {
148890
149310
  const ageMs = now2 - mtimeMs;
148891
149311
  const tier = classifyTranscriptTier(ageMs);
148892
149312
  const bytes = fileInfo.size;
148893
- const candidateSessionDir = join140(slugDir, sessionId);
149313
+ const candidateSessionDir = join142(slugDir, sessionId);
148894
149314
  let sessionDir = null;
148895
149315
  let sessionDirBytes = 0;
148896
149316
  try {
@@ -148932,7 +149352,7 @@ async function pruneTranscripts(opts) {
148932
149352
  const deletedPaths = [];
148933
149353
  let bytesFreed = 0;
148934
149354
  let pruned = 0;
148935
- const resolvedProjectsDir = projectsDir ?? join140(homedir13(), ".claude", "projects");
149355
+ const resolvedProjectsDir = projectsDir ?? join142(homedir13(), ".claude", "projects");
148936
149356
  let slugs;
148937
149357
  try {
148938
149358
  const entries = await readdir6(resolvedProjectsDir, { withFileTypes: true });
@@ -148941,7 +149361,7 @@ async function pruneTranscripts(opts) {
148941
149361
  return { pruned: 0, bytesFreed: 0, deletedPaths: [], dryRun };
148942
149362
  }
148943
149363
  for (const slug of slugs) {
148944
- const slugDir = join140(resolvedProjectsDir, slug);
149364
+ const slugDir = join142(resolvedProjectsDir, slug);
148945
149365
  let entries;
148946
149366
  try {
148947
149367
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -148950,7 +149370,7 @@ async function pruneTranscripts(opts) {
148950
149370
  }
148951
149371
  for (const entry of entries) {
148952
149372
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
148953
- const jsonlPath = join140(slugDir, entry.name);
149373
+ const jsonlPath = join142(slugDir, entry.name);
148954
149374
  let fileInfo;
148955
149375
  try {
148956
149376
  fileInfo = await stat5(jsonlPath);
@@ -148960,7 +149380,7 @@ async function pruneTranscripts(opts) {
148960
149380
  const ageMs = now2 - fileInfo.mtimeMs;
148961
149381
  if (ageMs <= effectiveMaxAgeMs) continue;
148962
149382
  const sessionId = parseSessionId(entry.name);
148963
- const sessionDir = join140(slugDir, sessionId);
149383
+ const sessionDir = join142(slugDir, sessionId);
148964
149384
  const jsonlBytes = fileInfo.size;
148965
149385
  let sessionDirBytes = 0;
148966
149386
  try {
@@ -149049,7 +149469,7 @@ function registerTranscriptCommand(program) {
149049
149469
  }
149050
149470
  return;
149051
149471
  }
149052
- const projectsDir = opts.projectsDir ?? join141(homedir14(), ".claude", "projects");
149472
+ const projectsDir = opts.projectsDir ?? join143(homedir14(), ".claude", "projects");
149053
149473
  try {
149054
149474
  const result = await scanTranscripts(projectsDir);
149055
149475
  const envelope = {
@@ -149356,7 +149776,7 @@ Tier breakdown:
149356
149776
  process.exit(2);
149357
149777
  return;
149358
149778
  }
149359
- const projectsDir = opts.projectsDir ?? join141(homedir14(), ".claude", "projects");
149779
+ const projectsDir = opts.projectsDir ?? join143(homedir14(), ".claude", "projects");
149360
149780
  try {
149361
149781
  const pruneResult = await pruneTranscripts({
149362
149782
  olderThanMs,
@@ -149567,16 +149987,16 @@ init_src3();
149567
149987
  init_renderers();
149568
149988
  import { execFileSync as execFileSync18, spawn as spawn3 } from "node:child_process";
149569
149989
  import { mkdir as mkdir21, open, readFile as readFile25, rm as rm4, stat as stat6, writeFile as writeFile15 } from "node:fs/promises";
149570
- import { join as join142 } from "node:path";
149990
+ import { join as join144 } from "node:path";
149571
149991
  var DEFAULT_PORT = 3456;
149572
149992
  var DEFAULT_HOST = "127.0.0.1";
149573
149993
  function getWebPaths() {
149574
149994
  const cleoHome = getCleoHome();
149575
149995
  return {
149576
- pidFile: join142(cleoHome, "web-server.pid"),
149577
- configFile: join142(cleoHome, "web-server.json"),
149578
- logDir: join142(cleoHome, "logs"),
149579
- logFile: join142(cleoHome, "logs", "web-server.log")
149996
+ pidFile: join144(cleoHome, "web-server.pid"),
149997
+ configFile: join144(cleoHome, "web-server.json"),
149998
+ logDir: join144(cleoHome, "logs"),
149999
+ logFile: join144(cleoHome, "logs", "web-server.log")
149580
150000
  };
149581
150001
  }
149582
150002
  function isProcessRunning(pid) {
@@ -149615,7 +150035,7 @@ async function startWebServer(port, host) {
149615
150035
  throw new CleoError(1 /* GENERAL_ERROR */, `Server already running (PID: ${status.pid})`);
149616
150036
  }
149617
150037
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
149618
- const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join142(projectRoot, "packages", "studio", "build");
150038
+ const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join144(projectRoot, "packages", "studio", "build");
149619
150039
  await mkdir21(logDir, { recursive: true });
149620
150040
  await writeFile15(
149621
150041
  configFile,
@@ -149625,7 +150045,7 @@ async function startWebServer(port, host) {
149625
150045
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
149626
150046
  })
149627
150047
  );
149628
- const webIndexPath = join142(studioDir, "index.js");
150048
+ const webIndexPath = join144(studioDir, "index.js");
149629
150049
  try {
149630
150050
  await stat6(webIndexPath);
149631
150051
  } catch {
@@ -149855,9 +150275,9 @@ var codeCommand = defineCommand({
149855
150275
  async run({ args }) {
149856
150276
  await requireTreeSitter();
149857
150277
  const { smartOutline: smartOutline2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
149858
- const { join: join144 } = await import("node:path");
150278
+ const { join: join146 } = await import("node:path");
149859
150279
  const root = process.cwd();
149860
- const absPath = args.file.startsWith("/") ? args.file : join144(root, args.file);
150280
+ const absPath = args.file.startsWith("/") ? args.file : join146(root, args.file);
149861
150281
  const result = smartOutline2(absPath, root);
149862
150282
  if (result.errors.length > 0 && result.symbols.length === 0) {
149863
150283
  console.error(`Error: ${result.errors.join(", ")}`);
@@ -149923,9 +150343,9 @@ var codeCommand = defineCommand({
149923
150343
  async run({ args }) {
149924
150344
  await requireTreeSitter();
149925
150345
  const { smartUnfold: smartUnfold2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
149926
- const { join: join144 } = await import("node:path");
150346
+ const { join: join146 } = await import("node:path");
149927
150347
  const root = process.cwd();
149928
- const absPath = args.file.startsWith("/") ? args.file : join144(root, args.file);
150348
+ const absPath = args.file.startsWith("/") ? args.file : join146(root, args.file);
149929
150349
  const result = smartUnfold2(absPath, args.symbol, root);
149930
150350
  if (!result.found) {
149931
150351
  console.error(`Symbol "${args.symbol}" not found in ${args.file}`);
@@ -149944,8 +150364,8 @@ var codeCommand = defineCommand({
149944
150364
 
149945
150365
  // packages/cleo/src/cli/index.ts
149946
150366
  function getPackageVersion() {
149947
- const pkgPath = join143(dirname32(fileURLToPath9(import.meta.url)), "../../package.json");
149948
- const pkg = JSON.parse(readFileSync107(pkgPath, "utf-8"));
150367
+ const pkgPath = join145(dirname32(fileURLToPath9(import.meta.url)), "../../package.json");
150368
+ const pkg = JSON.parse(readFileSync109(pkgPath, "utf-8"));
149949
150369
  return pkg.version;
149950
150370
  }
149951
150371
  var CLI_VERSION = getPackageVersion();