mirror-mind 0.0.1 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/log-assistant-reply.sh +85 -0
- package/.claude/hooks/log-session-end.sh +85 -0
- package/.claude/hooks/log-user-prompt.sh +85 -0
- package/.claude/hooks/mirror-inject.sh +85 -0
- package/.claude/hooks/session-start.sh +85 -0
- package/.gemini/hooks/log-assistant.sh +85 -0
- package/.gemini/hooks/log-user.sh +85 -0
- package/.gemini/hooks/session-end.sh +85 -0
- package/.gemini/hooks/session-start.sh +85 -0
- package/.pi/extensions/mirror-logger.ts +646 -0
- package/.pi/skills/mm-backup/SKILL.md +21 -0
- package/.pi/skills/mm-build/SKILL.md +1206 -0
- package/.pi/skills/mm-consolidate/SKILL.md +112 -0
- package/.pi/skills/mm-consult/SKILL.md +70 -0
- package/.pi/skills/mm-conversations/SKILL.md +16 -0
- package/.pi/skills/mm-discard/SKILL.md +39 -0
- package/.pi/skills/mm-explore/SKILL.md +255 -0
- package/.pi/skills/mm-help/SKILL.md +74 -0
- package/.pi/skills/mm-identity/SKILL.md +96 -0
- package/.pi/skills/mm-journal/SKILL.md +16 -0
- package/.pi/skills/mm-journey/SKILL.md +23 -0
- package/.pi/skills/mm-journeys/SKILL.md +15 -0
- package/.pi/skills/mm-memories/SKILL.md +17 -0
- package/.pi/skills/mm-mirror/SKILL.md +98 -0
- package/.pi/skills/mm-mute/SKILL.md +18 -0
- package/.pi/skills/mm-new/SKILL.md +18 -0
- package/.pi/skills/mm-recall/SKILL.md +17 -0
- package/.pi/skills/mm-release-notes/SKILL.md +52 -0
- package/.pi/skills/mm-seed/SKILL.md +19 -0
- package/.pi/skills/mm-shadow/SKILL.md +117 -0
- package/.pi/skills/mm-soul/SKILL.md +502 -0
- package/.pi/skills/mm-tasks/SKILL.md +24 -0
- package/.pi/skills/mm-update/SKILL.md +32 -0
- package/.pi/skills/mm-week/SKILL.md +28 -0
- package/.pi/skills/mm-welcome/SKILL.md +24 -0
- package/AGENTS.md +188 -0
- package/README.md +126 -9
- package/bin/loader.js +67 -0
- package/bin/mirror-hook.js +7 -0
- package/bin/mirror.js +7 -0
- package/docs/releases/index.md +100 -0
- package/docs/releases/pending-cutoffs.md +510 -0
- package/docs/releases/v0.10.0.md +123 -0
- package/docs/releases/v0.10.1.md +66 -0
- package/docs/releases/v0.10.10.md +51 -0
- package/docs/releases/v0.10.11.md +39 -0
- package/docs/releases/v0.10.12.md +57 -0
- package/docs/releases/v0.10.13.md +35 -0
- package/docs/releases/v0.10.14.md +42 -0
- package/docs/releases/v0.10.15.md +53 -0
- package/docs/releases/v0.10.16.md +35 -0
- package/docs/releases/v0.10.17.md +43 -0
- package/docs/releases/v0.10.2.md +64 -0
- package/docs/releases/v0.10.3.md +78 -0
- package/docs/releases/v0.10.4.md +42 -0
- package/docs/releases/v0.10.5.md +57 -0
- package/docs/releases/v0.10.6.md +47 -0
- package/docs/releases/v0.10.7.md +53 -0
- package/docs/releases/v0.10.8.md +49 -0
- package/docs/releases/v0.10.9.md +37 -0
- package/docs/releases/v0.11.0.md +86 -0
- package/docs/releases/v0.12.0.md +67 -0
- package/docs/releases/v0.13.0.md +64 -0
- package/docs/releases/v0.14.0.md +68 -0
- package/docs/releases/v0.15.0.md +48 -0
- package/docs/releases/v0.16.0.md +50 -0
- package/docs/releases/v0.16.1.md +55 -0
- package/docs/releases/v0.16.2.md +36 -0
- package/docs/releases/v0.17.0.md +50 -0
- package/docs/releases/v0.17.1.md +58 -0
- package/docs/releases/v0.17.2.md +42 -0
- package/docs/releases/v0.17.3.md +58 -0
- package/docs/releases/v0.18.0.md +84 -0
- package/docs/releases/v0.18.1.md +51 -0
- package/docs/releases/v0.18.2.md +69 -0
- package/docs/releases/v0.19.0.md +85 -0
- package/docs/releases/v0.19.1.md +46 -0
- package/docs/releases/v0.20.0.md +85 -0
- package/docs/releases/v0.21.0.md +61 -0
- package/docs/releases/v0.21.1.md +47 -0
- package/docs/releases/v0.22.0.md +77 -0
- package/docs/releases/v0.22.1.md +42 -0
- package/docs/releases/v0.23.0.md +105 -0
- package/docs/releases/v0.24.0.md +125 -0
- package/docs/releases/v0.25.0.md +107 -0
- package/docs/releases/v0.26.0.md +139 -0
- package/docs/releases/v0.26.1.md +65 -0
- package/docs/releases/v0.26.2.md +43 -0
- package/docs/releases/v0.27.0.md +63 -0
- package/docs/releases/v0.28.0.md +59 -0
- package/docs/releases/v0.29.0.md +61 -0
- package/docs/releases/v0.29.1.md +59 -0
- package/docs/releases/v0.29.2.md +59 -0
- package/docs/releases/v0.29.3.md +93 -0
- package/docs/releases/v0.30.0.md +75 -0
- package/docs/releases/v0.30.1.md +93 -0
- package/docs/releases/v0.30.2.md +66 -0
- package/docs/releases/v0.31.0.md +122 -0
- package/docs/releases/v0.31.1.md +142 -0
- package/docs/releases/v0.31.10.md +118 -0
- package/docs/releases/v0.31.11.md +88 -0
- package/docs/releases/v0.31.12.md +105 -0
- package/docs/releases/v0.31.13.md +99 -0
- package/docs/releases/v0.31.14.md +97 -0
- package/docs/releases/v0.31.2.md +115 -0
- package/docs/releases/v0.31.3.md +142 -0
- package/docs/releases/v0.31.4.md +117 -0
- package/docs/releases/v0.31.5.md +155 -0
- package/docs/releases/v0.31.6.md +132 -0
- package/docs/releases/v0.31.7.md +132 -0
- package/docs/releases/v0.31.8.md +120 -0
- package/docs/releases/v0.31.9.md +120 -0
- package/docs/releases/v0.32.0.md +261 -0
- package/docs/releases/v0.32.1.md +59 -0
- package/docs/releases/v0.33.0.md +164 -0
- package/docs/releases/v0.8.0.md +118 -0
- package/docs/releases/v0.9.0.md +98 -0
- package/docs/releases/v0.9.1.md +83 -0
- package/package.json +102 -6
- package/plugins/mirror-mind/.claude-plugin/plugin.json +17 -0
- package/plugins/mirror-mind/hooks/hooks.json +62 -0
- package/plugins/mirror-mind/hooks/log-assistant-reply.sh +98 -0
- package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
- package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
- package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
- package/plugins/mirror-mind/hooks/session-start.sh +98 -0
- package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
- package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
- package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
- package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
- package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
- package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
- package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
- package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
- package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
- package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
- package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
- package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +67 -0
- package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
- package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
- package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
- package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
- package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
- package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
- package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
- package/scripts/codex-hooks/session-end.sh +85 -0
- package/scripts/codex-hooks/session-start.sh +85 -0
- package/scripts/codex-mirror.sh +48 -0
- package/templates/identity/README.md +119 -0
- package/templates/identity/ego/behavior.yaml +52 -0
- package/templates/identity/ego/constraints.yaml +15 -0
- package/templates/identity/ego/identity.yaml +43 -0
- package/templates/identity/journeys/personal-growth.yaml +39 -0
- package/templates/identity/organization/identity.yaml +24 -0
- package/templates/identity/organization/principles.yaml +17 -0
- package/templates/identity/personas/coach.yaml +94 -0
- package/templates/identity/personas/designer.yaml +93 -0
- package/templates/identity/personas/doctor.yaml +96 -0
- package/templates/identity/personas/engineer.yaml +77 -0
- package/templates/identity/personas/financial.yaml +97 -0
- package/templates/identity/personas/prompt-engineer.yaml +122 -0
- package/templates/identity/personas/researcher.yaml +88 -0
- package/templates/identity/personas/strategist.yaml +91 -0
- package/templates/identity/personas/teacher.yaml +95 -0
- package/templates/identity/personas/therapist.yaml +91 -0
- package/templates/identity/personas/thinker.yaml +74 -0
- package/templates/identity/personas/writer.yaml +76 -0
- package/templates/identity/self/config.yaml +16 -0
- package/templates/identity/self/soul.yaml +105 -0
- package/templates/identity/user/identity.yaml +30 -0
- package/ts/src/backup/staging.ts +62 -0
- package/ts/src/backup/zipBackup.ts +267 -0
- package/ts/src/backup/zipReader.ts +109 -0
- package/ts/src/backup/zipWriter.ts +148 -0
- package/ts/src/builder/activeCheckpoint.ts +134 -0
- package/ts/src/builder/aggregateStatus.ts +34 -0
- package/ts/src/builder/approve.ts +149 -0
- package/ts/src/builder/argv.ts +292 -0
- package/ts/src/builder/ariadMethod.ts +536 -0
- package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
- package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
- package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
- package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
- package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
- package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
- package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
- package/ts/src/builder/artifacts/storyFiles.ts +61 -0
- package/ts/src/builder/artifacts/storyIndex.ts +166 -0
- package/ts/src/builder/cadence.ts +59 -0
- package/ts/src/builder/card.ts +192 -0
- package/ts/src/builder/checkpointRefused.ts +66 -0
- package/ts/src/builder/closure.ts +964 -0
- package/ts/src/builder/commands.ts +2053 -0
- package/ts/src/builder/cursorPosition.ts +176 -0
- package/ts/src/builder/cursorTransitions.ts +77 -0
- package/ts/src/builder/deliveryCursor.ts +577 -0
- package/ts/src/builder/deliveryStoryClosure.ts +521 -0
- package/ts/src/builder/deliveryStoryPlan.ts +536 -0
- package/ts/src/builder/deliveryStoryReady.ts +160 -0
- package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
- package/ts/src/builder/expand.ts +336 -0
- package/ts/src/builder/flowUnit.ts +339 -0
- package/ts/src/builder/homeSurface.ts +122 -0
- package/ts/src/builder/implementationGuard.ts +125 -0
- package/ts/src/builder/index.ts +11 -0
- package/ts/src/builder/lifecycleRefusal.ts +92 -0
- package/ts/src/builder/lifecycleRibbon.ts +159 -0
- package/ts/src/builder/load.ts +313 -0
- package/ts/src/builder/methodAdoption.ts +113 -0
- package/ts/src/builder/methodDefinition.ts +429 -0
- package/ts/src/builder/methodInspection.ts +371 -0
- package/ts/src/builder/plan.ts +408 -0
- package/ts/src/builder/planPreauthorization.ts +265 -0
- package/ts/src/builder/prepare.ts +225 -0
- package/ts/src/builder/projectPaths.ts +64 -0
- package/ts/src/builder/pull.ts +356 -0
- package/ts/src/builder/pullCandidates.ts +463 -0
- package/ts/src/builder/pullCandidatesRender.ts +238 -0
- package/ts/src/builder/refinementField.ts +93 -0
- package/ts/src/builder/releaseIntent.ts +173 -0
- package/ts/src/builder/resumeState.ts +84 -0
- package/ts/src/builder/resumeSurface.ts +149 -0
- package/ts/src/builder/roadmapGrammar.ts +300 -0
- package/ts/src/builder/roadmapScan.ts +97 -0
- package/ts/src/builder/roadmapScope.ts +210 -0
- package/ts/src/builder/scopePhrases.ts +146 -0
- package/ts/src/builder/storyPaths.ts +196 -0
- package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
- package/ts/src/builder/surfaceProtocol.ts +42 -0
- package/ts/src/builder/templateGeneration.ts +148 -0
- package/ts/src/builder/transition.ts +178 -0
- package/ts/src/consult/args.ts +99 -0
- package/ts/src/consult/core.ts +122 -0
- package/ts/src/consult/modelCatalog.ts +55 -0
- package/ts/src/consult/render.ts +47 -0
- package/ts/src/conversation/append.ts +414 -0
- package/ts/src/conversation/backfill.ts +387 -0
- package/ts/src/conversation/closeTail.ts +467 -0
- package/ts/src/conversation/extraction.ts +333 -0
- package/ts/src/conversation/extractionDriver.ts +130 -0
- package/ts/src/conversation/extractionRun.ts +70 -0
- package/ts/src/conversation/hookPayload.ts +51 -0
- package/ts/src/conversation/journeyInference.ts +165 -0
- package/ts/src/conversation/journeyRepair.ts +114 -0
- package/ts/src/conversation/lifecycleFaces.ts +197 -0
- package/ts/src/conversation/lifecycleWrites.ts +313 -0
- package/ts/src/conversation/listing.ts +77 -0
- package/ts/src/conversation/logger.ts +851 -0
- package/ts/src/conversation/loggerCli.ts +321 -0
- package/ts/src/conversation/loggerRuntime.ts +259 -0
- package/ts/src/conversation/metadataLifecycle.ts +443 -0
- package/ts/src/conversation/recall.ts +66 -0
- package/ts/src/conversation/sessionComposites.ts +258 -0
- package/ts/src/conversation/sessionImport.ts +90 -0
- package/ts/src/conversation/transcriptBackfill.ts +141 -0
- package/ts/src/cultivation/applyActions.ts +241 -0
- package/ts/src/cultivation/cluster.ts +86 -0
- package/ts/src/cultivation/consolidationStore.ts +281 -0
- package/ts/src/cultivation/promptContext.ts +62 -0
- package/ts/src/cultivation/propose.ts +305 -0
- package/ts/src/cultivation/scan.ts +155 -0
- package/ts/src/db/backupGate.ts +47 -0
- package/ts/src/db/bootstrap.ts +108 -0
- package/ts/src/db/bootstrapLock.ts +223 -0
- package/ts/src/db/copyGuard.ts +60 -0
- package/ts/src/db/database.ts +397 -0
- package/ts/src/db/decode.ts +66 -0
- package/ts/src/db/ftsIntegrity.ts +41 -0
- package/ts/src/db/migrateOnOpen.ts +214 -0
- package/ts/src/db/migrations.ts +576 -0
- package/ts/src/db/readyOnOpen.ts +35 -0
- package/ts/src/db/rowDecode.ts +42 -0
- package/ts/src/db/schema.ts +432 -0
- package/ts/src/db/schemaInventory.ts +225 -0
- package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
- package/ts/src/db/schemaState.ts +91 -0
- package/ts/src/db/schemaTsDivergence.ts +114 -0
- package/ts/src/descriptor/descriptorRead.ts +49 -0
- package/ts/src/docs/docsLint.ts +265 -0
- package/ts/src/explorer/handoff.ts +522 -0
- package/ts/src/explorer/render.ts +335 -0
- package/ts/src/explorer/story.ts +769 -0
- package/ts/src/explorer/transition.ts +72 -0
- package/ts/src/extensions/bindings.ts +170 -0
- package/ts/src/extensions/catalog.ts +249 -0
- package/ts/src/extensions/catalogCommands.ts +513 -0
- package/ts/src/extensions/catalogWrites.ts +652 -0
- package/ts/src/extensions/contextRuntime.ts +325 -0
- package/ts/src/extensions/dispatch.ts +374 -0
- package/ts/src/extensions/errors.ts +24 -0
- package/ts/src/extensions/manifest.ts +356 -0
- package/ts/src/extensions/migrations.ts +350 -0
- package/ts/src/extraction/conversation.ts +304 -0
- package/ts/src/extraction/conversationMetadata.ts +206 -0
- package/ts/src/extraction/fencing.ts +106 -0
- package/ts/src/extraction/json.ts +17 -0
- package/ts/src/extraction/prompts.ts +470 -0
- package/ts/src/frontDoor/args.ts +30 -0
- package/ts/src/frontDoor/argvShape.ts +106 -0
- package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
- package/ts/src/frontDoor/buildRoute.ts +398 -0
- package/ts/src/frontDoor/cli.ts +1872 -0
- package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
- package/ts/src/frontDoor/consultRoute.ts +50 -0
- package/ts/src/frontDoor/contentTailRoute.ts +239 -0
- package/ts/src/frontDoor/conversationLoggerRoute.ts +83 -0
- package/ts/src/frontDoor/cultivationRoute.ts +210 -0
- package/ts/src/frontDoor/dbPath.ts +131 -0
- package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
- package/ts/src/frontDoor/exploreRoute.ts +572 -0
- package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
- package/ts/src/frontDoor/frontDoorLog.ts +57 -0
- package/ts/src/frontDoor/identityWrite.ts +36 -0
- package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
- package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
- package/ts/src/frontDoor/liveBackup.ts +100 -0
- package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
- package/ts/src/frontDoor/namedRefusal.ts +35 -0
- package/ts/src/frontDoor/nodeSupport.ts +24 -0
- package/ts/src/frontDoor/render/consolidate.ts +199 -0
- package/ts/src/frontDoor/render/conversations.ts +33 -0
- package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
- package/ts/src/frontDoor/render/descriptor.ts +20 -0
- package/ts/src/frontDoor/render/detectPersona.ts +50 -0
- package/ts/src/frontDoor/render/icons.ts +13 -0
- package/ts/src/frontDoor/render/identity.ts +59 -0
- package/ts/src/frontDoor/render/identityRows.ts +17 -0
- package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
- package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
- package/ts/src/frontDoor/render/journeys.ts +79 -0
- package/ts/src/frontDoor/render/list.ts +41 -0
- package/ts/src/frontDoor/render/memories.ts +67 -0
- package/ts/src/frontDoor/render/recall.ts +49 -0
- package/ts/src/frontDoor/render/shadow.ts +155 -0
- package/ts/src/frontDoor/render/tasks.ts +99 -0
- package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
- package/ts/src/frontDoor/render/week.ts +113 -0
- package/ts/src/frontDoor/routing.ts +1001 -0
- package/ts/src/frontDoor/runtimeRoute.ts +623 -0
- package/ts/src/frontDoor/searchRoute.ts +166 -0
- package/ts/src/frontDoor/seedPaths.ts +98 -0
- package/ts/src/frontDoor/sessionStartWelcomeRoute.ts +166 -0
- package/ts/src/frontDoor/soulRoute.ts +433 -0
- package/ts/src/frontDoor/stdinSource.ts +37 -0
- package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
- package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
- package/ts/src/frontDoor/usage.ts +176 -0
- package/ts/src/guards/claudePlugin.ts +298 -0
- package/ts/src/guards/packContents.ts +306 -0
- package/ts/src/guards/piSourcedSkills.ts +70 -0
- package/ts/src/guards/retiredRouteShadows.ts +57 -0
- package/ts/src/guards/retiredSurfaces.ts +564 -0
- package/ts/src/hooks/claude.ts +214 -0
- package/ts/src/hooks/codex.ts +45 -0
- package/ts/src/hooks/gemini.ts +126 -0
- package/ts/src/hooks/main.ts +109 -0
- package/ts/src/hooks/mirrorState.ts +71 -0
- package/ts/src/hooks/payload.ts +73 -0
- package/ts/src/hooks/runtime.ts +179 -0
- package/ts/src/hooks/runtimeDetection.ts +34 -0
- package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
- package/ts/src/identity/descriptorGenerate.ts +162 -0
- package/ts/src/identity/identityEdit.ts +143 -0
- package/ts/src/identity/identityKey.ts +77 -0
- package/ts/src/identity/identityRead.ts +69 -0
- package/ts/src/identity/identityStore.ts +80 -0
- package/ts/src/identity/journeyListing.ts +53 -0
- package/ts/src/identity/personaInspect.ts +44 -0
- package/ts/src/identity/personaListing.ts +37 -0
- package/ts/src/identity/setIdentity.ts +64 -0
- package/ts/src/index.ts +231 -0
- package/ts/src/init/init.ts +111 -0
- package/ts/src/journey/journeyOptions.ts +131 -0
- package/ts/src/journey/journeyRemoval.ts +158 -0
- package/ts/src/journey/journeyStatus.ts +149 -0
- package/ts/src/journey/journeySyncFile.ts +87 -0
- package/ts/src/journey/journeyWrite.ts +203 -0
- package/ts/src/journey/parentJourney.ts +41 -0
- package/ts/src/journey/validateParentJourney.ts +55 -0
- package/ts/src/mcp/boundary.ts +151 -0
- package/ts/src/mcp/guards.ts +244 -0
- package/ts/src/mcp/main.ts +121 -0
- package/ts/src/mcp/payload.ts +141 -0
- package/ts/src/mcp/protocol.ts +141 -0
- package/ts/src/mcp/readModels.ts +241 -0
- package/ts/src/mcp/registry.ts +201 -0
- package/ts/src/mcp/serve.ts +120 -0
- package/ts/src/mcp/tools/deterministic.ts +137 -0
- package/ts/src/mcp/tools/providerCrossing.ts +187 -0
- package/ts/src/mcp/wire.ts +8 -0
- package/ts/src/memory/journal.ts +180 -0
- package/ts/src/memory/listing.ts +107 -0
- package/ts/src/memory/memoryWrite.ts +88 -0
- package/ts/src/memory/reinforcement.ts +35 -0
- package/ts/src/mirror/context.ts +161 -0
- package/ts/src/mirror/defaultResolution.ts +199 -0
- package/ts/src/mirror/mirrorForm.ts +43 -0
- package/ts/src/mirror/orchestration.ts +364 -0
- package/ts/src/mirror/reception.ts +194 -0
- package/ts/src/mirror/render.ts +75 -0
- package/ts/src/mirror/runtimeSession.ts +205 -0
- package/ts/src/mode/operatingMode.ts +148 -0
- package/ts/src/observability/callOutcome.ts +115 -0
- package/ts/src/observability/inspectLedger.ts +329 -0
- package/ts/src/observability/ledgerHooks.ts +126 -0
- package/ts/src/observability/llmCalls.ts +154 -0
- package/ts/src/persona/detectPersona.ts +81 -0
- package/ts/src/planning/promptAssembly.ts +111 -0
- package/ts/src/planning/weekPending.ts +81 -0
- package/ts/src/planning/weekPlan.ts +183 -0
- package/ts/src/planning/weekSave.ts +117 -0
- package/ts/src/providers/config.ts +189 -0
- package/ts/src/providers/cost.ts +64 -0
- package/ts/src/providers/credits.ts +204 -0
- package/ts/src/providers/embedding.ts +321 -0
- package/ts/src/providers/familyProviders.ts +147 -0
- package/ts/src/providers/llm.ts +334 -0
- package/ts/src/providers/openrouter.ts +244 -0
- package/ts/src/providers/redaction.ts +110 -0
- package/ts/src/providers/replay.ts +15 -0
- package/ts/src/providers/transport.ts +410 -0
- package/ts/src/repair/encodingRepair.ts +253 -0
- package/ts/src/runtime/backup.ts +151 -0
- package/ts/src/runtime/channel.ts +146 -0
- package/ts/src/runtime/config.ts +168 -0
- package/ts/src/runtime/diagnose.ts +686 -0
- package/ts/src/runtime/git.ts +510 -0
- package/ts/src/runtime/installKind.ts +220 -0
- package/ts/src/runtime/migrate.ts +154 -0
- package/ts/src/runtime/packageIdentity.ts +102 -0
- package/ts/src/runtime/releaseNotes.ts +244 -0
- package/ts/src/runtime/status.ts +557 -0
- package/ts/src/runtime/strategies/clone.ts +200 -0
- package/ts/src/runtime/strategies/package.ts +328 -0
- package/ts/src/runtime/treeRoot.ts +30 -0
- package/ts/src/runtime/update.ts +445 -0
- package/ts/src/runtime/updateGate.ts +40 -0
- package/ts/src/runtime/updatePipeline.ts +159 -0
- package/ts/src/runtime/version.ts +36 -0
- package/ts/src/runtime/wiring.ts +130 -0
- package/ts/src/search/memorySearch.ts +338 -0
- package/ts/src/search/ranker.ts +154 -0
- package/ts/src/seed/seed.ts +256 -0
- package/ts/src/seed/seedYaml.ts +133 -0
- package/ts/src/soul/apply.ts +218 -0
- package/ts/src/soul/harvest.ts +267 -0
- package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
- package/ts/src/soul/prompts/soul_self_voice.md +219 -0
- package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
- package/ts/src/soul/prompts.ts +85 -0
- package/ts/src/soul/render.ts +358 -0
- package/ts/src/soul/state.ts +212 -0
- package/ts/src/soul/transition.ts +37 -0
- package/ts/src/tasks/journeyPathParse.ts +113 -0
- package/ts/src/tasks/taskImportSync.ts +142 -0
- package/ts/src/tasks/taskStore.ts +312 -0
- package/ts/src/tasks/weekView.ts +120 -0
- package/ts/src/util/clipCodePoints.ts +26 -0
- package/ts/src/util/paths.ts +63 -0
- package/ts/src/util/program.ts +9 -0
- package/ts/src/util/pyGenerators.ts +144 -0
- package/ts/src/util/pythonText.ts +317 -0
- package/ts/src/util/semver.ts +45 -0
- package/ts/src/util/shellWord.ts +25 -0
- package/ts/src/util/slug.ts +64 -0
- package/ts/src/welcome/card.ts +339 -0
- package/ts/src/welcome/statusLine.ts +101 -0
- package/ts/src/welcome/updateCache.ts +129 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh\"",
|
|
10
|
+
"timeout": 300
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"UserPromptSubmit": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/mirror-inject.sh\"",
|
|
22
|
+
"timeout": 30
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"matcher": "",
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "command",
|
|
31
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/log-user-prompt.sh\"",
|
|
32
|
+
"async": true
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"Stop": [
|
|
38
|
+
{
|
|
39
|
+
"matcher": "",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/log-assistant-reply.sh\"",
|
|
44
|
+
"async": true
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"SessionEnd": [
|
|
50
|
+
{
|
|
51
|
+
"matcher": "",
|
|
52
|
+
"hooks": [
|
|
53
|
+
{
|
|
54
|
+
"type": "command",
|
|
55
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/log-session-end.sh\"",
|
|
56
|
+
"async": true
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Mirror Mind hook wrapper — GENERATED by scripts/generate_hook_wrappers.sh.
|
|
3
|
+
# Edit the generator, never this file: every wrapper shares these bytes and
|
|
4
|
+
# differs only in the hook name and in how it finds the Mirror entry
|
|
5
|
+
# (CV22.DS10.TS5 decision D4; CV22.DS10.US3 decision D5).
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
HOOK="claude:stop"
|
|
8
|
+
|
|
9
|
+
# This wrapper is the Claude plugin's, and a plugin is copied into Claude
|
|
10
|
+
# Code's own cache: no relative path from here reaches the Mirror tree. It
|
|
11
|
+
# runs the installed `mirror-hook` bin instead, and reads no tree .env.
|
|
12
|
+
REPO_ROOT=""
|
|
13
|
+
|
|
14
|
+
# A hook never fails the user's turn, and never fails in silence: when it
|
|
15
|
+
# cannot do its job it appends ONE line to <mirror home>/hooks.log and exits 0.
|
|
16
|
+
# The home is found the way the core finds it -- MIRROR_HOME, else
|
|
17
|
+
# MIRROR_USER -- from the environment when set there, else from the tree's
|
|
18
|
+
# .env when the wrapper is in a tree, else from the user's config file
|
|
19
|
+
# (~/.config/mirror/env), in the core's order (US3, D3). A GUI launch carries
|
|
20
|
+
# neither variable, and the first wrappers then wrote to a home nobody reads.
|
|
21
|
+
env_file_value() {
|
|
22
|
+
[ -f "$2" ] || return 0
|
|
23
|
+
sed -n -E "s/^[[:space:]]*(export[[:space:]]+)?$1[[:space:]]*=[[:space:]]*//p" "$2" \
|
|
24
|
+
| tail -n 1 | tr -d "\"'\r"
|
|
25
|
+
}
|
|
26
|
+
env_value() {
|
|
27
|
+
local value=""
|
|
28
|
+
if [ -n "${!1+set}" ]; then printf '%s' "${!1}"; return; fi
|
|
29
|
+
[ -z "$REPO_ROOT" ] || value="$(env_file_value "$1" "$REPO_ROOT/.env")"
|
|
30
|
+
[ -n "$value" ] || value="$(env_file_value "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/mirror/env")"
|
|
31
|
+
printf '%s' "$value"
|
|
32
|
+
}
|
|
33
|
+
note() {
|
|
34
|
+
local home user
|
|
35
|
+
home="$(env_value MIRROR_HOME)"
|
|
36
|
+
user="$(env_value MIRROR_USER)"
|
|
37
|
+
if [ -n "$home" ]; then
|
|
38
|
+
home="${home/#\~/$HOME}"
|
|
39
|
+
elif [ -n "$user" ]; then
|
|
40
|
+
home="$HOME/.mirror-minds/$user"
|
|
41
|
+
[ -d "$home" ] || [ ! -d "$HOME/.mirror/$user" ] || home="$HOME/.mirror/$user"
|
|
42
|
+
else
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
mkdir -p "$home" 2>/dev/null \
|
|
46
|
+
&& printf '%s %s: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$HOOK" "$1" >> "$home/hooks.log" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Find the bin. MIRROR_BIN names the directory holding `mirror` and
|
|
50
|
+
# `mirror-hook` (`$(npm prefix -g)/bin`), the same trust class as MIRROR_NODE;
|
|
51
|
+
# then the PATH; then the global bin directories a GUI launch leaves off it.
|
|
52
|
+
ENTRY=""
|
|
53
|
+
[ -n "${MIRROR_BIN:-}" ] && [ -x "$MIRROR_BIN/mirror-hook" ] && ENTRY="$MIRROR_BIN/mirror-hook"
|
|
54
|
+
[ -n "$ENTRY" ] || ENTRY="$(command -v mirror-hook 2>/dev/null || true)"
|
|
55
|
+
for candidate in "$HOME/.nvm/current/bin" /opt/homebrew/bin /usr/local/bin; do
|
|
56
|
+
[ -n "$ENTRY" ] && break
|
|
57
|
+
[ -x "$candidate/mirror-hook" ] && ENTRY="$candidate/mirror-hook"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -z "$ENTRY" ]; then
|
|
61
|
+
note "mirror-hook not found on PATH; hook skipped. Install mirror-mind (npm install -g mirror-mind) or set MIRROR_BIN to its bin directory."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Find Node. /usr/bin/python3 exists on every macOS; node usually lives under
|
|
66
|
+
# nvm or Homebrew and is NOT on the PATH of a GUI-launched runtime. The Python
|
|
67
|
+
# hooks could end in `|| true` because they always found their interpreter;
|
|
68
|
+
# the same silence here would hide a new failure — no logging, no inject, no
|
|
69
|
+
# close tail — that a user would meet weeks later as "Mirror stopped
|
|
70
|
+
# remembering". So an unresolvable Node is RECORDED, never swallowed. The
|
|
71
|
+
# directory the entry was found in is searched first: an npm global bin holds
|
|
72
|
+
# the `node` that installed the package beside `mirror-hook`, while a system
|
|
73
|
+
# `/usr/local/bin/node` can be years older (CI's Ubuntu runner has one).
|
|
74
|
+
NODE="${MIRROR_NODE:-}"
|
|
75
|
+
if [ -z "$NODE" ] || [ ! -x "$NODE" ]; then
|
|
76
|
+
NODE="$(command -v node 2>/dev/null || true)"
|
|
77
|
+
fi
|
|
78
|
+
for candidate in "$(dirname "$ENTRY")/node" "$HOME/.nvm/current/bin/node" /opt/homebrew/bin/node /usr/local/bin/node; do
|
|
79
|
+
[ -n "$NODE" ] && break
|
|
80
|
+
[ -x "$candidate" ] && NODE="$candidate"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$NODE" ]; then
|
|
84
|
+
note "node not found on PATH; hook skipped. Set MIRROR_NODE."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Not `exec`: the entry exits 0 whatever happens inside it, so a non-zero exit
|
|
89
|
+
# means Node itself could not run the hook -- too old for the loader shim, or
|
|
90
|
+
# it crashed. That used to vanish into a stderr no runtime shows (TS5 handoff
|
|
91
|
+
# review, finding N1). No flags: the entry reads configuration and silences
|
|
92
|
+
# its own warnings (US3, D3).
|
|
93
|
+
"$NODE" "$ENTRY" "$HOOK" "$@"
|
|
94
|
+
status=$?
|
|
95
|
+
if [ "$status" -ne 0 ]; then
|
|
96
|
+
note "node exited $status before the hook finished ($NODE, $("$NODE" --version 2>/dev/null || echo 'version unknown')); Mirror needs Node 24 or later. Set MIRROR_NODE."
|
|
97
|
+
fi
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Mirror Mind hook wrapper — GENERATED by scripts/generate_hook_wrappers.sh.
|
|
3
|
+
# Edit the generator, never this file: every wrapper shares these bytes and
|
|
4
|
+
# differs only in the hook name and in how it finds the Mirror entry
|
|
5
|
+
# (CV22.DS10.TS5 decision D4; CV22.DS10.US3 decision D5).
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
HOOK="claude:session-end"
|
|
8
|
+
|
|
9
|
+
# This wrapper is the Claude plugin's, and a plugin is copied into Claude
|
|
10
|
+
# Code's own cache: no relative path from here reaches the Mirror tree. It
|
|
11
|
+
# runs the installed `mirror-hook` bin instead, and reads no tree .env.
|
|
12
|
+
REPO_ROOT=""
|
|
13
|
+
|
|
14
|
+
# A hook never fails the user's turn, and never fails in silence: when it
|
|
15
|
+
# cannot do its job it appends ONE line to <mirror home>/hooks.log and exits 0.
|
|
16
|
+
# The home is found the way the core finds it -- MIRROR_HOME, else
|
|
17
|
+
# MIRROR_USER -- from the environment when set there, else from the tree's
|
|
18
|
+
# .env when the wrapper is in a tree, else from the user's config file
|
|
19
|
+
# (~/.config/mirror/env), in the core's order (US3, D3). A GUI launch carries
|
|
20
|
+
# neither variable, and the first wrappers then wrote to a home nobody reads.
|
|
21
|
+
env_file_value() {
|
|
22
|
+
[ -f "$2" ] || return 0
|
|
23
|
+
sed -n -E "s/^[[:space:]]*(export[[:space:]]+)?$1[[:space:]]*=[[:space:]]*//p" "$2" \
|
|
24
|
+
| tail -n 1 | tr -d "\"'\r"
|
|
25
|
+
}
|
|
26
|
+
env_value() {
|
|
27
|
+
local value=""
|
|
28
|
+
if [ -n "${!1+set}" ]; then printf '%s' "${!1}"; return; fi
|
|
29
|
+
[ -z "$REPO_ROOT" ] || value="$(env_file_value "$1" "$REPO_ROOT/.env")"
|
|
30
|
+
[ -n "$value" ] || value="$(env_file_value "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/mirror/env")"
|
|
31
|
+
printf '%s' "$value"
|
|
32
|
+
}
|
|
33
|
+
note() {
|
|
34
|
+
local home user
|
|
35
|
+
home="$(env_value MIRROR_HOME)"
|
|
36
|
+
user="$(env_value MIRROR_USER)"
|
|
37
|
+
if [ -n "$home" ]; then
|
|
38
|
+
home="${home/#\~/$HOME}"
|
|
39
|
+
elif [ -n "$user" ]; then
|
|
40
|
+
home="$HOME/.mirror-minds/$user"
|
|
41
|
+
[ -d "$home" ] || [ ! -d "$HOME/.mirror/$user" ] || home="$HOME/.mirror/$user"
|
|
42
|
+
else
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
mkdir -p "$home" 2>/dev/null \
|
|
46
|
+
&& printf '%s %s: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$HOOK" "$1" >> "$home/hooks.log" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Find the bin. MIRROR_BIN names the directory holding `mirror` and
|
|
50
|
+
# `mirror-hook` (`$(npm prefix -g)/bin`), the same trust class as MIRROR_NODE;
|
|
51
|
+
# then the PATH; then the global bin directories a GUI launch leaves off it.
|
|
52
|
+
ENTRY=""
|
|
53
|
+
[ -n "${MIRROR_BIN:-}" ] && [ -x "$MIRROR_BIN/mirror-hook" ] && ENTRY="$MIRROR_BIN/mirror-hook"
|
|
54
|
+
[ -n "$ENTRY" ] || ENTRY="$(command -v mirror-hook 2>/dev/null || true)"
|
|
55
|
+
for candidate in "$HOME/.nvm/current/bin" /opt/homebrew/bin /usr/local/bin; do
|
|
56
|
+
[ -n "$ENTRY" ] && break
|
|
57
|
+
[ -x "$candidate/mirror-hook" ] && ENTRY="$candidate/mirror-hook"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -z "$ENTRY" ]; then
|
|
61
|
+
note "mirror-hook not found on PATH; hook skipped. Install mirror-mind (npm install -g mirror-mind) or set MIRROR_BIN to its bin directory."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Find Node. /usr/bin/python3 exists on every macOS; node usually lives under
|
|
66
|
+
# nvm or Homebrew and is NOT on the PATH of a GUI-launched runtime. The Python
|
|
67
|
+
# hooks could end in `|| true` because they always found their interpreter;
|
|
68
|
+
# the same silence here would hide a new failure — no logging, no inject, no
|
|
69
|
+
# close tail — that a user would meet weeks later as "Mirror stopped
|
|
70
|
+
# remembering". So an unresolvable Node is RECORDED, never swallowed. The
|
|
71
|
+
# directory the entry was found in is searched first: an npm global bin holds
|
|
72
|
+
# the `node` that installed the package beside `mirror-hook`, while a system
|
|
73
|
+
# `/usr/local/bin/node` can be years older (CI's Ubuntu runner has one).
|
|
74
|
+
NODE="${MIRROR_NODE:-}"
|
|
75
|
+
if [ -z "$NODE" ] || [ ! -x "$NODE" ]; then
|
|
76
|
+
NODE="$(command -v node 2>/dev/null || true)"
|
|
77
|
+
fi
|
|
78
|
+
for candidate in "$(dirname "$ENTRY")/node" "$HOME/.nvm/current/bin/node" /opt/homebrew/bin/node /usr/local/bin/node; do
|
|
79
|
+
[ -n "$NODE" ] && break
|
|
80
|
+
[ -x "$candidate" ] && NODE="$candidate"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$NODE" ]; then
|
|
84
|
+
note "node not found on PATH; hook skipped. Set MIRROR_NODE."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Not `exec`: the entry exits 0 whatever happens inside it, so a non-zero exit
|
|
89
|
+
# means Node itself could not run the hook -- too old for the loader shim, or
|
|
90
|
+
# it crashed. That used to vanish into a stderr no runtime shows (TS5 handoff
|
|
91
|
+
# review, finding N1). No flags: the entry reads configuration and silences
|
|
92
|
+
# its own warnings (US3, D3).
|
|
93
|
+
"$NODE" "$ENTRY" "$HOOK" "$@"
|
|
94
|
+
status=$?
|
|
95
|
+
if [ "$status" -ne 0 ]; then
|
|
96
|
+
note "node exited $status before the hook finished ($NODE, $("$NODE" --version 2>/dev/null || echo 'version unknown')); Mirror needs Node 24 or later. Set MIRROR_NODE."
|
|
97
|
+
fi
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Mirror Mind hook wrapper — GENERATED by scripts/generate_hook_wrappers.sh.
|
|
3
|
+
# Edit the generator, never this file: every wrapper shares these bytes and
|
|
4
|
+
# differs only in the hook name and in how it finds the Mirror entry
|
|
5
|
+
# (CV22.DS10.TS5 decision D4; CV22.DS10.US3 decision D5).
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
HOOK="claude:user-prompt"
|
|
8
|
+
|
|
9
|
+
# This wrapper is the Claude plugin's, and a plugin is copied into Claude
|
|
10
|
+
# Code's own cache: no relative path from here reaches the Mirror tree. It
|
|
11
|
+
# runs the installed `mirror-hook` bin instead, and reads no tree .env.
|
|
12
|
+
REPO_ROOT=""
|
|
13
|
+
|
|
14
|
+
# A hook never fails the user's turn, and never fails in silence: when it
|
|
15
|
+
# cannot do its job it appends ONE line to <mirror home>/hooks.log and exits 0.
|
|
16
|
+
# The home is found the way the core finds it -- MIRROR_HOME, else
|
|
17
|
+
# MIRROR_USER -- from the environment when set there, else from the tree's
|
|
18
|
+
# .env when the wrapper is in a tree, else from the user's config file
|
|
19
|
+
# (~/.config/mirror/env), in the core's order (US3, D3). A GUI launch carries
|
|
20
|
+
# neither variable, and the first wrappers then wrote to a home nobody reads.
|
|
21
|
+
env_file_value() {
|
|
22
|
+
[ -f "$2" ] || return 0
|
|
23
|
+
sed -n -E "s/^[[:space:]]*(export[[:space:]]+)?$1[[:space:]]*=[[:space:]]*//p" "$2" \
|
|
24
|
+
| tail -n 1 | tr -d "\"'\r"
|
|
25
|
+
}
|
|
26
|
+
env_value() {
|
|
27
|
+
local value=""
|
|
28
|
+
if [ -n "${!1+set}" ]; then printf '%s' "${!1}"; return; fi
|
|
29
|
+
[ -z "$REPO_ROOT" ] || value="$(env_file_value "$1" "$REPO_ROOT/.env")"
|
|
30
|
+
[ -n "$value" ] || value="$(env_file_value "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/mirror/env")"
|
|
31
|
+
printf '%s' "$value"
|
|
32
|
+
}
|
|
33
|
+
note() {
|
|
34
|
+
local home user
|
|
35
|
+
home="$(env_value MIRROR_HOME)"
|
|
36
|
+
user="$(env_value MIRROR_USER)"
|
|
37
|
+
if [ -n "$home" ]; then
|
|
38
|
+
home="${home/#\~/$HOME}"
|
|
39
|
+
elif [ -n "$user" ]; then
|
|
40
|
+
home="$HOME/.mirror-minds/$user"
|
|
41
|
+
[ -d "$home" ] || [ ! -d "$HOME/.mirror/$user" ] || home="$HOME/.mirror/$user"
|
|
42
|
+
else
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
mkdir -p "$home" 2>/dev/null \
|
|
46
|
+
&& printf '%s %s: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$HOOK" "$1" >> "$home/hooks.log" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Find the bin. MIRROR_BIN names the directory holding `mirror` and
|
|
50
|
+
# `mirror-hook` (`$(npm prefix -g)/bin`), the same trust class as MIRROR_NODE;
|
|
51
|
+
# then the PATH; then the global bin directories a GUI launch leaves off it.
|
|
52
|
+
ENTRY=""
|
|
53
|
+
[ -n "${MIRROR_BIN:-}" ] && [ -x "$MIRROR_BIN/mirror-hook" ] && ENTRY="$MIRROR_BIN/mirror-hook"
|
|
54
|
+
[ -n "$ENTRY" ] || ENTRY="$(command -v mirror-hook 2>/dev/null || true)"
|
|
55
|
+
for candidate in "$HOME/.nvm/current/bin" /opt/homebrew/bin /usr/local/bin; do
|
|
56
|
+
[ -n "$ENTRY" ] && break
|
|
57
|
+
[ -x "$candidate/mirror-hook" ] && ENTRY="$candidate/mirror-hook"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -z "$ENTRY" ]; then
|
|
61
|
+
note "mirror-hook not found on PATH; hook skipped. Install mirror-mind (npm install -g mirror-mind) or set MIRROR_BIN to its bin directory."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Find Node. /usr/bin/python3 exists on every macOS; node usually lives under
|
|
66
|
+
# nvm or Homebrew and is NOT on the PATH of a GUI-launched runtime. The Python
|
|
67
|
+
# hooks could end in `|| true` because they always found their interpreter;
|
|
68
|
+
# the same silence here would hide a new failure — no logging, no inject, no
|
|
69
|
+
# close tail — that a user would meet weeks later as "Mirror stopped
|
|
70
|
+
# remembering". So an unresolvable Node is RECORDED, never swallowed. The
|
|
71
|
+
# directory the entry was found in is searched first: an npm global bin holds
|
|
72
|
+
# the `node` that installed the package beside `mirror-hook`, while a system
|
|
73
|
+
# `/usr/local/bin/node` can be years older (CI's Ubuntu runner has one).
|
|
74
|
+
NODE="${MIRROR_NODE:-}"
|
|
75
|
+
if [ -z "$NODE" ] || [ ! -x "$NODE" ]; then
|
|
76
|
+
NODE="$(command -v node 2>/dev/null || true)"
|
|
77
|
+
fi
|
|
78
|
+
for candidate in "$(dirname "$ENTRY")/node" "$HOME/.nvm/current/bin/node" /opt/homebrew/bin/node /usr/local/bin/node; do
|
|
79
|
+
[ -n "$NODE" ] && break
|
|
80
|
+
[ -x "$candidate" ] && NODE="$candidate"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$NODE" ]; then
|
|
84
|
+
note "node not found on PATH; hook skipped. Set MIRROR_NODE."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Not `exec`: the entry exits 0 whatever happens inside it, so a non-zero exit
|
|
89
|
+
# means Node itself could not run the hook -- too old for the loader shim, or
|
|
90
|
+
# it crashed. That used to vanish into a stderr no runtime shows (TS5 handoff
|
|
91
|
+
# review, finding N1). No flags: the entry reads configuration and silences
|
|
92
|
+
# its own warnings (US3, D3).
|
|
93
|
+
"$NODE" "$ENTRY" "$HOOK" "$@"
|
|
94
|
+
status=$?
|
|
95
|
+
if [ "$status" -ne 0 ]; then
|
|
96
|
+
note "node exited $status before the hook finished ($NODE, $("$NODE" --version 2>/dev/null || echo 'version unknown')); Mirror needs Node 24 or later. Set MIRROR_NODE."
|
|
97
|
+
fi
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Mirror Mind hook wrapper — GENERATED by scripts/generate_hook_wrappers.sh.
|
|
3
|
+
# Edit the generator, never this file: every wrapper shares these bytes and
|
|
4
|
+
# differs only in the hook name and in how it finds the Mirror entry
|
|
5
|
+
# (CV22.DS10.TS5 decision D4; CV22.DS10.US3 decision D5).
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
HOOK="claude:inject"
|
|
8
|
+
|
|
9
|
+
# This wrapper is the Claude plugin's, and a plugin is copied into Claude
|
|
10
|
+
# Code's own cache: no relative path from here reaches the Mirror tree. It
|
|
11
|
+
# runs the installed `mirror-hook` bin instead, and reads no tree .env.
|
|
12
|
+
REPO_ROOT=""
|
|
13
|
+
|
|
14
|
+
# A hook never fails the user's turn, and never fails in silence: when it
|
|
15
|
+
# cannot do its job it appends ONE line to <mirror home>/hooks.log and exits 0.
|
|
16
|
+
# The home is found the way the core finds it -- MIRROR_HOME, else
|
|
17
|
+
# MIRROR_USER -- from the environment when set there, else from the tree's
|
|
18
|
+
# .env when the wrapper is in a tree, else from the user's config file
|
|
19
|
+
# (~/.config/mirror/env), in the core's order (US3, D3). A GUI launch carries
|
|
20
|
+
# neither variable, and the first wrappers then wrote to a home nobody reads.
|
|
21
|
+
env_file_value() {
|
|
22
|
+
[ -f "$2" ] || return 0
|
|
23
|
+
sed -n -E "s/^[[:space:]]*(export[[:space:]]+)?$1[[:space:]]*=[[:space:]]*//p" "$2" \
|
|
24
|
+
| tail -n 1 | tr -d "\"'\r"
|
|
25
|
+
}
|
|
26
|
+
env_value() {
|
|
27
|
+
local value=""
|
|
28
|
+
if [ -n "${!1+set}" ]; then printf '%s' "${!1}"; return; fi
|
|
29
|
+
[ -z "$REPO_ROOT" ] || value="$(env_file_value "$1" "$REPO_ROOT/.env")"
|
|
30
|
+
[ -n "$value" ] || value="$(env_file_value "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/mirror/env")"
|
|
31
|
+
printf '%s' "$value"
|
|
32
|
+
}
|
|
33
|
+
note() {
|
|
34
|
+
local home user
|
|
35
|
+
home="$(env_value MIRROR_HOME)"
|
|
36
|
+
user="$(env_value MIRROR_USER)"
|
|
37
|
+
if [ -n "$home" ]; then
|
|
38
|
+
home="${home/#\~/$HOME}"
|
|
39
|
+
elif [ -n "$user" ]; then
|
|
40
|
+
home="$HOME/.mirror-minds/$user"
|
|
41
|
+
[ -d "$home" ] || [ ! -d "$HOME/.mirror/$user" ] || home="$HOME/.mirror/$user"
|
|
42
|
+
else
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
mkdir -p "$home" 2>/dev/null \
|
|
46
|
+
&& printf '%s %s: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$HOOK" "$1" >> "$home/hooks.log" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Find the bin. MIRROR_BIN names the directory holding `mirror` and
|
|
50
|
+
# `mirror-hook` (`$(npm prefix -g)/bin`), the same trust class as MIRROR_NODE;
|
|
51
|
+
# then the PATH; then the global bin directories a GUI launch leaves off it.
|
|
52
|
+
ENTRY=""
|
|
53
|
+
[ -n "${MIRROR_BIN:-}" ] && [ -x "$MIRROR_BIN/mirror-hook" ] && ENTRY="$MIRROR_BIN/mirror-hook"
|
|
54
|
+
[ -n "$ENTRY" ] || ENTRY="$(command -v mirror-hook 2>/dev/null || true)"
|
|
55
|
+
for candidate in "$HOME/.nvm/current/bin" /opt/homebrew/bin /usr/local/bin; do
|
|
56
|
+
[ -n "$ENTRY" ] && break
|
|
57
|
+
[ -x "$candidate/mirror-hook" ] && ENTRY="$candidate/mirror-hook"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -z "$ENTRY" ]; then
|
|
61
|
+
note "mirror-hook not found on PATH; hook skipped. Install mirror-mind (npm install -g mirror-mind) or set MIRROR_BIN to its bin directory."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Find Node. /usr/bin/python3 exists on every macOS; node usually lives under
|
|
66
|
+
# nvm or Homebrew and is NOT on the PATH of a GUI-launched runtime. The Python
|
|
67
|
+
# hooks could end in `|| true` because they always found their interpreter;
|
|
68
|
+
# the same silence here would hide a new failure — no logging, no inject, no
|
|
69
|
+
# close tail — that a user would meet weeks later as "Mirror stopped
|
|
70
|
+
# remembering". So an unresolvable Node is RECORDED, never swallowed. The
|
|
71
|
+
# directory the entry was found in is searched first: an npm global bin holds
|
|
72
|
+
# the `node` that installed the package beside `mirror-hook`, while a system
|
|
73
|
+
# `/usr/local/bin/node` can be years older (CI's Ubuntu runner has one).
|
|
74
|
+
NODE="${MIRROR_NODE:-}"
|
|
75
|
+
if [ -z "$NODE" ] || [ ! -x "$NODE" ]; then
|
|
76
|
+
NODE="$(command -v node 2>/dev/null || true)"
|
|
77
|
+
fi
|
|
78
|
+
for candidate in "$(dirname "$ENTRY")/node" "$HOME/.nvm/current/bin/node" /opt/homebrew/bin/node /usr/local/bin/node; do
|
|
79
|
+
[ -n "$NODE" ] && break
|
|
80
|
+
[ -x "$candidate" ] && NODE="$candidate"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$NODE" ]; then
|
|
84
|
+
note "node not found on PATH; hook skipped. Set MIRROR_NODE."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Not `exec`: the entry exits 0 whatever happens inside it, so a non-zero exit
|
|
89
|
+
# means Node itself could not run the hook -- too old for the loader shim, or
|
|
90
|
+
# it crashed. That used to vanish into a stderr no runtime shows (TS5 handoff
|
|
91
|
+
# review, finding N1). No flags: the entry reads configuration and silences
|
|
92
|
+
# its own warnings (US3, D3).
|
|
93
|
+
"$NODE" "$ENTRY" "$HOOK" "$@"
|
|
94
|
+
status=$?
|
|
95
|
+
if [ "$status" -ne 0 ]; then
|
|
96
|
+
note "node exited $status before the hook finished ($NODE, $("$NODE" --version 2>/dev/null || echo 'version unknown')); Mirror needs Node 24 or later. Set MIRROR_NODE."
|
|
97
|
+
fi
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Mirror Mind hook wrapper — GENERATED by scripts/generate_hook_wrappers.sh.
|
|
3
|
+
# Edit the generator, never this file: every wrapper shares these bytes and
|
|
4
|
+
# differs only in the hook name and in how it finds the Mirror entry
|
|
5
|
+
# (CV22.DS10.TS5 decision D4; CV22.DS10.US3 decision D5).
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
HOOK="claude:session-start"
|
|
8
|
+
|
|
9
|
+
# This wrapper is the Claude plugin's, and a plugin is copied into Claude
|
|
10
|
+
# Code's own cache: no relative path from here reaches the Mirror tree. It
|
|
11
|
+
# runs the installed `mirror-hook` bin instead, and reads no tree .env.
|
|
12
|
+
REPO_ROOT=""
|
|
13
|
+
|
|
14
|
+
# A hook never fails the user's turn, and never fails in silence: when it
|
|
15
|
+
# cannot do its job it appends ONE line to <mirror home>/hooks.log and exits 0.
|
|
16
|
+
# The home is found the way the core finds it -- MIRROR_HOME, else
|
|
17
|
+
# MIRROR_USER -- from the environment when set there, else from the tree's
|
|
18
|
+
# .env when the wrapper is in a tree, else from the user's config file
|
|
19
|
+
# (~/.config/mirror/env), in the core's order (US3, D3). A GUI launch carries
|
|
20
|
+
# neither variable, and the first wrappers then wrote to a home nobody reads.
|
|
21
|
+
env_file_value() {
|
|
22
|
+
[ -f "$2" ] || return 0
|
|
23
|
+
sed -n -E "s/^[[:space:]]*(export[[:space:]]+)?$1[[:space:]]*=[[:space:]]*//p" "$2" \
|
|
24
|
+
| tail -n 1 | tr -d "\"'\r"
|
|
25
|
+
}
|
|
26
|
+
env_value() {
|
|
27
|
+
local value=""
|
|
28
|
+
if [ -n "${!1+set}" ]; then printf '%s' "${!1}"; return; fi
|
|
29
|
+
[ -z "$REPO_ROOT" ] || value="$(env_file_value "$1" "$REPO_ROOT/.env")"
|
|
30
|
+
[ -n "$value" ] || value="$(env_file_value "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/mirror/env")"
|
|
31
|
+
printf '%s' "$value"
|
|
32
|
+
}
|
|
33
|
+
note() {
|
|
34
|
+
local home user
|
|
35
|
+
home="$(env_value MIRROR_HOME)"
|
|
36
|
+
user="$(env_value MIRROR_USER)"
|
|
37
|
+
if [ -n "$home" ]; then
|
|
38
|
+
home="${home/#\~/$HOME}"
|
|
39
|
+
elif [ -n "$user" ]; then
|
|
40
|
+
home="$HOME/.mirror-minds/$user"
|
|
41
|
+
[ -d "$home" ] || [ ! -d "$HOME/.mirror/$user" ] || home="$HOME/.mirror/$user"
|
|
42
|
+
else
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
mkdir -p "$home" 2>/dev/null \
|
|
46
|
+
&& printf '%s %s: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$HOOK" "$1" >> "$home/hooks.log" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Find the bin. MIRROR_BIN names the directory holding `mirror` and
|
|
50
|
+
# `mirror-hook` (`$(npm prefix -g)/bin`), the same trust class as MIRROR_NODE;
|
|
51
|
+
# then the PATH; then the global bin directories a GUI launch leaves off it.
|
|
52
|
+
ENTRY=""
|
|
53
|
+
[ -n "${MIRROR_BIN:-}" ] && [ -x "$MIRROR_BIN/mirror-hook" ] && ENTRY="$MIRROR_BIN/mirror-hook"
|
|
54
|
+
[ -n "$ENTRY" ] || ENTRY="$(command -v mirror-hook 2>/dev/null || true)"
|
|
55
|
+
for candidate in "$HOME/.nvm/current/bin" /opt/homebrew/bin /usr/local/bin; do
|
|
56
|
+
[ -n "$ENTRY" ] && break
|
|
57
|
+
[ -x "$candidate/mirror-hook" ] && ENTRY="$candidate/mirror-hook"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -z "$ENTRY" ]; then
|
|
61
|
+
note "mirror-hook not found on PATH; hook skipped. Install mirror-mind (npm install -g mirror-mind) or set MIRROR_BIN to its bin directory."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Find Node. /usr/bin/python3 exists on every macOS; node usually lives under
|
|
66
|
+
# nvm or Homebrew and is NOT on the PATH of a GUI-launched runtime. The Python
|
|
67
|
+
# hooks could end in `|| true` because they always found their interpreter;
|
|
68
|
+
# the same silence here would hide a new failure — no logging, no inject, no
|
|
69
|
+
# close tail — that a user would meet weeks later as "Mirror stopped
|
|
70
|
+
# remembering". So an unresolvable Node is RECORDED, never swallowed. The
|
|
71
|
+
# directory the entry was found in is searched first: an npm global bin holds
|
|
72
|
+
# the `node` that installed the package beside `mirror-hook`, while a system
|
|
73
|
+
# `/usr/local/bin/node` can be years older (CI's Ubuntu runner has one).
|
|
74
|
+
NODE="${MIRROR_NODE:-}"
|
|
75
|
+
if [ -z "$NODE" ] || [ ! -x "$NODE" ]; then
|
|
76
|
+
NODE="$(command -v node 2>/dev/null || true)"
|
|
77
|
+
fi
|
|
78
|
+
for candidate in "$(dirname "$ENTRY")/node" "$HOME/.nvm/current/bin/node" /opt/homebrew/bin/node /usr/local/bin/node; do
|
|
79
|
+
[ -n "$NODE" ] && break
|
|
80
|
+
[ -x "$candidate" ] && NODE="$candidate"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$NODE" ]; then
|
|
84
|
+
note "node not found on PATH; hook skipped. Set MIRROR_NODE."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Not `exec`: the entry exits 0 whatever happens inside it, so a non-zero exit
|
|
89
|
+
# means Node itself could not run the hook -- too old for the loader shim, or
|
|
90
|
+
# it crashed. That used to vanish into a stderr no runtime shows (TS5 handoff
|
|
91
|
+
# review, finding N1). No flags: the entry reads configuration and silences
|
|
92
|
+
# its own warnings (US3, D3).
|
|
93
|
+
"$NODE" "$ENTRY" "$HOOK" "$@"
|
|
94
|
+
status=$?
|
|
95
|
+
if [ "$status" -ne 0 ]; then
|
|
96
|
+
note "node exited $status before the hook finished ($NODE, $("$NODE" --version 2>/dev/null || echo 'version unknown')); Mirror needs Node 24 or later. Set MIRROR_NODE."
|
|
97
|
+
fi
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "mm:backup"
|
|
3
|
+
description: Backs up the production memory database
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Memory Database Backup
|
|
8
|
+
|
|
9
|
+
Runs a backup of the configured production database.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
mirror backup
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This command:
|
|
16
|
+
- Archives a consistent snapshot of the database, one `memory.db` in WAL mode,
|
|
17
|
+
readable only by its owner
|
|
18
|
+
- Removes backups older than 30 days
|
|
19
|
+
- Also runs automatically at session end through the `SessionEnd` hook
|
|
20
|
+
|
|
21
|
+
The backup succeeded only when the command exits 0 and prints a
|
|
22
|
+
`Backup created:` line. Then tell the user: "Memory database backed up." and show
|
|
23
|
+
that line.
|
|
24
|
+
|
|
25
|
+
If the command exits non-zero, or prints a line starting with
|
|
26
|
+
`backup: no archive was written:`, the backup failed. Tell the user so, quote
|
|
27
|
+
that line, and never say the database was backed up.
|