trellis 3.2.2 → 3.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +4 -0
  3. package/dist/better-sqlite-backend-CDYOAJDF.js +209 -0
  4. package/dist/boot-middleware-LBJX4N2S.js +9 -0
  5. package/dist/boot-middleware-PATBLD52.js +9 -0
  6. package/dist/bridge-G5DPW6TY.js +2361 -0
  7. package/dist/bridge-JSSPQPRH.js +2389 -0
  8. package/dist/bridge-LNXE4HAW.js +2389 -0
  9. package/dist/bridge-OAAXJWSA.js +2389 -0
  10. package/dist/bridge-SFS63RHC.js +2367 -0
  11. package/dist/bridge-U5TOUBVM.js +2389 -0
  12. package/dist/browser/index.js +9 -9
  13. package/dist/{chunk-KSU2GW22.js → chunk-276W52FK.js} +8 -0
  14. package/dist/{chunk-KFQGP6VL.js → chunk-2ESYSVXG.js} +15 -0
  15. package/dist/{chunk-L5N5PR2S.js → chunk-2WW2X2BR.js} +313 -77
  16. package/dist/chunk-3XCOAP6G.js +48 -0
  17. package/dist/chunk-53PDCTJ3.js +1856 -0
  18. package/dist/{chunk-N6MYZT4O.js → chunk-547FZFKO.js} +1 -1
  19. package/dist/{chunk-H6JB3PZ3.js → chunk-5KSGGKET.js} +1 -1
  20. package/dist/{chunk-J2TXUFCZ.js → chunk-6RWGFC3N.js} +134 -20
  21. package/dist/{chunk-QB5ISE47.js → chunk-7WVOPXJV.js} +3 -3
  22. package/dist/chunk-CMSFD6OV.js +11801 -0
  23. package/dist/{chunk-RSWUFTO2.js → chunk-CPUYCCLT.js} +2 -2
  24. package/dist/{chunk-4HYPLFJD.js → chunk-FA5TFVA5.js} +1 -1
  25. package/dist/{chunk-4XIVMVHC.js → chunk-G3XIHPSQ.js} +1 -1
  26. package/dist/{chunk-JHHEXEDM.js → chunk-GCQF75T4.js} +3 -3
  27. package/dist/{chunk-FKQO5A3H.js → chunk-GHG4H3AS.js} +2 -2
  28. package/dist/{chunk-GLM4HGN4.js → chunk-GRWQPKYK.js} +1 -1
  29. package/dist/{chunk-PZ4XYZ4J.js → chunk-GXA73CNC.js} +33 -8
  30. package/dist/{chunk-6GEZ6DN5.js → chunk-H6VTC5SS.js} +3 -3
  31. package/dist/{chunk-S3XLFZ27.js → chunk-IHHSOBJS.js} +1 -1
  32. package/dist/chunk-IJNC25UD.js +2243 -0
  33. package/dist/{chunk-VDAKEOML.js → chunk-J6OUIION.js} +1 -1
  34. package/dist/chunk-JAVAYMMS.js +6 -0
  35. package/dist/{chunk-S6GBJ2ZB.js → chunk-JCQQFLO5.js} +1 -1
  36. package/dist/{chunk-FWRS4CSC.js → chunk-KQG6ZYXP.js} +3 -3
  37. package/dist/chunk-KXAISKZT.js +119 -0
  38. package/dist/chunk-N3R74ZSR.js +7949 -0
  39. package/dist/{chunk-GU374KWZ.js → chunk-NLFRRGX6.js} +3 -3
  40. package/dist/{chunk-XMQ7G77X.js → chunk-OB4CMMX6.js} +1 -1
  41. package/dist/chunk-OKNASCZY.js +182 -0
  42. package/dist/chunk-ONOPPX5E.js +394 -0
  43. package/dist/chunk-QMSU2RAH.js +98 -0
  44. package/dist/{chunk-TCKXSOBP.js → chunk-RARKFVWU.js} +8 -1
  45. package/dist/{chunk-2W3MHTMG.js → chunk-SJWVDS5M.js} +835 -127
  46. package/dist/{chunk-SPSPV5BC.js → chunk-SZ3VAB5P.js} +159 -2
  47. package/dist/chunk-V2ASD6RQ.js +147 -0
  48. package/dist/{chunk-KQ4A2D2P.js → chunk-V4YCJDYL.js} +58 -38
  49. package/dist/{chunk-LNUIGRDZ.js → chunk-VWKLKLYB.js} +1 -1
  50. package/dist/chunk-W5PADCDF.js +1856 -0
  51. package/dist/{chunk-MLC5BUYO.js → chunk-WMERMSWI.js} +1 -1
  52. package/dist/{chunk-IZX2PLIB.js → chunk-WXAURJUD.js} +835 -127
  53. package/dist/chunk-YC5I32PS.js +147 -0
  54. package/dist/{chunk-VBYUTRXX.js → chunk-YKVB4LUQ.js} +3 -3
  55. package/dist/{chunk-7ZFRVCUE.js → chunk-YPT6XMS4.js} +48 -64
  56. package/dist/cli/deploy-cli.d.ts.map +1 -1
  57. package/dist/{deploy-cli-C35HTITO.js → cli/deploy-cli.js} +45 -6
  58. package/dist/cli/gateway-deploy-cli.d.ts +19 -0
  59. package/dist/cli/gateway-deploy-cli.d.ts.map +1 -0
  60. package/dist/cli/index.d.ts.map +1 -1
  61. package/dist/cli/index.js +1363 -884
  62. package/dist/cli/lane.d.ts.map +1 -1
  63. package/dist/cli/protocol.d.ts +6 -0
  64. package/dist/cli/protocol.d.ts.map +1 -0
  65. package/dist/client/index.browser.js +2 -2
  66. package/dist/client/index.js +11 -11
  67. package/dist/client/sdk.browser.d.ts +28 -1
  68. package/dist/client/sdk.browser.d.ts.map +1 -1
  69. package/dist/client/sdk.browser.js +2 -2
  70. package/dist/client/sdk.js +2 -2
  71. package/dist/cms/index.js +1 -1
  72. package/dist/config-KMY6RRK3.js +19 -0
  73. package/dist/core/index.js +17 -17
  74. package/dist/core/kernel/boot-middleware.d.ts +1 -1
  75. package/dist/core/kernel/boot-middleware.d.ts.map +1 -1
  76. package/dist/core/kernel/schema-middleware.d.ts +2 -1
  77. package/dist/core/kernel/schema-middleware.d.ts.map +1 -1
  78. package/dist/core/kernel/trellis-kernel.d.ts +10 -10
  79. package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
  80. package/dist/core/persist/factory.js +2 -2
  81. package/dist/core/persist/sqljs-backend.js +2 -2
  82. package/dist/db/index.js +32 -27
  83. package/dist/decisions/index.js +4 -4
  84. package/dist/embeddings/index.js +2 -2
  85. package/dist/engine.d.ts +24 -6
  86. package/dist/engine.d.ts.map +1 -1
  87. package/dist/gateway-deploy-cli-4TU4V3QI.js +312 -0
  88. package/dist/gateway-deploy-cli-A4ISTDHJ.js +298 -0
  89. package/dist/gateway-deploy-cli-D3XTKJQJ.js +312 -0
  90. package/dist/gateway-deploy-cli-ECV3OQCN.js +305 -0
  91. package/dist/gateway-deploy-cli-JUHKVIJE.js +296 -0
  92. package/dist/gateway-deploy-cli-NSDW2JLT.js +310 -0
  93. package/dist/gateway-serve-CM5EAZ52.js +113 -0
  94. package/dist/import-AJLYHFIA.js +10 -0
  95. package/dist/index.js +11 -11
  96. package/dist/launch-explorer-FVX6ZABW.js +95 -0
  97. package/dist/links/index.js +2 -2
  98. package/dist/mcp/bridge.d.ts +45 -0
  99. package/dist/mcp/bridge.d.ts.map +1 -0
  100. package/dist/mcp/discovery.d.ts +15 -0
  101. package/dist/mcp/discovery.d.ts.map +1 -0
  102. package/dist/mcp/gateway-config.d.ts +20 -0
  103. package/dist/mcp/gateway-config.d.ts.map +1 -0
  104. package/dist/mcp/gateway-serve.d.ts +19 -0
  105. package/dist/mcp/gateway-serve.d.ts.map +1 -0
  106. package/dist/mcp/gateway-serve.js +119 -0
  107. package/dist/mcp/graph-summary.d.ts +47 -0
  108. package/dist/mcp/graph-summary.d.ts.map +1 -0
  109. package/dist/mcp/room-audit.d.ts +14 -0
  110. package/dist/mcp/room-audit.d.ts.map +1 -0
  111. package/dist/mcp/room-helpers.d.ts +43 -0
  112. package/dist/mcp/room-helpers.d.ts.map +1 -0
  113. package/dist/mcp/room-registry.d.ts +32 -0
  114. package/dist/mcp/room-registry.d.ts.map +1 -0
  115. package/dist/mcp/room.d.ts +28 -0
  116. package/dist/mcp/room.d.ts.map +1 -0
  117. package/dist/plugins/agent-memory/index.js +1 -1
  118. package/dist/plugins/idea-garden/index.js +1 -1
  119. package/dist/plugins/plan-approval/index.js +1 -1
  120. package/dist/plugins/proactive-watcher/index.js +1 -1
  121. package/dist/protocol/envelope.d.ts +30 -0
  122. package/dist/protocol/envelope.d.ts.map +1 -0
  123. package/dist/protocol/index.d.ts +3 -0
  124. package/dist/protocol/index.d.ts.map +1 -0
  125. package/dist/protocol/whereami.d.ts +33 -0
  126. package/dist/protocol/whereami.d.ts.map +1 -0
  127. package/dist/query-KHDDIR5G.js +31 -0
  128. package/dist/react/index.js +3 -3
  129. package/dist/react/realtime.js +1 -1
  130. package/dist/react/schema-hooks.js +6 -6
  131. package/dist/realtime/index.js +3 -3
  132. package/dist/realtime/relay-server.d.ts.map +1 -1
  133. package/dist/realtime/room.d.ts.map +1 -1
  134. package/dist/realtime.bundle.js +2 -0
  135. package/dist/relay-server-BT6DCJ7F.js +12 -0
  136. package/dist/relay-server-MPQVGNQU.js +12 -0
  137. package/dist/relay-server-PAPW2EWC.js +12 -0
  138. package/dist/remote-manager-6ERQUBSL.js +224 -0
  139. package/dist/remote-manager-G665WWYY.js +224 -0
  140. package/dist/remote-manager-HJTEZ4OF.js +224 -0
  141. package/dist/remote-manager-NYP2Y5UR.js +224 -0
  142. package/dist/remote-manager-WGLCAMMC.js +224 -0
  143. package/dist/scaffold/write.d.ts.map +1 -1
  144. package/dist/schema/index.js +1 -1
  145. package/dist/server/cors.d.ts +13 -0
  146. package/dist/server/cors.d.ts.map +1 -0
  147. package/dist/server/deploy-gateway.d.ts +27 -0
  148. package/dist/server/deploy-gateway.d.ts.map +1 -0
  149. package/dist/server/deploy.d.ts +1 -1
  150. package/dist/server/deploy.d.ts.map +1 -1
  151. package/dist/server/deploy.js +10 -0
  152. package/dist/server/discovery-mcp-gateway.d.ts +13 -0
  153. package/dist/server/discovery-mcp-gateway.d.ts.map +1 -0
  154. package/dist/server/index.js +44 -37
  155. package/dist/server/mcp-gateway.d.ts +27 -0
  156. package/dist/server/mcp-gateway.d.ts.map +1 -0
  157. package/dist/server/mcp-oauth-metadata.d.ts +31 -0
  158. package/dist/server/mcp-oauth-metadata.d.ts.map +1 -0
  159. package/dist/server/node-adapter.d.ts +7 -0
  160. package/dist/server/node-adapter.d.ts.map +1 -1
  161. package/dist/server/node-adapter.js +2 -2
  162. package/dist/server/realtime.d.ts.map +1 -1
  163. package/dist/server/server.d.ts +8 -0
  164. package/dist/server/server.d.ts.map +1 -1
  165. package/dist/server/streamable-mcp-gateway.d.ts +12 -0
  166. package/dist/server/streamable-mcp-gateway.d.ts.map +1 -0
  167. package/dist/server/usage-meter.d.ts +11 -0
  168. package/dist/server/usage-meter.d.ts.map +1 -1
  169. package/dist/server-4VEZHXXS.js +23 -0
  170. package/dist/{server-ZVWGLLRF.js → server-556BMK4C.js} +1 -1
  171. package/dist/server-FQT2VYRE.js +23 -0
  172. package/dist/server-HGZE4ECC.js +23 -0
  173. package/dist/server-J4JKEAMH.js +23 -0
  174. package/dist/server-LXPM5TFR.js +23 -0
  175. package/dist/{server-MB3OPSPI.js → server-POB4NEUX.js} +2 -2
  176. package/dist/server-VJKAPGPG.js +23 -0
  177. package/dist/server-YHS3XIIG.js +23 -0
  178. package/dist/server-ZHTPWPXS.js +23 -0
  179. package/dist/sprites-NC6D7YZS.js +27 -0
  180. package/dist/svelte/index.js +3 -3
  181. package/dist/svelte/schema-hooks.js +4 -4
  182. package/dist/sync/index.js +4 -4
  183. package/dist/tenancy-2SZTP4UD.js +16 -0
  184. package/dist/tenancy-7MTSESMJ.js +16 -0
  185. package/dist/tenancy-U4E7ZEAG.js +16 -0
  186. package/dist/vcs/decompose.d.ts.map +1 -1
  187. package/dist/vcs/index.js +5 -5
  188. package/dist/vcs/lane-disk-materialize.d.ts +11 -0
  189. package/dist/vcs/lane-disk-materialize.d.ts.map +1 -0
  190. package/dist/vcs/lane-worktree.d.ts +21 -0
  191. package/dist/vcs/lane-worktree.d.ts.map +1 -0
  192. package/dist/vcs/store.d.ts +28 -0
  193. package/dist/vcs/store.d.ts.map +1 -0
  194. package/dist/vcs/types.d.ts +5 -0
  195. package/dist/vcs/types.d.ts.map +1 -1
  196. package/dist/vm-config-YZRJ3KUB.js +21 -0
  197. package/dist/vue/index.js +3 -3
  198. package/dist/vue/schema-hooks.js +4 -4
  199. package/package.json +4 -3
  200. package/dist/chunk-FF36CQHZ.js +0 -61
  201. package/dist/chunk-GFZCJ4EH.js +0 -108
  202. package/dist/chunk-KIJITUZB.js +0 -419
  203. package/dist/chunk-SGMDTWJJ.js +0 -149
  204. package/dist/chunk-UQISRW6T.js +0 -203
  205. package/dist/db/trellis.css +0 -1
  206. package/dist/deploy-LQ7GUGJ5.js +0 -9
  207. package/dist/deploy-YNVG5E4E.js +0 -9
  208. package/dist/deploy-cli-24BCHAXY.js +0 -67
  209. package/dist/sprites-RU3E4XQN.js +0 -15
  210. package/dist/tenancy-NBLLGCNJ.js +0 -14
package/dist/cli/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  init_node_adapter,
4
4
  startNodeServer
5
- } from "../chunk-TCKXSOBP.js";
5
+ } from "../chunk-RARKFVWU.js";
6
6
  import {
7
7
  seedContext
8
- } from "../chunk-S6GBJ2ZB.js";
8
+ } from "../chunk-OKNASCZY.js";
9
9
  import {
10
10
  TrellisVcsEngine,
11
11
  formatPromoteExplain,
@@ -19,8 +19,8 @@ import {
19
19
  updateProfile,
20
20
  writeAgentScaffold,
21
21
  writeIdeScaffold
22
- } from "../chunk-L5N5PR2S.js";
23
- import "../chunk-GU374KWZ.js";
22
+ } from "../chunk-N3R74ZSR.js";
23
+ import "../chunk-NLFRRGX6.js";
24
24
  import {
25
25
  OntologyRegistry,
26
26
  builtinOntologies,
@@ -32,21 +32,21 @@ import {
32
32
  } from "../chunk-X5FLTRUB.js";
33
33
  import {
34
34
  TrellisKernel
35
- } from "../chunk-KQ4A2D2P.js";
35
+ } from "../chunk-V4YCJDYL.js";
36
36
  import {
37
37
  QueryEngine
38
38
  } from "../chunk-6CTA6MCE.js";
39
- import "../chunk-4XIVMVHC.js";
40
- import "../chunk-VBYUTRXX.js";
41
- import "../chunk-N6MYZT4O.js";
39
+ import "../chunk-G3XIHPSQ.js";
40
+ import "../chunk-IJNC25UD.js";
41
+ import "../chunk-547FZFKO.js";
42
42
  import {
43
43
  init_reconciler,
44
44
  reconciler_exports
45
- } from "../chunk-4HYPLFJD.js";
45
+ } from "../chunk-FA5TFVA5.js";
46
46
  import {
47
47
  createVcsOp,
48
48
  init_ops
49
- } from "../chunk-GLM4HGN4.js";
49
+ } from "../chunk-GRWQPKYK.js";
50
50
  import {
51
51
  VectorStore,
52
52
  buildRAGContext,
@@ -56,27 +56,27 @@ import {
56
56
  init_embeddings,
57
57
  init_model,
58
58
  init_store
59
- } from "../chunk-S3XLFZ27.js";
59
+ } from "../chunk-IHHSOBJS.js";
60
60
  import {
61
61
  buildRefIndex,
62
62
  createResolverContext,
63
63
  init_links,
64
64
  links_exports
65
- } from "../chunk-VDAKEOML.js";
65
+ } from "../chunk-J6OUIION.js";
66
66
  import {
67
67
  __esm,
68
68
  __export,
69
69
  __require,
70
70
  __toCommonJS
71
- } from "../chunk-KFQGP6VL.js";
71
+ } from "../chunk-2ESYSVXG.js";
72
72
 
73
73
  // src/ui/server.ts
74
74
  var server_exports = {};
75
75
  __export(server_exports, {
76
76
  startUIServer: () => startUIServer
77
77
  });
78
- import { readFileSync as readFileSync4, existsSync as existsSync5 } from "fs";
79
- import { join as join5, dirname as dirname5 } from "path";
78
+ import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
79
+ import { join as join6, dirname as dirname5 } from "path";
80
80
  import { fileURLToPath as fileURLToPath2 } from "url";
