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,557 @@
1
+ // `runtime status` (CV22.DS7.TS3 plateau 3a). Port of the status half of
2
+ // `src/memory/cli/runtime.py`.
3
+ //
4
+ // The story's reason lives in `inspectCoreMigrations`. Python grades the
5
+ // database's `_migrations` ledger against ITS OWN migration list, so since
6
+ // CV22.DS6.US2 -- when TypeScript authored `017_journey_parent_column`, the
7
+ // first migration with no Python counterpart -- Python's `runtime diagnose`
8
+ // has flagged `core_migration_unknown` on every install that ever ran the TS
9
+ // engine. The schema authority moved to TypeScript in DS6; the grader follows
10
+ // it here, and the false alarm goes away.
11
+ //
12
+ // The grading rule is `assertSchemaState`'s, not a second one invented for
13
+ // diagnostics (see `inspectCoreMigrations`).
14
+ //
15
+ // NOT ported: `_runtime_status_blockers`. Its only caller is
16
+ // `render_runtime_update_dry_run`, which belongs to the git-based updater that
17
+ // the 2026-09-07 decision assigned to CV22.DS10.
18
+
19
+ import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
20
+ import { join, resolve } from "node:path";
21
+ import { type Database, openDatabaseReadOnly } from "#db/database.ts";
22
+ import { KNOWN_MIGRATION_IDS } from "#db/schemaState.ts";
23
+ import { ExtensionError } from "#extensions/errors.ts";
24
+ import { loadExtensionManifest } from "#extensions/manifest.ts";
25
+ import { inspectMigrationFiles } from "#extensions/migrations.ts";
26
+ import { type DbPathEnv, dbNameForEnv, resolveMirrorHome } from "#frontDoor/dbPath.ts";
27
+ import { DEFAULT_EMBEDDING_MODEL, DEFAULT_EXTRACTION_MODEL } from "#providers/config.ts";
28
+ import { sortByCodePoint } from "#util/pythonText.ts";
29
+ import { channelFor } from "./channel.ts";
30
+ import type { MarkerValue } from "./git.ts";
31
+ import {
32
+ type GitStatus,
33
+ inspectCloneRole,
34
+ inspectGitFor,
35
+ inspectUpdateChannel,
36
+ renderRepositoryLines,
37
+ } from "./git.ts";
38
+ import { detectInstallKind, type InstallKind, renderInstallLines } from "./installKind.ts";
39
+
40
+ export interface CoreMigrationHealth {
41
+ ready: boolean;
42
+ applied_count: number | null;
43
+ known_count: number;
44
+ missing: string[];
45
+ unknown: string[];
46
+ note: string | null;
47
+ }
48
+
49
+ export interface ExtensionHealth {
50
+ extension_id: string;
51
+ ready: boolean;
52
+ note: string | null;
53
+ pending_migrations: string[];
54
+ drifted_migrations: string[];
55
+ unknown_migrations: string[];
56
+ }
57
+
58
+ export interface RuntimeStatusReport {
59
+ version: string;
60
+ /** How the running front door is installed (CV22.DS10.US3 plateau 4; US2 D3). */
61
+ install: InstallKind;
62
+ git: GitStatus;
63
+ mirror_home: string | null;
64
+ mirror_home_error: string | null;
65
+ db_path: string | null;
66
+ db_exists: boolean | null;
67
+ core_migrations: CoreMigrationHealth;
68
+ extensions: string[];
69
+ extension_health: ExtensionHealth[];
70
+ clone_role: MarkerValue;
71
+ memory_env: string;
72
+ update_channel: MarkerValue;
73
+ node_version: string | null;
74
+ }
75
+
76
+ function health(fields: Partial<CoreMigrationHealth>): CoreMigrationHealth {
77
+ return {
78
+ ready: false,
79
+ applied_count: null,
80
+ known_count: 0,
81
+ missing: [],
82
+ unknown: [],
83
+ note: null,
84
+ ...fields,
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Open the database for inspection without touching it. Read-only is not a
90
+ * preference here: a `diagnose` that migrates the database it is diagnosing
91
+ * would report a state it created, so this path must never bootstrap, migrate,
92
+ * or write.
93
+ */
94
+ function connectReadOnly(dbPath: string): Database {
95
+ return openDatabaseReadOnly(dbPath);
96
+ }
97
+
98
+ function errorMessage(error: unknown): string {
99
+ return error instanceof Error ? error.message : String(error);
100
+ }
101
+
102
+ /**
103
+ * Port of `inspect_core_migrations`, graded against the TypeScript manifest.
104
+ *
105
+ * One rule, `assertSchemaState`'s, so the codebase keeps ONE definition of a
106
+ * healthy ledger: every id in `KNOWN_MIGRATION_IDS` is required, and an id
107
+ * outside it is unknown. A current database renders `current (17/17)`.
108
+ *
109
+ * Until CV22.DS10.TS5 this grader kept a second rule for one migration.
110
+ * `017_journey_parent_column` is the first one TypeScript authored, and the
111
+ * Python oracle graded ledgers against its own sixteen, so a database carrying
112
+ * 017 was "unknown" to Python (the false alarm DS6 removed here) and a database
113
+ * without it was "current (16/16)". To keep matching that recorded answer,
114
+ * `known_count` counted only what a given database required, and a missing
115
+ * 017 was forgiven. With the oracle deleted there was nothing left to match:
116
+ * the forgiveness hid a pending migration behind "ready" on exactly the
117
+ * databases `runtime migrate` exists to bring forward. TS5 finding F19 (a
118
+ * removal the comment here promised for plateau 3 and nobody performed) made
119
+ * the denominator honest: seventeen, everywhere.
120
+ */
121
+ export function inspectCoreMigrations(
122
+ dbPath: string | null,
123
+ dbExists: boolean | null,
124
+ ): CoreMigrationHealth {
125
+ const requiredIds = KNOWN_MIGRATION_IDS;
126
+ if (dbPath === null) {
127
+ return health({ known_count: requiredIds.length, note: "database path unknown" });
128
+ }
129
+ if (dbExists !== true) {
130
+ return health({ known_count: requiredIds.length, note: "database missing" });
131
+ }
132
+
133
+ let rows: string[];
134
+ let db: Database | null = null;
135
+ try {
136
+ db = connectReadOnly(dbPath);
137
+ const present = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?");
138
+ if (present.get("_migrations") === undefined) {
139
+ return health({
140
+ applied_count: 0,
141
+ known_count: requiredIds.length,
142
+ missing: [...requiredIds],
143
+ note: "migration ledger missing",
144
+ });
145
+ }
146
+ rows = (db.prepare("SELECT id FROM _migrations").all() as { id: string }[]).map(
147
+ (row) => row.id,
148
+ );
149
+ } catch (error) {
150
+ return health({
151
+ known_count: requiredIds.length,
152
+ missing: [...requiredIds],
153
+ note: errorMessage(error),
154
+ });
155
+ } finally {
156
+ db?.close();
157
+ }
158
+
159
+ const applied = new Set(rows);
160
+ const missing = requiredIds.filter((id) => !applied.has(id));
161
+ const knownSet = new Set(requiredIds);
162
+ const unknown = sortByCodePoint(rows.filter((id) => !knownSet.has(id)));
163
+ const appliedKnown = requiredIds.filter((id) => applied.has(id)).length;
164
+
165
+ return {
166
+ ready: missing.length === 0 && unknown.length === 0,
167
+ applied_count: appliedKnown,
168
+ known_count: requiredIds.length,
169
+ missing,
170
+ unknown,
171
+ note: null,
172
+ };
173
+ }
174
+
175
+ /** Python `default_extensions_dir_for_home`. */
176
+ export function extensionsDirForHome(mirrorHome: string): string {
177
+ return join(mirrorHome, "extensions");
178
+ }
179
+
180
+ function extensionDirectories(mirrorHome: string | null): string[] {
181
+ if (mirrorHome === null) return [];
182
+ const dir = extensionsDirForHome(mirrorHome);
183
+ if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];
184
+ return sortByCodePoint(readdirSync(dir)).filter((name) => {
185
+ const child = join(dir, name);
186
+ return statSync(child).isDirectory() && existsSync(join(child, "skill.yaml"));
187
+ });
188
+ }
189
+
190
+ /** Port of `list_installed_extensions`: directory names, not manifest ids. */
191
+ export function listInstalledExtensions(mirrorHome: string | null): string[] {
192
+ return extensionDirectories(mirrorHome);
193
+ }
194
+
195
+ /**
196
+ * Port of `inspect_extension_health`. Only `command-skill` extensions own
197
+ * tables, so only they are graded against `_ext_migrations`; a prompt-skill is
198
+ * healthy once its manifest validates.
199
+ */
200
+ export function inspectExtensionHealth(
201
+ mirrorHome: string | null,
202
+ dbPath: string | null,
203
+ dbExists: boolean | null,
204
+ ): ExtensionHealth[] {
205
+ const names = extensionDirectories(mirrorHome);
206
+ if (mirrorHome === null || names.length === 0) return [];
207
+ const extensionsDir = extensionsDirForHome(mirrorHome);
208
+
209
+ const results: ExtensionHealth[] = [];
210
+ let db: Database | null = null;
211
+ if (dbPath !== null && dbExists === true) {
212
+ try {
213
+ db = connectReadOnly(dbPath);
214
+ } catch {
215
+ db = null;
216
+ }
217
+ }
218
+
219
+ const row = (extensionId: string, fields: Partial<ExtensionHealth>): ExtensionHealth => ({
220
+ extension_id: extensionId,
221
+ ready: false,
222
+ note: null,
223
+ pending_migrations: [],
224
+ drifted_migrations: [],
225
+ unknown_migrations: [],
226
+ ...fields,
227
+ });
228
+
229
+ try {
230
+ for (const name of names) {
231
+ const child = join(extensionsDir, name);
232
+ // The oracle attributes a manifest failure to the DIRECTORY name,
233
+ // because the declared id is exactly what it could not read.
234
+ let extensionId = name;
235
+ let kind: string;
236
+ try {
237
+ const manifest = loadExtensionManifest(child);
238
+ extensionId = manifest.id;
239
+ kind = manifest.kind;
240
+ } catch (error) {
241
+ if (!(error instanceof ExtensionError)) throw error;
242
+ results.push(row(extensionId, { note: error.message }));
243
+ continue;
244
+ }
245
+
246
+ if (kind !== "command-skill") {
247
+ results.push(row(extensionId, { ready: true }));
248
+ continue;
249
+ }
250
+ if (db === null) {
251
+ results.push(row(extensionId, { note: "database unavailable" }));
252
+ continue;
253
+ }
254
+
255
+ const migrationsDir = join(child, "migrations");
256
+ let hasLedger: boolean;
257
+ try {
258
+ hasLedger =
259
+ db
260
+ .prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?")
261
+ .get("_ext_migrations") !== undefined;
262
+ } catch (error) {
263
+ results.push(row(extensionId, { note: `database unavailable: ${errorMessage(error)}` }));
264
+ continue;
265
+ }
266
+ if (!hasLedger) {
267
+ const hasMigrations =
268
+ existsSync(migrationsDir) &&
269
+ readdirSync(migrationsDir).some((file) => file.endsWith(".sql"));
270
+ results.push(
271
+ row(extensionId, {
272
+ ready: !hasMigrations,
273
+ note: hasMigrations ? "extension migration ledger missing" : null,
274
+ }),
275
+ );
276
+ continue;
277
+ }
278
+
279
+ let pending: string[];
280
+ let drifted: string[];
281
+ let unknown: string[];
282
+ try {
283
+ ({ pending, drifted } = inspectMigrationFiles(db, extensionId, migrationsDir));
284
+ const known = new Set(
285
+ existsSync(migrationsDir)
286
+ ? readdirSync(migrationsDir).filter((file) =>
287
+ statSync(join(migrationsDir, file)).isFile(),
288
+ )
289
+ : [],
290
+ );
291
+ const applied = db
292
+ .prepare("SELECT filename FROM _ext_migrations WHERE extension_id = ?")
293
+ .all(extensionId) as { filename: string }[];
294
+ unknown = sortByCodePoint(
295
+ applied.map((entry) => String(entry.filename)).filter((file) => !known.has(file)),
296
+ );
297
+ } catch (error) {
298
+ if (!(error instanceof ExtensionError)) throw error;
299
+ results.push(row(extensionId, { note: error.message }));
300
+ continue;
301
+ }
302
+
303
+ // Note assembly is order-sensitive: the oracle appends in exactly this
304
+ // sequence and joins with `; `.
305
+ let note: string | null = null;
306
+ if (pending.length > 0) note = "pending migrations";
307
+ if (drifted.length > 0) {
308
+ note = note === null ? "migration checksum drift" : `${note}; checksum drift`;
309
+ }
310
+ if (unknown.length > 0) {
311
+ note = note === null ? "unknown applied migrations" : `${note}; unknown applied`;
312
+ }
313
+ results.push(
314
+ row(extensionId, {
315
+ ready: pending.length === 0 && drifted.length === 0 && unknown.length === 0,
316
+ note,
317
+ pending_migrations: pending,
318
+ drifted_migrations: drifted,
319
+ unknown_migrations: unknown,
320
+ }),
321
+ );
322
+ }
323
+ } finally {
324
+ db?.close();
325
+ }
326
+ return results;
327
+ }
328
+
329
+ /**
330
+ * The Node version, read from the running process rather than from `node` on
331
+ * PATH (Navigator decision, 2026-09-08). The oracle spawns `node --version`
332
+ * because it has no other way to ask; TypeScript IS the Node runtime the line
333
+ * exists to diagnose -- the docstring says so -- and `process.version` is both
334
+ * free and correct. The two disagree only when PATH's node is not the node
335
+ * running the front door, and in that case the oracle is the one that is wrong.
336
+ */
337
+ export function detectNodeVersion(): string | null {
338
+ return process.version.replace(/^v/, "") || null;
339
+ }
340
+
341
+ export interface BuildStatusOptions {
342
+ start?: string;
343
+ mirrorHome?: string | null;
344
+ channel?: string | null;
345
+ env?: DbPathEnv & NodeJS.ProcessEnv;
346
+ /** Test/golden seam: the oracle pins `package_version()` the same way. */
347
+ version?: string;
348
+ nodeVersion?: string | null;
349
+ /**
350
+ * The running front door's install, detected by the caller; the golden
351
+ * tests pin it like `version`. Absent, it is read from this tree's own
352
+ * front door with no npm probe (see `installKind.ts`).
353
+ */
354
+ install?: InstallKind;
355
+ }
356
+
357
+ /**
358
+ * The channel the report shows. A clone is inspected at `start`, as the
359
+ * oracle did and `version --start PATH` still means; a package has no tree at
360
+ * `start` and keeps its channel in the user's config file (US3 D9).
361
+ */
362
+ function channelForStatus(
363
+ install: InstallKind,
364
+ startPath: string,
365
+ override: string | null,
366
+ env: NodeJS.ProcessEnv,
367
+ ): MarkerValue {
368
+ if (install.kind === "package") return channelFor(install, env, undefined, override);
369
+ return inspectUpdateChannel(startPath, override);
370
+ }
371
+
372
+ /**
373
+ * Python's `resolve_mirror_home` raises `ValueError`, and
374
+ * `build_runtime_status` prints `str(exc)` as `Mirror home note:`. The front
375
+ * door's own resolver adds a MEMORY_DIR/DB_PATH hint that is right for a
376
+ * front-door failure and wrong for this report, which is graded against the
377
+ * oracle -- so the not-configured sentence is restated in the oracle's words.
378
+ * The conflict sentence already matches byte-for-byte.
379
+ */
380
+ function mirrorHomeForStatus(env: DbPathEnv): { home: string | null; error: string | null } {
381
+ try {
382
+ return { home: resolveMirrorHome(env), error: null };
383
+ } catch (error) {
384
+ const message = errorMessage(error);
385
+ if (message.startsWith("Mirror home is not configured")) {
386
+ return {
387
+ home: null,
388
+ error: "Mirror home is not configured. Set MIRROR_HOME or MIRROR_USER.",
389
+ };
390
+ }
391
+ return { home: null, error: message };
392
+ }
393
+ }
394
+
395
+ /** Port of `build_runtime_status`. */
396
+ export function buildRuntimeStatus(options: BuildStatusOptions = {}): RuntimeStatusReport {
397
+ const startPath = resolve(options.start ?? process.cwd());
398
+ const env = options.env ?? process.env;
399
+ const install =
400
+ options.install ??
401
+ detectInstallKind({ frontDoorPath: new URL("../frontDoor/cli.ts", import.meta.url).pathname });
402
+ // The git facts are a clone's. A package has no repository, and grading the
403
+ // cwd as one read "not a git repository" as a git error, said `attention
404
+ // needed`, and so refused every package update at the gate (CV22.DS10.US3
405
+ // plateau 4, found by the package lane of the update smoke).
406
+ const git = inspectGitFor(install, startPath);
407
+
408
+ let mirrorHome: string | null;
409
+ let mirrorHomeError: string | null;
410
+ if (options.mirrorHome !== undefined && options.mirrorHome !== null) {
411
+ const expanded = resolve(options.mirrorHome);
412
+ mirrorHome = existsSync(expanded) ? realpathSync(expanded) : expanded;
413
+ mirrorHomeError = null;
414
+ } else {
415
+ ({ home: mirrorHome, error: mirrorHomeError } = mirrorHomeForStatus(env));
416
+ }
417
+
418
+ const memoryEnv = env.MEMORY_ENV || "production";
419
+ const dbPath = mirrorHome === null ? null : join(mirrorHome, dbNameForEnv(memoryEnv));
420
+ const dbExists = dbPath === null ? null : existsSync(dbPath);
421
+
422
+ return {
423
+ version: options.version ?? "unknown",
424
+ install,
425
+ git,
426
+ mirror_home: mirrorHome,
427
+ mirror_home_error: mirrorHomeError,
428
+ db_path: dbPath,
429
+ db_exists: dbExists,
430
+ core_migrations: inspectCoreMigrations(dbPath, dbExists),
431
+ extensions: listInstalledExtensions(mirrorHome),
432
+ extension_health: inspectExtensionHealth(mirrorHome, dbPath, dbExists),
433
+ clone_role: inspectCloneRole(startPath),
434
+ memory_env: memoryEnv,
435
+ update_channel: channelForStatus(install, startPath, options.channel ?? null, env),
436
+ node_version: options.nodeVersion === undefined ? detectNodeVersion() : options.nodeVersion,
437
+ };
438
+ }
439
+
440
+ /** Port of the `status` property: any one blocker downgrades the whole report. */
441
+ export function statusVerdict(report: RuntimeStatusReport): string {
442
+ if (report.mirror_home_error) return "attention needed";
443
+ if (report.git.error) return "attention needed";
444
+ if (report.git.dirty) return "attention needed";
445
+ if (report.db_exists === false) return "attention needed";
446
+ if (!report.core_migrations.ready) return "attention needed";
447
+ if (report.extension_health.some((item) => !item.ready)) return "attention needed";
448
+ return "ready";
449
+ }
450
+
451
+ function yesNo(value: boolean | null): string {
452
+ if (value === null) return "unknown";
453
+ return value ? "yes" : "no";
454
+ }
455
+
456
+ /** Port of `_render_core_migrations`. */
457
+ export function renderCoreMigrations(item: CoreMigrationHealth): string {
458
+ if (item.ready) {
459
+ return `Core migrations: current (${item.applied_count}/${item.known_count})`;
460
+ }
461
+ const count = item.applied_count === null ? "unknown" : String(item.applied_count);
462
+ let detail = `${count}/${item.known_count} applied`;
463
+ if (item.missing.length > 0) detail = `${detail}; missing ${item.missing.join(", ")}`;
464
+ if (item.unknown.length > 0) detail = `${detail}; unknown ${item.unknown.join(", ")}`;
465
+ if (item.note) detail = `${detail}; ${item.note}`;
466
+ return `Core migrations: attention needed (${detail})`;
467
+ }
468
+
469
+ /** Port of `_render_extension_health`. */
470
+ export function renderExtensionHealth(items: readonly ExtensionHealth[]): string[] {
471
+ if (items.length === 0) return ["Extension health: ready (0 checked)"];
472
+ const issues = items.filter((item) => !item.ready);
473
+ if (issues.length === 0) return [`Extension health: ready (${items.length} checked)`];
474
+
475
+ const lines = [
476
+ `Extension health: attention needed (${items.length} checked, ${issues.length} issue(s))`,
477
+ ];
478
+ for (const item of issues) {
479
+ const details: string[] = [];
480
+ if (item.note) details.push(item.note);
481
+ if (item.pending_migrations.length > 0) {
482
+ details.push(`pending ${item.pending_migrations.join(", ")}`);
483
+ }
484
+ if (item.drifted_migrations.length > 0) {
485
+ details.push(`drifted ${item.drifted_migrations.join(", ")}`);
486
+ }
487
+ if (item.unknown_migrations.length > 0) {
488
+ details.push(`unknown ${item.unknown_migrations.join(", ")}`);
489
+ }
490
+ lines.push(
491
+ ` - ${item.extension_id}: ${details.length > 0 ? details.join("; ") : "attention needed"}`,
492
+ );
493
+ }
494
+ return lines;
495
+ }
496
+
497
+ /** Python's `f"{value:g}"` for the LLM timeout floats: `10.0` renders as `10`. */
498
+ function formatG(value: number): string {
499
+ return String(Number.parseFloat(value.toPrecision(6)));
500
+ }
501
+
502
+ function floatEnv(raw: string | undefined, fallback: number): number {
503
+ if (raw === undefined) return fallback;
504
+ const parsed = Number.parseFloat(raw);
505
+ return Number.isNaN(parsed) ? fallback : parsed;
506
+ }
507
+
508
+ function intEnv(raw: string | undefined, fallback: number): number {
509
+ if (raw === undefined) return fallback;
510
+ const parsed = Number.parseInt(raw, 10);
511
+ return Number.isNaN(parsed) ? fallback : parsed;
512
+ }
513
+
514
+ /** Port of `render_runtime_status`. */
515
+ export function renderRuntimeStatus(
516
+ report: RuntimeStatusReport,
517
+ env: NodeJS.ProcessEnv = process.env,
518
+ ): string {
519
+ const lines: string[] = ["Mirror runtime status", ""];
520
+ lines.push(`Version: ${report.version}`);
521
+ lines.push(...renderInstallLines(report.install));
522
+ lines.push(...renderRepositoryLines(report.install, report.git, true));
523
+ lines.push(`Mirror home: ${report.mirror_home ? report.mirror_home : "not configured"}`);
524
+ if (report.mirror_home_error) lines.push(`Mirror home note: ${report.mirror_home_error}`);
525
+ lines.push(`Database: ${report.db_path ? report.db_path : "unknown"}`);
526
+ lines.push(`Database exists: ${yesNo(report.db_exists)}`);
527
+ lines.push(renderCoreMigrations(report.core_migrations));
528
+ if (report.extensions.length > 0) {
529
+ lines.push(
530
+ `Installed extensions: ${report.extensions.length} (${report.extensions.join(", ")})`,
531
+ );
532
+ } else {
533
+ lines.push("Installed extensions: 0");
534
+ }
535
+ lines.push(...renderExtensionHealth(report.extension_health));
536
+ lines.push(`Clone role: ${report.clone_role.value}`);
537
+ if (report.clone_role.note) lines.push(`Clone role note: ${report.clone_role.note}`);
538
+ lines.push(`Update channel: ${report.update_channel.value}`);
539
+ if (report.update_channel.note) lines.push(`Update channel note: ${report.update_channel.note}`);
540
+ lines.push(`Node: ${report.node_version || "not found (TS front door requires Node >= 24)"}`);
541
+ lines.push(`MEMORY_ENV: ${report.memory_env}`);
542
+ const reception = floatEnv(env.MEMORY_LLM_TIMEOUT_RECEPTION, 10);
543
+ const embedding = floatEnv(env.MEMORY_LLM_TIMEOUT_EMBEDDING, 15);
544
+ const extraction = floatEnv(env.MEMORY_LLM_TIMEOUT_EXTRACTION, 60);
545
+ const retries = intEnv(env.MEMORY_LLM_MAX_RETRIES, 2);
546
+ lines.push(
547
+ `LLM timeouts (s): reception=${formatG(reception)}, ` +
548
+ `embedding=${formatG(embedding)}, extraction=${formatG(extraction)}; retries=${retries}`,
549
+ );
550
+ lines.push(
551
+ `Models: extraction=${env.MEMORY_EXTRACTION_MODEL ?? DEFAULT_EXTRACTION_MODEL}, ` +
552
+ `embedding=${env.MEMORY_EMBEDDING_MODEL ?? DEFAULT_EMBEDDING_MODEL}`,
553
+ );
554
+ lines.push("");
555
+ lines.push(`Status: ${statusVerdict(report)}`);
556
+ return `${lines.join("\n")}\n`;
557
+ }