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,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* readFile.ts — Mindweave's first tool: read a text file.
|
|
3
|
+
*
|
|
4
|
+
* The smallest useful, fully read-only capability — it proves the whole
|
|
5
|
+
* tool loop end-to-end without any risk of changing the user's files.
|
|
6
|
+
*
|
|
7
|
+
* Design borrows the proven essentials from mature agents (line-numbered
|
|
8
|
+
* output, optional offset/limit range, a size cap that nudges toward ranged
|
|
9
|
+
* reads, binary refusal, a friendly not-found). It deliberately does NOT carry
|
|
10
|
+
* "read surgically / how to investigate" guidance — that is the model's
|
|
11
|
+
* judgment, not the tool's job.
|
|
12
|
+
*/
|
|
13
|
+
import { promises as fs } from "node:fs";
|
|
14
|
+
import { foreignAgentReason, protectedPathReason } from "./guard.js";
|
|
15
|
+
import { requestAgentDataAccess } from "./approval.js";
|
|
16
|
+
import { relativize, resolvePath, nextTouch, touch, markScope } from "./paths.js";
|
|
17
|
+
import { addFocus } from "./focus.js";
|
|
18
|
+
import { chassisForPath } from "./chassisMux.js";
|
|
19
|
+
import { renderOutlineEntries } from "./codeIntel.js";
|
|
20
|
+
import { estimateTokens } from "../memory/compaction.js";
|
|
21
|
+
import { failQuietly } from "./results.js";
|
|
22
|
+
// Caps protect the model's context window, not the disk. They are deliberately
|
|
23
|
+
// MODEL-AGNOSTIC fixed defaults, not derived from any one model's context window —
|
|
24
|
+
// so they stay correct as other models are added.
|
|
25
|
+
// - MAX_BYTES: refuse a whole-file read of a file this large; use a range.
|
|
26
|
+
// - MAX_LINES: a default read returns at most this many lines (the model pages
|
|
27
|
+
// with offset for more). This is the big BYOK-cost lever — a 5000-line file
|
|
28
|
+
// costs one bounded read, not 5000 lines every time.
|
|
29
|
+
// - MAX_OUTPUT_CHARS: final safety truncation (e.g. minified long lines).
|
|
30
|
+
const MAX_BYTES = 256 * 1024;
|
|
31
|
+
const MAX_LINES = envInt("MINDWEAVE_READ_MAX_LINES", 2000);
|
|
32
|
+
const MAX_OUTPUT_CHARS = 120_000;
|
|
33
|
+
/**
|
|
34
|
+
* Most files one call may read.
|
|
35
|
+
*
|
|
36
|
+
* The point of the list is to collapse round trips, not to let a single call pull an
|
|
37
|
+
* unbounded amount of the repository into context. Ten covers every batch a real task
|
|
38
|
+
* asks for; past that the model should be searching, not reading.
|
|
39
|
+
*/
|
|
40
|
+
const MAX_FILES = 10;
|
|
41
|
+
/**
|
|
42
|
+
* Token budget for a WHOLE-file read, past which the file's structure is returned
|
|
43
|
+
* instead of its contents.
|
|
44
|
+
*
|
|
45
|
+
* The habit this exists to break: answering "where is this handled?" by reading a
|
|
46
|
+
* 1,700-line file. That costs its full length on the request that fetches it AND on
|
|
47
|
+
* every request afterwards for the rest of the turn, so one careless read is re-billed
|
|
48
|
+
* five or ten times. The usual answer is a hard token cap that refuses the read; this
|
|
49
|
+
* one does better, because the code map already knows the file's shape.
|
|
50
|
+
*
|
|
51
|
+
* ~8,000 tokens is roughly 700 lines of code. Below that a whole read is a reasonable
|
|
52
|
+
* way to understand a file. Above it, the model almost never wants all of it — it wants
|
|
53
|
+
* one function — and an outline plus a ranged follow-up costs a fraction of the same
|
|
54
|
+
* answer. A range is NEVER budgeted: asking for specific lines is already the careful
|
|
55
|
+
* behaviour, and second-guessing it would just cost a round trip.
|
|
56
|
+
*/
|
|
57
|
+
const WHOLE_READ_TOKEN_BUDGET = envInt("MINDWEAVE_WHOLE_READ_TOKENS", 8_000);
|
|
58
|
+
// Returned instead of re-sending identical content when a file is unchanged
|
|
59
|
+
// since the model last read it — pure token savings on a re-read.
|
|
60
|
+
const FILE_UNCHANGED = "This file is unchanged since you last read it in this conversation — the " +
|
|
61
|
+
"earlier read is still current, use that instead of re-reading.";
|
|
62
|
+
export const readFile = {
|
|
63
|
+
name: "read_file",
|
|
64
|
+
readOnly: true,
|
|
65
|
+
// The description states the tool's CONTRACT, not just its happy path, because two
|
|
66
|
+
// of its outcomes are easy to misread as failures and one of its roles is invisible
|
|
67
|
+
// from here. Every claim below is checked against the behaviour in `execute`; if that
|
|
68
|
+
// changes, this changes with it.
|
|
69
|
+
description: `Read text files and return their contents with line numbers. ` +
|
|
70
|
+
`\`paths\` TAKES A LIST: pass every file you want in ONE call rather than calling ` +
|
|
71
|
+
`this once per file. Each extra call is a full model round-trip that re-sends the ` +
|
|
72
|
+
`whole conversation, so four separate reads cost several times what one read of ` +
|
|
73
|
+
`four files costs, and take four times as long. Up to ${MAX_FILES} at a time. ` +
|
|
74
|
+
`When you already know which part of a file you need, READ ONLY THAT PART: pass ` +
|
|
75
|
+
`\`offset\` (and optionally \`limit\`). A range applies to a SINGLE file: pass one path ` +
|
|
76
|
+
`when you use one, or the range is ignored and the files come back whole. ` +
|
|
77
|
+
`Reading a file whole costs its full length on this ` +
|
|
78
|
+
`request and on every later one this turn, so a needless whole read is paid for many ` +
|
|
79
|
+
`times over. ` +
|
|
80
|
+
`A whole read past ~${Math.round(WHOLE_READ_TOKEN_BUDGET / 1000)}k tokens returns the ` +
|
|
81
|
+
`file's STRUCTURE — its symbols with line numbers — instead of its contents, so you ` +
|
|
82
|
+
`can follow up with the exact range, or with read_symbol for one symbol by name. ` +
|
|
83
|
+
`That is an answer, not a failure. ` +
|
|
84
|
+
`Otherwise reads up to ${MAX_LINES} lines per file from the start. A file larger than ` +
|
|
85
|
+
`${Math.round(MAX_BYTES / 1024)} KB must be read with \`limit\` set rather than whole. ` +
|
|
86
|
+
`Very long output is truncated at the end, and says so. ` +
|
|
87
|
+
`One unreadable path does not fail the others: it is reported in place and the rest ` +
|
|
88
|
+
`still come back. ` +
|
|
89
|
+
`Reading is also what unlocks editing: edit, replace_symbol_body ` +
|
|
90
|
+
`and overwriting an existing file with write_file all require that file to have ` +
|
|
91
|
+
`been read this session (read_symbol counts too). ` +
|
|
92
|
+
`ONE REPLY MEANS YOU ALREADY HAVE THE FILE and should not read it again: it says the ` +
|
|
93
|
+
`file is unchanged since your earlier read in this conversation, so that earlier read ` +
|
|
94
|
+
`is still current. It is a successful read, and it satisfies the edit requirement above. ` +
|
|
95
|
+
`When you only want one function, class or type, prefer read_symbol, which returns ` +
|
|
96
|
+
`just that symbol instead of pulling in a large file to look at a small part of it.`,
|
|
97
|
+
parameters: {
|
|
98
|
+
type: "object",
|
|
99
|
+
additionalProperties: false,
|
|
100
|
+
required: ["paths"],
|
|
101
|
+
properties: {
|
|
102
|
+
paths: {
|
|
103
|
+
type: "array",
|
|
104
|
+
minItems: 1,
|
|
105
|
+
maxItems: MAX_FILES,
|
|
106
|
+
items: { type: "string" },
|
|
107
|
+
description: "The files to read, absolute or relative to the working directory. Pass every " +
|
|
108
|
+
"file you need at once — one call with four paths costs a quarter of what four " +
|
|
109
|
+
"calls cost.",
|
|
110
|
+
},
|
|
111
|
+
offset: {
|
|
112
|
+
type: "integer",
|
|
113
|
+
minimum: 1,
|
|
114
|
+
description: "1-based line number to start at. Ignored unless `paths` holds exactly one file.",
|
|
115
|
+
},
|
|
116
|
+
limit: {
|
|
117
|
+
type: "integer",
|
|
118
|
+
minimum: 1,
|
|
119
|
+
description: "Number of lines to read from `offset`. Ignored unless `paths` holds exactly one file.",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
async execute(args, ctx) {
|
|
124
|
+
const paths = toPathList(args);
|
|
125
|
+
if (paths.length === 0)
|
|
126
|
+
return failQuietly("`paths` is required — pass at least one file.");
|
|
127
|
+
if (paths.length > MAX_FILES) {
|
|
128
|
+
return failQuietly(`Too many files (${paths.length}). Read at most ${MAX_FILES} in one call.`);
|
|
129
|
+
}
|
|
130
|
+
let offset = toPositiveInt(args.offset);
|
|
131
|
+
let limit = toPositiveInt(args.limit);
|
|
132
|
+
// A range names lines in ONE file. Applying it across a list would silently return a
|
|
133
|
+
// different slice of each, which reads as an answer and is not one — so the range is
|
|
134
|
+
// DROPPED here rather than honoured.
|
|
135
|
+
//
|
|
136
|
+
// It is dropped, though, and not treated as a failed call. Rejecting the whole call
|
|
137
|
+
// costs a round trip to recover, which is the exact cost this tool exists to avoid —
|
|
138
|
+
// the same reason one unreadable path below does not fail the others. In practice it
|
|
139
|
+
// cost more than the round trip: told only to pass a single path, a model retried
|
|
140
|
+
// with the first path and silently abandoned the rest of its list.
|
|
141
|
+
//
|
|
142
|
+
// Whole reads are already bounded by WHOLE_READ_TOKEN_BUDGET, so dropping a range
|
|
143
|
+
// cannot turn a cheap ranged read into an unbounded one.
|
|
144
|
+
const rangeDropped = (offset !== undefined || limit !== undefined) && paths.length > 1;
|
|
145
|
+
if (rangeDropped) {
|
|
146
|
+
offset = undefined;
|
|
147
|
+
limit = undefined;
|
|
148
|
+
}
|
|
149
|
+
const parts = [];
|
|
150
|
+
const summaries = [];
|
|
151
|
+
const fullPaths = [];
|
|
152
|
+
let failures = 0;
|
|
153
|
+
for (const rawPath of paths) {
|
|
154
|
+
const one = await readOne(rawPath, ctx, offset, limit);
|
|
155
|
+
// A bad path is reported IN PLACE rather than failing the call. Losing three good
|
|
156
|
+
// reads because the fourth was misspelled would cost another whole round trip to
|
|
157
|
+
// recover, which is the exact cost this tool exists to avoid.
|
|
158
|
+
if (one.error)
|
|
159
|
+
failures++;
|
|
160
|
+
parts.push(paths.length > 1 ? `===== ${one.label} =====\n${one.body}` : one.body);
|
|
161
|
+
summaries.push(one.summary);
|
|
162
|
+
if (one.fullPath)
|
|
163
|
+
fullPaths.push(one.fullPath);
|
|
164
|
+
}
|
|
165
|
+
if (paths.length === 1) {
|
|
166
|
+
return {
|
|
167
|
+
output: parts.join("\n"),
|
|
168
|
+
summary: summaries[0] ?? "",
|
|
169
|
+
...(failures > 0 ? { isError: true } : {}),
|
|
170
|
+
...(fullPaths.length > 0 ? { fullContentOf: fullPaths } : {}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Prepended as another part rather than raised as an error, so the model learns the
|
|
174
|
+
// rule and still gets every file it asked for.
|
|
175
|
+
if (rangeDropped) {
|
|
176
|
+
parts.unshift("Note: `offset`/`limit` name lines in a single file, so the range was ignored and " +
|
|
177
|
+
`all ${paths.length} files were read whole. To read a range, call again with one path.`);
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
output: parts.join("\n\n"),
|
|
181
|
+
summary: `read ${paths.length} files${failures > 0 ? ` (${failures} failed)` : ""}`,
|
|
182
|
+
...(fullPaths.length > 0 ? { fullContentOf: fullPaths } : {}),
|
|
183
|
+
};
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Read one file. Every rule here — the caps, the dedup, the presence flag — is per file
|
|
188
|
+
* and unchanged by batching; only the number of files a single call handles is new.
|
|
189
|
+
*/
|
|
190
|
+
async function readOne(rawPath, ctx, offset, limit) {
|
|
191
|
+
const bad = (message) => ({
|
|
192
|
+
label: rawPath,
|
|
193
|
+
body: `Error: ${message}`,
|
|
194
|
+
summary: message,
|
|
195
|
+
error: true,
|
|
196
|
+
});
|
|
197
|
+
const trimmed = rawPath.trim();
|
|
198
|
+
if (!trimmed)
|
|
199
|
+
return bad("empty path.");
|
|
200
|
+
const filePath = resolvePath(ctx, trimmed);
|
|
201
|
+
const blocked = protectedPathReason(filePath);
|
|
202
|
+
if (blocked)
|
|
203
|
+
return bad(`Refusing to read ${trimmed}: it is ${blocked}.`);
|
|
204
|
+
const otherTool = foreignAgentReason(filePath);
|
|
205
|
+
if (otherTool) {
|
|
206
|
+
const denied = await requestAgentDataAccess(ctx, otherTool, `Reading ${trimmed}`);
|
|
207
|
+
if (denied)
|
|
208
|
+
return bad(denied.summary ?? "access refused");
|
|
209
|
+
}
|
|
210
|
+
let stat;
|
|
211
|
+
try {
|
|
212
|
+
stat = await fs.stat(filePath);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return bad(`File not found: ${trimmed}`);
|
|
216
|
+
}
|
|
217
|
+
if (stat.isDirectory())
|
|
218
|
+
return bad(`${trimmed} is a directory, not a file.`);
|
|
219
|
+
const full = offset === undefined && limit === undefined;
|
|
220
|
+
const prior = ctx.reads.get(filePath);
|
|
221
|
+
const unchanged = prior !== undefined && prior.mtimeMs === stat.mtimeMs && prior.size === stat.size;
|
|
222
|
+
// Read-dedup: if the model already read this whole file, it hasn't changed since
|
|
223
|
+
// (same mtime + size), and that earlier read is STILL IN the transcript, don't
|
|
224
|
+
// re-send the content. The presence half is derived per turn rather than read off
|
|
225
|
+
// the ledger: microcompaction can clear the earlier result's body at any time, and
|
|
226
|
+
// a stored "you have it" bit would then be a lie the model obeys. No presence set
|
|
227
|
+
// (a subagent, a test) means no dedup — a wasted read, never a phantom one.
|
|
228
|
+
if (full && prior?.full && unchanged && ctx.transcriptFull?.has(filePath)) {
|
|
229
|
+
touch(ctx, filePath);
|
|
230
|
+
const shown = relativize(ctx, filePath);
|
|
231
|
+
return { label: shown, body: FILE_UNCHANGED, summary: `read ${shown} (unchanged)` };
|
|
232
|
+
}
|
|
233
|
+
if (limit === undefined && stat.size > MAX_BYTES) {
|
|
234
|
+
return bad(`File is large (${formatBytes(stat.size)}). Read a range with \`offset\` and \`limit\` instead of the whole file.`);
|
|
235
|
+
}
|
|
236
|
+
const buf = await fs.readFile(filePath);
|
|
237
|
+
if (looksBinary(buf))
|
|
238
|
+
return bad(`${trimmed} looks like a binary file; cannot read as text.`);
|
|
239
|
+
// A WHOLE read of a big file: answer with the file's shape instead of its contents.
|
|
240
|
+
//
|
|
241
|
+
// This is the one place the code map pays for itself. The alternative on offer
|
|
242
|
+
// elsewhere is an error telling the model to "use offset and limit" — which it cannot
|
|
243
|
+
// act on, because it does not know which lines it wants yet. That is the whole reason
|
|
244
|
+
// the whole-file read happens. An outline answers the question the read was really
|
|
245
|
+
// asking ("where in here is the thing I need?") and makes the follow-up a precise
|
|
246
|
+
// range instead of another guess.
|
|
247
|
+
//
|
|
248
|
+
// Ranges are exempt by construction: this branch only runs when `full` is true.
|
|
249
|
+
if (full) {
|
|
250
|
+
const estimate = estimateTokens(buf.toString("utf8"));
|
|
251
|
+
if (estimate > WHOLE_READ_TOKEN_BUDGET) {
|
|
252
|
+
const shown = relativize(ctx, filePath);
|
|
253
|
+
const lineTotal = buf.toString("utf8").split(/\r?\n/).length;
|
|
254
|
+
const head = `${shown} is ${lineTotal} lines (~${Math.round(estimate / 100) / 10}k tokens), too large to read whole — ` +
|
|
255
|
+
`reading it would re-send all of that on every later request this turn.`;
|
|
256
|
+
const entries = (await chassisForPath(ctx, filePath)?.outline(filePath)) ?? [];
|
|
257
|
+
if (entries.length > 0) {
|
|
258
|
+
return {
|
|
259
|
+
label: shown,
|
|
260
|
+
body: `${head}\n\nIts structure, with line numbers:\n\n` +
|
|
261
|
+
renderOutlineEntries(entries).join("\n") +
|
|
262
|
+
`\n\nRead the part you need with \`offset\`/\`limit\`, or read_symbol for one symbol by name.`,
|
|
263
|
+
summary: `outlined ${shown} (${lineTotal} lines — too large to read whole)`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// No outline for this file type. Say the size and how to proceed, which is all a
|
|
267
|
+
// language the code map cannot parse allows us to say honestly.
|
|
268
|
+
return bad(`${head} Read a range with \`offset\` and \`limit\`, or search it for the part you need.`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Split on CRLF or LF so a Windows file doesn't show a trailing \r on every
|
|
272
|
+
// line — the model can't see it, would omit it from an edit's old_string, and
|
|
273
|
+
// the edit would then fail to match. The edit tool normalizes line endings too.
|
|
274
|
+
const allLines = buf.toString("utf8").split(/\r?\n/);
|
|
275
|
+
const totalLines = allLines.length;
|
|
276
|
+
const start = offset ?? 1;
|
|
277
|
+
if (start > totalLines) {
|
|
278
|
+
return bad(`offset ${start} is past the end of the file (${totalLines} lines).`);
|
|
279
|
+
}
|
|
280
|
+
// A read with no explicit limit still stops after MAX_LINES — the default
|
|
281
|
+
// read is bounded, and the model pages with offset for the rest.
|
|
282
|
+
const effectiveLimit = limit ?? MAX_LINES;
|
|
283
|
+
const end = Math.min(totalLines, start - 1 + effectiveLimit);
|
|
284
|
+
const slice = allLines.slice(start - 1, end);
|
|
285
|
+
// Line numbers, right-aligned to the widest number in the slice.
|
|
286
|
+
const width = String(end).length;
|
|
287
|
+
let body = slice.map((line, i) => `${String(start + i).padStart(width)}\t${line}`).join("\n");
|
|
288
|
+
// Tell the model when the default cap hid the rest of the file.
|
|
289
|
+
if (limit === undefined && end < totalLines) {
|
|
290
|
+
body += `\n… (showing lines ${start}-${end} of ${totalLines}; pass offset to read further)`;
|
|
291
|
+
}
|
|
292
|
+
const charTruncated = body.length > MAX_OUTPUT_CHARS;
|
|
293
|
+
if (charTruncated) {
|
|
294
|
+
body = body.slice(0, MAX_OUTPUT_CHARS) + "\n… (truncated — read a smaller range with offset/limit)";
|
|
295
|
+
}
|
|
296
|
+
// "Whole file" means the whole file ACTUALLY WENT OUT, not merely that the caller
|
|
297
|
+
// asked for no range. A 2500-line file read with no offset stops at the MAX_LINES
|
|
298
|
+
// cap, and recording that as full let a later re-read be answered "unchanged since
|
|
299
|
+
// you last read" for 500 lines the model was never shown. Same for the character
|
|
300
|
+
// cap. The flag is the dedup's whole basis, so it has to mean what it says.
|
|
301
|
+
const wholeFileSent = full && end >= totalLines && !charTruncated;
|
|
302
|
+
// Record the read so edit / write_file know this file has been seen, so a
|
|
303
|
+
// later identical read can be deduped, and so it enters the working set (recency +
|
|
304
|
+
// the focused range for a partial read, used to localize a large file).
|
|
305
|
+
markScope(ctx, filePath);
|
|
306
|
+
ctx.reads.set(filePath, {
|
|
307
|
+
mtimeMs: stat.mtimeMs,
|
|
308
|
+
size: stat.size,
|
|
309
|
+
full: wholeFileSent,
|
|
310
|
+
touchedAt: nextTouch(),
|
|
311
|
+
focus: !wholeFileSent ? addFocus(prior?.focus, { start, end }) : prior?.focus,
|
|
312
|
+
});
|
|
313
|
+
const shown = relativize(ctx, filePath);
|
|
314
|
+
const ranged = offset !== undefined || limit !== undefined;
|
|
315
|
+
return {
|
|
316
|
+
label: shown,
|
|
317
|
+
body,
|
|
318
|
+
summary: ranged ? `read ${shown} lines ${start}-${end}` : `read ${shown} (${slice.length} lines)`,
|
|
319
|
+
// Presence, recorded as a FACT at the moment it is true, keyed by the absolute path
|
|
320
|
+
// this call actually resolved to. Re-deriving it later by re-resolving these
|
|
321
|
+
// arguments would be a guess: `cd` moves the working directory mid-session, so the
|
|
322
|
+
// same recorded "a.ts" can resolve to a different file than it did when read.
|
|
323
|
+
...(wholeFileSent ? { fullPath: filePath } : {}),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* The paths one call asked for.
|
|
328
|
+
*
|
|
329
|
+
* Accepts a bare string as well as a list, and still reads the old singular `path`,
|
|
330
|
+
* because a resumed session replays tool calls the model made under the previous schema
|
|
331
|
+
* — refusing those would turn every `/continue` into a wall of errors.
|
|
332
|
+
*/
|
|
333
|
+
function toPathList(args) {
|
|
334
|
+
const raw = args.paths ?? args.path;
|
|
335
|
+
if (typeof raw === "string")
|
|
336
|
+
return raw.trim() ? [raw] : [];
|
|
337
|
+
if (!Array.isArray(raw))
|
|
338
|
+
return [];
|
|
339
|
+
return raw.filter((v) => typeof v === "string" && v.trim().length > 0);
|
|
340
|
+
}
|
|
341
|
+
/** A positive integer from an env var, or `fallback`. Lets caps be tuned without
|
|
342
|
+
* baking any one model's limits into the code. */
|
|
343
|
+
function envInt(name, fallback) {
|
|
344
|
+
const n = Number(process.env[name]);
|
|
345
|
+
return Number.isInteger(n) && n > 0 ? n : fallback;
|
|
346
|
+
}
|
|
347
|
+
function toPositiveInt(value) {
|
|
348
|
+
const n = typeof value === "number"
|
|
349
|
+
? value
|
|
350
|
+
: typeof value === "string"
|
|
351
|
+
? Number(value)
|
|
352
|
+
: NaN;
|
|
353
|
+
return Number.isInteger(n) && n >= 1 ? n : undefined;
|
|
354
|
+
}
|
|
355
|
+
/** A NUL byte in the first chunk is a reliable, cheap "this isn't text" signal. */
|
|
356
|
+
function looksBinary(buf) {
|
|
357
|
+
const n = Math.min(buf.length, 8192);
|
|
358
|
+
for (let i = 0; i < n; i++) {
|
|
359
|
+
if (buf[i] === 0)
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
function formatBytes(n) {
|
|
365
|
+
if (n < 1024)
|
|
366
|
+
return `${n} B`;
|
|
367
|
+
if (n < 1024 * 1024)
|
|
368
|
+
return `${Math.round(n / 1024)} KB`;
|
|
369
|
+
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=readFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../src/tools/readFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* readSymbol.ts — read one symbol's definition, not the whole file.
|
|
3
|
+
*
|
|
4
|
+
* The token-saving companion to read_file: when the model only needs to see one
|
|
5
|
+
* function/class/method, this returns exactly that symbol's lines (located via the
|
|
6
|
+
* code map's LSP `documentSymbol` range, or a tree-sitter span as a fallback)
|
|
7
|
+
* instead of pulling a 2000-line file to look at 20 lines. read_file and its
|
|
8
|
+
* whole-file read are unchanged — this is the surgical alternative, and WHEN to
|
|
9
|
+
* reach for it stays the model's judgment.
|
|
10
|
+
*
|
|
11
|
+
* It also records the file as read, so a follow-up edit / replace_symbol_body
|
|
12
|
+
* clears the read-before-edit gate without a redundant whole-file read.
|
|
13
|
+
*/
|
|
14
|
+
import { promises as fs } from "node:fs";
|
|
15
|
+
import { relativize, resolvePath, nextTouch, markScope } from "./paths.js";
|
|
16
|
+
import { addFocus, coversSpan } from "./focus.js";
|
|
17
|
+
import { allChassis, symbolSpans } from "./chassisMux.js";
|
|
18
|
+
import { sliceBody } from "./spanCore.js";
|
|
19
|
+
import { fail, failQuietly } from "./results.js";
|
|
20
|
+
// Even a single symbol can be huge (a 900-line class). Cap what we return so one
|
|
21
|
+
// read_symbol can't flood the context; the model can read_file a range for more.
|
|
22
|
+
const MAX_SYMBOL_LINES = 400;
|
|
23
|
+
export const readSymbolTool = {
|
|
24
|
+
name: "read_symbol",
|
|
25
|
+
readOnly: true,
|
|
26
|
+
// The description told the model to pass `path` for an ambiguous name without saying
|
|
27
|
+
// what happens if it does not: the tool LISTS the candidates rather than guessing, so
|
|
28
|
+
// the first call is always safe and is itself the way to disambiguate. It also never
|
|
29
|
+
// mentioned that this read satisfies the read-before-edit gate, which is the whole
|
|
30
|
+
// reason it can replace a full read_file before an edit rather than merely precede one.
|
|
31
|
+
description: "Read the full definition of a symbol (function, class, method, type, and so on) by " +
|
|
32
|
+
"name: just its lines, not the whole file. Prefer this over read_file whenever you " +
|
|
33
|
+
"only need one symbol, since it avoids pulling a large file in to look at a small " +
|
|
34
|
+
"part of it. " +
|
|
35
|
+
"THIS COUNTS AS READING THE FILE, so you can edit that symbol straight afterwards " +
|
|
36
|
+
"without a separate read_file first. " +
|
|
37
|
+
"If the name is defined in several files it does NOT guess: you get the candidates " +
|
|
38
|
+
"with their locations, and you pick one with `path`. So calling it without `path` " +
|
|
39
|
+
"first is safe, and is usually how you find out there was an ambiguity at all. " +
|
|
40
|
+
`Long symbols stop after ${MAX_SYMBOL_LINES} lines and tell you where to continue ` +
|
|
41
|
+
"with read_file. Without a language server the match is name-level, and it says so " +
|
|
42
|
+
"when that is the case.",
|
|
43
|
+
parameters: {
|
|
44
|
+
type: "object",
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
required: ["name"],
|
|
47
|
+
properties: {
|
|
48
|
+
name: { type: "string", description: "The symbol name to read." },
|
|
49
|
+
path: {
|
|
50
|
+
type: "string",
|
|
51
|
+
description: "File the symbol is in (optional; disambiguates a name defined in several files).",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
async execute(args, ctx) {
|
|
56
|
+
const name = typeof args.name === "string" ? args.name.trim() : "";
|
|
57
|
+
if (!name)
|
|
58
|
+
return failQuietly("`name` is required.");
|
|
59
|
+
if (allChassis(ctx).length === 0) {
|
|
60
|
+
return {
|
|
61
|
+
output: "The code map isn't available here — use outline, grep, and read_file instead.",
|
|
62
|
+
summary: "code map unavailable",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const rawPath = typeof args.path === "string" && args.path.trim() ? args.path.trim() : undefined;
|
|
66
|
+
const wantAbs = rawPath ? resolvePath(ctx, rawPath) : undefined;
|
|
67
|
+
const spans = await symbolSpans(ctx, name, wantAbs ? { path: wantAbs } : {});
|
|
68
|
+
if (spans.length === 0) {
|
|
69
|
+
return {
|
|
70
|
+
output: `Couldn't locate a symbol named '${name}'${rawPath ? ` in ${rawPath}` : ""}. ` +
|
|
71
|
+
"Use outline to list a file's symbols, or grep for the name.",
|
|
72
|
+
summary: `read_symbol ${name} — not found`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Defined in several files → list them and ask for a path (don't guess).
|
|
76
|
+
const files = new Set(spans.map((s) => s.file));
|
|
77
|
+
if (files.size > 1) {
|
|
78
|
+
const list = spans
|
|
79
|
+
.map((s) => `${relativize(ctx, s.file)}:${s.start}-${s.end} ${s.kind} ${s.name}`)
|
|
80
|
+
.join("\n");
|
|
81
|
+
return {
|
|
82
|
+
output: `'${name}' is defined in several files — pass \`path\` to pick one:\n${list}`,
|
|
83
|
+
summary: `read_symbol ${name} (${files.size} files)`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const span = spans[0];
|
|
87
|
+
const abs = resolvePath(ctx, span.file);
|
|
88
|
+
let content;
|
|
89
|
+
let stat;
|
|
90
|
+
try {
|
|
91
|
+
stat = await fs.stat(abs);
|
|
92
|
+
content = await fs.readFile(abs, "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return fail(`could not read ${relativize(ctx, span.file)}.`);
|
|
96
|
+
}
|
|
97
|
+
const capped = Math.min(span.end, span.start + MAX_SYMBOL_LINES - 1);
|
|
98
|
+
const body = sliceBody(content, span.start, capped);
|
|
99
|
+
const truncated = capped < span.end ? `\n… (symbol continues to line ${span.end}; read_file a range for the rest)` : "";
|
|
100
|
+
const caveat = span.confidence === "name-level"
|
|
101
|
+
? "\n(name-level match — verify with grep if exact identity matters)"
|
|
102
|
+
: "";
|
|
103
|
+
const shown = relativize(ctx, span.file);
|
|
104
|
+
// Record the read (ranged) so a follow-up edit clears the read-before-edit gate,
|
|
105
|
+
// with recency + the symbol's span as focus (for working-set localization).
|
|
106
|
+
const prior = ctx.reads.get(abs);
|
|
107
|
+
const unchanged = prior?.mtimeMs === stat.mtimeMs && prior?.size === stat.size;
|
|
108
|
+
markScope(ctx, abs);
|
|
109
|
+
ctx.reads.set(abs, {
|
|
110
|
+
mtimeMs: stat.mtimeMs,
|
|
111
|
+
size: stat.size,
|
|
112
|
+
full: false,
|
|
113
|
+
touchedAt: nextTouch(),
|
|
114
|
+
focus: addFocus(prior?.focus, { start: span.start, end: span.end }),
|
|
115
|
+
});
|
|
116
|
+
// DEDUP, the same contract read_file has had and this tool never did. Once a file
|
|
117
|
+
// is in the working set, its content is rebuilt into the volatile tail on EVERY
|
|
118
|
+
// turn — so re-sending a symbol body the model is already looking at pays for the
|
|
119
|
+
// same lines twice, every time. Measured across terminal coding agents,
|
|
120
|
+
// repeated reads are ~42% of avoidable token spend, and this was our version of it:
|
|
121
|
+
// a session re-read the same four functions over and over while all four sat in
|
|
122
|
+
// <working_files>.
|
|
123
|
+
//
|
|
124
|
+
// Checked against what the working set actually PUT ON SCREEN this turn, not
|
|
125
|
+
// against the read ledger. The ledger records what was read once; it does not
|
|
126
|
+
// prove the text is still visible, and a sub-agent or a headless run has no
|
|
127
|
+
// working set at all — so trusting it would tell the model "you already have
|
|
128
|
+
// this" about content it cannot see. A wasted read is cheap; a phantom one makes
|
|
129
|
+
// the model work from text it never received. Also requires the file to be
|
|
130
|
+
// UNCHANGED: after an edit the new body has to come back.
|
|
131
|
+
const alreadyShown = unchanged && coversSpan(ctx.workingSetSpans?.get(abs), span.start, span.end);
|
|
132
|
+
if (alreadyShown) {
|
|
133
|
+
return {
|
|
134
|
+
output: `${span.kind} ${span.name} — ${shown}:${span.start}-${span.end} is already in your ` +
|
|
135
|
+
`<working_files> block, unchanged. Read it there rather than calling this again.`,
|
|
136
|
+
summary: `${span.name} (already in context)`,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
output: `${span.kind} ${span.name} — ${shown}:${span.start}-${span.end}\n${body}${truncated}${caveat}`,
|
|
141
|
+
summary: `read ${span.name} (${shown}:${span.start}-${span.end})`,
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=readSymbol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readSymbol.js","sourceRoot":"","sources":["../../src/tools/readSymbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,iFAAiF;AACjF,iFAAiF;AACjF,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,IAAI;IACd,qFAAqF;IACrF,sFAAsF;IACtF,qFAAqF;IACrF,mFAAmF;IACnF,wFAAwF;IACxF,WAAW,EACT,qFAAqF;QACrF,oFAAoF;QACpF,mFAAmF;QACnF,cAAc;QACd,mFAAmF;QACnF,sCAAsC;QACtC,oFAAoF;QACpF,mFAAmF;QACnF,gFAAgF;QAChF,2BAA2B,gBAAgB,wCAAwC;QACnF,oFAAoF;QACpF,wBAAwB;IAC1B,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,oBAAoB,EAAE,KAAK;QAC3B,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;YACjE,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kFAAkF;aAChG;SACF;KACF;IAED,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,IAAI;YAAE,OAAO,WAAW,CAAC,qBAAqB,CAAC,CAAC;QACrD,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO;gBACL,MAAM,EAAE,+EAA+E;gBACvF,OAAO,EAAE,sBAAsB;aAChC,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACjG,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAE7E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,MAAM,EACJ,mCAAmC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI;oBAC9E,6DAA6D;gBAC/D,OAAO,EAAE,eAAe,IAAI,cAAc;aAC3C,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,KAAK;iBACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;iBACjF,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO;gBACL,MAAM,EAAE,IAAI,IAAI,+DAA+D,IAAI,EAAE;gBACrF,OAAO,EAAE,eAAe,IAAI,KAAK,KAAK,CAAC,IAAI,SAAS;aACrD,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAe,CAAC;QACpB,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1B,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,kBAAkB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,SAAS,GACb,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,iCAAiC,IAAI,CAAC,GAAG,mCAAmC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,MAAM,MAAM,GACV,IAAI,CAAC,UAAU,KAAK,YAAY;YAC9B,CAAC,CAAC,mEAAmE;YACrE,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEzC,iFAAiF;QACjF,4EAA4E;QAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;QAC/E,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,KAAK;YACX,SAAS,EAAE,SAAS,EAAE;YACtB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;SACpE,CAAC,CAAC;QAEH,kFAAkF;QAClF,gFAAgF;QAChF,kFAAkF;QAClF,wEAAwE;QACxE,oFAAoF;QACpF,gFAAgF;QAChF,mBAAmB;QACnB,EAAE;QACF,6EAA6E;QAC7E,8EAA8E;QAC9E,4EAA4E;QAC5E,6EAA6E;QAC7E,iFAAiF;QACjF,2EAA2E;QAC3E,0DAA0D;QAC1D,MAAM,YAAY,GAAG,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAClG,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO;gBACL,MAAM,EACJ,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,sBAAsB;oBACpF,iFAAiF;gBACnF,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,uBAAuB;aAC7C,CAAC;QACJ,CAAC;QAED,OAAO;YACL,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE;YACtG,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG;SAClE,CAAC;IACJ,CAAC;CACF,CAAC"}
|