81
81
  function buildGraph(engine) {
82
82
  const nodes = [];
@@ -177,11 +177,11 @@ function buildGraph(engine) {
177
177
  const mdFiles = [];
178
178
  for (const f of files) {
179
179
  if (f.path.endsWith(".md")) {
180
- const absPath = join5(engine.getRootPath(), f.path);
181
- if (existsSync5(absPath)) {
180
+ const absPath = join6(engine.getRootPath(), f.path);
181
+ if (existsSync6(absPath)) {
182
182
  mdFiles.push({
183
183
  path: f.path,
184
- content: readFileSync4(absPath, "utf-8")
184
+ content: readFileSync6(absPath, "utf-8")
185
185
  });
186
186
  }
187
187
  }
@@ -326,8 +326,8 @@ function buildSystemInfo(engine) {
326
326
  const status = engine.status();
327
327
  const store = engine.getStore();
328
328
  const stats = store.getStats();
329
- const embeddingsAvailable = existsSync5(
330
- join5(engine.getRootPath(), ".trellis", "embeddings.db")
329
+ const embeddingsAvailable = existsSync6(
330
+ join6(engine.getRootPath(), ".trellis", "embeddings.db")
331
331
  );
332
332
  const blobStoreAvailable = engine.getBlobStore() !== null;
333
333
  return {
@@ -409,13 +409,13 @@ async function startUIServer(opts) {
409
409
  const push = (...paths) => {
410
410
  for (const p of paths) candidates.push(p);
411
411
  };
412
- push(join5(process.cwd(), "dist", "ui", "client.html"));
412
+ push(join6(process.cwd(), "dist", "ui", "client.html"));
413
413
  try {
414
414
  const moduleDir = dirname5(fileURLToPath2(import.meta.url));
415
415
  push(
416
- join5(moduleDir, "client.html"),
417
- join5(moduleDir, "..", "ui", "client.html"),
418
- join5(moduleDir, "ui", "client.html")
416
+ join6(moduleDir, "client.html"),
417
+ join6(moduleDir, "..", "ui", "client.html"),
418
+ join6(moduleDir, "ui", "client.html")
419
419
  );
420
420
  } catch {
421
421
  }
@@ -423,43 +423,43 @@ async function startUIServer(opts) {
423
423
  if (argvEntry) {
424
424
  const argvDir = dirname5(argvEntry);
425
425
  push(
426
- join5(argvDir, "client.html"),
427
- join5(argvDir, "..", "ui", "client.html"),
428
- join5(argvDir, "ui", "client.html"),
429
- join5(argvDir, "..", "dist", "ui", "client.html")
426
+ join6(argvDir, "client.html"),
427
+ join6(argvDir, "..", "ui", "client.html"),
428
+ join6(argvDir, "ui", "client.html"),
429
+ join6(argvDir, "..", "dist", "ui", "client.html")
430
430
  );
431
431
  let dir = argvDir;
432
432
  for (let i = 0; i < 6; i++) {
433
- push(join5(dir, "dist", "ui", "client.html"), join5(dir, "ui", "client.html"));
433
+ push(join6(dir, "dist", "ui", "client.html"), join6(dir, "ui", "client.html"));
434
434
  dir = dirname5(dir);
435
435
  }
436
436
  }
437
437
  let cwd = process.cwd();
438
438
  for (let i = 0; i < 8; i++) {
439
439
  push(
440
- join5(cwd, "dist", "ui", "client.html"),
441
- join5(cwd, "node_modules", "trellis", "dist", "ui", "client.html")
440
+ join6(cwd, "dist", "ui", "client.html"),
441
+ join6(cwd, "node_modules", "trellis", "dist", "ui", "client.html")
442
442
  );
443
443
  const parent = dirname5(cwd);
444
444
  if (parent === cwd) break;
445
445
  cwd = parent;
446
446
  }
447
447
  for (const p of candidates) {
448
- if (existsSync5(p)) return p;
448
+ if (existsSync6(p)) return p;
449
449
  }
450
450
  throw new Error(
451
451
  `Could not find client.html. cwd=${process.cwd()} argv=${argvEntry ?? "(none)"}
452
452
  Try reinstalling the package or running \`npm run build\`.`
453
453
  );
454
454
  }
455
- const clientHtml = readFileSync4(findClientHtml(), "utf-8");
455
+ const clientHtml = readFileSync6(findClientHtml(), "utf-8");
456
456
  let embeddingManager = null;
457
457
  async function getEmbeddingManager() {
458
458
  if (!embeddingManager) {
459
459
  try {
460
460
  const { EmbeddingManager } = (init_embeddings(), __toCommonJS(embeddings_exports));
461
- const dbPath = join5(opts.rootPath, ".trellis", "embeddings.db");
462
- if (existsSync5(dbPath)) {
461
+ const dbPath = join6(opts.rootPath, ".trellis", "embeddings.db");
462
+ if (existsSync6(dbPath)) {
463
463
  embeddingManager = await EmbeddingManager.create(dbPath);
464
464
  }
465
465
  } catch {
@@ -609,8 +609,8 @@ var init_server = __esm({
609
609
  // src/cli/index.ts
610
610
  init_engine();
611
611
  import { Command } from "commander";
612
- import chalk4 from "chalk";
613
- import { resolve as resolve2, join as join6 } from "path";
612
+ import chalk5 from "chalk";
613
+ import { resolve as resolve2, join as join7 } from "path";
614
614
  import { select, checkbox } from "@inquirer/prompts";
615
615
  init_auto_embed();
616
616
  init_store();
@@ -774,9 +774,9 @@ async function importFromGit(opts) {
774
774
  agentId: opts.agentId ?? `git-import:${opts.from}`,
775
775
  defaultBranch
776
776
  });
777
- const trellisDir = join2(opts.to, ".trellis");
778
- if (!existsSync2(trellisDir)) {
779
- mkdirSync(trellisDir, { recursive: true });
777
+ const trellisDir2 = join2(opts.to, ".trellis");
778
+ if (!existsSync2(trellisDir2)) {
779
+ mkdirSync(trellisDir2, { recursive: true });
780
780
  }
781
781
  const importEngine = new ImportEngine(engine, opts);
782
782
  await importEngine.createBranch(defaultBranch);
@@ -901,9 +901,9 @@ var ImportEngine = class {
901
901
  flushOps() {
902
902
  const opsPath = join2(this.opts.to, ".trellis", "ops.json");
903
903
  const configPath = join2(this.opts.to, ".trellis", "config.json");
904
- const trellisDir = join2(this.opts.to, ".trellis");
905
- if (!existsSync2(trellisDir)) {
906
- mkdirSync(trellisDir, { recursive: true });
904
+ const trellisDir2 = join2(this.opts.to, ".trellis");
905
+ if (!existsSync2(trellisDir2)) {
906
+ mkdirSync(trellisDir2, { recursive: true });
907
907
  }
908
908
  if (!existsSync2(configPath)) {
909
909
  const config = {
@@ -922,11 +922,11 @@ var ImportEngine = class {
922
922
  agentId: this.agentId(),
923
923
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
924
924
  };
925
- const { writeFileSync: writeFileSync4 } = __require("fs");
926
- writeFileSync4(configPath, JSON.stringify(config, null, 2));
925
+ const { writeFileSync: writeFileSync5 } = __require("fs");
926
+ writeFileSync5(configPath, JSON.stringify(config, null, 2));
927
927
  }
928
- const { writeFileSync: writeFileSync3 } = __require("fs");
929
- writeFileSync3(opsPath, JSON.stringify(this.ops, null, 2));
928
+ const { writeFileSync: writeFileSync4 } = __require("fs");
929
+ writeFileSync4(opsPath, JSON.stringify(this.ops, null, 2));
930
930
  }
931
931
  async hashFileAtCommit(commitHash, filePath) {
932
932
  try {
@@ -1230,15 +1230,15 @@ function deriveDid(rawPublicKey) {
1230
1230
  return `did:key:z${encoded}`;
1231
1231
  }
1232
1232
  var IDENTITY_FILE = "identity.json";
1233
- function saveIdentity(trellisDir, identity) {
1234
- const filePath = join4(trellisDir, IDENTITY_FILE);
1233
+ function saveIdentity(trellisDir2, identity) {
1234
+ const filePath = join4(trellisDir2, IDENTITY_FILE);
1235
1235
  if (!existsSync4(dirname3(filePath))) {
1236
1236
  mkdirSync3(dirname3(filePath), { recursive: true });
1237
1237
  }
1238
1238
  writeFileSync2(filePath, JSON.stringify(identity, null, 2), "utf-8");
1239
1239
  }
1240
- function loadIdentity(trellisDir) {
1241
- const filePath = join4(trellisDir, IDENTITY_FILE);
1240
+ function loadIdentity(trellisDir2) {
1241
+ const filePath = join4(trellisDir2, IDENTITY_FILE);
1242
1242
  if (!existsSync4(filePath)) return null;
1243
1243
  try {
1244
1244
  return JSON.parse(readFileSync2(filePath, "utf-8"));
@@ -1246,8 +1246,8 @@ function loadIdentity(trellisDir) {
1246
1246
  return null;
1247
1247
  }
1248
1248
  }
1249
- function hasIdentity(trellisDir) {
1250
- return existsSync4(join4(trellisDir, IDENTITY_FILE));
1249
+ function hasIdentity(trellisDir2) {
1250
+ return existsSync4(join4(trellisDir2, IDENTITY_FILE));
1251
1251
  }
1252
1252
  function toPublicIdentity(identity) {
1253
1253
  return {
@@ -1441,12 +1441,22 @@ function registerLaneCommands(program2) {
1441
1441
  console.log(chalk3.green(`\u2713 Lane created: ${chalk3.bold(meta.id)}`));
1442
1442
  console.log(` ${chalk3.dim("Base:")} ${meta.baseBranch} @ ${meta.baseOpHash.slice(0, 20)}\u2026`);
1443
1443
  console.log(` ${chalk3.dim("Target:")} ${meta.targetBranch}`);
1444
+ if (meta.worktreePath) {
1445
+ console.log(` ${chalk3.dim("Worktree:")} ${meta.worktreePath}`);
1446
+ }
1444
1447
  if (meta.issueId) {
1445
1448
  console.log(` ${chalk3.dim("Issue:")} ${meta.issueId}`);
1446
1449
  }
1447
1450
  console.log(
1448
1451
  chalk3.dim(` Enter: trellis lane enter ${meta.id} | export TRELLIS_LANE_ID=${meta.id}`)
1449
1452
  );
1453
+ if (!meta.worktreePath) {
1454
+ console.log(
1455
+ chalk3.yellow(
1456
+ " No worktree \u2014 set lanes.worktreeBind in .trellis/config.json and use a CLI build that includes TRL-40 (bun src/cli/index.ts or rebuild dist)."
1457
+ )
1458
+ );
1459
+ }
1450
1460
  } catch (err) {
1451
1461
  console.error(chalk3.red(err.message));
1452
1462
  process.exit(1);
@@ -1482,6 +1492,9 @@ function registerLaneCommands(program2) {
1482
1492
  ` ${chalk3.dim("from")} ${lane.parentLaneId}${lane.forkKind ? ` (${lane.forkKind})` : ""}`
1483
1493
  );
1484
1494
  }
1495
+ if (lane.worktreePath) {
1496
+ console.log(` ${chalk3.dim("worktree")} ${lane.worktreePath}`);
1497
+ }
1485
1498
  }
1486
1499
  });
1487
1500
  laneCmd.command("enter <id>").description("Enter a lane (route writes to lane journal)").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
@@ -1550,6 +1563,9 @@ function registerLaneCommands(program2) {
1550
1563
  if (meta.agentId) {
1551
1564
  console.log(` ${chalk3.dim("Agent:")} ${meta.agentId}`);
1552
1565
  }
1566
+ if (meta.worktreePath) {
1567
+ console.log(` ${chalk3.dim("Worktree:")} ${meta.worktreePath}`);
1568
+ }
1553
1569
  if (filePaths.length > 0) {
1554
1570
  console.log(` ${chalk3.dim("Files:")} ${filePaths.length} touched`);
1555
1571
  }
@@ -1644,6 +1660,392 @@ function summarizeOpKinds(ops) {
1644
1660
  return [...counts.entries()].map(([kind, n]) => `${kind.replace("vcs:", "")}:${n}`).join(", ");
1645
1661
  }
1646
1662
 
1663
+ // src/cli/protocol.ts
1664
+ init_engine();
1665
+ import chalk4 from "chalk";
1666
+ import { readFileSync as readFileSync5 } from "fs";
1667
+
1668
+ // src/protocol/envelope.ts
1669
+ var HANDOFF_ROLES = [
1670
+ "strategist",
1671
+ "designer",
1672
+ "architect",
1673
+ "executor",
1674
+ "reviewer",
1675
+ "optimizer",
1676
+ "synthesist",
1677
+ "writer",
1678
+ "human"
1679
+ ];
1680
+ var HANDOFF_STATUSES = [
1681
+ "HANDOFF",
1682
+ "CLARIFY",
1683
+ "REJECT",
1684
+ "BLOCKED",
1685
+ "DECISION"
1686
+ ];
1687
+ var ROLE_SET = new Set(HANDOFF_ROLES);
1688
+ var STATUS_SET = new Set(HANDOFF_STATUSES);
1689
+ var ROLE_BALL = {
1690
+ strategist: "\u{1F7E3}",
1691
+ designer: "\u{1F7E0}",
1692
+ architect: "\u{1F535}",
1693
+ executor: "\u{1F7E2}",
1694
+ reviewer: "\u{1F7E1}",
1695
+ optimizer: "\u26A1",
1696
+ synthesist: "\u{1F3A8}",
1697
+ writer: "\u270D\uFE0F",
1698
+ human: "\u26AA"
1699
+ };
1700
+ function parseYamlFields(yaml) {
1701
+ const result = {};
1702
+ const lines = yaml.replace(/\r\n/g, "\n").split("\n");
1703
+ let currentKey = null;
1704
+ let bodyLines = [];
1705
+ let inBody = false;
1706
+ const flushBody = () => {
1707
+ if (currentKey && inBody) {
1708
+ result[currentKey] = bodyLines.join("\n").replace(/\n$/, "");
1709
+ inBody = false;
1710
+ bodyLines = [];
1711
+ }
1712
+ };
1713
+ for (const line of lines) {
1714
+ if (inBody) {
1715
+ if (line.startsWith(" ") || line === "") {
1716
+ bodyLines.push(line.startsWith(" ") ? line.slice(2) : "");
1717
+ continue;
1718
+ }
1719
+ flushBody();
1720
+ }
1721
+ const kv = line.match(/^([a-z_]+):\s*(.*)$/);
1722
+ if (!kv) continue;
1723
+ currentKey = kv[1];
1724
+ const rest = kv[2];
1725
+ if (rest === "|") {
1726
+ inBody = true;
1727
+ bodyLines = [];
1728
+ } else {
1729
+ result[currentKey] = rest.trim();
1730
+ }
1731
+ }
1732
+ flushBody();
1733
+ return result;
1734
+ }
1735
+ function extractYamlFooter(text) {
1736
+ const normalized = text.replace(/\r\n/g, "\n");
1737
+ const idx = normalized.lastIndexOf("\n---\n");
1738
+ if (idx === -1) {
1739
+ if (normalized.startsWith("---\n")) {
1740
+ return normalized.slice(4);
1741
+ }
1742
+ return null;
1743
+ }
1744
+ return normalized.slice(idx + 5);
1745
+ }
1746
+ function parseEnvelope(text) {
1747
+ const yaml = extractYamlFooter(text);
1748
+ if (!yaml) {
1749
+ throw new Error("No handoff envelope found (expected --- YAML footer)");
1750
+ }
1751
+ const fields = parseYamlFields(yaml);
1752
+ if (!fields.from || !fields.to || !fields.re || !fields.status) {
1753
+ throw new Error("Envelope missing required fields: from, to, re, status");
1754
+ }
1755
+ const env = {
1756
+ from: fields.from,
1757
+ to: fields.to,
1758
+ re: fields.re,
1759
+ status: fields.status
1760
+ };
1761
+ if (fields.body) env.body = fields.body;
1762
+ if (fields.in_reply_to) env.in_reply_to = fields.in_reply_to;
1763
+ if (fields.refs) {
1764
+ env.refs = fields.refs.split(",").map((r) => r.trim()).filter(Boolean);
1765
+ }
1766
+ const validation = validateEnvelope(env);
1767
+ if (!validation.ok) {
1768
+ throw new Error(validation.errors.join("; "));
1769
+ }
1770
+ return env;
1771
+ }
1772
+ function validateEnvelope(env) {
1773
+ const errors = [];
1774
+ if (!ROLE_SET.has(env.from)) {
1775
+ errors.push(`invalid from role: ${env.from}`);
1776
+ }
1777
+ if (!ROLE_SET.has(env.to)) {
1778
+ errors.push(`invalid to role: ${env.to}`);
1779
+ }
1780
+ if (!STATUS_SET.has(env.status)) {
1781
+ errors.push(`invalid status: ${env.status}`);
1782
+ }
1783
+ if (!env.re?.trim()) {
1784
+ errors.push("re is required");
1785
+ } else if (!/^TRL-\d+/.test(env.re.trim())) {
1786
+ errors.push(`re must start with TRL-N issue ref, got: ${env.re}`);
1787
+ }
1788
+ return errors.length === 0 ? { ok: true } : { ok: false, errors };
1789
+ }
1790
+ function formatEnvelope(env) {
1791
+ const lines = [
1792
+ "---",
1793
+ `from: ${env.from}`,
1794
+ `to: ${env.to}`,
1795
+ `re: ${env.re}`,
1796
+ `status: ${env.status}`
1797
+ ];
1798
+ if (env.body !== void 0) {
1799
+ if (env.body.includes("\n")) {
1800
+ lines.push("body: |", ...env.body.split("\n").map((l) => ` ${l}`));
1801
+ } else {
1802
+ lines.push(`body: ${env.body}`);
1803
+ }
1804
+ }
1805
+ if (env.refs?.length) {
1806
+ lines.push(`refs: ${env.refs.join(", ")}`);
1807
+ }
1808
+ if (env.in_reply_to) {
1809
+ lines.push(`in_reply_to: ${env.in_reply_to}`);
1810
+ }
1811
+ return lines.join("\n");
1812
+ }
1813
+ function formatTurnBanner(env, stage) {
1814
+ const ball = ROLE_BALL[env.to] ?? "\u26AA";
1815
+ const stagePart = stage ? ` \xB7 stage ${stage}` : "";
1816
+ return `${ball} TURN ${env.to}${stagePart} \xB7 ${env.status} \xB7 ${env.re}`;
1817
+ }
1818
+ function formatIssueDescription(env, stage) {
1819
+ return `${formatTurnBanner(env, stage)}
1820
+ ${formatEnvelope(env)}`;
1821
+ }
1822
+ function isWaitingOnHuman(env) {
1823
+ return env.to === "human";
1824
+ }
1825
+ function tryParseEnvelope(description) {
1826
+ if (!description?.includes("from:")) return void 0;
1827
+ try {
1828
+ return parseEnvelope(description);
1829
+ } catch {
1830
+ return void 0;
1831
+ }
1832
+ }
1833
+
1834
+ // src/protocol/whereami.ts
1835
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
1836
+ import { join as join5 } from "path";
1837
+ function trellisDir(rootPath) {
1838
+ return join5(rootPath, ".trellis");
1839
+ }
1840
+ function checkpointPath(rootPath) {
1841
+ return join5(trellisDir(rootPath), "reentry-checkpoint.json");
1842
+ }
1843
+ function loadCheckpoint(rootPath) {
1844
+ const path = checkpointPath(rootPath);
1845
+ if (!existsSync5(path)) return null;
1846
+ try {
1847
+ return JSON.parse(readFileSync4(path, "utf-8"));
1848
+ } catch {
1849
+ return null;
1850
+ }
1851
+ }
1852
+ function writeCheckpoint(rootPath, issueIds, openMessageIds) {
1853
+ const cp = {
1854
+ at: (/* @__PURE__ */ new Date()).toISOString(),
1855
+ issueIds,
1856
+ openMessageIds
1857
+ };
1858
+ const dir = trellisDir(rootPath);
1859
+ mkdirSync4(dir, { recursive: true });
1860
+ writeFileSync3(checkpointPath(rootPath), JSON.stringify(cp, null, 2), "utf-8");
1861
+ return cp;
1862
+ }
1863
+ function isOpenProtocolChild(issue) {
1864
+ if (issue.status === "closed") return false;
1865
+ return issue.labels.includes("message") || issue.labels.includes("decision");
1866
+ }
1867
+ function collectProtocolChildren(engine) {
1868
+ return engine.listIssues().filter(isOpenProtocolChild);
1869
+ }
1870
+ function findWaitingOnYou(engine) {
1871
+ const waiting = [];
1872
+ for (const issue of collectProtocolChildren(engine)) {
1873
+ const envelope = tryParseEnvelope(issue.description);
1874
+ if (!envelope) continue;
1875
+ if (issue.labels.includes("decision")) {
1876
+ waiting.push({ issue, envelope });
1877
+ continue;
1878
+ }
1879
+ if (isWaitingOnHuman(envelope)) {
1880
+ waiting.push({ issue, envelope });
1881
+ }
1882
+ }
1883
+ return waiting;
1884
+ }
1885
+ function findMovedSinceCheckpoint(engine, rootPath) {
1886
+ const cp = loadCheckpoint(rootPath);
1887
+ if (!cp) return [];
1888
+ const known = /* @__PURE__ */ new Set([...cp.issueIds, ...cp.openMessageIds]);
1889
+ const moved = [];
1890
+ for (const issue of engine.listIssues()) {
1891
+ if (known.has(issue.id)) continue;
1892
+ if (issue.labels.includes("message") || issue.labels.includes("decision")) {
1893
+ moved.push(issue);
1894
+ }
1895
+ }
1896
+ for (const issue of collectProtocolChildren(engine)) {
1897
+ if (cp.openMessageIds.includes(issue.id)) continue;
1898
+ if (issue.labels.includes("message") || issue.labels.includes("decision")) {
1899
+ if (!moved.some((m) => m.id === issue.id)) {
1900
+ moved.push(issue);
1901
+ }
1902
+ }
1903
+ }
1904
+ return moved;
1905
+ }
1906
+ function getActiveContext(engine, rootPath) {
1907
+ const issues = engine.listIssues({ status: "in_progress" });
1908
+ const laneId = engine.getActiveLaneId();
1909
+ let worktreePath;
1910
+ if (laneId) {
1911
+ worktreePath = engine.getLaneMeta(laneId)?.worktreePath;
1912
+ }
1913
+ const editRoot = worktreePath ?? rootPath;
1914
+ return { issues, laneId, worktreePath, editRoot };
1915
+ }
1916
+ function formatWhereami(opts) {
1917
+ const { engine, rootPath } = opts;
1918
+ const lines = ["Trellis whereami", ""];
1919
+ lines.push("## WAITING ON YOU");
1920
+ const waiting = findWaitingOnYou(engine);
1921
+ if (waiting.length === 0) {
1922
+ lines.push(" (none)");
1923
+ } else {
1924
+ for (const { issue, envelope } of waiting) {
1925
+ lines.push(
1926
+ ` ${issue.id} \xB7 ${envelope.status} \xB7 to:${envelope.to} \xB7 re:${envelope.re}`
1927
+ );
1928
+ if (envelope.body) {
1929
+ const preview = envelope.body.split("\n")[0].slice(0, 80);
1930
+ lines.push(` ${preview}`);
1931
+ }
1932
+ }
1933
+ }
1934
+ lines.push("");
1935
+ lines.push("## ACTIVE");
1936
+ const active = getActiveContext(engine, rootPath);
1937
+ if (active.issues.length === 0) {
1938
+ lines.push(" (no in_progress issues)");
1939
+ } else {
1940
+ for (const issue of active.issues) {
1941
+ lines.push(` ${issue.id} \xB7 ${issue.title ?? "(untitled)"}`);
1942
+ }
1943
+ }
1944
+ if (active.laneId) {
1945
+ lines.push(` Lane: ${active.laneId}`);
1946
+ }
1947
+ if (active.worktreePath) {
1948
+ lines.push(` Worktree: ${active.worktreePath}`);
1949
+ }
1950
+ lines.push(` Edit root: ${active.editRoot}`);
1951
+ lines.push("");
1952
+ lines.push("## MOVED SINCE LAST");
1953
+ const cp = loadCheckpoint(rootPath);
1954
+ if (!cp) {
1955
+ lines.push(" (no checkpoint \u2014 run trellis whereami checkpoint)");
1956
+ } else {
1957
+ const moved = findMovedSinceCheckpoint(engine, rootPath);
1958
+ if (moved.length === 0) {
1959
+ lines.push(` (none since ${cp.at})`);
1960
+ } else {
1961
+ for (const issue of moved) {
1962
+ lines.push(` ${issue.id} \xB7 ${issue.title ?? "(untitled)"}`);
1963
+ }
1964
+ }
1965
+ }
1966
+ return lines.join("\n");
1967
+ }
1968
+
1969
+ // src/cli/protocol.ts
1970
+ async function openEngine2(rootPath) {
1971
+ const engine = new TrellisVcsEngine({ rootPath });
1972
+ engine.open();
1973
+ await engine.syncEnvLaneFromEnv();
1974
+ return engine;
1975
+ }
1976
+ function readBody(opts) {
1977
+ if (opts.body) return opts.body;
1978
+ if (opts.file) return readFileSync5(opts.file, "utf-8");
1979
+ if (!process.stdin.isTTY) {
1980
+ return readFileSync5(0, "utf-8").trim() || void 0;
1981
+ }
1982
+ return void 0;
1983
+ }
1984
+ function registerWhereamiCommands(program2) {
1985
+ const whereamiCmd = program2.command("whereami").description("Re-entry dump: waiting / active / moved since checkpoint").option("-p, --path <path>", "Repository path", ".");
1986
+ whereamiCmd.action(async (opts) => {
1987
+ const rootPath = resolveRepoRoot(opts.path);
1988
+ const engine = await openEngine2(rootPath);
1989
+ console.log(formatWhereami({ engine, rootPath }));
1990
+ });
1991
+ whereamiCmd.command("checkpoint").description("Save re-entry checkpoint manifest").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
1992
+ const rootPath = resolveRepoRoot(opts.path);
1993
+ const engine = await openEngine2(rootPath);
1994
+ const allIds = engine.listIssues().map((i) => i.id);
1995
+ const openMessageIds = engine.listIssues().filter(
1996
+ (i) => i.status !== "closed" && (i.labels.includes("message") || i.labels.includes("decision"))
1997
+ ).map((i) => i.id);
1998
+ const cp = writeCheckpoint(rootPath, allIds, openMessageIds);
1999
+ console.log(chalk4.green(`\u2713 Checkpoint saved at ${cp.at}`));
2000
+ console.log(
2001
+ ` ${chalk4.dim("Issues:")} ${cp.issueIds.length} \xB7 ${chalk4.dim("open protocol:")} ${cp.openMessageIds.length}`
2002
+ );
2003
+ });
2004
+ }
2005
+ function registerProtocolCommands(program2) {
2006
+ registerWhereamiCommands(program2);
2007
+ const protocolCmd = program2.command("protocol").description("Agent handoff protocol (trellis-handoffs envelope)");
2008
+ protocolCmd.command("send").description("Record a handoff envelope as a child issue").requiredOption("--parent <id>", "Parent issue id").requiredOption("--from <role>", "Sender role").requiredOption("--to <role>", "Receiver role").requiredOption("--re <path>", "Issue path (e.g. TRL-41)").requiredOption(
2009
+ "--status <status>",
2010
+ "HANDOFF | CLARIFY | REJECT | BLOCKED | DECISION"
2011
+ ).option("--body <text>", "Message body").option("--file <path>", "Read body from file").option("-l, --label <label>", "Override label (default: message or decision)").option("--stage <stage>", "Pipeline stage for turn banner").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
2012
+ const rootPath = resolveRepoRoot(opts.path);
2013
+ const engine = await openEngine2(rootPath);
2014
+ const envelope = {
2015
+ from: opts.from,
2016
+ to: opts.to,
2017
+ re: opts.re,
2018
+ status: opts.status,
2019
+ body: readBody(opts)
2020
+ };
2021
+ const validation = validateEnvelope(envelope);
2022
+ if (!validation.ok) {
2023
+ console.error(chalk4.red(validation.errors.join("\n")));
2024
+ process.exit(1);
2025
+ }
2026
+ const label = opts.label ?? (envelope.status === "DECISION" ? "decision" : "message");
2027
+ const title = `msg: ${envelope.status} ${envelope.re}`;
2028
+ const description = formatIssueDescription(envelope, opts.stage);
2029
+ const op = await engine.createIssue(title, {
2030
+ parentId: opts.parent,
2031
+ labels: [label],
2032
+ description,
2033
+ status: "queue"
2034
+ });
2035
+ const childId = op.vcs?.issueId;
2036
+ console.log(
2037
+ chalk4.green(`\u2713 Protocol message recorded: ${chalk4.bold(childId)}`)
2038
+ );
2039
+ console.log(` ${chalk4.dim("Parent:")} ${opts.parent}`);
2040
+ console.log(` ${chalk4.dim("Label:")} ${label}`);
2041
+ });
2042
+ protocolCmd.command("whereami").description("Re-entry orientation (alias of trellis whereami)").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
2043
+ const rootPath = resolveRepoRoot(opts.path);
2044
+ const engine = await openEngine2(rootPath);
2045
+ console.log(formatWhereami({ engine, rootPath }));
2046
+ });
2047
+ }
2048
+
1647
2049
  // src/cli/index.ts
1648
2050
  var program = new Command();
1649
2051
  program.name("trellis").description("TrellisVCS \u2014 graph-native, code-first version control").version(cliVersion());
@@ -1660,15 +2062,15 @@ async function runInit(rootPath, opts = {}) {
1660
2062
  };
1661
2063
  }
1662
2064
  if (!hasProfile()) {
1663
- const identity = hasIdentity(rootPath) ? loadIdentity(join6(rootPath, ".trellis")) : null;
2065
+ const identity = hasIdentity(rootPath) ? loadIdentity(join7(rootPath, ".trellis")) : null;
1664
2066
  if (isInteractive) {
1665
- console.log(chalk4.cyan("\n Welcome to Trellis! Let's get you set up."));
2067
+ console.log(chalk5.cyan("\n Welcome to Trellis! Let's get you set up."));
1666
2068
  const newProfile = await promptForProfile({
1667
2069
  name: identity?.displayName
1668
2070
  });
1669
2071
  saveProfile(newProfile);
1670
2072
  console.log(
1671
- chalk4.green(" \u2713 Profile saved to ~/.trellis/profile.json\n")
2073
+ chalk5.green(" \u2713 Profile saved to ~/.trellis/profile.json\n")
1672
2074
  );
1673
2075
  } else {
1674
2076
  updateProfile({ name: identity?.displayName || "Unknown" });
@@ -1688,7 +2090,7 @@ async function runInit(rootPath, opts = {}) {
1688
2090
  selectedIdes = ["cursor"];
1689
2091
  }
1690
2092
  if (isInteractive) {
1691
- console.log(chalk4.cyan("\n Configuring workspace..."));
2093
+ console.log(chalk5.cyan("\n Configuring workspace..."));
1692
2094
  const setupType = await select({
1693
2095
  message: "Choose your setup mode:",
1694
2096
  choices: [
@@ -1719,11 +2121,11 @@ async function runInit(rootPath, opts = {}) {
1719
2121
  selectedIdes = ides;
1720
2122
  plugins = [];
1721
2123
  console.log(
1722
- chalk4.green(` \u2713 Detected project type: ${chalk4.bold(framework)}`)
2124
+ chalk5.green(` \u2713 Detected project type: ${chalk5.bold(framework)}`)
1723
2125
  );
1724
2126
  console.log(
1725
- chalk4.green(
1726
- ` \u2713 Scaffolding rules for: ${chalk4.bold(selectedIdes.join(", "))}`
2127
+ chalk5.green(
2128
+ ` \u2713 Scaffolding rules for: ${chalk5.bold(selectedIdes.join(", "))}`
1727
2129
  )
1728
2130
  );
1729
2131
  } else {
@@ -1851,7 +2253,7 @@ async function runInit(rootPath, opts = {}) {
1851
2253
  }
1852
2254
  const label = progress.phase === "discovering" ? "Discovering\u2026" : progress.phase === "hashing" ? "Hashing\u2026" : progress.phase === "scaffolding" ? "Scaffolding\u2026" : "Scanning\u2026";
1853
2255
  process.stdout.write(
1854
- `\r\x1B[2K ${chalk4.dim(label)} ${progress.message}`
2256
+ `\r\x1B[2K ${chalk5.dim(label)} ${progress.message}`
1855
2257
  );
1856
2258
  }
1857
2259
  });
@@ -1917,24 +2319,24 @@ program.command("init").description(
1917
2319
  }
1918
2320
  const label = progress.phase === "discovering" ? "Discovering\u2026" : progress.phase === "hashing" ? "Hashing\u2026" : progress.phase === "scaffolding" ? "Scaffolding\u2026" : "Scanning\u2026";
1919
2321
  process.stdout.write(
1920
- `\r\x1B[2K ${chalk4.dim(label)} ${progress.message}`
2322
+ `\r\x1B[2K ${chalk5.dim(label)} ${progress.message}`
1921
2323
  );
1922
2324
  }
1923
2325
  });
1924
2326
  if (renderedProgress) {
1925
2327
  process.stdout.write("\n");
1926
2328
  }
1927
- console.log(chalk4.green("\u2713 Indexed Trellis workspace"));
1928
- console.log(` ${chalk4.dim("Path:")} ${rootPath}`);
2329
+ console.log(chalk5.green("\u2713 Indexed Trellis workspace"));
2330
+ console.log(` ${chalk5.dim("Path:")} ${rootPath}`);
1929
2331
  console.log(
1930
- ` ${chalk4.dim("Files indexed:")} ${result.filesIndexed}`
2332
+ ` ${chalk5.dim("Files indexed:")} ${result.filesIndexed}`
1931
2333
  );
1932
2334
  console.log(
1933
- ` ${chalk4.dim("Ops created:")} ${result.opsCreated}`
2335
+ ` ${chalk5.dim("Ops created:")} ${result.opsCreated}`
1934
2336
  );
1935
2337
  return;
1936
2338
  }
1937
- console.log(chalk4.yellow("Already a Trellis workspace."));
2339
+ console.log(chalk5.yellow("Already a Trellis workspace."));
1938
2340
  return;
1939
2341
  }
1940
2342
  const configResult = await runInit(rootPath, {
@@ -1944,74 +2346,74 @@ program.command("init").description(
1944
2346
  footprint,
1945
2347
  indexWorkspace
1946
2348
  });
1947
- console.log(chalk4.green("\u2713 Initialized Trellis repository"));
1948
- console.log(` ${chalk4.dim("Path:")} ${rootPath}`);
2349
+ console.log(chalk5.green("\u2713 Initialized Trellis repository"));
2350
+ console.log(` ${chalk5.dim("Path:")} ${rootPath}`);
1949
2351
  console.log(
1950
- ` ${chalk4.dim("Files indexed:")} ${configResult.filesIndexed}`
2352
+ ` ${chalk5.dim("Files indexed:")} ${configResult.filesIndexed}`
1951
2353
  );
1952
2354
  console.log(
1953
- ` ${chalk4.dim("Ops:")} ${configResult.opsCreated} initial ${configResult.opsCreated === 1 ? "operation" : "operations"}`
2355
+ ` ${chalk5.dim("Ops:")} ${configResult.opsCreated} initial ${configResult.opsCreated === 1 ? "operation" : "operations"}`
1954
2356
  );
1955
- console.log(` ${chalk4.dim("Config:")} .trellis/config.json`);
1956
- console.log(` ${chalk4.dim("Op log:")} .trellis/ops.json`);
1957
- console.log(` ${chalk4.dim("Agent context:")} .trellis/agents/AGENTS.md`);
2357
+ console.log(` ${chalk5.dim("Config:")} .trellis/config.json`);
2358
+ console.log(` ${chalk5.dim("Op log:")} .trellis/ops.json`);
2359
+ console.log(` ${chalk5.dim("Agent context:")} .trellis/agents/AGENTS.md`);
1958
2360
  const preInfer = await inferProjectContext(rootPath);
1959
2361
  if (preInfer.domain) {
1960
2362
  console.log(
1961
- ` ${chalk4.dim("Domain:")} ${chalk4.cyan(preInfer.domain)} ${chalk4.dim("(inferred)")}`
2363
+ ` ${chalk5.dim("Domain:")} ${chalk5.cyan(preInfer.domain)} ${chalk5.dim("(inferred)")}`
1962
2364
  );
1963
2365
  }
1964
2366
  if (preInfer.ecosystem && preInfer.ecosystem !== "unknown") {
1965
- console.log(` ${chalk4.dim("Ecosystem:")} ${preInfer.ecosystem}`);
2367
+ console.log(` ${chalk5.dim("Ecosystem:")} ${preInfer.ecosystem}`);
1966
2368
  }
1967
2369
  console.log();
1968
- console.log(chalk4.bold("Next steps (VCS):"));
2370
+ console.log(chalk5.bold("Next steps (VCS):"));
1969
2371
  console.log();
1970
2372
  console.log(
1971
- ` ${chalk4.cyan("trellis status")} Check repository status`
2373
+ ` ${chalk5.cyan("trellis status")} Check repository status`
1972
2374
  );
1973
- console.log(` ${chalk4.cyan("trellis log")} View recent history`);
2375
+ console.log(` ${chalk5.cyan("trellis log")} View recent history`);
1974
2376
  console.log(
1975
- ` ${chalk4.cyan("trellis branch")} List or create branches`
2377
+ ` ${chalk5.cyan("trellis branch")} List or create branches`
1976
2378
  );
1977
2379
  console.log(
1978
- ` ${chalk4.cyan("trellis milestone")} Create narrative checkpoints`
2380
+ ` ${chalk5.cyan("trellis milestone")} Create narrative checkpoints`
1979
2381
  );
1980
2382
  console.log(
1981
- ` ${chalk4.cyan("trellis garden")} Discover abandoned work`
2383
+ ` ${chalk5.cyan("trellis garden")} Discover abandoned work`
1982
2384
  );
1983
2385
  console.log(
1984
- ` ${chalk4.cyan("trellis issue")} Create and track issues`
2386
+ ` ${chalk5.cyan("trellis issue")} Create and track issues`
1985
2387
  );
1986
2388
  if (preInfer.confidence !== "high") {
1987
2389
  console.log(
1988
- ` ${chalk4.cyan("trellis season")} Enrich project context for agents`
2390
+ ` ${chalk5.cyan("trellis season")} Enrich project context for agents`
1989
2391
  );
1990
2392
  }
1991
2393
  console.log();
1992
- console.log(chalk4.bold("Semantic Substrate (Live local services):"));
2394
+ console.log(chalk5.bold("Semantic Substrate (Live local services):"));
1993
2395
  console.log();
1994
2396
  console.log(
1995
- ` ${chalk4.cyan("trellis web")} Launch local web client / graph visualizer`
2397
+ ` ${chalk5.cyan("trellis web")} Launch local web client / graph visualizer`
1996
2398
  );
1997
2399
  console.log(
1998
- ` ${chalk4.cyan("trellis query")} Run EQL-S semantic queries against your code graph`
2400
+ ` ${chalk5.cyan("trellis query")} Run EQL-S semantic queries against your code graph`
1999
2401
  );
2000
2402
  if (configResult.selectedIdes.length > 0) {
2001
2403
  console.log(
2002
- ` ${chalk4.cyan("Agent Rules")} Active for ${chalk4.bold(configResult.selectedIdes.join(", "))}. Agents will auto-detect the graph.`
2404
+ ` ${chalk5.cyan("Agent Rules")} Active for ${chalk5.bold(configResult.selectedIdes.join(", "))}. Agents will auto-detect the graph.`
2003
2405
  );
2004
2406
  }
2005
2407
  console.log();
2006
2408
  if (configResult.indexWorkspace) {
2007
2409
  console.log(
2008
- chalk4.dim(
2410
+ chalk5.dim(
2009
2411
  "The causal stream is now active. Every file change will be tracked."
2010
2412
  )
2011
2413
  );
2012
2414
  } else {
2013
2415
  console.log(
2014
- chalk4.dim(
2416
+ chalk5.dim(
2015
2417
  "Minimal workspace initialized. Existing files were not indexed."
2016
2418
  )
2017
2419
  );
@@ -2025,35 +2427,35 @@ program.command("seed").description("Refresh agent context files with current pr
2025
2427
  const rootPath = resolveRepoRoot(opts.path);
2026
2428
  const ide = opts.ide || "none";
2027
2429
  const force = opts.force || false;
2028
- console.log(chalk4.dim("Seeding agent context..."));
2430
+ console.log(chalk5.dim("Seeding agent context..."));
2029
2431
  const result = await seedContext({ rootPath, ide, force });
2030
2432
  if (result.success) {
2031
- console.log(chalk4.green("\u2713 Context seeded"));
2433
+ console.log(chalk5.green("\u2713 Context seeded"));
2032
2434
  console.log(
2033
- ` ${chalk4.dim("Files updated:")} ${result.filesUpdated.length}`
2435
+ ` ${chalk5.dim("Files updated:")} ${result.filesUpdated.length}`
2034
2436
  );
2035
2437
  for (const f of result.filesUpdated) {
2036
- console.log(` ${chalk4.dim("-")} ${f}`);
2438
+ console.log(` ${chalk5.dim("-")} ${f}`);
2037
2439
  }
2038
- console.log(` ${chalk4.dim("Timestamp:")} ${result.timestamp}`);
2440
+ console.log(` ${chalk5.dim("Timestamp:")} ${result.timestamp}`);
2039
2441
  } else {
2040
- console.log(chalk4.red("\u2717 Failed to seed context"));
2442
+ console.log(chalk5.red("\u2717 Failed to seed context"));
2041
2443
  }
2042
2444
  });
2043
2445
  program.command("repair").description("Attempt to repair a corrupted .trellis/ops.json file").option("-p, --path <path>", "Repository path", ".").action((opts) => {
2044
2446
  const rootPath = resolveRepoRoot(opts.path);
2045
- console.log(chalk4.yellow("Attempting to repair ops.json..."));
2447
+ console.log(chalk5.yellow("Attempting to repair ops.json..."));
2046
2448
  const result = TrellisVcsEngine.repair(rootPath);
2047
2449
  if (result.lost === -1) {
2048
2450
  console.log(
2049
- chalk4.red(
2451
+ chalk5.red(
2050
2452
  "Could not recover any ops. A corrupted backup was saved as ops.json.corrupted"
2051
2453
  )
2052
2454
  );
2053
2455
  } else if (result.recovered > 0) {
2054
- console.log(chalk4.green(`\u2713 Recovered ${result.recovered} ops.`));
2456
+ console.log(chalk5.green(`\u2713 Recovered ${result.recovered} ops.`));
2055
2457
  } else {
2056
- console.log(chalk4.green("ops.json is already valid. No repair needed."));
2458
+ console.log(chalk5.green("ops.json is already valid. No repair needed."));
2057
2459
  }
2058
2460
  });
2059
2461
  program.command("status").description("Show current repository status").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
@@ -2061,32 +2463,32 @@ program.command("status").description("Show current repository status").option("
2061
2463
  const engine = new TrellisVcsEngine({ rootPath });
2062
2464
  engine.open();
2063
2465
  const st = engine.status();
2064
- console.log(chalk4.bold("TrellisVCS Status"));
2466
+ console.log(chalk5.bold("TrellisVCS Status"));
2065
2467
  console.log();
2066
- console.log(` ${chalk4.dim("Branch:")} ${chalk4.cyan(st.branch)}`);
2067
- console.log(` ${chalk4.dim("Total ops:")} ${st.totalOps}`);
2068
- console.log(` ${chalk4.dim("Tracked files:")} ${st.trackedFiles}`);
2468
+ console.log(` ${chalk5.dim("Branch:")} ${chalk5.cyan(st.branch)}`);
2469
+ console.log(` ${chalk5.dim("Total ops:")} ${st.totalOps}`);
2470
+ console.log(` ${chalk5.dim("Tracked files:")} ${st.trackedFiles}`);
2069
2471
  if (st.lastOp) {
2070
2472
  console.log();
2071
2473
  console.log(
2072
- ` ${chalk4.dim("Last op:")} ${chalk4.yellow(st.lastOp.kind)}`
2474
+ ` ${chalk5.dim("Last op:")} ${chalk5.yellow(st.lastOp.kind)}`
2073
2475
  );
2074
- console.log(` ${chalk4.dim(" at:")} ${st.lastOp.timestamp}`);
2476
+ console.log(` ${chalk5.dim(" at:")} ${st.lastOp.timestamp}`);
2075
2477
  if (st.lastOp.vcs?.filePath) {
2076
2478
  console.log(
2077
- ` ${chalk4.dim(" file:")} ${st.lastOp.vcs.filePath}`
2479
+ ` ${chalk5.dim(" file:")} ${st.lastOp.vcs.filePath}`
2078
2480
  );
2079
2481
  }
2080
2482
  }
2081
2483
  if (st.recentOps.length > 0) {
2082
2484
  console.log();
2083
- console.log(chalk4.dim(" Recent activity:"));
2485
+ console.log(chalk5.dim(" Recent activity:"));
2084
2486
  const display = st.recentOps.filter((op) => op.kind !== "vcs:branchCreate").slice(-5);
2085
2487
  for (const op of display) {
2086
2488
  const kind = formatOpKind(op.kind);
2087
2489
  const file = op.vcs?.filePath ?? "";
2088
2490
  const time = formatRelativeTime2(op.timestamp);
2089
- console.log(` ${kind} ${chalk4.white(file)} ${chalk4.dim(time)}`);
2491
+ console.log(` ${kind} ${chalk5.white(file)} ${chalk5.dim(time)}`);
2090
2492
  }
2091
2493
  }
2092
2494
  });
@@ -2099,8 +2501,8 @@ program.command("log").description("Show operation history").option("-p, --path
2099
2501
  filePath: opts.file
2100
2502
  });
2101
2503
  if (opts.remote || opts.all) {
2102
- const { RemoteManager } = await import("../remote-manager-ODE3T2KR.js");
2103
- const remoteManager = new RemoteManager(join6(rootPath, ".trellis"));
2504
+ const { RemoteManager } = await import("../remote-manager-6ERQUBSL.js");
2505
+ const remoteManager = new RemoteManager(join7(rootPath, ".trellis"));
2104
2506
  if (opts.all) {
2105
2507
  const remotes = remoteManager.listRemotes();
2106
2508
  const remoteOps = ops.filter(
@@ -2126,7 +2528,7 @@ program.command("log").description("Show operation history").option("-p, --path
2126
2528
  }
2127
2529
  }
2128
2530
  if (ops.length === 0) {
2129
- console.log(chalk4.dim("No operations found."));
2531
+ console.log(chalk5.dim("No operations found."));
2130
2532
  return;
2131
2533
  }
2132
2534
  const groupedOps = opts.all || opts.remote ? ops.reduce(
@@ -2141,19 +2543,19 @@ program.command("log").description("Show operation history").option("-p, --path
2141
2543
  },
2142
2544
  {}
2143
2545
  ) : { local: ops };
2144
- console.log(chalk4.bold(`Causal Stream \u2014 ${ops.length} ops`));
2546
+ console.log(chalk5.bold(`Causal Stream \u2014 ${ops.length} ops`));
2145
2547
  console.log();
2146
2548
  for (const [remote, remoteOps] of Object.entries(groupedOps)) {
2147
2549
  if (opts.all || opts.remote) {
2148
- console.log(chalk4.cyan(`${remote === "local" ? "Local" : remote}:`));
2550
+ console.log(chalk5.cyan(`${remote === "local" ? "Local" : remote}:`));
2149
2551
  }
2150
2552
  for (const op of remoteOps.reverse()) {
2151
2553
  const kind = formatOpKind(op.kind);
2152
- const hash = chalk4.dim(op.hash.slice(0, 28) + "\u2026");
2554
+ const hash = chalk5.dim(op.hash.slice(0, 28) + "\u2026");
2153
2555
  const time = formatRelativeTime2(op.timestamp);
2154
- const file = op.vcs?.filePath ? chalk4.white(op.vcs.filePath) : "";
2155
- const rename = op.vcs?.oldFilePath ? chalk4.dim(` (from ${op.vcs.oldFilePath})`) : "";
2156
- console.log(` ${hash} ${kind} ${file}${rename} ${chalk4.dim(time)}`);
2556
+ const file = op.vcs?.filePath ? chalk5.white(op.vcs.filePath) : "";
2557
+ const rename = op.vcs?.oldFilePath ? chalk5.dim(` (from ${op.vcs.oldFilePath})`) : "";
2558
+ console.log(` ${hash} ${kind} ${file}${rename} ${chalk5.dim(time)}`);
2157
2559
  }
2158
2560
  if (opts.all || opts.remote) {
2159
2561
  console.log();
@@ -2166,13 +2568,13 @@ program.command("files").description("List all tracked files").option("-p, --pat
2166
2568
  engine.open();
2167
2569
  const files = engine.trackedFiles();
2168
2570
  if (files.length === 0) {
2169
- console.log(chalk4.dim("No tracked files."));
2571
+ console.log(chalk5.dim("No tracked files."));
2170
2572
  return;
2171
2573
  }
2172
- console.log(chalk4.bold(`Tracked Files \u2014 ${files.length}`));
2574
+ console.log(chalk5.bold(`Tracked Files \u2014 ${files.length}`));
2173
2575
  console.log();
2174
2576
  for (const f of files.sort((a, b) => a.path.localeCompare(b.path))) {
2175
- const hash = f.contentHash ? chalk4.dim(f.contentHash.slice(0, 12)) : chalk4.dim("(no hash)");
2577
+ const hash = f.contentHash ? chalk5.dim(f.contentHash.slice(0, 12)) : chalk5.dim("(no hash)");
2176
2578
  console.log(` ${hash} ${f.path}`);
2177
2579
  }
2178
2580
  });
@@ -2183,10 +2585,10 @@ program.command("watch").description("Start file watcher (foreground, Ctrl+C to
2183
2585
  await engine.syncEnvLaneFromEnv();
2184
2586
  const laneId = engine.getActiveLaneId();
2185
2587
  console.log(
2186
- chalk4.green("\u2713 Watching for changes\u2026") + chalk4.dim(" (Ctrl+C to stop)")
2588
+ chalk5.green("\u2713 Watching for changes\u2026") + chalk5.dim(" (Ctrl+C to stop)")
2187
2589
  );
2188
2590
  if (laneId) {
2189
- console.log(chalk4.dim(` Lane: ${laneId} (writes \u2192 lane journal)`));
2591
+ console.log(chalk5.dim(` Lane: ${laneId} (writes \u2192 lane journal)`));
2190
2592
  }
2191
2593
  console.log();
2192
2594
  const originalWatch = engine.watch.bind(engine);
@@ -2194,15 +2596,15 @@ program.command("watch").description("Start file watcher (foreground, Ctrl+C to
2194
2596
  process.on("SIGINT", () => {
2195
2597
  engine.stop();
2196
2598
  console.log();
2197
- console.log(chalk4.dim("Watcher stopped."));
2599
+ console.log(chalk5.dim("Watcher stopped."));
2198
2600
  process.exit(0);
2199
2601
  });
2200
2602
  });
2201
2603
  program.command("import").description("Import from an existing Git repository").requiredOption("--from <path>", "Path to the Git repository to import from").option("-p, --path <path>", "Target TrellisVCS repository path", ".").action(async (opts) => {
2202
2604
  const from = resolve2(opts.from);
2203
2605
  const to = resolve2(opts.path);
2204
- console.log(chalk4.dim(`Importing from Git: ${from}`));
2205
- console.log(chalk4.dim(`Target: ${to}`));
2606
+ console.log(chalk5.dim(`Importing from Git: ${from}`));
2607
+ console.log(chalk5.dim(`Target: ${to}`));
2206
2608
  console.log();
2207
2609
  try {
2208
2610
  const result = await importFromGit({
@@ -2210,10 +2612,10 @@ program.command("import").description("Import from an existing Git repository").
2210
2612
  to,
2211
2613
  onProgress: (p) => {
2212
2614
  if (p.phase === "reading") {
2213
- process.stdout.write(`\r ${chalk4.dim("Reading\u2026")} ${p.message}`);
2615
+ process.stdout.write(`\r ${chalk5.dim("Reading\u2026")} ${p.message}`);
2214
2616
  } else if (p.phase === "importing") {
2215
2617
  process.stdout.write(
2216
- `\r ${chalk4.dim("Importing\u2026")} ${p.current}/${p.total} commits`
2618
+ `\r ${chalk5.dim("Importing\u2026")} ${p.current}/${p.total} commits`
2217
2619
  );
2218
2620
  } else {
2219
2621
  process.stdout.write("\n");
@@ -2221,24 +2623,24 @@ program.command("import").description("Import from an existing Git repository").
2221
2623
  }
2222
2624
  });
2223
2625
  console.log();
2224
- console.log(chalk4.green("\u2713 Git import complete"));
2225
- console.log(` ${chalk4.dim("Commits:")} ${result.commitsImported}`);
2226
- console.log(` ${chalk4.dim("Ops:")} ${result.opsCreated}`);
2227
- console.log(` ${chalk4.dim("Files:")} ${result.filesTracked}`);
2626
+ console.log(chalk5.green("\u2713 Git import complete"));
2627
+ console.log(` ${chalk5.dim("Commits:")} ${result.commitsImported}`);
2628
+ console.log(` ${chalk5.dim("Ops:")} ${result.opsCreated}`);
2629
+ console.log(` ${chalk5.dim("Files:")} ${result.filesTracked}`);
2228
2630
  console.log(
2229
- ` ${chalk4.dim("Branches:")} ${result.branches.join(", ")}`
2631
+ ` ${chalk5.dim("Branches:")} ${result.branches.join(", ")}`
2230
2632
  );
2231
2633
  console.log(
2232
- ` ${chalk4.dim("Duration:")} ${(result.duration / 1e3).toFixed(1)}s`
2634
+ ` ${chalk5.dim("Duration:")} ${(result.duration / 1e3).toFixed(1)}s`
2233
2635
  );
2234
2636
  console.log();
2235
2637
  console.log(
2236
- chalk4.dim(
2638
+ chalk5.dim(
2237
2639
  "Run `trellis status` or `trellis log` to explore the imported history."
2238
2640
  )
2239
2641
  );
2240
2642
  } catch (err) {
2241
- console.error(chalk4.red(`
2643
+ console.error(chalk5.red(`
2242
2644
  Import failed: ${err.message}`));
2243
2645
  process.exit(1);
2244
2646
  }
@@ -2246,8 +2648,8 @@ Import failed: ${err.message}`));
2246
2648
  program.command("export").description("Export milestones to a Git repository").requiredOption("--to <path>", "Path to the target Git repository").option("-p, --path <path>", "Source TrellisVCS repository path", ".").option("--author-name <name>", "Author name for Git commits").option("--author-email <email>", "Author email for Git commits").action(async (opts) => {
2247
2649
  const from = resolveRepoRoot(opts.path);
2248
2650
  const to = resolve2(opts.to);
2249
- console.log(chalk4.dim(`Exporting from: ${from}`));
2250
- console.log(chalk4.dim(`Target Git repo: ${to}`));
2651
+ console.log(chalk5.dim(`Exporting from: ${from}`));
2652
+ console.log(chalk5.dim(`Target Git repo: ${to}`));
2251
2653
  console.log();
2252
2654
  try {
2253
2655
  const result = await exportToGit({
@@ -2257,10 +2659,10 @@ program.command("export").description("Export milestones to a Git repository").r
2257
2659
  authorEmail: opts.authorEmail,
2258
2660
  onProgress: (p) => {
2259
2661
  if (p.phase === "preparing") {
2260
- console.log(` ${chalk4.dim(p.message)}`);
2662
+ console.log(` ${chalk5.dim(p.message)}`);
2261
2663
  } else if (p.phase === "exporting") {
2262
2664
  process.stdout.write(
2263
- `\r ${chalk4.dim("Exporting\u2026")} ${p.current}/${p.total} milestones`
2665
+ `\r ${chalk5.dim("Exporting\u2026")} ${p.current}/${p.total} milestones`
2264
2666
  );
2265
2667
  } else {
2266
2668
  process.stdout.write("\n");
@@ -2268,14 +2670,14 @@ program.command("export").description("Export milestones to a Git repository").r
2268
2670
  }
2269
2671
  });
2270
2672
  console.log();
2271
- console.log(chalk4.green("\u2713 Git export complete"));
2272
- console.log(` ${chalk4.dim("Milestones:")} ${result.milestonesExported}`);
2273
- console.log(` ${chalk4.dim("Commits:")} ${result.commitsCreated}`);
2673
+ console.log(chalk5.green("\u2713 Git export complete"));
2674
+ console.log(` ${chalk5.dim("Milestones:")} ${result.milestonesExported}`);
2675
+ console.log(` ${chalk5.dim("Commits:")} ${result.commitsCreated}`);
2274
2676
  console.log(
2275
- ` ${chalk4.dim("Duration:")} ${(result.duration / 1e3).toFixed(1)}s`
2677
+ ` ${chalk5.dim("Duration:")} ${(result.duration / 1e3).toFixed(1)}s`
2276
2678
  );
2277
2679
  } catch (err) {
2278
- console.error(chalk4.red(`
2680
+ console.error(chalk5.red(`
2279
2681
  Export failed: ${err.message}`));
2280
2682
  process.exit(1);
2281
2683
  }
@@ -2287,9 +2689,9 @@ program.command("branch").description("Manage branches").argument("[name]", "Bra
2287
2689
  if (opts.delete) {
2288
2690
  try {
2289
2691
  await engine.deleteBranch(opts.delete);
2290
- console.log(chalk4.green(`\u2713 Deleted branch '${opts.delete}'`));
2692
+ console.log(chalk5.green(`\u2713 Deleted branch '${opts.delete}'`));
2291
2693
  } catch (err) {
2292
- console.error(chalk4.red(err.message));
2694
+ console.error(chalk5.red(err.message));
2293
2695
  process.exit(1);
2294
2696
  }
2295
2697
  return;
@@ -2300,9 +2702,9 @@ program.command("branch").description("Manage branches").argument("[name]", "Bra
2300
2702
  if (exists) {
2301
2703
  try {
2302
2704
  engine.switchBranch(name);
2303
- console.log(chalk4.green(`\u2713 Switched to branch '${name}'`));
2705
+ console.log(chalk5.green(`\u2713 Switched to branch '${name}'`));
2304
2706
  } catch (err) {
2305
- console.error(chalk4.red(err.message));
2707
+ console.error(chalk5.red(err.message));
2306
2708
  process.exit(1);
2307
2709
  }
2308
2710
  } else {
@@ -2310,10 +2712,10 @@ program.command("branch").description("Manage branches").argument("[name]", "Bra
2310
2712
  await engine.createBranch(name);
2311
2713
  engine.switchBranch(name);
2312
2714
  console.log(
2313
- chalk4.green(`\u2713 Created and switched to branch '${name}'`)
2715
+ chalk5.green(`\u2713 Created and switched to branch '${name}'`)
2314
2716
  );
2315
2717
  } catch (err) {
2316
- console.error(chalk4.red(err.message));
2718
+ console.error(chalk5.red(err.message));
2317
2719
  process.exit(1);
2318
2720
  }
2319
2721
  }
@@ -2321,14 +2723,14 @@ program.command("branch").description("Manage branches").argument("[name]", "Bra
2321
2723
  }
2322
2724
  const branches = engine.listBranches();
2323
2725
  if (branches.length === 0) {
2324
- console.log(chalk4.dim("No branches"));
2726
+ console.log(chalk5.dim("No branches"));
2325
2727
  return;
2326
2728
  }
2327
- console.log(chalk4.bold("Branches\n"));
2729
+ console.log(chalk5.bold("Branches\n"));
2328
2730
  for (const b of branches) {
2329
- const marker = b.isCurrent ? chalk4.green("* ") : " ";
2330
- const name2 = b.isCurrent ? chalk4.green(b.name) : b.name;
2331
- const age = b.createdAt ? chalk4.dim(formatRelativeTime2(b.createdAt)) : "";
2731
+ const marker = b.isCurrent ? chalk5.green("* ") : " ";
2732
+ const name2 = b.isCurrent ? chalk5.green(b.name) : b.name;
2733
+ const age = b.createdAt ? chalk5.dim(formatRelativeTime2(b.createdAt)) : "";
2332
2734
  console.log(`${marker}${name2} ${age}`);
2333
2735
  }
2334
2736
  });
@@ -2339,7 +2741,7 @@ program.command("milestone").description("Create or list milestones").argument("
2339
2741
  if (action === "create") {
2340
2742
  if (!opts.message) {
2341
2743
  console.error(
2342
- chalk4.red('Milestone message is required: --message "..."')
2744
+ chalk5.red('Milestone message is required: --message "..."')
2343
2745
  );
2344
2746
  process.exit(1);
2345
2747
  }
@@ -2348,32 +2750,32 @@ program.command("milestone").description("Create or list milestones").argument("
2348
2750
  fromOpHash: opts.from,
2349
2751
  toOpHash: opts.to
2350
2752
  });
2351
- console.log(chalk4.green(`\u2713 Milestone created`));
2352
- console.log(` ${chalk4.dim("ID:")} ${op.vcs?.milestoneId}`);
2353
- console.log(` ${chalk4.dim("Message:")} ${opts.message}`);
2354
- console.log(` ${chalk4.dim("Hash:")} ${op.hash.slice(0, 32)}\u2026`);
2753
+ console.log(chalk5.green(`\u2713 Milestone created`));
2754
+ console.log(` ${chalk5.dim("ID:")} ${op.vcs?.milestoneId}`);
2755
+ console.log(` ${chalk5.dim("Message:")} ${opts.message}`);
2756
+ console.log(` ${chalk5.dim("Hash:")} ${op.hash.slice(0, 32)}\u2026`);
2355
2757
  } catch (err) {
2356
- console.error(chalk4.red(`Failed: ${err.message}`));
2758
+ console.error(chalk5.red(`Failed: ${err.message}`));
2357
2759
  process.exit(1);
2358
2760
  }
2359
2761
  return;
2360
2762
  }
2361
2763
  const milestones = engine.listMilestones();
2362
2764
  if (milestones.length === 0) {
2363
- console.log(chalk4.dim("No milestones"));
2765
+ console.log(chalk5.dim("No milestones"));
2364
2766
  return;
2365
2767
  }
2366
- console.log(chalk4.bold(`Milestones (${milestones.length})
2768
+ console.log(chalk5.bold(`Milestones (${milestones.length})
2367
2769
  `));
2368
2770
  for (const m of milestones) {
2369
2771
  const age = m.createdAt ? formatRelativeTime2(m.createdAt) : "";
2370
2772
  console.log(
2371
- ` ${chalk4.cyan("\u2605")} ${chalk4.bold(m.message ?? "(no message)")}`
2773
+ ` ${chalk5.cyan("\u2605")} ${chalk5.bold(m.message ?? "(no message)")}`
2372
2774
  );
2373
- console.log(` ${chalk4.dim("ID:")} ${m.id} ${chalk4.dim(age)}`);
2775
+ console.log(` ${chalk5.dim("ID:")} ${m.id} ${chalk5.dim(age)}`);
2374
2776
  if (m.affectedFiles.length > 0) {
2375
2777
  console.log(
2376
- ` ${chalk4.dim("Files:")} ${m.affectedFiles.slice(0, 5).join(", ")}${m.affectedFiles.length > 5 ? ` +${m.affectedFiles.length - 5} more` : ""}`
2778
+ ` ${chalk5.dim("Files:")} ${m.affectedFiles.slice(0, 5).join(", ")}${m.affectedFiles.length > 5 ? ` +${m.affectedFiles.length - 5} more` : ""}`
2377
2779
  );
2378
2780
  }
2379
2781
  console.log();
@@ -2386,26 +2788,26 @@ program.command("checkpoint").description("Create or list checkpoints").argument
2386
2788
  if (action === "create") {
2387
2789
  try {
2388
2790
  const op = await engine.createCheckpoint("manual");
2389
- console.log(chalk4.green(`\u2713 Checkpoint created`));
2390
- console.log(` ${chalk4.dim("Hash:")} ${op.hash.slice(0, 32)}\u2026`);
2391
- console.log(` ${chalk4.dim("Trigger:")} manual`);
2791
+ console.log(chalk5.green(`\u2713 Checkpoint created`));
2792
+ console.log(` ${chalk5.dim("Hash:")} ${op.hash.slice(0, 32)}\u2026`);
2793
+ console.log(` ${chalk5.dim("Trigger:")} manual`);
2392
2794
  } catch (err) {
2393
- console.error(chalk4.red(`Failed: ${err.message}`));
2795
+ console.error(chalk5.red(`Failed: ${err.message}`));
2394
2796
  process.exit(1);
2395
2797
  }
2396
2798
  return;
2397
2799
  }
2398
2800
  const checkpoints = engine.listCheckpoints();
2399
2801
  if (checkpoints.length === 0) {
2400
- console.log(chalk4.dim("No checkpoints"));
2802
+ console.log(chalk5.dim("No checkpoints"));
2401
2803
  return;
2402
2804
  }
2403
- console.log(chalk4.bold(`Checkpoints (${checkpoints.length})
2805
+ console.log(chalk5.bold(`Checkpoints (${checkpoints.length})
2404
2806
  `));
2405
2807
  for (const cp of checkpoints) {
2406
2808
  const age = cp.createdAt ? formatRelativeTime2(cp.createdAt) : "";
2407
2809
  console.log(
2408
- ` ${chalk4.dim("\u25CF")} ${cp.id.slice(0, 32)} ${chalk4.dim(cp.trigger ?? "")} ${chalk4.dim(age)}`
2810
+ ` ${chalk5.dim("\u25CF")} ${cp.id.slice(0, 32)} ${chalk5.dim(cp.trigger ?? "")} ${chalk5.dim(age)}`
2409
2811
  );
2410
2812
  }
2411
2813
  });
@@ -2421,44 +2823,44 @@ program.command("diff").description("Show file-level diff between two points in
2421
2823
  } else {
2422
2824
  const ops = engine.getOps();
2423
2825
  if (ops.length < 2) {
2424
- console.log(chalk4.dim("Not enough history to diff."));
2826
+ console.log(chalk5.dim("Not enough history to diff."));
2425
2827
  return;
2426
2828
  }
2427
2829
  result = engine.diffOps(ops[0].hash, ops[ops.length - 1].hash);
2428
2830
  }
2429
2831
  if (result.diffs.length === 0) {
2430
- console.log(chalk4.dim("No differences."));
2832
+ console.log(chalk5.dim("No differences."));
2431
2833
  return;
2432
2834
  }
2433
2835
  const s = result.stats;
2434
2836
  console.log(
2435
- `${chalk4.green(`+${s.added} added`)} ${chalk4.yellow(`~${s.modified} modified`)} ${chalk4.red(`-${s.removed} removed`)}${s.renamed ? ` ${chalk4.blue(`\u2192${s.renamed} renamed`)}` : ""}`
2837
+ `${chalk5.green(`+${s.added} added`)} ${chalk5.yellow(`~${s.modified} modified`)} ${chalk5.red(`-${s.removed} removed`)}${s.renamed ? ` ${chalk5.blue(`\u2192${s.renamed} renamed`)}` : ""}`
2436
2838
  );
2437
2839
  console.log();
2438
2840
  if (opts.stat) return;
2439
2841
  for (const diff of result.diffs) {
2440
2842
  switch (diff.kind) {
2441
2843
  case "fileAdded":
2442
- console.log(`${chalk4.green("+ " + diff.path)}`);
2844
+ console.log(`${chalk5.green("+ " + diff.path)}`);
2443
2845
  break;
2444
2846
  case "fileDeleted":
2445
- console.log(`${chalk4.red("- " + diff.path)}`);
2847
+ console.log(`${chalk5.red("- " + diff.path)}`);
2446
2848
  break;
2447
2849
  case "fileRenamed":
2448
- console.log(`${chalk4.blue(`\u2192 ${diff.oldPath} \u2192 ${diff.path}`)}`);
2850
+ console.log(`${chalk5.blue(`\u2192 ${diff.oldPath} \u2192 ${diff.path}`)}`);
2449
2851
  break;
2450
2852
  case "fileModified":
2451
- console.log(`${chalk4.yellow("~ " + diff.path)}`);
2853
+ console.log(`${chalk5.yellow("~ " + diff.path)}`);
2452
2854
  if (diff.unifiedDiff) {
2453
2855
  for (const line of diff.unifiedDiff.split("\n")) {
2454
2856
  if (line.startsWith("+")) {
2455
- console.log(chalk4.green(line));
2857
+ console.log(chalk5.green(line));
2456
2858
  } else if (line.startsWith("-")) {
2457
- console.log(chalk4.red(line));
2859
+ console.log(chalk5.red(line));
2458
2860
  } else if (line.startsWith("@@")) {
2459
- console.log(chalk4.cyan(line));
2861
+ console.log(chalk5.cyan(line));
2460
2862
  } else {
2461
- console.log(chalk4.dim(line));
2863
+ console.log(chalk5.dim(line));
2462
2864
  }
2463
2865
  }
2464
2866
  }
@@ -2473,67 +2875,67 @@ program.command("merge").description("Merge a branch into the current branch").a
2473
2875
  engine.open();
2474
2876
  const result = engine.mergeBranch(branch);
2475
2877
  if (result.clean) {
2476
- console.log(chalk4.green("\u2713 Merge completed cleanly"));
2878
+ console.log(chalk5.green("\u2713 Merge completed cleanly"));
2477
2879
  } else {
2478
2880
  console.log(
2479
- chalk4.yellow(`\u26A0 Merge has ${result.conflicts.length} conflict(s)`)
2881
+ chalk5.yellow(`\u26A0 Merge has ${result.conflicts.length} conflict(s)`)
2480
2882
  );
2481
2883
  }
2482
2884
  const s = result.stats;
2483
- console.log(` ${chalk4.dim("Modified:")} ${s.modified}`);
2484
- console.log(` ${chalk4.dim("Deleted:")} ${s.deleted}`);
2485
- console.log(` ${chalk4.dim("Conflicted:")} ${s.conflicted}`);
2885
+ console.log(` ${chalk5.dim("Modified:")} ${s.modified}`);
2886
+ console.log(` ${chalk5.dim("Deleted:")} ${s.deleted}`);
2887
+ console.log(` ${chalk5.dim("Conflicted:")} ${s.conflicted}`);
2486
2888
  if (result.conflicts.length > 0) {
2487
2889
  console.log();
2488
- console.log(chalk4.bold("Conflicts:"));
2890
+ console.log(chalk5.bold("Conflicts:"));
2489
2891
  for (const c of result.conflicts) {
2490
- console.log(` ${chalk4.red("\u2717")} ${c.path} (${c.kind})`);
2892
+ console.log(` ${chalk5.red("\u2717")} ${c.path} (${c.kind})`);
2491
2893
  }
2492
2894
  }
2493
2895
  if (opts.dryRun) {
2494
2896
  console.log();
2495
- console.log(chalk4.dim("(dry run \u2014 no changes applied)"));
2897
+ console.log(chalk5.dim("(dry run \u2014 no changes applied)"));
2496
2898
  }
2497
2899
  });
2498
2900
  program.command("parse").description("Parse a file into AST-level semantic entities").argument("<file>", "File to parse").option("-p, --path <path>", "Repository path", ".").action((file, opts) => {
2499
2901
  const rootPath = resolveRepoRoot(opts.path);
2500
2902
  const engine = new TrellisVcsEngine({ rootPath });
2501
2903
  engine.open();
2502
- const { readFileSync: readFileSync5 } = __require("fs");
2904
+ const { readFileSync: readFileSync7 } = __require("fs");
2503
2905
  const filePath = resolve2(file);
2504
- const content = readFileSync5(filePath, "utf-8");
2906
+ const content = readFileSync7(filePath, "utf-8");
2505
2907
  const result = engine.parseFile(content, file);
2506
2908
  if (!result) {
2507
- console.log(chalk4.dim(`No parser available for: ${file}`));
2909
+ console.log(chalk5.dim(`No parser available for: ${file}`));
2508
2910
  return;
2509
2911
  }
2510
- console.log(chalk4.bold(`Parse: ${file}
2912
+ console.log(chalk5.bold(`Parse: ${file}
2511
2913
  `));
2512
- console.log(` ${chalk4.dim("Language:")} ${result.language}`);
2914
+ console.log(` ${chalk5.dim("Language:")} ${result.language}`);
2513
2915
  console.log(
2514
- ` ${chalk4.dim("Declarations:")} ${result.declarations.length}`
2916
+ ` ${chalk5.dim("Declarations:")} ${result.declarations.length}`
2515
2917
  );
2516
- console.log(` ${chalk4.dim("Imports:")} ${result.imports.length}`);
2517
- console.log(` ${chalk4.dim("Exports:")} ${result.exports.length}`);
2918
+ console.log(` ${chalk5.dim("Imports:")} ${result.imports.length}`);
2919
+ console.log(` ${chalk5.dim("Exports:")} ${result.exports.length}`);
2518
2920
  if (result.declarations.length > 0) {
2519
2921
  console.log();
2520
- console.log(chalk4.bold("Declarations:"));
2922
+ console.log(chalk5.bold("Declarations:"));
2521
2923
  for (const d of result.declarations) {
2522
2924
  console.log(
2523
- ` ${chalk4.cyan(d.kind.padEnd(14))} ${chalk4.bold(d.name)}${d.children.length ? ` (${d.children.length} members)` : ""}`
2925
+ ` ${chalk5.cyan(d.kind.padEnd(14))} ${chalk5.bold(d.name)}${d.children.length ? ` (${d.children.length} members)` : ""}`
2524
2926
  );
2525
2927
  for (const child of d.children) {
2526
- console.log(` ${chalk4.dim(child.kind.padEnd(14))} ${child.name}`);
2928
+ console.log(` ${chalk5.dim(child.kind.padEnd(14))} ${child.name}`);
2527
2929
  }
2528
2930
  }
2529
2931
  }
2530
2932
  if (result.imports.length > 0) {
2531
2933
  console.log();
2532
- console.log(chalk4.bold("Imports:"));
2934
+ console.log(chalk5.bold("Imports:"));
2533
2935
  for (const imp of result.imports) {
2534
2936
  const specs = imp.specifiers.length > 0 ? ` { ${imp.specifiers.join(", ")} }` : "";
2535
2937
  console.log(
2536
- ` ${chalk4.dim("from")} ${chalk4.yellow(imp.source)}${specs}`
2938
+ ` ${chalk5.dim("from")} ${chalk5.yellow(imp.source)}${specs}`
2537
2939
  );
2538
2940
  }
2539
2941
  }
@@ -2542,64 +2944,64 @@ program.command("sdiff").description("Show semantic diff between two versions of
2542
2944
  const rootPath = resolveRepoRoot(opts.path);
2543
2945
  const engine = new TrellisVcsEngine({ rootPath });
2544
2946
  engine.open();
2545
- const { readFileSync: readFileSync5 } = __require("fs");
2546
- const oldContent = readFileSync5(resolve2(fileA), "utf-8");
2547
- const newContent = readFileSync5(resolve2(fileB), "utf-8");
2947
+ const { readFileSync: readFileSync7 } = __require("fs");
2948
+ const oldContent = readFileSync7(resolve2(fileA), "utf-8");
2949
+ const newContent = readFileSync7(resolve2(fileB), "utf-8");
2548
2950
  const patches = engine.semanticDiff(oldContent, newContent, fileA);
2549
2951
  if (patches.length === 0) {
2550
- console.log(chalk4.dim("No semantic differences."));
2952
+ console.log(chalk5.dim("No semantic differences."));
2551
2953
  return;
2552
2954
  }
2553
- console.log(chalk4.bold(`Semantic diff: ${fileA} \u2192 ${fileB}
2955
+ console.log(chalk5.bold(`Semantic diff: ${fileA} \u2192 ${fileB}
2554
2956
  `));
2555
- console.log(` ${chalk4.dim("Patches:")} ${patches.length}
2957
+ console.log(` ${chalk5.dim("Patches:")} ${patches.length}
2556
2958
  `);
2557
2959
  for (const patch of patches) {
2558
2960
  switch (patch.kind) {
2559
2961
  case "symbolAdd":
2560
2962
  console.log(
2561
- ` ${chalk4.green("+")} ${chalk4.green(`${patch.entity.kind}: ${patch.entity.name}`)}`
2963
+ ` ${chalk5.green("+")} ${chalk5.green(`${patch.entity.kind}: ${patch.entity.name}`)}`
2562
2964
  );
2563
2965
  break;
2564
2966
  case "symbolRemove":
2565
2967
  console.log(
2566
- ` ${chalk4.red("-")} ${chalk4.red(`${patch.entityName}`)} (removed)`
2968
+ ` ${chalk5.red("-")} ${chalk5.red(`${patch.entityName}`)} (removed)`
2567
2969
  );
2568
2970
  break;
2569
2971
  case "symbolModify":
2570
2972
  console.log(
2571
- ` ${chalk4.yellow("~")} ${chalk4.yellow(patch.entityName)} (modified)`
2973
+ ` ${chalk5.yellow("~")} ${chalk5.yellow(patch.entityName)} (modified)`
2572
2974
  );
2573
2975
  break;
2574
2976
  case "symbolRename":
2575
2977
  console.log(
2576
- ` ${chalk4.blue("\u2192")} ${chalk4.blue(`${patch.oldName} \u2192 ${patch.newName}`)} (renamed)`
2978
+ ` ${chalk5.blue("\u2192")} ${chalk5.blue(`${patch.oldName} \u2192 ${patch.newName}`)} (renamed)`
2577
2979
  );
2578
2980
  break;
2579
2981
  case "importAdd":
2580
2982
  console.log(
2581
- ` ${chalk4.green("+")} import from ${chalk4.yellow(patch.source)}`
2983
+ ` ${chalk5.green("+")} import from ${chalk5.yellow(patch.source)}`
2582
2984
  );
2583
2985
  break;
2584
2986
  case "importRemove":
2585
2987
  console.log(
2586
- ` ${chalk4.red("-")} import from ${chalk4.yellow(patch.source)}`
2988
+ ` ${chalk5.red("-")} import from ${chalk5.yellow(patch.source)}`
2587
2989
  );
2588
2990
  break;
2589
2991
  case "importModify":
2590
2992
  console.log(
2591
- ` ${chalk4.yellow("~")} import from ${chalk4.yellow(patch.source)} (specifiers changed)`
2993
+ ` ${chalk5.yellow("~")} import from ${chalk5.yellow(patch.source)} (specifiers changed)`
2592
2994
  );
2593
2995
  break;
2594
2996
  case "exportAdd":
2595
- console.log(` ${chalk4.green("+")} export ${chalk4.bold(patch.name)}`);
2997
+ console.log(` ${chalk5.green("+")} export ${chalk5.bold(patch.name)}`);
2596
2998
  break;
2597
2999
  case "exportRemove":
2598
- console.log(` ${chalk4.red("-")} export ${chalk4.bold(patch.name)}`);
3000
+ console.log(` ${chalk5.red("-")} export ${chalk5.bold(patch.name)}`);
2599
3001
  break;
2600
3002
  case "symbolMove":
2601
3003
  console.log(
2602
- ` ${chalk4.blue("\u2192")} ${chalk4.blue(patch.entityName)} moved ${patch.oldFile} \u2192 ${patch.newFile}`
3004
+ ` ${chalk5.blue("\u2192")} ${chalk5.blue(patch.entityName)} moved ${patch.oldFile} \u2192 ${patch.newFile}`
2603
3005
  );
2604
3006
  break;
2605
3007
  }
@@ -2614,18 +3016,18 @@ program.command("sync").description("Sync operations with another TrellisVCS rep
2614
3016
  engine.open();
2615
3017
  const ops = engine.getOps();
2616
3018
  if (action === "status" || !action) {
2617
- console.log(chalk4.bold("Sync Status\n"));
2618
- console.log(` ${chalk4.dim("Local ops:")} ${ops.length}`);
3019
+ console.log(chalk5.bold("Sync Status\n"));
3020
+ console.log(` ${chalk5.dim("Local ops:")} ${ops.length}`);
2619
3021
  console.log(
2620
- ` ${chalk4.dim("Head:")} ${ops.length > 0 ? ops[ops.length - 1].hash.slice(0, 16) + "\u2026" : "(none)"}`
3022
+ ` ${chalk5.dim("Head:")} ${ops.length > 0 ? ops[ops.length - 1].hash.slice(0, 16) + "\u2026" : "(none)"}`
2621
3023
  );
2622
- console.log(` ${chalk4.dim("Branch:")} ${engine.getCurrentBranch()}`);
3024
+ console.log(` ${chalk5.dim("Branch:")} ${engine.getCurrentBranch()}`);
2623
3025
  return;
2624
3026
  }
2625
3027
  if (action === "reconcile" && opts.remote) {
2626
3028
  const remotePath = resolve2(opts.remote);
2627
3029
  if (!TrellisVcsEngine.isRepo(remotePath)) {
2628
- console.error(chalk4.red(`Not a TrellisVCS repository: ${remotePath}`));
3030
+ console.error(chalk5.red(`Not a TrellisVCS repository: ${remotePath}`));
2629
3031
  process.exit(1);
2630
3032
  }
2631
3033
  const remoteEngine = new TrellisVcsEngine({ rootPath: remotePath });
@@ -2633,32 +3035,32 @@ program.command("sync").description("Sync operations with another TrellisVCS rep
2633
3035
  const remoteOps = remoteEngine.getOps();
2634
3036
  const { reconcile } = (init_reconciler(), __toCommonJS(reconciler_exports));
2635
3037
  const result = reconcile(ops, remoteOps);
2636
- console.log(chalk4.bold("Reconcile Result\n"));
2637
- console.log(` ${chalk4.dim("Merged ops:")} ${result.merged.length}`);
2638
- console.log(` ${chalk4.dim("Unique local:")} ${result.uniqueToA.length}`);
3038
+ console.log(chalk5.bold("Reconcile Result\n"));
3039
+ console.log(` ${chalk5.dim("Merged ops:")} ${result.merged.length}`);
3040
+ console.log(` ${chalk5.dim("Unique local:")} ${result.uniqueToA.length}`);
2639
3041
  console.log(
2640
- ` ${chalk4.dim("Unique remote:")} ${result.uniqueToB.length}`
3042
+ ` ${chalk5.dim("Unique remote:")} ${result.uniqueToB.length}`
2641
3043
  );
2642
3044
  console.log(
2643
- ` ${chalk4.dim("Fork point:")} ${result.forkPoint?.slice(0, 16) ?? "(none)"}`
3045
+ ` ${chalk5.dim("Fork point:")} ${result.forkPoint?.slice(0, 16) ?? "(none)"}`
2644
3046
  );
2645
3047
  console.log(
2646
- ` ${chalk4.dim("Clean:")} ${result.clean ? chalk4.green("yes") : chalk4.red("no")}`
3048
+ ` ${chalk5.dim("Clean:")} ${result.clean ? chalk5.green("yes") : chalk5.red("no")}`
2647
3049
  );
2648
3050
  if (result.conflicts.length > 0) {
2649
3051
  console.log();
2650
- console.log(chalk4.bold("Conflicts:"));
3052
+ console.log(chalk5.bold("Conflicts:"));
2651
3053
  for (const c of result.conflicts) {
2652
- console.log(` ${chalk4.red("\u2717")} ${c.filePath}: ${c.reason}`);
3054
+ console.log(` ${chalk5.red("\u2717")} ${c.filePath}: ${c.reason}`);
2653
3055
  }
2654
3056
  }
2655
3057
  return;
2656
3058
  }
2657
3059
  console.log(
2658
- chalk4.dim("Use --remote <path> with reconcile to compare repositories.")
3060
+ chalk5.dim("Use --remote <path> with reconcile to compare repositories.")
2659
3061
  );
2660
3062
  console.log(
2661
- chalk4.dim("Full peer sync requires a transport layer (coming soon).")
3063
+ chalk5.dim("Full peer sync requires a transport layer (coming soon).")
2662
3064
  );
2663
3065
  });
2664
3066
  program.command("garden").description("Explore the Idea Garden \u2014 abandoned work clusters").argument(
@@ -2671,66 +3073,66 @@ program.command("garden").description("Explore the Idea Garden \u2014 abandoned
2671
3073
  const garden = engine.garden();
2672
3074
  if (action === "stats") {
2673
3075
  const s = garden.stats();
2674
- console.log(chalk4.bold("Idea Garden Stats\n"));
2675
- console.log(` ${chalk4.dim("Total clusters:")} ${s.total}`);
2676
- console.log(` ${chalk4.dim("Abandoned:")} ${s.abandoned}`);
2677
- console.log(` ${chalk4.dim("Draft:")} ${s.draft}`);
2678
- console.log(` ${chalk4.dim("Revived:")} ${s.revived}`);
2679
- console.log(` ${chalk4.dim("Total ops:")} ${s.totalOps}`);
2680
- console.log(` ${chalk4.dim("Total files:")} ${s.totalFiles}`);
3076
+ console.log(chalk5.bold("Idea Garden Stats\n"));
3077
+ console.log(` ${chalk5.dim("Total clusters:")} ${s.total}`);
3078
+ console.log(` ${chalk5.dim("Abandoned:")} ${s.abandoned}`);
3079
+ console.log(` ${chalk5.dim("Draft:")} ${s.draft}`);
3080
+ console.log(` ${chalk5.dim("Revived:")} ${s.revived}`);
3081
+ console.log(` ${chalk5.dim("Total ops:")} ${s.totalOps}`);
3082
+ console.log(` ${chalk5.dim("Total files:")} ${s.totalFiles}`);
2681
3083
  return;
2682
3084
  }
2683
3085
  if (action === "show") {
2684
3086
  if (!id) {
2685
- console.error(chalk4.red("Usage: trellis garden show <cluster-id>"));
3087
+ console.error(chalk5.red("Usage: trellis garden show <cluster-id>"));
2686
3088
  process.exit(1);
2687
3089
  }
2688
3090
  const cluster = garden.getCluster(id);
2689
3091
  if (!cluster) {
2690
- console.error(chalk4.red(`Cluster not found: ${id}`));
3092
+ console.error(chalk5.red(`Cluster not found: ${id}`));
2691
3093
  process.exit(1);
2692
3094
  }
2693
- console.log(chalk4.bold(`Cluster: ${cluster.id}
3095
+ console.log(chalk5.bold(`Cluster: ${cluster.id}
2694
3096
  `));
2695
3097
  console.log(
2696
- ` ${chalk4.dim("Status:")} ${formatClusterStatus(cluster.status)}`
3098
+ ` ${chalk5.dim("Status:")} ${formatClusterStatus(cluster.status)}`
2697
3099
  );
2698
- console.log(` ${chalk4.dim("Detected by:")} ${cluster.detectedBy}`);
2699
- console.log(` ${chalk4.dim("Created:")} ${cluster.createdAt}`);
2700
- console.log(` ${chalk4.dim("Abandoned:")} ${cluster.abandonedAt}`);
2701
- console.log(` ${chalk4.dim("Ops:")} ${cluster.ops.length}`);
3100
+ console.log(` ${chalk5.dim("Detected by:")} ${cluster.detectedBy}`);
3101
+ console.log(` ${chalk5.dim("Created:")} ${cluster.createdAt}`);
3102
+ console.log(` ${chalk5.dim("Abandoned:")} ${cluster.abandonedAt}`);
3103
+ console.log(` ${chalk5.dim("Ops:")} ${cluster.ops.length}`);
2702
3104
  console.log(
2703
- ` ${chalk4.dim("Files:")} ${cluster.affectedFiles.join(", ")}`
3105
+ ` ${chalk5.dim("Files:")} ${cluster.affectedFiles.join(", ")}`
2704
3106
  );
2705
3107
  if (cluster.estimatedIntent) {
2706
- console.log(` ${chalk4.dim("Intent:")} ${cluster.estimatedIntent}`);
3108
+ console.log(` ${chalk5.dim("Intent:")} ${cluster.estimatedIntent}`);
2707
3109
  }
2708
3110
  console.log();
2709
- console.log(chalk4.bold("Operations:"));
3111
+ console.log(chalk5.bold("Operations:"));
2710
3112
  for (const op of cluster.ops.slice(0, 20)) {
2711
3113
  console.log(
2712
- ` ${formatOpKind(op.kind)} ${chalk4.dim(op.hash.slice(0, 12))} ${op.vcs?.filePath ?? ""}`
3114
+ ` ${formatOpKind(op.kind)} ${chalk5.dim(op.hash.slice(0, 12))} ${op.vcs?.filePath ?? ""}`
2713
3115
  );
2714
3116
  }
2715
3117
  if (cluster.ops.length > 20) {
2716
- console.log(chalk4.dim(` ... +${cluster.ops.length - 20} more`));
3118
+ console.log(chalk5.dim(` ... +${cluster.ops.length - 20} more`));
2717
3119
  }
2718
3120
  return;
2719
3121
  }
2720
3122
  if (action === "revive") {
2721
3123
  if (!id) {
2722
- console.error(chalk4.red("Usage: trellis garden revive <cluster-id>"));
3124
+ console.error(chalk5.red("Usage: trellis garden revive <cluster-id>"));
2723
3125
  process.exit(1);
2724
3126
  }
2725
3127
  const ops = garden.revive(id);
2726
3128
  if (!ops) {
2727
- console.error(chalk4.red(`Cluster not found: ${id}`));
3129
+ console.error(chalk5.red(`Cluster not found: ${id}`));
2728
3130
  process.exit(1);
2729
3131
  }
2730
- console.log(chalk4.green(`\u2713 Cluster revived: ${id}`));
2731
- console.log(` ${chalk4.dim("Ops to replay:")} ${ops.length}`);
3132
+ console.log(chalk5.green(`\u2713 Cluster revived: ${id}`));
3133
+ console.log(` ${chalk5.dim("Ops to replay:")} ${ops.length}`);
2732
3134
  console.log(
2733
- ` ${chalk4.dim("Files:")} ${[...new Set(ops.filter((o) => o.vcs?.filePath).map((o) => o.vcs.filePath))].join(", ")}`
3135
+ ` ${chalk5.dim("Files:")} ${[...new Set(ops.filter((o) => o.vcs?.filePath).map((o) => o.vcs.filePath))].join(", ")}`
2734
3136
  );
2735
3137
  return;
2736
3138
  }
@@ -2742,10 +3144,10 @@ program.command("garden").description("Explore the Idea Garden \u2014 abandoned
2742
3144
  limit: opts.limit
2743
3145
  });
2744
3146
  if (results.length === 0) {
2745
- console.log(chalk4.dim("No matching clusters found."));
3147
+ console.log(chalk5.dim("No matching clusters found."));
2746
3148
  return;
2747
3149
  }
2748
- console.log(chalk4.bold(`Search results (${results.length})
3150
+ console.log(chalk5.bold(`Search results (${results.length})
2749
3151
  `));
2750
3152
  for (const c of results) {
2751
3153
  printClusterSummary(c);
@@ -2759,10 +3161,10 @@ program.command("garden").description("Explore the Idea Garden \u2014 abandoned
2759
3161
  limit: opts.limit
2760
3162
  });
2761
3163
  if (clusters.length === 0) {
2762
- console.log(chalk4.dim("No idea clusters found. The garden is empty."));
3164
+ console.log(chalk5.dim("No idea clusters found. The garden is empty."));
2763
3165
  return;
2764
3166
  }
2765
- console.log(chalk4.bold(`Idea Garden (${clusters.length} clusters)
3167
+ console.log(chalk5.bold(`Idea Garden (${clusters.length} clusters)
2766
3168
  `));
2767
3169
  for (const c of clusters) {
2768
3170
  printClusterSummary(c);
@@ -2771,67 +3173,67 @@ program.command("garden").description("Explore the Idea Garden \u2014 abandoned
2771
3173
  function formatClusterStatus(status) {
2772
3174
  switch (status) {
2773
3175
  case "abandoned":
2774
- return chalk4.yellow("abandoned");
3176
+ return chalk5.yellow("abandoned");
2775
3177
  case "draft":
2776
- return chalk4.blue("draft");
3178
+ return chalk5.blue("draft");
2777
3179
  case "revived":
2778
- return chalk4.green("revived");
3180
+ return chalk5.green("revived");
2779
3181
  default:
2780
- return chalk4.dim(status);
3182
+ return chalk5.dim(status);
2781
3183
  }
2782
3184
  }
2783
3185
  function printClusterSummary(c) {
2784
3186
  console.log(
2785
- ` ${chalk4.cyan("\u2740")} ${chalk4.bold(c.id)} ${formatClusterStatus(c.status)} ${chalk4.dim(c.detectedBy)}`
3187
+ ` ${chalk5.cyan("\u2740")} ${chalk5.bold(c.id)} ${formatClusterStatus(c.status)} ${chalk5.dim(c.detectedBy)}`
2786
3188
  );
2787
3189
  console.log(
2788
- ` ${chalk4.dim("Ops:")} ${c.ops.length} ${chalk4.dim("Files:")} ${c.affectedFiles.slice(0, 3).join(", ")}${c.affectedFiles.length > 3 ? ` +${c.affectedFiles.length - 3}` : ""}`
3190
+ ` ${chalk5.dim("Ops:")} ${c.ops.length} ${chalk5.dim("Files:")} ${c.affectedFiles.slice(0, 3).join(", ")}${c.affectedFiles.length > 3 ? ` +${c.affectedFiles.length - 3}` : ""}`
2789
3191
  );
2790
3192
  console.log(
2791
- ` ${chalk4.dim("Created:")} ${formatRelativeTime2(c.createdAt)} ${chalk4.dim("Abandoned:")} ${formatRelativeTime2(c.abandonedAt)}`
3193
+ ` ${chalk5.dim("Created:")} ${formatRelativeTime2(c.createdAt)} ${chalk5.dim("Abandoned:")} ${formatRelativeTime2(c.abandonedAt)}`
2792
3194
  );
2793
3195
  console.log();
2794
3196
  }
2795
3197
  function formatIssueStatus(status) {
2796
3198
  switch (status) {
2797
3199
  case "backlog":
2798
- return chalk4.gray("backlog");
3200
+ return chalk5.gray("backlog");
2799
3201
  case "queue":
2800
- return chalk4.blue("queue");
3202
+ return chalk5.blue("queue");
2801
3203
  case "in_progress":
2802
- return chalk4.yellow("in_progress");
3204
+ return chalk5.yellow("in_progress");
2803
3205
  case "paused":
2804
- return chalk4.magenta("paused");
3206
+ return chalk5.magenta("paused");
2805
3207
  case "closed":
2806
- return chalk4.green("closed");
3208
+ return chalk5.green("closed");
2807
3209
  default:
2808
- return chalk4.dim(status ?? "unknown");
3210
+ return chalk5.dim(status ?? "unknown");
2809
3211
  }
2810
3212
  }
2811
3213
  function formatPriority(p) {
2812
3214
  switch (p) {
2813
3215
  case "critical":
2814
- return chalk4.red("critical");
3216
+ return chalk5.red("critical");
2815
3217
  case "high":
2816
- return chalk4.yellow("high");
3218
+ return chalk5.yellow("high");
2817
3219
  case "medium":
2818
- return chalk4.cyan("medium");
3220
+ return chalk5.cyan("medium");
2819
3221
  case "low":
2820
- return chalk4.dim("low");
3222
+ return chalk5.dim("low");
2821
3223
  default:
2822
- return chalk4.dim(p ?? "");
3224
+ return chalk5.dim(p ?? "");
2823
3225
  }
2824
3226
  }
2825
3227
  function formatCriterionStatus(status) {
2826
3228
  switch (status) {
2827
3229
  case "passed":
2828
- return chalk4.green("\u2713 passed");
3230
+ return chalk5.green("\u2713 passed");
2829
3231
  case "failed":
2830
- return chalk4.red("\u2717 failed");
3232
+ return chalk5.red("\u2717 failed");
2831
3233
  case "pending":
2832
- return chalk4.dim("\u25CB pending");
3234
+ return chalk5.dim("\u25CB pending");
2833
3235
  default:
2834
- return chalk4.dim(status ?? "pending");
3236
+ return chalk5.dim(status ?? "pending");
2835
3237
  }
2836
3238
  }
2837
3239
  var issueCmd = program.command("issue").description("Manage issues (task tracking)");
@@ -2867,18 +3269,18 @@ issueCmd.command("create").description("Create a new issue").requiredOption("-t,
2867
3269
  criteria
2868
3270
  });
2869
3271
  const issueId = op.vcs?.issueId;
2870
- console.log(chalk4.green(`\u2713 Issue created: ${chalk4.bold(issueId)}`));
2871
- console.log(` ${chalk4.dim("Title:")} ${opts.title}`);
2872
- console.log(` ${chalk4.dim("Priority:")} ${formatPriority(opts.priority)}`);
3272
+ console.log(chalk5.green(`\u2713 Issue created: ${chalk5.bold(issueId)}`));
3273
+ console.log(` ${chalk5.dim("Title:")} ${opts.title}`);
3274
+ console.log(` ${chalk5.dim("Priority:")} ${formatPriority(opts.priority)}`);
2873
3275
  if (labels) {
2874
- console.log(` ${chalk4.dim("Labels:")} ${labels.join(", ")}`);
3276
+ console.log(` ${chalk5.dim("Labels:")} ${labels.join(", ")}`);
2875
3277
  }
2876
3278
  if (opts.parent) {
2877
- console.log(` ${chalk4.dim("Parent:")} ${opts.parent}`);
3279
+ console.log(` ${chalk5.dim("Parent:")} ${opts.parent}`);
2878
3280
  }
2879
3281
  if (criteria) {
2880
3282
  console.log(
2881
- ` ${chalk4.dim("Criteria:")} ${criteria.length} acceptance criteria`
3283
+ ` ${chalk5.dim("Criteria:")} ${criteria.length} acceptance criteria`
2882
3284
  );
2883
3285
  }
2884
3286
  });
@@ -2896,8 +3298,8 @@ issueCmd.command("list").description("List issues").option(
2896
3298
  parentId: opts.parent
2897
3299
  });
2898
3300
  if (opts.remote || opts.all) {
2899
- const { RemoteManager } = await import("../remote-manager-ODE3T2KR.js");
2900
- const remoteManager = new RemoteManager(join6(rootPath, ".trellis"));
3301
+ const { RemoteManager } = await import("../remote-manager-6ERQUBSL.js");
3302
+ const remoteManager = new RemoteManager(join7(rootPath, ".trellis"));
2901
3303
  if (opts.all) {
2902
3304
  const remotes = remoteManager.listRemotes();
2903
3305
  const remoteIssues = issues.filter(
@@ -2917,7 +3319,7 @@ issueCmd.command("list").description("List issues").option(
2917
3319
  }
2918
3320
  }
2919
3321
  if (issues.length === 0) {
2920
- console.log(chalk4.dim("No issues found."));
3322
+ console.log(chalk5.dim("No issues found."));
2921
3323
  return;
2922
3324
  }
2923
3325
  const groupedIssues = opts.all || opts.remote ? issues.reduce(
@@ -2930,24 +3332,24 @@ issueCmd.command("list").description("List issues").option(
2930
3332
  },
2931
3333
  {}
2932
3334
  ) : { local: issues };
2933
- console.log(chalk4.bold(`Issues (${issues.length})
3335
+ console.log(chalk5.bold(`Issues (${issues.length})
2934
3336
  `));
2935
3337
  for (const [remote, remoteIssues] of Object.entries(groupedIssues)) {
2936
3338
  if (opts.all || opts.remote) {
2937
- console.log(chalk4.cyan(`
3339
+ console.log(chalk5.cyan(`
2938
3340
  ${remote === "local" ? "Local" : remote}:`));
2939
3341
  }
2940
3342
  for (const issue of remoteIssues) {
2941
- const labels = (issue.labels?.length ?? 0) > 0 ? chalk4.dim(` [${issue.labels.join(",")}]`) : "";
2942
- const assignee = issue.assignee ? chalk4.dim(` \u2192 ${issue.assignee}`) : "";
2943
- const parent = issue.parentId ? chalk4.dim(` \u2190 ${issue.parentId}`) : "";
2944
- const blocked = issue.isBlocked ? chalk4.yellow(" \u{1F512} blocked") : "";
2945
- const criteria = (issue.criteria?.length ?? 0) > 0 ? chalk4.dim(
3343
+ const labels = (issue.labels?.length ?? 0) > 0 ? chalk5.dim(` [${issue.labels.join(",")}]`) : "";
3344
+ const assignee = issue.assignee ? chalk5.dim(` \u2192 ${issue.assignee}`) : "";
3345
+ const parent = issue.parentId ? chalk5.dim(` \u2190 ${issue.parentId}`) : "";
3346
+ const blocked = issue.isBlocked ? chalk5.yellow(" \u{1F512} blocked") : "";
3347
+ const criteria = (issue.criteria?.length ?? 0) > 0 ? chalk5.dim(
2946
3348
  ` (${issue.criteria.filter((c) => c.status === "passed").length}/${issue.criteria.length} AC)`
2947
3349
  ) : "";
2948
3350
  const displayId = opts.all || opts.remote ? issue.id : issue.id;
2949
3351
  console.log(
2950
- ` ${formatPriority(issue.priority)} ${chalk4.bold(displayId)} ${formatIssueStatus(issue.status)} ${issue.title ?? ""}${labels}${assignee}${parent}${blocked}${criteria}`
3352
+ ` ${formatPriority(issue.priority)} ${chalk5.bold(displayId)} ${formatIssueStatus(issue.status)} ${issue.title ?? ""}${labels}${assignee}${parent}${blocked}${criteria}`
2951
3353
  );
2952
3354
  }
2953
3355
  }
@@ -2960,61 +3362,61 @@ issueCmd.command("show").description("Show issue details").argument("<id>", "Iss
2960
3362
  if (!issue) {
2961
3363
  throw new Error(`Issue not found: ${id}`);
2962
3364
  }
2963
- console.log(chalk4.bold(`${issue.id}: ${issue.title ?? "(untitled)"}
3365
+ console.log(chalk5.bold(`${issue.id}: ${issue.title ?? "(untitled)"}
2964
3366
  `));
2965
3367
  if (issue.description) {
2966
- console.log(` ${chalk4.dim(issue.description)}
3368
+ console.log(` ${chalk5.dim(issue.description)}
2967
3369
  `);
2968
3370
  }
2969
3371
  console.log(
2970
- ` ${chalk4.dim("Status:")} ${formatIssueStatus(issue.status)}`
3372
+ ` ${chalk5.dim("Status:")} ${formatIssueStatus(issue.status)}`
2971
3373
  );
2972
3374
  console.log(
2973
- ` ${chalk4.dim("Priority:")} ${formatPriority(issue.priority)}`
3375
+ ` ${chalk5.dim("Priority:")} ${formatPriority(issue.priority)}`
2974
3376
  );
2975
3377
  if ((issue.labels?.length ?? 0) > 0) {
2976
- console.log(` ${chalk4.dim("Labels:")} ${issue.labels.join(", ")}`);
3378
+ console.log(` ${chalk5.dim("Labels:")} ${issue.labels.join(", ")}`);
2977
3379
  }
2978
3380
  if (issue.assignee) {
2979
- console.log(` ${chalk4.dim("Assignee:")} ${issue.assignee}`);
3381
+ console.log(` ${chalk5.dim("Assignee:")} ${issue.assignee}`);
2980
3382
  }
2981
3383
  if (issue.parentId) {
2982
- console.log(` ${chalk4.dim("Parent:")} ${issue.parentId}`);
3384
+ console.log(` ${chalk5.dim("Parent:")} ${issue.parentId}`);
2983
3385
  }
2984
3386
  if (issue.branchName) {
2985
- console.log(` ${chalk4.dim("Branch:")} ${issue.branchName}`);
3387
+ console.log(` ${chalk5.dim("Branch:")} ${issue.branchName}`);
2986
3388
  }
2987
3389
  if ((issue.blockedBy?.length ?? 0) > 0) {
2988
3390
  console.log(
2989
- ` ${chalk4.dim("Blocked by:")} ${issue.blockedBy.map((b) => chalk4.yellow(b)).join(", ")}`
3391
+ ` ${chalk5.dim("Blocked by:")} ${issue.blockedBy.map((b) => chalk5.yellow(b)).join(", ")}`
2990
3392
  );
2991
3393
  }
2992
3394
  if ((issue.blocking?.length ?? 0) > 0) {
2993
3395
  console.log(
2994
- ` ${chalk4.dim("Blocking:")} ${issue.blocking.map((b) => chalk4.cyan(b)).join(", ")}`
3396
+ ` ${chalk5.dim("Blocking:")} ${issue.blocking.map((b) => chalk5.cyan(b)).join(", ")}`
2995
3397
  );
2996
3398
  }
2997
3399
  if (issue.createdAt) {
2998
3400
  console.log(
2999
- ` ${chalk4.dim("Created:")} ${formatRelativeTime2(issue.createdAt)}`
3401
+ ` ${chalk5.dim("Created:")} ${formatRelativeTime2(issue.createdAt)}`
3000
3402
  );
3001
3403
  }
3002
3404
  if (issue.startedAt) {
3003
3405
  console.log(
3004
- ` ${chalk4.dim("Started:")} ${formatRelativeTime2(issue.startedAt)}`
3406
+ ` ${chalk5.dim("Started:")} ${formatRelativeTime2(issue.startedAt)}`
3005
3407
  );
3006
3408
  }
3007
3409
  if (issue.closedAt) {
3008
3410
  console.log(
3009
- ` ${chalk4.dim("Closed:")} ${formatRelativeTime2(issue.closedAt)}`
3411
+ ` ${chalk5.dim("Closed:")} ${formatRelativeTime2(issue.closedAt)}`
3010
3412
  );
3011
3413
  }
3012
3414
  if ((issue.criteria?.length ?? 0) > 0) {
3013
3415
  console.log(`
3014
- ${chalk4.bold("Acceptance Criteria:")}`);
3416
+ ${chalk5.bold("Acceptance Criteria:")}`);
3015
3417
  for (const c of issue.criteria) {
3016
3418
  const desc = c.description ?? c.id;
3017
- const cmd = c.command ? chalk4.dim(` (${c.command})`) : "";
3419
+ const cmd = c.command ? chalk5.dim(` (${c.command})`) : "";
3018
3420
  console.log(` ${formatCriterionStatus(c.status)} ${desc}${cmd}`);
3019
3421
  }
3020
3422
  }
@@ -3025,17 +3427,17 @@ issueCmd.command("start").description("Start working on an issue (creates branch
3025
3427
  engine.open();
3026
3428
  await engine.startIssue(id, { lane: !opts.noLane });
3027
3429
  const issue = engine.getIssue(id);
3028
- console.log(chalk4.green(`\u2713 Started issue ${chalk4.bold(id)}`));
3430
+ console.log(chalk5.green(`\u2713 Started issue ${chalk5.bold(id)}`));
3029
3431
  if (issue?.branchName) {
3030
- console.log(` ${chalk4.dim("Branch:")} ${issue.branchName}`);
3432
+ console.log(` ${chalk5.dim("Branch:")} ${issue.branchName}`);
3031
3433
  }
3032
3434
  if (issue?.assignee) {
3033
- console.log(` ${chalk4.dim("Assignee:")} ${issue.assignee}`);
3435
+ console.log(` ${chalk5.dim("Assignee:")} ${issue.assignee}`);
3034
3436
  }
3035
3437
  const laneId = engine.getActiveLaneId();
3036
3438
  if (laneId) {
3037
- console.log(` ${chalk4.dim("Lane:")} ${laneId}`);
3038
- console.log(chalk4.dim(` export TRELLIS_LANE_ID=${laneId}`));
3439
+ console.log(` ${chalk5.dim("Lane:")} ${laneId}`);
3440
+ console.log(chalk5.dim(` export TRELLIS_LANE_ID=${laneId}`));
3039
3441
  }
3040
3442
  });
3041
3443
  issueCmd.command("pause").description("Pause an in-progress issue (switches to default branch)").argument("<id>", "Issue ID").requiredOption(
@@ -3046,9 +3448,9 @@ issueCmd.command("pause").description("Pause an in-progress issue (switches to d
3046
3448
  const engine = new TrellisVcsEngine({ rootPath });
3047
3449
  engine.open();
3048
3450
  await engine.pauseIssue(id, opts.note);
3049
- console.log(chalk4.yellow(`\u23F8 Paused issue ${chalk4.bold(id)}`));
3050
- console.log(` ${chalk4.dim("Note:")} ${opts.note}`);
3051
- console.log(` ${chalk4.dim("Switched to:")} ${engine.getCurrentBranch()}`);
3451
+ console.log(chalk5.yellow(`\u23F8 Paused issue ${chalk5.bold(id)}`));
3452
+ console.log(` ${chalk5.dim("Note:")} ${opts.note}`);
3453
+ console.log(` ${chalk5.dim("Switched to:")} ${engine.getCurrentBranch()}`);
3052
3454
  });
3053
3455
  issueCmd.command("resume").description("Resume a paused issue (switches to issue branch and lane)").argument("<id>", "Issue ID").option("--no-lane", "Do not re-enter linked agent lane").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
3054
3456
  const rootPath = resolveRepoRoot(opts.path);
@@ -3056,13 +3458,13 @@ issueCmd.command("resume").description("Resume a paused issue (switches to issue
3056
3458
  engine.open();
3057
3459
  await engine.resumeIssue(id, { lane: !opts.noLane });
3058
3460
  const issue = engine.getIssue(id);
3059
- console.log(chalk4.green(`\u25B6 Resumed issue ${chalk4.bold(id)}`));
3461
+ console.log(chalk5.green(`\u25B6 Resumed issue ${chalk5.bold(id)}`));
3060
3462
  if (issue?.branchName) {
3061
- console.log(` ${chalk4.dim("Branch:")} ${issue.branchName}`);
3463
+ console.log(` ${chalk5.dim("Branch:")} ${issue.branchName}`);
3062
3464
  }
3063
3465
  const laneId = engine.getActiveLaneId();
3064
3466
  if (laneId) {
3065
- console.log(` ${chalk4.dim("Lane:")} ${laneId}`);
3467
+ console.log(` ${chalk5.dim("Lane:")} ${laneId}`);
3066
3468
  }
3067
3469
  });
3068
3470
  issueCmd.command("triage").description("Move a backlog issue to queue (ready to start)").argument("<id>", "Issue ID").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
@@ -3070,7 +3472,7 @@ issueCmd.command("triage").description("Move a backlog issue to queue (ready to
3070
3472
  const engine = new TrellisVcsEngine({ rootPath });
3071
3473
  engine.open();
3072
3474
  await engine.triageIssue(id);
3073
- console.log(chalk4.green(`\u2713 Triaged ${chalk4.bold(id)} \u2192 queue`));
3475
+ console.log(chalk5.green(`\u2713 Triaged ${chalk5.bold(id)} \u2192 queue`));
3074
3476
  });
3075
3477
  issueCmd.command("update").description("Update issue metadata").argument("<id>", "Issue ID").option("--title <title>", "New title").option("-d, --desc <description>", "Short description").option("--description <description>", "Alias for --desc").option(
3076
3478
  "--status <status>",
@@ -3100,31 +3502,31 @@ issueCmd.command("update").description("Update issue metadata").argument("<id>",
3100
3502
  );
3101
3503
  }
3102
3504
  await engine.updateIssue(id, updates);
3103
- console.log(chalk4.green(`\u2713 Updated ${chalk4.bold(id)}`));
3505
+ console.log(chalk5.green(`\u2713 Updated ${chalk5.bold(id)}`));
3104
3506
  });
3105
3507
  issueCmd.command("describe").description("Set an issue description").argument("<id>", "Issue ID").argument("<description>", "Short description text").option("-p, --path <path>", "Repository path", ".").action(async (id, description, opts) => {
3106
3508
  const rootPath = resolveRepoRoot(opts.path);
3107
3509
  const engine = new TrellisVcsEngine({ rootPath });
3108
3510
  engine.open();
3109
3511
  await engine.updateIssue(id, { description });
3110
- console.log(chalk4.green(`\u2713 Description set for ${chalk4.bold(id)}`));
3512
+ console.log(chalk5.green(`\u2713 Description set for ${chalk5.bold(id)}`));
3111
3513
  });
3112
3514
  issueCmd.command("assign").description("Assign an issue to an agent").argument("<id>", "Issue ID").requiredOption("--to <agentId>", "Agent ID to assign").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
3113
3515
  const rootPath = resolveRepoRoot(opts.path);
3114
3516
  const engine = new TrellisVcsEngine({ rootPath });
3115
3517
  engine.open();
3116
3518
  await engine.assignIssue(id, opts.to);
3117
- console.log(chalk4.green(`\u2713 Assigned ${chalk4.bold(id)} \u2192 ${opts.to}`));
3519
+ console.log(chalk5.green(`\u2713 Assigned ${chalk5.bold(id)} \u2192 ${opts.to}`));
3118
3520
  });
3119
3521
  issueCmd.command("ac").description("Add acceptance criterion to an issue").argument("<id>", "Issue ID").argument("<description>", "Criterion description").option("--test <command>", "Shell command to validate (exit 0 = pass)").option("-p, --path <path>", "Repository path", ".").action(async (id, description, opts) => {
3120
3522
  const rootPath = resolveRepoRoot(opts.path);
3121
3523
  const engine = new TrellisVcsEngine({ rootPath });
3122
3524
  engine.open();
3123
3525
  await engine.addCriterion(id, description, opts.test);
3124
- const cmdNote = opts.test ? chalk4.dim(` (test: ${opts.test})`) : "";
3526
+ const cmdNote = opts.test ? chalk5.dim(` (test: ${opts.test})`) : "";
3125
3527
  console.log(
3126
- chalk4.green(
3127
- `\u2713 Added criterion to ${chalk4.bold(id)}: ${description}${cmdNote}`
3528
+ chalk5.green(
3529
+ `\u2713 Added criterion to ${chalk5.bold(id)}: ${description}${cmdNote}`
3128
3530
  )
3129
3531
  );
3130
3532
  });
@@ -3134,8 +3536,8 @@ issueCmd.command("ac-pass").description("Manually mark an acceptance criterion a
3134
3536
  engine.open();
3135
3537
  await engine.setCriterionStatus(id, parseInt(index, 10), "passed");
3136
3538
  console.log(
3137
- chalk4.green(
3138
- `\u2713 Criterion #${index} on ${chalk4.bold(id)} marked as passed`
3539
+ chalk5.green(
3540
+ `\u2713 Criterion #${index} on ${chalk5.bold(id)} marked as passed`
3139
3541
  )
3140
3542
  );
3141
3543
  });
@@ -3145,31 +3547,31 @@ issueCmd.command("ac-fail").description("Manually mark an acceptance criterion a
3145
3547
  engine.open();
3146
3548
  await engine.setCriterionStatus(id, parseInt(index, 10), "failed");
3147
3549
  console.log(
3148
- chalk4.red(`\u2717 Criterion #${index} on ${chalk4.bold(id)} marked as failed`)
3550
+ chalk5.red(`\u2717 Criterion #${index} on ${chalk5.bold(id)} marked as failed`)
3149
3551
  );
3150
3552
  });
3151
3553
  issueCmd.command("check").description("Run acceptance criteria for an issue").argument("<id>", "Issue ID").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
3152
3554
  const rootPath = resolveRepoRoot(opts.path);
3153
3555
  const engine = new TrellisVcsEngine({ rootPath });
3154
3556
  engine.open();
3155
- console.log(chalk4.bold(`Running criteria for ${id}...
3557
+ console.log(chalk5.bold(`Running criteria for ${id}...
3156
3558
  `));
3157
3559
  const results = await engine.runCriteria(id);
3158
3560
  if (results.length === 0) {
3159
- console.log(chalk4.dim("No acceptance criteria defined."));
3561
+ console.log(chalk5.dim("No acceptance criteria defined."));
3160
3562
  return;
3161
3563
  }
3162
3564
  for (const r of results) {
3163
3565
  const desc = r.description ?? r.id;
3164
- const statusStr = r.status === "passed" ? chalk4.green("\u2713 PASSED") : r.status === "failed" ? chalk4.red("\u2717 FAILED") : chalk4.dim("\u25CB SKIPPED");
3566
+ const statusStr = r.status === "passed" ? chalk5.green("\u2713 PASSED") : r.status === "failed" ? chalk5.red("\u2717 FAILED") : chalk5.dim("\u25CB SKIPPED");
3165
3567
  console.log(` ${statusStr} ${desc}`);
3166
3568
  if (r.command) {
3167
- console.log(` ${chalk4.dim("$")} ${r.command}`);
3569
+ console.log(` ${chalk5.dim("$")} ${r.command}`);
3168
3570
  }
3169
3571
  if (r.output && r.status === "failed") {
3170
3572
  const lines = r.output.split("\n").slice(0, 5);
3171
3573
  for (const line of lines) {
3172
- console.log(` ${chalk4.dim(line)}`);
3574
+ console.log(` ${chalk5.dim(line)}`);
3173
3575
  }
3174
3576
  }
3175
3577
  }
@@ -3178,12 +3580,12 @@ issueCmd.command("check").description("Run acceptance criteria for an issue").ar
3178
3580
  console.log();
3179
3581
  if (passed === total) {
3180
3582
  console.log(
3181
- chalk4.green(
3583
+ chalk5.green(
3182
3584
  `All ${total} criteria passed. Close with: trellis issue close ${id} --confirm`
3183
3585
  )
3184
3586
  );
3185
3587
  } else {
3186
- console.log(chalk4.yellow(`${passed}/${total} criteria passing.`));
3588
+ console.log(chalk5.yellow(`${passed}/${total} criteria passing.`));
3187
3589
  }
3188
3590
  });
3189
3591
  issueCmd.command("close").description("Close an issue (requires all criteria pass + --confirm)").argument("<id>", "Issue ID").option("--confirm", "Confirm closure after criteria pass").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
@@ -3193,7 +3595,7 @@ issueCmd.command("close").description("Close an issue (requires all criteria pas
3193
3595
  const lane = engine.findLaneForIssue(id);
3194
3596
  if (lane && lane.status === "active" && engine.getLaneOpCount(lane.id) > 0) {
3195
3597
  console.log(
3196
- chalk4.yellow(
3598
+ chalk5.yellow(
3197
3599
  `\u26A0 Lane ${lane.id} has unpromoted ops \u2014 promote before close when W3 lands (trellis lane promote)`
3198
3600
  )
3199
3601
  );
@@ -3201,7 +3603,7 @@ issueCmd.command("close").description("Close an issue (requires all criteria pas
3201
3603
  try {
3202
3604
  const result = await engine.closeIssue(id, { confirm: opts.confirm });
3203
3605
  if (!result.op) {
3204
- console.log(chalk4.bold(`Criteria status for ${id}:
3606
+ console.log(chalk5.bold(`Criteria status for ${id}:
3205
3607
  `));
3206
3608
  for (const r of result.criteriaResults) {
3207
3609
  console.log(
@@ -3210,15 +3612,15 @@ issueCmd.command("close").description("Close an issue (requires all criteria pas
3210
3612
  }
3211
3613
  console.log();
3212
3614
  console.log(
3213
- chalk4.yellow(
3615
+ chalk5.yellow(
3214
3616
  `All criteria pass. Re-run with --confirm to close: trellis issue close ${id} --confirm`
3215
3617
  )
3216
3618
  );
3217
3619
  return;
3218
3620
  }
3219
- console.log(chalk4.green(`\u2713 Issue ${chalk4.bold(id)} closed`));
3621
+ console.log(chalk5.green(`\u2713 Issue ${chalk5.bold(id)} closed`));
3220
3622
  } catch (err) {
3221
- console.error(chalk4.red(err.message));
3623
+ console.error(chalk5.red(err.message));
3222
3624
  process.exit(1);
3223
3625
  }
3224
3626
  });
@@ -3227,7 +3629,7 @@ issueCmd.command("reopen").description("Reopen a closed issue").argument("<id>",
3227
3629
  const engine = new TrellisVcsEngine({ rootPath });
3228
3630
  engine.open();
3229
3631
  await engine.reopenIssue(id);
3230
- console.log(chalk4.green(`\u2713 Issue ${chalk4.bold(id)} reopened`));
3632
+ console.log(chalk5.green(`\u2713 Issue ${chalk5.bold(id)} reopened`));
3231
3633
  });
3232
3634
  issueCmd.command("block").description("Mark an issue as blocked by another issue").argument("<id>", "Issue ID to block").argument("<blockedBy>", "Issue ID that blocks it").option("-p, --path <path>", "Repository path", ".").action(async (id, blockedBy, opts) => {
3233
3635
  const rootPath = resolveRepoRoot(opts.path);
@@ -3235,8 +3637,8 @@ issueCmd.command("block").description("Mark an issue as blocked by another issue
3235
3637
  engine.open();
3236
3638
  await engine.blockIssue(id, blockedBy);
3237
3639
  console.log(
3238
- chalk4.yellow(
3239
- `\u{1F512} ${chalk4.bold(id)} is now blocked by ${chalk4.bold(blockedBy)}`
3640
+ chalk5.yellow(
3641
+ `\u{1F512} ${chalk5.bold(id)} is now blocked by ${chalk5.bold(blockedBy)}`
3240
3642
  )
3241
3643
  );
3242
3644
  });
@@ -3246,8 +3648,8 @@ issueCmd.command("unblock").description("Remove a blocking relationship").argume
3246
3648
  engine.open();
3247
3649
  await engine.unblockIssue(id, blockedBy);
3248
3650
  console.log(
3249
- chalk4.green(
3250
- `\u{1F513} ${chalk4.bold(id)} is no longer blocked by ${chalk4.bold(blockedBy)}`
3651
+ chalk5.green(
3652
+ `\u{1F513} ${chalk5.bold(id)} is no longer blocked by ${chalk5.bold(blockedBy)}`
3251
3653
  )
3252
3654
  );
3253
3655
  });
@@ -3257,16 +3659,16 @@ issueCmd.command("active").description("Show all active (in-progress) issues").o
3257
3659
  engine.open();
3258
3660
  const active = engine.getActiveIssues();
3259
3661
  if (active.length === 0) {
3260
- console.log(chalk4.dim("No active issues."));
3662
+ console.log(chalk5.dim("No active issues."));
3261
3663
  return;
3262
3664
  }
3263
- console.log(chalk4.bold(`Active Issues (${active.length})
3665
+ console.log(chalk5.bold(`Active Issues (${active.length})
3264
3666
  `));
3265
3667
  for (const issue of active) {
3266
- const branch = issue.branchName ? chalk4.dim(` on ${issue.branchName}`) : "";
3267
- const assignee = issue.assignee ? chalk4.dim(` \u2192 ${issue.assignee}`) : "";
3668
+ const branch = issue.branchName ? chalk5.dim(` on ${issue.branchName}`) : "";
3669
+ const assignee = issue.assignee ? chalk5.dim(` \u2192 ${issue.assignee}`) : "";
3268
3670
  console.log(
3269
- ` ${formatPriority(issue.priority)} ${chalk4.bold(issue.id)} ${issue.title ?? ""}${branch}${assignee}`
3671
+ ` ${formatPriority(issue.priority)} ${chalk5.bold(issue.id)} ${issue.title ?? ""}${branch}${assignee}`
3270
3672
  );
3271
3673
  }
3272
3674
  });
@@ -3296,14 +3698,14 @@ decisionCmd.command("list").description("List decision traces").option("-p, --pa
3296
3698
  limit: parseInt(opts.limit, 10)
3297
3699
  });
3298
3700
  if (decisions.length === 0) {
3299
- console.log(chalk4.dim("No decision traces found."));
3701
+ console.log(chalk5.dim("No decision traces found."));
3300
3702
  return;
3301
3703
  }
3302
3704
  for (const d of decisions) {
3303
- const ts = d.createdAt ? chalk4.dim(d.createdAt) : "";
3304
- console.log(`${chalk4.cyan(d.id)} ${chalk4.white(d.toolName)} ${ts}`);
3705
+ const ts = d.createdAt ? chalk5.dim(d.createdAt) : "";
3706
+ console.log(`${chalk5.cyan(d.id)} ${chalk5.white(d.toolName)} ${ts}`);
3305
3707
  if (d.rationale) {
3306
- console.log(` ${chalk4.dim("\u2192")} ${d.rationale}`);
3708
+ console.log(` ${chalk5.dim("\u2192")} ${d.rationale}`);
3307
3709
  }
3308
3710
  }
3309
3711
  });
@@ -3313,26 +3715,26 @@ decisionCmd.command("show").description("Show full details of a decision trace")
3313
3715
  engine.open();
3314
3716
  const d = engine.getDecision(id);
3315
3717
  if (!d) {
3316
- console.error(chalk4.red(`Decision ${id} not found.`));
3718
+ console.error(chalk5.red(`Decision ${id} not found.`));
3317
3719
  process.exit(1);
3318
3720
  }
3319
- console.log(`${chalk4.bold("ID:")} ${d.id}`);
3320
- console.log(`${chalk4.bold("Tool:")} ${d.toolName}`);
3321
- console.log(`${chalk4.bold("Created:")} ${d.createdAt ?? "unknown"}`);
3322
- console.log(`${chalk4.bold("Agent:")} ${d.createdBy ?? "unknown"}`);
3323
- if (d.context) console.log(`${chalk4.bold("Context:")} ${d.context}`);
3324
- if (d.rationale) console.log(`${chalk4.bold("Rationale:")} ${d.rationale}`);
3721
+ console.log(`${chalk5.bold("ID:")} ${d.id}`);
3722
+ console.log(`${chalk5.bold("Tool:")} ${d.toolName}`);
3723
+ console.log(`${chalk5.bold("Created:")} ${d.createdAt ?? "unknown"}`);
3724
+ console.log(`${chalk5.bold("Agent:")} ${d.createdBy ?? "unknown"}`);
3725
+ if (d.context) console.log(`${chalk5.bold("Context:")} ${d.context}`);
3726
+ if (d.rationale) console.log(`${chalk5.bold("Rationale:")} ${d.rationale}`);
3325
3727
  if (d.alternatives && d.alternatives.length > 0) {
3326
3728
  console.log(
3327
- `${chalk4.bold("Alternatives:")} ${d.alternatives.join(", ")}`
3729
+ `${chalk5.bold("Alternatives:")} ${d.alternatives.join(", ")}`
3328
3730
  );
3329
3731
  }
3330
3732
  if (d.outputSummary) {
3331
- console.log(`${chalk4.bold("Output:")} ${d.outputSummary}`);
3733
+ console.log(`${chalk5.bold("Output:")} ${d.outputSummary}`);
3332
3734
  }
3333
3735
  if (d.relatedEntities.length > 0) {
3334
3736
  console.log(
3335
- `${chalk4.bold("Related:")} ${d.relatedEntities.join(", ")}`
3737
+ `${chalk5.bold("Related:")} ${d.relatedEntities.join(", ")}`
3336
3738
  );
3337
3739
  }
3338
3740
  });
@@ -3345,27 +3747,27 @@ decisionCmd.command("chain").description("Trace all decisions that affected a gi
3345
3747
  engine.open();
3346
3748
  const chain = engine.getDecisionChain(entityId);
3347
3749
  if (chain.length === 0) {
3348
- console.log(chalk4.dim(`No decision traces found for ${entityId}.`));
3750
+ console.log(chalk5.dim(`No decision traces found for ${entityId}.`));
3349
3751
  return;
3350
3752
  }
3351
3753
  console.log(
3352
- chalk4.bold(`Decision chain for ${entityId} (${chain.length} decisions):`)
3754
+ chalk5.bold(`Decision chain for ${entityId} (${chain.length} decisions):`)
3353
3755
  );
3354
3756
  for (const d of chain) {
3355
- const ts = d.createdAt ? chalk4.dim(d.createdAt) : "";
3356
- console.log(` ${chalk4.cyan(d.id)} ${chalk4.white(d.toolName)} ${ts}`);
3757
+ const ts = d.createdAt ? chalk5.dim(d.createdAt) : "";
3758
+ console.log(` ${chalk5.cyan(d.id)} ${chalk5.white(d.toolName)} ${ts}`);
3357
3759
  if (d.rationale) {
3358
- console.log(` ${chalk4.dim("\u2192")} ${d.rationale}`);
3760
+ console.log(` ${chalk5.dim("\u2192")} ${d.rationale}`);
3359
3761
  }
3360
3762
  }
3361
3763
  });
3362
3764
  program.command("identity").description("Manage local identity (Ed25519 key pair)").argument("[action]", '"init" or "show" (default: show)').option("-p, --path <path>", "Repository path", ".").option("--name <name>", "Display name for new identity").option("--email <email>", "Email for new identity").action((action, opts) => {
3363
3765
  const rootPath = resolve2(opts.path);
3364
- const trellisDir = join6(rootPath, ".trellis");
3766
+ const trellisDir2 = join7(rootPath, ".trellis");
3365
3767
  if (action === "init") {
3366
- if (hasIdentity(trellisDir)) {
3768
+ if (hasIdentity(trellisDir2)) {
3367
3769
  console.error(
3368
- chalk4.yellow(
3770
+ chalk5.yellow(
3369
3771
  "Identity already exists. Use `trellis identity` to view it."
3370
3772
  )
3371
3773
  );
@@ -3374,35 +3776,35 @@ program.command("identity").description("Manage local identity (Ed25519 key pair
3374
3776
  const name = opts.name ?? "Anonymous";
3375
3777
  const email = opts.email;
3376
3778
  const identity2 = createIdentity({ displayName: name, email });
3377
- saveIdentity(trellisDir, identity2);
3378
- console.log(chalk4.green("\u2713 Identity created"));
3379
- console.log(` ${chalk4.dim("Name:")} ${identity2.displayName}`);
3779
+ saveIdentity(trellisDir2, identity2);
3780
+ console.log(chalk5.green("\u2713 Identity created"));
3781
+ console.log(` ${chalk5.dim("Name:")} ${identity2.displayName}`);
3380
3782
  if (identity2.email) {
3381
- console.log(` ${chalk4.dim("Email:")} ${identity2.email}`);
3783
+ console.log(` ${chalk5.dim("Email:")} ${identity2.email}`);
3382
3784
  }
3383
- console.log(` ${chalk4.dim("DID:")} ${identity2.did}`);
3384
- console.log(` ${chalk4.dim("ID:")} ${identity2.entityId}`);
3785
+ console.log(` ${chalk5.dim("DID:")} ${identity2.did}`);
3786
+ console.log(` ${chalk5.dim("ID:")} ${identity2.entityId}`);
3385
3787
  return;
3386
3788
  }
3387
- const identity = loadIdentity(trellisDir);
3789
+ const identity = loadIdentity(trellisDir2);
3388
3790
  if (!identity) {
3389
3791
  console.log(
3390
- chalk4.dim(
3792
+ chalk5.dim(
3391
3793
  'No identity configured. Run `trellis identity init --name "Your Name"`.'
3392
3794
  )
3393
3795
  );
3394
3796
  return;
3395
3797
  }
3396
3798
  const pub = toPublicIdentity(identity);
3397
- console.log(chalk4.bold("Identity\n"));
3398
- console.log(` ${chalk4.dim("Name:")} ${pub.displayName}`);
3799
+ console.log(chalk5.bold("Identity\n"));
3800
+ console.log(` ${chalk5.dim("Name:")} ${pub.displayName}`);
3399
3801
  if (pub.email) {
3400
- console.log(` ${chalk4.dim("Email:")} ${pub.email}`);
3802
+ console.log(` ${chalk5.dim("Email:")} ${pub.email}`);
3401
3803
  }
3402
- console.log(` ${chalk4.dim("DID:")} ${pub.did}`);
3403
- console.log(` ${chalk4.dim("Entity ID:")} ${pub.entityId}`);
3404
- console.log(` ${chalk4.dim("Public Key:")} ${pub.publicKey.slice(0, 32)}\u2026`);
3405
- console.log(` ${chalk4.dim("Created:")} ${pub.createdAt}`);
3804
+ console.log(` ${chalk5.dim("DID:")} ${pub.did}`);
3805
+ console.log(` ${chalk5.dim("Entity ID:")} ${pub.entityId}`);
3806
+ console.log(` ${chalk5.dim("Public Key:")} ${pub.publicKey.slice(0, 32)}\u2026`);
3807
+ console.log(` ${chalk5.dim("Created:")} ${pub.createdAt}`);
3406
3808
  });
3407
3809
  program.command("refs").description("List wiki-link references in files or find backlinks").argument("[file]", "File to list outgoing refs for").option("-p, --path <path>", "Repository path", ".").option(
3408
3810
  "--backlinks <entity>",
@@ -3411,7 +3813,7 @@ program.command("refs").description("List wiki-link references in files or find
3411
3813
  const rootPath = resolveRepoRoot(opts.path);
3412
3814
  const engine = new TrellisVcsEngine({ rootPath });
3413
3815
  engine.open();
3414
- const { readFileSync: readFileSync5 } = __require("fs");
3816
+ const { readFileSync: readFileSync7 } = __require("fs");
3415
3817
  const {
3416
3818
  parseFileRefs,
3417
3819
  buildRefIndex: buildRefIndex2,
@@ -3430,8 +3832,8 @@ program.command("refs").description("List wiki-link references in files or find
3430
3832
  const fileContents = [];
3431
3833
  for (const f of trackedFiles) {
3432
3834
  try {
3433
- const absPath = join6(rootPath, f.path);
3434
- const content = readFileSync5(absPath, "utf-8");
3835
+ const absPath = join7(rootPath, f.path);
3836
+ const content = readFileSync7(absPath, "utf-8");
3435
3837
  fileContents.push({ path: f.path, content });
3436
3838
  } catch {
3437
3839
  }
@@ -3439,10 +3841,10 @@ program.command("refs").description("List wiki-link references in files or find
3439
3841
  const index = buildRefIndex2(fileContents, resolverCtx);
3440
3842
  if (opts.stats) {
3441
3843
  const stats = getIndexStats(index);
3442
- console.log(chalk4.bold("Reference Index Stats\n"));
3443
- console.log(` ${chalk4.dim("Files with refs:")} ${stats.totalFiles}`);
3444
- console.log(` ${chalk4.dim("Total refs:")} ${stats.totalRefs}`);
3445
- console.log(` ${chalk4.dim("Unique entities:")} ${stats.totalEntities}`);
3844
+ console.log(chalk5.bold("Reference Index Stats\n"));
3845
+ console.log(` ${chalk5.dim("Files with refs:")} ${stats.totalFiles}`);
3846
+ console.log(` ${chalk5.dim("Total refs:")} ${stats.totalRefs}`);
3847
+ console.log(` ${chalk5.dim("Unique entities:")} ${stats.totalEntities}`);
3446
3848
  return;
3447
3849
  }
3448
3850
  if (opts.backlinks) {
@@ -3462,14 +3864,14 @@ program.command("refs").description("List wiki-link references in files or find
3462
3864
  const sources = getBacklinks2(index, eid);
3463
3865
  if (sources.length > 0) {
3464
3866
  console.log(
3465
- chalk4.bold(
3466
- `Backlinks for ${chalk4.cyan(eid)} (${sources.length})
3867
+ chalk5.bold(
3868
+ `Backlinks for ${chalk5.cyan(eid)} (${sources.length})
3467
3869
  `
3468
3870
  )
3469
3871
  );
3470
3872
  for (const s of sources) {
3471
3873
  console.log(
3472
- ` ${chalk4.dim(s.filePath)}:${s.line} ${chalk4.dim(`(${s.context})`)}`
3874
+ ` ${chalk5.dim(s.filePath)}:${s.line} ${chalk5.dim(`(${s.context})`)}`
3473
3875
  );
3474
3876
  }
3475
3877
  found = true;
@@ -3477,7 +3879,7 @@ program.command("refs").description("List wiki-link references in files or find
3477
3879
  }
3478
3880
  }
3479
3881
  if (!found) {
3480
- console.log(chalk4.dim(`No references found for: ${entity}`));
3882
+ console.log(chalk5.dim(`No references found for: ${entity}`));
3481
3883
  }
3482
3884
  return;
3483
3885
  }
@@ -3494,31 +3896,31 @@ program.command("refs").description("List wiki-link references in files or find
3494
3896
  }
3495
3897
  const diags = getDiagnostics(index, registry, resolvedIds);
3496
3898
  if (diags.length === 0) {
3497
- console.log(chalk4.green("\u2713 No broken or stale references found."));
3899
+ console.log(chalk5.green("\u2713 No broken or stale references found."));
3498
3900
  return;
3499
3901
  }
3500
3902
  const stale = diags.filter((d) => d.state === "stale");
3501
3903
  const broken = diags.filter((d) => d.state === "broken");
3502
3904
  if (broken.length > 0) {
3503
3905
  console.log(
3504
- chalk4.bold(chalk4.red(`Broken references (${broken.length})
3906
+ chalk5.bold(chalk5.red(`Broken references (${broken.length})
3505
3907
  `))
3506
3908
  );
3507
3909
  for (const d of broken) {
3508
3910
  console.log(
3509
- ` ${chalk4.red("\u2717")} ${d.source.filePath}:${d.source.line} ${d.message}`
3911
+ ` ${chalk5.red("\u2717")} ${d.source.filePath}:${d.source.line} ${d.message}`
3510
3912
  );
3511
3913
  }
3512
3914
  console.log();
3513
3915
  }
3514
3916
  if (stale.length > 0) {
3515
3917
  console.log(
3516
- chalk4.bold(chalk4.yellow(`Stale references (${stale.length})
3918
+ chalk5.bold(chalk5.yellow(`Stale references (${stale.length})
3517
3919
  `))
3518
3920
  );
3519
3921
  for (const d of stale) {
3520
3922
  console.log(
3521
- ` ${chalk4.yellow("\u26A0")} ${d.source.filePath}:${d.source.line} ${d.message}`
3923
+ ` ${chalk5.yellow("\u26A0")} ${d.source.filePath}:${d.source.line} ${d.message}`
3522
3924
  );
3523
3925
  }
3524
3926
  }
@@ -3527,43 +3929,43 @@ program.command("refs").description("List wiki-link references in files or find
3527
3929
  if (file) {
3528
3930
  const refs = getOutgoingRefs2(index, file);
3529
3931
  if (refs.length === 0) {
3530
- console.log(chalk4.dim(`No [[...]] references found in: ${file}`));
3932
+ console.log(chalk5.dim(`No [[...]] references found in: ${file}`));
3531
3933
  return;
3532
3934
  }
3533
3935
  console.log(
3534
- chalk4.bold(`References in ${chalk4.cyan(file)} (${refs.length})
3936
+ chalk5.bold(`References in ${chalk5.cyan(file)} (${refs.length})
3535
3937
  `)
3536
3938
  );
3537
3939
  for (const ref of refs) {
3538
3940
  const resolved = resolveRef(ref, resolverCtx);
3539
- const stateIcon = resolved.state === "resolved" ? chalk4.green("\u2713") : resolved.state === "stale" ? chalk4.yellow("\u26A0") : chalk4.red("\u2717");
3941
+ const stateIcon = resolved.state === "resolved" ? chalk5.green("\u2713") : resolved.state === "stale" ? chalk5.yellow("\u26A0") : chalk5.red("\u2717");
3540
3942
  const display = ref.alias ?? ref.raw;
3541
- const entityId = resolved.entityId ?? chalk4.dim("unresolved");
3943
+ const entityId = resolved.entityId ?? chalk5.dim("unresolved");
3542
3944
  console.log(
3543
- ` ${stateIcon} [[${display}]] \u2192 ${entityId} ${chalk4.dim(`L${ref.source.line}`)}`
3945
+ ` ${stateIcon} [[${display}]] \u2192 ${entityId} ${chalk5.dim(`L${ref.source.line}`)}`
3544
3946
  );
3545
3947
  }
3546
3948
  } else {
3547
3949
  const stats = getIndexStats(index);
3548
3950
  if (stats.totalRefs === 0) {
3549
3951
  console.log(
3550
- chalk4.dim("No [[...]] references found in any tracked files.")
3952
+ chalk5.dim("No [[...]] references found in any tracked files.")
3551
3953
  );
3552
3954
  return;
3553
3955
  }
3554
3956
  console.log(
3555
- chalk4.bold(
3957
+ chalk5.bold(
3556
3958
  `References (${stats.totalRefs} across ${stats.totalFiles} files)
3557
3959
  `
3558
3960
  )
3559
3961
  );
3560
3962
  for (const [filePath, refs] of index.outgoing) {
3561
- console.log(` ${chalk4.cyan(filePath)} (${refs.length} refs)`);
3963
+ console.log(` ${chalk5.cyan(filePath)} (${refs.length} refs)`);
3562
3964
  for (const ref of refs) {
3563
3965
  const resolved = resolveRef(ref, resolverCtx);
3564
- const stateIcon = resolved.state === "resolved" ? chalk4.green("\u2713") : resolved.state === "stale" ? chalk4.yellow("\u26A0") : chalk4.red("\u2717");
3966
+ const stateIcon = resolved.state === "resolved" ? chalk5.green("\u2713") : resolved.state === "stale" ? chalk5.yellow("\u26A0") : chalk5.red("\u2717");
3565
3967
  console.log(
3566
- ` ${stateIcon} [[${ref.raw}]] ${chalk4.dim(`L${ref.source.line}`)}`
3968
+ ` ${stateIcon} [[${ref.raw}]] ${chalk5.dim(`L${ref.source.line}`)}`
3567
3969
  );
3568
3970
  }
3569
3971
  }
@@ -3577,7 +3979,7 @@ program.command("search").description("Semantic search across all embedded conte
3577
3979
  const engine = new TrellisVcsEngine({ rootPath });
3578
3980
  engine.open();
3579
3981
  const { EmbeddingManager } = (init_embeddings(), __toCommonJS(embeddings_exports));
3580
- const dbPath = join6(rootPath, ".trellis", "embeddings.db");
3982
+ const dbPath = join7(rootPath, ".trellis", "embeddings.db");
3581
3983
  const manager = await EmbeddingManager.create(dbPath);
3582
3984
  try {
3583
3985
  const searchOpts = {
@@ -3589,25 +3991,25 @@ program.command("search").description("Semantic search across all embedded conte
3589
3991
  const results = await manager.search(query, searchOpts);
3590
3992
  if (results.length === 0) {
3591
3993
  console.log(
3592
- chalk4.dim(
3994
+ chalk5.dim(
3593
3995
  "No results found. Try `trellis reindex` to build the index."
3594
3996
  )
3595
3997
  );
3596
3998
  return;
3597
3999
  }
3598
4000
  console.log(
3599
- chalk4.bold(
3600
- `Search results for ${chalk4.cyan(`"${query}"`)} (${results.length})
4001
+ chalk5.bold(
4002
+ `Search results for ${chalk5.cyan(`"${query}"`)} (${results.length})
3601
4003
  `
3602
4004
  )
3603
4005
  );
3604
4006
  for (const r of results) {
3605
4007
  const score = (r.score * 100).toFixed(1);
3606
- const typeTag = chalk4.dim(`[${r.chunk.chunkType}]`);
3607
- const filePart = r.chunk.filePath ? chalk4.dim(` ${r.chunk.filePath}`) : "";
4008
+ const typeTag = chalk5.dim(`[${r.chunk.chunkType}]`);
4009
+ const filePart = r.chunk.filePath ? chalk5.dim(` ${r.chunk.filePath}`) : "";
3608
4010
  const preview = r.chunk.content.slice(0, 120).replace(/\n/g, " ");
3609
- console.log(` ${chalk4.green(`${score}%`)} ${typeTag}${filePart}`);
3610
- console.log(` ${chalk4.dim(preview)}`);
4011
+ console.log(` ${chalk5.green(`${score}%`)} ${typeTag}${filePart}`);
4012
+ console.log(` ${chalk5.dim(preview)}`);
3611
4013
  console.log();
3612
4014
  }
3613
4015
  } finally {
@@ -3619,14 +4021,14 @@ program.command("reindex").description("Rebuild the semantic embedding index").o
3619
4021
  const engine = new TrellisVcsEngine({ rootPath });
3620
4022
  engine.open();
3621
4023
  const { EmbeddingManager } = (init_embeddings(), __toCommonJS(embeddings_exports));
3622
- const dbPath = join6(rootPath, ".trellis", "embeddings.db");
4024
+ const dbPath = join7(rootPath, ".trellis", "embeddings.db");
3623
4025
  const manager = await EmbeddingManager.create(dbPath);
3624
4026
  try {
3625
- console.log(chalk4.dim("Loading embedding model\u2026"));
4027
+ console.log(chalk5.dim("Loading embedding model\u2026"));
3626
4028
  const result = await manager.reindex(engine);
3627
- console.log(chalk4.green(`\u2713 Indexed ${result.chunks} chunks`));
4029
+ console.log(chalk5.green(`\u2713 Indexed ${result.chunks} chunks`));
3628
4030
  const stats = manager.stats();
3629
- console.log(chalk4.dim(` Types: ${JSON.stringify(stats.byType)}`));
4031
+ console.log(chalk5.dim(` Types: ${JSON.stringify(stats.byType)}`));
3630
4032
  } finally {
3631
4033
  manager.close();
3632
4034
  }
@@ -3655,24 +4057,24 @@ program.command("ui").description(
3655
4057
  try {
3656
4058
  const server = await startUIServer2({ rootPath, port: appPort });
3657
4059
  const url = `http://localhost:${server.port}`;
3658
- console.log(chalk4.yellow("Legacy System Visualizer (client.html)"));
3659
- console.log(chalk4.green(`\u2713 Running at ${chalk4.bold(url)}`));
4060
+ console.log(chalk5.yellow("Legacy System Visualizer (client.html)"));
4061
+ console.log(chalk5.green(`\u2713 Running at ${chalk5.bold(url)}`));
3660
4062
  openBrowser(url);
3661
4063
  process.on("SIGINT", () => {
3662
4064
  server.stop();
3663
4065
  process.exit(0);
3664
4066
  });
3665
4067
  } catch (err) {
3666
- console.error(chalk4.red(`Failed to start server: ${err.message}`));
4068
+ console.error(chalk5.red(`Failed to start server: ${err.message}`));
3667
4069
  process.exit(1);
3668
4070
  }
3669
4071
  return;
3670
4072
  }
3671
4073
  try {
3672
- const { launchRealtimeExplorer } = await import("../launch-explorer-HZ4ZJA4X.js");
3673
- console.log(chalk4.dim(`Workspace: ${rootPath}`));
4074
+ const { launchRealtimeExplorer } = await import("../launch-explorer-FVX6ZABW.js");
4075
+ console.log(chalk5.dim(`Workspace: ${rootPath}`));
3674
4076
  console.log(
3675
- chalk4.dim("Starting Svelte realtime explorer (sidecar + Vite)\u2026\n")
4077
+ chalk5.dim("Starting Svelte realtime explorer (sidecar + Vite)\u2026\n")
3676
4078
  );
3677
4079
  const handle = await launchRealtimeExplorer({
3678
4080
  rootPath,
@@ -3680,27 +4082,27 @@ program.command("ui").description(
3680
4082
  trellisPort
3681
4083
  });
3682
4084
  console.log(
3683
- chalk4.green(`\u2713 Live graph explorer \u2192 ${chalk4.bold(handle.appUrl)}`)
4085
+ chalk5.green(`\u2713 Live graph explorer \u2192 ${chalk5.bold(handle.appUrl)}`)
3684
4086
  );
3685
4087
  console.log(
3686
- chalk4.dim(` Trellis sidecar / inspector \u2192 ${handle.trellisUrl}`)
4088
+ chalk5.dim(` Trellis sidecar / inspector \u2192 ${handle.trellisUrl}`)
3687
4089
  );
3688
- console.log(chalk4.dim(" Press Ctrl+C to stop\n"));
4090
+ console.log(chalk5.dim(" Press Ctrl+C to stop\n"));
3689
4091
  openBrowser(handle.appUrl);
3690
4092
  process.on("SIGINT", () => {
3691
4093
  handle.stop();
3692
- console.log(chalk4.dim("\nExplorer stopped."));
4094
+ console.log(chalk5.dim("\nExplorer stopped."));
3693
4095
  process.exit(0);
3694
4096
  });
3695
4097
  } catch (err) {
3696
- console.error(chalk4.red(`Failed to start explorer: ${err.message}`));
4098
+ console.error(chalk5.red(`Failed to start explorer: ${err.message}`));
3697
4099
  process.exit(1);
3698
4100
  }
3699
4101
  });
3700
4102
  async function bootKernel(rootPath) {
3701
- const dbPath = join6(rootPath, ".trellis", "kernel.db");
4103
+ const dbPath = join7(rootPath, ".trellis", "kernel.db");
3702
4104
  const { createKernelBackend } = await import("../core/persist/factory.js");
3703
- const { attachStandardMiddleware } = await import("../boot-middleware-MHLHFCUC.js");
4105
+ const { attachStandardMiddleware } = await import("../boot-middleware-PATBLD52.js");
3704
4106
  const backend = await createKernelBackend(dbPath);
3705
4107
  const kernel = new TrellisKernel({
3706
4108
  backend,
@@ -3710,40 +4112,61 @@ async function bootKernel(rootPath) {
3710
4112
  attachStandardMiddleware(kernel);
3711
4113
  return kernel;
3712
4114
  }
3713
- var entityCmd = program.command("entity").description("Manage graph entities (generic CRUD)");
3714
- entityCmd.command("create").description("Create a new entity in the graph").requiredOption("-i, --id <id>", 'Entity ID (e.g. "project:my-app")').requiredOption("-t, --type <type>", 'Entity type (e.g. "Project", "User")').option("-a, --attr <attrs...>", "Attributes as key=value pairs").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
3715
- const rootPath = resolveRepoRoot(opts.path);
4115
+ function parseAttrPairs(pairs) {
4116
+ const attrs = {};
4117
+ if (!pairs) return attrs;
4118
+ for (const pair of pairs) {
4119
+ const eq = pair.indexOf("=");
4120
+ if (eq === -1) continue;
4121
+ const key = pair.slice(0, eq);
4122
+ let val = pair.slice(eq + 1);
4123
+ if (val === "true") val = true;
4124
+ else if (val === "false") val = false;
4125
+ else if (!isNaN(Number(val)) && val !== "") val = Number(val);
4126
+ attrs[key] = val;
4127
+ }
4128
+ return attrs;
4129
+ }
4130
+ async function withGraphStore(rootPath, fn) {
4131
+ if (TrellisVcsEngine.isRepo(rootPath)) {
4132
+ const engine = new TrellisVcsEngine({ rootPath });
4133
+ engine.open();
4134
+ await fn({ mode: "vcs", engine });
4135
+ return;
4136
+ }
3716
4137
  const kernel = await bootKernel(rootPath);
3717
4138
  try {
3718
- const attrs = {};
3719
- if (opts.attr) {
3720
- for (const pair of opts.attr) {
3721
- const eq = pair.indexOf("=");
3722
- if (eq === -1) continue;
3723
- const key = pair.slice(0, eq);
3724
- let val = pair.slice(eq + 1);
3725
- if (val === "true") val = true;
3726
- else if (val === "false") val = false;
3727
- else if (!isNaN(Number(val)) && val !== "") val = Number(val);
3728
- attrs[key] = val;
3729
- }
3730
- }
3731
- const result = await kernel.createEntity(opts.id, opts.type, attrs);
3732
- console.log(chalk4.green(`\u2713 Entity created: ${chalk4.bold(opts.id)}`));
3733
- console.log(` ${chalk4.dim("Type:")} ${opts.type}`);
3734
- console.log(` ${chalk4.dim("Facts:")} ${result.factsDelta.added}`);
3735
- console.log(` ${chalk4.dim("Op:")} ${result.op.hash.slice(0, 32)}\u2026`);
4139
+ await fn({ mode: "kernel", kernel });
3736
4140
  } finally {
3737
4141
  kernel.close();
3738
4142
  }
4143
+ }
4144
+ var entityCmd = program.command("entity").description("Manage graph entities (generic CRUD)");
4145
+ entityCmd.command("create").description("Create a new entity in the graph").requiredOption("-i, --id <id>", 'Entity ID (e.g. "project:my-app")').requiredOption("-t, --type <type>", 'Entity type (e.g. "Project", "User")').option("-a, --attr <attrs...>", "Attributes as key=value pairs").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
4146
+ const rootPath = resolveRepoRoot(opts.path);
4147
+ const attrs = parseAttrPairs(opts.attr);
4148
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4149
+ if (mode === "vcs" && engine) {
4150
+ const op = await engine.createStoreEntity(opts.id, opts.type, attrs);
4151
+ console.log(chalk5.green(`\u2713 Entity created: ${chalk5.bold(opts.id)}`));
4152
+ console.log(` ${chalk5.dim("Type:")} ${opts.type}`);
4153
+ console.log(` ${chalk5.dim("Journal:")} ops.json (vcs:storeAssert)`);
4154
+ console.log(` ${chalk5.dim("Op:")} ${op.hash.slice(0, 32)}\u2026`);
4155
+ return;
4156
+ }
4157
+ const result = await kernel.createEntity(opts.id, opts.type, attrs);
4158
+ console.log(chalk5.green(`\u2713 Entity created: ${chalk5.bold(opts.id)}`));
4159
+ console.log(` ${chalk5.dim("Type:")} ${opts.type}`);
4160
+ console.log(` ${chalk5.dim("Facts:")} ${result.factsDelta.added}`);
4161
+ console.log(` ${chalk5.dim("Op:")} ${result.op.hash.slice(0, 32)}\u2026`);
4162
+ });
3739
4163
  });
3740
4164
  entityCmd.command("get").description("Get an entity by ID").argument("<id>", "Entity ID").option("-p, --path <path>", "Repository path", ".").option("--json", "Output as JSON").action(async (id, opts) => {
3741
4165
  const rootPath = resolveRepoRoot(opts.path);
3742
- const kernel = await bootKernel(rootPath);
3743
- try {
3744
- const entity = kernel.getEntity(id);
4166
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4167
+ const entity = mode === "vcs" && engine ? engine.getStoreEntity(id) : kernel.getEntity(id);
3745
4168
  if (!entity) {
3746
- console.error(chalk4.red(`Entity not found: ${id}`));
4169
+ console.error(chalk5.red(`Entity not found: ${id}`));
3747
4170
  process.exit(1);
3748
4171
  }
3749
4172
  if (opts.json) {
@@ -3759,82 +4182,64 @@ entityCmd.command("get").description("Get an entity by ID").argument("<id>", "En
3759
4182
  console.log(JSON.stringify(obj, null, 2));
3760
4183
  return;
3761
4184
  }
3762
- console.log(chalk4.bold(`${entity.type}: ${entity.id}
4185
+ console.log(chalk5.bold(`${entity.type}: ${entity.id}
3763
4186
  `));
3764
4187
  for (const f of entity.facts) {
3765
- console.log(` ${chalk4.dim(f.a.padEnd(20))} ${f.v}`);
4188
+ console.log(` ${chalk5.dim(f.a.padEnd(20))} ${f.v}`);
3766
4189
  }
3767
4190
  if (entity.links.length > 0) {
3768
4191
  console.log(`
3769
- ${chalk4.bold("Links:")}`);
4192
+ ${chalk5.bold("Links:")}`);
3770
4193
  for (const l of entity.links) {
3771
4194
  const dir = l.e1 === id ? "\u2192" : "\u2190";
3772
4195
  const other = l.e1 === id ? l.e2 : l.e1;
3773
- console.log(` ${dir} ${chalk4.dim(l.a)} ${other}`);
4196
+ console.log(` ${dir} ${chalk5.dim(l.a)} ${other}`);
3774
4197
  }
3775
4198
  }
3776
- } finally {
3777
- kernel.close();
3778
- }
4199
+ });
3779
4200
  });
3780
4201
  entityCmd.command("update").description("Update attributes on an existing entity").argument("<id>", "Entity ID").requiredOption("-a, --attr <attrs...>", "Attributes as key=value pairs").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
3781
4202
  const rootPath = resolveRepoRoot(opts.path);
3782
- const kernel = await bootKernel(rootPath);
3783
- try {
3784
- const updates = {};
3785
- for (const pair of opts.attr) {
3786
- const eq = pair.indexOf("=");
3787
- if (eq === -1) continue;
3788
- const key = pair.slice(0, eq);
3789
- let val = pair.slice(eq + 1);
3790
- if (val === "true") val = true;
3791
- else if (val === "false") val = false;
3792
- else if (!isNaN(Number(val)) && val !== "") val = Number(val);
3793
- updates[key] = val;
3794
- }
3795
- await kernel.updateEntity(id, updates);
3796
- console.log(chalk4.green(`\u2713 Updated ${chalk4.bold(id)}`));
4203
+ const updates = parseAttrPairs(opts.attr);
4204
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4205
+ if (mode === "vcs" && engine) {
4206
+ await engine.updateStoreEntity(id, updates);
4207
+ } else {
4208
+ await kernel.updateEntity(id, updates);
4209
+ }
4210
+ console.log(chalk5.green(`\u2713 Updated ${chalk5.bold(id)}`));
3797
4211
  for (const [k, v] of Object.entries(updates)) {
3798
- console.log(` ${chalk4.dim(k)} = ${v}`);
4212
+ console.log(` ${chalk5.dim(k)} = ${v}`);
3799
4213
  }
3800
- } finally {
3801
- kernel.close();
3802
- }
4214
+ });
3803
4215
  });
3804
4216
  entityCmd.command("delete").description("Delete an entity and all its facts/links").argument("<id>", "Entity ID").option("-p, --path <path>", "Repository path", ".").action(async (id, opts) => {
3805
4217
  const rootPath = resolveRepoRoot(opts.path);
3806
- const kernel = await bootKernel(rootPath);
3807
- try {
3808
- const entity = kernel.getEntity(id);
4218
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4219
+ const entity = mode === "vcs" && engine ? engine.getStoreEntity(id) : kernel.getEntity(id);
3809
4220
  if (!entity) {
3810
- console.error(chalk4.red(`Entity not found: ${id}`));
4221
+ console.error(chalk5.red(`Entity not found: ${id}`));
3811
4222
  process.exit(1);
3812
4223
  }
3813
- await kernel.deleteEntity(id);
3814
- console.log(chalk4.green(`\u2713 Deleted entity ${chalk4.bold(id)}`));
3815
- } finally {
3816
- kernel.close();
3817
- }
4224
+ if (mode === "vcs" && engine) {
4225
+ await engine.deleteStoreEntity(id);
4226
+ } else {
4227
+ await kernel.deleteEntity(id);
4228
+ }
4229
+ console.log(chalk5.green(`\u2713 Deleted entity ${chalk5.bold(id)}`));
4230
+ });
3818
4231
  });
3819
4232
  entityCmd.command("list").description("List entities, optionally filtered by type").option("-t, --type <type>", "Filter by entity type").option("-f, --filter <filters...>", "Attribute filters as key=value").option("--json", "Output as JSON").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
3820
4233
  const rootPath = resolveRepoRoot(opts.path);
3821
- const kernel = await bootKernel(rootPath);
3822
- try {
3823
- let filters;
3824
- if (opts.filter) {
3825
- filters = {};
3826
- for (const pair of opts.filter) {
3827
- const eq = pair.indexOf("=");
3828
- if (eq === -1) continue;
3829
- const key = pair.slice(0, eq);
3830
- let val = pair.slice(eq + 1);
3831
- if (val === "true") val = true;
3832
- else if (val === "false") val = false;
3833
- else if (!isNaN(Number(val)) && val !== "") val = Number(val);
3834
- filters[key] = val;
3835
- }
3836
- }
3837
- const entities = kernel.listEntities(opts.type, filters);
4234
+ const filters = parseAttrPairs(opts.filter);
4235
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4236
+ const entities = mode === "vcs" && engine ? engine.listStoreEntities(
4237
+ opts.type,
4238
+ Object.keys(filters).length > 0 ? filters : void 0
4239
+ ) : kernel.listEntities(
4240
+ opts.type,
4241
+ Object.keys(filters).length > 0 ? filters : void 0
4242
+ );
3838
4243
  if (opts.json) {
3839
4244
  const out = entities.map((e) => {
3840
4245
  const obj = { id: e.id, type: e.type };
@@ -3847,65 +4252,64 @@ entityCmd.command("list").description("List entities, optionally filtered by typ
3847
4252
  return;
3848
4253
  }
3849
4254
  if (entities.length === 0) {
3850
- console.log(chalk4.dim("No entities found."));
4255
+ console.log(chalk5.dim("No entities found."));
3851
4256
  return;
3852
4257
  }
3853
4258
  const typeLabel = opts.type ? ` (type: ${opts.type})` : "";
3854
- console.log(chalk4.bold(`Entities (${entities.length})${typeLabel}
4259
+ console.log(chalk5.bold(`Entities (${entities.length})${typeLabel}
3855
4260
  `));
3856
4261
  for (const e of entities) {
3857
- const nameFact = e.facts.find((f) => f.a === "name");
3858
- const name = nameFact ? ` ${chalk4.white(String(nameFact.v))}` : "";
4262
+ const labelFact = e.facts.find((f) => f.a === "title") ?? e.facts.find((f) => f.a === "name");
4263
+ const name = labelFact ? ` ${chalk5.white(String(labelFact.v))}` : "";
3859
4264
  console.log(
3860
- ` ${chalk4.cyan(e.type.padEnd(16))} ${chalk4.bold(e.id)}${name}`
4265
+ ` ${chalk5.cyan(e.type.padEnd(16))} ${chalk5.bold(e.id)}${name}`
3861
4266
  );
3862
4267
  }
3863
- } finally {
3864
- kernel.close();
3865
- }
4268
+ });
3866
4269
  });
3867
4270
  var factCmd = program.command("fact").description("Add or remove individual facts on entities");
3868
4271
  factCmd.command("add").description("Add a fact to an entity").argument("<entity>", "Entity ID").argument("<attribute>", "Attribute name").argument("<value>", "Value").option("-p, --path <path>", "Repository path", ".").action(async (entity, attribute, value, opts) => {
3869
4272
  const rootPath = resolveRepoRoot(opts.path);
3870
- const kernel = await bootKernel(rootPath);
3871
- try {
3872
- let val = value;
3873
- if (val === "true") val = true;
3874
- else if (val === "false") val = false;
3875
- else if (!isNaN(Number(val)) && val !== "") val = Number(val);
3876
- await kernel.addFact(entity, attribute, val);
4273
+ let val = value;
4274
+ if (val === "true") val = true;
4275
+ else if (val === "false") val = false;
4276
+ else if (!isNaN(Number(val)) && val !== "") val = Number(val);
4277
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4278
+ if (mode === "vcs" && engine) {
4279
+ await engine.addStoreFact(entity, attribute, val);
4280
+ } else {
4281
+ await kernel.addFact(entity, attribute, val);
4282
+ }
3877
4283
  console.log(
3878
- chalk4.green(
3879
- `\u2713 Added fact: ${chalk4.bold(entity)}.${attribute} = ${val}`
4284
+ chalk5.green(
4285
+ `\u2713 Added fact: ${chalk5.bold(entity)}.${attribute} = ${val}`
3880
4286
  )
3881
4287
  );
3882
- } finally {
3883
- kernel.close();
3884
- }
4288
+ });
3885
4289
  });
3886
4290
  factCmd.command("remove").description("Remove a fact from an entity").argument("<entity>", "Entity ID").argument("<attribute>", "Attribute name").argument("<value>", "Value to remove").option("-p, --path <path>", "Repository path", ".").action(async (entity, attribute, value, opts) => {
3887
4291
  const rootPath = resolveRepoRoot(opts.path);
3888
- const kernel = await bootKernel(rootPath);
3889
- try {
3890
- let val = value;
3891
- if (val === "true") val = true;
3892
- else if (val === "false") val = false;
3893
- else if (!isNaN(Number(val)) && val !== "") val = Number(val);
3894
- await kernel.removeFact(entity, attribute, val);
4292
+ let val = value;
4293
+ if (val === "true") val = true;
4294
+ else if (val === "false") val = false;
4295
+ else if (!isNaN(Number(val)) && val !== "") val = Number(val);
4296
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4297
+ if (mode === "vcs" && engine) {
4298
+ await engine.removeStoreFact(entity, attribute, val);
4299
+ } else {
4300
+ await kernel.removeFact(entity, attribute, val);
4301
+ }
3895
4302
  console.log(
3896
- chalk4.green(
3897
- `\u2713 Removed fact: ${chalk4.bold(entity)}.${attribute} = ${val}`
4303
+ chalk5.green(
4304
+ `\u2713 Removed fact: ${chalk5.bold(entity)}.${attribute} = ${val}`
3898
4305
  )
3899
4306
  );
3900
- } finally {
3901
- kernel.close();
3902
- }
4307
+ });
3903
4308
  });
3904
4309
  factCmd.command("query").description("Query facts by entity or attribute").option("-e, --entity <id>", "Filter by entity ID").option("-a, --attribute <attr>", "Filter by attribute").option("--json", "Output as JSON").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
3905
4310
  const rootPath = resolveRepoRoot(opts.path);
3906
- const kernel = await bootKernel(rootPath);
3907
- try {
3908
- const store = kernel.getStore();
4311
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4312
+ const store = mode === "vcs" && engine ? engine.getEavStore() : kernel.getStore();
3909
4313
  let facts;
3910
4314
  if (opts.entity) {
3911
4315
  facts = store.getFactsByEntity(opts.entity);
@@ -3919,57 +4323,56 @@ factCmd.command("query").description("Query facts by entity or attribute").optio
3919
4323
  return;
3920
4324
  }
3921
4325
  if (facts.length === 0) {
3922
- console.log(chalk4.dim("No facts found."));
4326
+ console.log(chalk5.dim("No facts found."));
3923
4327
  return;
3924
4328
  }
3925
- console.log(chalk4.bold(`Facts (${facts.length})
4329
+ console.log(chalk5.bold(`Facts (${facts.length})
3926
4330
  `));
3927
4331
  for (const f of facts.slice(0, 100)) {
3928
4332
  console.log(
3929
- ` ${chalk4.cyan(f.e.padEnd(24))} ${chalk4.dim(f.a.padEnd(20))} ${f.v}`
4333
+ ` ${chalk5.cyan(f.e.padEnd(24))} ${chalk5.dim(f.a.padEnd(20))} ${f.v}`
3930
4334
  );
3931
4335
  }
3932
4336
  if (facts.length > 100) {
3933
- console.log(chalk4.dim(` \u2026 +${facts.length - 100} more`));
4337
+ console.log(chalk5.dim(` \u2026 +${facts.length - 100} more`));
3934
4338
  }
3935
- } finally {
3936
- kernel.close();
3937
- }
4339
+ });
3938
4340
  });
3939
4341
  var linkCmd = program.command("link").description("Add or remove links between entities");
3940
4342
  linkCmd.command("add").description("Add a link between two entities").argument("<source>", "Source entity ID").argument("<attribute>", "Relationship attribute").argument("<target>", "Target entity ID").option("-p, --path <path>", "Repository path", ".").action(async (source, attribute, target, opts) => {
3941
4343
  const rootPath = resolveRepoRoot(opts.path);
3942
- const kernel = await bootKernel(rootPath);
3943
- try {
3944
- await kernel.addLink(source, attribute, target);
4344
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4345
+ if (mode === "vcs" && engine) {
4346
+ await engine.addStoreLink(source, attribute, target);
4347
+ } else {
4348
+ await kernel.addLink(source, attribute, target);
4349
+ }
3945
4350
  console.log(
3946
- chalk4.green(
3947
- `\u2713 Link: ${chalk4.bold(source)} \u2014[${attribute}]\u2192 ${chalk4.bold(target)}`
4351
+ chalk5.green(
4352
+ `\u2713 Link: ${chalk5.bold(source)} \u2014[${attribute}]\u2192 ${chalk5.bold(target)}`
3948
4353
  )
3949
4354
  );
3950
- } finally {
3951
- kernel.close();
3952
- }
4355
+ });
3953
4356
  });
3954
4357
  linkCmd.command("remove").description("Remove a link between two entities").argument("<source>", "Source entity ID").argument("<attribute>", "Relationship attribute").argument("<target>", "Target entity ID").option("-p, --path <path>", "Repository path", ".").action(async (source, attribute, target, opts) => {
3955
4358
  const rootPath = resolveRepoRoot(opts.path);
3956
- const kernel = await bootKernel(rootPath);
3957
- try {
3958
- await kernel.removeLink(source, attribute, target);
4359
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4360
+ if (mode === "vcs" && engine) {
4361
+ await engine.removeStoreLink(source, attribute, target);
4362
+ } else {
4363
+ await kernel.removeLink(source, attribute, target);
4364
+ }
3959
4365
  console.log(
3960
- chalk4.green(
3961
- `\u2713 Removed: ${chalk4.bold(source)} \u2014[${attribute}]\u2192 ${chalk4.bold(target)}`
4366
+ chalk5.green(
4367
+ `\u2713 Removed: ${chalk5.bold(source)} \u2014[${attribute}]\u2192 ${chalk5.bold(target)}`
3962
4368
  )
3963
4369
  );
3964
- } finally {
3965
- kernel.close();
3966
- }
4370
+ });
3967
4371
  });
3968
4372
  linkCmd.command("query").description("Query links for an entity").option("-e, --entity <id>", "Entity ID").option("-a, --attribute <attr>", "Relationship attribute").option("--json", "Output as JSON").option("-p, --path <path>", "Repository path", ".").action(async (opts) => {
3969
4373
  const rootPath = resolveRepoRoot(opts.path);
3970
- const kernel = await bootKernel(rootPath);
3971
- try {
3972
- const store = kernel.getStore();
4374
+ await withGraphStore(rootPath, async ({ mode, engine, kernel }) => {
4375
+ const store = mode === "vcs" && engine ? engine.getEavStore() : kernel.getStore();
3973
4376
  let links;
3974
4377
  if (opts.entity && opts.attribute) {
3975
4378
  links = store.getLinksByEntityAndAttribute(opts.entity, opts.attribute);
@@ -3985,22 +4388,20 @@ linkCmd.command("query").description("Query links for an entity").option("-e, --
3985
4388
  return;
3986
4389
  }
3987
4390
  if (links.length === 0) {
3988
- console.log(chalk4.dim("No links found."));
4391
+ console.log(chalk5.dim("No links found."));
3989
4392
  return;
3990
4393
  }
3991
- console.log(chalk4.bold(`Links (${links.length})
4394
+ console.log(chalk5.bold(`Links (${links.length})
3992
4395
  `));
3993
4396
  for (const l of links.slice(0, 100)) {
3994
4397
  console.log(
3995
- ` ${chalk4.cyan(l.e1)} \u2014[${chalk4.dim(l.a)}]\u2192 ${chalk4.cyan(l.e2)}`
4398
+ ` ${chalk5.cyan(l.e1)} \u2014[${chalk5.dim(l.a)}]\u2192 ${chalk5.cyan(l.e2)}`
3996
4399
  );
3997
4400
  }
3998
4401
  if (links.length > 100) {
3999
- console.log(chalk4.dim(` \u2026 +${links.length - 100} more`));
4402
+ console.log(chalk5.dim(` \u2026 +${links.length - 100} more`));
4000
4403
  }
4001
- } finally {
4002
- kernel.close();
4003
- }
4404
+ });
4004
4405
  });
4005
4406
  program.command("examples").description("Print example CLI commands and EQL-S queries for this repo").option("-p, --path <path>", "Repository path", ".").option("--json", "Output as JSON").action(async (opts) => {
4006
4407
  const rootPath = resolveRepoRoot(opts.path);
@@ -4016,20 +4417,20 @@ program.command("examples").description("Print example CLI commands and EQL-S qu
4016
4417
  console.log(JSON.stringify(examples, null, 2));
4017
4418
  return;
4018
4419
  }
4019
- console.log(chalk4.bold("Example commands for this repo\n"));
4420
+ console.log(chalk5.bold("Example commands for this repo\n"));
4020
4421
  for (const section of examples.sections) {
4021
- console.log(chalk4.cyan(section.title));
4422
+ console.log(chalk5.cyan(section.title));
4022
4423
  for (const cmd of section.commands) {
4023
- console.log(` ${chalk4.dim("$")} ${cmd}`);
4424
+ console.log(` ${chalk5.dim("$")} ${cmd}`);
4024
4425
  }
4025
4426
  console.log();
4026
4427
  }
4027
- console.log(chalk4.cyan("EQL-S queries"));
4428
+ console.log(chalk5.cyan("EQL-S queries"));
4028
4429
  console.log(
4029
- chalk4.dim(" (requires kernel materialization \u2014 run after init)\n")
4430
+ chalk5.dim(" (requires kernel materialization \u2014 run after init)\n")
4030
4431
  );
4031
4432
  for (const cmd of examples.eql) {
4032
- console.log(` ${chalk4.dim("$")} ${cmd}`);
4433
+ console.log(` ${chalk5.dim("$")} ${cmd}`);
4033
4434
  }
4034
4435
  });
4035
4436
  program.command("query").description("Execute an EQL-S query against the graph").argument(
@@ -4048,7 +4449,7 @@ program.command("query").description("Execute an EQL-S query against the graph")
4048
4449
  try {
4049
4450
  q = parseQuery(queryStr);
4050
4451
  } catch (e) {
4051
- console.error(chalk4.red(`Parse error: ${e.message}`));
4452
+ console.error(chalk5.red(`Parse error: ${e.message}`));
4052
4453
  process.exit(1);
4053
4454
  return;
4054
4455
  }
@@ -4058,16 +4459,16 @@ program.command("query").description("Execute an EQL-S query against the graph")
4058
4459
  console.log(JSON.stringify(result.bindings, null, 2));
4059
4460
  } else {
4060
4461
  if (result.count === 0) {
4061
- console.log(chalk4.dim("No results."));
4462
+ console.log(chalk5.dim("No results."));
4062
4463
  } else {
4063
4464
  const cols = result.bindings.length > 0 ? Object.keys(result.bindings[0]) : [];
4064
- console.log(chalk4.bold(cols.map((c) => `?${c}`).join(" ")));
4065
- console.log(chalk4.dim("\u2500".repeat(cols.length * 20)));
4465
+ console.log(chalk5.bold(cols.map((c) => `?${c}`).join(" ")));
4466
+ console.log(chalk5.dim("\u2500".repeat(cols.length * 20)));
4066
4467
  for (const row of result.bindings) {
4067
4468
  console.log(cols.map((c) => String(row[c] ?? "")).join(" "));
4068
4469
  }
4069
4470
  console.log(
4070
- chalk4.dim(
4471
+ chalk5.dim(
4071
4472
  `
4072
4473
  ${result.count} result(s) in ${result.executionTime.toFixed(1)}ms`
4073
4474
  )
@@ -4083,18 +4484,18 @@ program.command("repl").description("Interactive EQL-S query shell").option("-p,
4083
4484
  const kernel = await bootKernel(rootPath);
4084
4485
  const store = kernel.getStore();
4085
4486
  const engine = new QueryEngine(store);
4086
- console.log(chalk4.cyan.bold("Trellis EQL-S REPL"));
4487
+ console.log(chalk5.cyan.bold("Trellis EQL-S REPL"));
4087
4488
  console.log(
4088
- chalk4.dim(
4489
+ chalk5.dim(
4089
4490
  'Type EQL-S queries or "find ?e where attr = value" shorthand.'
4090
4491
  )
4091
4492
  );
4092
- console.log(chalk4.dim("Type .exit to quit, .help for help.\n"));
4493
+ console.log(chalk5.dim("Type .exit to quit, .help for help.\n"));
4093
4494
  const readline = await import("readline");
4094
4495
  const rl = readline.createInterface({
4095
4496
  input: process.stdin,
4096
4497
  output: process.stdout,
4097
- prompt: chalk4.green("eql> ")
4498
+ prompt: chalk5.green("eql> ")
4098
4499
  });
4099
4500
  rl.prompt();
4100
4501
  rl.on("line", (line) => {
@@ -4110,19 +4511,19 @@ program.command("repl").description("Interactive EQL-S query shell").option("-p,
4110
4511
  }
4111
4512
  if (trimmed === ".help") {
4112
4513
  console.log(`
4113
- ${chalk4.bold("EQL-S Query Syntax:")}
4114
- ${chalk4.cyan("SELECT")} ?var1 ?var2 ${chalk4.cyan("WHERE")} { patterns } [${chalk4.cyan("FILTER")} ...] [${chalk4.cyan("ORDER BY")} ...] [${chalk4.cyan("LIMIT")} n]
4514
+ ${chalk5.bold("EQL-S Query Syntax:")}
4515
+ ${chalk5.cyan("SELECT")} ?var1 ?var2 ${chalk5.cyan("WHERE")} { patterns } [${chalk5.cyan("FILTER")} ...] [${chalk5.cyan("ORDER BY")} ...] [${chalk5.cyan("LIMIT")} n]
4115
4516
 
4116
- ${chalk4.bold("Pattern types:")}
4117
- ${chalk4.yellow('[?e "attr" "value"]')} Fact pattern (entity, attribute, value)
4118
- ${chalk4.yellow('(?src "rel" ?tgt)')} Link pattern (source, relationship, target)
4119
- ${chalk4.yellow('NOT [?e "attr" ?v]')} Negation
4120
- ${chalk4.yellow("OR { ... } { ... }")} Disjunction
4517
+ ${chalk5.bold("Pattern types:")}
4518
+ ${chalk5.yellow('[?e "attr" "value"]')} Fact pattern (entity, attribute, value)
4519
+ ${chalk5.yellow('(?src "rel" ?tgt)')} Link pattern (source, relationship, target)
4520
+ ${chalk5.yellow('NOT [?e "attr" ?v]')} Negation
4521
+ ${chalk5.yellow("OR { ... } { ... }")} Disjunction
4121
4522
 
4122
- ${chalk4.bold("Shorthand:")}
4123
- ${chalk4.yellow('find ?e where type = "Project"')}
4523
+ ${chalk5.bold("Shorthand:")}
4524
+ ${chalk5.yellow('find ?e where type = "Project"')}
4124
4525
 
4125
- ${chalk4.bold("Commands:")}
4526
+ ${chalk5.bold("Commands:")}
4126
4527
  .exit / .quit Exit the REPL
4127
4528
  .stats Show store statistics
4128
4529
  .help Show this help
@@ -4151,27 +4552,27 @@ ${chalk4.bold("Commands:")}
4151
4552
  }
4152
4553
  const result = engine.execute(q);
4153
4554
  if (result.count === 0) {
4154
- console.log(chalk4.dim("No results."));
4555
+ console.log(chalk5.dim("No results."));
4155
4556
  } else {
4156
4557
  const cols = Object.keys(result.bindings[0]);
4157
- console.log(chalk4.bold(cols.map((c) => `?${c}`).join(" ")));
4558
+ console.log(chalk5.bold(cols.map((c) => `?${c}`).join(" ")));
4158
4559
  for (const row of result.bindings) {
4159
4560
  console.log(cols.map((c) => String(row[c] ?? "")).join(" "));
4160
4561
  }
4161
4562
  console.log(
4162
- chalk4.dim(
4563
+ chalk5.dim(
4163
4564
  `${result.count} result(s) in ${result.executionTime.toFixed(1)}ms`
4164
4565
  )
4165
4566
  );
4166
4567
  }
4167
4568
  } catch (e) {
4168
- console.error(chalk4.red(`Error: ${e.message}`));
4569
+ console.error(chalk5.red(`Error: ${e.message}`));
4169
4570
  }
4170
4571
  rl.prompt();
4171
4572
  });
4172
4573
  rl.on("close", () => {
4173
4574
  kernel.close();
4174
- console.log(chalk4.dim("Goodbye."));
4575
+ console.log(chalk5.dim("Goodbye."));
4175
4576
  });
4176
4577
  });
4177
4578
  var ontologyCmd = program.command("ontology").description("Manage and inspect ontology schemas");
@@ -4180,15 +4581,15 @@ ontologyCmd.command("list").description("List all registered ontologies (built-i
4180
4581
  for (const o of builtinOntologies) registry.register(o);
4181
4582
  const schemas = registry.list();
4182
4583
  if (schemas.length === 0) {
4183
- console.log(chalk4.dim("No ontologies registered."));
4584
+ console.log(chalk5.dim("No ontologies registered."));
4184
4585
  return;
4185
4586
  }
4186
- console.log(chalk4.bold(`Ontologies (${schemas.length})
4587
+ console.log(chalk5.bold(`Ontologies (${schemas.length})
4187
4588
  `));
4188
4589
  for (const s of schemas) {
4189
- console.log(` ${chalk4.cyan(s.id)} ${chalk4.dim(`v${s.version}`)}`);
4590
+ console.log(` ${chalk5.cyan(s.id)} ${chalk5.dim(`v${s.version}`)}`);
4190
4591
  console.log(
4191
- ` ${s.name}${s.description ? ` \u2014 ${chalk4.dim(s.description)}` : ""}`
4592
+ ` ${s.name}${s.description ? ` \u2014 ${chalk5.dim(s.description)}` : ""}`
4192
4593
  );
4193
4594
  console.log(` Entities: ${s.entities.map((e) => e.name).join(", ")}`);
4194
4595
  console.log(
@@ -4206,35 +4607,35 @@ ontologyCmd.command("inspect").description("Inspect a specific ontology or entit
4206
4607
  const schema = registry.get(name);
4207
4608
  if (schema) {
4208
4609
  console.log(
4209
- chalk4.bold(
4210
- `${schema.name} ${chalk4.dim(`(${schema.id} v${schema.version})`)}`
4610
+ chalk5.bold(
4611
+ `${schema.name} ${chalk5.dim(`(${schema.id} v${schema.version})`)}`
4211
4612
  )
4212
4613
  );
4213
- if (schema.description) console.log(chalk4.dim(schema.description));
4614
+ if (schema.description) console.log(chalk5.dim(schema.description));
4214
4615
  console.log();
4215
- console.log(chalk4.bold("Entity Types:"));
4616
+ console.log(chalk5.bold("Entity Types:"));
4216
4617
  for (const e of schema.entities) {
4217
4618
  console.log(
4218
4619
  `
4219
- ${chalk4.cyan.bold(e.name)}${e.abstract ? chalk4.dim(" (abstract)") : ""}${e.extends ? chalk4.dim(` extends ${e.extends}`) : ""}`
4620
+ ${chalk5.cyan.bold(e.name)}${e.abstract ? chalk5.dim(" (abstract)") : ""}${e.extends ? chalk5.dim(` extends ${e.extends}`) : ""}`
4220
4621
  );
4221
- if (e.description) console.log(` ${chalk4.dim(e.description)}`);
4622
+ if (e.description) console.log(` ${chalk5.dim(e.description)}`);
4222
4623
  for (const a of e.attributes) {
4223
4624
  const flags = [
4224
- a.required ? chalk4.red("required") : null,
4625
+ a.required ? chalk5.red("required") : null,
4225
4626
  a.enum ? `enum[${a.enum.join("|")}]` : null,
4226
4627
  a.default !== void 0 ? `default=${a.default}` : null
4227
4628
  ].filter(Boolean).join(", ");
4228
4629
  console.log(
4229
- ` ${chalk4.yellow(a.name)}: ${a.type}${flags ? ` (${flags})` : ""}`
4630
+ ` ${chalk5.yellow(a.name)}: ${a.type}${flags ? ` (${flags})` : ""}`
4230
4631
  );
4231
4632
  }
4232
4633
  }
4233
4634
  if (schema.relations.length > 0) {
4234
- console.log(chalk4.bold("\nRelations:"));
4635
+ console.log(chalk5.bold("\nRelations:"));
4235
4636
  for (const r of schema.relations) {
4236
4637
  console.log(
4237
- ` ${chalk4.yellow(r.name)}: ${r.sourceTypes.join("|")} \u2192 ${r.targetTypes.join("|")}${r.cardinality ? ` [${r.cardinality}]` : ""}`
4638
+ ` ${chalk5.yellow(r.name)}: ${r.sourceTypes.join("|")} \u2192 ${r.targetTypes.join("|")}${r.cardinality ? ` [${r.cardinality}]` : ""}`
4238
4639
  );
4239
4640
  }
4240
4641
  }
@@ -4243,43 +4644,43 @@ ontologyCmd.command("inspect").description("Inspect a specific ontology or entit
4243
4644
  const def = registry.getEntityDef(name);
4244
4645
  if (def) {
4245
4646
  const ontId = registry.getEntityOntology(name);
4246
- console.log(chalk4.bold(`${def.name}`) + chalk4.dim(` (from ${ontId})`));
4247
- if (def.description) console.log(chalk4.dim(def.description));
4647
+ console.log(chalk5.bold(`${def.name}`) + chalk5.dim(` (from ${ontId})`));
4648
+ if (def.description) console.log(chalk5.dim(def.description));
4248
4649
  if (def.abstract)
4249
- console.log(chalk4.dim("(abstract \u2014 cannot be instantiated)"));
4250
- if (def.extends) console.log(chalk4.dim(`extends ${def.extends}`));
4251
- console.log(chalk4.bold("\nAttributes:"));
4650
+ console.log(chalk5.dim("(abstract \u2014 cannot be instantiated)"));
4651
+ if (def.extends) console.log(chalk5.dim(`extends ${def.extends}`));
4652
+ console.log(chalk5.bold("\nAttributes:"));
4252
4653
  for (const a of def.attributes) {
4253
4654
  const flags = [
4254
- a.required ? chalk4.red("required") : null,
4655
+ a.required ? chalk5.red("required") : null,
4255
4656
  a.enum ? `enum[${a.enum.join("|")}]` : null,
4256
4657
  a.default !== void 0 ? `default=${a.default}` : null
4257
4658
  ].filter(Boolean).join(", ");
4258
4659
  console.log(
4259
- ` ${chalk4.yellow(a.name)}: ${a.type}${flags ? ` (${flags})` : ""}`
4660
+ ` ${chalk5.yellow(a.name)}: ${a.type}${flags ? ` (${flags})` : ""}`
4260
4661
  );
4261
- if (a.description) console.log(` ${chalk4.dim(a.description)}`);
4662
+ if (a.description) console.log(` ${chalk5.dim(a.description)}`);
4262
4663
  }
4263
4664
  const rels = registry.getRelationsForType(name);
4264
4665
  if (rels.length > 0) {
4265
- console.log(chalk4.bold("\nRelations:"));
4666
+ console.log(chalk5.bold("\nRelations:"));
4266
4667
  for (const r of rels) {
4267
4668
  const dir = r.sourceTypes.includes(name) ? "\u2192" : "\u2190";
4268
4669
  console.log(
4269
- ` ${chalk4.yellow(r.name)} ${dir} ${r.sourceTypes.includes(name) ? r.targetTypes.join("|") : r.sourceTypes.join("|")}`
4670
+ ` ${chalk5.yellow(r.name)} ${dir} ${r.sourceTypes.includes(name) ? r.targetTypes.join("|") : r.sourceTypes.join("|")}`
4270
4671
  );
4271
4672
  }
4272
4673
  }
4273
4674
  return;
4274
4675
  }
4275
- console.error(chalk4.red(`Unknown ontology or entity type: "${name}"`));
4676
+ console.error(chalk5.red(`Unknown ontology or entity type: "${name}"`));
4276
4677
  console.log(
4277
- chalk4.dim(
4678
+ chalk5.dim(
4278
4679
  "Available ontologies: " + registry.list().map((s) => s.id).join(", ")
4279
4680
  )
4280
4681
  );
4281
4682
  console.log(
4282
- chalk4.dim("Available types: " + registry.listEntityTypes().join(", "))
4683
+ chalk5.dim("Available types: " + registry.listEntityTypes().join(", "))
4283
4684
  );
4284
4685
  });
4285
4686
  ontologyCmd.command("validate").description(
@@ -4293,32 +4694,32 @@ ontologyCmd.command("validate").description(
4293
4694
  const store = kernel.getStore();
4294
4695
  const result = validateStore(store, registry);
4295
4696
  if (result.errors.length > 0) {
4296
- console.log(chalk4.red.bold(`\u2717 ${result.errors.length} error(s):
4697
+ console.log(chalk5.red.bold(`\u2717 ${result.errors.length} error(s):
4297
4698
  `));
4298
4699
  for (const err of result.errors) {
4299
4700
  console.log(
4300
- ` ${chalk4.red("ERROR")} ${chalk4.bold(err.entityId)} (${err.entityType}) \u2192 ${err.field}: ${err.message}`
4701
+ ` ${chalk5.red("ERROR")} ${chalk5.bold(err.entityId)} (${err.entityType}) \u2192 ${err.field}: ${err.message}`
4301
4702
  );
4302
4703
  }
4303
4704
  }
4304
4705
  if (result.warnings.length > 0) {
4305
4706
  console.log(
4306
- chalk4.yellow.bold(`
4707
+ chalk5.yellow.bold(`
4307
4708
  \u26A0 ${result.warnings.length} warning(s):
4308
4709
  `)
4309
4710
  );
4310
4711
  for (const w of result.warnings) {
4311
4712
  console.log(
4312
- ` ${chalk4.yellow("WARN")} ${chalk4.bold(w.entityId)} (${w.entityType}) \u2192 ${w.field}: ${w.message}`
4713
+ ` ${chalk5.yellow("WARN")} ${chalk5.bold(w.entityId)} (${w.entityType}) \u2192 ${w.field}: ${w.message}`
4313
4714
  );
4314
4715
  }
4315
4716
  }
4316
4717
  if (result.valid && result.warnings.length === 0) {
4317
- console.log(chalk4.green("\u2713 All entities pass ontology validation."));
4718
+ console.log(chalk5.green("\u2713 All entities pass ontology validation."));
4318
4719
  } else if (result.valid) {
4319
- console.log(chalk4.green("\n\u2713 Valid (with warnings)."));
4720
+ console.log(chalk5.green("\n\u2713 Valid (with warnings)."));
4320
4721
  } else {
4321
- console.log(chalk4.red("\n\u2717 Validation failed."));
4722
+ console.log(chalk5.red("\n\u2717 Validation failed."));
4322
4723
  }
4323
4724
  } finally {
4324
4725
  kernel.close();
@@ -4326,7 +4727,7 @@ ontologyCmd.command("validate").description(
4326
4727
  });
4327
4728
  program.command("ask").description("Natural language search over the graph (semantic search)").argument("<question>", "Natural language query").option("-p, --path <path>", "Repository path", ".").option("-n, --limit <n>", "Max results", "5").option("--json", "Output as JSON").option("--rag", "Output as RAG context (for LLM consumption)").action(async (question, opts) => {
4328
4729
  const rootPath = resolveRepoRoot(opts.path);
4329
- const dbPath = join6(rootPath, ".trellis", "embeddings.db");
4730
+ const dbPath = join7(rootPath, ".trellis", "embeddings.db");
4330
4731
  const vectorStore = await VectorStore.create(dbPath);
4331
4732
  try {
4332
4733
  const limit = parseInt(opts.limit, 10) || 5;
@@ -4337,17 +4738,17 @@ program.command("ask").description("Natural language search over the graph (sema
4337
4738
  if (opts.json) {
4338
4739
  console.log(JSON.stringify(ctx, null, 2));
4339
4740
  } else {
4340
- console.log(chalk4.bold.cyan("RAG Context"));
4341
- console.log(chalk4.dim(`Query: ${ctx.query}`));
4741
+ console.log(chalk5.bold.cyan("RAG Context"));
4742
+ console.log(chalk5.dim(`Query: ${ctx.query}`));
4342
4743
  console.log(
4343
- chalk4.dim(
4744
+ chalk5.dim(
4344
4745
  `Chunks: ${ctx.chunks.length} | ~${ctx.estimatedTokens} tokens
4345
4746
  `
4346
4747
  )
4347
4748
  );
4348
4749
  for (const c of ctx.chunks) {
4349
4750
  console.log(
4350
- chalk4.yellow(
4751
+ chalk5.yellow(
4351
4752
  `[${c.score.toFixed(3)}] ${c.entityId} (${c.chunkType})`
4352
4753
  )
4353
4754
  );
@@ -4374,17 +4775,17 @@ program.command("ask").description("Natural language search over the graph (sema
4374
4775
  } else {
4375
4776
  if (results.length === 0) {
4376
4777
  console.log(
4377
- chalk4.dim(
4778
+ chalk5.dim(
4378
4779
  "No results. Run `trellis reindex` first to build the embedding index."
4379
4780
  )
4380
4781
  );
4381
4782
  } else {
4382
- console.log(chalk4.bold(`Results for: "${question}"
4783
+ console.log(chalk5.bold(`Results for: "${question}"
4383
4784
  `));
4384
4785
  for (const r of results) {
4385
- const score = chalk4.dim(`[${r.score.toFixed(3)}]`);
4386
- const entity = chalk4.cyan(r.chunk.entityId);
4387
- const type = chalk4.dim(`(${r.chunk.chunkType})`);
4786
+ const score = chalk5.dim(`[${r.score.toFixed(3)}]`);
4787
+ const entity = chalk5.cyan(r.chunk.entityId);
4788
+ const type = chalk5.dim(`(${r.chunk.chunkType})`);
4388
4789
  console.log(`${score} ${entity} ${type}`);
4389
4790
  const preview = r.chunk.content.length > 200 ? r.chunk.content.slice(0, 200) + "\u2026" : r.chunk.content;
4390
4791
  console.log(` ${preview}
@@ -4395,10 +4796,10 @@ program.command("ask").description("Natural language search over the graph (sema
4395
4796
  }
4396
4797
  } catch (err) {
4397
4798
  if (err.message?.includes("No transformers")) {
4398
- console.error(chalk4.red("Embedding model not available."));
4399
- console.error(chalk4.dim("Install: bun add @huggingface/transformers"));
4799
+ console.error(chalk5.red("Embedding model not available."));
4800
+ console.error(chalk5.dim("Install: bun add @huggingface/transformers"));
4400
4801
  } else {
4401
- console.error(chalk4.red(`Error: ${err.message}`));
4802
+ console.error(chalk5.red(`Error: ${err.message}`));
4402
4803
  }
4403
4804
  } finally {
4404
4805
  vectorStore.close();
@@ -4406,16 +4807,16 @@ program.command("ask").description("Natural language search over the graph (sema
4406
4807
  });
4407
4808
  function formatOpKind(kind) {
4408
4809
  const kindMap = {
4409
- "vcs:fileAdd": chalk4.green("+add"),
4410
- "vcs:fileModify": chalk4.yellow("~mod"),
4411
- "vcs:fileDelete": chalk4.red("-del"),
4412
- "vcs:fileRename": chalk4.blue("\u2192ren"),
4413
- "vcs:branchCreate": chalk4.magenta("\u2295branch"),
4414
- "vcs:branchAdvance": chalk4.magenta("\u2192branch"),
4415
- "vcs:milestoneCreate": chalk4.cyan("\u2605milestone"),
4416
- "vcs:checkpointCreate": chalk4.dim("\u25CFcheckpoint")
4810
+ "vcs:fileAdd": chalk5.green("+add"),
4811
+ "vcs:fileModify": chalk5.yellow("~mod"),
4812
+ "vcs:fileDelete": chalk5.red("-del"),
4813
+ "vcs:fileRename": chalk5.blue("\u2192ren"),
4814
+ "vcs:branchCreate": chalk5.magenta("\u2295branch"),
4815
+ "vcs:branchAdvance": chalk5.magenta("\u2192branch"),
4816
+ "vcs:milestoneCreate": chalk5.cyan("\u2605milestone"),
4817
+ "vcs:checkpointCreate": chalk5.dim("\u25CFcheckpoint")
4417
4818
  };
4418
- return kindMap[kind] ?? chalk4.dim(kind);
4819
+ return kindMap[kind] ?? chalk5.dim(kind);
4419
4820
  }
4420
4821
  function formatRelativeTime2(iso) {
4421
4822
  const now = Date.now();
@@ -4428,11 +4829,11 @@ function formatRelativeTime2(iso) {
4428
4829
  }
4429
4830
  var db = program.command("db").description("Trellis DB \u2014 use Trellis as an application database");
4430
4831
  db.command("init").description("Initialize a new Trellis DB in the current directory").option("-p, --path <path>", "Database directory", ".trellis-db").option("--port <port>", "Server port", "3000").option("--key <key>", "API key (auto-generated if omitted)").option("--jwt-secret <secret>", "JWT secret (auto-generated if omitted)").option("--multi-tenant", "Enable multi-tenancy (separate SQLite per tenant)").action(async (opts) => {
4431
- const { writeConfig, defaultLocalConfig, hasConfig, configPath } = await import("../config-PFTP67TR.js");
4832
+ const { writeConfig, defaultLocalConfig, hasConfig, configPath } = await import("../config-KMY6RRK3.js");
4432
4833
  const { resolve: resolve3 } = await import("path");
4433
4834
  if (hasConfig(".")) {
4434
4835
  console.log(
4435
- chalk4.yellow(
4836
+ chalk5.yellow(
4436
4837
  `Already initialized (${configPath(".")}). Use \`trellis db serve\` to start.`
4437
4838
  )
4438
4839
  );
@@ -4450,52 +4851,54 @@ db.command("init").description("Initialize a new Trellis DB in the current direc
4450
4851
  }),
4451
4852
  "."
4452
4853
  );
4453
- console.log(chalk4.green("\u2713 Trellis DB initialized"));
4454
- console.log(chalk4.dim(` Config: .trellis-db.json`));
4455
- console.log(chalk4.dim(` DB path: ${dbPath}`));
4456
- console.log(chalk4.dim(` API key: ${apiKey}`));
4457
- console.log(chalk4.dim(` Port: ${opts.port}`));
4854
+ console.log(chalk5.green("\u2713 Trellis DB initialized"));
4855
+ console.log(chalk5.dim(` Config: .trellis-db.json`));
4856
+ console.log(chalk5.dim(` DB path: ${dbPath}`));
4857
+ console.log(chalk5.dim(` API key: ${apiKey}`));
4858
+ console.log(chalk5.dim(` Port: ${opts.port}`));
4458
4859
  console.log("");
4459
- console.log(chalk4.bold("Next steps:"));
4860
+ console.log(chalk5.bold("Next steps:"));
4460
4861
  console.log(
4461
- ` ${chalk4.cyan("trellis db serve")} Start the local HTTP server`
4862
+ ` ${chalk5.cyan("trellis db serve")} Start the local HTTP server`
4462
4863
  );
4463
4864
  console.log(
4464
- ` ${chalk4.cyan("trellis deploy --name <n>")} Deploy room node to Sprites`
4865
+ ` ${chalk5.cyan("trellis deploy --name <n>")} Deploy room node to Sprites`
4465
4866
  );
4466
4867
  });
4467
4868
  db.command("serve").description("Start the Trellis DB HTTP + WebSocket server").option("-p, --port <port>", "Override port from config").option("--config-dir <dir>", "Directory containing .trellis-db.json", ".").action(async (opts) => {
4468
- const { readConfig } = await import("../config-PFTP67TR.js");
4469
- const { TenantPool } = await import("../tenancy-POMWQP6M.js");
4470
- const { startServer } = await import("../server-ZVWGLLRF.js");
4869
+ const { readConfig } = await import("../config-KMY6RRK3.js");
4870
+ const { TenantPool } = await import("../tenancy-U4E7ZEAG.js");
4871
+ const { startServer } = await import("../server-FQT2VYRE.js");
4471
4872
  const config = readConfig(opts.configDir);
4472
4873
  if (!config) {
4473
4874
  console.error(
4474
- chalk4.red("No .trellis-db.json found. Run `trellis db init` first.")
4875
+ chalk5.red("No .trellis-db.json found. Run `trellis db init` first.")
4475
4876
  );
4476
4877
  process.exit(1);
4477
4878
  }
4478
4879
  if (!config.dbPath) {
4479
4880
  console.error(
4480
- chalk4.red("Config is missing dbPath. Re-run `trellis db init`.")
4881
+ chalk5.red("Config is missing dbPath. Re-run `trellis db init`.")
4481
4882
  );
4482
4883
  process.exit(1);
4483
4884
  }
4484
4885
  const port = opts.port ? parseInt(opts.port) : config.port ?? 3e3;
4485
- const { DEFAULT_TENANT, resolvePoolBackendFromEnv } = await import("../tenancy-POMWQP6M.js");
4886
+ const { DEFAULT_TENANT, resolvePoolBackendFromEnv } = await import("../tenancy-U4E7ZEAG.js");
4486
4887
  const backendOpts = resolvePoolBackendFromEnv();
4487
4888
  const pool = new TenantPool(
4488
4889
  config.dbPath,
4489
4890
  backendOpts ? { backend: backendOpts } : void 0
4490
4891
  );
4491
4892
  await pool.preload(DEFAULT_TENANT);
4492
- const { startServerCrossRuntime } = await import("../server-ZVWGLLRF.js");
4893
+ const { startServerCrossRuntime } = await import("../server-FQT2VYRE.js");
4493
4894
  const server = await startServerCrossRuntime({ port, config, pool });
4494
- console.log(chalk4.green(`\u2713 Trellis DB running`));
4495
- console.log(chalk4.dim(` URL: http://localhost:${port}`));
4496
- console.log(chalk4.dim(` Docs: GET http://localhost:${port}/health`));
4895
+ console.log(chalk5.green(`\u2713 Trellis DB running`));
4896
+ console.log(chalk5.dim(` URL: http://localhost:${port}`));
4897
+ console.log(chalk5.dim(` MCP: http://localhost:${port}/mcp`));
4898
+ console.log(chalk5.dim(` Gateway: http://localhost:${port}/gateway/mcp`));
4899
+ console.log(chalk5.dim(` Docs: GET http://localhost:${port}/health`));
4497
4900
  if (config.apiKey) {
4498
- console.log(chalk4.dim(` Key: ${config.apiKey}`));
4901
+ console.log(chalk5.dim(` Key: ${config.apiKey}`));
4499
4902
  }
4500
4903
  });
4501
4904
  db.command("create <type> [json]").description("Create an entity (json can be a JSON string or @file.json)").option("--config-dir <dir>", "Config directory", ".").option("--tenant <id>", "Tenant ID").action(async (type, jsonArg, opts) => {
@@ -4503,12 +4906,12 @@ db.command("create <type> [json]").description("Create an entity (json can be a
4503
4906
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4504
4907
  let attributes = {};
4505
4908
  if (jsonArg) {
4506
- const { readFileSync: readFileSync5 } = await import("fs");
4507
- const raw = jsonArg.startsWith("@") ? readFileSync5(jsonArg.slice(1), "utf8") : jsonArg;
4909
+ const { readFileSync: readFileSync7 } = await import("fs");
4910
+ const raw = jsonArg.startsWith("@") ? readFileSync7(jsonArg.slice(1), "utf8") : jsonArg;
4508
4911
  attributes = JSON.parse(raw);
4509
4912
  }
4510
4913
  const id = await db2.create(type, attributes);
4511
- console.log(chalk4.green(`\u2713 Created: ${chalk4.bold(id)}`));
4914
+ console.log(chalk5.green(`\u2713 Created: ${chalk5.bold(id)}`));
4512
4915
  db2.close();
4513
4916
  });
4514
4917
  db.command("read <id>").description("Read an entity by ID").option("--config-dir <dir>", "Config directory", ".").action(async (id, opts) => {
@@ -4516,7 +4919,7 @@ db.command("read <id>").description("Read an entity by ID").option("--config-dir
4516
4919
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4517
4920
  const entity = await db2.read(id);
4518
4921
  if (!entity) {
4519
- console.error(chalk4.red(`Not found: ${id}`));
4922
+ console.error(chalk5.red(`Not found: ${id}`));
4520
4923
  process.exit(1);
4521
4924
  }
4522
4925
  console.log(JSON.stringify(entity, null, 2));
@@ -4525,17 +4928,17 @@ db.command("read <id>").description("Read an entity by ID").option("--config-dir
4525
4928
  db.command("update <id> <json>").description("Update entity attributes (JSON string or @file.json)").option("--config-dir <dir>", "Config directory", ".").action(async (id, jsonArg, opts) => {
4526
4929
  const { TrellisDb } = await import("../client/sdk.js");
4527
4930
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4528
- const { readFileSync: readFileSync5 } = await import("fs");
4529
- const raw = jsonArg.startsWith("@") ? readFileSync5(jsonArg.slice(1), "utf8") : jsonArg;
4931
+ const { readFileSync: readFileSync7 } = await import("fs");
4932
+ const raw = jsonArg.startsWith("@") ? readFileSync7(jsonArg.slice(1), "utf8") : jsonArg;
4530
4933
  await db2.update(id, JSON.parse(raw));
4531
- console.log(chalk4.green(`\u2713 Updated: ${chalk4.bold(id)}`));
4934
+ console.log(chalk5.green(`\u2713 Updated: ${chalk5.bold(id)}`));
4532
4935
  db2.close();
4533
4936
  });
4534
4937
  db.command("delete <id>").description("Delete an entity by ID").option("--config-dir <dir>", "Config directory", ".").action(async (id, opts) => {
4535
4938
  const { TrellisDb } = await import("../client/sdk.js");
4536
4939
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4537
4940
  await db2.delete(id);
4538
- console.log(chalk4.green(`\u2713 Deleted: ${chalk4.bold(id)}`));
4941
+ console.log(chalk5.green(`\u2713 Deleted: ${chalk5.bold(id)}`));
4539
4942
  db2.close();
4540
4943
  });
4541
4944
  db.command("list").description("List entities").option("--type <type>", "Filter by entity type").option("--limit <n>", "Max results", "50").option("--offset <n>", "Offset", "0").option("--config-dir <dir>", "Config directory", ".").action(async (opts) => {
@@ -4553,11 +4956,11 @@ db.command("query <eql>").description("Run an EQL-S query").option("--config-dir
4553
4956
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4554
4957
  const result = await db2.query(eql);
4555
4958
  console.log(JSON.stringify(result.bindings, null, 2));
4556
- console.log(chalk4.dim(`Execution time: ${result.executionTime}ms`));
4959
+ console.log(chalk5.dim(`Execution time: ${result.executionTime}ms`));
4557
4960
  db2.close();
4558
4961
  });
4559
4962
  db.command("upload <file>").description("Upload a file to the blob store").option("--config-dir <dir>", "Config directory", ".").option("--type <mime>", "MIME type (auto-detected if omitted)").action(async (filePath, opts) => {
4560
- const { readFileSync: readFileSync5 } = await import("fs");
4963
+ const { readFileSync: readFileSync7 } = await import("fs");
4561
4964
  const { extname } = await import("path");
4562
4965
  const { TrellisDb } = await import("../client/sdk.js");
4563
4966
  const mimeMap = {
@@ -4570,22 +4973,22 @@ db.command("upload <file>").description("Upload a file to the blob store").optio
4570
4973
  ".txt": "text/plain"
4571
4974
  };
4572
4975
  const contentType = opts.type ?? mimeMap[extname(filePath).toLowerCase()] ?? "application/octet-stream";
4573
- const buffer = readFileSync5(filePath);
4976
+ const buffer = readFileSync7(filePath);
4574
4977
  const db2 = await TrellisDb.fromConfig(opts.configDir);
4575
4978
  const result = await db2.upload(new Uint8Array(buffer), contentType);
4576
- console.log(chalk4.green(`\u2713 Uploaded`));
4577
- console.log(chalk4.dim(` Hash: ${result.hash}`));
4578
- console.log(chalk4.dim(` Size: ${result.size} bytes`));
4979
+ console.log(chalk5.green(`\u2713 Uploaded`));
4980
+ console.log(chalk5.dim(` Hash: ${result.hash}`));
4981
+ console.log(chalk5.dim(` Size: ${result.size} bytes`));
4579
4982
  db2.close();
4580
4983
  });
4581
4984
  db.command("import <file>").description("Import data from CSV, JSON, NDJSON, or Parquet").requiredOption("--type <type>", "Entity type to assign to each record").option("--id-field <field>", "Field to use as entity ID").option("--limit <n>", "Max rows to import").option("--config-dir <dir>", "Config directory", ".").option("--tenant <id>", "Tenant ID").action(async (filePath, opts) => {
4582
- const { readConfig } = await import("../config-PFTP67TR.js");
4583
- const { TenantPool } = await import("../tenancy-POMWQP6M.js");
4584
- const { importFile } = await import("../import-UZEKXU3B.js");
4985
+ const { readConfig } = await import("../config-KMY6RRK3.js");
4986
+ const { TenantPool } = await import("../tenancy-U4E7ZEAG.js");
4987
+ const { importFile } = await import("../import-AJLYHFIA.js");
4585
4988
  const config = readConfig(opts.configDir);
4586
4989
  if (!config?.dbPath) {
4587
4990
  console.error(
4588
- chalk4.red("No .trellis-db.json found. Run `trellis db init` first.")
4991
+ chalk5.red("No .trellis-db.json found. Run `trellis db init` first.")
4589
4992
  );
4590
4993
  process.exit(1);
4591
4994
  }
@@ -4596,13 +4999,13 @@ db.command("import <file>").description("Import data from CSV, JSON, NDJSON, or
4596
4999
  idField: opts.idField,
4597
5000
  limit: opts.limit ? parseInt(opts.limit) : void 0
4598
5001
  });
4599
- console.log(chalk4.green(`\u2713 Import complete`));
4600
- console.log(chalk4.dim(` Imported: ${result.imported}`));
4601
- console.log(chalk4.dim(` Skipped: ${result.skipped}`));
5002
+ console.log(chalk5.green(`\u2713 Import complete`));
5003
+ console.log(chalk5.dim(` Imported: ${result.imported}`));
5004
+ console.log(chalk5.dim(` Skipped: ${result.skipped}`));
4602
5005
  if (result.errors.length > 0) {
4603
- console.log(chalk4.yellow(` Errors: ${result.errors.length}`));
5006
+ console.log(chalk5.yellow(` Errors: ${result.errors.length}`));
4604
5007
  result.errors.slice(0, 5).forEach((e) => {
4605
- console.log(chalk4.red(` Row ${e.row}: ${e.message}`));
5008
+ console.log(chalk5.red(` Row ${e.row}: ${e.message}`));
4606
5009
  });
4607
5010
  }
4608
5011
  pool.closeAll();
@@ -4621,7 +5024,7 @@ function registerDeployOptions(cmd) {
4621
5024
  );
4622
5025
  }
4623
5026
  async function handleDeployCommand(opts) {
4624
- const { runDeployCli } = await import("../deploy-cli-C35HTITO.js");
5027
+ const { runDeployCli } = await import("./deploy-cli.js");
4625
5028
  await runDeployCli(opts);
4626
5029
  }
4627
5030
  registerDeployOptions(
@@ -4634,7 +5037,7 @@ var vmProgram = new Command("vm");
4634
5037
  vmProgram.description("Manage Sprites VMs").option("-s, --sprite <name>", "Sprite name to operate on");
4635
5038
  async function getSpriteName(spriteOption) {
4636
5039
  if (spriteOption) return spriteOption;
4637
- const { getActiveSprite } = await import("../vm-config-JI4OXKDQ.js");
5040
+ const { getActiveSprite } = await import("../vm-config-YZRJ3KUB.js");
4638
5041
  const active = getActiveSprite();
4639
5042
  if (active) return active;
4640
5043
  throw new Error(
@@ -4642,9 +5045,9 @@ async function getSpriteName(spriteOption) {
4642
5045
  );
4643
5046
  }
4644
5047
  vmProgram.command("create <name>").description("Create a new Sprite and deploy Trellis DB").option("-k, --api-key <key>", "API key (auto-generated if omitted)").option("-p, --port <port>", "Port (default: 3000)", "3000").action(async (name, cmdOpts) => {
4645
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4646
- const { trackSprite } = await import("../vm-config-JI4OXKDQ.js");
4647
- const { deploy } = await import("../deploy-LQ7GUGJ5.js");
5048
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5049
+ const { trackSprite } = await import("../vm-config-YZRJ3KUB.js");
5050
+ const { deploy } = await import("../server/deploy.js");
4648
5051
  try {
4649
5052
  await assertSpriteCli();
4650
5053
  console.log(`Creating Sprite: ${name}...`);
@@ -4654,7 +5057,7 @@ vmProgram.command("create <name>").description("Create a new Sprite and deploy T
4654
5057
  name,
4655
5058
  apiKey: cmdOpts.apiKey,
4656
5059
  port: parseInt(cmdOpts.port),
4657
- onProgress: (msg) => console.log(chalk4.dim(` ${msg}`))
5060
+ onProgress: (msg) => console.log(chalk5.dim(` ${msg}`))
4658
5061
  });
4659
5062
  trackSprite(name, {
4660
5063
  url: result.url,
@@ -4663,18 +5066,18 @@ vmProgram.command("create <name>").description("Create a new Sprite and deploy T
4663
5066
  });
4664
5067
  console.log("");
4665
5068
  console.log(
4666
- chalk4.green(`\u2713 Sprite ${name} created and Trellis DB deployed`)
5069
+ chalk5.green(`\u2713 Sprite ${name} created and Trellis DB deployed`)
4667
5070
  );
4668
- console.log(chalk4.dim(` URL: ${result.url}`));
4669
- console.log(chalk4.dim(` Key: ${result.apiKey}`));
5071
+ console.log(chalk5.dim(` URL: ${result.url}`));
5072
+ console.log(chalk5.dim(` Key: ${result.apiKey}`));
4670
5073
  console.log("");
4671
5074
  } catch (err) {
4672
- console.error(chalk4.red(`Failed: ${err.message}`));
5075
+ console.error(chalk5.red(`Failed: ${err.message}`));
4673
5076
  process.exit(1);
4674
5077
  }
4675
5078
  });
4676
5079
  vmProgram.command("list").description("List all tracked Sprites").action(async () => {
4677
- const { loadVmConfig } = await import("../vm-config-JI4OXKDQ.js");
5080
+ const { loadVmConfig } = await import("../vm-config-YZRJ3KUB.js");
4678
5081
  const config = loadVmConfig();
4679
5082
  const sprites = config.sprites;
4680
5083
  if (Object.keys(sprites).length === 0) {
@@ -4685,8 +5088,8 @@ vmProgram.command("list").description("List all tracked Sprites").action(async (
4685
5088
  }
4686
5089
  console.log("Tracked Sprites:");
4687
5090
  for (const [name, sprite] of Object.entries(sprites)) {
4688
- const activeMarker = config.activeSprite === name ? chalk4.green("*") : " ";
4689
- const trellisStatus = sprite.hasTrellis ? chalk4.green("\u2713 Trellis") : chalk4.dim("\u25CB No Trellis");
5091
+ const activeMarker = config.activeSprite === name ? chalk5.green("*") : " ";
5092
+ const trellisStatus = sprite.hasTrellis ? chalk5.green("\u2713 Trellis") : chalk5.dim("\u25CB No Trellis");
4690
5093
  console.log(`${activeMarker} ${name} ${trellisStatus}`);
4691
5094
  console.log(` URL: ${sprite.url}`);
4692
5095
  if (sprite.lastCheckpoint) {
@@ -4696,8 +5099,8 @@ vmProgram.command("list").description("List all tracked Sprites").action(async (
4696
5099
  }
4697
5100
  });
4698
5101
  vmProgram.command("use <name>").description("Set the active Sprite").action(async (name) => {
4699
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4700
- const { setActiveSprite } = await import("../vm-config-JI4OXKDQ.js");
5102
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5103
+ const { setActiveSprite } = await import("../vm-config-YZRJ3KUB.js");
4701
5104
  try {
4702
5105
  await assertSpriteCli();
4703
5106
  try {
@@ -4706,15 +5109,15 @@ vmProgram.command("use <name>").description("Set the active Sprite").action(asyn
4706
5109
  throw new Error(`Sprite ${name} does not exist`);
4707
5110
  }
4708
5111
  setActiveSprite(name);
4709
- console.log(chalk4.green(`\u2713 Active Sprite set to: ${name}`));
5112
+ console.log(chalk5.green(`\u2713 Active Sprite set to: ${name}`));
4710
5113
  } catch (err) {
4711
- console.error(chalk4.red(`Failed: ${err.message}`));
5114
+ console.error(chalk5.red(`Failed: ${err.message}`));
4712
5115
  process.exit(1);
4713
5116
  }
4714
5117
  });
4715
5118
  vmProgram.command("destroy <name>").description("Destroy a Sprite").action(async (name) => {
4716
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4717
- const { untrackSprite } = await import("../vm-config-JI4OXKDQ.js");
5119
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5120
+ const { untrackSprite } = await import("../vm-config-YZRJ3KUB.js");
4718
5121
  try {
4719
5122
  await assertSpriteCli();
4720
5123
  const { createInterface } = await import("readline");
@@ -4737,36 +5140,36 @@ vmProgram.command("destroy <name>").description("Destroy a Sprite").action(async
4737
5140
  }
4738
5141
  await runSpriteCmd(["destroy", "-s", name, "-y"]);
4739
5142
  untrackSprite(name);
4740
- console.log(chalk4.green(`\u2713 Sprite ${name} destroyed`));
5143
+ console.log(chalk5.green(`\u2713 Sprite ${name} destroyed`));
4741
5144
  } catch (err) {
4742
- console.error(chalk4.red(`Failed: ${err.message}`));
5145
+ console.error(chalk5.red(`Failed: ${err.message}`));
4743
5146
  process.exit(1);
4744
5147
  }
4745
5148
  });
4746
5149
  vmProgram.command("exec <command...>").description("Execute a command on the active Sprite").action(async (command) => {
4747
- const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5150
+ const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4748
5151
  try {
4749
5152
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4750
5153
  console.log(`Executing on ${spriteName}: ${command.join(" ")}`);
4751
5154
  await runSpriteInteractive(["exec", "--sprite", spriteName, ...command]);
4752
5155
  } catch (err) {
4753
- console.error(chalk4.red(`Failed: ${err.message}`));
5156
+ console.error(chalk5.red(`Failed: ${err.message}`));
4754
5157
  process.exit(1);
4755
5158
  }
4756
5159
  });
4757
5160
  vmProgram.command("console").description("Open an interactive console on the active Sprite").action(async () => {
4758
- const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5161
+ const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4759
5162
  try {
4760
5163
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4761
5164
  console.log(`Opening console on ${spriteName}...`);
4762
5165
  await runSpriteInteractive(["console", "--sprite", spriteName]);
4763
5166
  } catch (err) {
4764
- console.error(chalk4.red(`Failed: ${err.message}`));
5167
+ console.error(chalk5.red(`Failed: ${err.message}`));
4765
5168
  process.exit(1);
4766
5169
  }
4767
5170
  });
4768
5171
  vmProgram.command("sessions").description("Manage Sprite sessions").argument("<action>", "Action: list, attach, or kill").argument("[sessionId]", "Session ID (required for attach/kill)").action(async (action, sessionId) => {
4769
- const { runSpriteCmd, runSpriteInteractive, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5172
+ const { runSpriteCmd, runSpriteInteractive, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4770
5173
  try {
4771
5174
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4772
5175
  switch (action) {
@@ -4792,23 +5195,23 @@ vmProgram.command("sessions").description("Manage Sprite sessions").argument("<a
4792
5195
  spriteName,
4793
5196
  sessionId
4794
5197
  ]);
4795
- console.log(chalk4.green(`\u2713 Killed session ${sessionId}`));
5198
+ console.log(chalk5.green(`\u2713 Killed session ${sessionId}`));
4796
5199
  break;
4797
5200
  default:
4798
5201
  throw new Error(`Invalid action: ${action}`);
4799
5202
  }
4800
5203
  } catch (err) {
4801
- console.error(chalk4.red(`Failed: ${err.message}`));
5204
+ console.error(chalk5.red(`Failed: ${err.message}`));
4802
5205
  process.exit(1);
4803
5206
  }
4804
5207
  });
4805
5208
  vmProgram.command("url").description("Get or update the URL for the active Sprite").option("--public", "Get public URL (default)").option("--private", "Get private URL").option("--update-auth", "Update authentication").action(async (cmdOpts) => {
4806
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5209
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4807
5210
  try {
4808
5211
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4809
5212
  if (cmdOpts.updateAuth) {
4810
5213
  await runSpriteCmd(["url", "update", "--auth", "--sprite", spriteName]);
4811
- console.log(chalk4.green(`\u2713 Updated authentication for ${spriteName}`));
5214
+ console.log(chalk5.green(`\u2713 Updated authentication for ${spriteName}`));
4812
5215
  } else {
4813
5216
  const urlType = cmdOpts.private ? "private" : "public";
4814
5217
  const url = await runSpriteCmd([
@@ -4820,24 +5223,24 @@ vmProgram.command("url").description("Get or update the URL for the active Sprit
4820
5223
  console.log(url.trim());
4821
5224
  }
4822
5225
  } catch (err) {
4823
- console.error(chalk4.red(`Failed: ${err.message}`));
5226
+ console.error(chalk5.red(`Failed: ${err.message}`));
4824
5227
  process.exit(1);
4825
5228
  }
4826
5229
  });
4827
5230
  vmProgram.command("proxy <ports...>").description("Proxy local ports to the active Sprite").action(async (ports) => {
4828
- const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5231
+ const { runSpriteInteractive, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4829
5232
  try {
4830
5233
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4831
5234
  console.log(`Proxying ports ${ports.join(", ")} to ${spriteName}...`);
4832
5235
  await runSpriteInteractive(["proxy", "--sprite", spriteName, ...ports]);
4833
5236
  } catch (err) {
4834
- console.error(chalk4.red(`Failed: ${err.message}`));
5237
+ console.error(chalk5.red(`Failed: ${err.message}`));
4835
5238
  process.exit(1);
4836
5239
  }
4837
5240
  });
4838
5241
  vmProgram.command("checkpoint").description("Manage Sprite checkpoints").argument("<action>", "Action: create, list, or restore").option("-m, --milestone <msg>", "Message for linked milestone (create only)").option("-c, --checkpoint <id>", "Checkpoint ID (restore only)").action(async (action, cmdOpts) => {
4839
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4840
- const { loadVmConfig, trackSprite } = await import("../vm-config-JI4OXKDQ.js");
5242
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5243
+ const { loadVmConfig, trackSprite } = await import("../vm-config-YZRJ3KUB.js");
4841
5244
  try {
4842
5245
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4843
5246
  switch (action) {
@@ -4864,7 +5267,7 @@ vmProgram.command("checkpoint").description("Manage Sprite checkpoints").argumen
4864
5267
  linkedMilestone: milestoneId
4865
5268
  });
4866
5269
  console.log(
4867
- chalk4.green(`\u2713 Checkpoint: ${checkpointId || "unknown"}`)
5270
+ chalk5.green(`\u2713 Checkpoint: ${checkpointId || "unknown"}`)
4868
5271
  );
4869
5272
  break;
4870
5273
  case "list":
@@ -4880,18 +5283,18 @@ vmProgram.command("checkpoint").description("Manage Sprite checkpoints").argumen
4880
5283
  spriteName,
4881
5284
  cmdOpts.checkpoint
4882
5285
  ]);
4883
- console.log(chalk4.green(`\u2713 Restored: ${cmdOpts.checkpoint}`));
5286
+ console.log(chalk5.green(`\u2713 Restored: ${cmdOpts.checkpoint}`));
4884
5287
  break;
4885
5288
  default:
4886
5289
  throw new Error(`Invalid action: ${action}`);
4887
5290
  }
4888
5291
  } catch (err) {
4889
- console.error(chalk4.red(`Failed: ${err.message}`));
5292
+ console.error(chalk5.red(`Failed: ${err.message}`));
4890
5293
  process.exit(1);
4891
5294
  }
4892
5295
  });
4893
5296
  vmProgram.command("cp <src> <dest>").description("Copy files (use :prefix for remote paths)").action(async (src, dest) => {
4894
- const { runSpriteCmd, runSpriteCopy, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
5297
+ const { runSpriteCmd, runSpriteCopy, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
4895
5298
  try {
4896
5299
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4897
5300
  const isToSprite = !src.startsWith(":") && dest.startsWith(":");
@@ -4899,58 +5302,58 @@ vmProgram.command("cp <src> <dest>").description("Copy files (use :prefix for re
4899
5302
  if (isToSprite) {
4900
5303
  await runSpriteCopy(src, spriteName, dest.slice(1));
4901
5304
  console.log(
4902
- chalk4.green(`\u2713 Copied ${src} to ${spriteName}:${dest.slice(1)}`)
5305
+ chalk5.green(`\u2713 Copied ${src} to ${spriteName}:${dest.slice(1)}`)
4903
5306
  );
4904
5307
  } else if (isFromSprite) {
4905
5308
  await runSpriteCopy(src.slice(1), spriteName, dest);
4906
5309
  console.log(
4907
- chalk4.green(`\u2713 Copied ${spriteName}:${src.slice(1)} to ${dest}`)
5310
+ chalk5.green(`\u2713 Copied ${spriteName}:${src.slice(1)} to ${dest}`)
4908
5311
  );
4909
5312
  } else {
4910
5313
  await runSpriteCmd(["cp", src, dest]);
4911
- console.log(chalk4.green(`\u2713 Copied ${src} to ${dest}`));
5314
+ console.log(chalk5.green(`\u2713 Copied ${src} to ${dest}`));
4912
5315
  }
4913
5316
  } catch (err) {
4914
- console.error(chalk4.red(`Failed: ${err.message}`));
5317
+ console.error(chalk5.red(`Failed: ${err.message}`));
4915
5318
  process.exit(1);
4916
5319
  }
4917
5320
  });
4918
5321
  vmProgram.command("status").description("Show detailed status of the active Sprite").action(async () => {
4919
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4920
- const { loadVmConfig } = await import("../vm-config-JI4OXKDQ.js");
5322
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5323
+ const { loadVmConfig } = await import("../vm-config-YZRJ3KUB.js");
4921
5324
  try {
4922
5325
  const spriteName = await getSpriteName(vmProgram.opts().sprite);
4923
5326
  const config = loadVmConfig();
4924
5327
  const spriteConfig = config.sprites[spriteName];
4925
5328
  if (!spriteConfig) {
4926
- console.log(chalk4.red(`Sprite ${spriteName} not in config`));
5329
+ console.log(chalk5.red(`Sprite ${spriteName} not in config`));
4927
5330
  return;
4928
5331
  }
4929
- console.log(`Status for: ${chalk4.cyan(spriteName)}`);
5332
+ console.log(`Status for: ${chalk5.cyan(spriteName)}`);
4930
5333
  console.log(
4931
- ` Active: ${config.activeSprite === spriteName ? chalk4.green("yes") : chalk4.dim("no")}`
5334
+ ` Active: ${config.activeSprite === spriteName ? chalk5.green("yes") : chalk5.dim("no")}`
4932
5335
  );
4933
5336
  console.log(` URL: ${spriteConfig.url}`);
4934
5337
  console.log(
4935
- ` Trellis: ${spriteConfig.hasTrellis ? chalk4.green("yes") : chalk4.dim("no")}`
5338
+ ` Trellis: ${spriteConfig.hasTrellis ? chalk5.green("yes") : chalk5.dim("no")}`
4936
5339
  );
4937
5340
  if (spriteConfig.hasTrellis) {
4938
5341
  console.log(
4939
- ` API Key: ${spriteConfig.apiKey ?? chalk4.dim("not available")}`
5342
+ ` API Key: ${spriteConfig.apiKey ?? chalk5.dim("not available")}`
4940
5343
  );
4941
5344
  }
4942
5345
  if (spriteConfig.lastCheckpoint) {
4943
5346
  console.log(` Checkpoint: ${spriteConfig.lastCheckpoint}`);
4944
5347
  }
4945
5348
  } catch (err) {
4946
- console.error(chalk4.red(`Failed: ${err.message}`));
5349
+ console.error(chalk5.red(`Failed: ${err.message}`));
4947
5350
  process.exit(1);
4948
5351
  }
4949
5352
  });
4950
5353
  vmProgram.command("code [name]").description("Create Sprite, deploy Trellis, open in browser").action(async (nameOpt) => {
4951
- const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
4952
- const { loadVmConfig, trackSprite, getActiveSprite } = await import("../vm-config-JI4OXKDQ.js");
4953
- const { deploy } = await import("../deploy-LQ7GUGJ5.js");
5354
+ const { runSpriteCmd, assertSpriteCli } = await import("../sprites-NC6D7YZS.js");
5355
+ const { loadVmConfig, trackSprite, getActiveSprite } = await import("../vm-config-YZRJ3KUB.js");
5356
+ const { deploy } = await import("../server/deploy.js");
4954
5357
  const openUrl = (url) => {
4955
5358
  const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : null;
4956
5359
  if (!cmd) {
@@ -4980,20 +5383,20 @@ vmProgram.command("code [name]").description("Create Sprite, deploy Trellis, ope
4980
5383
  console.log(`Deploying Trellis to ${spriteName}...`);
4981
5384
  const result = await deploy({
4982
5385
  name: spriteName,
4983
- onProgress: (msg) => console.log(chalk4.dim(` ${msg}`))
5386
+ onProgress: (msg) => console.log(chalk5.dim(` ${msg}`))
4984
5387
  });
4985
5388
  trackSprite(spriteName, {
4986
5389
  url: result.url,
4987
5390
  hasTrellis: true,
4988
5391
  apiKey: result.apiKey
4989
5392
  });
4990
- console.log(chalk4.green(`\u2713 Deployed`));
5393
+ console.log(chalk5.green(`\u2713 Deployed`));
4991
5394
  }
4992
5395
  const url = spriteConfig?.url || `https://${spriteName}.sprites.app`;
4993
5396
  console.log(`Opening ${url}...`);
4994
5397
  openUrl(url);
4995
5398
  } catch (err) {
4996
- console.error(chalk4.red(`Failed: ${err.message}`));
5399
+ console.error(chalk5.red(`Failed: ${err.message}`));
4997
5400
  process.exit(1);
4998
5401
  }
4999
5402
  });
@@ -5008,11 +5411,11 @@ program.command("season").description("Enrich project context for agents \u2014
5008
5411
  const ask = (q) => new Promise((r) => rl.question(q, (a) => r(a.trim())));
5009
5412
  const context = await inferProjectContext(rootPath);
5010
5413
  console.log(
5011
- chalk4.bold("\n Trellis Season \u2014 let's enrich your project context\n")
5414
+ chalk5.bold("\n Trellis Season \u2014 let's enrich your project context\n")
5012
5415
  );
5013
- console.log(chalk4.dim(` Current domain: ${context.domain ?? "(none)"}`));
5416
+ console.log(chalk5.dim(` Current domain: ${context.domain ?? "(none)"}`));
5014
5417
  console.log(
5015
- chalk4.dim(` Current ecosystem: ${context.ecosystem ?? "(none)"}
5418
+ chalk5.dim(` Current ecosystem: ${context.ecosystem ?? "(none)"}
5016
5419
  `)
5017
5420
  );
5018
5421
  const domain = await ask(
@@ -5033,15 +5436,15 @@ program.command("season").description("Enrich project context for agents \u2014
5033
5436
  };
5034
5437
  const profile = loadProfile();
5035
5438
  writeAgentScaffold(rootPath, { profile, context: updatedContext });
5036
- const agentContextPath = join6(
5439
+ const agentContextPath = join7(
5037
5440
  rootPath,
5038
5441
  ".trellis",
5039
5442
  "agents",
5040
5443
  "agent-context.json"
5041
5444
  );
5042
5445
  try {
5043
- const { readFileSync: readFileSync5, writeFileSync: writeFileSync3 } = await import("fs");
5044
- const existing = JSON.parse(readFileSync5(agentContextPath, "utf-8"));
5446
+ const { readFileSync: readFileSync7, writeFileSync: writeFileSync4 } = await import("fs");
5447
+ const existing = JSON.parse(readFileSync7(agentContextPath, "utf-8"));
5045
5448
  existing.domain = updatedContext.domain;
5046
5449
  if (toolsRaw) {
5047
5450
  existing.tools = toolsRaw.split(",").map((s) => s.trim()).filter(Boolean);
@@ -5051,20 +5454,20 @@ program.command("season").description("Enrich project context for agents \u2014
5051
5454
  }
5052
5455
  existing.generatedAt = (/* @__PURE__ */ new Date()).toISOString();
5053
5456
  existing.confidence = "high";
5054
- writeFileSync3(agentContextPath, JSON.stringify(existing, null, 2));
5457
+ writeFileSync4(agentContextPath, JSON.stringify(existing, null, 2));
5055
5458
  } catch {
5056
5459
  }
5057
5460
  console.log();
5058
- console.log(chalk4.green("\u2713 Project context updated"));
5461
+ console.log(chalk5.green("\u2713 Project context updated"));
5059
5462
  console.log(
5060
- ` ${chalk4.dim("AGENTS.md:")} .trellis/agents/AGENTS.md`
5463
+ ` ${chalk5.dim("AGENTS.md:")} .trellis/agents/AGENTS.md`
5061
5464
  );
5062
5465
  console.log(
5063
- ` ${chalk4.dim("Agent config:")} .trellis/agents/agent-context.json`
5466
+ ` ${chalk5.dim("Agent config:")} .trellis/agents/agent-context.json`
5064
5467
  );
5065
5468
  if (updatedContext.domain) {
5066
5469
  console.log(
5067
- ` ${chalk4.dim("Domain:")} ${chalk4.cyan(updatedContext.domain)}`
5470
+ ` ${chalk5.dim("Domain:")} ${chalk5.cyan(updatedContext.domain)}`
5068
5471
  );
5069
5472
  }
5070
5473
  console.log();
@@ -5072,57 +5475,57 @@ program.command("season").description("Enrich project context for agents \u2014
5072
5475
  program.command("code").alias("ide").description(
5073
5476
  'Launch OpenCode in "Harness" mode, bridged to this Trellis repository'
5074
5477
  ).option("-p, --path <path>", "Repository path", ".").option("-m, --model <model>", "OpenCode model to use").option("-w, --web", "Launch MCP server in HTTP mode for web client access").option("--mcp-port <port>", "MCP HTTP server port (default: 3333)", "3333").option("--no-init", "Skip initialization even if not a Trellis workspace").action(async (opts) => {
5075
- const { resolve: resolve3, dirname: dirname7, join: join7 } = await import("path");
5076
- const { existsSync: existsSync6 } = await import("fs");
5478
+ const { resolve: resolve3, dirname: dirname7, join: join8 } = await import("path");
5479
+ const { existsSync: existsSync7 } = await import("fs");
5077
5480
  const { spawn } = await import("child_process");
5078
- const { readFileSync: readFileSync5 } = await import("fs");
5481
+ const { readFileSync: readFileSync7 } = await import("fs");
5079
5482
  const { createServer: createHttpServer } = await import("http");
5080
5483
  const rootPath = findRepoRoot(opts.path) ?? resolve3(opts.path);
5081
5484
  if (!opts.noInit) {
5082
5485
  if (!TrellisVcsEngine.isRepo(rootPath)) {
5083
- console.log(chalk4.dim("Not a Trellis workspace \u2014 initializing\u2026"));
5486
+ console.log(chalk5.dim("Not a Trellis workspace \u2014 initializing\u2026"));
5084
5487
  await runInit(rootPath, {
5085
5488
  interactive: false
5086
5489
  });
5087
- console.log(chalk4.green("\u2713 Initialized Trellis repository"));
5490
+ console.log(chalk5.green("\u2713 Initialized Trellis repository"));
5088
5491
  }
5089
5492
  }
5090
5493
  function findOpencode() {
5091
5494
  const here2 = dirname7(process.argv[1]);
5092
5495
  const candidates = [
5093
- join7(here2, "..", "node_modules", ".bin", "opencode"),
5094
- join7(here2, "..", "..", "node_modules", ".bin", "opencode")
5496
+ join8(here2, "..", "node_modules", ".bin", "opencode"),
5497
+ join8(here2, "..", "..", "node_modules", ".bin", "opencode")
5095
5498
  ];
5096
5499
  let dir = here2;
5097
5500
  for (let i = 0; i < 5; i++) {
5098
- const p = join7(dir, "node_modules", ".bin", "opencode");
5099
- if (existsSync6(p)) return p;
5501
+ const p = join8(dir, "node_modules", ".bin", "opencode");
5502
+ if (existsSync7(p)) return p;
5100
5503
  dir = dirname7(dir);
5101
5504
  }
5102
5505
  for (const p of candidates) {
5103
- if (existsSync6(p)) return p;
5506
+ if (existsSync7(p)) return p;
5104
5507
  }
5105
5508
  return null;
5106
5509
  }
5107
5510
  function findMcpServer() {
5108
5511
  const here2 = dirname7(process.argv[1]);
5109
5512
  const candidates = [
5110
- join7(here2, "..", "..", "src", "mcp", "index.ts"),
5111
- join7(here2, "..", "src", "mcp", "index.ts"),
5112
- join7(here2, "..", "..", "..", "src", "mcp", "index.ts"),
5113
- join7(here2, "..", "mcp", "index.js"),
5114
- join7(here2, "..", "mcp", "index.ts"),
5115
- join7(here2, "mcp", "index.ts")
5513
+ join8(here2, "..", "..", "src", "mcp", "index.ts"),
5514
+ join8(here2, "..", "src", "mcp", "index.ts"),
5515
+ join8(here2, "..", "..", "..", "src", "mcp", "index.ts"),
5516
+ join8(here2, "..", "mcp", "index.js"),
5517
+ join8(here2, "..", "mcp", "index.ts"),
5518
+ join8(here2, "mcp", "index.ts")
5116
5519
  ];
5117
5520
  for (const p of candidates) {
5118
- if (existsSync6(p)) return p;
5521
+ if (existsSync7(p)) return p;
5119
5522
  }
5120
5523
  return null;
5121
5524
  }
5122
5525
  const opencode = findOpencode();
5123
5526
  if (!opencode) {
5124
5527
  console.error(
5125
- chalk4.red(
5528
+ chalk5.red(
5126
5529
  "OpenCode not found. Try running `bun install` or `npm install -g opencode-ai`."
5127
5530
  )
5128
5531
  );
@@ -5130,22 +5533,22 @@ program.command("code").alias("ide").description(
5130
5533
  }
5131
5534
  const mcp = findMcpServer();
5132
5535
  if (!mcp) {
5133
- console.error(chalk4.red("Trellis MCP server not found."));
5536
+ console.error(chalk5.red("Trellis MCP server not found."));
5134
5537
  process.exit(1);
5135
5538
  }
5136
5539
  const mcpPort = parseInt(opts.mcpPort, 10) || 3333;
5137
5540
  const mcpUrl = `http://localhost:${mcpPort}`;
5138
- console.log(chalk4.green(`\u26A1 Spinning up Trellis Agentic Harness...`));
5139
- console.log(chalk4.dim(` Root: ${rootPath}`));
5140
- console.log(chalk4.dim(` MCP: ${mcp}`));
5141
- console.log(chalk4.dim(` Agent: OpenCode`));
5541
+ console.log(chalk5.green(`\u26A1 Spinning up Trellis Agentic Harness...`));
5542
+ console.log(chalk5.dim(` Root: ${rootPath}`));
5543
+ console.log(chalk5.dim(` MCP: ${mcp}`));
5544
+ console.log(chalk5.dim(` Agent: OpenCode`));
5142
5545
  if (opts.web) {
5143
- console.log(chalk4.dim(` Web: ${mcpUrl}`));
5546
+ console.log(chalk5.dim(` Web: ${mcpUrl}`));
5144
5547
  }
5145
5548
  console.log("");
5146
5549
  let mcpProcess = null;
5147
5550
  if (opts.web) {
5148
- console.log(chalk4.dim(` Starting MCP server on port ${mcpPort}\u2026`));
5551
+ console.log(chalk5.dim(` Starting MCP server on port ${mcpPort}\u2026`));
5149
5552
  mcpProcess = spawn(
5150
5553
  "bun",
5151
5554
  [
@@ -5166,26 +5569,26 @@ program.command("code").alias("ide").description(
5166
5569
  mcpProcess.stderr?.on("data", (data) => {
5167
5570
  const msg = data.toString();
5168
5571
  if (!msg.includes("TrellisVCS MCP Server")) {
5169
- process.stderr.write(chalk4.dim(` [mcp] ${msg}`));
5572
+ process.stderr.write(chalk5.dim(` [mcp] ${msg}`));
5170
5573
  }
5171
5574
  });
5172
5575
  mcpProcess.on("error", (err) => {
5173
5576
  console.error(
5174
- chalk4.red(`
5577
+ chalk5.red(`
5175
5578
  \u2717 MCP server failed to start: ${err.message}`)
5176
5579
  );
5177
5580
  process.exit(1);
5178
5581
  });
5179
5582
  const ready = await waitForMcpReady(mcpUrl, 1e4);
5180
5583
  if (!ready) {
5181
- console.error(chalk4.red(`
5584
+ console.error(chalk5.red(`
5182
5585
  \u2717 MCP server did not become ready in time`));
5183
5586
  if (mcpProcess) {
5184
5587
  mcpProcess.kill();
5185
5588
  }
5186
5589
  process.exit(1);
5187
5590
  }
5188
- console.log(chalk4.green(`\u2713 MCP server ready at ${mcpUrl}`));
5591
+ console.log(chalk5.green(`\u2713 MCP server ready at ${mcpUrl}`));
5189
5592
  }
5190
5593
  const args = [rootPath];
5191
5594
  if (opts.model) {
@@ -5217,9 +5620,9 @@ program.command("code").alias("ide").description(
5217
5620
  mcpProcess.kill();
5218
5621
  }
5219
5622
  if (code === 0) {
5220
- console.log(chalk4.green("\n\u2713 Agentic session complete."));
5623
+ console.log(chalk5.green("\n\u2713 Agentic session complete."));
5221
5624
  } else {
5222
- console.log(chalk4.yellow(`
5625
+ console.log(chalk5.yellow(`
5223
5626
  \u26A0 Agent session exited with code ${code}`));
5224
5627
  }
5225
5628
  process.exit(code ?? 0);
@@ -5230,27 +5633,27 @@ program.command("studio").alias("web").description("Launch Trellis Studio in you
5230
5633
  "Open the new-project prompt instead of the current directory"
5231
5634
  ).option("--no-open", "Do not auto-open the browser").option("--no-init", "Skip initialization even if not a Trellis workspace").option("--quiet-backend", "Suppress backend stdout/stderr").allowUnknownOption(true).action(async (opts, command) => {
5232
5635
  const { resolve: resolve3 } = await import("path");
5233
- const { existsSync: existsSync6, readFileSync: readFileSync5 } = await import("fs");
5636
+ const { existsSync: existsSync7, readFileSync: readFileSync7 } = await import("fs");
5234
5637
  const { spawn } = await import("child_process");
5235
5638
  const { createRequire } = await import("module");
5236
5639
  const path = await import("path");
5237
5640
  const rootPath = findRepoRoot(opts.path) ?? resolve3(opts.path);
5238
5641
  if (!opts.noInit) {
5239
5642
  if (!TrellisVcsEngine.isRepo(rootPath)) {
5240
- console.log(chalk4.dim("Not a Trellis workspace \u2014 initializing\u2026"));
5643
+ console.log(chalk5.dim("Not a Trellis workspace \u2014 initializing\u2026"));
5241
5644
  await runInit(rootPath, { interactive: false });
5242
- console.log(chalk4.green("\u2713 Initialized Trellis repository"));
5645
+ console.log(chalk5.green("\u2713 Initialized Trellis repository"));
5243
5646
  }
5244
5647
  }
5245
5648
  const requireFn = createRequire(import.meta.url);
5246
5649
  let turtlecodeBin = null;
5247
5650
  try {
5248
5651
  const pkgPath = requireFn.resolve("turtlecode/package.json");
5249
- const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
5652
+ const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
5250
5653
  const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.turtlecode;
5251
5654
  if (binRel) {
5252
5655
  const candidate = path.join(path.dirname(pkgPath), binRel);
5253
- if (existsSync6(candidate)) turtlecodeBin = candidate;
5656
+ if (existsSync7(candidate)) turtlecodeBin = candidate;
5254
5657
  }
5255
5658
  } catch {
5256
5659
  }
@@ -5263,8 +5666,8 @@ program.command("studio").alias("web").description("Launch Trellis Studio in you
5263
5666
  passthrough.push(...extra);
5264
5667
  const spawnArgs = turtlecodeBin ? [turtlecodeBin, ...passthrough] : ["turtlecode", ...passthrough];
5265
5668
  const spawnCmd = turtlecodeBin ? process.execPath : "npx";
5266
- console.log(chalk4.green("\u26A1 Launching Trellis Studio..."));
5267
- console.log(chalk4.dim(` Project: ${rootPath}`));
5669
+ console.log(chalk5.green("\u26A1 Launching Trellis Studio..."));
5670
+ console.log(chalk5.dim(` Project: ${rootPath}`));
5268
5671
  console.log("");
5269
5672
  const child = spawn(spawnCmd, spawnArgs, {
5270
5673
  stdio: "inherit",
@@ -5274,12 +5677,12 @@ program.command("studio").alias("web").description("Launch Trellis Studio in you
5274
5677
  child.on("error", (err) => {
5275
5678
  if (err.code === "ENOENT" && !turtlecodeBin) {
5276
5679
  console.error(
5277
- chalk4.red(
5680
+ chalk5.red(
5278
5681
  "\nCould not find `turtlecode`. Reinstall trellis, or install turtlecode globally: `npm i -g turtlecode`\n"
5279
5682
  )
5280
5683
  );
5281
5684
  } else {
5282
- console.error(chalk4.red(`
5685
+ console.error(chalk5.red(`
5283
5686
  Failed to launch Studio: ${err.message}`));
5284
5687
  }
5285
5688
  process.exit(1);
@@ -5320,18 +5723,18 @@ cmsCmd.command("register-library <pkg>").description(
5320
5723
  "Print the facts that would be asserted without contacting the server"
5321
5724
  ).action(async (pkg, opts) => {
5322
5725
  const rootPath = resolveRepoRoot(opts.path);
5323
- const { readFileSync: readFileSync5, existsSync: existsSync6 } = await import("fs");
5324
- const manifestPath = join6(
5726
+ const { readFileSync: readFileSync7, existsSync: existsSync7 } = await import("fs");
5727
+ const manifestPath = join7(
5325
5728
  rootPath,
5326
5729
  "node_modules",
5327
5730
  pkg,
5328
5731
  "dist",
5329
5732
  "components.json"
5330
5733
  );
5331
- if (!existsSync6(manifestPath)) {
5332
- console.error(chalk4.red(`\u2717 No manifest at ${manifestPath}`));
5734
+ if (!existsSync7(manifestPath)) {
5735
+ console.error(chalk5.red(`\u2717 No manifest at ${manifestPath}`));
5333
5736
  console.error(
5334
- chalk4.dim(
5737
+ chalk5.dim(
5335
5738
  ` Install ${pkg} in this repo and ensure it ships dist/components.json.`
5336
5739
  )
5337
5740
  );
@@ -5339,15 +5742,15 @@ cmsCmd.command("register-library <pkg>").description(
5339
5742
  }
5340
5743
  let manifest;
5341
5744
  try {
5342
- manifest = JSON.parse(readFileSync5(manifestPath, "utf8"));
5745
+ manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
5343
5746
  } catch (err) {
5344
- console.error(chalk4.red(`\u2717 Manifest is not valid JSON: ${manifestPath}`));
5345
- console.error(chalk4.dim(` ${err?.message ?? String(err)}`));
5747
+ console.error(chalk5.red(`\u2717 Manifest is not valid JSON: ${manifestPath}`));
5748
+ console.error(chalk5.dim(` ${err?.message ?? String(err)}`));
5346
5749
  process.exit(1);
5347
5750
  }
5348
5751
  const { package: pkgName, version, components } = manifest;
5349
5752
  if (!Array.isArray(components) || components.length === 0) {
5350
- console.error(chalk4.yellow(`\u26A0 Manifest is empty: ${manifestPath}`));
5753
+ console.error(chalk5.yellow(`\u26A0 Manifest is empty: ${manifestPath}`));
5351
5754
  process.exit(1);
5352
5755
  }
5353
5756
  const pkgSlug = pkgName.replace(/^@/, "").replace(/\//g, "__");
@@ -5367,10 +5770,10 @@ cmsCmd.command("register-library <pkg>").description(
5367
5770
  );
5368
5771
  }
5369
5772
  if (opts.dryRun) {
5370
- console.log(chalk4.dim("\u2500\u2500 Dry run: would assert these facts \u2500\u2500"));
5773
+ console.log(chalk5.dim("\u2500\u2500 Dry run: would assert these facts \u2500\u2500"));
5371
5774
  console.log(JSON.stringify(facts, null, 2));
5372
5775
  console.log(
5373
- chalk4.dim(
5776
+ chalk5.dim(
5374
5777
  `\u2500\u2500 ${facts.length} facts across ${components.length} components \u2500\u2500`
5375
5778
  )
5376
5779
  );
@@ -5392,31 +5795,31 @@ cmsCmd.command("register-library <pkg>").description(
5392
5795
  });
5393
5796
  if (!res.ok) {
5394
5797
  const body2 = await res.text().catch(() => "");
5395
- console.error(chalk4.red(`\u2717 Assert failed: HTTP ${res.status}`));
5396
- if (body2) console.error(chalk4.dim(` ${body2.slice(0, 400)}`));
5798
+ console.error(chalk5.red(`\u2717 Assert failed: HTTP ${res.status}`));
5799
+ if (body2) console.error(chalk5.dim(` ${body2.slice(0, 400)}`));
5397
5800
  process.exit(1);
5398
5801
  }
5399
5802
  const body = await res.json().catch(() => ({ added: 0 }));
5400
5803
  console.log(
5401
- chalk4.green(
5402
- `\u2713 Registered ${chalk4.bold(String(components.length))} components from ${chalk4.bold(pkgName)}@${version}`
5804
+ chalk5.green(
5805
+ `\u2713 Registered ${chalk5.bold(String(components.length))} components from ${chalk5.bold(pkgName)}@${version}`
5403
5806
  )
5404
5807
  );
5405
- console.log(` ${chalk4.dim("Facts added:")} ${body.added ?? "?"}`);
5406
- console.log(` ${chalk4.dim("Workspace:")} ${rootPath}`);
5808
+ console.log(` ${chalk5.dim("Facts added:")} ${body.added ?? "?"}`);
5809
+ console.log(` ${chalk5.dim("Workspace:")} ${rootPath}`);
5407
5810
  for (const comp of components) {
5408
5811
  console.log(
5409
- ` ${chalk4.dim("\u2022")} ${comp.component} ${chalk4.dim(`(design:component:${pkgSlug}:${comp.slug})`)}`
5812
+ ` ${chalk5.dim("\u2022")} ${comp.component} ${chalk5.dim(`(design:component:${pkgSlug}:${comp.slug})`)}`
5410
5813
  );
5411
5814
  }
5412
5815
  } catch (err) {
5413
5816
  const msg = err?.message ?? String(err);
5414
5817
  console.error(
5415
- chalk4.red(`\u2717 Could not reach Trellis server at ${opts.url}`)
5818
+ chalk5.red(`\u2717 Could not reach Trellis server at ${opts.url}`)
5416
5819
  );
5417
- console.error(chalk4.dim(` ${msg}`));
5820
+ console.error(chalk5.dim(` ${msg}`));
5418
5821
  console.error(
5419
- chalk4.dim(
5822
+ chalk5.dim(
5420
5823
  ` Hint: start the Trellis backend (e.g. open the turtlecode IDE) and retry.`
5421
5824
  )
5422
5825
  );
@@ -5425,91 +5828,91 @@ cmsCmd.command("register-library <pkg>").description(
5425
5828
  });
5426
5829
  program.command("remote").description("Manage remote workspace subscriptions").argument("[action]", '"add", "remove", or "list" (default: list)').argument("[name]", "Remote name (for add/remove)").argument("[path]", "Remote path (for add)").option("-p, --path <path>", "Repository path", ".").action(async (action, name, path, opts) => {
5427
5830
  const rootPath = resolveRepoRoot(opts.path);
5428
- const { RemoteManager } = await import("../remote-manager-ODE3T2KR.js");
5429
- const remoteManager = new RemoteManager(join6(rootPath, ".trellis"));
5831
+ const { RemoteManager } = await import("../remote-manager-6ERQUBSL.js");
5832
+ const remoteManager = new RemoteManager(join7(rootPath, ".trellis"));
5430
5833
  try {
5431
5834
  if (!action || action === "list") {
5432
5835
  const remotes = remoteManager.listRemotes();
5433
5836
  if (remotes.length === 0) {
5434
- console.log(chalk4.dim("No remotes configured."));
5837
+ console.log(chalk5.dim("No remotes configured."));
5435
5838
  return;
5436
5839
  }
5437
- console.log(chalk4.bold(`Remotes (${remotes.length})
5840
+ console.log(chalk5.bold(`Remotes (${remotes.length})
5438
5841
  `));
5439
5842
  for (const remote of remotes) {
5440
- const lastPulled = remote.pulledAt ? chalk4.dim(
5843
+ const lastPulled = remote.pulledAt ? chalk5.dim(
5441
5844
  ` (pulled ${new Date(remote.pulledAt).toLocaleDateString()})`
5442
- ) : chalk4.dim(" (never pulled)");
5845
+ ) : chalk5.dim(" (never pulled)");
5443
5846
  console.log(
5444
- ` ${chalk4.cyan(remote.name)}: ${remote.path}${lastPulled}`
5847
+ ` ${chalk5.cyan(remote.name)}: ${remote.path}${lastPulled}`
5445
5848
  );
5446
5849
  }
5447
5850
  return;
5448
5851
  }
5449
5852
  if (action === "add") {
5450
5853
  if (!name) {
5451
- console.error(chalk4.red("Error: Remote name required for add"));
5854
+ console.error(chalk5.red("Error: Remote name required for add"));
5452
5855
  process.exit(1);
5453
5856
  }
5454
5857
  if (!path) {
5455
- console.error(chalk4.red("Error: Remote path required for add"));
5858
+ console.error(chalk5.red("Error: Remote path required for add"));
5456
5859
  process.exit(1);
5457
5860
  }
5458
5861
  remoteManager.addRemote(name, path);
5459
- console.log(chalk4.green(`\u2713 Added remote '${name}' -> ${path}`));
5862
+ console.log(chalk5.green(`\u2713 Added remote '${name}' -> ${path}`));
5460
5863
  return;
5461
5864
  }
5462
5865
  if (action === "remove") {
5463
5866
  if (!name) {
5464
- console.error(chalk4.red("Error: Remote name required for remove"));
5867
+ console.error(chalk5.red("Error: Remote name required for remove"));
5465
5868
  process.exit(1);
5466
5869
  }
5467
5870
  remoteManager.removeRemote(name);
5468
- console.log(chalk4.green(`\u2713 Removed remote '${name}'`));
5871
+ console.log(chalk5.green(`\u2713 Removed remote '${name}'`));
5469
5872
  return;
5470
5873
  }
5471
- console.error(chalk4.red(`Unknown action: ${action}`));
5874
+ console.error(chalk5.red(`Unknown action: ${action}`));
5472
5875
  process.exit(1);
5473
5876
  } catch (error) {
5474
- console.error(chalk4.red(`Error: ${error}`));
5877
+ console.error(chalk5.red(`Error: ${error}`));
5475
5878
  process.exit(1);
5476
5879
  }
5477
5880
  });
5478
5881
  program.command("pull").description("Pull operations from remote workspaces").option("-p, --path <path>", "Repository path", ".").option("--remote <remote>", "Pull from specific remote only").action(async (opts) => {
5479
5882
  const rootPath = resolveRepoRoot(opts.path);
5480
- const { RemoteManager } = await import("../remote-manager-ODE3T2KR.js");
5481
- const remoteManager = new RemoteManager(join6(rootPath, ".trellis"));
5883
+ const { RemoteManager } = await import("../remote-manager-6ERQUBSL.js");
5884
+ const remoteManager = new RemoteManager(join7(rootPath, ".trellis"));
5482
5885
  const engine = new TrellisVcsEngine({ rootPath });
5483
5886
  engine.open();
5484
5887
  try {
5485
5888
  if (opts.remote) {
5486
5889
  const result = await remoteManager.pullRemote(opts.remote, engine);
5487
- console.log(chalk4.bold(`Pull from ${opts.remote}
5890
+ console.log(chalk5.bold(`Pull from ${opts.remote}
5488
5891
  `));
5489
- console.log(` ${chalk4.dim("New ops:")} ${result.newOps}`);
5892
+ console.log(` ${chalk5.dim("New ops:")} ${result.newOps}`);
5490
5893
  if (result.errors.length > 0) {
5491
- console.log(` ${chalk4.dim("Errors:")} ${result.errors.join(", ")}`);
5894
+ console.log(` ${chalk5.dim("Errors:")} ${result.errors.join(", ")}`);
5492
5895
  }
5493
- console.log(` ${chalk4.dim("Duration:")} ${result.durationMs}ms`);
5896
+ console.log(` ${chalk5.dim("Duration:")} ${result.durationMs}ms`);
5494
5897
  } else {
5495
5898
  const result = await remoteManager.pullAll(engine);
5496
- console.log(chalk4.bold("Pull from all remotes\n"));
5497
- console.log(` ${chalk4.dim("Total new ops:")} ${result.totalNewOps}`);
5498
- console.log(` ${chalk4.dim("Duration:")} ${result.totalDurationMs}ms`);
5899
+ console.log(chalk5.bold("Pull from all remotes\n"));
5900
+ console.log(` ${chalk5.dim("Total new ops:")} ${result.totalNewOps}`);
5901
+ console.log(` ${chalk5.dim("Duration:")} ${result.totalDurationMs}ms`);
5499
5902
  for (const remoteResult of result.results) {
5500
- const status = remoteResult.errors.length > 0 ? chalk4.red("\u2717") : chalk4.green("\u2713");
5903
+ const status = remoteResult.errors.length > 0 ? chalk5.red("\u2717") : chalk5.green("\u2713");
5501
5904
  console.log(
5502
5905
  ` ${status} ${remoteResult.remote}: ${remoteResult.newOps} new ops`
5503
5906
  );
5504
5907
  if (remoteResult.errors.length > 0) {
5505
5908
  for (const error of remoteResult.errors) {
5506
- console.log(` ${chalk4.dim(error)}`);
5909
+ console.log(` ${chalk5.dim(error)}`);
5507
5910
  }
5508
5911
  }
5509
5912
  }
5510
5913
  }
5511
5914
  } catch (error) {
5512
- console.error(chalk4.red(`Pull failed: ${error}`));
5915
+ console.error(chalk5.red(`Pull failed: ${error}`));
5513
5916
  process.exit(1);
5514
5917
  }
5515
5918
  });
@@ -5518,8 +5921,8 @@ program.command("skills").description("Install Trellis agent skills using the sk
5518
5921
  const extraArgs = skillsIndex !== -1 ? process.argv.slice(skillsIndex + 1) : [];
5519
5922
  const { spawnSync } = await import("child_process");
5520
5923
  const skillsArgs = ["skills", "add", "trentbrew/trellis", ...extraArgs];
5521
- console.log(chalk4.cyan(" Installing Trellis agent skills..."));
5522
- console.log(chalk4.dim(` Running: npx ${skillsArgs.join(" ")}
5924
+ console.log(chalk5.cyan(" Installing Trellis agent skills..."));
5925
+ console.log(chalk5.dim(` Running: npx ${skillsArgs.join(" ")}
5523
5926
  `));
5524
5927
  if (process.env.TRELLIS_CLI_DRY_RUN === "1") {
5525
5928
  return;
@@ -5530,7 +5933,7 @@ program.command("skills").description("Install Trellis agent skills using the sk
5530
5933
  });
5531
5934
  if (result.error) {
5532
5935
  console.error(
5533
- chalk4.red(`
5936
+ chalk5.red(`
5534
5937
  \u2717 Failed to run skills CLI: ${result.error.message}`)
5535
5938
  );
5536
5939
  process.exit(1);
@@ -5539,5 +5942,81 @@ program.command("skills").description("Install Trellis agent skills using the sk
5539
5942
  process.exit(result.status ?? 1);
5540
5943
  }
5541
5944
  });
5945
+ var mcpProgram = program.command("mcp").description("MCP servers and remote room bridges");
5946
+ mcpProgram.command("bridge").description(
5947
+ "stdio proxy to a remote Trellis room MCP endpoint (Streamable HTTP)"
5948
+ ).option("-r, --room <url>", "Room base URL or full /mcp URL").option("-k, --api-key <key>", "API key (defaults to .trellis-db.json)").option("--tenant <id>", "Default tenant (e.g. embed-design-review)").option(
5949
+ "--playground-room <slug>",
5950
+ "Playground ?room= slug \u2192 tenant embed-{slug}"
5951
+ ).option("--config-dir <dir>", "Directory containing .trellis-db.json", ".").option("--quiet", "Suppress stderr startup message").action(async (opts) => {
5952
+ const { runRoomMcpBridge } = await import("../bridge-JSSPQPRH.js");
5953
+ try {
5954
+ await runRoomMcpBridge({
5955
+ room: opts.room,
5956
+ apiKey: opts.apiKey,
5957
+ tenant: opts.tenant,
5958
+ playgroundRoom: opts.playgroundRoom,
5959
+ configDir: opts.configDir,
5960
+ quiet: !!opts.quiet
5961
+ });
5962
+ } catch (err) {
5963
+ console.error(
5964
+ chalk5.red(err instanceof Error ? err.message : String(err))
5965
+ );
5966
+ process.exit(1);
5967
+ }
5968
+ });
5969
+ var gatewayProgram = mcpProgram.command("gateway").description("Hosted MCP discovery gateway (mcp.trellis.computer pattern)");
5970
+ gatewayProgram.command("serve").description("Start discovery-only MCP gateway (list_rooms, connect_room)").option("-p, --port <port>", "HTTP port", "3940").option("--config-dir <dir>", "Directory for .trellis-db.json lookup", ".").option(
5971
+ "--public-url <url>",
5972
+ "Public URL for OAuth metadata (default: http://localhost:<port>)"
5973
+ ).action(async (opts) => {
5974
+ const { startGatewayServer } = await import("../mcp/gateway-serve.js");
5975
+ const port = parseInt(opts.port, 10) || 3940;
5976
+ const publicUrl = opts.publicUrl?.trim() || `http://localhost:${port}`;
5977
+ const server = await startGatewayServer({
5978
+ port,
5979
+ configDir: opts.configDir,
5980
+ publicUrl
5981
+ });
5982
+ console.log(chalk5.green("\u2713 Trellis MCP discovery gateway running"));
5983
+ console.log(chalk5.dim(` Public: ${publicUrl}`));
5984
+ console.log(chalk5.dim(` MCP: ${publicUrl}/mcp`));
5985
+ console.log(chalk5.dim(` Gateway: ${publicUrl}/gateway/mcp`));
5986
+ console.log(chalk5.dim(` Health: ${publicUrl}/health`));
5987
+ console.log(chalk5.dim(` OAuth: ${publicUrl}/.well-known/oauth-protected-resource`));
5988
+ console.log("");
5989
+ console.log(chalk5.bold("Tools: list_rooms, get_room, connect_room"));
5990
+ await new Promise((resolve3) => {
5991
+ const shutdown = () => {
5992
+ server.stop();
5993
+ resolve3();
5994
+ };
5995
+ process.on("SIGINT", shutdown);
5996
+ process.on("SIGTERM", shutdown);
5997
+ });
5998
+ });
5999
+ gatewayProgram.command("deploy").description("Deploy discovery gateway to Sprites (mcp.trellis.computer)").requiredOption("--name <name>", "Sprite name (e.g. mcp-gateway)").option(
6000
+ "--public-url <url>",
6001
+ "Vanity URL for agents",
6002
+ "https://mcp.trellis.computer"
6003
+ ).option(
6004
+ "--port <port>",
6005
+ "Port inside Sprite (default: 8080)"
6006
+ ).option("--config-dir <dir>", "Directory for gateway config + room registry", ".").option(
6007
+ "--rooms-file <path>",
6008
+ "Extra rooms JSON merged into .trellis-rooms.json at deploy"
6009
+ ).option("--stub", "Write config only \u2014 skip Sprites provisioning", false).action(async (opts) => {
6010
+ const { runGatewayDeployCli } = await import("../gateway-deploy-cli-4TU4V3QI.js");
6011
+ await runGatewayDeployCli({
6012
+ name: opts.name,
6013
+ publicUrl: opts.publicUrl,
6014
+ port: opts.port,
6015
+ configDir: opts.configDir,
6016
+ roomsFile: opts.roomsFile,
6017
+ stub: !!opts.stub
6018
+ });
6019
+ });
5542
6020
  registerLaneCommands(program);
6021
+ registerProtocolCommands(program);
5543
6022
  program.parseAsync(process.argv).catch(handleCliError);