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,119 @@
|
|
|
1
|
+
/** Longest resource description we pass on, mirroring the tool-description cap. */
|
|
2
|
+
export const MAX_RESOURCE_DESCRIPTION = 512;
|
|
3
|
+
/** How many resources one listing may return, before it is a context problem itself. */
|
|
4
|
+
export const MAX_RESOURCES_LISTED = 200;
|
|
5
|
+
/** Does this server say it has resources at all? */
|
|
6
|
+
export function hasResources(capabilities) {
|
|
7
|
+
return Boolean(capabilities?.resources);
|
|
8
|
+
}
|
|
9
|
+
function text(value, max = MAX_RESOURCE_DESCRIPTION) {
|
|
10
|
+
const s = typeof value === "string" ? value.trim() : "";
|
|
11
|
+
return s.length > max ? s.slice(0, max - 1) + "…" : s;
|
|
12
|
+
}
|
|
13
|
+
/** Parse a `resources/list` payload, dropping entries that cannot be used (pure). */
|
|
14
|
+
export function parseResourceList(server, result) {
|
|
15
|
+
const raw = result?.resources;
|
|
16
|
+
if (!Array.isArray(raw))
|
|
17
|
+
return [];
|
|
18
|
+
const out = [];
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
for (const item of raw) {
|
|
21
|
+
const r = item;
|
|
22
|
+
const uri = typeof r?.uri === "string" ? r.uri.trim() : "";
|
|
23
|
+
// A resource with no URI cannot be read, so it is not a resource.
|
|
24
|
+
if (!uri || seen.has(uri))
|
|
25
|
+
continue;
|
|
26
|
+
seen.add(uri);
|
|
27
|
+
out.push({ server, uri, name: text(r?.name, 128) || uri, description: text(r?.description), mimeType: text(r?.mimeType, 64) });
|
|
28
|
+
}
|
|
29
|
+
return sortResources(out);
|
|
30
|
+
}
|
|
31
|
+
/** Parse a `resources/templates/list` payload (pure). */
|
|
32
|
+
export function parseTemplateList(server, result) {
|
|
33
|
+
const raw = result?.resourceTemplates;
|
|
34
|
+
if (!Array.isArray(raw))
|
|
35
|
+
return [];
|
|
36
|
+
const out = [];
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
for (const item of raw) {
|
|
39
|
+
const r = item;
|
|
40
|
+
const uriTemplate = typeof r?.uriTemplate === "string" ? r.uriTemplate.trim() : "";
|
|
41
|
+
if (!uriTemplate || seen.has(uriTemplate))
|
|
42
|
+
continue;
|
|
43
|
+
seen.add(uriTemplate);
|
|
44
|
+
out.push({
|
|
45
|
+
server,
|
|
46
|
+
uriTemplate,
|
|
47
|
+
name: text(r?.name, 128) || uriTemplate,
|
|
48
|
+
description: text(r?.description),
|
|
49
|
+
mimeType: text(r?.mimeType, 64),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return [...out].sort((a, b) => a.server.localeCompare(b.server) || a.uriTemplate.localeCompare(b.uriTemplate));
|
|
53
|
+
}
|
|
54
|
+
/** Stable order, for the same reason the tool catalog has one: readable, diffable output. */
|
|
55
|
+
export function sortResources(resources) {
|
|
56
|
+
return [...resources].sort((a, b) => a.server.localeCompare(b.server) || a.uri.localeCompare(b.uri));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parse a `resources/read` payload into blocks (pure).
|
|
60
|
+
*
|
|
61
|
+
* Note the shape difference, which is easy to get wrong: `tools/call` returns `content`
|
|
62
|
+
* with typed blocks, while `resources/read` returns `contents` with entries that carry
|
|
63
|
+
* either `text` or `blob` and no `type` at all. Reusing the tool parser here would
|
|
64
|
+
* silently yield nothing.
|
|
65
|
+
*/
|
|
66
|
+
export function parseResourceRead(result) {
|
|
67
|
+
const raw = result?.contents;
|
|
68
|
+
if (!Array.isArray(raw))
|
|
69
|
+
return [];
|
|
70
|
+
const blocks = [];
|
|
71
|
+
for (const item of raw) {
|
|
72
|
+
const c = item;
|
|
73
|
+
if (!c || typeof c !== "object")
|
|
74
|
+
continue;
|
|
75
|
+
const mime = typeof c.mimeType === "string" ? c.mimeType : "";
|
|
76
|
+
if (typeof c.text === "string" && c.text)
|
|
77
|
+
blocks.push({ kind: "text", text: c.text });
|
|
78
|
+
else if (typeof c.blob === "string" && c.blob)
|
|
79
|
+
blocks.push({ kind: "binary", mime: mime || "application/octet-stream", base64: c.blob });
|
|
80
|
+
}
|
|
81
|
+
return blocks;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Render a listing for the model (pure).
|
|
85
|
+
*
|
|
86
|
+
* The URI is what it needs to pass back, so the URI leads. Templates are marked as such
|
|
87
|
+
* and shown with their placeholders intact, because a model that mistakes a template for
|
|
88
|
+
* a real URI will read `logs://{date}` and get an error it cannot interpret.
|
|
89
|
+
*/
|
|
90
|
+
export function renderResourceList(resources, templates) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
if (resources.length > 0) {
|
|
93
|
+
lines.push("Resources (read one with read_mcp_resource):");
|
|
94
|
+
for (const r of resources.slice(0, MAX_RESOURCES_LISTED)) {
|
|
95
|
+
const bits = [r.name !== r.uri ? r.name : "", r.description, r.mimeType].filter(Boolean).join(" — ");
|
|
96
|
+
lines.push(`- [${r.server}] ${r.uri}${bits ? ` — ${bits}` : ""}`);
|
|
97
|
+
}
|
|
98
|
+
if (resources.length > MAX_RESOURCES_LISTED) {
|
|
99
|
+
lines.push(` … and ${resources.length - MAX_RESOURCES_LISTED} more (narrow with the \`server\` argument).`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (templates.length > 0) {
|
|
103
|
+
if (lines.length > 0)
|
|
104
|
+
lines.push("");
|
|
105
|
+
lines.push("Templates (fill in the {placeholders} to build a URI, then read it):");
|
|
106
|
+
// Capped for the same reason as the resources above, which this branch was missing:
|
|
107
|
+
// the length is chosen by a third party, and an uncapped external payload is the
|
|
108
|
+
// failure mode MCP has already produced here once.
|
|
109
|
+
for (const t of templates.slice(0, MAX_RESOURCES_LISTED)) {
|
|
110
|
+
const bits = [t.name !== t.uriTemplate ? t.name : "", t.description].filter(Boolean).join(" — ");
|
|
111
|
+
lines.push(`- [${t.server}] ${t.uriTemplate}${bits ? ` — ${bits}` : ""}`);
|
|
112
|
+
}
|
|
113
|
+
if (templates.length > MAX_RESOURCES_LISTED) {
|
|
114
|
+
lines.push(` … and ${templates.length - MAX_RESOURCES_LISTED} more (narrow with the \`server\` argument).`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return lines.join("\n");
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resultStore.ts — what to do with an MCP result that is too big, or is not text.
|
|
3
|
+
*
|
|
4
|
+
* A `tools/call` result goes straight into the model's context, and its size is chosen
|
|
5
|
+
* by a third party. Before this file existed there was no ceiling at all: a server that
|
|
6
|
+
* answered a query with two megabytes of JSON put two megabytes of JSON in the prompt,
|
|
7
|
+
* and a server that returned an image put a base64 blob there instead — bytes the model
|
|
8
|
+
* cannot see and pays for anyway. One such call could exhaust a turn.
|
|
9
|
+
*
|
|
10
|
+
* So oversized and binary payloads go to a file and the model gets a POINTER: a head
|
|
11
|
+
* excerpt (for text), the path, the size, and what to do next. That is strictly more
|
|
12
|
+
* useful than a truncation, because nothing is actually lost — the model can read the
|
|
13
|
+
* part it needs with the tools it already has, or run a command over the file, instead
|
|
14
|
+
* of being handed a fragment and no way to reach the rest.
|
|
15
|
+
*
|
|
16
|
+
* Files land in the project's state dir alongside `mcp-trust.json`, not in the project
|
|
17
|
+
* itself: this is scratch output from an external server, and dropping it into someone's
|
|
18
|
+
* working tree would show up in their `git status`.
|
|
19
|
+
*
|
|
20
|
+
* The decisions are pure and tested; only `spill` and `sweepOldResults` touch disk.
|
|
21
|
+
*/
|
|
22
|
+
import { promises as fs } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { projectDir } from "../memory/store.js";
|
|
25
|
+
/**
|
|
26
|
+
* Longest result text we will put in the prompt, in characters.
|
|
27
|
+
*
|
|
28
|
+
* ~7K tokens at the 3.5-chars/token proxy used everywhere else in this codebase. Chosen
|
|
29
|
+
* to be generous for a legitimately large answer (a long file listing, a verbose API
|
|
30
|
+
* response) while still being a small fraction of any model's window, since the result
|
|
31
|
+
* arrives mid-turn on top of everything else already in context.
|
|
32
|
+
*/
|
|
33
|
+
export const MAX_RESULT_CHARS = 24_000;
|
|
34
|
+
/** How much of an oversized result to show inline before the pointer. */
|
|
35
|
+
export const RESULT_HEAD_CHARS = 2_000;
|
|
36
|
+
/** Delete spilled results older than this. They are scratch, not history. */
|
|
37
|
+
export const RESULT_TTL_MS = 7 * 24 * 60 * 60 * 1_000;
|
|
38
|
+
/** Where a project's spilled MCP results live. */
|
|
39
|
+
export function resultsDir(cwd) {
|
|
40
|
+
return join(projectDir(cwd), "mcp-results");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* File extension for a mime type (pure).
|
|
44
|
+
*
|
|
45
|
+
* The point is that the file opens with native tooling when someone double-clicks it —
|
|
46
|
+
* a `.png` rather than a `.bin`. Unknown types fall back to the subtype when it looks
|
|
47
|
+
* like an extension, because `application/x-parquet` is more useful as `.parquet` than
|
|
48
|
+
* as `.bin`.
|
|
49
|
+
*/
|
|
50
|
+
export function extensionForMime(mime) {
|
|
51
|
+
const type = (mime || "").split(";")[0].trim().toLowerCase();
|
|
52
|
+
const known = {
|
|
53
|
+
"text/plain": "txt",
|
|
54
|
+
"text/markdown": "md",
|
|
55
|
+
"text/html": "html",
|
|
56
|
+
"text/csv": "csv",
|
|
57
|
+
"text/xml": "xml",
|
|
58
|
+
"application/json": "json",
|
|
59
|
+
"application/xml": "xml",
|
|
60
|
+
"application/pdf": "pdf",
|
|
61
|
+
"application/zip": "zip",
|
|
62
|
+
"application/octet-stream": "bin",
|
|
63
|
+
"image/png": "png",
|
|
64
|
+
"image/jpeg": "jpg",
|
|
65
|
+
"image/gif": "gif",
|
|
66
|
+
"image/webp": "webp",
|
|
67
|
+
"image/svg+xml": "svg",
|
|
68
|
+
"audio/wav": "wav",
|
|
69
|
+
"audio/mpeg": "mp3",
|
|
70
|
+
"audio/ogg": "ogg",
|
|
71
|
+
"video/mp4": "mp4",
|
|
72
|
+
};
|
|
73
|
+
if (known[type])
|
|
74
|
+
return known[type];
|
|
75
|
+
const subtype = type.split("/")[1] ?? "";
|
|
76
|
+
const cleaned = subtype.replace(/^x[-.]/, "").replace(/\+.*$/, "").replace(/[^a-z0-9]/g, "");
|
|
77
|
+
return cleaned && cleaned.length <= 8 ? cleaned : "bin";
|
|
78
|
+
}
|
|
79
|
+
/** A filesystem-safe fragment of a server or tool name (pure). */
|
|
80
|
+
export function safeSlug(value) {
|
|
81
|
+
return (value || "x").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 32) || "x";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build the filename for one spilled result (pure).
|
|
85
|
+
*
|
|
86
|
+
* Named after what produced it, so a directory of these is readable rather than a pile
|
|
87
|
+
* of hashes. The stamp keeps two calls to the same tool from overwriting each other.
|
|
88
|
+
*/
|
|
89
|
+
export function spillFileName(server, tool, mime, stamp, nonce) {
|
|
90
|
+
return `${safeSlug(server)}-${safeSlug(tool)}-${stamp}-${nonce}.${extensionForMime(mime)}`;
|
|
91
|
+
}
|
|
92
|
+
/** Human byte count for the pointer line (pure). */
|
|
93
|
+
export function humanSize(bytes) {
|
|
94
|
+
if (bytes < 1_024)
|
|
95
|
+
return `${bytes} B`;
|
|
96
|
+
if (bytes < 1_024 * 1_024)
|
|
97
|
+
return `${(bytes / 1_024).toFixed(1)} KB`;
|
|
98
|
+
return `${(bytes / (1_024 * 1_024)).toFixed(1)} MB`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Is this text too big to hand to the model whole (pure)?
|
|
102
|
+
*
|
|
103
|
+
* Its own function so the threshold is testable and so callers cannot each invent their
|
|
104
|
+
* own idea of "too big".
|
|
105
|
+
*/
|
|
106
|
+
export function isOversized(text, max = MAX_RESULT_CHARS) {
|
|
107
|
+
return text.length > max;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* What the model sees in place of an oversized result (pure).
|
|
111
|
+
*
|
|
112
|
+
* Deliberately a beginning plus instructions, not a middle-out truncation: the head of a
|
|
113
|
+
* result is nearly always the part that says what it is, and the model needs to know
|
|
114
|
+
* both that there is more and exactly how to get it. Saying "truncated" without a path
|
|
115
|
+
* is how a model ends up guessing at content it could have read.
|
|
116
|
+
*/
|
|
117
|
+
export function oversizedPointer(text, path, head = RESULT_HEAD_CHARS) {
|
|
118
|
+
return (`${text.slice(0, head)}\n\n` +
|
|
119
|
+
`[Result truncated here — it was ${humanSize(Buffer.byteLength(text, "utf8"))} ` +
|
|
120
|
+
`(${text.length} characters) and the whole of it is saved at:\n${path}\n` +
|
|
121
|
+
`Nothing was lost: read that file (or grep it) for the parts you need.]`);
|
|
122
|
+
}
|
|
123
|
+
/** What the model sees in place of a binary block (pure). */
|
|
124
|
+
export function binaryPointer(mime, bytes, path) {
|
|
125
|
+
return (`[${mime || "binary"} content, ${humanSize(bytes)}, saved to:\n${path}\n` +
|
|
126
|
+
`It is binary, so do not try to read it as text — pass the path to a tool that ` +
|
|
127
|
+
`handles that format, or give it to the user.]`);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Write one payload to the results dir and return its path.
|
|
131
|
+
*
|
|
132
|
+
* Best-effort: a failed write returns null and the caller falls back to describing the
|
|
133
|
+
* content rather than storing it. A server's oversized answer must not be able to fail
|
|
134
|
+
* a turn through our own disk handling.
|
|
135
|
+
*/
|
|
136
|
+
export async function spill(cwd, server, tool, mime, body) {
|
|
137
|
+
try {
|
|
138
|
+
const dir = resultsDir(cwd);
|
|
139
|
+
await fs.mkdir(dir, { recursive: true });
|
|
140
|
+
const nonce = Math.random().toString(36).slice(2, 8);
|
|
141
|
+
const path = join(dir, spillFileName(server, tool, mime, Date.now(), nonce));
|
|
142
|
+
await fs.writeFile(path, body);
|
|
143
|
+
return path;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Delete spilled results past their TTL.
|
|
151
|
+
*
|
|
152
|
+
* Called once per session rather than on a timer: this directory only grows when a
|
|
153
|
+
* server returns something large, so sweeping on the way in is enough, and it keeps the
|
|
154
|
+
* whole mechanism free of background work.
|
|
155
|
+
*/
|
|
156
|
+
export async function sweepOldResults(cwd, ttlMs = RESULT_TTL_MS, now = Date.now()) {
|
|
157
|
+
try {
|
|
158
|
+
const dir = resultsDir(cwd);
|
|
159
|
+
const names = await fs.readdir(dir);
|
|
160
|
+
let removed = 0;
|
|
161
|
+
for (const name of names) {
|
|
162
|
+
const path = join(dir, name);
|
|
163
|
+
try {
|
|
164
|
+
const stat = await fs.stat(path);
|
|
165
|
+
if (now - stat.mtimeMs > ttlMs) {
|
|
166
|
+
await fs.rm(path, { force: true });
|
|
167
|
+
removed++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Raced with something else, or not ours to delete. Skip it.
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return removed;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return 0; // no directory yet, which is the normal case
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=resultStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resultStore.js","sourceRoot":"","sources":["../../src/mcp/resultStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* subscriptions.ts — staying current with a server that changes underneath us.
|
|
3
|
+
*
|
|
4
|
+
* A server's tool list is not fixed. It can gain tools when a user authenticates, lose
|
|
5
|
+
* them when a backend goes away, or change entirely on a redeploy. Before 2026-07-28 a
|
|
6
|
+
* client learned about that through `resources/subscribe` and an always-on GET channel;
|
|
7
|
+
* both are gone. In their place is `subscriptions/listen`: ONE long-lived stream that
|
|
8
|
+
* the client opts into by naming the change types it cares about.
|
|
9
|
+
*
|
|
10
|
+
* Opting in is the whole design point. A client that subscribes to everything pays for
|
|
11
|
+
* traffic it will ignore, and — more to the point here — every `toolsListChanged` we
|
|
12
|
+
* accept means re-fetching a catalog and rewriting the tool list mid-session, which
|
|
13
|
+
* costs a prompt-cache prefix. So we ask for exactly what we can act on today.
|
|
14
|
+
*
|
|
15
|
+
* The decisions are pure so the policy is testable without a server; `connection.ts`
|
|
16
|
+
* owns the plumbing.
|
|
17
|
+
*/
|
|
18
|
+
/** Change types the 2026-07-28 spec defines for `subscriptions/listen`. */
|
|
19
|
+
export const SUBSCRIPTION_TYPES = ["toolsListChanged", "promptsListChanged", "resourcesListChanged", "resourceSubscriptions"];
|
|
20
|
+
/** The notification a server sends when its tool list moved. */
|
|
21
|
+
export const TOOLS_CHANGED = "notifications/tools/list_changed";
|
|
22
|
+
/**
|
|
23
|
+
* Which change types to request from a server (pure).
|
|
24
|
+
*
|
|
25
|
+
* Only what we can act on, and only where the server says the list can move. All three
|
|
26
|
+
* are actionable now: a changed tool list rebuilds the catalog (and re-runs the trust
|
|
27
|
+
* check), a changed prompt list rebuilds the slash commands, and a changed resource list
|
|
28
|
+
* invalidates a cached listing. `resourceSubscriptions` is still not requested — that is
|
|
29
|
+
* per-resource content watching, which nothing in the agent consumes.
|
|
30
|
+
*
|
|
31
|
+
* A server that advertises none of them gets no subscription at all rather than an empty
|
|
32
|
+
* one, because an empty `subscriptions/listen` still costs a held-open stream.
|
|
33
|
+
*/
|
|
34
|
+
export function subscriptionsFor(capabilities) {
|
|
35
|
+
const wanted = [];
|
|
36
|
+
// `listChanged: false` is a server saying its list is fixed. Believe it.
|
|
37
|
+
const declares = (key) => {
|
|
38
|
+
const cap = capabilities?.[key];
|
|
39
|
+
return Boolean(cap) && cap.listChanged !== false;
|
|
40
|
+
};
|
|
41
|
+
if (declares("tools"))
|
|
42
|
+
wanted.push("toolsListChanged");
|
|
43
|
+
if (declares("prompts"))
|
|
44
|
+
wanted.push("promptsListChanged");
|
|
45
|
+
if (declares("resources"))
|
|
46
|
+
wanted.push("resourcesListChanged");
|
|
47
|
+
return wanted;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Does this notification mean "your tool catalog is stale" (pure)?
|
|
51
|
+
*
|
|
52
|
+
* Matched loosely on purpose. The method name is spelled slightly differently across
|
|
53
|
+
* revisions and implementations (`notifications/tools/list_changed` vs
|
|
54
|
+
* `toolsListChanged`), and the cost of missing one is a permanently stale catalog,
|
|
55
|
+
* while the cost of an extra match is one wasted `tools/list`.
|
|
56
|
+
*/
|
|
57
|
+
export function isToolsChanged(method) {
|
|
58
|
+
return isListChanged(method, "tool");
|
|
59
|
+
}
|
|
60
|
+
/** Does this notification mean "your prompt list is stale" (pure)? */
|
|
61
|
+
export function isPromptsChanged(method) {
|
|
62
|
+
return isListChanged(method, "prompt");
|
|
63
|
+
}
|
|
64
|
+
/** Does this notification mean "your resource list is stale" (pure)? */
|
|
65
|
+
export function isResourcesChanged(method) {
|
|
66
|
+
// `resources/updated` is a different thing — one resource's CONTENT changed — and we
|
|
67
|
+
// hold no per-resource cache to invalidate, so it is deliberately not matched here.
|
|
68
|
+
return isListChanged(method, "resource");
|
|
69
|
+
}
|
|
70
|
+
function isListChanged(method, subject) {
|
|
71
|
+
const m = method.toLowerCase();
|
|
72
|
+
return m.includes(subject) && (m.includes("list_changed") || m.includes("listchanged"));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=subscriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../../src/mcp/subscriptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,uBAAuB,CAAU,CAAC;AAGvI,gEAAgE;AAChE,MAAM,CAAC,MAAM,aAAa,GAAG,kCAAkC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAqC;IACpE,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,yEAAyE;IACzE,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAW,EAAE;QACxC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC,GAAG,CAA0C,CAAC;QACzE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,GAAI,CAAC,WAAW,KAAK,KAAK,CAAC;IACpD,CAAC,CAAC;IACF,IAAI,QAAQ,CAAC,OAAO,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACvD,IAAI,QAAQ,CAAC,SAAS,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3D,IAAI,QAAQ,CAAC,WAAW,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,qFAAqF;IACrF,oFAAoF;IACpF,OAAO,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,aAAa,CAAC,MAAc,EAAE,OAAe;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAC1F,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* headerValue.ts — putting an arbitrary body value into an HTTP header value.
|
|
3
|
+
*
|
|
4
|
+
* Streamable HTTP mirrors selected body fields into headers so intermediaries can route
|
|
5
|
+
* without parsing the body. Those fields are written by third parties and are not
|
|
6
|
+
* constrained to anything a header can carry: a tool name is only SHOULD-constrained to
|
|
7
|
+
* safe characters, a resource URI is not constrained at all, and a tool argument can be
|
|
8
|
+
* any string a user typed. The spec's answer is a sentinel encoding rather than a
|
|
9
|
+
* rejection, so this is the one place that decides when to reach for it.
|
|
10
|
+
*
|
|
11
|
+
* Its own module because two unrelated callers need it — the transport, for `Mcp-Name`,
|
|
12
|
+
* and the catalog layer, for `Mcp-Param-*` — and the second should not have to import a
|
|
13
|
+
* fetch client to encode a string.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* A value that needs no rescuing: visible ASCII, space or tab only (RFC 9110 field
|
|
17
|
+
* values), no leading or trailing whitespace, and nothing that could be mistaken for an
|
|
18
|
+
* already-encoded value.
|
|
19
|
+
*/
|
|
20
|
+
function isHeaderSafe(value) {
|
|
21
|
+
if (/[^\t\x20-\x7e]/.test(value))
|
|
22
|
+
return false;
|
|
23
|
+
if (/^[\t\x20]|[\t\x20]$/.test(value))
|
|
24
|
+
return false;
|
|
25
|
+
return !/^=\?base64\?[\s\S]*\?=$/.test(value);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Mirror one body value into a header value (pure).
|
|
29
|
+
*
|
|
30
|
+
* Anything outside the safe set travels in the spec's sentinel `=?base64?...?=`, which
|
|
31
|
+
* servers decode before comparing the header against the body. A plain value that merely
|
|
32
|
+
* LOOKS like the sentinel is encoded too: otherwise a server would decode a value the
|
|
33
|
+
* client never encoded, compare the wrong bytes, and reject a legitimate request.
|
|
34
|
+
*/
|
|
35
|
+
export function encodeHeaderValue(value) {
|
|
36
|
+
if (isHeaderSafe(value))
|
|
37
|
+
return value;
|
|
38
|
+
return `=?base64?${Buffer.from(value, "utf8").toString("base64")}?=`;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=headerValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerValue.js","sourceRoot":"","sources":["../../../src/mcp/transport/headerValue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,YAAY,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;AACvE,CAAC"}
|