mirror-mind 0.0.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/.claude/hooks/log-assistant-reply.sh +85 -0
  2. package/.claude/hooks/log-session-end.sh +85 -0
  3. package/.claude/hooks/log-user-prompt.sh +85 -0
  4. package/.claude/hooks/mirror-inject.sh +85 -0
  5. package/.claude/hooks/session-start.sh +85 -0
  6. package/.gemini/hooks/log-assistant.sh +85 -0
  7. package/.gemini/hooks/log-user.sh +85 -0
  8. package/.gemini/hooks/session-end.sh +85 -0
  9. package/.gemini/hooks/session-start.sh +85 -0
  10. package/.pi/extensions/mirror-logger.ts +646 -0
  11. package/.pi/skills/mm-backup/SKILL.md +21 -0
  12. package/.pi/skills/mm-build/SKILL.md +1206 -0
  13. package/.pi/skills/mm-consolidate/SKILL.md +112 -0
  14. package/.pi/skills/mm-consult/SKILL.md +70 -0
  15. package/.pi/skills/mm-conversations/SKILL.md +16 -0
  16. package/.pi/skills/mm-discard/SKILL.md +39 -0
  17. package/.pi/skills/mm-explore/SKILL.md +255 -0
  18. package/.pi/skills/mm-help/SKILL.md +74 -0
  19. package/.pi/skills/mm-identity/SKILL.md +96 -0
  20. package/.pi/skills/mm-journal/SKILL.md +16 -0
  21. package/.pi/skills/mm-journey/SKILL.md +23 -0
  22. package/.pi/skills/mm-journeys/SKILL.md +15 -0
  23. package/.pi/skills/mm-memories/SKILL.md +17 -0
  24. package/.pi/skills/mm-mirror/SKILL.md +98 -0
  25. package/.pi/skills/mm-mute/SKILL.md +18 -0
  26. package/.pi/skills/mm-new/SKILL.md +18 -0
  27. package/.pi/skills/mm-recall/SKILL.md +17 -0
  28. package/.pi/skills/mm-release-notes/SKILL.md +52 -0
  29. package/.pi/skills/mm-seed/SKILL.md +19 -0
  30. package/.pi/skills/mm-shadow/SKILL.md +117 -0
  31. package/.pi/skills/mm-soul/SKILL.md +502 -0
  32. package/.pi/skills/mm-tasks/SKILL.md +24 -0
  33. package/.pi/skills/mm-update/SKILL.md +32 -0
  34. package/.pi/skills/mm-week/SKILL.md +28 -0
  35. package/.pi/skills/mm-welcome/SKILL.md +24 -0
  36. package/AGENTS.md +188 -0
  37. package/README.md +126 -9
  38. package/bin/loader.js +67 -0
  39. package/bin/mirror-hook.js +7 -0
  40. package/bin/mirror.js +7 -0
  41. package/docs/releases/index.md +100 -0
  42. package/docs/releases/pending-cutoffs.md +510 -0
  43. package/docs/releases/v0.10.0.md +123 -0
  44. package/docs/releases/v0.10.1.md +66 -0
  45. package/docs/releases/v0.10.10.md +51 -0
  46. package/docs/releases/v0.10.11.md +39 -0
  47. package/docs/releases/v0.10.12.md +57 -0
  48. package/docs/releases/v0.10.13.md +35 -0
  49. package/docs/releases/v0.10.14.md +42 -0
  50. package/docs/releases/v0.10.15.md +53 -0
  51. package/docs/releases/v0.10.16.md +35 -0
  52. package/docs/releases/v0.10.17.md +43 -0
  53. package/docs/releases/v0.10.2.md +64 -0
  54. package/docs/releases/v0.10.3.md +78 -0
  55. package/docs/releases/v0.10.4.md +42 -0
  56. package/docs/releases/v0.10.5.md +57 -0
  57. package/docs/releases/v0.10.6.md +47 -0
  58. package/docs/releases/v0.10.7.md +53 -0
  59. package/docs/releases/v0.10.8.md +49 -0
  60. package/docs/releases/v0.10.9.md +37 -0
  61. package/docs/releases/v0.11.0.md +86 -0
  62. package/docs/releases/v0.12.0.md +67 -0
  63. package/docs/releases/v0.13.0.md +64 -0
  64. package/docs/releases/v0.14.0.md +68 -0
  65. package/docs/releases/v0.15.0.md +48 -0
  66. package/docs/releases/v0.16.0.md +50 -0
  67. package/docs/releases/v0.16.1.md +55 -0
  68. package/docs/releases/v0.16.2.md +36 -0
  69. package/docs/releases/v0.17.0.md +50 -0
  70. package/docs/releases/v0.17.1.md +58 -0
  71. package/docs/releases/v0.17.2.md +42 -0
  72. package/docs/releases/v0.17.3.md +58 -0
  73. package/docs/releases/v0.18.0.md +84 -0
  74. package/docs/releases/v0.18.1.md +51 -0
  75. package/docs/releases/v0.18.2.md +69 -0
  76. package/docs/releases/v0.19.0.md +85 -0
  77. package/docs/releases/v0.19.1.md +46 -0
  78. package/docs/releases/v0.20.0.md +85 -0
  79. package/docs/releases/v0.21.0.md +61 -0
  80. package/docs/releases/v0.21.1.md +47 -0
  81. package/docs/releases/v0.22.0.md +77 -0
  82. package/docs/releases/v0.22.1.md +42 -0
  83. package/docs/releases/v0.23.0.md +105 -0
  84. package/docs/releases/v0.24.0.md +125 -0
  85. package/docs/releases/v0.25.0.md +107 -0
  86. package/docs/releases/v0.26.0.md +139 -0
  87. package/docs/releases/v0.26.1.md +65 -0
  88. package/docs/releases/v0.26.2.md +43 -0
  89. package/docs/releases/v0.27.0.md +63 -0
  90. package/docs/releases/v0.28.0.md +59 -0
  91. package/docs/releases/v0.29.0.md +61 -0
  92. package/docs/releases/v0.29.1.md +59 -0
  93. package/docs/releases/v0.29.2.md +59 -0
  94. package/docs/releases/v0.29.3.md +93 -0
  95. package/docs/releases/v0.30.0.md +75 -0
  96. package/docs/releases/v0.30.1.md +93 -0
  97. package/docs/releases/v0.30.2.md +66 -0
  98. package/docs/releases/v0.31.0.md +122 -0
  99. package/docs/releases/v0.31.1.md +142 -0
  100. package/docs/releases/v0.31.10.md +118 -0
  101. package/docs/releases/v0.31.11.md +88 -0
  102. package/docs/releases/v0.31.12.md +105 -0
  103. package/docs/releases/v0.31.13.md +99 -0
  104. package/docs/releases/v0.31.14.md +97 -0
  105. package/docs/releases/v0.31.2.md +115 -0
  106. package/docs/releases/v0.31.3.md +142 -0
  107. package/docs/releases/v0.31.4.md +117 -0
  108. package/docs/releases/v0.31.5.md +155 -0
  109. package/docs/releases/v0.31.6.md +132 -0
  110. package/docs/releases/v0.31.7.md +132 -0
  111. package/docs/releases/v0.31.8.md +120 -0
  112. package/docs/releases/v0.31.9.md +120 -0
  113. package/docs/releases/v0.32.0.md +261 -0
  114. package/docs/releases/v0.32.1.md +59 -0
  115. package/docs/releases/v0.33.0.md +164 -0
  116. package/docs/releases/v0.8.0.md +118 -0
  117. package/docs/releases/v0.9.0.md +98 -0
  118. package/docs/releases/v0.9.1.md +83 -0
  119. package/package.json +102 -6
  120. package/plugins/mirror-mind/.claude-plugin/plugin.json +17 -0
  121. package/plugins/mirror-mind/hooks/hooks.json +62 -0
  122. package/plugins/mirror-mind/hooks/log-assistant-reply.sh +98 -0
  123. package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
  124. package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
  125. package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
  126. package/plugins/mirror-mind/hooks/session-start.sh +98 -0
  127. package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
  128. package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
  129. package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
  130. package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
  131. package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
  132. package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
  133. package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
  134. package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
  135. package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
  136. package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
  137. package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
  138. package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
  139. package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
  140. package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +67 -0
  141. package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
  142. package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
  143. package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
  144. package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
  145. package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
  146. package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
  147. package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
  148. package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
  149. package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
  150. package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
  151. package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
  152. package/scripts/codex-hooks/session-end.sh +85 -0
  153. package/scripts/codex-hooks/session-start.sh +85 -0
  154. package/scripts/codex-mirror.sh +48 -0
  155. package/templates/identity/README.md +119 -0
  156. package/templates/identity/ego/behavior.yaml +52 -0
  157. package/templates/identity/ego/constraints.yaml +15 -0
  158. package/templates/identity/ego/identity.yaml +43 -0
  159. package/templates/identity/journeys/personal-growth.yaml +39 -0
  160. package/templates/identity/organization/identity.yaml +24 -0
  161. package/templates/identity/organization/principles.yaml +17 -0
  162. package/templates/identity/personas/coach.yaml +94 -0
  163. package/templates/identity/personas/designer.yaml +93 -0
  164. package/templates/identity/personas/doctor.yaml +96 -0
  165. package/templates/identity/personas/engineer.yaml +77 -0
  166. package/templates/identity/personas/financial.yaml +97 -0
  167. package/templates/identity/personas/prompt-engineer.yaml +122 -0
  168. package/templates/identity/personas/researcher.yaml +88 -0
  169. package/templates/identity/personas/strategist.yaml +91 -0
  170. package/templates/identity/personas/teacher.yaml +95 -0
  171. package/templates/identity/personas/therapist.yaml +91 -0
  172. package/templates/identity/personas/thinker.yaml +74 -0
  173. package/templates/identity/personas/writer.yaml +76 -0
  174. package/templates/identity/self/config.yaml +16 -0
  175. package/templates/identity/self/soul.yaml +105 -0
  176. package/templates/identity/user/identity.yaml +30 -0
  177. package/ts/src/backup/staging.ts +62 -0
  178. package/ts/src/backup/zipBackup.ts +267 -0
  179. package/ts/src/backup/zipReader.ts +109 -0
  180. package/ts/src/backup/zipWriter.ts +148 -0
  181. package/ts/src/builder/activeCheckpoint.ts +134 -0
  182. package/ts/src/builder/aggregateStatus.ts +34 -0
  183. package/ts/src/builder/approve.ts +149 -0
  184. package/ts/src/builder/argv.ts +292 -0
  185. package/ts/src/builder/ariadMethod.ts +536 -0
  186. package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
  187. package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
  188. package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
  189. package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
  190. package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
  191. package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
  192. package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
  193. package/ts/src/builder/artifacts/storyFiles.ts +61 -0
  194. package/ts/src/builder/artifacts/storyIndex.ts +166 -0
  195. package/ts/src/builder/cadence.ts +59 -0
  196. package/ts/src/builder/card.ts +192 -0
  197. package/ts/src/builder/checkpointRefused.ts +66 -0
  198. package/ts/src/builder/closure.ts +964 -0
  199. package/ts/src/builder/commands.ts +2053 -0
  200. package/ts/src/builder/cursorPosition.ts +176 -0
  201. package/ts/src/builder/cursorTransitions.ts +77 -0
  202. package/ts/src/builder/deliveryCursor.ts +577 -0
  203. package/ts/src/builder/deliveryStoryClosure.ts +521 -0
  204. package/ts/src/builder/deliveryStoryPlan.ts +536 -0
  205. package/ts/src/builder/deliveryStoryReady.ts +160 -0
  206. package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
  207. package/ts/src/builder/expand.ts +336 -0
  208. package/ts/src/builder/flowUnit.ts +339 -0
  209. package/ts/src/builder/homeSurface.ts +122 -0
  210. package/ts/src/builder/implementationGuard.ts +125 -0
  211. package/ts/src/builder/index.ts +11 -0
  212. package/ts/src/builder/lifecycleRefusal.ts +92 -0
  213. package/ts/src/builder/lifecycleRibbon.ts +159 -0
  214. package/ts/src/builder/load.ts +313 -0
  215. package/ts/src/builder/methodAdoption.ts +113 -0
  216. package/ts/src/builder/methodDefinition.ts +429 -0
  217. package/ts/src/builder/methodInspection.ts +371 -0
  218. package/ts/src/builder/plan.ts +408 -0
  219. package/ts/src/builder/planPreauthorization.ts +265 -0
  220. package/ts/src/builder/prepare.ts +225 -0
  221. package/ts/src/builder/projectPaths.ts +64 -0
  222. package/ts/src/builder/pull.ts +356 -0
  223. package/ts/src/builder/pullCandidates.ts +463 -0
  224. package/ts/src/builder/pullCandidatesRender.ts +238 -0
  225. package/ts/src/builder/refinementField.ts +93 -0
  226. package/ts/src/builder/releaseIntent.ts +173 -0
  227. package/ts/src/builder/resumeState.ts +84 -0
  228. package/ts/src/builder/resumeSurface.ts +149 -0
  229. package/ts/src/builder/roadmapGrammar.ts +300 -0
  230. package/ts/src/builder/roadmapScan.ts +97 -0
  231. package/ts/src/builder/roadmapScope.ts +210 -0
  232. package/ts/src/builder/scopePhrases.ts +146 -0
  233. package/ts/src/builder/storyPaths.ts +196 -0
  234. package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
  235. package/ts/src/builder/surfaceProtocol.ts +42 -0
  236. package/ts/src/builder/templateGeneration.ts +148 -0
  237. package/ts/src/builder/transition.ts +178 -0
  238. package/ts/src/consult/args.ts +99 -0
  239. package/ts/src/consult/core.ts +122 -0
  240. package/ts/src/consult/modelCatalog.ts +55 -0
  241. package/ts/src/consult/render.ts +47 -0
  242. package/ts/src/conversation/append.ts +414 -0
  243. package/ts/src/conversation/backfill.ts +387 -0
  244. package/ts/src/conversation/closeTail.ts +467 -0
  245. package/ts/src/conversation/extraction.ts +333 -0
  246. package/ts/src/conversation/extractionDriver.ts +130 -0
  247. package/ts/src/conversation/extractionRun.ts +70 -0
  248. package/ts/src/conversation/hookPayload.ts +51 -0
  249. package/ts/src/conversation/journeyInference.ts +165 -0
  250. package/ts/src/conversation/journeyRepair.ts +114 -0
  251. package/ts/src/conversation/lifecycleFaces.ts +197 -0
  252. package/ts/src/conversation/lifecycleWrites.ts +313 -0
  253. package/ts/src/conversation/listing.ts +77 -0
  254. package/ts/src/conversation/logger.ts +851 -0
  255. package/ts/src/conversation/loggerCli.ts +321 -0
  256. package/ts/src/conversation/loggerRuntime.ts +259 -0
  257. package/ts/src/conversation/metadataLifecycle.ts +443 -0
  258. package/ts/src/conversation/recall.ts +66 -0
  259. package/ts/src/conversation/sessionComposites.ts +258 -0
  260. package/ts/src/conversation/sessionImport.ts +90 -0
  261. package/ts/src/conversation/transcriptBackfill.ts +141 -0
  262. package/ts/src/cultivation/applyActions.ts +241 -0
  263. package/ts/src/cultivation/cluster.ts +86 -0
  264. package/ts/src/cultivation/consolidationStore.ts +281 -0
  265. package/ts/src/cultivation/promptContext.ts +62 -0
  266. package/ts/src/cultivation/propose.ts +305 -0
  267. package/ts/src/cultivation/scan.ts +155 -0
  268. package/ts/src/db/backupGate.ts +47 -0
  269. package/ts/src/db/bootstrap.ts +108 -0
  270. package/ts/src/db/bootstrapLock.ts +223 -0
  271. package/ts/src/db/copyGuard.ts +60 -0
  272. package/ts/src/db/database.ts +397 -0
  273. package/ts/src/db/decode.ts +66 -0
  274. package/ts/src/db/ftsIntegrity.ts +41 -0
  275. package/ts/src/db/migrateOnOpen.ts +214 -0
  276. package/ts/src/db/migrations.ts +576 -0
  277. package/ts/src/db/readyOnOpen.ts +35 -0
  278. package/ts/src/db/rowDecode.ts +42 -0
  279. package/ts/src/db/schema.ts +432 -0
  280. package/ts/src/db/schemaInventory.ts +225 -0
  281. package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
  282. package/ts/src/db/schemaState.ts +91 -0
  283. package/ts/src/db/schemaTsDivergence.ts +114 -0
  284. package/ts/src/descriptor/descriptorRead.ts +49 -0
  285. package/ts/src/docs/docsLint.ts +265 -0
  286. package/ts/src/explorer/handoff.ts +522 -0
  287. package/ts/src/explorer/render.ts +335 -0
  288. package/ts/src/explorer/story.ts +769 -0
  289. package/ts/src/explorer/transition.ts +72 -0
  290. package/ts/src/extensions/bindings.ts +170 -0
  291. package/ts/src/extensions/catalog.ts +249 -0
  292. package/ts/src/extensions/catalogCommands.ts +513 -0
  293. package/ts/src/extensions/catalogWrites.ts +652 -0
  294. package/ts/src/extensions/contextRuntime.ts +325 -0
  295. package/ts/src/extensions/dispatch.ts +374 -0
  296. package/ts/src/extensions/errors.ts +24 -0
  297. package/ts/src/extensions/manifest.ts +356 -0
  298. package/ts/src/extensions/migrations.ts +350 -0
  299. package/ts/src/extraction/conversation.ts +304 -0
  300. package/ts/src/extraction/conversationMetadata.ts +206 -0
  301. package/ts/src/extraction/fencing.ts +106 -0
  302. package/ts/src/extraction/json.ts +17 -0
  303. package/ts/src/extraction/prompts.ts +470 -0
  304. package/ts/src/frontDoor/args.ts +30 -0
  305. package/ts/src/frontDoor/argvShape.ts +106 -0
  306. package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
  307. package/ts/src/frontDoor/buildRoute.ts +398 -0
  308. package/ts/src/frontDoor/cli.ts +1872 -0
  309. package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
  310. package/ts/src/frontDoor/consultRoute.ts +50 -0
  311. package/ts/src/frontDoor/contentTailRoute.ts +239 -0
  312. package/ts/src/frontDoor/conversationLoggerRoute.ts +83 -0
  313. package/ts/src/frontDoor/cultivationRoute.ts +210 -0
  314. package/ts/src/frontDoor/dbPath.ts +131 -0
  315. package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
  316. package/ts/src/frontDoor/exploreRoute.ts +572 -0
  317. package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
  318. package/ts/src/frontDoor/frontDoorLog.ts +57 -0
  319. package/ts/src/frontDoor/identityWrite.ts +36 -0
  320. package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
  321. package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
  322. package/ts/src/frontDoor/liveBackup.ts +100 -0
  323. package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
  324. package/ts/src/frontDoor/namedRefusal.ts +35 -0
  325. package/ts/src/frontDoor/nodeSupport.ts +24 -0
  326. package/ts/src/frontDoor/render/consolidate.ts +199 -0
  327. package/ts/src/frontDoor/render/conversations.ts +33 -0
  328. package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
  329. package/ts/src/frontDoor/render/descriptor.ts +20 -0
  330. package/ts/src/frontDoor/render/detectPersona.ts +50 -0
  331. package/ts/src/frontDoor/render/icons.ts +13 -0
  332. package/ts/src/frontDoor/render/identity.ts +59 -0
  333. package/ts/src/frontDoor/render/identityRows.ts +17 -0
  334. package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
  335. package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
  336. package/ts/src/frontDoor/render/journeys.ts +79 -0
  337. package/ts/src/frontDoor/render/list.ts +41 -0
  338. package/ts/src/frontDoor/render/memories.ts +67 -0
  339. package/ts/src/frontDoor/render/recall.ts +49 -0
  340. package/ts/src/frontDoor/render/shadow.ts +155 -0
  341. package/ts/src/frontDoor/render/tasks.ts +99 -0
  342. package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
  343. package/ts/src/frontDoor/render/week.ts +113 -0
  344. package/ts/src/frontDoor/routing.ts +1001 -0
  345. package/ts/src/frontDoor/runtimeRoute.ts +623 -0
  346. package/ts/src/frontDoor/searchRoute.ts +166 -0
  347. package/ts/src/frontDoor/seedPaths.ts +98 -0
  348. package/ts/src/frontDoor/sessionStartWelcomeRoute.ts +166 -0
  349. package/ts/src/frontDoor/soulRoute.ts +433 -0
  350. package/ts/src/frontDoor/stdinSource.ts +37 -0
  351. package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
  352. package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
  353. package/ts/src/frontDoor/usage.ts +176 -0
  354. package/ts/src/guards/claudePlugin.ts +298 -0
  355. package/ts/src/guards/packContents.ts +306 -0
  356. package/ts/src/guards/piSourcedSkills.ts +70 -0
  357. package/ts/src/guards/retiredRouteShadows.ts +57 -0
  358. package/ts/src/guards/retiredSurfaces.ts +564 -0
  359. package/ts/src/hooks/claude.ts +214 -0
  360. package/ts/src/hooks/codex.ts +45 -0
  361. package/ts/src/hooks/gemini.ts +126 -0
  362. package/ts/src/hooks/main.ts +109 -0
  363. package/ts/src/hooks/mirrorState.ts +71 -0
  364. package/ts/src/hooks/payload.ts +73 -0
  365. package/ts/src/hooks/runtime.ts +179 -0
  366. package/ts/src/hooks/runtimeDetection.ts +34 -0
  367. package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
  368. package/ts/src/identity/descriptorGenerate.ts +162 -0
  369. package/ts/src/identity/identityEdit.ts +143 -0
  370. package/ts/src/identity/identityKey.ts +77 -0
  371. package/ts/src/identity/identityRead.ts +69 -0
  372. package/ts/src/identity/identityStore.ts +80 -0
  373. package/ts/src/identity/journeyListing.ts +53 -0
  374. package/ts/src/identity/personaInspect.ts +44 -0
  375. package/ts/src/identity/personaListing.ts +37 -0
  376. package/ts/src/identity/setIdentity.ts +64 -0
  377. package/ts/src/index.ts +231 -0
  378. package/ts/src/init/init.ts +111 -0
  379. package/ts/src/journey/journeyOptions.ts +131 -0
  380. package/ts/src/journey/journeyRemoval.ts +158 -0
  381. package/ts/src/journey/journeyStatus.ts +149 -0
  382. package/ts/src/journey/journeySyncFile.ts +87 -0
  383. package/ts/src/journey/journeyWrite.ts +203 -0
  384. package/ts/src/journey/parentJourney.ts +41 -0
  385. package/ts/src/journey/validateParentJourney.ts +55 -0
  386. package/ts/src/mcp/boundary.ts +151 -0
  387. package/ts/src/mcp/guards.ts +244 -0
  388. package/ts/src/mcp/main.ts +121 -0
  389. package/ts/src/mcp/payload.ts +141 -0
  390. package/ts/src/mcp/protocol.ts +141 -0
  391. package/ts/src/mcp/readModels.ts +241 -0
  392. package/ts/src/mcp/registry.ts +201 -0
  393. package/ts/src/mcp/serve.ts +120 -0
  394. package/ts/src/mcp/tools/deterministic.ts +137 -0
  395. package/ts/src/mcp/tools/providerCrossing.ts +187 -0
  396. package/ts/src/mcp/wire.ts +8 -0
  397. package/ts/src/memory/journal.ts +180 -0
  398. package/ts/src/memory/listing.ts +107 -0
  399. package/ts/src/memory/memoryWrite.ts +88 -0
  400. package/ts/src/memory/reinforcement.ts +35 -0
  401. package/ts/src/mirror/context.ts +161 -0
  402. package/ts/src/mirror/defaultResolution.ts +199 -0
  403. package/ts/src/mirror/mirrorForm.ts +43 -0
  404. package/ts/src/mirror/orchestration.ts +364 -0
  405. package/ts/src/mirror/reception.ts +194 -0
  406. package/ts/src/mirror/render.ts +75 -0
  407. package/ts/src/mirror/runtimeSession.ts +205 -0
  408. package/ts/src/mode/operatingMode.ts +148 -0
  409. package/ts/src/observability/callOutcome.ts +115 -0
  410. package/ts/src/observability/inspectLedger.ts +329 -0
  411. package/ts/src/observability/ledgerHooks.ts +126 -0
  412. package/ts/src/observability/llmCalls.ts +154 -0
  413. package/ts/src/persona/detectPersona.ts +81 -0
  414. package/ts/src/planning/promptAssembly.ts +111 -0
  415. package/ts/src/planning/weekPending.ts +81 -0
  416. package/ts/src/planning/weekPlan.ts +183 -0
  417. package/ts/src/planning/weekSave.ts +117 -0
  418. package/ts/src/providers/config.ts +189 -0
  419. package/ts/src/providers/cost.ts +64 -0
  420. package/ts/src/providers/credits.ts +204 -0
  421. package/ts/src/providers/embedding.ts +321 -0
  422. package/ts/src/providers/familyProviders.ts +147 -0
  423. package/ts/src/providers/llm.ts +334 -0
  424. package/ts/src/providers/openrouter.ts +244 -0
  425. package/ts/src/providers/redaction.ts +110 -0
  426. package/ts/src/providers/replay.ts +15 -0
  427. package/ts/src/providers/transport.ts +410 -0
  428. package/ts/src/repair/encodingRepair.ts +253 -0
  429. package/ts/src/runtime/backup.ts +151 -0
  430. package/ts/src/runtime/channel.ts +146 -0
  431. package/ts/src/runtime/config.ts +168 -0
  432. package/ts/src/runtime/diagnose.ts +686 -0
  433. package/ts/src/runtime/git.ts +510 -0
  434. package/ts/src/runtime/installKind.ts +220 -0
  435. package/ts/src/runtime/migrate.ts +154 -0
  436. package/ts/src/runtime/packageIdentity.ts +102 -0
  437. package/ts/src/runtime/releaseNotes.ts +244 -0
  438. package/ts/src/runtime/status.ts +557 -0
  439. package/ts/src/runtime/strategies/clone.ts +200 -0
  440. package/ts/src/runtime/strategies/package.ts +328 -0
  441. package/ts/src/runtime/treeRoot.ts +30 -0
  442. package/ts/src/runtime/update.ts +445 -0
  443. package/ts/src/runtime/updateGate.ts +40 -0
  444. package/ts/src/runtime/updatePipeline.ts +159 -0
  445. package/ts/src/runtime/version.ts +36 -0
  446. package/ts/src/runtime/wiring.ts +130 -0
  447. package/ts/src/search/memorySearch.ts +338 -0
  448. package/ts/src/search/ranker.ts +154 -0
  449. package/ts/src/seed/seed.ts +256 -0
  450. package/ts/src/seed/seedYaml.ts +133 -0
  451. package/ts/src/soul/apply.ts +218 -0
  452. package/ts/src/soul/harvest.ts +267 -0
  453. package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
  454. package/ts/src/soul/prompts/soul_self_voice.md +219 -0
  455. package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
  456. package/ts/src/soul/prompts.ts +85 -0
  457. package/ts/src/soul/render.ts +358 -0
  458. package/ts/src/soul/state.ts +212 -0
  459. package/ts/src/soul/transition.ts +37 -0
  460. package/ts/src/tasks/journeyPathParse.ts +113 -0
  461. package/ts/src/tasks/taskImportSync.ts +142 -0
  462. package/ts/src/tasks/taskStore.ts +312 -0
  463. package/ts/src/tasks/weekView.ts +120 -0
  464. package/ts/src/util/clipCodePoints.ts +26 -0
  465. package/ts/src/util/paths.ts +63 -0
  466. package/ts/src/util/program.ts +9 -0
  467. package/ts/src/util/pyGenerators.ts +144 -0
  468. package/ts/src/util/pythonText.ts +317 -0
  469. package/ts/src/util/semver.ts +45 -0
  470. package/ts/src/util/shellWord.ts +25 -0
  471. package/ts/src/util/slug.ts +64 -0
  472. package/ts/src/welcome/card.ts +339 -0
  473. package/ts/src/welcome/statusLine.ts +101 -0
  474. package/ts/src/welcome/updateCache.ts +129 -0
