mirror-mind 0.0.1 → 0.32.1
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-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 +561 -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 +99 -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.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 +13 -0
- package/plugins/mirror-mind/hooks/hooks.json +50 -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/mcp/launch.sh +52 -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 +65 -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/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 +576 -0
- package/ts/src/conversation/loggerCli.ts +282 -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 +1865 -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 +73 -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 +999 -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/soulRoute.ts +433 -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 +252 -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 +176 -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 +68 -0
- package/ts/src/hooks/runtime.ts +159 -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/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,339 @@
|
|
|
1
|
+
// CV22.DS7.US8 — the Navigator flow unit.
|
|
2
|
+
//
|
|
3
|
+
// Port of `src/memory/builder/flow_unit.py`. Plateau 3 took the read side, because
|
|
4
|
+
// Plan needs the EFFECTIVE flow unit before it can record story authority (bounded
|
|
5
|
+
// story authority exists only under `story_by_story`). Plateau 5 completes it: the
|
|
6
|
+
// write side was re-sequenced out of Scope F by the panel, since the DS smoke opens
|
|
7
|
+
// with `set-flow-unit` and seeding the flow unit by a raw cursor write instead
|
|
8
|
+
// would be the unrecorded mutation plateau 3a ruled out.
|
|
9
|
+
//
|
|
10
|
+
// The selection surface is CHOSEN by the unit, not fixed: `delivery_story` renders
|
|
11
|
+
// DELIVERY_STORY_SCOPE_CONFIRMATION over the child work packages, `story_by_story`
|
|
12
|
+
// renders NEXT_STORY_CONFIRMATION over the first child as the recommended story.
|
|
13
|
+
// One function, two surface ids — a port that hard-codes either one fails the
|
|
14
|
+
// corpus guard that compares each recorded id against its own wrapped marker.
|
|
15
|
+
//
|
|
16
|
+
// CR105: choosing also RECORDS the question its surface asks, as the cursor's
|
|
17
|
+
// checkpoint and pending confirmation, and only at a Delivery Story's flow
|
|
18
|
+
// decision: after Prepare or Expand, before its Plan. Until then, Expand's
|
|
19
|
+
// story-by-story stop survived a choice of Delivery Story flow, and every surface
|
|
20
|
+
// that reads the cursor reported a question that flow never asks.
|
|
21
|
+
|
|
22
|
+
import type { WritableDatabase } from "#db/database.ts";
|
|
23
|
+
import { pyStrip } from "#util/pythonText.ts";
|
|
24
|
+
import { hasDeliveryStoryPlan } from "./aggregateStatus.ts";
|
|
25
|
+
import { cardPrefixed, cardText, cardWrapped } from "./card.ts";
|
|
26
|
+
import { deliveryStoryCodeForItem } from "./cursorTransitions.ts";
|
|
27
|
+
import {
|
|
28
|
+
type BuilderDeliveryCursor,
|
|
29
|
+
type CursorWriteDeps,
|
|
30
|
+
getDeliveryCursor,
|
|
31
|
+
setDeliveryCursor,
|
|
32
|
+
} from "./deliveryCursor.ts";
|
|
33
|
+
import { wrapAriadSurface } from "./surfaceProtocol.ts";
|
|
34
|
+
|
|
35
|
+
export const FLOW_UNIT_STORY_BY_STORY = "story_by_story";
|
|
36
|
+
export const FLOW_UNIT_DELIVERY_STORY = "delivery_story";
|
|
37
|
+
export const ALLOWED_FLOW_UNITS = [FLOW_UNIT_STORY_BY_STORY, FLOW_UNIT_DELIVERY_STORY] as const;
|
|
38
|
+
|
|
39
|
+
/** A Navigator stop as the cursor records it: the checkpoint, and what the Navigator owes. */
|
|
40
|
+
export interface FlowStop {
|
|
41
|
+
readonly checkpoint: string;
|
|
42
|
+
readonly confirmation: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* CR105: the question each flow unit's surface asks, as the cursor records it. The
|
|
47
|
+
* checkpoint is the surface's own id. Expand records the story-by-story stop, since
|
|
48
|
+
* its next-story question is the default flow's; choosing a flow unit records its
|
|
49
|
+
* own. The Delivery Story Plan replaces the scope stop, and nothing enforces it:
|
|
50
|
+
* CR001 declined a runtime-enforced scope stop, and this is recorded, not enforced.
|
|
51
|
+
*/
|
|
52
|
+
export const FLOW_STOPS: Readonly<Record<(typeof ALLOWED_FLOW_UNITS)[number], FlowStop>> = {
|
|
53
|
+
story_by_story: {
|
|
54
|
+
checkpoint: "next_story_confirmation",
|
|
55
|
+
confirmation: "navigator_story_confirmation",
|
|
56
|
+
},
|
|
57
|
+
delivery_story: {
|
|
58
|
+
checkpoint: "delivery_story_scope_confirmation",
|
|
59
|
+
confirmation: "navigator_scope_confirmation",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const FLOW_CONFIRMATIONS: ReadonlySet<string> = new Set(
|
|
64
|
+
Object.values(FLOW_STOPS).map((stop) => stop.confirmation),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* CR105: why a flow unit cannot be chosen on this cursor, or null at a Delivery
|
|
69
|
+
* Story's flow decision: after Prepare or Expand, before its Plan. The active item is
|
|
70
|
+
* a Delivery Story, its Plan is not recorded, and nothing is pending but a flow stop,
|
|
71
|
+
* or nothing at all. Anywhere else the choice would print a question the cursor is not
|
|
72
|
+
* at, and after a Delivery Story Plan it stranded the Delivery Story: approval started
|
|
73
|
+
* its implementation under story-by-story flow, and its closure then refused.
|
|
74
|
+
*
|
|
75
|
+
* The sentence leads with the consequence, for the agent reading it.
|
|
76
|
+
*/
|
|
77
|
+
export function flowDecisionRefusal(cursor: BuilderDeliveryCursor): string | null {
|
|
78
|
+
const refused = "no flow unit was chosen";
|
|
79
|
+
const item = cursor.activeItem;
|
|
80
|
+
if (!item) {
|
|
81
|
+
return `${refused}: no item has been pulled yet, and a flow unit is chosen for an active Delivery Story.`;
|
|
82
|
+
}
|
|
83
|
+
if (cursor.activeItemLevel !== "delivery_story") {
|
|
84
|
+
const level = cursor.activeItemLevel
|
|
85
|
+
? `is a ${cursor.activeItemLevel.replaceAll("_", " ")}`
|
|
86
|
+
: "is not a Delivery Story";
|
|
87
|
+
const deliveryStory = deliveryStoryCodeForItem(item);
|
|
88
|
+
const whose = deliveryStory ? `its Delivery Story, ${deliveryStory},` : "its Delivery Story";
|
|
89
|
+
return `${refused}: the active item, ${item}, ${level}. The flow unit is chosen for ${whose} before that Delivery Story's Plan.`;
|
|
90
|
+
}
|
|
91
|
+
if (hasDeliveryStoryPlan(cursor.aggregateCheckpointStatus)) {
|
|
92
|
+
return `${refused}: ${item}'s Delivery Story Plan is already recorded, and the flow unit is chosen before it.`;
|
|
93
|
+
}
|
|
94
|
+
const pending = cursor.pendingConfirmation;
|
|
95
|
+
if (pending !== null && !FLOW_CONFIRMATIONS.has(pending)) {
|
|
96
|
+
return `${refused}: ${item} is waiting for ${pending}, and the flow unit is chosen before its Plan.`;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Python `effective_navigator_flow_unit`.
|
|
103
|
+
*
|
|
104
|
+
* An unset or UNRECOGNIZED value falls back to `story_by_story` with source
|
|
105
|
+
* `default`, rather than raising — so a cursor written by a newer engine, or one
|
|
106
|
+
* carrying a typo, still yields a usable flow unit instead of blocking the
|
|
107
|
+
* lifecycle. The source is returned because the Navigator-facing surfaces
|
|
108
|
+
* distinguish "you chose this" from "this is the default".
|
|
109
|
+
*/
|
|
110
|
+
export function effectiveNavigatorFlowUnit(cursor: BuilderDeliveryCursor): {
|
|
111
|
+
flowUnit: string;
|
|
112
|
+
source: string;
|
|
113
|
+
} {
|
|
114
|
+
const current = cursor.navigatorFlowUnit;
|
|
115
|
+
if (current !== null && (ALLOWED_FLOW_UNITS as readonly string[]).includes(current)) {
|
|
116
|
+
return { flowUnit: current, source: "cursor" };
|
|
117
|
+
}
|
|
118
|
+
return { flowUnit: FLOW_UNIT_STORY_BY_STORY, source: "default" };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface NavigatorFlowUnitReport {
|
|
122
|
+
readonly journey: string;
|
|
123
|
+
readonly method: string;
|
|
124
|
+
readonly activeItem: string | null;
|
|
125
|
+
readonly activeItemTitle: string | null;
|
|
126
|
+
readonly activeItemLevel: string | null;
|
|
127
|
+
readonly flowUnit: string;
|
|
128
|
+
readonly source: string;
|
|
129
|
+
readonly cursor: BuilderDeliveryCursor;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Python `set_navigator_flow_unit`.
|
|
134
|
+
*
|
|
135
|
+
* Validation BEFORE the cursor read, so an unknown unit reports the allowed values
|
|
136
|
+
* even when no cursor exists. The choice is made only at the Delivery Story's flow
|
|
137
|
+
* decision, and anywhere else it refuses before writing (`flowDecisionRefusal`). It
|
|
138
|
+
* is not a lifecycle transition: it writes the unit, `last_delivery_event`, and the
|
|
139
|
+
* stop its surface asks (CR105). Everything else on the cursor carries forward.
|
|
140
|
+
*/
|
|
141
|
+
export function setNavigatorFlowUnit(
|
|
142
|
+
db: WritableDatabase,
|
|
143
|
+
options: { journey: string; method: string; flowUnit: string },
|
|
144
|
+
deps: CursorWriteDeps,
|
|
145
|
+
): NavigatorFlowUnitReport {
|
|
146
|
+
if (!(ALLOWED_FLOW_UNITS as readonly string[]).includes(options.flowUnit)) {
|
|
147
|
+
throw new Error(`navigator flow unit must be one of: ${ALLOWED_FLOW_UNITS.join(", ")}`);
|
|
148
|
+
}
|
|
149
|
+
const existing = getDeliveryCursor(db, options.journey);
|
|
150
|
+
if (existing === null) {
|
|
151
|
+
throw new Error("delivery cursor is required before choosing navigator flow unit");
|
|
152
|
+
}
|
|
153
|
+
const refusal = flowDecisionRefusal(existing);
|
|
154
|
+
if (refusal !== null) throw new Error(refusal);
|
|
155
|
+
const stop = FLOW_STOPS[options.flowUnit as (typeof ALLOWED_FLOW_UNITS)[number]];
|
|
156
|
+
const updated = setDeliveryCursor(
|
|
157
|
+
db,
|
|
158
|
+
{
|
|
159
|
+
journey: options.journey,
|
|
160
|
+
method: options.method,
|
|
161
|
+
activeItem: existing.activeItem,
|
|
162
|
+
activeItemTitle: existing.activeItemTitle,
|
|
163
|
+
activeItemLevel: existing.activeItemLevel,
|
|
164
|
+
activeCheckpoint: stop.checkpoint,
|
|
165
|
+
pendingConfirmation: stop.confirmation,
|
|
166
|
+
lastDeliveryEvent: "navigator_flow_unit_selected",
|
|
167
|
+
cadenceProfile: existing.cadenceProfile,
|
|
168
|
+
cadenceLimits: existing.cadenceLimits,
|
|
169
|
+
granularityDecision: existing.granularityDecision,
|
|
170
|
+
navigatorFlowUnit: options.flowUnit,
|
|
171
|
+
childWorkItems: existing.childWorkItems,
|
|
172
|
+
aggregateCheckpointStatus: existing.aggregateCheckpointStatus,
|
|
173
|
+
},
|
|
174
|
+
deps,
|
|
175
|
+
);
|
|
176
|
+
return {
|
|
177
|
+
journey: options.journey,
|
|
178
|
+
method: options.method,
|
|
179
|
+
activeItem: updated.activeItem,
|
|
180
|
+
activeItemTitle: updated.activeItemTitle,
|
|
181
|
+
activeItemLevel: updated.activeItemLevel,
|
|
182
|
+
flowUnit: options.flowUnit,
|
|
183
|
+
source: "cursor",
|
|
184
|
+
cursor: updated,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Python `inspect_navigator_flow_unit`. */
|
|
189
|
+
export function inspectNavigatorFlowUnit(
|
|
190
|
+
db: WritableDatabase,
|
|
191
|
+
options: { journey: string; method: string },
|
|
192
|
+
): NavigatorFlowUnitReport {
|
|
193
|
+
const cursor = getDeliveryCursor(db, options.journey);
|
|
194
|
+
if (cursor === null) {
|
|
195
|
+
throw new Error("delivery cursor is required before inspecting navigator flow unit");
|
|
196
|
+
}
|
|
197
|
+
const { flowUnit, source } = effectiveNavigatorFlowUnit(cursor);
|
|
198
|
+
return {
|
|
199
|
+
journey: options.journey,
|
|
200
|
+
method: options.method,
|
|
201
|
+
activeItem: cursor.activeItem,
|
|
202
|
+
activeItemTitle: cursor.activeItemTitle,
|
|
203
|
+
activeItemLevel: cursor.activeItemLevel,
|
|
204
|
+
flowUnit,
|
|
205
|
+
source,
|
|
206
|
+
cursor,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Python `_active_delivery`. */
|
|
211
|
+
function activeDelivery(report: NavigatorFlowUnitReport): string {
|
|
212
|
+
if (report.activeItem === null) return "none";
|
|
213
|
+
const title = report.activeItemTitle ? ` — ${report.activeItemTitle}` : "";
|
|
214
|
+
return `🟦[${report.activeItem}]${title}`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Python `_scope_item_lines`: an EMPTY list renders nothing, not `none`. */
|
|
218
|
+
function scopeItemLines(label: string, items: readonly string[]): string[] {
|
|
219
|
+
if (items.length === 0) return [];
|
|
220
|
+
return [
|
|
221
|
+
"│ │",
|
|
222
|
+
cardText(label),
|
|
223
|
+
...cardPrefixed(items, "-"),
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Python `_delivery_story_scope_hypothesis`.
|
|
229
|
+
*
|
|
230
|
+
* The checkout/address special case is product copy, not a heuristic worth
|
|
231
|
+
* generalizing: it is reproduced verbatim because the surface is graded byte for
|
|
232
|
+
* byte.
|
|
233
|
+
*/
|
|
234
|
+
function deliveryStoryScopeHypothesis(report: NavigatorFlowUnitReport): string {
|
|
235
|
+
const title = pyStrip(report.activeItemTitle ?? "");
|
|
236
|
+
const normalized = title.toLowerCase();
|
|
237
|
+
if (normalized.includes("checkout") && normalized.includes("address")) {
|
|
238
|
+
return (
|
|
239
|
+
"This Delivery Story should let the customer enter checkout, provide or confirm " +
|
|
240
|
+
"a delivery address, and leave the order ready for the next checkout step."
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (title) return `This Delivery Story should deliver the scope implied by: ${title}.`;
|
|
244
|
+
return (
|
|
245
|
+
"I will infer a complete Delivery Story plan from the roadmap and project context; " +
|
|
246
|
+
"correct or add any scope details before I proceed."
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Python `render_flow_unit_scope_confirmation_report`. */
|
|
251
|
+
export function renderFlowUnitScopeConfirmationReport(report: NavigatorFlowUnitReport): string {
|
|
252
|
+
const deliveryStory = report.flowUnit === FLOW_UNIT_DELIVERY_STORY;
|
|
253
|
+
const surfaceName = deliveryStory
|
|
254
|
+
? "delivery_story_scope_confirmation"
|
|
255
|
+
: "next_story_confirmation";
|
|
256
|
+
const title = deliveryStory
|
|
257
|
+
? " 🧭 DELIVERY STORY SCOPE CONFIRMATION"
|
|
258
|
+
: " 🧭 NEXT STORY CONFIRMATION";
|
|
259
|
+
const understanding = deliveryStory
|
|
260
|
+
? deliveryStoryScopeHypothesis(report)
|
|
261
|
+
: "We will continue story by story. The next step is to confirm which child story " +
|
|
262
|
+
"becomes the next Navigator-facing lifecycle unit.";
|
|
263
|
+
const scopeLabel = deliveryStory ? "Work packages in scope" : "Recommended story";
|
|
264
|
+
const scopeItems = deliveryStory
|
|
265
|
+
? report.cursor.childWorkItems
|
|
266
|
+
: report.cursor.childWorkItems.slice(0, 1);
|
|
267
|
+
const prompt = deliveryStory
|
|
268
|
+
? "Before I create the DS Plan, correct or add anything:"
|
|
269
|
+
: "Before I create the Story Plan, correct or add anything:";
|
|
270
|
+
const question = deliveryStory
|
|
271
|
+
? "1. Is this the right scope?"
|
|
272
|
+
: "1. Is this the right next story?";
|
|
273
|
+
const body = [
|
|
274
|
+
"Delivery",
|
|
275
|
+
"",
|
|
276
|
+
"╭────────────────────────────────────────────────────────╮",
|
|
277
|
+
cardText(title),
|
|
278
|
+
"│ │",
|
|
279
|
+
cardText("My understanding"),
|
|
280
|
+
...cardWrapped(understanding),
|
|
281
|
+
"│ │",
|
|
282
|
+
cardText("Active delivery"),
|
|
283
|
+
...cardWrapped(activeDelivery(report)),
|
|
284
|
+
...scopeItemLines(scopeLabel, scopeItems),
|
|
285
|
+
"│ │",
|
|
286
|
+
...cardWrapped(prompt),
|
|
287
|
+
...cardWrapped(question),
|
|
288
|
+
"│ │",
|
|
289
|
+
...cardWrapped("Choose the next move when ready."),
|
|
290
|
+
"╰────────────────────────────────────────────────────────╯",
|
|
291
|
+
];
|
|
292
|
+
return wrapAriadSurface(surfaceName, `${body.join("\n")}\n`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Python `_flow_unit_change_summary` / `_description` / `_next_movement`. */
|
|
296
|
+
function flowUnitChangeSummary(flowUnit: string): string {
|
|
297
|
+
return flowUnit === FLOW_UNIT_DELIVERY_STORY
|
|
298
|
+
? "Navigator-facing lifecycle will continue at Delivery Story level."
|
|
299
|
+
: "Navigator-facing lifecycle will continue story by story.";
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function flowUnitDescription(flowUnit: string): string {
|
|
303
|
+
return flowUnit === FLOW_UNIT_DELIVERY_STORY
|
|
304
|
+
? "the Delivery Story becomes the lifecycle unit; child stories remain traceable work packages"
|
|
305
|
+
: "child stories get their own Navigator checkpoints";
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function flowUnitNextMovement(flowUnit: string): string {
|
|
309
|
+
return flowUnit === FLOW_UNIT_DELIVERY_STORY
|
|
310
|
+
? "Plan the Delivery Story as the Navigator-facing unit."
|
|
311
|
+
: "Confirm the recommended child story, then Plan.";
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** Python `render_navigator_flow_unit_report`: the READ face. */
|
|
315
|
+
export function renderNavigatorFlowUnitReport(report: NavigatorFlowUnitReport): string {
|
|
316
|
+
const body = [
|
|
317
|
+
"Delivery",
|
|
318
|
+
"",
|
|
319
|
+
"╭────────────────────────────────────────────────────────╮",
|
|
320
|
+
"│ 🧭 FLOW UNIT SELECTED │",
|
|
321
|
+
"│ │",
|
|
322
|
+
cardText("What changed?"),
|
|
323
|
+
...cardWrapped(flowUnitChangeSummary(report.flowUnit)),
|
|
324
|
+
"│ │",
|
|
325
|
+
cardText("Active delivery"),
|
|
326
|
+
...cardWrapped(activeDelivery(report)),
|
|
327
|
+
"│ │",
|
|
328
|
+
cardText("Selected flow unit"),
|
|
329
|
+
cardText(report.flowUnit),
|
|
330
|
+
...cardWrapped(flowUnitDescription(report.flowUnit)),
|
|
331
|
+
"│ │",
|
|
332
|
+
cardText("Next movement"),
|
|
333
|
+
...cardWrapped(flowUnitNextMovement(report.flowUnit)),
|
|
334
|
+
"│ │",
|
|
335
|
+
...cardWrapped("Choose the next move when ready."),
|
|
336
|
+
"╰────────────────────────────────────────────────────────╯",
|
|
337
|
+
];
|
|
338
|
+
return wrapAriadSurface("navigator_flow_unit", `${body.join("\n")}\n`);
|
|
339
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// CV22.DS7.US8 plateau 1 — the Builder Orientation surface.
|
|
2
|
+
//
|
|
3
|
+
// Port of `render_builder_orientation_surface` in
|
|
4
|
+
// `src/memory/builder/home_surface.py`. This is what `build load` shows an Ariad
|
|
5
|
+
// journey with no active item, and it is almost entirely branches — which is what
|
|
6
|
+
// a port collapses. Three of them are worth naming because each is a silent
|
|
7
|
+
// behavior change if merged:
|
|
8
|
+
//
|
|
9
|
+
// * `_available_refinement_moves` RETURNS EARLY for a canonical index, so the
|
|
10
|
+
// Workbench-storage move below it is unreachable in that state. An
|
|
11
|
+
// `if/elif` chain written without the early return appends it.
|
|
12
|
+
// * `_refinement_orientation_lines` has two shapes since CV22.DS10.TS4: a
|
|
13
|
+
// canonical index, and none.
|
|
14
|
+
// * It renders only without an active item, so since CR002 it takes the raw
|
|
15
|
+
// project-wide report, never a scope. Python placed the journey in the CV of
|
|
16
|
+
// a project-wide recommendation, synthesizing `🟪[CV99] roadmap focus` when
|
|
17
|
+
// that CV was absent from the snapshot. Now the journey is told no item was
|
|
18
|
+
// pulled, the list is labelled project-wide, and the first move is the
|
|
19
|
+
// literal Pull command. Its scoped branches were unreachable and went in
|
|
20
|
+
// CR002's handoff review.
|
|
21
|
+
//
|
|
22
|
+
// `render_builder_home_surface` was ported and never called: `build load`
|
|
23
|
+
// renders `PROJECT_POSITION` and this surface. CR002 deleted it rather than
|
|
24
|
+
// scope a surface no journey could see, whose one distinctive line was a
|
|
25
|
+
// project-wide "recommended pull".
|
|
26
|
+
//
|
|
27
|
+
// CR115: it asks how the next item will run, and answers with the journey's cadence,
|
|
28
|
+
// which shapes the next Plan; `build load` passes the cursor's, so every caller decides.
|
|
29
|
+
|
|
30
|
+
import { type CadenceView, cadenceOrientationLines } from "./cadence.ts";
|
|
31
|
+
import { cardPrefixed, cardText, cardWrapped } from "./card.ts";
|
|
32
|
+
import type { PullCandidatesReport } from "./pullCandidates.ts";
|
|
33
|
+
import { CANONICAL_REFINEMENT_INDEX, type RefinementFieldSnapshot } from "./refinementField.ts";
|
|
34
|
+
import { NO_ITEM_PULLED_YET, PROJECT_WIDE_CANDIDATES, pullExplicitly } from "./scopePhrases.ts";
|
|
35
|
+
import { wrapAriadSurface } from "./surfaceProtocol.ts";
|
|
36
|
+
|
|
37
|
+
const FRAME_TOP = "╭────────────────────────────────────────────────────────╮";
|
|
38
|
+
const FRAME_BOTTOM = "╰────────────────────────────────────────────────────────╯";
|
|
39
|
+
const FRAME_BLANK = "│ │";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Python `_pull_candidate_lines`, project-wide. Python marked its project-wide
|
|
43
|
+
* recommendation with `▸`; without a journey scope there is none, so every
|
|
44
|
+
* candidate is a `·`.
|
|
45
|
+
*/
|
|
46
|
+
function pullCandidateLines(report: PullCandidatesReport): string[] {
|
|
47
|
+
const lines = [cardText(PROJECT_WIDE_CANDIDATES)];
|
|
48
|
+
if (report.candidates.length === 0) lines.push(cardText("none"));
|
|
49
|
+
for (const candidate of report.candidates) {
|
|
50
|
+
lines.push(...cardWrapped(`· ${candidate.code} ${candidate.title}`));
|
|
51
|
+
}
|
|
52
|
+
return lines;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Python `_refinement_orientation_lines`. Two shapes since CV22.DS10.TS4. */
|
|
56
|
+
function refinementOrientationLines(refinement: RefinementFieldSnapshot): string[] {
|
|
57
|
+
if (refinement.canonicalIndex) {
|
|
58
|
+
return [
|
|
59
|
+
cardText("authority: project files"),
|
|
60
|
+
...cardWrapped(`index: ${refinement.canonicalIndex}`),
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
return [
|
|
64
|
+
cardText("authority: project files (not started)"),
|
|
65
|
+
...cardWrapped(`create: ${CANONICAL_REFINEMENT_INDEX}`),
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Python `_available_refinement_moves`. The canonical-index path returns after
|
|
71
|
+
* three moves; the legacy path always appends a fourth. The first move is the
|
|
72
|
+
* literal Pull command: the surface renders only when no item has been pulled.
|
|
73
|
+
*/
|
|
74
|
+
export function availableRefinementMoves(
|
|
75
|
+
refinement: RefinementFieldSnapshot,
|
|
76
|
+
journey: string,
|
|
77
|
+
): string[] {
|
|
78
|
+
const moves = [pullExplicitly(journey), "inspect roadmap"];
|
|
79
|
+
if (refinement.canonicalIndex) {
|
|
80
|
+
moves.push("inspect canonical Refinement index");
|
|
81
|
+
return moves;
|
|
82
|
+
}
|
|
83
|
+
moves.push(`create ${CANONICAL_REFINEMENT_INDEX}`);
|
|
84
|
+
return moves;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Python `render_builder_orientation_surface`, for a journey with no active item:
|
|
89
|
+
* `build load`'s only caller. `candidates` is the raw project-wide scan.
|
|
90
|
+
*/
|
|
91
|
+
export function renderBuilderOrientationSurface(options: {
|
|
92
|
+
candidates: PullCandidatesReport;
|
|
93
|
+
refinement: RefinementFieldSnapshot;
|
|
94
|
+
cadence: CadenceView;
|
|
95
|
+
}): string {
|
|
96
|
+
const { candidates, refinement, cadence } = options;
|
|
97
|
+
const lines: string[] = [
|
|
98
|
+
"Builder Orientation",
|
|
99
|
+
"",
|
|
100
|
+
FRAME_TOP,
|
|
101
|
+
"│ ■ BUILDER ORIENTATION │",
|
|
102
|
+
FRAME_BLANK,
|
|
103
|
+
cardText("Where are we in the roadmap?"),
|
|
104
|
+
cardText(NO_ITEM_PULLED_YET),
|
|
105
|
+
FRAME_BLANK,
|
|
106
|
+
cardText("What can be pulled next?"),
|
|
107
|
+
...pullCandidateLines(candidates),
|
|
108
|
+
FRAME_BLANK,
|
|
109
|
+
cardText("What is open for refinement?"),
|
|
110
|
+
...refinementOrientationLines(refinement),
|
|
111
|
+
FRAME_BLANK,
|
|
112
|
+
cardText("How will the next item run?"),
|
|
113
|
+
...cadenceOrientationLines(cadence),
|
|
114
|
+
FRAME_BLANK,
|
|
115
|
+
cardText("What can we do now?"),
|
|
116
|
+
...cardPrefixed(availableRefinementMoves(refinement, candidates.journey), "-"),
|
|
117
|
+
FRAME_BLANK,
|
|
118
|
+
...cardWrapped("Choose a move when ready."),
|
|
119
|
+
FRAME_BOTTOM,
|
|
120
|
+
];
|
|
121
|
+
return wrapAriadSurface("builder_orientation", `${lines.join("\n")}\n`);
|
|
122
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// CV22.DS7.US8 plateau 2 — the implementation guard.
|
|
2
|
+
//
|
|
3
|
+
// Port of `assert_implementation_allowed`,
|
|
4
|
+
// `render_implementation_guard_allowed`, and
|
|
5
|
+
// `render_implementation_guard_blocked` from `src/memory/builder/lifecycle.py`.
|
|
6
|
+
// This is the leaf `build check-implementation` answers, and the reason it moved
|
|
7
|
+
// out of plateau 1: it reads the delivery cursor.
|
|
8
|
+
//
|
|
9
|
+
// It is not a boolean. Four outcomes, and the order of the checks decides which
|
|
10
|
+
// message a Navigator sees:
|
|
11
|
+
//
|
|
12
|
+
// 1. no cursor at all -> requires a delivery cursor
|
|
13
|
+
// 2. ANY pending confirmation -> blocked on that confirmation,
|
|
14
|
+
// even when the Plan is approved, because an unanswered checkpoint outranks
|
|
15
|
+
// an approval
|
|
16
|
+
// 3. `last_delivery_event == "plan_approved"` -> allowed
|
|
17
|
+
// 4. the Delivery Story combination -> allowed, but only with ALL FOUR
|
|
18
|
+
// conditions: event `delivery_story_plan_approved`, level `delivery_story`,
|
|
19
|
+
// flow unit `delivery_story`, and `plan:approved` present in the aggregate
|
|
20
|
+
// checkpoint status. Miss any one and the generic refusal is what prints.
|
|
21
|
+
//
|
|
22
|
+
// Note what is NOT required: an active item. A cursor whose event is
|
|
23
|
+
// `plan_approved` with no active item is ALLOWED, and the surface renders
|
|
24
|
+
// `active item / none`. That reads like an oversight and is Python's behavior.
|
|
25
|
+
|
|
26
|
+
import type { Database } from "#db/database.ts";
|
|
27
|
+
import { cardText, cardWrapped } from "./card.ts";
|
|
28
|
+
import type { BuilderDeliveryCursor } from "./deliveryCursor.ts";
|
|
29
|
+
import { getDeliveryCursor } from "./deliveryCursor.ts";
|
|
30
|
+
import { renderLifecycleRibbon } from "./lifecycleRibbon.ts";
|
|
31
|
+
import { wrapAriadSurface } from "./surfaceProtocol.ts";
|
|
32
|
+
|
|
33
|
+
const FRAME_TOP = "╭────────────────────────────────────────────────────────╮";
|
|
34
|
+
const FRAME_BOTTOM = "╰────────────────────────────────────────────────────────╯";
|
|
35
|
+
const FRAME_BLANK = "│ │";
|
|
36
|
+
const GUARD_TITLE = "│ 🟧■ IMPLEMENTATION GUARD │";
|
|
37
|
+
|
|
38
|
+
/** Python's `PermissionError` from the guard. */
|
|
39
|
+
export class ImplementationBlockedError extends Error {
|
|
40
|
+
constructor(message: string) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.name = "ImplementationBlockedError";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Python `_has_approved_delivery_story_plan`: all four conditions. */
|
|
47
|
+
export function hasApprovedDeliveryStoryPlan(cursor: BuilderDeliveryCursor): boolean {
|
|
48
|
+
return (
|
|
49
|
+
cursor.lastDeliveryEvent === "delivery_story_plan_approved" &&
|
|
50
|
+
cursor.activeItemLevel === "delivery_story" &&
|
|
51
|
+
cursor.navigatorFlowUnit === "delivery_story" &&
|
|
52
|
+
cursor.aggregateCheckpointStatus.includes("plan:approved")
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Python `assert_implementation_allowed`. */
|
|
57
|
+
export function assertImplementationAllowed(db: Database, journey: string): BuilderDeliveryCursor {
|
|
58
|
+
const normalized = typeof journey === "string" ? journey.trim() : "";
|
|
59
|
+
if (!normalized) throw new Error("journey must not be empty");
|
|
60
|
+
const cursor = getDeliveryCursor(db, normalized);
|
|
61
|
+
if (cursor === null) {
|
|
62
|
+
throw new ImplementationBlockedError("Implementation requires a Builder delivery cursor");
|
|
63
|
+
}
|
|
64
|
+
if (cursor.pendingConfirmation) {
|
|
65
|
+
throw new ImplementationBlockedError(
|
|
66
|
+
`Implementation is blocked: pending confirmation ${cursor.pendingConfirmation}.`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (cursor.lastDeliveryEvent === "plan_approved") return cursor;
|
|
70
|
+
if (hasApprovedDeliveryStoryPlan(cursor)) return cursor;
|
|
71
|
+
throw new ImplementationBlockedError(
|
|
72
|
+
"Implementation is blocked: approved Plan is required before Implement.",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Python `render_implementation_guard_allowed`. */
|
|
77
|
+
export function renderImplementationGuardAllowed(cursor: BuilderDeliveryCursor): string {
|
|
78
|
+
const body = [
|
|
79
|
+
"Delivery",
|
|
80
|
+
renderLifecycleRibbon("implement", cursor.activeItemLevel),
|
|
81
|
+
"",
|
|
82
|
+
FRAME_TOP,
|
|
83
|
+
GUARD_TITLE,
|
|
84
|
+
FRAME_BLANK,
|
|
85
|
+
cardText("status"),
|
|
86
|
+
cardText("allowed"),
|
|
87
|
+
FRAME_BLANK,
|
|
88
|
+
cardText("active item"),
|
|
89
|
+
cardText(cursor.activeItem || "none"),
|
|
90
|
+
FRAME_BLANK,
|
|
91
|
+
cardText("last delivery event"),
|
|
92
|
+
cardText(cursor.lastDeliveryEvent || "none"),
|
|
93
|
+
FRAME_BLANK,
|
|
94
|
+
cardText("boundary"),
|
|
95
|
+
...cardWrapped("Implementation may begin under the approved Plan contract."),
|
|
96
|
+
FRAME_BOTTOM,
|
|
97
|
+
].join("\n");
|
|
98
|
+
return wrapAriadSurface("implementation_guard", `${body}\n`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Python `render_implementation_guard_blocked`. The level is the cursor's, when there
|
|
103
|
+
* is one: the refusal carries only its reason, and a story's ribbon must still say
|
|
104
|
+
* Expand never applied (CR113).
|
|
105
|
+
*/
|
|
106
|
+
export function renderImplementationGuardBlocked(reason: string, level: string | null): string {
|
|
107
|
+
const body = [
|
|
108
|
+
"Delivery",
|
|
109
|
+
renderLifecycleRibbon("implement", level),
|
|
110
|
+
"",
|
|
111
|
+
FRAME_TOP,
|
|
112
|
+
GUARD_TITLE,
|
|
113
|
+
FRAME_BLANK,
|
|
114
|
+
cardText("status"),
|
|
115
|
+
cardText("blocked"),
|
|
116
|
+
FRAME_BLANK,
|
|
117
|
+
cardText("missing checkpoint"),
|
|
118
|
+
...cardWrapped(reason),
|
|
119
|
+
FRAME_BLANK,
|
|
120
|
+
cardText("boundary"),
|
|
121
|
+
...cardWrapped("No implementation files may be mutated until the guard allows Implement."),
|
|
122
|
+
FRAME_BOTTOM,
|
|
123
|
+
].join("\n");
|
|
124
|
+
return wrapAriadSurface("implementation_guard", `${body}\n`);
|
|
125
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Lazy Builder boundary for the front door (CV22.DS7.US8 plateau 8).
|
|
2
|
+
//
|
|
3
|
+
// `frontDoor/cli.ts` imports this module only when a `build` command is routed.
|
|
4
|
+
// Keeping the whole Builder command tree behind one module is what keeps every
|
|
5
|
+
// other command working when this one cannot load.
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
invokeBuilderArgv,
|
|
9
|
+
invokeReadOnlyBuilderArgv,
|
|
10
|
+
READ_ONLY_BUILDER_SUBCOMMANDS,
|
|
11
|
+
} from "./argv.ts";
|