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,429 @@
|
|
|
1
|
+
// CV22.DS7.US8 plateau 1 — the typed model for a Builder method definition.
|
|
2
|
+
//
|
|
3
|
+
// Port of `src/memory/builder/method_definition.py`.
|
|
4
|
+
//
|
|
5
|
+
// `validateMethodDefinition` has NO runtime caller, in Python or here: no `build`
|
|
6
|
+
// leaf invokes it, and Python's copy is reached only from Python's tests. It is
|
|
7
|
+
// ported anyway, and the reason is dated rather than general.
|
|
8
|
+
//
|
|
9
|
+
// Today the DSL's correctness is guaranteed by something stronger: the TypeScript
|
|
10
|
+
// definition is deep-equal to a Python definition that Python's own suite
|
|
11
|
+
// validates. That proof has an expiry. When DS10 deletes Python, the dump it is
|
|
12
|
+
// compared against goes with it, and from then on new Builder work edits the
|
|
13
|
+
// TypeScript DSL by hand — an authored artifact with per-field invariants and no
|
|
14
|
+
// checker. Porting the validator now means the invariant survives the deletion
|
|
15
|
+
// instead of being noticed missing afterwards.
|
|
16
|
+
//
|
|
17
|
+
// Optional fields use `undefined`, not `null`: Python's dataclass defaults are
|
|
18
|
+
// `None` for absent scalars and `()` for absent tuples, and the golden dump omits
|
|
19
|
+
// nothing — so the TS shape keeps empty arrays as empty arrays and absent scalars
|
|
20
|
+
// as absent, which is what deep equality against the dump requires.
|
|
21
|
+
|
|
22
|
+
/** Python `MethodDefinitionError`. */
|
|
23
|
+
export class MethodDefinitionError extends Error {
|
|
24
|
+
constructor(message: string) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "MethodDefinitionError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A map whose KEYS are authored content, not field names. Rendered verbatim into
|
|
32
|
+
* the inspection surface, so they are never renamed or case-converted.
|
|
33
|
+
*/
|
|
34
|
+
export type OpaqueMap = { readonly [key: string]: unknown };
|
|
35
|
+
|
|
36
|
+
export interface DslResolution {
|
|
37
|
+
readonly layers: readonly string[];
|
|
38
|
+
readonly conflictPolicy: string;
|
|
39
|
+
readonly audit: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface TaxonomyLevel {
|
|
43
|
+
readonly id: string;
|
|
44
|
+
readonly label: string;
|
|
45
|
+
readonly contains: readonly string[];
|
|
46
|
+
readonly allowedStates: readonly string[];
|
|
47
|
+
readonly stateSemantics?: OpaqueMap;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface Taxonomy {
|
|
51
|
+
readonly stateVocabulary: readonly string[];
|
|
52
|
+
readonly levels: readonly TaxonomyLevel[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface LifecycleEvent {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly meaning: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface WorkItemLevelDefinition {
|
|
61
|
+
readonly id: string;
|
|
62
|
+
readonly label: string;
|
|
63
|
+
readonly implementableByDefault: boolean;
|
|
64
|
+
readonly expandsTo: readonly string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface CadenceProfileDefinition {
|
|
68
|
+
readonly id: string;
|
|
69
|
+
readonly label: string;
|
|
70
|
+
readonly stopPolicy: string;
|
|
71
|
+
readonly active: boolean;
|
|
72
|
+
readonly planApprovalPolicy: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface CheckpointDefinition {
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly occursAfter?: string;
|
|
78
|
+
readonly blocks: readonly string[];
|
|
79
|
+
readonly requiredArtifacts: readonly string[];
|
|
80
|
+
readonly requiredConfirmations: readonly string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface SurfaceDefinition {
|
|
84
|
+
readonly id: string;
|
|
85
|
+
readonly event?: string;
|
|
86
|
+
readonly stopsFor?: string;
|
|
87
|
+
readonly transport: string;
|
|
88
|
+
readonly markerProtocol: string;
|
|
89
|
+
readonly interpretationPolicy: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface ContractDefinition {
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly appliesAt: string;
|
|
95
|
+
readonly rules: readonly string[];
|
|
96
|
+
readonly stopConditions: readonly string[];
|
|
97
|
+
readonly requiredOutputs: readonly string[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface SurfaceRoute {
|
|
101
|
+
readonly trigger: string;
|
|
102
|
+
readonly surfaces: readonly string[];
|
|
103
|
+
readonly intents: readonly string[];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface TemplateDefinition {
|
|
107
|
+
readonly id: string;
|
|
108
|
+
readonly path: string;
|
|
109
|
+
readonly content: string;
|
|
110
|
+
readonly description?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface MethodDefinition {
|
|
114
|
+
readonly id: string;
|
|
115
|
+
readonly label: string;
|
|
116
|
+
readonly resolution: DslResolution;
|
|
117
|
+
readonly taxonomy: Taxonomy;
|
|
118
|
+
readonly lifecycle: readonly LifecycleEvent[];
|
|
119
|
+
readonly workItemLevels: readonly WorkItemLevelDefinition[];
|
|
120
|
+
readonly cadenceProfiles: readonly CadenceProfileDefinition[];
|
|
121
|
+
readonly checkpoints: readonly CheckpointDefinition[];
|
|
122
|
+
readonly contracts: readonly ContractDefinition[];
|
|
123
|
+
readonly policies?: OpaqueMap;
|
|
124
|
+
readonly surfaces: readonly SurfaceDefinition[];
|
|
125
|
+
readonly surfaceRoutes: readonly SurfaceRoute[];
|
|
126
|
+
readonly templates: readonly TemplateDefinition[];
|
|
127
|
+
readonly openQuestions?: OpaqueMap;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Python's dataclass defaults, for a definition that declares only id/label. */
|
|
131
|
+
export function emptyMethodDefinition(id: string, label: string): MethodDefinition {
|
|
132
|
+
return {
|
|
133
|
+
id,
|
|
134
|
+
label,
|
|
135
|
+
resolution: { layers: ["method_default"], conflictPolicy: "explicit_override", audit: true },
|
|
136
|
+
taxonomy: { stateVocabulary: [], levels: [] },
|
|
137
|
+
lifecycle: [],
|
|
138
|
+
workItemLevels: [],
|
|
139
|
+
cadenceProfiles: [],
|
|
140
|
+
checkpoints: [],
|
|
141
|
+
contracts: [],
|
|
142
|
+
surfaces: [],
|
|
143
|
+
surfaceRoutes: [],
|
|
144
|
+
templates: [],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Python `_require_non_empty`. Note the check is `value.strip()`, so a field of
|
|
150
|
+
* only whitespace is empty — and Python additionally rejects a non-`str`, which
|
|
151
|
+
* TypeScript's types already prevent.
|
|
152
|
+
*/
|
|
153
|
+
function requireNonEmpty(value: string, fieldName: string): void {
|
|
154
|
+
if (value.trim() === "") {
|
|
155
|
+
throw new MethodDefinitionError(`${fieldName} must not be empty`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Python `_require_unique`: also non-empty per value, and it reports the FIRST repeat. */
|
|
160
|
+
function requireUnique(values: readonly string[], label: string): void {
|
|
161
|
+
const seen = new Set<string>();
|
|
162
|
+
for (const value of values) {
|
|
163
|
+
requireNonEmpty(value, label);
|
|
164
|
+
if (seen.has(value)) {
|
|
165
|
+
throw new MethodDefinitionError(`duplicate ${label}: ${value}`);
|
|
166
|
+
}
|
|
167
|
+
seen.add(value);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Python `_require_known_choice`: the allowed values are sorted in the message. */
|
|
172
|
+
function requireKnownChoice(value: string, allowed: readonly string[], fieldName: string): void {
|
|
173
|
+
requireNonEmpty(value, fieldName);
|
|
174
|
+
if (!allowed.includes(value)) {
|
|
175
|
+
throw new MethodDefinitionError(
|
|
176
|
+
`${fieldName} must be one of ${[...allowed].sort().join(", ")}`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function requireKnownEvent(
|
|
182
|
+
eventId: string,
|
|
183
|
+
lifecycleIds: ReadonlySet<string>,
|
|
184
|
+
owner: string,
|
|
185
|
+
): void {
|
|
186
|
+
if (!lifecycleIds.has(eventId)) {
|
|
187
|
+
throw new MethodDefinitionError(`${owner} references unknown lifecycle event ${eventId}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Python `MethodDefinition.lifecycle_ids`. */
|
|
192
|
+
export function lifecycleIds(definition: MethodDefinition): Set<string> {
|
|
193
|
+
return new Set(definition.lifecycle.map((event) => event.id));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Python `validate_method_definition`, in its exact check order. */
|
|
197
|
+
export function validateMethodDefinition(definition: MethodDefinition): void {
|
|
198
|
+
requireNonEmpty(definition.id, "method id");
|
|
199
|
+
requireNonEmpty(definition.label, "method label");
|
|
200
|
+
validateResolution(definition.resolution);
|
|
201
|
+
validateTaxonomy(definition.taxonomy);
|
|
202
|
+
validateLifecycle(definition.lifecycle);
|
|
203
|
+
validateWorkItemLevels(definition.workItemLevels);
|
|
204
|
+
validateCadenceProfiles(definition.cadenceProfiles);
|
|
205
|
+
const events = lifecycleIds(definition);
|
|
206
|
+
validateCheckpoints(definition.checkpoints, events);
|
|
207
|
+
validateContracts(definition.contracts, events);
|
|
208
|
+
validateSurfaces(definition.surfaces, events);
|
|
209
|
+
validateSurfaceRoutes(definition.surfaceRoutes, definition.surfaces);
|
|
210
|
+
validateTemplates(definition.templates);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function validateResolution(resolution: DslResolution): void {
|
|
214
|
+
if (resolution.layers.length === 0) {
|
|
215
|
+
throw new MethodDefinitionError("dsl resolution must declare at least one layer");
|
|
216
|
+
}
|
|
217
|
+
requireUnique(resolution.layers, "dsl resolution layer");
|
|
218
|
+
for (const layer of resolution.layers) requireNonEmpty(layer, "dsl resolution layer");
|
|
219
|
+
requireNonEmpty(resolution.conflictPolicy, "dsl conflict policy");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function validateTaxonomy(taxonomy: Taxonomy): void {
|
|
223
|
+
requireUnique(taxonomy.stateVocabulary, "taxonomy state");
|
|
224
|
+
const levelIds = taxonomy.levels.map((level) => level.id);
|
|
225
|
+
requireUnique(levelIds, "taxonomy level");
|
|
226
|
+
|
|
227
|
+
const knownLevels = new Set(levelIds);
|
|
228
|
+
const knownStates = new Set(taxonomy.stateVocabulary);
|
|
229
|
+
for (const level of taxonomy.levels) {
|
|
230
|
+
requireNonEmpty(level.id, "taxonomy level id");
|
|
231
|
+
requireNonEmpty(level.label, `taxonomy level ${level.id} label`);
|
|
232
|
+
requireUnique(level.contains, `taxonomy level ${level.id} child`);
|
|
233
|
+
requireUnique(level.allowedStates, `taxonomy level ${level.id} state`);
|
|
234
|
+
for (const childId of level.contains) {
|
|
235
|
+
if (!knownLevels.has(childId)) {
|
|
236
|
+
throw new MethodDefinitionError(
|
|
237
|
+
`taxonomy level ${level.id} references unknown taxonomy level ${childId}`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
for (const state of level.allowedStates) {
|
|
242
|
+
// Python guards with `if known_states and ...`, so a definition with an
|
|
243
|
+
// EMPTY state vocabulary allows any state. Reproduced deliberately.
|
|
244
|
+
if (knownStates.size > 0 && !knownStates.has(state)) {
|
|
245
|
+
throw new MethodDefinitionError(
|
|
246
|
+
`taxonomy level ${level.id} allows unknown taxonomy state ${state}`,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
for (const state of Object.keys(level.stateSemantics ?? {})) {
|
|
251
|
+
if (!level.allowedStates.includes(state)) {
|
|
252
|
+
throw new MethodDefinitionError(
|
|
253
|
+
`taxonomy level ${level.id} declares state semantics for disallowed state ${state}`,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function validateLifecycle(events: readonly LifecycleEvent[]): void {
|
|
261
|
+
requireUnique(
|
|
262
|
+
events.map((event) => event.id),
|
|
263
|
+
"lifecycle event",
|
|
264
|
+
);
|
|
265
|
+
for (const event of events) {
|
|
266
|
+
requireNonEmpty(event.id, "lifecycle event id");
|
|
267
|
+
requireNonEmpty(event.meaning, `lifecycle event ${event.id} meaning`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function validateWorkItemLevels(levels: readonly WorkItemLevelDefinition[]): void {
|
|
272
|
+
const levelIds = levels.map((level) => level.id);
|
|
273
|
+
requireUnique(levelIds, "work item level");
|
|
274
|
+
const known = new Set(levelIds);
|
|
275
|
+
for (const level of levels) {
|
|
276
|
+
requireNonEmpty(level.id, "work item level id");
|
|
277
|
+
requireNonEmpty(level.label, `work item level ${level.id} label`);
|
|
278
|
+
requireUnique(level.expandsTo, `work item level ${level.id} expansion target`);
|
|
279
|
+
for (const target of level.expandsTo) {
|
|
280
|
+
if (!known.has(target)) {
|
|
281
|
+
throw new MethodDefinitionError(
|
|
282
|
+
`work item level ${level.id} expands to unknown level ${target}`,
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const PLAN_APPROVAL_POLICIES = ["navigator_approval", "bounded_story_authority"];
|
|
290
|
+
|
|
291
|
+
function validateCadenceProfiles(profiles: readonly CadenceProfileDefinition[]): void {
|
|
292
|
+
requireUnique(
|
|
293
|
+
profiles.map((profile) => profile.id),
|
|
294
|
+
"cadence profile",
|
|
295
|
+
);
|
|
296
|
+
for (const profile of profiles) {
|
|
297
|
+
requireNonEmpty(profile.id, "cadence profile id");
|
|
298
|
+
requireNonEmpty(profile.label, `cadence profile ${profile.id} label`);
|
|
299
|
+
requireNonEmpty(profile.stopPolicy, `cadence profile ${profile.id} stop policy`);
|
|
300
|
+
if (!PLAN_APPROVAL_POLICIES.includes(profile.planApprovalPolicy)) {
|
|
301
|
+
// Not `requireKnownChoice`: Python writes this message by hand, with no
|
|
302
|
+
// sorted allowed-values list.
|
|
303
|
+
throw new MethodDefinitionError(
|
|
304
|
+
`cadence profile ${profile.id} has unknown plan approval policy ${profile.planApprovalPolicy}`,
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function validateCheckpoints(
|
|
311
|
+
checkpoints: readonly CheckpointDefinition[],
|
|
312
|
+
events: ReadonlySet<string>,
|
|
313
|
+
): void {
|
|
314
|
+
requireUnique(
|
|
315
|
+
checkpoints.map((checkpoint) => checkpoint.id),
|
|
316
|
+
"checkpoint",
|
|
317
|
+
);
|
|
318
|
+
for (const checkpoint of checkpoints) {
|
|
319
|
+
requireNonEmpty(checkpoint.id, "checkpoint id");
|
|
320
|
+
if (checkpoint.occursAfter !== undefined) {
|
|
321
|
+
requireKnownEvent(checkpoint.occursAfter, events, `checkpoint ${checkpoint.id}`);
|
|
322
|
+
}
|
|
323
|
+
for (const eventId of checkpoint.blocks) {
|
|
324
|
+
requireKnownEvent(eventId, events, `checkpoint ${checkpoint.id}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function validateContracts(
|
|
330
|
+
contracts: readonly ContractDefinition[],
|
|
331
|
+
events: ReadonlySet<string>,
|
|
332
|
+
): void {
|
|
333
|
+
requireUnique(
|
|
334
|
+
contracts.map((contract) => contract.id),
|
|
335
|
+
"contract",
|
|
336
|
+
);
|
|
337
|
+
for (const contract of contracts) {
|
|
338
|
+
requireNonEmpty(contract.id, "contract id");
|
|
339
|
+
requireKnownEvent(contract.appliesAt, events, `contract ${contract.id}`);
|
|
340
|
+
requireUnique(contract.rules, `contract ${contract.id} rule`);
|
|
341
|
+
requireUnique(contract.stopConditions, `contract ${contract.id} stop condition`);
|
|
342
|
+
requireUnique(contract.requiredOutputs, `contract ${contract.id} required output`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** The three pseudo-events a surface may name that are not lifecycle events. */
|
|
347
|
+
const SURFACE_PSEUDO_EVENTS = new Set(["adoption", "on_builder_load", "roadmap_inspection"]);
|
|
348
|
+
|
|
349
|
+
function validateSurfaces(
|
|
350
|
+
surfaces: readonly SurfaceDefinition[],
|
|
351
|
+
events: ReadonlySet<string>,
|
|
352
|
+
): void {
|
|
353
|
+
requireUnique(
|
|
354
|
+
surfaces.map((surface) => surface.id),
|
|
355
|
+
"surface",
|
|
356
|
+
);
|
|
357
|
+
for (const surface of surfaces) {
|
|
358
|
+
requireNonEmpty(surface.id, "surface id");
|
|
359
|
+
requireKnownChoice(surface.transport, ["verbatim"], `surface ${surface.id} transport`);
|
|
360
|
+
requireKnownChoice(
|
|
361
|
+
surface.markerProtocol,
|
|
362
|
+
["ariad_compact"],
|
|
363
|
+
`surface ${surface.id} marker_protocol`,
|
|
364
|
+
);
|
|
365
|
+
requireKnownChoice(
|
|
366
|
+
surface.interpretationPolicy,
|
|
367
|
+
["after_block_only"],
|
|
368
|
+
`surface ${surface.id} interpretation_policy`,
|
|
369
|
+
);
|
|
370
|
+
if (surface.event !== undefined && SURFACE_PSEUDO_EVENTS.has(surface.event)) continue;
|
|
371
|
+
if (surface.event !== undefined) {
|
|
372
|
+
requireKnownEvent(surface.event, events, `surface ${surface.id}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function validateSurfaceRoutes(
|
|
378
|
+
routes: readonly SurfaceRoute[],
|
|
379
|
+
surfaces: readonly SurfaceDefinition[],
|
|
380
|
+
): void {
|
|
381
|
+
requireUnique(
|
|
382
|
+
routes.map((route) => route.trigger),
|
|
383
|
+
"surface route",
|
|
384
|
+
);
|
|
385
|
+
const surfaceIds = new Set(surfaces.map((surface) => surface.id));
|
|
386
|
+
for (const route of routes) {
|
|
387
|
+
requireNonEmpty(route.trigger, "surface route trigger");
|
|
388
|
+
if (route.surfaces.length === 0) {
|
|
389
|
+
throw new MethodDefinitionError(
|
|
390
|
+
`surface route ${route.trigger} must declare at least one surface`,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
requireUnique(route.surfaces, `surface route ${route.trigger} surface`);
|
|
394
|
+
requireUnique(route.intents, `surface route ${route.trigger} intent`);
|
|
395
|
+
for (const surfaceId of route.surfaces) {
|
|
396
|
+
if (!surfaceIds.has(surfaceId)) {
|
|
397
|
+
throw new MethodDefinitionError(
|
|
398
|
+
`surface route ${route.trigger} references unknown surface ${surfaceId}`,
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function validateTemplates(templates: readonly TemplateDefinition[]): void {
|
|
406
|
+
requireUnique(
|
|
407
|
+
templates.map((template) => template.id),
|
|
408
|
+
"template",
|
|
409
|
+
);
|
|
410
|
+
requireUnique(
|
|
411
|
+
templates.map((template) => template.path),
|
|
412
|
+
"template path",
|
|
413
|
+
);
|
|
414
|
+
for (const template of templates) {
|
|
415
|
+
requireNonEmpty(template.id, "template id");
|
|
416
|
+
requireNonEmpty(template.path, `template ${template.id} path`);
|
|
417
|
+
requireNonEmpty(template.content, `template ${template.id} content`);
|
|
418
|
+
// Python checks `".." in path.split("/")`, a WHOLE component — so `a..b.md`
|
|
419
|
+
// is legal and only a bare `..` segment is rejected.
|
|
420
|
+
if (template.path.startsWith("/") || template.path.split("/").includes("..")) {
|
|
421
|
+
throw new MethodDefinitionError(
|
|
422
|
+
`template ${template.id} path must be relative and stay inside project root`,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
if (template.description !== undefined) {
|
|
426
|
+
requireNonEmpty(template.description, `template ${template.id} description`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|