@bastani/atomic 0.9.2 → 0.9.3-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +2 -2
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/direct-tools.ts +4 -2
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/proxy-call.ts +3 -1
- package/dist/builtin/mcp/utils.ts +18 -7
- package/dist/builtin/subagents/CHANGELOG.md +11 -0
- package/dist/builtin/subagents/README.md +6 -6
- package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
- package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
- package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
- package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
- package/dist/builtin/subagents/agents/debugger.md +5 -5
- package/dist/builtin/subagents/agents/worker.md +56 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
- package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
- package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
- package/dist/builtin/subagents/src/extension/schemas.ts +2 -2
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
- package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
- package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
- package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +13 -0
- package/dist/builtin/workflows/README.md +2 -2
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
- package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
- package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
- package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
- package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
- package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
- package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
- package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
- package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
- package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
- package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
- package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
- package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
- package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +1 -2
- package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
- package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/config-self-update.d.ts.map +1 -1
- package/dist/config-self-update.js +3 -4
- package/dist/config-self-update.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -5
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts +1 -0
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +1 -0
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +23 -0
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -0
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +29 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +36 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
- package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-metrics.js +50 -1
- package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.js +2 -0
- package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
- package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-runner.js +1 -1
- package/dist/core/compaction/context-compaction-runner.js.map +1 -1
- package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-application.js +5 -5
- package/dist/core/compaction/context-deletion-application.js.map +1 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
- package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-targets.js +23 -3
- package/dist/core/compaction/context-deletion-targets.js.map +1 -1
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
- package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tools.js +18 -10
- package/dist/core/compaction/context-deletion-tools.js.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.js +2 -4
- package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
- package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
- package/dist/core/copilot-gemini-tool-arguments.js +2 -60
- package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +2 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +11 -3
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +11 -0
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/tool-events.d.ts +13 -13
- package/dist/core/extensions/tool-events.d.ts.map +1 -1
- package/dist/core/extensions/tool-events.js +3 -3
- package/dist/core/extensions/tool-events.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/flattened-tool-arguments.d.ts +18 -0
- package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
- package/dist/core/flattened-tool-arguments.js +104 -0
- package/dist/core/flattened-tool-arguments.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +2 -2
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +18 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
- package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-resource-accessors.js +15 -0
- package/dist/core/settings-manager-resource-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +11 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +3 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/artifact-protocol.d.ts +11 -0
- package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
- package/dist/core/tools/artifact-protocol.js +76 -0
- package/dist/core/tools/artifact-protocol.js.map +1 -0
- package/dist/core/tools/artifacts.d.ts +18 -0
- package/dist/core/tools/artifacts.d.ts.map +1 -0
- package/dist/core/tools/artifacts.js +90 -0
- package/dist/core/tools/artifacts.js.map +1 -0
- package/dist/core/tools/bash-async-jobs.d.ts +20 -0
- package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
- package/dist/core/tools/bash-async-jobs.js +59 -0
- package/dist/core/tools/bash-async-jobs.js.map +1 -0
- package/dist/core/tools/bash-async-output.d.ts +10 -0
- package/dist/core/tools/bash-async-output.d.ts.map +1 -0
- package/dist/core/tools/bash-async-output.js +80 -0
- package/dist/core/tools/bash-async-output.js.map +1 -0
- package/dist/core/tools/bash-interceptor.d.ts +10 -0
- package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
- package/dist/core/tools/bash-interceptor.js +39 -0
- package/dist/core/tools/bash-interceptor.js.map +1 -0
- package/dist/core/tools/bash-leading-cd.d.ts +7 -0
- package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
- package/dist/core/tools/bash-leading-cd.js +59 -0
- package/dist/core/tools/bash-leading-cd.js.map +1 -0
- package/dist/core/tools/bash-pty-native.d.ts +14 -0
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
- package/dist/core/tools/bash-pty-native.js +71 -0
- package/dist/core/tools/bash-pty-native.js.map +1 -0
- package/dist/core/tools/bash.d.ts +28 -17
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +152 -35
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/block-resolver.d.ts +16 -0
- package/dist/core/tools/block-resolver.d.ts.map +1 -0
- package/dist/core/tools/block-resolver.js +74 -0
- package/dist/core/tools/block-resolver.js.map +1 -0
- package/dist/core/tools/conflict-registry.d.ts +16 -0
- package/dist/core/tools/conflict-registry.d.ts.map +1 -0
- package/dist/core/tools/conflict-registry.js +44 -0
- package/dist/core/tools/conflict-registry.js.map +1 -0
- package/dist/core/tools/directory-tree.d.ts +13 -0
- package/dist/core/tools/directory-tree.d.ts.map +1 -0
- package/dist/core/tools/directory-tree.js +81 -0
- package/dist/core/tools/directory-tree.js.map +1 -0
- package/dist/core/tools/edit.d.ts +4 -29
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +136 -228
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/fetch-url.d.ts +74 -0
- package/dist/core/tools/fetch-url.d.ts.map +1 -0
- package/dist/core/tools/fetch-url.js +518 -0
- package/dist/core/tools/fetch-url.js.map +1 -0
- package/dist/core/tools/find.d.ts +27 -9
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +400 -176
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/glob-path-utils.d.ts +8 -0
- package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
- package/dist/core/tools/glob-path-utils.js +26 -0
- package/dist/core/tools/glob-path-utils.js.map +1 -0
- package/dist/core/tools/grep.d.ts +12 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +141 -17
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
- package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/apply.js +752 -0
- package/dist/core/tools/hashline-engine/apply.js.map +1 -0
- package/dist/core/tools/hashline-engine/block.d.ts +40 -0
- package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/block.js +117 -0
- package/dist/core/tools/hashline-engine/block.js.map +1 -0
- package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
- package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
- package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
- package/dist/core/tools/hashline-engine/format.d.ts +71 -0
- package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/format.js +178 -0
- package/dist/core/tools/hashline-engine/format.js.map +1 -0
- package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
- package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/fs.js +143 -0
- package/dist/core/tools/hashline-engine/fs.js.map +1 -0
- package/dist/core/tools/hashline-engine/index.d.ts +18 -0
- package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/index.js +20 -0
- package/dist/core/tools/hashline-engine/index.js.map +1 -0
- package/dist/core/tools/hashline-engine/input.d.ts +101 -0
- package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/input.js +398 -0
- package/dist/core/tools/hashline-engine/input.js.map +1 -0
- package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
- package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/messages.js +144 -0
- package/dist/core/tools/hashline-engine/messages.js.map +1 -0
- package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
- package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/mismatch.js +90 -0
- package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
- package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
- package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/normalize.js +33 -0
- package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
- package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
- package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/parser.js +381 -0
- package/dist/core/tools/hashline-engine/parser.js.map +1 -0
- package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
- package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/patcher.js +341 -0
- package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
- package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
- package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/prefixes.js +135 -0
- package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
- package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
- package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/recovery.js +168 -0
- package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
- package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
- package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/snapshots.js +108 -0
- package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
- package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
- package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/stream.js +111 -0
- package/dist/core/tools/hashline-engine/stream.js.map +1 -0
- package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
- package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
- package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
- package/dist/core/tools/hashline-engine/types.d.ts +166 -0
- package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/types.js +9 -0
- package/dist/core/tools/hashline-engine/types.js.map +1 -0
- package/dist/core/tools/hashline.d.ts +29 -0
- package/dist/core/tools/hashline.d.ts.map +1 -0
- package/dist/core/tools/hashline.js +110 -0
- package/dist/core/tools/hashline.js.map +1 -0
- package/dist/core/tools/index.d.ts +6 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +52 -35
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/notebook.d.ts +38 -0
- package/dist/core/tools/notebook.d.ts.map +1 -0
- package/dist/core/tools/notebook.js +125 -0
- package/dist/core/tools/notebook.js.map +1 -0
- package/dist/core/tools/read-document-extract.d.ts +9 -0
- package/dist/core/tools/read-document-extract.d.ts.map +1 -0
- package/dist/core/tools/read-document-extract.js +212 -0
- package/dist/core/tools/read-document-extract.js.map +1 -0
- package/dist/core/tools/read-selectors.d.ts +24 -0
- package/dist/core/tools/read-selectors.d.ts.map +1 -0
- package/dist/core/tools/read-selectors.js +277 -0
- package/dist/core/tools/read-selectors.js.map +1 -0
- package/dist/core/tools/read-url.d.ts +37 -0
- package/dist/core/tools/read-url.d.ts.map +1 -0
- package/dist/core/tools/read-url.js +39 -0
- package/dist/core/tools/read-url.js.map +1 -0
- package/dist/core/tools/read.d.ts +11 -11
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +224 -94
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/resource-selectors.d.ts +44 -0
- package/dist/core/tools/resource-selectors.d.ts.map +1 -0
- package/dist/core/tools/resource-selectors.js +808 -0
- package/dist/core/tools/resource-selectors.js.map +1 -0
- package/dist/core/tools/search-details.d.ts +26 -0
- package/dist/core/tools/search-details.d.ts.map +1 -0
- package/dist/core/tools/search-details.js +24 -0
- package/dist/core/tools/search-details.js.map +1 -0
- package/dist/core/tools/search-line-ranges.d.ts +11 -0
- package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
- package/dist/core/tools/search-line-ranges.js +65 -0
- package/dist/core/tools/search-line-ranges.js.map +1 -0
- package/dist/core/tools/search-native.d.ts +97 -0
- package/dist/core/tools/search-native.d.ts.map +1 -0
- package/dist/core/tools/search-native.js +27 -0
- package/dist/core/tools/search-native.js.map +1 -0
- package/dist/core/tools/search.d.ts +24 -0
- package/dist/core/tools/search.d.ts.map +1 -0
- package/dist/core/tools/search.js +573 -0
- package/dist/core/tools/search.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +4 -4
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +3 -3
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/url-ip-guards.d.ts +4 -0
- package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
- package/dist/core/tools/url-ip-guards.js +126 -0
- package/dist/core/tools/url-ip-guards.js.map +1 -0
- package/dist/core/tools/write.d.ts +12 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +166 -14
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -3
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/index-extensions.d.ts +2 -2
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +9 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
- package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js +7 -0
- package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.js +0 -5
- package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +1 -0
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +80 -2
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +51 -0
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +5 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +4 -1
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
- package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-onboarding.js +220 -0
- package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +4 -0
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +6 -0
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.js +9 -4
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +28 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +21 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/markit.d.ts +8 -0
- package/dist/utils/markit.d.ts.map +1 -0
- package/dist/utils/markit.js +53 -0
- package/dist/utils/markit.js.map +1 -0
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -1
- package/dist/utils/paths.js.map +1 -1
- package/docs/compaction.md +16 -1
- package/docs/containerization.md +1 -1
- package/docs/docs.json +1 -0
- package/docs/extensions.md +25 -36
- package/docs/quickstart.md +11 -6
- package/docs/sdk.md +5 -5
- package/docs/settings.md +7 -0
- package/docs/subagents.md +3 -2
- package/docs/tools.md +49 -0
- package/docs/usage.md +3 -3
- package/docs/workflows.md +7 -5
- package/examples/extensions/subagent/README.md +5 -5
- package/examples/extensions/subagent/agents/planner.md +1 -1
- package/examples/extensions/subagent/agents/reviewer.md +1 -1
- package/examples/extensions/subagent/agents/scout.md +2 -2
- package/examples/extensions/subagent/display.ts +3 -3
- package/examples/sdk/05-tools.ts +3 -3
- package/examples/sdk/README.md +1 -1
- package/package.json +3 -2
package/dist/core/tools/read.js
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
|
|
2
2
|
import { Text } from "@earendil-works/pi-tui";
|
|
3
3
|
import { constants } from "fs";
|
|
4
|
-
import { access as fsAccess, readFile as fsReadFile } from "fs/promises";
|
|
4
|
+
import { access as fsAccess, readFile as fsReadFile, stat as fsStat } from "fs/promises";
|
|
5
5
|
import { Type } from "typebox";
|
|
6
6
|
import { getReadmePath } from "../../config.js";
|
|
7
7
|
import { keyHint, keyText } from "../../modes/interactive/components/keybinding-hints.js";
|
|
8
|
+
import { parseConflictBlocks, registerConflictBlocks } from "./conflict-registry.js";
|
|
8
9
|
import { getLanguageFromPath, highlightCode } from "../../modes/interactive/theme/theme.js";
|
|
9
10
|
import { formatDimensionNote, resizeImage } from "../../utils/image-resize.js";
|
|
10
11
|
import { detectSupportedImageMimeTypeFromFile } from "../../utils/mime.js";
|
|
11
12
|
import { formatPathRelativeToCwdOrAbsolute } from "../../utils/paths.js";
|
|
13
|
+
import { buildDirectoryTree } from "./directory-tree.js";
|
|
14
|
+
import { applyReadLineSelection, extractDocumentMarkdown, isDocumentPath } from "./read-document-extract.js";
|
|
15
|
+
import { isReadableUrlPath } from "./fetch-url.js";
|
|
16
|
+
import { readUrlBranch } from "./read-url.js";
|
|
17
|
+
import { isNotebookPath, readEditableNotebookText } from "./notebook.js";
|
|
18
|
+
import { createHashlineSnapshotStore, formatHashlineContent, recordHashlineSnapshot } from "./hashline.js";
|
|
12
19
|
import { resolveReadPathAsync, resolveToCwd } from "./path-utils.js";
|
|
13
20
|
import { getTextOutput, invalidArgText, replaceTabs, shortenPath, str } from "./render-utils.js";
|
|
21
|
+
import { formatHashlineSelectedLines, isReadResourceSelector, selectExactReadRanges, selectReadRanges, splitReadLineSelector } from "./read-selectors.js";
|
|
22
|
+
import { parseArchiveSelector, readArchiveSelector, readInternalSelector, readSqliteSelector, resolveArchiveSelector, resolveInternalSelector, sqliteSelectorForPath } from "./resource-selectors.js";
|
|
14
23
|
import { wrapToolDefinition } from "./tool-definition-wrapper.js";
|
|
15
24
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from "./truncate.js";
|
|
16
25
|
const readSchema = Type.Object({
|
|
17
|
-
path: Type.String({ description: "
|
|
18
|
-
|
|
19
|
-
limit: Type.Optional(Type.Number({ description: "Maximum number of lines to read" })),
|
|
20
|
-
});
|
|
21
|
-
// Matches mehmoodosman/claude-code DEFAULT_MAX_RESULT_SIZE_CHARS.
|
|
22
|
-
// Reads are blocked (not persisted) because the source is already a file on disk;
|
|
23
|
-
// re-persisting it would be circular.
|
|
26
|
+
path: Type.String({ description: "File, directory, archive member, SQLite selector, internal resource, image, document, or URL to read. Append selectors such as :raw, :conflicts, :N, :A-B, :A+C, or :A-B,C-D to scope output." }),
|
|
27
|
+
}, { additionalProperties: false });
|
|
24
28
|
const READ_TOOL_MAX_RESULT_CHARS = 50_000;
|
|
25
29
|
const COMPACT_RESOURCE_FILE_NAMES = new Set(["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"]);
|
|
26
30
|
const defaultReadOperations = {
|
|
@@ -28,44 +32,27 @@ const defaultReadOperations = {
|
|
|
28
32
|
access: (path) => fsAccess(path, constants.R_OK),
|
|
29
33
|
detectImageMimeType: detectSupportedImageMimeTypeFromFile,
|
|
30
34
|
};
|
|
31
|
-
function formatReadLineRange(
|
|
32
|
-
|
|
33
|
-
return "";
|
|
34
|
-
const startLine = args.offset ?? 1;
|
|
35
|
-
const endLine = args.limit !== undefined ? startLine + args.limit - 1 : "";
|
|
36
|
-
return theme.fg("warning", `:${startLine}${endLine ? `-${endLine}` : ""}`);
|
|
35
|
+
function formatReadLineRange(_args, _theme) {
|
|
36
|
+
return "";
|
|
37
37
|
}
|
|
38
38
|
function formatReadCall(args, theme) {
|
|
39
|
-
const rawPath = str(args?.
|
|
39
|
+
const rawPath = str(args?.path);
|
|
40
40
|
const path = rawPath !== null ? shortenPath(rawPath) : null;
|
|
41
41
|
const invalidArg = invalidArgText(theme);
|
|
42
42
|
const pathDisplay = path === null ? invalidArg : path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
|
|
43
43
|
return `${theme.fg("toolTitle", theme.bold("read"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;
|
|
44
44
|
}
|
|
45
|
-
function trimTrailingEmptyLines(lines) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return lines.slice(0, end);
|
|
51
|
-
}
|
|
52
|
-
function getNonVisionImageNote(model) {
|
|
53
|
-
if (!model || model.input.includes("image")) {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
return "[Current model does not support images. The image will be omitted from this request.]";
|
|
57
|
-
}
|
|
58
|
-
function toPosixPath(filePath) {
|
|
59
|
-
return filePath.split(sep).join("/");
|
|
60
|
-
}
|
|
61
|
-
function formatCount(count) {
|
|
62
|
-
return count.toLocaleString("en-US");
|
|
63
|
-
}
|
|
45
|
+
function trimTrailingEmptyLines(lines) { let end = lines.length; while (end > 0 && lines[end - 1] === "")
|
|
46
|
+
end--; return lines.slice(0, end); }
|
|
47
|
+
function getNonVisionImageNote(model) { return !model || model.input.includes("image") ? undefined : "[Current model does not support images. The image will be omitted from this request.]"; }
|
|
48
|
+
function toPosixPath(filePath) { return filePath.split(sep).join("/"); }
|
|
49
|
+
function formatCount(count) { return count.toLocaleString("en-US"); }
|
|
64
50
|
function shellQuote(value) {
|
|
65
51
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
66
52
|
}
|
|
67
53
|
function buildOversizedReadMessage(details) {
|
|
68
54
|
const pathForExample = JSON.stringify(details.path);
|
|
55
|
+
const rangePathForExample = JSON.stringify(`${details.path}:${details.startLine}+200`);
|
|
69
56
|
const shellPathForExample = shellQuote(details.path);
|
|
70
57
|
const requestedLimitLine = details.requestedLimit !== undefined ? [`Requested line limit: ${formatCount(details.requestedLimit)}`] : [];
|
|
71
58
|
if (details.byteGuidance) {
|
|
@@ -77,21 +64,24 @@ function buildOversizedReadMessage(details) {
|
|
|
77
64
|
"The selected content starts with a single oversized line, so line pagination is not useful. Read byte slices instead. Examples:",
|
|
78
65
|
`- Inspect the start of line ${details.startLine}: sed -n '${details.startLine}p' ${shellPathForExample} | head -c ${DEFAULT_MAX_BYTES}`,
|
|
79
66
|
`- Inspect a later byte window: sed -n '${details.startLine}p' ${shellPathForExample} | tail -c +${DEFAULT_MAX_BYTES + 1} | head -c ${DEFAULT_MAX_BYTES}`,
|
|
80
|
-
`- Search for relevant text first:
|
|
67
|
+
`- Search for relevant text first: search({ "pattern": "functionName", "paths": ${pathForExample} })`,
|
|
81
68
|
].join("\n");
|
|
82
69
|
}
|
|
83
70
|
const targetedSnippetOffset = Math.max(details.startLine, 120);
|
|
71
|
+
const snippetPathForExample = JSON.stringify(`${details.path}:${targetedSnippetOffset}+80`);
|
|
84
72
|
return [
|
|
85
73
|
`File read blocked: requested selected range is too large (${formatCount(details.chars)} chars; threshold: ${formatCount(details.maxChars)} chars).`,
|
|
86
74
|
`Path: ${details.path}`,
|
|
87
75
|
...requestedLimitLine,
|
|
88
76
|
"",
|
|
89
77
|
"Read only the needed context incrementally. Examples:",
|
|
90
|
-
`- Search for relevant symbols first:
|
|
91
|
-
`- Read a smaller line range: read({ "path": ${
|
|
92
|
-
`- Read a targeted snippet around a match: read({ "path": ${
|
|
78
|
+
`- Search for relevant symbols first: search({ "pattern": "functionName", "paths": ${pathForExample} })`,
|
|
79
|
+
`- Read a smaller line range: read({ "path": ${rangePathForExample} })`,
|
|
80
|
+
`- Read a targeted snippet around a match: read({ "path": ${snippetPathForExample} })`,
|
|
93
81
|
].join("\n");
|
|
94
82
|
}
|
|
83
|
+
function readSourceMeta(source) { return { meta: { source, sourcePath: source } }; }
|
|
84
|
+
function oversizedReadResult(details) { return { content: [{ type: "text", text: buildOversizedReadMessage(details) }], details: { oversizedRead: details, meta: { source: details.path, sourcePath: details.path, limits: { maxChars: details.maxChars }, } } }; }
|
|
95
85
|
function getPiDocsClassification(absolutePath) {
|
|
96
86
|
const packageRoot = dirname(getReadmePath());
|
|
97
87
|
const relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));
|
|
@@ -108,7 +98,7 @@ function getPiDocsClassification(absolutePath) {
|
|
|
108
98
|
return undefined;
|
|
109
99
|
}
|
|
110
100
|
function getCompactReadClassification(args, cwd) {
|
|
111
|
-
const rawPath = str(args?.
|
|
101
|
+
const rawPath = str(args?.path);
|
|
112
102
|
if (!rawPath)
|
|
113
103
|
return undefined;
|
|
114
104
|
const absolutePath = resolveToCwd(rawPath, cwd);
|
|
@@ -144,7 +134,7 @@ function formatReadResult(args, result, options, theme, showImages, _cwd, isErro
|
|
|
144
134
|
if (!options.expanded && !isError && !oversizedReadBlocked) {
|
|
145
135
|
return "";
|
|
146
136
|
}
|
|
147
|
-
const rawPath = str(args?.
|
|
137
|
+
const rawPath = str(args?.path);
|
|
148
138
|
const output = oversizedRead ? buildOversizedReadMessage(oversizedRead) : getTextOutput(result, showImages);
|
|
149
139
|
const lang = rawPath && !oversizedReadBlocked ? getLanguageFromPath(rawPath) : undefined;
|
|
150
140
|
const renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split("\n");
|
|
@@ -170,18 +160,40 @@ function formatReadResult(args, result, options, theme, showImages, _cwd, isErro
|
|
|
170
160
|
}
|
|
171
161
|
return text;
|
|
172
162
|
}
|
|
163
|
+
function archiveSelectorMemberExists(pathValue, cwd) { const archive = parseArchiveSelector(pathValue); if (!archive || !archive.memberPath)
|
|
164
|
+
return false; try {
|
|
165
|
+
readArchiveSelector(resolveArchiveSelector(archive, cwd));
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return false;
|
|
170
|
+
} }
|
|
171
|
+
function appendReadSelectors(pathValue, selector) {
|
|
172
|
+
const range = selector.ranges?.map((item) => item.end === undefined ? `${item.start}` : `${item.start}-${item.end}`).join(",") ?? (selector.offset ? `${selector.offset}` : "");
|
|
173
|
+
return `${pathValue}${range ? `:${range}` : ""}${selector.conflicts ? ":conflicts" : ""}${selector.raw ? ":raw" : ""}`;
|
|
174
|
+
}
|
|
173
175
|
export function createReadToolDefinition(cwd, options) {
|
|
174
176
|
const autoResizeImages = options?.autoResizeImages ?? true;
|
|
175
177
|
const ops = options?.operations ?? defaultReadOperations;
|
|
178
|
+
const hashlineStore = options?.hashlineStore ?? createHashlineSnapshotStore();
|
|
176
179
|
return {
|
|
177
180
|
name: "read",
|
|
178
181
|
label: "read",
|
|
179
|
-
description:
|
|
180
|
-
promptSnippet: "Read
|
|
181
|
-
promptGuidelines: ["Use read to
|
|
182
|
+
description: "Read files, directories, archives, SQLite databases, internal resources, images, documents, and URLs through one path string.",
|
|
183
|
+
promptSnippet: "Read a path selector.",
|
|
184
|
+
promptGuidelines: ["Use read to inspect file and resource contents; use path selectors for line ranges, raw output, and conflict views."],
|
|
182
185
|
parameters: readSchema,
|
|
183
186
|
maxResultSizeChars: Infinity,
|
|
184
|
-
async execute(_toolCallId, { path
|
|
187
|
+
async execute(_toolCallId, { path }, signal, _onUpdate, ctx) {
|
|
188
|
+
const resourceCtx = ctx;
|
|
189
|
+
const splitSelector = splitReadLineSelector(path), markerless = path.replace(/:raw(?=(:|$))/g, "").replace(/:conflicts(?=(:|$))/g, ""), sqliteOriginal = sqliteSelectorForPath(markerless, cwd), sqliteDirect = sqliteSelectorForPath(path, cwd);
|
|
190
|
+
const selector = archiveSelectorMemberExists(path, cwd) ? { path } : sqliteDirect && (sqliteDirect.table === "raw" || sqliteDirect.table === "conflicts") ? { path } : sqliteOriginal?.rowId && splitSelector.path !== markerless ? { path: markerless, raw: splitSelector.raw, conflicts: splitSelector.conflicts } : sqliteOriginal && splitSelector.path === markerless && markerless !== path ? { path: markerless, raw: splitSelector.raw, conflicts: splitSelector.conflicts } : splitSelector.path === path && sqliteDirect ? { path } : splitSelector;
|
|
191
|
+
const effectivePath = selector.path;
|
|
192
|
+
const effectiveOffset = selector.offset;
|
|
193
|
+
const effectiveLimit = selector.limit;
|
|
194
|
+
const effectiveRanges = selector.ranges;
|
|
195
|
+
const rawOutput = selector.raw;
|
|
196
|
+
const conflictsOnly = selector.conflicts;
|
|
185
197
|
return new Promise((resolve, reject) => {
|
|
186
198
|
if (signal?.aborted) {
|
|
187
199
|
reject(new Error("Operation aborted"));
|
|
@@ -195,22 +207,125 @@ export function createReadToolDefinition(cwd, options) {
|
|
|
195
207
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
196
208
|
(async () => {
|
|
197
209
|
try {
|
|
198
|
-
const
|
|
210
|
+
const archive = parseArchiveSelector(effectivePath);
|
|
211
|
+
const sqlite = sqliteSelectorForPath(effectivePath, cwd);
|
|
212
|
+
if (isReadableUrlPath(effectivePath)) {
|
|
213
|
+
resolve(await readUrlBranch({ effectivePath, rawOutput: rawOutput === true, effectiveRanges, effectiveOffset, effectiveLimit, cwd, ctx, signal, maxChars: READ_TOOL_MAX_RESULT_CHARS, maxBytes: DEFAULT_MAX_BYTES, oversized: oversizedReadResult, sourceMeta: readSourceMeta }));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (sqlite) {
|
|
217
|
+
const textContent = readSqliteSelector(sqlite), selection = applyReadLineSelection(textContent.split("\n"), effectiveRanges, effectiveOffset, effectiveLimit, rawOutput), selectedText = selection.lines.join("\n");
|
|
218
|
+
if ((effectiveRanges || effectiveOffset) && selection.lines.length === 0) {
|
|
219
|
+
const requested = effectiveRanges?.[0]?.start ?? effectiveOffset ?? 1;
|
|
220
|
+
resolve({ content: [{ type: "text", text: `Requested line ${requested} is beyond end of resource (${textContent.split("\n").length} lines total).` }], details: undefined });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (selectedText.length > READ_TOOL_MAX_RESULT_CHARS || Buffer.byteLength(selectedText, "utf8") > DEFAULT_MAX_BYTES) {
|
|
224
|
+
resolve(oversizedReadResult({ blocked: true, path: effectivePath, chars: selectedText.length, maxChars: READ_TOOL_MAX_RESULT_CHARS, startLine: selection.firstLine, totalFileLines: textContent.split("\n").length, firstLineBytes: Buffer.byteLength(selection.lines[0] ?? "", "utf8"), byteGuidance: false }));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
resolve({ content: [{ type: "text", text: selectedText }], details: readSourceMeta(effectivePath) });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (archive) {
|
|
231
|
+
const resolvedArchive = resolveArchiveSelector(archive, cwd);
|
|
232
|
+
const textContent = readArchiveSelector(resolvedArchive);
|
|
233
|
+
let allLines = textContent.split("\n");
|
|
234
|
+
if (conflictsOnly) {
|
|
235
|
+
let inConflict = false;
|
|
236
|
+
const conflictLines = allLines.filter((line) => { if (line.startsWith("<<<<<<<"))
|
|
237
|
+
inConflict = true; const keep = inConflict; if (line.startsWith(">>>>>>>"))
|
|
238
|
+
inConflict = false; return keep; });
|
|
239
|
+
if (conflictLines.length === 0) {
|
|
240
|
+
resolve({ content: [{ type: "text", text: "No conflict markers found" }], details: undefined });
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
allLines = conflictLines;
|
|
244
|
+
}
|
|
245
|
+
const rangeSelection = (rawOutput ? selectExactReadRanges : selectReadRanges)(allLines, effectiveRanges);
|
|
246
|
+
const startLine = rangeSelection ? rangeSelection.firstLine - 1 : effectiveOffset ? Math.max(0, effectiveOffset - 1) : 0;
|
|
247
|
+
if (startLine >= allLines.length || (effectiveRanges && rangeSelection?.selectedLines.length === 0)) {
|
|
248
|
+
resolve({ content: [{ type: "text", text: `Requested line ${startLine + 1} is beyond end of resource (${allLines.length} lines total).` }], details: undefined });
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const endLine = effectiveLimit !== undefined ? Math.min(startLine + effectiveLimit, allLines.length) : allLines.length;
|
|
252
|
+
const selectedLines = rangeSelection?.selectedLines ?? allLines.slice(startLine, endLine);
|
|
253
|
+
const selectedText = selectedLines.join("\n");
|
|
254
|
+
if (selectedText.length > READ_TOOL_MAX_RESULT_CHARS || Buffer.byteLength(selectedText, "utf8") > DEFAULT_MAX_BYTES) {
|
|
255
|
+
resolve(oversizedReadResult({ blocked: true, path: `${resolvedArchive.archivePath}:${resolvedArchive.memberPath}`, chars: selectedText.length, maxChars: READ_TOOL_MAX_RESULT_CHARS, startLine: startLine + 1, totalFileLines: allLines.length, firstLineBytes: Buffer.byteLength(selectedLines[0] ?? "", "utf8"), byteGuidance: false }));
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
resolve({ content: [{ type: "text", text: selectedText }], details: readSourceMeta(`${resolvedArchive.archivePath}:${resolvedArchive.memberPath}`) });
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (/^(?:skill|agent|artifact|history|issue|local|memory|pr|conflict|omp|rule|mcp|vault):\/\//.test(effectivePath)) {
|
|
262
|
+
const sourcePath = effectivePath.startsWith("local://") ? resolveInternalSelector(effectivePath, cwd) : undefined;
|
|
263
|
+
if (sourcePath) {
|
|
264
|
+
resolve(await createReadToolDefinition(cwd, options).execute(_toolCallId, { path: appendReadSelectors(sourcePath, selector) }, signal, _onUpdate, ctx));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const allLines = (await readInternalSelector(effectivePath, cwd, resourceCtx)).split("\n");
|
|
268
|
+
const rangeSelection = (rawOutput ? selectExactReadRanges : selectReadRanges)(allLines, effectiveRanges);
|
|
269
|
+
const startLine = rangeSelection ? rangeSelection.firstLine - 1 : effectiveOffset ? Math.max(0, effectiveOffset - 1) : 0;
|
|
270
|
+
if (startLine >= allLines.length || (effectiveRanges && rangeSelection?.selectedLines.length === 0)) {
|
|
271
|
+
resolve({ content: [{ type: "text", text: `Requested line ${startLine + 1} is beyond end of resource (${allLines.length} lines total).` }], details: undefined });
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const endLine = effectiveLimit !== undefined ? Math.min(startLine + effectiveLimit, allLines.length) : allLines.length;
|
|
275
|
+
const selectedLines = rangeSelection?.selectedLines ?? allLines.slice(startLine, endLine);
|
|
276
|
+
const selectedText = selectedLines.join("\n");
|
|
277
|
+
if (selectedText.length > READ_TOOL_MAX_RESULT_CHARS || Buffer.byteLength(selectedText, "utf8") > DEFAULT_MAX_BYTES) {
|
|
278
|
+
resolve(oversizedReadResult({ blocked: true, path: effectivePath, chars: selectedText.length, maxChars: READ_TOOL_MAX_RESULT_CHARS, startLine: startLine + 1, totalFileLines: allLines.length, firstLineBytes: Buffer.byteLength(selectedLines[0] ?? "", "utf8"), byteGuidance: false }));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
resolve({ content: [{ type: "text", text: selectedText }], details: readSourceMeta(effectivePath) });
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (isReadResourceSelector(effectivePath))
|
|
285
|
+
throw new Error(`Read resource selectors are not supported by this filesystem backend: ${path}`);
|
|
286
|
+
const absolutePath = await resolveReadPathAsync(effectivePath, cwd);
|
|
199
287
|
if (aborted)
|
|
200
288
|
return;
|
|
201
|
-
|
|
289
|
+
let content;
|
|
290
|
+
let details;
|
|
202
291
|
await ops.access(absolutePath);
|
|
203
292
|
if (aborted)
|
|
204
293
|
return;
|
|
294
|
+
if (isDocumentPath(absolutePath) && !rawOutput && !isNotebookPath(absolutePath)) {
|
|
295
|
+
const buffer = await ops.readFile(absolutePath);
|
|
296
|
+
const textContent = await extractDocumentMarkdown(buffer, absolutePath);
|
|
297
|
+
const selection = applyReadLineSelection(textContent.split("\n"), effectiveRanges, effectiveOffset, effectiveLimit, rawOutput);
|
|
298
|
+
if (selection.lines.length === 0) {
|
|
299
|
+
resolve({ content: [{ type: "text", text: `Requested line ${selection.firstLine} is beyond end of document (${textContent.split("\n").length} lines total).` }], details: undefined });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const selectedText = selection.lines.join("\n");
|
|
303
|
+
if (selectedText.length > READ_TOOL_MAX_RESULT_CHARS || Buffer.byteLength(selectedText, "utf8") > DEFAULT_MAX_BYTES) {
|
|
304
|
+
resolve(oversizedReadResult({ blocked: true, path: absolutePath, chars: selectedText.length, maxChars: READ_TOOL_MAX_RESULT_CHARS, startLine: selection.firstLine, totalFileLines: textContent.split("\n").length, firstLineBytes: Buffer.byteLength(selection.lines[0] ?? "", "utf8"), byteGuidance: false }));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
content = [{ type: "text", text: selectedText }];
|
|
308
|
+
resolve({ content, details: readSourceMeta(absolutePath) });
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (!options?.operations && (await fsStat(absolutePath)).isDirectory()) {
|
|
312
|
+
const tree = await buildDirectoryTree(absolutePath, { maxDepth: 2, perDirLimit: 12, rootLimit: null });
|
|
313
|
+
const allLines = tree.rendered.split("\n"), rangeSelection = (rawOutput ? selectExactReadRanges : selectReadRanges)(allLines, effectiveRanges), startLine = rangeSelection ? rangeSelection.firstLine - 1 : effectiveOffset ? Math.max(0, effectiveOffset - 1) : 0;
|
|
314
|
+
if (startLine >= allLines.length || (effectiveRanges && rangeSelection?.selectedLines.length === 0)) {
|
|
315
|
+
resolve({ content: [{ type: "text", text: `Requested line ${startLine + 1} is beyond end of directory (${allLines.length} lines total).` }], details: undefined });
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const endLine = effectiveLimit !== undefined ? Math.min(startLine + effectiveLimit, allLines.length) : allLines.length, selectedLines = rangeSelection?.selectedLines ?? allLines.slice(startLine, endLine);
|
|
319
|
+
content = [{ type: "text", text: selectedLines.join("\n") }];
|
|
320
|
+
const meta = { ...readSourceMeta(absolutePath).meta, ...(tree.truncated ? { limits: { perDirLimit: 12, totalLines: tree.totalLines } } : {}) };
|
|
321
|
+
resolve({ content, details: { isDirectory: true, resolvedPath: absolutePath, meta } });
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
205
324
|
const mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;
|
|
206
|
-
let content;
|
|
207
|
-
let details;
|
|
208
325
|
const nonVisionImageNote = getNonVisionImageNote(ctx?.model);
|
|
209
326
|
if (mimeType) {
|
|
210
|
-
// Read image as binary.
|
|
211
327
|
const buffer = await ops.readFile(absolutePath);
|
|
212
328
|
if (autoResizeImages) {
|
|
213
|
-
// Resize image if needed before sending it back to the model.
|
|
214
329
|
const resized = await resizeImage(buffer, mimeType);
|
|
215
330
|
if (!resized) {
|
|
216
331
|
let textNote = `Read image file [${mimeType}]\n[Image omitted: could not be resized below the inline image size limit.]`;
|
|
@@ -242,24 +357,52 @@ export function createReadToolDefinition(cwd, options) {
|
|
|
242
357
|
}
|
|
243
358
|
}
|
|
244
359
|
else {
|
|
245
|
-
// Read text content.
|
|
246
360
|
const buffer = await ops.readFile(absolutePath);
|
|
247
|
-
const textContent = buffer.toString("utf-8");
|
|
248
|
-
|
|
361
|
+
const textContent = (isNotebookPath(absolutePath) && !rawOutput) ? readEditableNotebookText(absolutePath, effectivePath) : buffer.toString("utf-8");
|
|
362
|
+
let allLines = textContent.split("\n");
|
|
363
|
+
let conflictLineNumbers;
|
|
364
|
+
if (conflictsOnly) {
|
|
365
|
+
registerConflictBlocks(cwd, parseConflictBlocks(absolutePath, textContent));
|
|
366
|
+
const conflictLines = [];
|
|
367
|
+
conflictLineNumbers = [];
|
|
368
|
+
let inConflict = false;
|
|
369
|
+
allLines.forEach((line, index) => {
|
|
370
|
+
if (line.startsWith("<<<<<<<"))
|
|
371
|
+
inConflict = true;
|
|
372
|
+
if (inConflict) {
|
|
373
|
+
conflictLines.push(line);
|
|
374
|
+
conflictLineNumbers.push(index + 1);
|
|
375
|
+
}
|
|
376
|
+
if (line.startsWith(">>>>>>>"))
|
|
377
|
+
inConflict = false;
|
|
378
|
+
});
|
|
379
|
+
if (conflictLines.length > 0)
|
|
380
|
+
allLines = conflictLines;
|
|
381
|
+
else {
|
|
382
|
+
signal?.removeEventListener("abort", onAbort);
|
|
383
|
+
resolve({ content: [{ type: "text", text: "No conflict markers found" }], details: undefined });
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
249
387
|
const totalFileLines = allLines.length;
|
|
250
|
-
|
|
251
|
-
const startLine =
|
|
388
|
+
const rangeSelection = (rawOutput ? selectExactReadRanges : selectReadRanges)(allLines, effectiveRanges);
|
|
389
|
+
const startLine = rangeSelection ? rangeSelection.firstLine - 1 : effectiveOffset ? Math.max(0, effectiveOffset - 1) : 0;
|
|
252
390
|
const startLineDisplay = startLine + 1;
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
391
|
+
if (startLine >= allLines.length || (effectiveRanges && rangeSelection?.selectedLines.length === 0)) {
|
|
392
|
+
const requested = effectiveRanges?.[0]?.start ?? startLineDisplay;
|
|
393
|
+
resolve({ content: [{ type: "text", text: `Requested line ${requested} is beyond end of file (${allLines.length} lines total). Use ${effectivePath}:${Math.max(1, allLines.length)} to read the final line.` }], details: undefined });
|
|
394
|
+
return;
|
|
256
395
|
}
|
|
257
396
|
let selectedContent;
|
|
258
397
|
let selectedLines;
|
|
259
398
|
let userLimitedLines;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
399
|
+
if (rangeSelection) {
|
|
400
|
+
selectedLines = rangeSelection.selectedLines;
|
|
401
|
+
selectedContent = rangeSelection.selectedContent;
|
|
402
|
+
userLimitedLines = rangeSelection.userLimitedLines;
|
|
403
|
+
}
|
|
404
|
+
else if (effectiveLimit !== undefined) {
|
|
405
|
+
const endLine = Math.min(startLine + effectiveLimit, allLines.length);
|
|
263
406
|
selectedLines = allLines.slice(startLine, endLine);
|
|
264
407
|
selectedContent = selectedLines.join("\n");
|
|
265
408
|
userLimitedLines = endLine - startLine;
|
|
@@ -273,60 +416,47 @@ export function createReadToolDefinition(cwd, options) {
|
|
|
273
416
|
const firstLineBytes = Buffer.byteLength(firstSelectedLine, "utf-8");
|
|
274
417
|
const selectedLineCount = trimTrailingEmptyLines(selectedLines).length;
|
|
275
418
|
const byteGuidance = selectedLineCount <= 1 || firstLineBytes > DEFAULT_MAX_BYTES;
|
|
276
|
-
const oversizedRead = {
|
|
277
|
-
|
|
278
|
-
path: absolutePath,
|
|
279
|
-
chars: selectedContent.length,
|
|
280
|
-
maxChars: READ_TOOL_MAX_RESULT_CHARS,
|
|
281
|
-
startLine: startLineDisplay,
|
|
282
|
-
...(limit !== undefined ? { requestedLimit: limit } : {}),
|
|
283
|
-
totalFileLines,
|
|
284
|
-
firstLineBytes,
|
|
285
|
-
byteGuidance,
|
|
286
|
-
};
|
|
287
|
-
details = { oversizedRead };
|
|
419
|
+
const oversizedRead = { blocked: true, path: absolutePath, chars: selectedContent.length, maxChars: READ_TOOL_MAX_RESULT_CHARS, startLine: startLineDisplay, ...(effectiveLimit !== undefined ? { requestedLimit: effectiveLimit } : {}), totalFileLines, firstLineBytes, byteGuidance };
|
|
420
|
+
details = { oversizedRead, meta: readSourceMeta(absolutePath).meta };
|
|
288
421
|
content = [{ type: "text", text: buildOversizedReadMessage(oversizedRead) }];
|
|
289
422
|
}
|
|
290
423
|
else {
|
|
291
|
-
// Apply truncation, respecting both line and byte limits.
|
|
292
424
|
const truncation = truncateHead(selectedContent);
|
|
293
|
-
let outputText;
|
|
425
|
+
let outputText = truncation.content;
|
|
294
426
|
if (truncation.firstLineExceedsLimit) {
|
|
295
|
-
// First line alone exceeds the byte limit. Point the model at a bash fallback.
|
|
296
427
|
const firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], "utf-8"));
|
|
297
|
-
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${
|
|
298
|
-
details = { truncation };
|
|
428
|
+
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${effectivePath} | head -c ${DEFAULT_MAX_BYTES}]`;
|
|
429
|
+
details = { truncation, meta: { source: absolutePath, sourcePath: absolutePath, truncation } };
|
|
299
430
|
}
|
|
300
431
|
else if (truncation.truncated) {
|
|
301
|
-
// Truncation occurred. Build an actionable continuation notice.
|
|
302
432
|
const endLineDisplay = startLineDisplay + truncation.outputLines - 1;
|
|
303
433
|
const nextOffset = endLineDisplay + 1;
|
|
304
|
-
outputText
|
|
305
|
-
|
|
306
|
-
outputText += `\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
outputText += `\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;
|
|
310
|
-
}
|
|
311
|
-
details = { truncation };
|
|
434
|
+
outputText += truncation.truncatedBy === "lines" ? `\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Continue with path selector :${nextOffset}.]` : `\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Continue with path selector :${nextOffset}.]`;
|
|
435
|
+
details = { truncation, meta: { source: absolutePath, sourcePath: absolutePath, truncation } };
|
|
312
436
|
}
|
|
313
|
-
else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {
|
|
314
|
-
// User-specified limit stopped early, but the file still has more content.
|
|
437
|
+
else if (!rawOutput && userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {
|
|
315
438
|
const remaining = allLines.length - (startLine + userLimitedLines);
|
|
316
439
|
const nextOffset = startLine + userLimitedLines + 1;
|
|
317
|
-
outputText = `${truncation.content}\n\n[${remaining} more lines in file.
|
|
440
|
+
outputText = `${truncation.content}\n\n[${remaining} more lines in file. Continue with path selector :${nextOffset}.]`;
|
|
318
441
|
}
|
|
442
|
+
if (truncation.firstLineExceedsLimit)
|
|
443
|
+
content = [{ type: "text", text: outputText }];
|
|
319
444
|
else {
|
|
320
|
-
|
|
321
|
-
|
|
445
|
+
const snapshot = recordHashlineSnapshot(absolutePath, cwd, textContent, hashlineStore);
|
|
446
|
+
const visibleContent = truncation.truncated ? truncation.content : selectedContent;
|
|
447
|
+
const header = `[${snapshot.displayPath}#${snapshot.tag}]`;
|
|
448
|
+
const selectedConflictLineNumbers = conflictLineNumbers && rangeSelection?.lineNumbers ? rangeSelection.lineNumbers.map((line) => conflictLineNumbers[line - 1]).filter((line) => typeof line === "number") : conflictLineNumbers ? conflictLineNumbers.slice(startLine, startLine + selectedLines.length) : undefined;
|
|
449
|
+
let hashlineOutput = rawOutput ? visibleContent : selectedConflictLineNumbers && visibleContent === selectedContent ? formatHashlineSelectedLines(header, selectedLines, selectedConflictLineNumbers) : rangeSelection && visibleContent === selectedContent ? formatHashlineSelectedLines(header, selectedLines, rangeSelection.lineNumbers) : formatHashlineContent(snapshot, visibleContent, startLineDisplay);
|
|
450
|
+
if (outputText.startsWith(truncation.content) && outputText.length > truncation.content.length)
|
|
451
|
+
hashlineOutput += outputText.slice(truncation.content.length);
|
|
452
|
+
content = [{ type: "text", text: hashlineOutput }];
|
|
322
453
|
}
|
|
323
|
-
content = [{ type: "text", text: outputText }];
|
|
324
454
|
}
|
|
325
455
|
}
|
|
326
456
|
if (aborted)
|
|
327
457
|
return;
|
|
328
458
|
signal?.removeEventListener("abort", onAbort);
|
|
329
|
-
resolve({ content, details });
|
|
459
|
+
resolve({ content, details: details ?? readSourceMeta(absolutePath) });
|
|
330
460
|
}
|
|
331
461
|
catch (error) {
|
|
332
462
|
signal?.removeEventListener("abort", onAbort);
|