@selesai/code 0.13.15 → 0.13.18
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 +37 -0
- package/README.md +2 -14
- package/dist/bun/cli.d.ts +3 -1
- package/dist/bun/cli.js +3 -9
- package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
- package/dist/bun/sandbox-env-setup.d.ts +1 -0
- package/dist/bun/sandbox-env-setup.js +3 -0
- package/dist/cli/auth-command.d.ts +23 -0
- package/dist/cli/auth-command.js +102 -0
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/setup.d.ts +1 -0
- package/dist/cli/setup.js +11 -0
- package/dist/cli.js +2 -14
- package/dist/config.d.ts +3 -2
- package/dist/config.js +9 -4
- package/dist/core/agent-session-runtime.js +15 -7
- package/dist/core/agent-session.d.ts +2 -6
- package/dist/core/agent-session.js +15 -4
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -1
- package/dist/core/extensions/loader.js +3 -0
- package/dist/core/extensions/types.d.ts +16 -2
- package/dist/core/http-dispatcher.js +2 -0
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.js +4 -0
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/model-config.d.ts +15 -0
- package/dist/core/model-config.js +3 -0
- package/dist/core/model-runtime.d.ts +1 -0
- package/dist/core/model-runtime.js +5 -2
- package/dist/core/provider-composer.js +8 -2
- package/dist/core/session-export.d.ts +3 -0
- package/dist/core/session-export.js +31 -0
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.js +40 -13
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.js +4 -2
- package/dist/core/system-prompt.js +10 -10
- package/dist/core/tools/bash.js +3 -117
- package/dist/core/tools/edit.d.ts +1 -12
- package/dist/core/tools/edit.js +5 -163
- package/dist/core/tools/find.js +4 -55
- package/dist/core/tools/grep.js +4 -60
- package/dist/core/tools/ls.js +4 -49
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.js +10 -122
- package/dist/core/tools/renderers/bash.d.ts +11 -0
- package/dist/core/tools/renderers/bash.js +129 -0
- package/dist/core/tools/renderers/edit.d.ts +22 -0
- package/dist/core/tools/renderers/edit.js +166 -0
- package/dist/core/tools/renderers/find.d.ts +9 -0
- package/dist/core/tools/renderers/find.js +63 -0
- package/dist/core/tools/renderers/grep.d.ts +9 -0
- package/dist/core/tools/renderers/grep.js +68 -0
- package/dist/core/tools/renderers/index.d.ts +27 -0
- package/dist/core/tools/renderers/index.js +46 -0
- package/dist/core/tools/renderers/ls.d.ts +9 -0
- package/dist/core/tools/renderers/ls.js +57 -0
- package/dist/core/tools/renderers/read.d.ts +10 -0
- package/dist/core/tools/renderers/read.js +128 -0
- package/dist/core/tools/renderers/write.d.ts +9 -0
- package/dist/core/tools/renderers/write.js +152 -0
- package/dist/core/tools/write.js +5 -146
- package/dist/extensions/capability-gateway/index.ts +12 -1
- package/dist/extensions/capability-gateway/integration.test.ts +23 -0
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
- package/dist/extensions/pi-hermes-memory/README.md +16 -12
- package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
- package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
- package/dist/extensions/pi-hermes-memory/package.json +4 -4
- package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
- package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
- package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
- package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
- package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
- package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
- package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
- package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
- package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
- package/dist/extensions/pi-intercom/README.md +16 -2
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
- package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
- package/dist/extensions/pi-intercom/index.ts +1 -1
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
- package/dist/extensions/pi-intercom/package.json +1 -1
- package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
- package/dist/extensions/pi-intercom/project-agent.ts +1 -6
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
- package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
- package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
- package/dist/extensions/pi-subagents/README.md +3 -3
- package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
- package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
- package/dist/extensions/pi-subagents/agents/scout.md +1 -1
- package/dist/extensions/pi-subagents/docs/agents.md +32 -16
- package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
- package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
- package/dist/extensions/pi-subagents/docs/missions.md +2 -0
- package/dist/extensions/pi-subagents/docs/models.md +58 -1
- package/dist/extensions/pi-subagents/docs/observability.md +50 -12
- package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
- package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
- package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
- package/dist/extensions/pi-subagents/package-lock.json +747 -177
- package/dist/extensions/pi-subagents/package.json +6 -4
- package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
- package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
- package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
- package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
- package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
- package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
- package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
- package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
- package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
- package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
- package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
- package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
- package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
- package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
- package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
- package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
- package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
- package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
- package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
- package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
- package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
- package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
- package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
- package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
- package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
- package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
- package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
- package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
- package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
- package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
- package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
- package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
- package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
- package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
- package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
- package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
- package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
- package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
- package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
- package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
- package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
- package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
- package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
- package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
- package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
- package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
- package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
- package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
- package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
- package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
- package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
- package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
- package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
- package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
- package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
- package/dist/extensions/pi-web-agent/src/types.ts +1 -1
- package/dist/extensions/pi-zentui/README.md +17 -0
- package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
- package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
- package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
- package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
- package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
- package/dist/extensions/pi-zentui/package-lock.json +277 -517
- package/dist/extensions/pi-zentui/package.json +7 -4
- package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
- package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
- package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
- package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
- package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
- package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
- package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
- package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
- package/dist/index.d.ts +1 -1
- package/dist/main.js +4 -1
- package/dist/modes/interactive/chat-viewport.d.ts +19 -0
- package/dist/modes/interactive/chat-viewport.js +27 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
- package/dist/modes/interactive/components/assistant-message.js +30 -13
- package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
- package/dist/modes/interactive/components/custom-editor.js +39 -1
- package/dist/modes/interactive/components/first-time-setup.js +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
- package/dist/modes/interactive/components/markdown-transform.js +18 -0
- package/dist/modes/interactive/components/model-selector.js +19 -17
- package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
- package/dist/modes/interactive/components/settings-selector.js +128 -20
- package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
- package/dist/modes/interactive/components/settings-submenu.js +164 -0
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
- package/dist/modes/interactive/components/status-indicator.js +10 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.js +75 -18
- package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
- package/dist/modes/interactive/components/tool-execution.js +35 -33
- package/dist/modes/interactive/components/trust-selector.js +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts +13 -15
- package/dist/modes/interactive/interactive-mode.js +144 -80
- package/dist/modes/interactive/session-share.d.ts +15 -0
- package/dist/modes/interactive/session-share.js +183 -0
- package/dist/modes/interactive/theme/dark.json +2 -1
- package/dist/modes/interactive/theme/light.json +2 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +5 -0
- package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
- package/dist/modes/interactive/theme/theme-json.js +129 -0
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +14 -5
- package/dist/modes/interactive/theme/theme.js +18 -119
- package/dist/modes/interactive/tui-renderer.d.ts +20 -0
- package/dist/modes/interactive/tui-renderer.js +65 -0
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/management-http.d.ts +24 -0
- package/dist/utils/management-http.js +53 -0
- package/dist/utils/text.d.ts +7 -0
- package/dist/utils/text.js +8 -0
- package/dist/utils/tools-manager.d.ts +1 -0
- package/dist/utils/tools-manager.js +43 -21
- package/docs/docs.json +0 -4
- package/package.json +4 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
- package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
- package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
- package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
- package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
- package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
- package/dist/skills/implanger/SKILL.md +0 -70
- package/dist/skills/output/SKILL.md +0 -49
- package/dist/skills/planger/SKILL.md +0 -167
- package/dist/skills/workflow/SKILL.md +0 -95
- package/docs/workflows.md +0 -18
- /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in tool renderers, without the tools themselves.
|
|
3
|
+
*
|
|
4
|
+
* A presentation displays tool calls and results; it does not execute them and does not need their
|
|
5
|
+
* typebox parameter schemas. Importing this instead of `core/tools/index.ts` keeps ~17 MB of module
|
|
6
|
+
* graph out of a process that only renders.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from "../../extensions/types.ts";
|
|
9
|
+
import type { ToolName } from "../index.ts";
|
|
10
|
+
import { createShellRenderers } from "./bash.ts";
|
|
11
|
+
import { editRenderers } from "./edit.ts";
|
|
12
|
+
import { findRenderers } from "./find.ts";
|
|
13
|
+
import { grepRenderers } from "./grep.ts";
|
|
14
|
+
import { lsRenderers } from "./ls.ts";
|
|
15
|
+
import { readRenderers } from "./read.ts";
|
|
16
|
+
import { writeRenderers } from "./write.ts";
|
|
17
|
+
export type ToolRenderers = Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
|
|
18
|
+
export { createShellRenderers, editRenderers, findRenderers, grepRenderers, lsRenderers, readRenderers, writeRenderers, };
|
|
19
|
+
/** Renderers for every built-in tool, keyed by tool name. */
|
|
20
|
+
export declare function createAllToolRenderers(): Record<ToolName, ToolRenderers>;
|
|
21
|
+
/**
|
|
22
|
+
* Merge built-in renderers into a tool definition that does not supply its own.
|
|
23
|
+
*
|
|
24
|
+
* `ToolExecutionComponent` used to do this lookup itself, which forced every presentation to import
|
|
25
|
+
* the tool implementations. Callers do it now, so a process that renders can import renderers alone.
|
|
26
|
+
*/
|
|
27
|
+
export declare function withBuiltInRenderers<TDefinition extends ToolRenderers>(toolName: string, definition: TDefinition | undefined): TDefinition | ToolRenderers | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in tool renderers, without the tools themselves.
|
|
3
|
+
*
|
|
4
|
+
* A presentation displays tool calls and results; it does not execute them and does not need their
|
|
5
|
+
* typebox parameter schemas. Importing this instead of `core/tools/index.ts` keeps ~17 MB of module
|
|
6
|
+
* graph out of a process that only renders.
|
|
7
|
+
*/
|
|
8
|
+
import { createShellRenderers } from "./bash.js";
|
|
9
|
+
import { editRenderers } from "./edit.js";
|
|
10
|
+
import { findRenderers } from "./find.js";
|
|
11
|
+
import { grepRenderers } from "./grep.js";
|
|
12
|
+
import { lsRenderers } from "./ls.js";
|
|
13
|
+
import { readRenderers } from "./read.js";
|
|
14
|
+
import { writeRenderers } from "./write.js";
|
|
15
|
+
export { createShellRenderers, editRenderers, findRenderers, grepRenderers, lsRenderers, readRenderers, writeRenderers, };
|
|
16
|
+
/** Renderers for every built-in tool, keyed by tool name. */
|
|
17
|
+
export function createAllToolRenderers() {
|
|
18
|
+
return {
|
|
19
|
+
read: readRenderers,
|
|
20
|
+
bash: createShellRenderers("$"),
|
|
21
|
+
powershell: createShellRenderers("PS>"),
|
|
22
|
+
edit: editRenderers,
|
|
23
|
+
write: writeRenderers,
|
|
24
|
+
grep: grepRenderers,
|
|
25
|
+
find: findRenderers,
|
|
26
|
+
ls: lsRenderers,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Merge built-in renderers into a tool definition that does not supply its own.
|
|
31
|
+
*
|
|
32
|
+
* `ToolExecutionComponent` used to do this lookup itself, which forced every presentation to import
|
|
33
|
+
* the tool implementations. Callers do it now, so a process that renders can import renderers alone.
|
|
34
|
+
*/
|
|
35
|
+
export function withBuiltInRenderers(toolName, definition) {
|
|
36
|
+
const builtIn = createAllToolRenderers()[toolName];
|
|
37
|
+
if (!definition)
|
|
38
|
+
return builtIn;
|
|
39
|
+
if (!builtIn)
|
|
40
|
+
return definition;
|
|
41
|
+
return {
|
|
42
|
+
...definition,
|
|
43
|
+
renderCall: definition.renderCall ?? builtIn.renderCall,
|
|
44
|
+
renderResult: definition.renderResult ?? builtIn.renderResult,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the ls tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `ls.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from "../../extensions/types.ts";
|
|
9
|
+
export declare const lsRenderers: Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the ls tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `ls.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
9
|
+
import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
|
|
10
|
+
import { getTextOutput, renderToolPath, str } from "../render-utils.js";
|
|
11
|
+
import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
|
|
12
|
+
function formatLsCall(args, theme, cwd) {
|
|
13
|
+
const limit = args?.limit;
|
|
14
|
+
const pathDisplay = renderToolPath(str(args?.path), theme, cwd, { emptyFallback: "." });
|
|
15
|
+
let text = `${theme.fg("toolTitle", theme.bold("ls"))} ${pathDisplay}`;
|
|
16
|
+
if (limit !== undefined) {
|
|
17
|
+
text += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
18
|
+
}
|
|
19
|
+
return text;
|
|
20
|
+
}
|
|
21
|
+
function formatLsResult(result, options, theme, showImages) {
|
|
22
|
+
const output = getTextOutput(result, showImages).trim();
|
|
23
|
+
let text = "";
|
|
24
|
+
if (output) {
|
|
25
|
+
const lines = output.split("\n");
|
|
26
|
+
const maxLines = options.expanded ? lines.length : 20;
|
|
27
|
+
const displayLines = lines.slice(0, maxLines);
|
|
28
|
+
const remaining = lines.length - maxLines;
|
|
29
|
+
text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
|
|
30
|
+
if (remaining > 0) {
|
|
31
|
+
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const entryLimit = result.details?.entryLimitReached;
|
|
35
|
+
const truncation = result.details?.truncation;
|
|
36
|
+
if (entryLimit || truncation?.truncated) {
|
|
37
|
+
const warnings = [];
|
|
38
|
+
if (entryLimit)
|
|
39
|
+
warnings.push(`${entryLimit} entries limit`);
|
|
40
|
+
if (truncation?.truncated)
|
|
41
|
+
warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
|
|
42
|
+
text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
|
|
43
|
+
}
|
|
44
|
+
return text;
|
|
45
|
+
}
|
|
46
|
+
export const lsRenderers = {
|
|
47
|
+
renderCall(args, theme, context) {
|
|
48
|
+
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
49
|
+
text.setText(formatLsCall(args, theme, context.cwd));
|
|
50
|
+
return text;
|
|
51
|
+
},
|
|
52
|
+
renderResult(result, options, theme, context) {
|
|
53
|
+
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
54
|
+
text.setText(formatLsResult(result, options, theme, context.showImages));
|
|
55
|
+
return text;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the read tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `read.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from "../../extensions/types.ts";
|
|
9
|
+
import type { ReadToolDetails } from "../read.ts";
|
|
10
|
+
export declare const readRenderers: Pick<ToolDefinition<any, ReadToolDetails | undefined>, "renderCall" | "renderResult">;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the read tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `read.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
|
|
9
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
10
|
+
import { getReadmePath } from "../../../config.js";
|
|
11
|
+
import { keyHint, keyText } from "../../../modes/interactive/components/keybinding-hints.js";
|
|
12
|
+
import { getLanguageFromPath, highlightCode } from "../../../modes/interactive/theme/theme.js";
|
|
13
|
+
import { formatPathRelativeToCwdOrAbsolute } from "../../../utils/paths.js";
|
|
14
|
+
import { resolveToCwd } from "../path-utils.js";
|
|
15
|
+
import { getTextOutput, renderToolPath, replaceTabs, str } from "../render-utils.js";
|
|
16
|
+
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "../truncate.js";
|
|
17
|
+
const COMPACT_RESOURCE_FILE_NAMES = new Set(["AGENTS.override.md", "AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"]);
|
|
18
|
+
function formatReadLineRange(args, theme) {
|
|
19
|
+
if (args?.offset === undefined && args?.limit === undefined)
|
|
20
|
+
return "";
|
|
21
|
+
const startLine = args.offset ?? 1;
|
|
22
|
+
const endLine = args.limit !== undefined ? startLine + args.limit - 1 : "";
|
|
23
|
+
return theme.fg("warning", `:${startLine}${endLine ? `-${endLine}` : ""}`);
|
|
24
|
+
}
|
|
25
|
+
function formatReadCall(args, theme, cwd) {
|
|
26
|
+
const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);
|
|
27
|
+
return `${theme.fg("toolTitle", theme.bold("read"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;
|
|
28
|
+
}
|
|
29
|
+
function trimTrailingEmptyLines(lines) {
|
|
30
|
+
let end = lines.length;
|
|
31
|
+
while (end > 0 && lines[end - 1] === "") {
|
|
32
|
+
end--;
|
|
33
|
+
}
|
|
34
|
+
return lines.slice(0, end);
|
|
35
|
+
}
|
|
36
|
+
function toPosixPath(filePath) {
|
|
37
|
+
return filePath.split(sep).join("/");
|
|
38
|
+
}
|
|
39
|
+
function getPiDocsClassification(absolutePath) {
|
|
40
|
+
const packageRoot = dirname(getReadmePath());
|
|
41
|
+
const relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));
|
|
42
|
+
if (relativePath === "" ||
|
|
43
|
+
relativePath === ".." ||
|
|
44
|
+
relativePath.startsWith(`..${sep}`) ||
|
|
45
|
+
isAbsolute(relativePath)) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const label = toPosixPath(relativePath);
|
|
49
|
+
if (label === "README.md" || label.startsWith("docs/") || label.startsWith("examples/")) {
|
|
50
|
+
return { kind: "docs", label };
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
function getCompactReadClassification(args, cwd) {
|
|
55
|
+
const rawPath = str(args?.file_path ?? args?.path);
|
|
56
|
+
if (!rawPath)
|
|
57
|
+
return undefined;
|
|
58
|
+
const absolutePath = resolveToCwd(rawPath, cwd);
|
|
59
|
+
const fileName = basename(absolutePath);
|
|
60
|
+
if (fileName === "SKILL.md") {
|
|
61
|
+
return { kind: "skill", label: basename(dirname(absolutePath)) || fileName };
|
|
62
|
+
}
|
|
63
|
+
const docsClassification = getPiDocsClassification(absolutePath);
|
|
64
|
+
if (docsClassification)
|
|
65
|
+
return docsClassification;
|
|
66
|
+
if (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {
|
|
67
|
+
return { kind: "resource", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
function formatCompactReadCall(classification, args, theme) {
|
|
72
|
+
const expandHint = theme.fg("dim", ` (${keyText("app.tools.expand")} to expand)`);
|
|
73
|
+
if (classification.kind === "skill") {
|
|
74
|
+
return (theme.fg("customMessageLabel", `\x1b[1m[skill]\x1b[22m `) +
|
|
75
|
+
theme.fg("customMessageText", classification.label) +
|
|
76
|
+
formatReadLineRange(args, theme) +
|
|
77
|
+
expandHint);
|
|
78
|
+
}
|
|
79
|
+
return (theme.fg("toolTitle", theme.bold(`read ${classification.kind}`)) +
|
|
80
|
+
" " +
|
|
81
|
+
theme.fg("accent", classification.label) +
|
|
82
|
+
formatReadLineRange(args, theme) +
|
|
83
|
+
expandHint);
|
|
84
|
+
}
|
|
85
|
+
function formatReadResult(args, result, options, theme, showImages, _cwd, isError) {
|
|
86
|
+
if (!options.expanded && !isError) {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
const rawPath = str(args?.file_path ?? args?.path);
|
|
90
|
+
const output = getTextOutput(result, showImages);
|
|
91
|
+
const lang = !isError && rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
92
|
+
const renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split("\n");
|
|
93
|
+
const lines = trimTrailingEmptyLines(renderedLines);
|
|
94
|
+
const maxLines = options.expanded ? lines.length : 10;
|
|
95
|
+
const displayLines = lines.slice(0, maxLines);
|
|
96
|
+
const remaining = lines.length - maxLines;
|
|
97
|
+
let text = `\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line)))).join("\n")}`;
|
|
98
|
+
if (remaining > 0) {
|
|
99
|
+
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
100
|
+
}
|
|
101
|
+
const truncation = result.details?.truncation;
|
|
102
|
+
if (truncation?.truncated) {
|
|
103
|
+
if (truncation.firstLineExceedsLimit) {
|
|
104
|
+
text += `\n${theme.fg("warning", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;
|
|
105
|
+
}
|
|
106
|
+
else if (truncation.truncatedBy === "lines") {
|
|
107
|
+
text += `\n${theme.fg("warning", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
text += `\n${theme.fg("warning", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return text;
|
|
114
|
+
}
|
|
115
|
+
export const readRenderers = {
|
|
116
|
+
renderCall(rawArgs, theme, context) {
|
|
117
|
+
const args = rawArgs;
|
|
118
|
+
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
119
|
+
const classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;
|
|
120
|
+
text.setText(classification ? formatCompactReadCall(classification, args, theme) : formatReadCall(args, theme, context.cwd));
|
|
121
|
+
return text;
|
|
122
|
+
},
|
|
123
|
+
renderResult(result, options, theme, context) {
|
|
124
|
+
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
125
|
+
text.setText(formatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError));
|
|
126
|
+
return text;
|
|
127
|
+
},
|
|
128
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the write tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `write.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from "../../extensions/types.ts";
|
|
9
|
+
export declare const writeRenderers: Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation for the write tool.
|
|
3
|
+
*
|
|
4
|
+
* Renderers live apart from the implementation so a process that only displays tool output does not
|
|
5
|
+
* load the execution path or its typebox parameter schema. `write.ts` spreads these into its
|
|
6
|
+
* definition, so the tool's public shape is unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import { Container, Text } from "@earendil-works/pi-tui";
|
|
9
|
+
import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
|
|
10
|
+
import { getLanguageFromPath, highlightCode } from "../../../modes/interactive/theme/theme.js";
|
|
11
|
+
import { normalizeDisplayText, renderToolPath, replaceTabs, str } from "../render-utils.js";
|
|
12
|
+
class WriteCallRenderComponent extends Text {
|
|
13
|
+
cache;
|
|
14
|
+
constructor() {
|
|
15
|
+
super("", 0, 0);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const WRITE_PARTIAL_FULL_HIGHLIGHT_LINES = 50;
|
|
19
|
+
function highlightSingleLine(line, lang) {
|
|
20
|
+
const highlighted = highlightCode(line, lang);
|
|
21
|
+
return highlighted[0] ?? "";
|
|
22
|
+
}
|
|
23
|
+
function refreshWriteHighlightPrefix(cache) {
|
|
24
|
+
const prefixCount = Math.min(WRITE_PARTIAL_FULL_HIGHLIGHT_LINES, cache.normalizedLines.length);
|
|
25
|
+
if (prefixCount === 0)
|
|
26
|
+
return;
|
|
27
|
+
const prefixSource = cache.normalizedLines.slice(0, prefixCount).join("\n");
|
|
28
|
+
const prefixHighlighted = highlightCode(prefixSource, cache.lang);
|
|
29
|
+
for (let i = 0; i < prefixCount; i++) {
|
|
30
|
+
cache.highlightedLines[i] =
|
|
31
|
+
prefixHighlighted[i] ?? highlightSingleLine(cache.normalizedLines[i] ?? "", cache.lang);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function rebuildWriteHighlightCacheFull(rawPath, fileContent) {
|
|
35
|
+
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
36
|
+
if (!lang)
|
|
37
|
+
return undefined;
|
|
38
|
+
const displayContent = normalizeDisplayText(fileContent);
|
|
39
|
+
const normalized = replaceTabs(displayContent);
|
|
40
|
+
return {
|
|
41
|
+
rawPath,
|
|
42
|
+
lang,
|
|
43
|
+
rawContent: fileContent,
|
|
44
|
+
normalizedLines: normalized.split("\n"),
|
|
45
|
+
highlightedLines: highlightCode(normalized, lang),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function updateWriteHighlightCacheIncremental(cache, rawPath, fileContent) {
|
|
49
|
+
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
50
|
+
if (!lang)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (!cache)
|
|
53
|
+
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
54
|
+
if (cache.lang !== lang || cache.rawPath !== rawPath)
|
|
55
|
+
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
56
|
+
if (!fileContent.startsWith(cache.rawContent))
|
|
57
|
+
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
58
|
+
if (fileContent.length === cache.rawContent.length)
|
|
59
|
+
return cache;
|
|
60
|
+
const deltaRaw = fileContent.slice(cache.rawContent.length);
|
|
61
|
+
const deltaDisplay = normalizeDisplayText(deltaRaw);
|
|
62
|
+
const deltaNormalized = replaceTabs(deltaDisplay);
|
|
63
|
+
cache.rawContent = fileContent;
|
|
64
|
+
if (cache.normalizedLines.length === 0) {
|
|
65
|
+
cache.normalizedLines.push("");
|
|
66
|
+
cache.highlightedLines.push("");
|
|
67
|
+
}
|
|
68
|
+
const segments = deltaNormalized.split("\n");
|
|
69
|
+
const lastIndex = cache.normalizedLines.length - 1;
|
|
70
|
+
cache.normalizedLines[lastIndex] += segments[0];
|
|
71
|
+
cache.highlightedLines[lastIndex] = highlightSingleLine(cache.normalizedLines[lastIndex], cache.lang);
|
|
72
|
+
for (let i = 1; i < segments.length; i++) {
|
|
73
|
+
cache.normalizedLines.push(segments[i]);
|
|
74
|
+
cache.highlightedLines.push(highlightSingleLine(segments[i], cache.lang));
|
|
75
|
+
}
|
|
76
|
+
refreshWriteHighlightPrefix(cache);
|
|
77
|
+
return cache;
|
|
78
|
+
}
|
|
79
|
+
function trimTrailingEmptyLines(lines) {
|
|
80
|
+
let end = lines.length;
|
|
81
|
+
while (end > 0 && lines[end - 1] === "") {
|
|
82
|
+
end--;
|
|
83
|
+
}
|
|
84
|
+
return lines.slice(0, end);
|
|
85
|
+
}
|
|
86
|
+
function formatWriteCall(args, options, theme, cache, cwd) {
|
|
87
|
+
const rawPath = str(args?.file_path ?? args?.path);
|
|
88
|
+
const fileContent = str(args?.content);
|
|
89
|
+
const pathDisplay = renderToolPath(rawPath, theme, cwd);
|
|
90
|
+
let text = `${theme.fg("toolTitle", theme.bold("write"))} ${pathDisplay}`;
|
|
91
|
+
if (fileContent === null) {
|
|
92
|
+
text += `\n\n${theme.fg("error", "[invalid content arg - expected string]")}`;
|
|
93
|
+
}
|
|
94
|
+
else if (fileContent) {
|
|
95
|
+
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
96
|
+
const renderedLines = lang
|
|
97
|
+
? (cache?.highlightedLines ?? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang))
|
|
98
|
+
: normalizeDisplayText(fileContent).split("\n");
|
|
99
|
+
const lines = trimTrailingEmptyLines(renderedLines);
|
|
100
|
+
const totalLines = lines.length;
|
|
101
|
+
const maxLines = options.expanded ? lines.length : 10;
|
|
102
|
+
const displayLines = lines.slice(0, maxLines);
|
|
103
|
+
const remaining = lines.length - maxLines;
|
|
104
|
+
text += `\n\n${displayLines.map((line) => (lang ? line : theme.fg("toolOutput", replaceTabs(line)))).join("\n")}`;
|
|
105
|
+
if (remaining > 0) {
|
|
106
|
+
text += `${theme.fg("muted", `\n... (${remaining} more lines, ${totalLines} total,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
111
|
+
function formatWriteResult(result, theme) {
|
|
112
|
+
if (!result.isError) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
const output = result.content
|
|
116
|
+
.filter((c) => c.type === "text")
|
|
117
|
+
.map((c) => c.text || "")
|
|
118
|
+
.join("\n");
|
|
119
|
+
if (!output) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
return `\n${theme.fg("error", output)}`;
|
|
123
|
+
}
|
|
124
|
+
export const writeRenderers = {
|
|
125
|
+
renderCall(args, theme, context) {
|
|
126
|
+
const renderArgs = args;
|
|
127
|
+
const rawPath = str(renderArgs?.file_path ?? renderArgs?.path);
|
|
128
|
+
const fileContent = str(renderArgs?.content);
|
|
129
|
+
const component = context.lastComponent ?? new WriteCallRenderComponent();
|
|
130
|
+
if (fileContent !== null) {
|
|
131
|
+
component.cache = context.argsComplete
|
|
132
|
+
? rebuildWriteHighlightCacheFull(rawPath, fileContent)
|
|
133
|
+
: updateWriteHighlightCacheIncremental(component.cache, rawPath, fileContent);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
component.cache = undefined;
|
|
137
|
+
}
|
|
138
|
+
component.setText(formatWriteCall(renderArgs, { expanded: context.expanded, isPartial: context.isPartial }, theme, component.cache, context.cwd));
|
|
139
|
+
return component;
|
|
140
|
+
},
|
|
141
|
+
renderResult(result, _options, theme, context) {
|
|
142
|
+
const output = formatWriteResult({ ...result, isError: context.isError }, theme);
|
|
143
|
+
if (!output) {
|
|
144
|
+
const component = context.lastComponent ?? new Container();
|
|
145
|
+
component.clear();
|
|
146
|
+
return component;
|
|
147
|
+
}
|
|
148
|
+
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
149
|
+
text.setText(output);
|
|
150
|
+
return text;
|
|
151
|
+
},
|
|
152
|
+
};
|
package/dist/core/tools/write.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { Container, Text } from "@earendil-works/pi-tui";
|
|
2
1
|
import { mkdir as fsMkdir, writeFile as fsWriteFile } from "fs/promises";
|
|
3
2
|
import { dirname } from "path";
|
|
4
3
|
import { Type } from "typebox";
|
|
5
|
-
import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
|
|
6
|
-
import { getLanguageFromPath, highlightCode } from "../../modes/interactive/theme/theme.js";
|
|
7
4
|
import { getExperimentalToolSampling } from "../experimental.js";
|
|
8
5
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
9
6
|
import { resolveToCwd } from "./path-utils.js";
|
|
10
|
-
import {
|
|
7
|
+
import { writeRenderers } from "./renderers/write.js";
|
|
11
8
|
import { wrapToolDefinition } from "./tool-definition-wrapper.js";
|
|
12
9
|
const writeSchema = Type.Object({
|
|
13
10
|
path: Type.String({ description: "Path to the file to write (relative or absolute)" }),
|
|
@@ -17,118 +14,6 @@ const defaultWriteOperations = {
|
|
|
17
14
|
writeFile: (path, content) => fsWriteFile(path, content, "utf-8"),
|
|
18
15
|
mkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => { }),
|
|
19
16
|
};
|
|
20
|
-
class WriteCallRenderComponent extends Text {
|
|
21
|
-
cache;
|
|
22
|
-
constructor() {
|
|
23
|
-
super("", 0, 0);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
const WRITE_PARTIAL_FULL_HIGHLIGHT_LINES = 50;
|
|
27
|
-
function highlightSingleLine(line, lang) {
|
|
28
|
-
const highlighted = highlightCode(line, lang);
|
|
29
|
-
return highlighted[0] ?? "";
|
|
30
|
-
}
|
|
31
|
-
function refreshWriteHighlightPrefix(cache) {
|
|
32
|
-
const prefixCount = Math.min(WRITE_PARTIAL_FULL_HIGHLIGHT_LINES, cache.normalizedLines.length);
|
|
33
|
-
if (prefixCount === 0)
|
|
34
|
-
return;
|
|
35
|
-
const prefixSource = cache.normalizedLines.slice(0, prefixCount).join("\n");
|
|
36
|
-
const prefixHighlighted = highlightCode(prefixSource, cache.lang);
|
|
37
|
-
for (let i = 0; i < prefixCount; i++) {
|
|
38
|
-
cache.highlightedLines[i] =
|
|
39
|
-
prefixHighlighted[i] ?? highlightSingleLine(cache.normalizedLines[i] ?? "", cache.lang);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function rebuildWriteHighlightCacheFull(rawPath, fileContent) {
|
|
43
|
-
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
44
|
-
if (!lang)
|
|
45
|
-
return undefined;
|
|
46
|
-
const displayContent = normalizeDisplayText(fileContent);
|
|
47
|
-
const normalized = replaceTabs(displayContent);
|
|
48
|
-
return {
|
|
49
|
-
rawPath,
|
|
50
|
-
lang,
|
|
51
|
-
rawContent: fileContent,
|
|
52
|
-
normalizedLines: normalized.split("\n"),
|
|
53
|
-
highlightedLines: highlightCode(normalized, lang),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
function updateWriteHighlightCacheIncremental(cache, rawPath, fileContent) {
|
|
57
|
-
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
58
|
-
if (!lang)
|
|
59
|
-
return undefined;
|
|
60
|
-
if (!cache)
|
|
61
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
62
|
-
if (cache.lang !== lang || cache.rawPath !== rawPath)
|
|
63
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
64
|
-
if (!fileContent.startsWith(cache.rawContent))
|
|
65
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
66
|
-
if (fileContent.length === cache.rawContent.length)
|
|
67
|
-
return cache;
|
|
68
|
-
const deltaRaw = fileContent.slice(cache.rawContent.length);
|
|
69
|
-
const deltaDisplay = normalizeDisplayText(deltaRaw);
|
|
70
|
-
const deltaNormalized = replaceTabs(deltaDisplay);
|
|
71
|
-
cache.rawContent = fileContent;
|
|
72
|
-
if (cache.normalizedLines.length === 0) {
|
|
73
|
-
cache.normalizedLines.push("");
|
|
74
|
-
cache.highlightedLines.push("");
|
|
75
|
-
}
|
|
76
|
-
const segments = deltaNormalized.split("\n");
|
|
77
|
-
const lastIndex = cache.normalizedLines.length - 1;
|
|
78
|
-
cache.normalizedLines[lastIndex] += segments[0];
|
|
79
|
-
cache.highlightedLines[lastIndex] = highlightSingleLine(cache.normalizedLines[lastIndex], cache.lang);
|
|
80
|
-
for (let i = 1; i < segments.length; i++) {
|
|
81
|
-
cache.normalizedLines.push(segments[i]);
|
|
82
|
-
cache.highlightedLines.push(highlightSingleLine(segments[i], cache.lang));
|
|
83
|
-
}
|
|
84
|
-
refreshWriteHighlightPrefix(cache);
|
|
85
|
-
return cache;
|
|
86
|
-
}
|
|
87
|
-
function trimTrailingEmptyLines(lines) {
|
|
88
|
-
let end = lines.length;
|
|
89
|
-
while (end > 0 && lines[end - 1] === "") {
|
|
90
|
-
end--;
|
|
91
|
-
}
|
|
92
|
-
return lines.slice(0, end);
|
|
93
|
-
}
|
|
94
|
-
function formatWriteCall(args, options, theme, cache, cwd) {
|
|
95
|
-
const rawPath = str(args?.file_path ?? args?.path);
|
|
96
|
-
const fileContent = str(args?.content);
|
|
97
|
-
const pathDisplay = renderToolPath(rawPath, theme, cwd);
|
|
98
|
-
let text = `${theme.fg("toolTitle", theme.bold("write"))} ${pathDisplay}`;
|
|
99
|
-
if (fileContent === null) {
|
|
100
|
-
text += `\n\n${theme.fg("error", "[invalid content arg - expected string]")}`;
|
|
101
|
-
}
|
|
102
|
-
else if (fileContent) {
|
|
103
|
-
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
104
|
-
const renderedLines = lang
|
|
105
|
-
? (cache?.highlightedLines ?? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang))
|
|
106
|
-
: normalizeDisplayText(fileContent).split("\n");
|
|
107
|
-
const lines = trimTrailingEmptyLines(renderedLines);
|
|
108
|
-
const totalLines = lines.length;
|
|
109
|
-
const maxLines = options.expanded ? lines.length : 10;
|
|
110
|
-
const displayLines = lines.slice(0, maxLines);
|
|
111
|
-
const remaining = lines.length - maxLines;
|
|
112
|
-
text += `\n\n${displayLines.map((line) => (lang ? line : theme.fg("toolOutput", replaceTabs(line)))).join("\n")}`;
|
|
113
|
-
if (remaining > 0) {
|
|
114
|
-
text += `${theme.fg("muted", `\n... (${remaining} more lines, ${totalLines} total,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return text;
|
|
118
|
-
}
|
|
119
|
-
function formatWriteResult(result, theme) {
|
|
120
|
-
if (!result.isError) {
|
|
121
|
-
return undefined;
|
|
122
|
-
}
|
|
123
|
-
const output = result.content
|
|
124
|
-
.filter((c) => c.type === "text")
|
|
125
|
-
.map((c) => c.text || "")
|
|
126
|
-
.join("\n");
|
|
127
|
-
if (!output) {
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
return `\n${theme.fg("error", output)}`;
|
|
131
|
-
}
|
|
132
17
|
export function createWriteToolDefinition(cwd, options) {
|
|
133
18
|
const ops = options?.operations ?? defaultWriteOperations;
|
|
134
19
|
return {
|
|
@@ -139,8 +24,8 @@ export function createWriteToolDefinition(cwd, options) {
|
|
|
139
24
|
promptGuidelines: ["Use write only for new files or complete rewrites."],
|
|
140
25
|
parameters: writeSchema,
|
|
141
26
|
constrainedSampling: getExperimentalToolSampling(),
|
|
142
|
-
async execute(_toolCallId, { path, content }, signal, _onUpdate,
|
|
143
|
-
const absolutePath = resolveToCwd(path, cwd);
|
|
27
|
+
async execute(_toolCallId, { path, content }, signal, _onUpdate, ctx) {
|
|
28
|
+
const absolutePath = resolveToCwd(path, ctx?.cwd || cwd);
|
|
144
29
|
const dir = dirname(absolutePath);
|
|
145
30
|
return withFileMutationQueue(absolutePath, async () => {
|
|
146
31
|
// Do not reject from an abort event listener here: that would release the
|
|
@@ -159,38 +44,12 @@ export function createWriteToolDefinition(cwd, options) {
|
|
|
159
44
|
await ops.writeFile(absolutePath, content);
|
|
160
45
|
throwIfAborted();
|
|
161
46
|
return {
|
|
162
|
-
content: [{ type: "text", text: `Successfully wrote
|
|
47
|
+
content: [{ type: "text", text: `Successfully wrote to ${path}` }],
|
|
163
48
|
details: undefined,
|
|
164
49
|
};
|
|
165
50
|
});
|
|
166
51
|
},
|
|
167
|
-
|
|
168
|
-
const renderArgs = args;
|
|
169
|
-
const rawPath = str(renderArgs?.file_path ?? renderArgs?.path);
|
|
170
|
-
const fileContent = str(renderArgs?.content);
|
|
171
|
-
const component = context.lastComponent ?? new WriteCallRenderComponent();
|
|
172
|
-
if (fileContent !== null) {
|
|
173
|
-
component.cache = context.argsComplete
|
|
174
|
-
? rebuildWriteHighlightCacheFull(rawPath, fileContent)
|
|
175
|
-
: updateWriteHighlightCacheIncremental(component.cache, rawPath, fileContent);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
component.cache = undefined;
|
|
179
|
-
}
|
|
180
|
-
component.setText(formatWriteCall(renderArgs, { expanded: context.expanded, isPartial: context.isPartial }, theme, component.cache, context.cwd));
|
|
181
|
-
return component;
|
|
182
|
-
},
|
|
183
|
-
renderResult(result, _options, theme, context) {
|
|
184
|
-
const output = formatWriteResult({ ...result, isError: context.isError }, theme);
|
|
185
|
-
if (!output) {
|
|
186
|
-
const component = context.lastComponent ?? new Container();
|
|
187
|
-
component.clear();
|
|
188
|
-
return component;
|
|
189
|
-
}
|
|
190
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
191
|
-
text.setText(output);
|
|
192
|
-
return text;
|
|
193
|
-
},
|
|
52
|
+
...writeRenderers,
|
|
194
53
|
};
|
|
195
54
|
}
|
|
196
55
|
export function createWriteTool(cwd, options) {
|
|
@@ -62,6 +62,17 @@ function catalogEntries(pi: ExtensionAPI): CatalogEntry[] {
|
|
|
62
62
|
return [...tools, ...skills];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
const EMBEDDED_SKILL_BLOCK = /<skill\s+name="([^"]+)"[^>]*>[\s\S]*?<\/skill>/gi;
|
|
66
|
+
|
|
67
|
+
function routePrompt(prompt: string, entries: CatalogEntry[]): ReturnType<typeof route> {
|
|
68
|
+
const loadedSkills = new Set([...prompt.matchAll(EMBEDDED_SKILL_BLOCK)].map((match) => match[1]!.toLowerCase()));
|
|
69
|
+
const query = prompt.replace(EMBEDDED_SKILL_BLOCK, " ");
|
|
70
|
+
return route(
|
|
71
|
+
query,
|
|
72
|
+
entries.filter((entry) => entry.kind !== "skill" || !loadedSkills.has(entry.name.toLowerCase())),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
65
76
|
function formatCatalog(entries: CatalogEntry[]): string {
|
|
66
77
|
const lines = entries.map(
|
|
67
78
|
(entry) =>
|
|
@@ -253,7 +264,7 @@ export default function capabilityGatewayExtension(pi: ExtensionAPI): void {
|
|
|
253
264
|
// ambiguity hints, or nothing for unrelated prompts.
|
|
254
265
|
// ------------------------------------------------------------------
|
|
255
266
|
pi.on("before_agent_start", (event) => {
|
|
256
|
-
const result =
|
|
267
|
+
const result = routePrompt(event.prompt, catalogEntries(pi));
|
|
257
268
|
if (result.action === "none") return undefined;
|
|
258
269
|
if (result.action === "activate" && result.entry) {
|
|
259
270
|
const active = pi.getActiveTools();
|