mindweave 0.0.1 → 2.1.2
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/LICENSE +190 -0
- package/README.md +171 -14
- package/dist/alternator/chassis/cache.js +47 -0
- package/dist/alternator/chassis/cache.js.map +1 -0
- package/dist/alternator/chassis/domRefs.js +53 -0
- package/dist/alternator/chassis/domRefs.js.map +1 -0
- package/dist/alternator/chassis/extractWorker.js +65 -0
- package/dist/alternator/chassis/extractWorker.js.map +1 -0
- package/dist/alternator/chassis/graph.js +221 -0
- package/dist/alternator/chassis/graph.js.map +1 -0
- package/dist/alternator/chassis/index.js +463 -0
- package/dist/alternator/chassis/index.js.map +1 -0
- package/dist/alternator/chassis/isolation.js +336 -0
- package/dist/alternator/chassis/isolation.js.map +1 -0
- package/dist/alternator/chassis/langCases.js +69 -0
- package/dist/alternator/chassis/langCases.js.map +1 -0
- package/dist/alternator/chassis/lsp.js +469 -0
- package/dist/alternator/chassis/lsp.js.map +1 -0
- package/dist/alternator/chassis/markup.js +262 -0
- package/dist/alternator/chassis/markup.js.map +1 -0
- package/dist/alternator/chassis/provision.js +198 -0
- package/dist/alternator/chassis/provision.js.map +1 -0
- package/dist/alternator/chassis/rank.js +72 -0
- package/dist/alternator/chassis/rank.js.map +1 -0
- package/dist/alternator/chassis/servers.js +215 -0
- package/dist/alternator/chassis/servers.js.map +1 -0
- package/dist/alternator/chassis/treesitter.js +608 -0
- package/dist/alternator/chassis/treesitter.js.map +1 -0
- package/dist/alternator/chassis/types.js +24 -0
- package/dist/alternator/chassis/types.js.map +1 -0
- package/dist/alternator/lane.js +67 -0
- package/dist/alternator/lane.js.map +1 -0
- package/dist/cli/App.js +2586 -0
- package/dist/cli/App.js.map +1 -0
- package/dist/cli/altScreen.js +67 -0
- package/dist/cli/altScreen.js.map +1 -0
- package/dist/cli/approvalChannel.js +72 -0
- package/dist/cli/approvalChannel.js.map +1 -0
- package/dist/cli/attachments.js +188 -0
- package/dist/cli/attachments.js.map +1 -0
- package/dist/cli/bootstrap.js +279 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/chatAnchor.js +94 -0
- package/dist/cli/chatAnchor.js.map +1 -0
- package/dist/cli/commandArgs.js +79 -0
- package/dist/cli/commandArgs.js.map +1 -0
- package/dist/cli/commandRoute.js +78 -0
- package/dist/cli/commandRoute.js.map +1 -0
- package/dist/cli/compaction.js +69 -0
- package/dist/cli/compaction.js.map +1 -0
- package/dist/cli/components/ApprovalBox.js +100 -0
- package/dist/cli/components/ApprovalBox.js.map +1 -0
- package/dist/cli/components/BlockView.js +128 -0
- package/dist/cli/components/BlockView.js.map +1 -0
- package/dist/cli/components/FirstRunFrame.js +41 -0
- package/dist/cli/components/FirstRunFrame.js.map +1 -0
- package/dist/cli/components/KeyManager.js +197 -0
- package/dist/cli/components/KeyManager.js.map +1 -0
- package/dist/cli/components/KeySetup.js +125 -0
- package/dist/cli/components/KeySetup.js.map +1 -0
- package/dist/cli/components/MenuFrame.js +24 -0
- package/dist/cli/components/MenuFrame.js.map +1 -0
- package/dist/cli/components/Picker.js +82 -0
- package/dist/cli/components/Picker.js.map +1 -0
- package/dist/cli/components/PromptInput.js +509 -0
- package/dist/cli/components/PromptInput.js.map +1 -0
- package/dist/cli/components/SubagentView.js +86 -0
- package/dist/cli/components/SubagentView.js.map +1 -0
- package/dist/cli/components/ToolGroup.js +60 -0
- package/dist/cli/components/ToolGroup.js.map +1 -0
- package/dist/cli/components/ToolLine.js +123 -0
- package/dist/cli/components/ToolLine.js.map +1 -0
- package/dist/cli/components/TrustGate.js +37 -0
- package/dist/cli/components/TrustGate.js.map +1 -0
- package/dist/cli/costView.js +40 -0
- package/dist/cli/costView.js.map +1 -0
- package/dist/cli/frameRate.js +30 -0
- package/dist/cli/frameRate.js.map +1 -0
- package/dist/cli/framebuffer/paint.js +165 -0
- package/dist/cli/framebuffer/paint.js.map +1 -0
- package/dist/cli/framebuffer/parse.js +266 -0
- package/dist/cli/framebuffer/parse.js.map +1 -0
- package/dist/cli/framebuffer/screen.js +196 -0
- package/dist/cli/framebuffer/screen.js.map +1 -0
- package/dist/cli/framebuffer/writer.js +139 -0
- package/dist/cli/framebuffer/writer.js.map +1 -0
- package/dist/cli/groupReveal.js +51 -0
- package/dist/cli/groupReveal.js.map +1 -0
- package/dist/cli/help.js +55 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/inputView.js +105 -0
- package/dist/cli/inputView.js.map +1 -0
- package/dist/cli/keyManager.js +65 -0
- package/dist/cli/keyManager.js.map +1 -0
- package/dist/cli/keySetup.js +35 -0
- package/dist/cli/keySetup.js.map +1 -0
- package/dist/cli/keyStore.js +73 -0
- package/dist/cli/keyStore.js.map +1 -0
- package/dist/cli/markdown.js +460 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/messageQueue.js +96 -0
- package/dist/cli/messageQueue.js.map +1 -0
- package/dist/cli/modes.js +90 -0
- package/dist/cli/modes.js.map +1 -0
- package/dist/cli/mouse.js +78 -0
- package/dist/cli/mouse.js.map +1 -0
- package/dist/cli/pasteAssembler.js +44 -0
- package/dist/cli/pasteAssembler.js.map +1 -0
- package/dist/cli/pathComplete.js +39 -0
- package/dist/cli/pathComplete.js.map +1 -0
- package/dist/cli/perfLog.js +90 -0
- package/dist/cli/perfLog.js.map +1 -0
- package/dist/cli/reveal.js +32 -0
- package/dist/cli/reveal.js.map +1 -0
- package/dist/cli/revealPace.js +59 -0
- package/dist/cli/revealPace.js.map +1 -0
- package/dist/cli/sessionCarry.js +19 -0
- package/dist/cli/sessionCarry.js.map +1 -0
- package/dist/cli/smoothScroll.js +74 -0
- package/dist/cli/smoothScroll.js.map +1 -0
- package/dist/cli/startupArgs.js +96 -0
- package/dist/cli/startupArgs.js.map +1 -0
- package/dist/cli/terminalRestore.js +34 -0
- package/dist/cli/terminalRestore.js.map +1 -0
- package/dist/cli/toolDisplay.js +219 -0
- package/dist/cli/toolDisplay.js.map +1 -0
- package/dist/cli/toolItems.js +65 -0
- package/dist/cli/toolItems.js.map +1 -0
- package/dist/cli/transcript.js +351 -0
- package/dist/cli/transcript.js.map +1 -0
- package/dist/cli/trust.js +79 -0
- package/dist/cli/trust.js.map +1 -0
- package/dist/cli/updateCheck.js +107 -0
- package/dist/cli/updateCheck.js.map +1 -0
- package/dist/cli/version.js +39 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli/viewport.js +179 -0
- package/dist/cli/viewport.js.map +1 -0
- package/dist/cli/virtualWindow.js +103 -0
- package/dist/cli/virtualWindow.js.map +1 -0
- package/dist/cli/workingVerb.js +37 -0
- package/dist/cli/workingVerb.js.map +1 -0
- package/dist/cli/wrap.js +145 -0
- package/dist/cli/wrap.js.map +1 -0
- package/dist/drivers/anthropic/cachePoints.js +77 -0
- package/dist/drivers/anthropic/cachePoints.js.map +1 -0
- package/dist/drivers/anthropic/client.js +432 -0
- package/dist/drivers/anthropic/client.js.map +1 -0
- package/dist/drivers/anthropic/index.js +10 -0
- package/dist/drivers/anthropic/index.js.map +1 -0
- package/dist/drivers/anthropic/manifest.js +221 -0
- package/dist/drivers/anthropic/manifest.js.map +1 -0
- package/dist/drivers/cerebras/client.js +69 -0
- package/dist/drivers/cerebras/client.js.map +1 -0
- package/dist/drivers/cerebras/index.js +5 -0
- package/dist/drivers/cerebras/index.js.map +1 -0
- package/dist/drivers/cerebras/manifest.js +140 -0
- package/dist/drivers/cerebras/manifest.js.map +1 -0
- package/dist/drivers/clientId.js +41 -0
- package/dist/drivers/clientId.js.map +1 -0
- package/dist/drivers/contextOverflow.js +77 -0
- package/dist/drivers/contextOverflow.js.map +1 -0
- package/dist/drivers/deepseek/client.js +168 -0
- package/dist/drivers/deepseek/client.js.map +1 -0
- package/dist/drivers/deepseek/index.js +16 -0
- package/dist/drivers/deepseek/index.js.map +1 -0
- package/dist/drivers/deepseek/inlineTools.js +46 -0
- package/dist/drivers/deepseek/inlineTools.js.map +1 -0
- package/dist/drivers/deepseek/manifest.js +166 -0
- package/dist/drivers/deepseek/manifest.js.map +1 -0
- package/dist/drivers/gemini/client.js +38 -0
- package/dist/drivers/gemini/client.js.map +1 -0
- package/dist/drivers/gemini/index.js +5 -0
- package/dist/drivers/gemini/index.js.map +1 -0
- package/dist/drivers/gemini/manifest.js +150 -0
- package/dist/drivers/gemini/manifest.js.map +1 -0
- package/dist/drivers/glm/client.js +90 -0
- package/dist/drivers/glm/client.js.map +1 -0
- package/dist/drivers/glm/index.js +9 -0
- package/dist/drivers/glm/index.js.map +1 -0
- package/dist/drivers/glm/manifest.js +183 -0
- package/dist/drivers/glm/manifest.js.map +1 -0
- package/dist/drivers/groq/client.js +80 -0
- package/dist/drivers/groq/client.js.map +1 -0
- package/dist/drivers/groq/index.js +5 -0
- package/dist/drivers/groq/index.js.map +1 -0
- package/dist/drivers/groq/manifest.js +160 -0
- package/dist/drivers/groq/manifest.js.map +1 -0
- package/dist/drivers/kimi/client.js +82 -0
- package/dist/drivers/kimi/client.js.map +1 -0
- package/dist/drivers/kimi/index.js +9 -0
- package/dist/drivers/kimi/index.js.map +1 -0
- package/dist/drivers/kimi/manifest.js +168 -0
- package/dist/drivers/kimi/manifest.js.map +1 -0
- package/dist/drivers/meta/client.js +30 -0
- package/dist/drivers/meta/client.js.map +1 -0
- package/dist/drivers/meta/index.js +5 -0
- package/dist/drivers/meta/index.js.map +1 -0
- package/dist/drivers/meta/manifest.js +101 -0
- package/dist/drivers/meta/manifest.js.map +1 -0
- package/dist/drivers/minimax/client.js +36 -0
- package/dist/drivers/minimax/client.js.map +1 -0
- package/dist/drivers/minimax/index.js +5 -0
- package/dist/drivers/minimax/index.js.map +1 -0
- package/dist/drivers/minimax/manifest.js +120 -0
- package/dist/drivers/minimax/manifest.js.map +1 -0
- package/dist/drivers/mistral/client.js +54 -0
- package/dist/drivers/mistral/client.js.map +1 -0
- package/dist/drivers/mistral/index.js +5 -0
- package/dist/drivers/mistral/index.js.map +1 -0
- package/dist/drivers/mistral/manifest.js +118 -0
- package/dist/drivers/mistral/manifest.js.map +1 -0
- package/dist/drivers/openai/client.js +290 -0
- package/dist/drivers/openai/client.js.map +1 -0
- package/dist/drivers/openai/index.js +9 -0
- package/dist/drivers/openai/index.js.map +1 -0
- package/dist/drivers/openai/manifest.js +133 -0
- package/dist/drivers/openai/manifest.js.map +1 -0
- package/dist/drivers/openaiCompat/wire.js +493 -0
- package/dist/drivers/openaiCompat/wire.js.map +1 -0
- package/dist/drivers/partialTurn.js +23 -0
- package/dist/drivers/partialTurn.js.map +1 -0
- package/dist/drivers/providerError.js +181 -0
- package/dist/drivers/providerError.js.map +1 -0
- package/dist/drivers/qwen/client.js +93 -0
- package/dist/drivers/qwen/client.js.map +1 -0
- package/dist/drivers/qwen/index.js +9 -0
- package/dist/drivers/qwen/index.js.map +1 -0
- package/dist/drivers/qwen/manifest.js +146 -0
- package/dist/drivers/qwen/manifest.js.map +1 -0
- package/dist/drivers/registry.js +177 -0
- package/dist/drivers/registry.js.map +1 -0
- package/dist/drivers/retryPolicy.js +129 -0
- package/dist/drivers/retryPolicy.js.map +1 -0
- package/dist/drivers/searchBlocks.js +61 -0
- package/dist/drivers/searchBlocks.js.map +1 -0
- package/dist/drivers/types.js +2 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/drivers/xai/client.js +63 -0
- package/dist/drivers/xai/client.js.map +1 -0
- package/dist/drivers/xai/index.js +5 -0
- package/dist/drivers/xai/index.js.map +1 -0
- package/dist/drivers/xai/manifest.js +137 -0
- package/dist/drivers/xai/manifest.js.map +1 -0
- package/dist/dynamo/_probe.tmp.js +20 -0
- package/dist/dynamo/_probe.tmp.js.map +1 -0
- package/dist/dynamo/cacheBreak.js +88 -0
- package/dist/dynamo/cacheBreak.js.map +1 -0
- package/dist/dynamo/contextWindow.js +243 -0
- package/dist/dynamo/contextWindow.js.map +1 -0
- package/dist/dynamo/engine.js +2011 -0
- package/dist/dynamo/engine.js.map +1 -0
- package/dist/dynamo/guard.js +132 -0
- package/dist/dynamo/guard.js.map +1 -0
- package/dist/dynamo/liveMeter.js +58 -0
- package/dist/dynamo/liveMeter.js.map +1 -0
- package/dist/dynamo/model.js +172 -0
- package/dist/dynamo/model.js.map +1 -0
- package/dist/dynamo/planArtifact.js +125 -0
- package/dist/dynamo/planArtifact.js.map +1 -0
- package/dist/dynamo/pricing.js +140 -0
- package/dist/dynamo/pricing.js.map +1 -0
- package/dist/dynamo/prompt.js +264 -0
- package/dist/dynamo/prompt.js.map +1 -0
- package/dist/dynamo/spend.js +45 -0
- package/dist/dynamo/spend.js.map +1 -0
- package/dist/dynamo/verify.js +483 -0
- package/dist/dynamo/verify.js.map +1 -0
- package/dist/governor/forbidden.js +181 -0
- package/dist/governor/forbidden.js.map +1 -0
- package/dist/governor/freshness.js +83 -0
- package/dist/governor/freshness.js.map +1 -0
- package/dist/governor/frontmatter.js +38 -0
- package/dist/governor/frontmatter.js.map +1 -0
- package/dist/governor/glob.js +75 -0
- package/dist/governor/glob.js.map +1 -0
- package/dist/governor/index.js +87 -0
- package/dist/governor/index.js.map +1 -0
- package/dist/governor/rules.js +80 -0
- package/dist/governor/rules.js.map +1 -0
- package/dist/governor/scope.js +91 -0
- package/dist/governor/scope.js.map +1 -0
- package/dist/governor/skills.js +176 -0
- package/dist/governor/skills.js.map +1 -0
- package/dist/governor/types.js +16 -0
- package/dist/governor/types.js.map +1 -0
- package/dist/governor/write.js +182 -0
- package/dist/governor/write.js.map +1 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/catalog.js +232 -0
- package/dist/mcp/catalog.js.map +1 -0
- package/dist/mcp/config.js +116 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/configWrite.js +254 -0
- package/dist/mcp/configWrite.js.map +1 -0
- package/dist/mcp/connection.js +504 -0
- package/dist/mcp/connection.js.map +1 -0
- package/dist/mcp/deferred.js +104 -0
- package/dist/mcp/deferred.js.map +1 -0
- package/dist/mcp/discover.js +128 -0
- package/dist/mcp/discover.js.map +1 -0
- package/dist/mcp/manager.js +679 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/paramHeaders.js +163 -0
- package/dist/mcp/paramHeaders.js.map +1 -0
- package/dist/mcp/prompts.js +136 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/protocol.js +171 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/resources.js +119 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/resultStore.js +180 -0
- package/dist/mcp/resultStore.js.map +1 -0
- package/dist/mcp/subscriptions.js +74 -0
- package/dist/mcp/subscriptions.js.map +1 -0
- package/dist/mcp/transport/headerValue.js +40 -0
- package/dist/mcp/transport/headerValue.js.map +1 -0
- package/dist/mcp/transport/http.js +321 -0
- package/dist/mcp/transport/http.js.map +1 -0
- package/dist/mcp/transport/stdio.js +234 -0
- package/dist/mcp/transport/stdio.js.map +1 -0
- package/dist/mcp/transport/types.js +27 -0
- package/dist/mcp/transport/types.js.map +1 -0
- package/dist/mcp/trust.js +98 -0
- package/dist/mcp/trust.js.map +1 -0
- package/dist/mcp/trustStore.js +55 -0
- package/dist/mcp/trustStore.js.map +1 -0
- package/dist/memory/autoMemory.js +340 -0
- package/dist/memory/autoMemory.js.map +1 -0
- package/dist/memory/compaction.js +513 -0
- package/dist/memory/compaction.js.map +1 -0
- package/dist/memory/images.js +173 -0
- package/dist/memory/images.js.map +1 -0
- package/dist/memory/presence.js +59 -0
- package/dist/memory/presence.js.map +1 -0
- package/dist/memory/projectNotes.js +247 -0
- package/dist/memory/projectNotes.js.map +1 -0
- package/dist/memory/restore.js +72 -0
- package/dist/memory/restore.js.map +1 -0
- package/dist/memory/session.js +472 -0
- package/dist/memory/session.js.map +1 -0
- package/dist/memory/sessionMemory.js +142 -0
- package/dist/memory/sessionMemory.js.map +1 -0
- package/dist/memory/sessionMemoryCompact.js +136 -0
- package/dist/memory/sessionMemoryCompact.js.map +1 -0
- package/dist/memory/store.js +217 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.js +14 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/workingSet.js +383 -0
- package/dist/memory/workingSet.js.map +1 -0
- package/dist/project/context.js +425 -0
- package/dist/project/context.js.map +1 -0
- package/dist/tools/approval.js +189 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/askUser.js +103 -0
- package/dist/tools/askUser.js.map +1 -0
- package/dist/tools/atomicWrite.js +151 -0
- package/dist/tools/atomicWrite.js.map +1 -0
- package/dist/tools/backgroundShells.js +468 -0
- package/dist/tools/backgroundShells.js.map +1 -0
- package/dist/tools/captureSweep.js +77 -0
- package/dist/tools/captureSweep.js.map +1 -0
- package/dist/tools/chassisMux.js +92 -0
- package/dist/tools/chassisMux.js.map +1 -0
- package/dist/tools/checkpoints.js +328 -0
- package/dist/tools/checkpoints.js.map +1 -0
- package/dist/tools/codeIntel.js +267 -0
- package/dist/tools/codeIntel.js.map +1 -0
- package/dist/tools/deferredNative.js +121 -0
- package/dist/tools/deferredNative.js.map +1 -0
- package/dist/tools/detail.js +135 -0
- package/dist/tools/detail.js.map +1 -0
- package/dist/tools/diagnostics.js +174 -0
- package/dist/tools/diagnostics.js.map +1 -0
- package/dist/tools/edit.js +167 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/editCore.js +283 -0
- package/dist/tools/editCore.js.map +1 -0
- package/dist/tools/editFile.js +183 -0
- package/dist/tools/editFile.js.map +1 -0
- package/dist/tools/editRipple.js +126 -0
- package/dist/tools/editRipple.js.map +1 -0
- package/dist/tools/editTarget.js +131 -0
- package/dist/tools/editTarget.js.map +1 -0
- package/dist/tools/editWindow.js +49 -0
- package/dist/tools/editWindow.js.map +1 -0
- package/dist/tools/eol.js +56 -0
- package/dist/tools/eol.js.map +1 -0
- package/dist/tools/exitPlan.js +175 -0
- package/dist/tools/exitPlan.js.map +1 -0
- package/dist/tools/focus.js +42 -0
- package/dist/tools/focus.js.map +1 -0
- package/dist/tools/gitignore.js +148 -0
- package/dist/tools/gitignore.js.map +1 -0
- package/dist/tools/glob.js +134 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/governorTools.js +258 -0
- package/dist/tools/governorTools.js.map +1 -0
- package/dist/tools/grep.js +450 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/guard.js +220 -0
- package/dist/tools/guard.js.map +1 -0
- package/dist/tools/killTree.js +215 -0
- package/dist/tools/killTree.js.map +1 -0
- package/dist/tools/listDir.js +143 -0
- package/dist/tools/listDir.js.map +1 -0
- package/dist/tools/mcpAdd.js +176 -0
- package/dist/tools/mcpAdd.js.map +1 -0
- package/dist/tools/mcpResources.js +116 -0
- package/dist/tools/mcpResources.js.map +1 -0
- package/dist/tools/mcpSearch.js +123 -0
- package/dist/tools/mcpSearch.js.map +1 -0
- package/dist/tools/multiEdit.js +168 -0
- package/dist/tools/multiEdit.js.map +1 -0
- package/dist/tools/paths.js +225 -0
- package/dist/tools/paths.js.map +1 -0
- package/dist/tools/posixShell.js +123 -0
- package/dist/tools/posixShell.js.map +1 -0
- package/dist/tools/readFile.js +371 -0
- package/dist/tools/readFile.js.map +1 -0
- package/dist/tools/readSymbol.js +145 -0
- package/dist/tools/readSymbol.js.map +1 -0
- package/dist/tools/registry.js +120 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/replaceSymbol.js +141 -0
- package/dist/tools/replaceSymbol.js.map +1 -0
- package/dist/tools/results.js +15 -0
- package/dist/tools/results.js.map +1 -0
- package/dist/tools/ripgrep.js +145 -0
- package/dist/tools/ripgrep.js.map +1 -0
- package/dist/tools/runCommand.js +633 -0
- package/dist/tools/runCommand.js.map +1 -0
- package/dist/tools/saveMemory.js +102 -0
- package/dist/tools/saveMemory.js.map +1 -0
- package/dist/tools/screenshot.js +200 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/screenshotWin.js +227 -0
- package/dist/tools/screenshotWin.js.map +1 -0
- package/dist/tools/search.js +121 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/sessionTools.js +187 -0
- package/dist/tools/sessionTools.js.map +1 -0
- package/dist/tools/shellCheckpoint.js +123 -0
- package/dist/tools/shellCheckpoint.js.map +1 -0
- package/dist/tools/shellLint.js +102 -0
- package/dist/tools/shellLint.js.map +1 -0
- package/dist/tools/shellTools.js +203 -0
- package/dist/tools/shellTools.js.map +1 -0
- package/dist/tools/spanCore.js +78 -0
- package/dist/tools/spanCore.js.map +1 -0
- package/dist/tools/subagent.js +224 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/subagentReport.js +114 -0
- package/dist/tools/subagentReport.js.map +1 -0
- package/dist/tools/tempSweep.js +118 -0
- package/dist/tools/tempSweep.js.map +1 -0
- package/dist/tools/todo.js +117 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/untrusted.js +46 -0
- package/dist/tools/untrusted.js.map +1 -0
- package/dist/tools/useSkill.js +62 -0
- package/dist/tools/useSkill.js.map +1 -0
- package/dist/tools/walk.js +152 -0
- package/dist/tools/walk.js.map +1 -0
- package/dist/tools/web.js +61 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/tools/webFetch.js +444 -0
- package/dist/tools/webFetch.js.map +1 -0
- package/dist/tools/webSearch.js +130 -0
- package/dist/tools/webSearch.js.map +1 -0
- package/dist/tools/workspace.js +212 -0
- package/dist/tools/workspace.js.map +1 -0
- package/dist/tools/workspaceDiscover.js +216 -0
- package/dist/tools/workspaceDiscover.js.map +1 -0
- package/dist/tools/writeFile.js +162 -0
- package/dist/tools/writeFile.js.map +1 -0
- package/package.json +74 -28
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trust.ts — noticing when a server changes what its tools claim to do.
|
|
3
|
+
*
|
|
4
|
+
* A tool description is not documentation. It is text written by a third party that
|
|
5
|
+
* goes straight into the model's prompt and is read as instruction. That makes the
|
|
6
|
+
* description an injection surface, and the 2026 literature on MCP converges on one
|
|
7
|
+
* structural cause for the whole family of attacks: **clients inherit trust from the
|
|
8
|
+
* servers they connect to and never verify it again.**
|
|
9
|
+
*
|
|
10
|
+
* Three named variants:
|
|
11
|
+
* - Tool poisoning — hidden instructions in a description or schema.
|
|
12
|
+
* - Rug pull — a clean server ships an update that poisons a description,
|
|
13
|
+
* and clients reload it silently.
|
|
14
|
+
* - Cross-server shadow — one server's description manipulates the agent into
|
|
15
|
+
* misusing a DIFFERENT server's tools.
|
|
16
|
+
*
|
|
17
|
+
* This module addresses the second one, and only the second one. We fingerprint every
|
|
18
|
+
* tool's description and schema on first sight, persist it, and refuse a tool whose
|
|
19
|
+
* fingerprint has moved until the user looks at the change. That is deterministic and
|
|
20
|
+
* fires regardless of what the model does.
|
|
21
|
+
*
|
|
22
|
+
* WHAT THIS DOES NOT DO, stated plainly here and in SECURITY.md because implying
|
|
23
|
+
* otherwise would be worse than not having it: a server that is malicious on day one
|
|
24
|
+
* passes every check in this file. First sight is trusted by construction — there is no
|
|
25
|
+
* signature to verify, no reputation to consult. This catches CHANGE, not badness. No
|
|
26
|
+
* MCP client currently solves the day-one case, and pretending we do would be the kind
|
|
27
|
+
* of claim that quietly becomes a lie.
|
|
28
|
+
*
|
|
29
|
+
* The decisions are pure; `store.ts` does the disk work.
|
|
30
|
+
*/
|
|
31
|
+
import { createHash } from "node:crypto";
|
|
32
|
+
import { mcpToolName } from "./catalog.js";
|
|
33
|
+
/** A tool's fingerprint: what it claims to do and what it claims to accept. */
|
|
34
|
+
export function fingerprint(def) {
|
|
35
|
+
// Description AND schema. A poisoned parameter description is the same attack as a
|
|
36
|
+
// poisoned tool description, and hashing only the latter would miss it entirely.
|
|
37
|
+
const material = JSON.stringify({ d: def.description, s: def.inputSchema });
|
|
38
|
+
return createHash("sha256").update(material).digest("hex").slice(0, 32);
|
|
39
|
+
}
|
|
40
|
+
/** Build the fingerprint record for a whole catalog. */
|
|
41
|
+
export function fingerprintCatalog(defs) {
|
|
42
|
+
const out = {};
|
|
43
|
+
for (const def of defs)
|
|
44
|
+
out[mcpToolName(def.server, def.name)] = fingerprint(def);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Compare a live catalog against what we recorded last time (pure).
|
|
49
|
+
*
|
|
50
|
+
* Note what is NOT flagged: a tool that disappeared. A server dropping a tool cannot
|
|
51
|
+
* inject anything, and treating removal as suspicious would make every ordinary server
|
|
52
|
+
* upgrade look like an attack — which trains the user to click through the prompt, which
|
|
53
|
+
* is how a real warning gets ignored.
|
|
54
|
+
*/
|
|
55
|
+
export function compareTrust(defs, known) {
|
|
56
|
+
const verdict = { unchanged: [], fresh: [], changed: [] };
|
|
57
|
+
for (const def of defs) {
|
|
58
|
+
const name = mcpToolName(def.server, def.name);
|
|
59
|
+
const now = fingerprint(def);
|
|
60
|
+
const before = known[name];
|
|
61
|
+
if (before === undefined)
|
|
62
|
+
verdict.fresh.push(name);
|
|
63
|
+
else if (before === now)
|
|
64
|
+
verdict.unchanged.push(name);
|
|
65
|
+
else
|
|
66
|
+
verdict.changed.push(name);
|
|
67
|
+
}
|
|
68
|
+
verdict.fresh.sort();
|
|
69
|
+
verdict.changed.sort();
|
|
70
|
+
verdict.unchanged.sort();
|
|
71
|
+
return verdict;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The question put to the user when a tool's description has moved (pure).
|
|
75
|
+
*
|
|
76
|
+
* Deliberately concrete about what changed and what the risk is. "Trust this server?"
|
|
77
|
+
* is unanswerable; "this tool's description changed since you last used it, and a
|
|
78
|
+
* description is instructions the agent follows" is a question someone can actually
|
|
79
|
+
* decide.
|
|
80
|
+
*/
|
|
81
|
+
export function changedToolsQuestion(changed) {
|
|
82
|
+
const list = changed.length <= 3 ? changed.join(", ") : `${changed.slice(0, 3).join(", ")} and ${changed.length - 3} more`;
|
|
83
|
+
return (`An MCP server changed what ${changed.length === 1 ? "a tool claims" : "some tools claim"} to do since you last ` +
|
|
84
|
+
`used ${changed.length === 1 ? "it" : "them"}: ${list}. Tool descriptions are instructions the agent follows, so ` +
|
|
85
|
+
`a silent change is how a trusted server turns hostile. Allow ${changed.length === 1 ? "it" : "them"}?`);
|
|
86
|
+
}
|
|
87
|
+
/** Merge accepted tools into the stored record, leaving refused ones flagged. */
|
|
88
|
+
export function acceptTools(known, defs, accept) {
|
|
89
|
+
const next = { ...known };
|
|
90
|
+
const wanted = new Set(accept);
|
|
91
|
+
for (const def of defs) {
|
|
92
|
+
const name = mcpToolName(def.server, def.name);
|
|
93
|
+
if (wanted.has(name))
|
|
94
|
+
next[name] = fingerprint(def);
|
|
95
|
+
}
|
|
96
|
+
return next;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.js","sourceRoot":"","sources":["../../src/mcp/trust.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trustStore.ts — where tool fingerprints live between sessions.
|
|
3
|
+
*
|
|
4
|
+
* Kept in the project's governor state dir, alongside `forbidden.md` and
|
|
5
|
+
* `forbidden-commands.md`, because this is the same kind of thing: a persisted decision
|
|
6
|
+
* about what this project is allowed to do, owned by the user rather than the model.
|
|
7
|
+
*
|
|
8
|
+
* Per PROJECT, not global. The same server can legitimately be a different build in two
|
|
9
|
+
* checkouts, and a global record would make an ordinary version difference look like a
|
|
10
|
+
* rug pull in every other project.
|
|
11
|
+
*
|
|
12
|
+
* Failure is always "no record": a missing or corrupt file means every tool reads as
|
|
13
|
+
* fresh. That is the safe direction for availability (MCP keeps working) and the honest
|
|
14
|
+
* one for security (we do not claim to have verified something we could not read).
|
|
15
|
+
*/
|
|
16
|
+
import { promises as fs } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { projectDir } from "../memory/store.js";
|
|
19
|
+
const FILE = "mcp-trust.json";
|
|
20
|
+
export function trustPath(cwd) {
|
|
21
|
+
return join(projectDir(cwd), FILE);
|
|
22
|
+
}
|
|
23
|
+
/** Load the fingerprint record for a project. `{}` when absent or unreadable. */
|
|
24
|
+
export async function loadTrust(cwd) {
|
|
25
|
+
try {
|
|
26
|
+
const raw = await fs.readFile(trustPath(cwd), "utf8");
|
|
27
|
+
const data = JSON.parse(raw);
|
|
28
|
+
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
29
|
+
return {};
|
|
30
|
+
// Drop anything that is not a string→string pair rather than trusting the shape.
|
|
31
|
+
const out = {};
|
|
32
|
+
for (const [name, hash] of Object.entries(data)) {
|
|
33
|
+
if (typeof hash === "string" && hash)
|
|
34
|
+
out[name] = hash;
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Persist the fingerprint record. Best-effort: a failed write must not break MCP. */
|
|
43
|
+
export async function saveTrust(cwd, record) {
|
|
44
|
+
try {
|
|
45
|
+
await fs.mkdir(projectDir(cwd), { recursive: true });
|
|
46
|
+
// Sorted keys so the file diffs cleanly in git and a review shows what moved.
|
|
47
|
+
const sorted = Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
|
|
48
|
+
await fs.writeFile(trustPath(cwd), JSON.stringify(sorted, null, 2) + "\n", "utf8");
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=trustStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustStore.js","sourceRoot":"","sources":["../../src/mcp/trustStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,MAAM,IAAI,GAAG,gBAAgB,CAAC;AAE9B,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACxE,iFAAiF;QACjF,MAAM,GAAG,GAAgB,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,EAAE,CAAC;YAC3E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACzD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,MAAmB;IAC9D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,8EAA8E;QAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjG,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autoMemory.ts — Mindweave's cross-session memory store.
|
|
3
|
+
*
|
|
4
|
+
* This is the persistence layer for what Mindweave learns and is asked to remember:
|
|
5
|
+
* facts about the user, feedback on how to work, project context, and pointers
|
|
6
|
+
* to external systems. It is the personal-memory layer, SEPARATE from two things
|
|
7
|
+
* it must not duplicate:
|
|
8
|
+
* - MINDWEAVE.md — the project's own knowledge file (read each session).
|
|
9
|
+
* - the governor — standing rules / skills / forbidden paths.
|
|
10
|
+
*
|
|
11
|
+
* Layout (under the same per-project state dir as sessions and the governor):
|
|
12
|
+
* ~/.mindweave/projects/<slug>/memory/
|
|
13
|
+
* MEMORY.md — the index: one line per memory, ALWAYS loaded into the
|
|
14
|
+
* prompt. Capped, so it stays a cheap table of contents.
|
|
15
|
+
* <name>.md — one topic file per memory, with a small frontmatter
|
|
16
|
+
* header. Read on demand by the model (grep/read), not
|
|
17
|
+
* auto-loaded.
|
|
18
|
+
*
|
|
19
|
+
* The model writes here through the `save_memory` tool, which saves SILENTLY: the
|
|
20
|
+
* user asked not to be made to approve each one. (This comment used to say the tool
|
|
21
|
+
* "confirms with the user first", which stopped being true when the prompt was
|
|
22
|
+
* dropped — worth stating plainly, because "we ask first" is exactly the kind of
|
|
23
|
+
* assurance someone reads once and then relies on.) This module is the mechanism
|
|
24
|
+
* only — it does not decide WHAT is worth remembering; that is the model's
|
|
25
|
+
* judgment, guided by the prompt.
|
|
26
|
+
*
|
|
27
|
+
* Like store.ts, this is the CLIENT side of the eventual client/server split:
|
|
28
|
+
* the pure engine never calls in here. All writes are best-effort.
|
|
29
|
+
*/
|
|
30
|
+
import { promises as fs } from "node:fs";
|
|
31
|
+
import { join } from "node:path";
|
|
32
|
+
import { writeFileAtomic } from "../tools/atomicWrite.js";
|
|
33
|
+
import { projectDir } from "./store.js";
|
|
34
|
+
/** The closed set of memory types (mirrors the prompt's taxonomy). */
|
|
35
|
+
export const MEMORY_TYPES = ["user", "feedback", "project", "reference"];
|
|
36
|
+
export function isMemoryType(v) {
|
|
37
|
+
return typeof v === "string" && MEMORY_TYPES.includes(v);
|
|
38
|
+
}
|
|
39
|
+
export const MEMORY_INDEX = "MEMORY.md";
|
|
40
|
+
// Caps for the always-loaded index. Lines is the natural boundary; bytes catches
|
|
41
|
+
// a short index with very long lines. Past either, we load a prefix + a warning.
|
|
42
|
+
const MAX_INDEX_LINES = 200;
|
|
43
|
+
const MAX_INDEX_BYTES = 25_000;
|
|
44
|
+
/** The memory directory for a project (under its state dir). */
|
|
45
|
+
export function memoryDir(projectCwd) {
|
|
46
|
+
return join(projectDir(projectCwd), "memory");
|
|
47
|
+
}
|
|
48
|
+
/** Create the memory directory if absent, so the model never has to mkdir. */
|
|
49
|
+
export async function ensureMemoryDir(projectCwd) {
|
|
50
|
+
try {
|
|
51
|
+
await fs.mkdir(memoryDir(projectCwd), { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Best-effort: a real perms error surfaces when save_memory's write fails.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Read MEMORY.md for injection into the prompt, truncated to the caps. Returns
|
|
59
|
+
* "" when there is no index yet (the prompt then says memory is empty).
|
|
60
|
+
*/
|
|
61
|
+
export async function loadMemoryIndex(projectCwd) {
|
|
62
|
+
const dir = memoryDir(projectCwd);
|
|
63
|
+
let raw;
|
|
64
|
+
try {
|
|
65
|
+
raw = await fs.readFile(join(dir, MEMORY_INDEX), "utf8");
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return "";
|
|
69
|
+
}
|
|
70
|
+
return truncateIndex((await reconcileIndex(dir, raw)).trim());
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Give back a pointer to any memory that has one on disk but none in the index (pure
|
|
74
|
+
* except for reading the directory).
|
|
75
|
+
*
|
|
76
|
+
* This is what makes a lost index line survivable instead of fatal. The index is
|
|
77
|
+
* read-modify-write, so two Mindweave instances open on one project can each write an
|
|
78
|
+
* index that lacks the other's line. Serialising fixes that inside a process and cannot
|
|
79
|
+
* fix it between two, and the alternatives all rest on a guess: a retry budget large
|
|
80
|
+
* enough, or a lock file with a staleness timeout long enough. Both are timing, and
|
|
81
|
+
* timing is what this project has learned not to trust.
|
|
82
|
+
*
|
|
83
|
+
* Reconciling needs no timing at all. The topic FILE is the durable record and it is
|
|
84
|
+
* never the thing lost; the pointer is derived from it. So a dropped line costs
|
|
85
|
+
* visibility until the next read rather than forever, and the repair is deterministic:
|
|
86
|
+
* the same directory always produces the same index.
|
|
87
|
+
*
|
|
88
|
+
* The recovered line is rebuilt from the file's own frontmatter, which is why the hook
|
|
89
|
+
* comes back as its `description` rather than the original prose. That is a real loss of
|
|
90
|
+
* flavour and the right trade: a memory listed plainly is found, and one not listed at
|
|
91
|
+
* all may as well not exist.
|
|
92
|
+
*
|
|
93
|
+
* Costs one directory read per session when nothing is missing, which is the normal case.
|
|
94
|
+
*/
|
|
95
|
+
async function reconcileIndex(dir, index) {
|
|
96
|
+
let names;
|
|
97
|
+
try {
|
|
98
|
+
names = await fs.readdir(dir);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return index;
|
|
102
|
+
}
|
|
103
|
+
const orphans = names.filter((n) => n.endsWith(".md") && n !== MEMORY_INDEX && !indexLists(index, n));
|
|
104
|
+
if (orphans.length === 0)
|
|
105
|
+
return index;
|
|
106
|
+
let out = index;
|
|
107
|
+
for (const file of orphans.sort()) {
|
|
108
|
+
const meta = await frontmatterOf(join(dir, file));
|
|
109
|
+
// Skip a file we cannot read a name out of rather than listing it as "undefined":
|
|
110
|
+
// an unreadable entry in the always-loaded index is worse than a missing one.
|
|
111
|
+
if (!meta.name)
|
|
112
|
+
continue;
|
|
113
|
+
out = applyIndexUpsert(out, file, `- [${meta.name}](${file}) — ${meta.description || "recovered entry"}`);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
/** The `name:` and `description:` from a memory file's frontmatter. */
|
|
118
|
+
async function frontmatterOf(path) {
|
|
119
|
+
try {
|
|
120
|
+
const raw = await fs.readFile(path, "utf8");
|
|
121
|
+
return {
|
|
122
|
+
name: /^name:[ \t]*(.*)$/m.exec(raw)?.[1]?.trim() ?? "",
|
|
123
|
+
description: /^description:[ \t]*(.*)$/m.exec(raw)?.[1]?.trim() ?? "",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return { name: "", description: "" };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Line-cap first (clean boundary), then byte-cap at the last newline that fits. */
|
|
131
|
+
function truncateIndex(content) {
|
|
132
|
+
if (!content)
|
|
133
|
+
return "";
|
|
134
|
+
const lines = content.split("\n");
|
|
135
|
+
const overLines = lines.length > MAX_INDEX_LINES;
|
|
136
|
+
const overBytes = content.length > MAX_INDEX_BYTES;
|
|
137
|
+
if (!overLines && !overBytes)
|
|
138
|
+
return content;
|
|
139
|
+
let out = overLines ? lines.slice(0, MAX_INDEX_LINES).join("\n") : content;
|
|
140
|
+
if (out.length > MAX_INDEX_BYTES) {
|
|
141
|
+
const cut = out.lastIndexOf("\n", MAX_INDEX_BYTES);
|
|
142
|
+
out = out.slice(0, cut > 0 ? cut : MAX_INDEX_BYTES);
|
|
143
|
+
}
|
|
144
|
+
return `${out}\n\n> WARNING: ${MEMORY_INDEX} is too long and was only partly loaded. Keep each index entry to one short line; move detail into the topic files.`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Write a memory: the topic file (frontmatter + body) plus its pointer line in
|
|
148
|
+
* MEMORY.md. A memory whose name slugs to an existing file is an UPDATE — the
|
|
149
|
+
* topic file is overwritten and its index line replaced in place, so the model
|
|
150
|
+
* refining a fact never creates a duplicate.
|
|
151
|
+
*/
|
|
152
|
+
export async function saveMemory(projectCwd, m) {
|
|
153
|
+
await ensureMemoryDir(projectCwd);
|
|
154
|
+
const dir = memoryDir(projectCwd);
|
|
155
|
+
const slug = slugify(m.name);
|
|
156
|
+
const file = `${slug}.md`;
|
|
157
|
+
const path = join(dir, file);
|
|
158
|
+
const previous = await existingName(path);
|
|
159
|
+
const updated = previous !== null;
|
|
160
|
+
// Atomic: cross-session memory is the one thing here that OUTLIVES the session, so a
|
|
161
|
+
// torn write costs a fact the user expected to be remembered permanently.
|
|
162
|
+
await writeFileAtomic(path, renderMemoryFile(m));
|
|
163
|
+
await upsertIndexLine(dir, file, `- [${oneLine(m.name)}](${file}) — ${oneLine(m.indexLine)}`);
|
|
164
|
+
const replaced = previous && previous !== oneLine(m.name) ? previous : undefined;
|
|
165
|
+
return { name: m.name, file, updated, ...(replaced ? { replaced } : {}) };
|
|
166
|
+
}
|
|
167
|
+
/** The `name:` of the memory already at `path`, or null if there is no file there.
|
|
168
|
+
* Returns "" for a file we cannot parse, which still counts as "something was here". */
|
|
169
|
+
async function existingName(path) {
|
|
170
|
+
try {
|
|
171
|
+
const raw = await fs.readFile(path, "utf8");
|
|
172
|
+
return /^name:[ \t]*(.*)$/m.exec(raw)?.[1]?.trim() ?? "";
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function renderMemoryFile(m) {
|
|
179
|
+
// Flat key: value frontmatter, the same shape the governor and skills use.
|
|
180
|
+
// Values are flattened to ONE line: these are model-supplied strings going into a
|
|
181
|
+
// line-oriented format, so an embedded newline would start what parses as a new
|
|
182
|
+
// frontmatter key — a `description` ending in "\ntype: user" would silently
|
|
183
|
+
// re-file the memory. Nothing malicious is needed for this, just a pasted title.
|
|
184
|
+
return [
|
|
185
|
+
"---",
|
|
186
|
+
`name: ${oneLine(m.name)}`,
|
|
187
|
+
`description: ${oneLine(m.description)}`,
|
|
188
|
+
`type: ${m.type}`,
|
|
189
|
+
"---",
|
|
190
|
+
"",
|
|
191
|
+
m.body.trim(),
|
|
192
|
+
"",
|
|
193
|
+
].join("\n");
|
|
194
|
+
}
|
|
195
|
+
/** Collapse any newline/carriage return into a space, so a value stays one field. */
|
|
196
|
+
function oneLine(value) {
|
|
197
|
+
return value.replace(/[\r\n]+/g, " ").trim();
|
|
198
|
+
}
|
|
199
|
+
function escapeRegExp(s) {
|
|
200
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
201
|
+
}
|
|
202
|
+
/** Does this line point at `file`?
|
|
203
|
+
*
|
|
204
|
+
* Anchored to the start on purpose. The old test was `line.includes("(file.md)")`,
|
|
205
|
+
* which matched anywhere in the line — so an index entry whose prose referenced
|
|
206
|
+
* another memory ("supersedes (user-role.md)") was deleted when that other memory was
|
|
207
|
+
* next saved. Index lines are model-written prose about memories, so cross-references
|
|
208
|
+
* are expected content, and losing one silently removes a memory from the only listing
|
|
209
|
+
* that is always loaded. */
|
|
210
|
+
function pointsAt(line, file) {
|
|
211
|
+
return new RegExp(`^\\s*-\\s*\\[[^\\]]*\\]\\(${escapeRegExp(file)}\\)`).test(line);
|
|
212
|
+
}
|
|
213
|
+
/** Whether `index` already lists `file`. */
|
|
214
|
+
export function indexLists(index, file) {
|
|
215
|
+
return index.split("\n").some((l) => pointsAt(l, file));
|
|
216
|
+
}
|
|
217
|
+
/** Add or replace the pointer line for `file` in an index's text (pure). */
|
|
218
|
+
export function applyIndexUpsert(current, file, line) {
|
|
219
|
+
if (!current.trim())
|
|
220
|
+
return `# Memory Index\n\n${line}\n`;
|
|
221
|
+
const kept = current
|
|
222
|
+
.split("\n")
|
|
223
|
+
.filter((l) => !pointsAt(l, file))
|
|
224
|
+
.join("\n")
|
|
225
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
226
|
+
.trimEnd();
|
|
227
|
+
return `${kept}\n${line}\n`;
|
|
228
|
+
}
|
|
229
|
+
/** How many times to re-attempt a write the filesystem refused. Bounded so two
|
|
230
|
+
* instances colliding cannot spin. */
|
|
231
|
+
const INDEX_WRITE_ATTEMPTS = 4;
|
|
232
|
+
/**
|
|
233
|
+
* Add or replace the index line that points at `file`, keeping MEMORY.md a flat list.
|
|
234
|
+
*
|
|
235
|
+
* Read, edit, write — which is a lost update waiting to happen, and the consequence is
|
|
236
|
+
* out of proportion to the window. Two instances saving at once both read the same
|
|
237
|
+
* index, and the second write drops the first one's line. The topic FILE survives, so
|
|
238
|
+
* nothing looks broken, but MEMORY.md is the only listing that is ever loaded and
|
|
239
|
+
* nothing rebuilds it: that memory is invisible from then on, permanently.
|
|
240
|
+
*
|
|
241
|
+
* So the write is verified rather than assumed. After writing we re-read and check our
|
|
242
|
+
* own pointer is actually there; if another writer landed on top of us, we re-read
|
|
243
|
+
* their content, re-apply our line to it, and write again. Each attempt starts from
|
|
244
|
+
* whatever is on disk NOW, so the two writers converge on an index containing both
|
|
245
|
+
* lines instead of racing to overwrite each other.
|
|
246
|
+
*
|
|
247
|
+
* Atomic writes (which this already uses) solve a different problem — they stop a
|
|
248
|
+
* reader seeing a half-written file. They cannot help here, because both writes are
|
|
249
|
+
* individually complete and simply describe different pasts.
|
|
250
|
+
*/
|
|
251
|
+
async function upsertIndexLine(dir, file, line) {
|
|
252
|
+
return serializeIndexWrite(() => upsertIndexLineNow(dir, file, line));
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Index edits from THIS process, one at a time.
|
|
256
|
+
*
|
|
257
|
+
* Two writers need two different answers and this is the half that can be made
|
|
258
|
+
* airtight. Inside one instance the collisions are ordinary: the engine runs
|
|
259
|
+
* concurrency-safe tools in parallel, so several `save_memory` calls can be in flight
|
|
260
|
+
* together. Read-modify-write under that loses lines, and no amount of retrying fixes
|
|
261
|
+
* it — measured at twelve concurrent saves, ten were lost, because every writer retried
|
|
262
|
+
* in step with the others and collided again.
|
|
263
|
+
*
|
|
264
|
+
* Serialising removes the race rather than narrowing it: each edit reads an index that
|
|
265
|
+
* already contains every edit before it. It also removes the Windows EPERM this
|
|
266
|
+
* uncovered, where several overlapping atomic writes fought over renaming onto the same
|
|
267
|
+
* destination.
|
|
268
|
+
*
|
|
269
|
+
* Cross-PROCESS contention (a second Mindweave open on the same project) is out of
|
|
270
|
+
* reach of a queue, and that is what the verify-and-retry below is for. The two are
|
|
271
|
+
* complementary, not alternatives.
|
|
272
|
+
*/
|
|
273
|
+
let indexWrites = Promise.resolve();
|
|
274
|
+
function serializeIndexWrite(run) {
|
|
275
|
+
// Chained off settled OR failed, so one failing write cannot wedge the queue for the
|
|
276
|
+
// rest of the session.
|
|
277
|
+
const next = indexWrites.then(run, run);
|
|
278
|
+
indexWrites = next.catch(() => undefined);
|
|
279
|
+
return next;
|
|
280
|
+
}
|
|
281
|
+
async function upsertIndexLineNow(dir, file, line) {
|
|
282
|
+
const indexPath = join(dir, MEMORY_INDEX);
|
|
283
|
+
const read = async () => {
|
|
284
|
+
try {
|
|
285
|
+
return await fs.readFile(indexPath, "utf8");
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return ""; // no index yet
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
// Retried only for a FAILED write, never to win a race. Windows refuses a rename
|
|
292
|
+
// while another process holds the destination, so two instances landing together
|
|
293
|
+
// produce EPERM; starting over from whatever is on disk now clears it.
|
|
294
|
+
//
|
|
295
|
+
// There is deliberately no "did my line survive" check here. One was written, and
|
|
296
|
+
// measured: across two processes it still lost 3 of 12, because both sides retry into
|
|
297
|
+
// each other. Convergence by retrying is a guess about budgets, and the reconcile on
|
|
298
|
+
// read makes a dropped line recoverable without guessing anything.
|
|
299
|
+
for (let attempt = 1; attempt <= INDEX_WRITE_ATTEMPTS; attempt++) {
|
|
300
|
+
try {
|
|
301
|
+
await writeFileAtomic(indexPath, applyIndexUpsert(await read(), file, line));
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
if (attempt === INDEX_WRITE_ATTEMPTS)
|
|
306
|
+
throw error;
|
|
307
|
+
await settle(attempt);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* A short, jittered pause between attempts.
|
|
313
|
+
*
|
|
314
|
+
* Correctness comes from re-reading and re-checking, not from this: with no pause the
|
|
315
|
+
* loop is still right, it just collides again immediately. The jitter is what stops two
|
|
316
|
+
* instances retrying in lockstep forever, which is the one way a bounded retry can burn
|
|
317
|
+
* its whole budget without either side making progress.
|
|
318
|
+
*/
|
|
319
|
+
function settle(attempt) {
|
|
320
|
+
const ms = Math.round(15 * attempt * (0.5 + Math.random()));
|
|
321
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
322
|
+
}
|
|
323
|
+
/** A filesystem-safe slug from a memory name. Falls back to "memory" if empty. */
|
|
324
|
+
export function slugify(name) {
|
|
325
|
+
return (name
|
|
326
|
+
.toLowerCase()
|
|
327
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
328
|
+
.replace(/^-+|-+$/g, "")
|
|
329
|
+
.slice(0, 60) || "memory");
|
|
330
|
+
}
|
|
331
|
+
async function exists(path) {
|
|
332
|
+
try {
|
|
333
|
+
await fs.stat(path);
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=autoMemory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoMemory.js","sourceRoot":"","sources":["../../src/memory/autoMemory.ts"],"names":[],"mappings":"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"}
|