@@ -0,0 +1,139 @@
1
+ // CV22.DS7.US8 plateau 7 — the wiring `build load` needs to run for real.
2
+ //
3
+ // `runBuildLoad` is a pure composition over a database plus three seams: an
4
+ // embedding provider, a conversation switch, and the clone-role guard. This
5
+ // module builds those seams from the process environment, and it exists at the
6
+ // route layer for two reasons: the guard reads the machine, and `builder/` is
7
+ // asserted to be provider-free (`test/builder/providerIsolation.test.ts`), which
8
+ // is the property that keeps twenty-six of the twenty-seven leaves unable to
9
+ // spend money.
10
+ //
11
+ // TWO callers, which is why it is a module and not an inline block:
12
+ // `explore story promote`, whose tail is a Builder session start (plateau 7),
13
+ // and plateau 8's `build` route. One wiring, so the two cannot drift about which
14
+ // transport answered or whether the close tail ran.
15
+ //
16
+ // ## The transport decision is COMPOSED, and taken before any byte
17
+ //
18
+ // `load` prints four surfaces before it reaches a provider, so the decision is
19
+ // resolved up front (`BUILD_LOAD_COMPOSITION`): a half-configured replay
20
+ // harness is refused here, before the caller has printed anything. Until
21
+ // CV22.DS10.TS5 three revert variables could also send the whole command back
22
+ // to Python from this point; they left with the fallback.
23
+
24
+ import { homedir } from "node:os";
25
+ import { dirname } from "node:path";
26
+ import type { BuildLoadDeps } from "#builder/load.ts";
27
+ import { switchConversation } from "#conversation/logger.ts";
28
+ import { createLoggerRuntime } from "#conversation/loggerRuntime.ts";
29
+ import type { WritableDatabase } from "#db/database.ts";
30
+ import { resolveFamilyProviders } from "#providers/familyProviders.ts";
31
+ import {
32
+ BUILD_LOAD_COMPOSITION,
33
+ BUILD_LOAD_TRANSPORT,
34
+ CONVERSATION_TAIL_TRANSPORT,
35
+ type ProviderTransportEnv,
36
+ } from "#providers/transport.ts";
37
+ import { newId, nowIso } from "#util/pyGenerators.ts";
38
+ import { inspectBuilderCloneRole } from "./cloneRoleGuard.ts";
39
+
40
+ export interface BuildLoadRuntimeOptions {
41
+ readonly db: WritableDatabase;
42
+ /** The resolved database path; the mirror home is its directory. */
43
+ readonly dbPath: string;
44
+ readonly env?: ProviderTransportEnv & Record<string, string | undefined>;
45
+ /** Python passes `--ignore-production-role` through to the guard. */
46
+ readonly ignoreProductionRole?: boolean;
47
+ /** Test seam: the home the logger runtime resolves Pi sessions against. */
48
+ readonly homeDir?: string;
49
+ }
50
+
51
+ export interface BuildLoadRuntime {
52
+ /** Which transport answered, for the front-door log. Never a payload. */
53
+ readonly reason: string;
54
+ readonly mode: "replay" | "live";
55
+ /** Ready for `runBuildLoad`. */
56
+ readonly deps: BuildLoadDeps;
57
+ }
58
+
59
+ /**
60
+ * Build the seams.
61
+ *
62
+ * Throws `ReplayFixtureIncompleteError` when half a fixture is configured: that
63
+ * is a refusal by name, never a live call.
64
+ */
65
+ export async function createBuildLoadRuntime(
66
+ options: BuildLoadRuntimeOptions,
67
+ ): Promise<BuildLoadRuntime> {
68
+ const env = options.env ?? process.env;
69
+ const family = await resolveFamilyProviders(env, BUILD_LOAD_COMPOSITION);
70
+ const embedding = family.embedding;
71
+ if (embedding === undefined) {
72
+ throw new Error("build load requires an embedding provider for its two searches");
73
+ }
74
+
75
+ // The close tail is the previous conversation's, and it belongs to the
76
+ // conversation-tail family -- so it runs through that family's own runtime
77
+ // rather than a second implementation here.
78
+ const tail = createLoggerRuntime({
79
+ db: options.db,
80
+ mirrorHome: dirname(options.dbPath),
81
+ homeDir: options.homeDir ?? homedir(),
82
+ env: tailEnv(env, family.mode),
83
+ deps: { newId, nowIso },
84
+ });
85
+ const hooks = await tail.closeHooks();
86
+
87
+ return {
88
+ reason: family.reason,
89
+ mode: family.mode,
90
+ deps: {
91
+ nowIso,
92
+ newId,
93
+ embeddingProvider: embedding,
94
+ switchConversation: async (journey, sessionId) => {
95
+ await switchConversation(
96
+ options.db,
97
+ sessionId,
98
+ { persona: "engineer", journey },
99
+ { newId, nowIso },
100
+ hooks,
101
+ );
102
+ },
103
+ cloneRoleGuard: (projectPath) =>
104
+ inspectBuilderCloneRole(projectPath, {
105
+ ignoreProductionRole: options.ignoreProductionRole ?? false,
106
+ }),
107
+ },
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Under replay, the close tail reads THIS family's fixtures.
113
+ *
114
+ * `createLoggerRuntime` resolves `CONVERSATION_TAIL_TRANSPORT` itself, so a
115
+ * shell holding only `MIRROR_TS_BUILD_*_REPLAY` would replay the two searches
116
+ * and send the close tail to the live provider — spending real money inside a
117
+ * command someone deliberately configured to be deterministic. Overlaying the
118
+ * tail's variables keeps the promise the composition makes: every seam inside
119
+ * `load` is answered by the owning family's fixtures.
120
+ *
121
+ * Live mode needs no overlay: both families resolve to the same live providers.
122
+ */
123
+ function tailEnv(
124
+ env: ProviderTransportEnv & Record<string, string | undefined>,
125
+ mode: "replay" | "live",
126
+ ): Record<string, string | undefined> {
127
+ if (mode !== "replay") return { ...env };
128
+ const llm = BUILD_LOAD_TRANSPORT.replay?.llm;
129
+ const embedding = BUILD_LOAD_TRANSPORT.replay?.embedding;
130
+ return {
131
+ ...env,
132
+ ...(CONVERSATION_TAIL_TRANSPORT.replay?.llm && llm
133
+ ? { [CONVERSATION_TAIL_TRANSPORT.replay.llm]: env[llm] }
134
+ : {}),
135
+ ...(CONVERSATION_TAIL_TRANSPORT.replay?.embedding && embedding
136
+ ? { [CONVERSATION_TAIL_TRANSPORT.replay.embedding]: env[embedding] }
137
+ : {}),
138
+ };
139
+ }
@@ -0,0 +1,398 @@
1
+ // CV22.DS7.US8 plateau 8 — production front-door route for `build`.
2
+ //
3
+ // Routing owns the two-level allowlist. This module owns argparse-class
4
+ // validation, the writable database boundary, and the lazy import of the Builder
5
+ // tree. No Builder module is imported at module evaluation time, so a broken
6
+ // Builder core breaks `build` and nothing else. Type-only imports are erased and
7
+ // do not cross it.
8
+
9
+ import type { CommandResult } from "#builder/commands.ts";
10
+ import type { Database, WritableDatabase } from "#db/database.ts";
11
+ import type { BuildLoadRuntime } from "#frontDoor/buildLoadRuntime.ts";
12
+
13
+ export interface BuildRouteDeps {
14
+ readonly withReadOnlyDatabase: (run: (db: Database) => number) => number;
15
+ readonly withWritableDatabase: (
16
+ run: (db: WritableDatabase, dbPath: string) => Promise<number> | number,
17
+ ) => Promise<number>;
18
+ readonly createLoadRuntime: (
19
+ db: WritableDatabase,
20
+ dbPath: string,
21
+ ignoreProductionRole: boolean,
22
+ ) => Promise<BuildLoadRuntime>;
23
+ readonly nowIso: () => string;
24
+ readonly environmentSessionId?: string | null;
25
+ }
26
+
27
+ export interface BuildRouteResult {
28
+ readonly exitCode: number;
29
+ /** Content-free front-door metadata. */
30
+ readonly detail: string;
31
+ }
32
+
33
+ interface CommandSpec {
34
+ readonly values?: readonly string[];
35
+ readonly flags?: readonly string[];
36
+ readonly required?: readonly string[];
37
+ readonly choices?: Readonly<Record<string, readonly string[]>>;
38
+ readonly positionals?: number;
39
+ }
40
+
41
+ const COMMON = ["--method", "--journey", "--session-id"] as const;
42
+ const COMMON_REQUIRED = ["--method"] as const;
43
+
44
+ const COMMAND_SPECS: Readonly<Record<string, CommandSpec>> = {
45
+ "inspect-method": {
46
+ values: ["--journey", "--session-id", "--mirror-home", "--db-path"],
47
+ positionals: 1,
48
+ },
49
+ adopt: { values: [...COMMON, "--mirror-home", "--db-path"], required: COMMON_REQUIRED },
50
+ "prepare-templates": {
51
+ values: [...COMMON, "--mirror-home", "--db-path"],
52
+ required: COMMON_REQUIRED,
53
+ },
54
+ "sync-cursor": { values: [...COMMON, "--mirror-home", "--db-path"], required: COMMON_REQUIRED },
55
+ "pull-candidates": {
56
+ values: [...COMMON, "--mirror-home", "--db-path"],
57
+ required: COMMON_REQUIRED,
58
+ },
59
+ "check-implementation": {
60
+ values: [...COMMON, "--mirror-home", "--db-path"],
61
+ required: COMMON_REQUIRED,
62
+ },
63
+ show: {
64
+ values: [...COMMON, "--mirror-home", "--db-path"],
65
+ required: COMMON_REQUIRED,
66
+ },
67
+ "pull-item": {
68
+ values: [
69
+ ...COMMON,
70
+ "--item-code",
71
+ "--item-title",
72
+ "--item-level",
73
+ "--why-now",
74
+ "--mirror-home",
75
+ "--db-path",
76
+ ],
77
+ required: ["--method", "--item-code", "--item-title", "--item-level", "--why-now"],
78
+ },
79
+ "prepare-item": { values: [...COMMON, "--mirror-home", "--db-path"], required: COMMON_REQUIRED },
80
+ "plan-item": {
81
+ values: [...COMMON, "--objective", "--stop-after", "--mirror-home", "--db-path"],
82
+ flags: ["--preauthorize-approval"],
83
+ required: COMMON_REQUIRED,
84
+ choices: { "--stop-after": ["navigator_validation"] },
85
+ },
86
+ "approve-plan": {
87
+ values: [...COMMON, "--mirror-home", "--db-path"],
88
+ flags: ["--use-preauthorization"],
89
+ required: COMMON_REQUIRED,
90
+ },
91
+ "cancel-plan-preauthorization": {
92
+ values: [...COMMON, "--mirror-home", "--db-path"],
93
+ required: COMMON_REQUIRED,
94
+ },
95
+ "validate-item": {
96
+ values: [
97
+ ...COMMON,
98
+ "--check",
99
+ "--checks-status",
100
+ "--e2e-decision",
101
+ "--e2e-evidence",
102
+ "--navigator-route",
103
+ "--expected-observation",
104
+ "--pass-condition",
105
+ "--fail-condition",
106
+ "--mirror-home",
107
+ "--db-path",
108
+ ],
109
+ flags: ["--navigator-accepted", "--implementation-complete"],
110
+ required: COMMON_REQUIRED,
111
+ choices: {
112
+ "--checks-status": ["passed", "failed", "not_run"],
113
+ "--e2e-decision": ["required", "not_required", "waived", "skipped"],
114
+ },
115
+ },
116
+ "review-item": {
117
+ values: [
118
+ ...COMMON,
119
+ "--debt",
120
+ "--decision",
121
+ "--defer-reason",
122
+ "--revisit-trigger",
123
+ "--mirror-home",
124
+ "--db-path",
125
+ ],
126
+ required: COMMON_REQUIRED,
127
+ choices: { "--decision": ["pending", "no_action", "defer", "pay_now"] },
128
+ },
129
+ "coherence-item": {
130
+ values: [
131
+ ...COMMON,
132
+ "--process",
133
+ "--project",
134
+ "--product",
135
+ "--local-difference",
136
+ "--mirror-home",
137
+ "--db-path",
138
+ ],
139
+ required: COMMON_REQUIRED,
140
+ },
141
+ "done-item": {
142
+ values: [
143
+ ...COMMON,
144
+ "--history-action",
145
+ "--roadmap-update",
146
+ "--next-recommendation",
147
+ "--mirror-home",
148
+ "--db-path",
149
+ ],
150
+ required: COMMON_REQUIRED,
151
+ },
152
+ "set-flow-unit": {
153
+ values: [...COMMON, "--unit", "--mirror-home", "--db-path"],
154
+ required: COMMON_REQUIRED,
155
+ choices: { "--unit": ["story_by_story", "delivery_story"] },
156
+ },
157
+ "plan-delivery-story": {
158
+ values: [...COMMON, "--objective", "--child", "--stop-after", "--mirror-home", "--db-path"],
159
+ flags: ["--preauthorize-approval"],
160
+ required: ["--method", "--objective"],
161
+ choices: { "--stop-after": ["navigator_validation"] },
162
+ },
163
+ "approve-delivery-story-plan": {
164
+ values: [...COMMON, "--mirror-home", "--db-path"],
165
+ flags: ["--use-preauthorization"],
166
+ required: COMMON_REQUIRED,
167
+ },
168
+ "cancel-delivery-story-plan-preauthorization": {
169
+ values: [...COMMON, "--mirror-home", "--db-path"],
170
+ required: COMMON_REQUIRED,
171
+ },
172
+ "validate-delivery-story": {
173
+ values: [...COMMON, "--summary", "--mirror-home", "--db-path"],
174
+ flags: ["--navigator-accepted"],
175
+ required: ["--method", "--summary"],
176
+ },
177
+ "review-delivery-story": {
178
+ values: [...COMMON, "--decision", "--summary", "--mirror-home", "--db-path"],
179
+ required: ["--method", "--decision", "--summary"],
180
+ choices: { "--decision": ["no_action", "defer", "pay_now"] },
181
+ },
182
+ "coherence-delivery-story": {
183
+ values: [...COMMON, "--summary", "--mirror-home", "--db-path"],
184
+ required: ["--method", "--summary"],
185
+ },
186
+ "done-delivery-story": {
187
+ values: [...COMMON, "--summary", "--mirror-home", "--db-path"],
188
+ required: ["--method", "--summary"],
189
+ },
190
+ "set-cadence": {
191
+ values: [...COMMON, "--profile", "--limit", "--mirror-home", "--db-path"],
192
+ required: ["--method", "--profile"],
193
+ },
194
+ "release-intent": {
195
+ values: [...COMMON, "--intent", "--mirror-home", "--db-path"],
196
+ required: COMMON_REQUIRED,
197
+ choices: { "--intent": ["planned", "none", "undecided"] },
198
+ },
199
+ "continue-lifecycle": {
200
+ values: [
201
+ ...COMMON,
202
+ "--process",
203
+ "--project",
204
+ "--product",
205
+ "--local-difference",
206
+ "--history-action",
207
+ "--roadmap-update",
208
+ "--next-recommendation",
209
+ "--mirror-home",
210
+ "--db-path",
211
+ ],
212
+ required: COMMON_REQUIRED,
213
+ },
214
+ };
215
+
216
+ const LOAD_SPEC: CommandSpec = {
217
+ values: ["--session-id", "--mirror-home", "--db-path"],
218
+ flags: ["--ignore-production-role"],
219
+ positionals: 1,
220
+ };
221
+
222
+ function usageError(message: string): CommandResult {
223
+ return { stdout: "", stderr: `Mirror TS build: ${message}\n`, exitCode: 2 };
224
+ }
225
+
226
+ export interface ParsedBuilderArgv {
227
+ /**
228
+ * The invocation in canonical `--option value` form: the subcommand, then
229
+ * positionals, then every option pair and flag in the order given. The
230
+ * Builder command mapping reads only this shape.
231
+ */
232
+ readonly argv: readonly string[];
233
+ }
234
+
235
+ /**
236
+ * Validate the input class argparse owns, with honest TS prose, and produce the
237
+ * canonical argv the command mapping reads.
238
+ *
239
+ * Python is the contract for what is ACCEPTED, not only for what is refused:
240
+ * argparse takes `--option=value` for any option, and any unambiguous prefix of
241
+ * a long option (`allow_abbrev` is on), so `--meth=ariad --jour=demo` is a valid
242
+ * Python invocation and must be a valid TypeScript one. An ambiguous prefix and
243
+ * an inline value on a flag are argparse's own refusals, reproduced at exit 2.
244
+ */
245
+ export function parseBuilderArgv(argv: readonly string[]): ParsedBuilderArgv | CommandResult {
246
+ const command = argv[0] ?? "";
247
+ const spec = command === "load" ? LOAD_SPEC : COMMAND_SPECS[command];
248
+ if (!spec) return usageError(`unknown subcommand ${command || "(none)"}`);
249
+
250
+ const values = new Set(spec.values ?? []);
251
+ const flags = new Set(spec.flags ?? []);
252
+ const known = [...values, ...flags];
253
+ const seen = new Map<string, string>();
254
+ const positionals: string[] = [];
255
+ const options: string[] = [];
256
+ for (let index = 1; index < argv.length; index += 1) {
257
+ const token = argv[index] ?? "";
258
+ if (!token.startsWith("--")) {
259
+ positionals.push(token);
260
+ continue;
261
+ }
262
+ const separator = token.indexOf("=");
263
+ const spelled = separator === -1 ? token : token.slice(0, separator);
264
+ const inline = separator === -1 ? null : token.slice(separator + 1);
265
+ let option = spelled;
266
+ if (!values.has(spelled) && !flags.has(spelled)) {
267
+ const candidates = known.filter((name) => name.startsWith(spelled));
268
+ if (candidates.length > 1) {
269
+ return usageError(
270
+ `${command}: ambiguous option ${spelled} could match ${candidates.join(", ")}`,
271
+ );
272
+ }
273
+ if (candidates.length === 0)
274
+ return usageError(`${command}: unrecognized argument ${spelled}`);
275
+ option = candidates[0] ?? spelled;
276
+ }
277
+ if (flags.has(option)) {
278
+ if (inline !== null) return usageError(`${command}: ${option} takes no value`);
279
+ options.push(option);
280
+ continue;
281
+ }
282
+ let value = inline;
283
+ if (value === null) {
284
+ const next = argv[index + 1];
285
+ // A separate token that looks like an option is an option, as argparse
286
+ // reads it; only the `=` form can carry such a value.
287
+ if (next === undefined || next.startsWith("--")) {
288
+ return usageError(`${command}: ${option} requires a value`);
289
+ }
290
+ value = next;
291
+ index += 1;
292
+ }
293
+ seen.set(option, value);
294
+ options.push(option, value);
295
+ }
296
+
297
+ if (positionals.length > (spec.positionals ?? 0)) {
298
+ return usageError(`${command}: too many positional arguments`);
299
+ }
300
+ if (command === "load" && positionals.length === 0) {
301
+ return usageError("load requires a journey slug");
302
+ }
303
+ for (const required of spec.required ?? []) {
304
+ if (!seen.has(required))
305
+ return usageError(`${command}: the following argument is required: ${required}`);
306
+ }
307
+ for (const [option, choices] of Object.entries(spec.choices ?? {})) {
308
+ const value = seen.get(option);
309
+ if (value !== undefined && !choices.includes(value)) {
310
+ return usageError(`${command}: invalid value for ${option}: ${value}`);
311
+ }
312
+ }
313
+ return { argv: [command, ...positionals, ...options] };
314
+ }
315
+
316
+ function writeResult(result: CommandResult): number {
317
+ if (result.stdout) process.stdout.write(result.stdout);
318
+ if (result.stderr) process.stderr.write(result.stderr);
319
+ return result.exitCode;
320
+ }
321
+
322
+ function positional(argv: readonly string[], values: readonly string[]): string | null {
323
+ const valueOptions = new Set(values);
324
+ for (let index = 1; index < argv.length; index += 1) {
325
+ const token = argv[index] ?? "";
326
+ if (valueOptions.has(token)) {
327
+ index += 1;
328
+ continue;
329
+ }
330
+ if (!token.startsWith("--")) return token;
331
+ }
332
+ return null;
333
+ }
334
+
335
+ export async function runBuildRoute(
336
+ argv: readonly string[],
337
+ deps: BuildRouteDeps,
338
+ ): Promise<BuildRouteResult> {
339
+ const command = argv[1] ?? "";
340
+ const parsed = parseBuilderArgv(argv.slice(1));
341
+ if (!("argv" in parsed)) {
342
+ return { exitCode: writeResult(parsed), detail: `leaf=${command || "(none)"}` };
343
+ }
344
+ const builderArgv = parsed.argv;
345
+
346
+ // This is the resilience boundary. A reverted invocation never imports this
347
+ // route; an enabled invocation imports the Builder core only now.
348
+ const builder = await import("#builder/index.ts");
349
+ if (builder.READ_ONLY_BUILDER_SUBCOMMANDS.has(command)) {
350
+ const exitCode = deps.withReadOnlyDatabase((db) =>
351
+ writeResult(
352
+ builder.invokeReadOnlyBuilderArgv(db, builderArgv, deps.environmentSessionId ?? null),
353
+ ),
354
+ );
355
+ return { exitCode, detail: `leaf=${command}` };
356
+ }
357
+
358
+ let detail = `leaf=${command}`;
359
+ const exitCode = await deps.withWritableDatabase(async (db, dbPath) => {
360
+ if (command === "load") {
361
+ const runtime = await deps.createLoadRuntime(
362
+ db,
363
+ dbPath,
364
+ builderArgv.includes("--ignore-production-role"),
365
+ );
366
+ const slug = positional(builderArgv, LOAD_SPEC.values ?? []);
367
+ if (slug === null) throw new Error("validated build load lost its journey slug");
368
+ // Keep the provider-backed leaf outside the deterministic command-tree
369
+ // import closure; providerIsolation.test.ts grades that reachability.
370
+ const { runBuildLoad } = await import("#builder/load.ts");
371
+ const result = await runBuildLoad(
372
+ db,
373
+ {
374
+ slug,
375
+ sessionId: optionValue(builderArgv, "--session-id"),
376
+ environmentSessionId: deps.environmentSessionId ?? null,
377
+ },
378
+ runtime.deps,
379
+ );
380
+ detail = `leaf=load calls=${result.providerCalls}${
381
+ result.degradedKind ? ` kind=${result.degradedKind}` : ""
382
+ }`;
383
+ return writeResult(result);
384
+ }
385
+
386
+ const result = builder.invokeBuilderArgv(db, builderArgv, {
387
+ nowIso: deps.nowIso,
388
+ environmentSessionId: deps.environmentSessionId ?? null,
389
+ });
390
+ return writeResult(result);
391
+ });
392
+ return { exitCode, detail };
393
+ }
394
+
395
+ function optionValue(argv: readonly string[], name: string): string | null {
396
+ const index = argv.lastIndexOf(name);
397
+ return index === -1 ? null : (argv[index + 1] ?? null);
398
+ }