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.
- package/.claude/hooks/log-assistant-reply.sh +85 -0
- package/.claude/hooks/log-session-end.sh +85 -0
- package/.claude/hooks/log-user-prompt.sh +85 -0
- package/.claude/hooks/mirror-inject.sh +85 -0
- package/.claude/hooks/session-start.sh +85 -0
- package/.gemini/hooks/log-assistant.sh +85 -0
- package/.gemini/hooks/log-user.sh +85 -0
- package/.gemini/hooks/session-end.sh +85 -0
- package/.gemini/hooks/session-start.sh +85 -0
- package/.pi/extensions/mirror-logger.ts +646 -0
- package/.pi/skills/mm-backup/SKILL.md +21 -0
- package/.pi/skills/mm-build/SKILL.md +1206 -0
- package/.pi/skills/mm-consolidate/SKILL.md +112 -0
- package/.pi/skills/mm-consult/SKILL.md +70 -0
- package/.pi/skills/mm-conversations/SKILL.md +16 -0
- package/.pi/skills/mm-discard/SKILL.md +39 -0
- package/.pi/skills/mm-explore/SKILL.md +255 -0
- package/.pi/skills/mm-help/SKILL.md +74 -0
- package/.pi/skills/mm-identity/SKILL.md +96 -0
- package/.pi/skills/mm-journal/SKILL.md +16 -0
- package/.pi/skills/mm-journey/SKILL.md +23 -0
- package/.pi/skills/mm-journeys/SKILL.md +15 -0
- package/.pi/skills/mm-memories/SKILL.md +17 -0
- package/.pi/skills/mm-mirror/SKILL.md +98 -0
- package/.pi/skills/mm-mute/SKILL.md +18 -0
- package/.pi/skills/mm-new/SKILL.md +18 -0
- package/.pi/skills/mm-recall/SKILL.md +17 -0
- package/.pi/skills/mm-release-notes/SKILL.md +52 -0
- package/.pi/skills/mm-seed/SKILL.md +19 -0
- package/.pi/skills/mm-shadow/SKILL.md +117 -0
- package/.pi/skills/mm-soul/SKILL.md +502 -0
- package/.pi/skills/mm-tasks/SKILL.md +24 -0
- package/.pi/skills/mm-update/SKILL.md +32 -0
- package/.pi/skills/mm-week/SKILL.md +28 -0
- package/.pi/skills/mm-welcome/SKILL.md +24 -0
- package/AGENTS.md +188 -0
- package/README.md +126 -9
- package/bin/loader.js +67 -0
- package/bin/mirror-hook.js +7 -0
- package/bin/mirror.js +7 -0
- package/docs/releases/index.md +100 -0
- package/docs/releases/pending-cutoffs.md +510 -0
- package/docs/releases/v0.10.0.md +123 -0
- package/docs/releases/v0.10.1.md +66 -0
- package/docs/releases/v0.10.10.md +51 -0
- package/docs/releases/v0.10.11.md +39 -0
- package/docs/releases/v0.10.12.md +57 -0
- package/docs/releases/v0.10.13.md +35 -0
- package/docs/releases/v0.10.14.md +42 -0
- package/docs/releases/v0.10.15.md +53 -0
- package/docs/releases/v0.10.16.md +35 -0
- package/docs/releases/v0.10.17.md +43 -0
- package/docs/releases/v0.10.2.md +64 -0
- package/docs/releases/v0.10.3.md +78 -0
- package/docs/releases/v0.10.4.md +42 -0
- package/docs/releases/v0.10.5.md +57 -0
- package/docs/releases/v0.10.6.md +47 -0
- package/docs/releases/v0.10.7.md +53 -0
- package/docs/releases/v0.10.8.md +49 -0
- package/docs/releases/v0.10.9.md +37 -0
- package/docs/releases/v0.11.0.md +86 -0
- package/docs/releases/v0.12.0.md +67 -0
- package/docs/releases/v0.13.0.md +64 -0
- package/docs/releases/v0.14.0.md +68 -0
- package/docs/releases/v0.15.0.md +48 -0
- package/docs/releases/v0.16.0.md +50 -0
- package/docs/releases/v0.16.1.md +55 -0
- package/docs/releases/v0.16.2.md +36 -0
- package/docs/releases/v0.17.0.md +50 -0
- package/docs/releases/v0.17.1.md +58 -0
- package/docs/releases/v0.17.2.md +42 -0
- package/docs/releases/v0.17.3.md +58 -0
- package/docs/releases/v0.18.0.md +84 -0
- package/docs/releases/v0.18.1.md +51 -0
- package/docs/releases/v0.18.2.md +69 -0
- package/docs/releases/v0.19.0.md +85 -0
- package/docs/releases/v0.19.1.md +46 -0
- package/docs/releases/v0.20.0.md +85 -0
- package/docs/releases/v0.21.0.md +61 -0
- package/docs/releases/v0.21.1.md +47 -0
- package/docs/releases/v0.22.0.md +77 -0
- package/docs/releases/v0.22.1.md +42 -0
- package/docs/releases/v0.23.0.md +105 -0
- package/docs/releases/v0.24.0.md +125 -0
- package/docs/releases/v0.25.0.md +107 -0
- package/docs/releases/v0.26.0.md +139 -0
- package/docs/releases/v0.26.1.md +65 -0
- package/docs/releases/v0.26.2.md +43 -0
- package/docs/releases/v0.27.0.md +63 -0
- package/docs/releases/v0.28.0.md +59 -0
- package/docs/releases/v0.29.0.md +61 -0
- package/docs/releases/v0.29.1.md +59 -0
- package/docs/releases/v0.29.2.md +59 -0
- package/docs/releases/v0.29.3.md +93 -0
- package/docs/releases/v0.30.0.md +75 -0
- package/docs/releases/v0.30.1.md +93 -0
- package/docs/releases/v0.30.2.md +66 -0
- package/docs/releases/v0.31.0.md +122 -0
- package/docs/releases/v0.31.1.md +142 -0
- package/docs/releases/v0.31.10.md +118 -0
- package/docs/releases/v0.31.11.md +88 -0
- package/docs/releases/v0.31.12.md +105 -0
- package/docs/releases/v0.31.13.md +99 -0
- package/docs/releases/v0.31.14.md +97 -0
- package/docs/releases/v0.31.2.md +115 -0
- package/docs/releases/v0.31.3.md +142 -0
- package/docs/releases/v0.31.4.md +117 -0
- package/docs/releases/v0.31.5.md +155 -0
- package/docs/releases/v0.31.6.md +132 -0
- package/docs/releases/v0.31.7.md +132 -0
- package/docs/releases/v0.31.8.md +120 -0
- package/docs/releases/v0.31.9.md +120 -0
- package/docs/releases/v0.32.0.md +261 -0
- package/docs/releases/v0.32.1.md +59 -0
- package/docs/releases/v0.33.0.md +164 -0
- package/docs/releases/v0.8.0.md +118 -0
- package/docs/releases/v0.9.0.md +98 -0
- package/docs/releases/v0.9.1.md +83 -0
- package/package.json +102 -6
- package/plugins/mirror-mind/.claude-plugin/plugin.json +17 -0
- package/plugins/mirror-mind/hooks/hooks.json +62 -0
- package/plugins/mirror-mind/hooks/log-assistant-reply.sh +98 -0
- package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
- package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
- package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
- package/plugins/mirror-mind/hooks/session-start.sh +98 -0
- package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
- package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
- package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
- package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
- package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
- package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
- package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
- package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
- package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
- package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
- package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
- package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +67 -0
- package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
- package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
- package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
- package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
- package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
- package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
- package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
- package/scripts/codex-hooks/session-end.sh +85 -0
- package/scripts/codex-hooks/session-start.sh +85 -0
- package/scripts/codex-mirror.sh +48 -0
- package/templates/identity/README.md +119 -0
- package/templates/identity/ego/behavior.yaml +52 -0
- package/templates/identity/ego/constraints.yaml +15 -0
- package/templates/identity/ego/identity.yaml +43 -0
- package/templates/identity/journeys/personal-growth.yaml +39 -0
- package/templates/identity/organization/identity.yaml +24 -0
- package/templates/identity/organization/principles.yaml +17 -0
- package/templates/identity/personas/coach.yaml +94 -0
- package/templates/identity/personas/designer.yaml +93 -0
- package/templates/identity/personas/doctor.yaml +96 -0
- package/templates/identity/personas/engineer.yaml +77 -0
- package/templates/identity/personas/financial.yaml +97 -0
- package/templates/identity/personas/prompt-engineer.yaml +122 -0
- package/templates/identity/personas/researcher.yaml +88 -0
- package/templates/identity/personas/strategist.yaml +91 -0
- package/templates/identity/personas/teacher.yaml +95 -0
- package/templates/identity/personas/therapist.yaml +91 -0
- package/templates/identity/personas/thinker.yaml +74 -0
- package/templates/identity/personas/writer.yaml +76 -0
- package/templates/identity/self/config.yaml +16 -0
- package/templates/identity/self/soul.yaml +105 -0
- package/templates/identity/user/identity.yaml +30 -0
- package/ts/src/backup/staging.ts +62 -0
- package/ts/src/backup/zipBackup.ts +267 -0
- package/ts/src/backup/zipReader.ts +109 -0
- package/ts/src/backup/zipWriter.ts +148 -0
- package/ts/src/builder/activeCheckpoint.ts +134 -0
- package/ts/src/builder/aggregateStatus.ts +34 -0
- package/ts/src/builder/approve.ts +149 -0
- package/ts/src/builder/argv.ts +292 -0
- package/ts/src/builder/ariadMethod.ts +536 -0
- package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
- package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
- package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
- package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
- package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
- package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
- package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
- package/ts/src/builder/artifacts/storyFiles.ts +61 -0
- package/ts/src/builder/artifacts/storyIndex.ts +166 -0
- package/ts/src/builder/cadence.ts +59 -0
- package/ts/src/builder/card.ts +192 -0
- package/ts/src/builder/checkpointRefused.ts +66 -0
- package/ts/src/builder/closure.ts +964 -0
- package/ts/src/builder/commands.ts +2053 -0
- package/ts/src/builder/cursorPosition.ts +176 -0
- package/ts/src/builder/cursorTransitions.ts +77 -0
- package/ts/src/builder/deliveryCursor.ts +577 -0
- package/ts/src/builder/deliveryStoryClosure.ts +521 -0
- package/ts/src/builder/deliveryStoryPlan.ts +536 -0
- package/ts/src/builder/deliveryStoryReady.ts +160 -0
- package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
- package/ts/src/builder/expand.ts +336 -0
- package/ts/src/builder/flowUnit.ts +339 -0
- package/ts/src/builder/homeSurface.ts +122 -0
- package/ts/src/builder/implementationGuard.ts +125 -0
- package/ts/src/builder/index.ts +11 -0
- package/ts/src/builder/lifecycleRefusal.ts +92 -0
- package/ts/src/builder/lifecycleRibbon.ts +159 -0
- package/ts/src/builder/load.ts +313 -0
- package/ts/src/builder/methodAdoption.ts +113 -0
- package/ts/src/builder/methodDefinition.ts +429 -0
- package/ts/src/builder/methodInspection.ts +371 -0
- package/ts/src/builder/plan.ts +408 -0
- package/ts/src/builder/planPreauthorization.ts +265 -0
- package/ts/src/builder/prepare.ts +225 -0
- package/ts/src/builder/projectPaths.ts +64 -0
- package/ts/src/builder/pull.ts +356 -0
- package/ts/src/builder/pullCandidates.ts +463 -0
- package/ts/src/builder/pullCandidatesRender.ts +238 -0
- package/ts/src/builder/refinementField.ts +93 -0
- package/ts/src/builder/releaseIntent.ts +173 -0
- package/ts/src/builder/resumeState.ts +84 -0
- package/ts/src/builder/resumeSurface.ts +149 -0
- package/ts/src/builder/roadmapGrammar.ts +300 -0
- package/ts/src/builder/roadmapScan.ts +97 -0
- package/ts/src/builder/roadmapScope.ts +210 -0
- package/ts/src/builder/scopePhrases.ts +146 -0
- package/ts/src/builder/storyPaths.ts +196 -0
- package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
- package/ts/src/builder/surfaceProtocol.ts +42 -0
- package/ts/src/builder/templateGeneration.ts +148 -0
- package/ts/src/builder/transition.ts +178 -0
- package/ts/src/consult/args.ts +99 -0
- package/ts/src/consult/core.ts +122 -0
- package/ts/src/consult/modelCatalog.ts +55 -0
- package/ts/src/consult/render.ts +47 -0
- package/ts/src/conversation/append.ts +414 -0
- package/ts/src/conversation/backfill.ts +387 -0
- package/ts/src/conversation/closeTail.ts +467 -0
- package/ts/src/conversation/extraction.ts +333 -0
- package/ts/src/conversation/extractionDriver.ts +130 -0
- package/ts/src/conversation/extractionRun.ts +70 -0
- package/ts/src/conversation/hookPayload.ts +51 -0
- package/ts/src/conversation/journeyInference.ts +165 -0
- package/ts/src/conversation/journeyRepair.ts +114 -0
- package/ts/src/conversation/lifecycleFaces.ts +197 -0
- package/ts/src/conversation/lifecycleWrites.ts +313 -0
- package/ts/src/conversation/listing.ts +77 -0
- package/ts/src/conversation/logger.ts +851 -0
- package/ts/src/conversation/loggerCli.ts +321 -0
- package/ts/src/conversation/loggerRuntime.ts +259 -0
- package/ts/src/conversation/metadataLifecycle.ts +443 -0
- package/ts/src/conversation/recall.ts +66 -0
- package/ts/src/conversation/sessionComposites.ts +258 -0
- package/ts/src/conversation/sessionImport.ts +90 -0
- package/ts/src/conversation/transcriptBackfill.ts +141 -0
- package/ts/src/cultivation/applyActions.ts +241 -0
- package/ts/src/cultivation/cluster.ts +86 -0
- package/ts/src/cultivation/consolidationStore.ts +281 -0
- package/ts/src/cultivation/promptContext.ts +62 -0
- package/ts/src/cultivation/propose.ts +305 -0
- package/ts/src/cultivation/scan.ts +155 -0
- package/ts/src/db/backupGate.ts +47 -0
- package/ts/src/db/bootstrap.ts +108 -0
- package/ts/src/db/bootstrapLock.ts +223 -0
- package/ts/src/db/copyGuard.ts +60 -0
- package/ts/src/db/database.ts +397 -0
- package/ts/src/db/decode.ts +66 -0
- package/ts/src/db/ftsIntegrity.ts +41 -0
- package/ts/src/db/migrateOnOpen.ts +214 -0
- package/ts/src/db/migrations.ts +576 -0
- package/ts/src/db/readyOnOpen.ts +35 -0
- package/ts/src/db/rowDecode.ts +42 -0
- package/ts/src/db/schema.ts +432 -0
- package/ts/src/db/schemaInventory.ts +225 -0
- package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
- package/ts/src/db/schemaState.ts +91 -0
- package/ts/src/db/schemaTsDivergence.ts +114 -0
- package/ts/src/descriptor/descriptorRead.ts +49 -0
- package/ts/src/docs/docsLint.ts +265 -0
- package/ts/src/explorer/handoff.ts +522 -0
- package/ts/src/explorer/render.ts +335 -0
- package/ts/src/explorer/story.ts +769 -0
- package/ts/src/explorer/transition.ts +72 -0
- package/ts/src/extensions/bindings.ts +170 -0
- package/ts/src/extensions/catalog.ts +249 -0
- package/ts/src/extensions/catalogCommands.ts +513 -0
- package/ts/src/extensions/catalogWrites.ts +652 -0
- package/ts/src/extensions/contextRuntime.ts +325 -0
- package/ts/src/extensions/dispatch.ts +374 -0
- package/ts/src/extensions/errors.ts +24 -0
- package/ts/src/extensions/manifest.ts +356 -0
- package/ts/src/extensions/migrations.ts +350 -0
- package/ts/src/extraction/conversation.ts +304 -0
- package/ts/src/extraction/conversationMetadata.ts +206 -0
- package/ts/src/extraction/fencing.ts +106 -0
- package/ts/src/extraction/json.ts +17 -0
- package/ts/src/extraction/prompts.ts +470 -0
- package/ts/src/frontDoor/args.ts +30 -0
- package/ts/src/frontDoor/argvShape.ts +106 -0
- package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
- package/ts/src/frontDoor/buildRoute.ts +398 -0
- package/ts/src/frontDoor/cli.ts +1872 -0
- package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
- package/ts/src/frontDoor/consultRoute.ts +50 -0
- package/ts/src/frontDoor/contentTailRoute.ts +239 -0
- package/ts/src/frontDoor/conversationLoggerRoute.ts +83 -0
- package/ts/src/frontDoor/cultivationRoute.ts +210 -0
- package/ts/src/frontDoor/dbPath.ts +131 -0
- package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
- package/ts/src/frontDoor/exploreRoute.ts +572 -0
- package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
- package/ts/src/frontDoor/frontDoorLog.ts +57 -0
- package/ts/src/frontDoor/identityWrite.ts +36 -0
- package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
- package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
- package/ts/src/frontDoor/liveBackup.ts +100 -0
- package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
- package/ts/src/frontDoor/namedRefusal.ts +35 -0
- package/ts/src/frontDoor/nodeSupport.ts +24 -0
- package/ts/src/frontDoor/render/consolidate.ts +199 -0
- package/ts/src/frontDoor/render/conversations.ts +33 -0
- package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
- package/ts/src/frontDoor/render/descriptor.ts +20 -0
- package/ts/src/frontDoor/render/detectPersona.ts +50 -0
- package/ts/src/frontDoor/render/icons.ts +13 -0
- package/ts/src/frontDoor/render/identity.ts +59 -0
- package/ts/src/frontDoor/render/identityRows.ts +17 -0
- package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
- package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
- package/ts/src/frontDoor/render/journeys.ts +79 -0
- package/ts/src/frontDoor/render/list.ts +41 -0
- package/ts/src/frontDoor/render/memories.ts +67 -0
- package/ts/src/frontDoor/render/recall.ts +49 -0
- package/ts/src/frontDoor/render/shadow.ts +155 -0
- package/ts/src/frontDoor/render/tasks.ts +99 -0
- package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
- package/ts/src/frontDoor/render/week.ts +113 -0
- package/ts/src/frontDoor/routing.ts +1001 -0
- package/ts/src/frontDoor/runtimeRoute.ts +623 -0
- package/ts/src/frontDoor/searchRoute.ts +166 -0
- package/ts/src/frontDoor/seedPaths.ts +98 -0
- package/ts/src/frontDoor/sessionStartWelcomeRoute.ts +166 -0
- package/ts/src/frontDoor/soulRoute.ts +433 -0
- package/ts/src/frontDoor/stdinSource.ts +37 -0
- package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
- package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
- package/ts/src/frontDoor/usage.ts +176 -0
- package/ts/src/guards/claudePlugin.ts +298 -0
- package/ts/src/guards/packContents.ts +306 -0
- package/ts/src/guards/piSourcedSkills.ts +70 -0
- package/ts/src/guards/retiredRouteShadows.ts +57 -0
- package/ts/src/guards/retiredSurfaces.ts +564 -0
- package/ts/src/hooks/claude.ts +214 -0
- package/ts/src/hooks/codex.ts +45 -0
- package/ts/src/hooks/gemini.ts +126 -0
- package/ts/src/hooks/main.ts +109 -0
- package/ts/src/hooks/mirrorState.ts +71 -0
- package/ts/src/hooks/payload.ts +73 -0
- package/ts/src/hooks/runtime.ts +179 -0
- package/ts/src/hooks/runtimeDetection.ts +34 -0
- package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
- package/ts/src/identity/descriptorGenerate.ts +162 -0
- package/ts/src/identity/identityEdit.ts +143 -0
- package/ts/src/identity/identityKey.ts +77 -0
- package/ts/src/identity/identityRead.ts +69 -0
- package/ts/src/identity/identityStore.ts +80 -0
- package/ts/src/identity/journeyListing.ts +53 -0
- package/ts/src/identity/personaInspect.ts +44 -0
- package/ts/src/identity/personaListing.ts +37 -0
- package/ts/src/identity/setIdentity.ts +64 -0
- package/ts/src/index.ts +231 -0
- package/ts/src/init/init.ts +111 -0
- package/ts/src/journey/journeyOptions.ts +131 -0
- package/ts/src/journey/journeyRemoval.ts +158 -0
- package/ts/src/journey/journeyStatus.ts +149 -0
- package/ts/src/journey/journeySyncFile.ts +87 -0
- package/ts/src/journey/journeyWrite.ts +203 -0
- package/ts/src/journey/parentJourney.ts +41 -0
- package/ts/src/journey/validateParentJourney.ts +55 -0
- package/ts/src/mcp/boundary.ts +151 -0
- package/ts/src/mcp/guards.ts +244 -0
- package/ts/src/mcp/main.ts +121 -0
- package/ts/src/mcp/payload.ts +141 -0
- package/ts/src/mcp/protocol.ts +141 -0
- package/ts/src/mcp/readModels.ts +241 -0
- package/ts/src/mcp/registry.ts +201 -0
- package/ts/src/mcp/serve.ts +120 -0
- package/ts/src/mcp/tools/deterministic.ts +137 -0
- package/ts/src/mcp/tools/providerCrossing.ts +187 -0
- package/ts/src/mcp/wire.ts +8 -0
- package/ts/src/memory/journal.ts +180 -0
- package/ts/src/memory/listing.ts +107 -0
- package/ts/src/memory/memoryWrite.ts +88 -0
- package/ts/src/memory/reinforcement.ts +35 -0
- package/ts/src/mirror/context.ts +161 -0
- package/ts/src/mirror/defaultResolution.ts +199 -0
- package/ts/src/mirror/mirrorForm.ts +43 -0
- package/ts/src/mirror/orchestration.ts +364 -0
- package/ts/src/mirror/reception.ts +194 -0
- package/ts/src/mirror/render.ts +75 -0
- package/ts/src/mirror/runtimeSession.ts +205 -0
- package/ts/src/mode/operatingMode.ts +148 -0
- package/ts/src/observability/callOutcome.ts +115 -0
- package/ts/src/observability/inspectLedger.ts +329 -0
- package/ts/src/observability/ledgerHooks.ts +126 -0
- package/ts/src/observability/llmCalls.ts +154 -0
- package/ts/src/persona/detectPersona.ts +81 -0
- package/ts/src/planning/promptAssembly.ts +111 -0
- package/ts/src/planning/weekPending.ts +81 -0
- package/ts/src/planning/weekPlan.ts +183 -0
- package/ts/src/planning/weekSave.ts +117 -0
- package/ts/src/providers/config.ts +189 -0
- package/ts/src/providers/cost.ts +64 -0
- package/ts/src/providers/credits.ts +204 -0
- package/ts/src/providers/embedding.ts +321 -0
- package/ts/src/providers/familyProviders.ts +147 -0
- package/ts/src/providers/llm.ts +334 -0
- package/ts/src/providers/openrouter.ts +244 -0
- package/ts/src/providers/redaction.ts +110 -0
- package/ts/src/providers/replay.ts +15 -0
- package/ts/src/providers/transport.ts +410 -0
- package/ts/src/repair/encodingRepair.ts +253 -0
- package/ts/src/runtime/backup.ts +151 -0
- package/ts/src/runtime/channel.ts +146 -0
- package/ts/src/runtime/config.ts +168 -0
- package/ts/src/runtime/diagnose.ts +686 -0
- package/ts/src/runtime/git.ts +510 -0
- package/ts/src/runtime/installKind.ts +220 -0
- package/ts/src/runtime/migrate.ts +154 -0
- package/ts/src/runtime/packageIdentity.ts +102 -0
- package/ts/src/runtime/releaseNotes.ts +244 -0
- package/ts/src/runtime/status.ts +557 -0
- package/ts/src/runtime/strategies/clone.ts +200 -0
- package/ts/src/runtime/strategies/package.ts +328 -0
- package/ts/src/runtime/treeRoot.ts +30 -0
- package/ts/src/runtime/update.ts +445 -0
- package/ts/src/runtime/updateGate.ts +40 -0
- package/ts/src/runtime/updatePipeline.ts +159 -0
- package/ts/src/runtime/version.ts +36 -0
- package/ts/src/runtime/wiring.ts +130 -0
- package/ts/src/search/memorySearch.ts +338 -0
- package/ts/src/search/ranker.ts +154 -0
- package/ts/src/seed/seed.ts +256 -0
- package/ts/src/seed/seedYaml.ts +133 -0
- package/ts/src/soul/apply.ts +218 -0
- package/ts/src/soul/harvest.ts +267 -0
- package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
- package/ts/src/soul/prompts/soul_self_voice.md +219 -0
- package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
- package/ts/src/soul/prompts.ts +85 -0
- package/ts/src/soul/render.ts +358 -0
- package/ts/src/soul/state.ts +212 -0
- package/ts/src/soul/transition.ts +37 -0
- package/ts/src/tasks/journeyPathParse.ts +113 -0
- package/ts/src/tasks/taskImportSync.ts +142 -0
- package/ts/src/tasks/taskStore.ts +312 -0
- package/ts/src/tasks/weekView.ts +120 -0
- package/ts/src/util/clipCodePoints.ts +26 -0
- package/ts/src/util/paths.ts +63 -0
- package/ts/src/util/program.ts +9 -0
- package/ts/src/util/pyGenerators.ts +144 -0
- package/ts/src/util/pythonText.ts +317 -0
- package/ts/src/util/semver.ts +45 -0
- package/ts/src/util/shellWord.ts +25 -0
- package/ts/src/util/slug.ts +64 -0
- package/ts/src/welcome/card.ts +339 -0
- package/ts/src/welcome/statusLine.ts +101 -0
- 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
|
+
}
|