@selesai/code 0.12.0 → 0.13.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 +17 -0
- package/dist/core/agent-session.d.ts +1 -1
- package/dist/core/agent-session.js +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.js +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/usage-totals.d.ts +2 -0
- package/dist/core/usage-totals.js +10 -0
- package/dist/extensions/ascii.txt +9 -0
- package/dist/extensions/package.json +1 -2
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +371 -0
- package/dist/extensions/pi-hermes-memory/LICENSE +21 -0
- package/dist/extensions/pi-hermes-memory/README.md +643 -0
- package/dist/extensions/pi-hermes-memory/docs/0.1/TASKS.md +197 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/PLAN.md +290 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/TASKS.md +134 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/TEST-PLAN.md +216 -0
- package/dist/extensions/pi-hermes-memory/docs/0.3/PLAN.md +330 -0
- package/dist/extensions/pi-hermes-memory/docs/0.3/TASKS.md +125 -0
- package/dist/extensions/pi-hermes-memory/docs/0.4/PLAN.md +160 -0
- package/dist/extensions/pi-hermes-memory/docs/0.4/TASKS.md +113 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/CHANGELOG.md +57 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/PLAN.md +202 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/TASKS.md +144 -0
- package/dist/extensions/pi-hermes-memory/docs/0.7/PLAN.md +349 -0
- package/dist/extensions/pi-hermes-memory/docs/0.7/TASKS.md +110 -0
- package/dist/extensions/pi-hermes-memory/docs/PUBLISHING.md +149 -0
- package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +468 -0
- package/dist/extensions/pi-hermes-memory/docs/images/memory-architecture.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi-logo.svg +22 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.png +0 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.svg +19 -0
- package/dist/extensions/pi-hermes-memory/docs/images/security-flow.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/session-lifecycle.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/source-architecture.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/memory-architecture.mmd +49 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/security-flow.mmd +40 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/session-lifecycle.mmd +56 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/source-architecture.mmd +54 -0
- package/dist/extensions/pi-hermes-memory/package-lock.json +3799 -0
- package/dist/extensions/pi-hermes-memory/package.json +66 -0
- package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +99 -0
- package/dist/extensions/pi-hermes-memory/scripts/ensure-dev.mjs +57 -0
- package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +6 -0
- package/dist/extensions/pi-hermes-memory/src/config.ts +178 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +424 -0
- package/dist/extensions/pi-hermes-memory/src/extension-root-migration.ts +639 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +401 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +297 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/child-process-watchdog.mjs +90 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +300 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +86 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +78 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/interview.ts +37 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/learn-memory.ts +186 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/message-parts.ts +27 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/pi-child-process.ts +485 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/preview-context.ts +105 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +506 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +145 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +151 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-live-index.ts +94 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +1334 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/standing-pin.ts +111 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/switch-project.ts +75 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +266 -0
- package/dist/extensions/pi-hermes-memory/src/index.ts +378 -0
- package/dist/extensions/pi-hermes-memory/src/lifecycle-timing.ts +54 -0
- package/dist/extensions/pi-hermes-memory/src/paths.ts +61 -0
- package/dist/extensions/pi-hermes-memory/src/project-context.ts +13 -0
- package/dist/extensions/pi-hermes-memory/src/project-memory-migration.ts +93 -0
- package/dist/extensions/pi-hermes-memory/src/project.ts +157 -0
- package/dist/extensions/pi-hermes-memory/src/prompt-context.ts +55 -0
- package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +375 -0
- package/dist/extensions/pi-hermes-memory/src/store/canonical-storage-path.ts +54 -0
- package/dist/extensions/pi-hermes-memory/src/store/content-scanner.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +1180 -0
- package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/markdown-mutation-lock.ts +38 -0
- package/dist/extensions/pi-hermes-memory/src/store/memory-lookup.ts +24 -0
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +1191 -0
- package/dist/extensions/pi-hermes-memory/src/store/recovery-maintenance.ts +66 -0
- package/dist/extensions/pi-hermes-memory/src/store/schema.ts +118 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-anchor-search.ts +472 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +511 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-parser.ts +213 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +234 -0
- package/dist/extensions/pi-hermes-memory/src/store/skill-store.ts +950 -0
- package/dist/extensions/pi-hermes-memory/src/store/skill-utils.ts +133 -0
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +1002 -0
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-native.ts +241 -0
- package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +247 -0
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +95 -0
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +469 -0
- package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +246 -0
- package/dist/extensions/pi-hermes-memory/src/tools/shared-output-view.ts +170 -0
- package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +333 -0
- package/dist/extensions/pi-hermes-memory/src/tools/tool-result-views.ts +105 -0
- package/dist/extensions/pi-hermes-memory/src/types.ts +214 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +434 -0
- package/dist/extensions/pi-hermes-memory/tests/extension-root-migration.test.ts +368 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +984 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +950 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/correction-detector.test.ts +671 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +157 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/interview.test.ts +127 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/pi-child-process.test.ts +905 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/preview-context.test.ts +152 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/prompt-context.test.ts +166 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/resources-discover.test.ts +71 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +614 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +192 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +677 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-live-index.test.ts +225 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +827 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/standing-pin.test.ts +134 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +491 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +199 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/thinking-max.test.ts +64 -0
- package/dist/extensions/pi-hermes-memory/tests/index.test.ts +30 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/flow.test.ts +126 -0
- package/dist/extensions/pi-hermes-memory/tests/lifecycle-timing.test.ts +76 -0
- package/dist/extensions/pi-hermes-memory/tests/paths.test.ts +23 -0
- package/dist/extensions/pi-hermes-memory/tests/project-memory-migration.test.ts +80 -0
- package/dist/extensions/pi-hermes-memory/tests/project-rebinding.test.ts +115 -0
- package/dist/extensions/pi-hermes-memory/tests/project.test.ts +120 -0
- package/dist/extensions/pi-hermes-memory/tests/run-all-timeout.test.ts +107 -0
- package/dist/extensions/pi-hermes-memory/tests/run-all.sh +45 -0
- package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-coordinator.test.ts +381 -0
- package/dist/extensions/pi-hermes-memory/tests/store/content-scanner.test.ts +388 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +1046 -0
- package/dist/extensions/pi-hermes-memory/tests/store/markdown-mutation-lock.test.ts +34 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +2150 -0
- package/dist/extensions/pi-hermes-memory/tests/store/recovery-maintenance.test.ts +170 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-anchor-search.test.ts +210 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +643 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-parser.test.ts +282 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +287 -0
- package/dist/extensions/pi-hermes-memory/tests/store/skill-store.test.ts +678 -0
- package/dist/extensions/pi-hermes-memory/tests/store/skill-utils.test.ts +21 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-lazy-load.test.ts +78 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +543 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +164 -0
- package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +171 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +84 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +709 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/session-search-tool.test.ts +345 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/shared-output-view.test.ts +362 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +478 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/tool-result-renderer-wiring.test.ts +40 -0
- package/dist/extensions/pi-hermes-memory/tsconfig.json +19 -0
- package/dist/extensions/pi-subagents/.oxlintrc.json +43 -0
- package/dist/extensions/pi-subagents/AGENTS.md +5 -0
- package/dist/extensions/pi-subagents/CHANGELOG.md +157 -0
- package/dist/extensions/pi-subagents/README.md +12 -6
- package/dist/extensions/pi-subagents/VISION.md +81 -0
- package/dist/extensions/pi-subagents/agents/claude-code-writer.md +15 -0
- package/dist/extensions/pi-subagents/agents/claude-code.md +15 -0
- package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +15 -0
- package/dist/extensions/pi-subagents/agents/codex-exec.md +15 -0
- package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +14 -0
- package/dist/extensions/pi-subagents/agents/cursor-agent.md +14 -0
- package/dist/extensions/pi-subagents/agents/reviewer.md +1 -3
- package/dist/extensions/pi-subagents/docs/agents.md +488 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +46 -9
- package/dist/extensions/pi-subagents/docs/extension-api.md +42 -3
- package/dist/extensions/pi-subagents/docs/models.md +27 -4
- package/dist/extensions/pi-subagents/docs/observability.md +10 -9
- package/dist/extensions/pi-subagents/docs/tool-reference.md +102 -6
- package/dist/extensions/pi-subagents/docs/workflows.md +135 -0
- package/dist/extensions/pi-subagents/package-lock.json +389 -2
- package/dist/extensions/pi-subagents/package.json +3 -1
- package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
- package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +3 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +7 -3
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +26 -5
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -22
- package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +4 -4
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +9 -2
- package/dist/extensions/pi-subagents/src/agents/agents.ts +322 -75
- package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +6 -0
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-events.ts +70 -0
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +27 -20
- package/dist/extensions/pi-subagents/src/api/agents.ts +10 -5
- package/dist/extensions/pi-subagents/src/api/background-work.ts +5 -1
- package/dist/extensions/pi-subagents/src/api/delegation.ts +0 -7
- package/dist/extensions/pi-subagents/src/api/preflight.ts +34 -12
- package/dist/extensions/pi-subagents/src/extension/config.ts +70 -0
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -3
- package/dist/extensions/pi-subagents/src/extension/index.ts +83 -30
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +44 -15
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +55 -19
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +41 -15
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -31
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -1
- package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -10
- package/dist/extensions/pi-subagents/src/inspectors/herdr/session-roots-codec.ts +42 -0
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +51 -3
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +2 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +5 -6
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +77 -10
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +176 -53
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +19 -12
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +29 -27
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +20 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +23 -261
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +73 -7
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +8 -3
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +74 -8
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +37 -21
- package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +8 -8
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +184 -9
- package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +45 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +28 -14
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +38 -15
- package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +50 -13
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +93 -8
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +10 -4
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -14
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +549 -377
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +58 -10
- package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +26 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +23 -9
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +9 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +204 -129
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +9 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +23 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +773 -311
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +140 -115
- package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +119 -0
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +463 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +19 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +151 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +21 -7
- package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +89 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +167 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +122 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +348 -55
- package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +5 -5
- package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +230 -0
- package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +105 -0
- package/dist/extensions/pi-subagents/src/runs/shared/launch-cwd.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +422 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +221 -158
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +69 -7
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +47 -6
- package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +7 -2
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +9 -3
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +419 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +15 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +81 -8
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +13 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +21 -1
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +44 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +98 -13
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +847 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +18 -0
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +46 -0
- package/dist/extensions/pi-subagents/src/shared/extension-context.ts +24 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +21 -0
- package/dist/extensions/pi-subagents/src/shared/formatters.ts +18 -3
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +5 -1
- package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +450 -0
- package/dist/extensions/pi-subagents/src/shared/session-file-trust.ts +19 -0
- package/dist/extensions/pi-subagents/src/shared/session-tokens.ts +14 -3
- package/dist/extensions/pi-subagents/src/shared/settings.ts +19 -105
- package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +17 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +359 -40
- package/dist/extensions/pi-subagents/src/shared/utils.ts +41 -84
- package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +116 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -9
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +0 -4
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -2
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +378 -88
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +22 -11
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +3 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +147 -79
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +11 -5
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +39 -18
- package/dist/extensions/pi-subagents/src/tui/render.ts +369 -46
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +1 -1
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +6 -3
- package/dist/extensions/pi-subagents/src/workflows/host-command.ts +230 -0
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +740 -58
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +121 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +270 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +195 -6
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +246 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1114 -260
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +150 -3
- package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +55 -0
- package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +59 -0
- package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +57 -1
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +20 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +4 -3
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +54 -4
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +482 -4
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +157 -9
- package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +5 -5
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1508 -291
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +423 -1
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/support/cursor-smoke-inputs.ts +51 -0
- package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +5 -5
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +6 -6
- package/dist/extensions/pi-subagents/test/unit/abort-recovery.test.ts +152 -0
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +48 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +184 -6
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +66 -6
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/anti-slop-oxlint.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +101 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +14 -7
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +190 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +8 -4
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +78 -1
- package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-name.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +245 -0
- package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +192 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +150 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +259 -0
- package/dist/extensions/pi-subagents/test/unit/cursor-smoke-inputs.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +1 -4
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/extension-context.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +223 -0
- package/dist/extensions/pi-subagents/test/unit/fast-mode-extension.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +208 -2
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +110 -1
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/formatters.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +18 -9
- package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +63 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +132 -0
- package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +156 -0
- package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +178 -26
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +138 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +91 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +72 -7
- package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +20 -2
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +129 -1
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +4 -0
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +358 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +574 -21
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +109 -1
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +71 -1
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +214 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +29 -8
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/result-delivery-ownership.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +101 -3
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +10 -8
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +71 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +41 -7
- package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +136 -2
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +137 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +33 -12
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +504 -1
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +3 -5
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +5 -6
- package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +0 -8
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +5 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +157 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +63 -4
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +27 -23
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +7 -5
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +106 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +484 -9
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +38 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +155 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +318 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +365 -0
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +349 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +2 -7
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/index.ts +13 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/rules/no-service-constructor-imports.ts +52 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/index.ts +41 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts +77 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts +49 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-known-value-widening.ts +247 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-module-mocking.ts +91 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-object-parameters.ts +126 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-apply.ts +28 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-get.ts +28 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-runtime-typeof.ts +67 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts +39 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-parameters.ts +83 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-returns.ts +115 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts +72 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts +134 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-widen-then-assert.ts +366 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts +62 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/dictionary-types.ts +502 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/lexical-type-parameters.ts +60 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/reflect-method.ts +35 -0
- package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +2 -2
- package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +1 -1
- package/dist/extensions/pi-zentui/extensions/zentui/format.ts +2 -1
- package/dist/extensions/pi-zentui/test/format.test.ts +15 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/interactive-mode.js +11 -11
- package/dist/skills/workflow/SKILL.md +65 -50
- package/package.json +112 -110
- package/dist/extensions/enable-readonly-tools.test.ts +0 -63
- package/dist/extensions/enable-readonly-tools.ts +0 -24
- package/dist/extensions/model-prompt-injector/config.json +0 -16
- package/dist/extensions/model-prompt-injector/index.test.ts +0 -102
- package/dist/extensions/model-prompt-injector/index.ts +0 -148
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +0 -98
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +0 -250
|
@@ -8,7 +8,8 @@ import { parse as parseYaml } from "yaml";
|
|
|
8
8
|
import * as os from "node:os";
|
|
9
9
|
import * as path from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
-
import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig
|
|
11
|
+
import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig } from "../shared/types.ts";
|
|
12
|
+
import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, parseExternalCliCapabilityNarrowing, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.ts";
|
|
12
13
|
import { getAgentDir, getProjectConfigDir } from "../shared/utils.ts";
|
|
13
14
|
import { KNOWN_FIELDS } from "./agent-serializer.ts";
|
|
14
15
|
import { parseChain, parseJsonChain } from "./chain-serializer.ts";
|
|
@@ -19,7 +20,6 @@ import { parseModelScopeConfig, type ModelScopeConfig } from "../runs/shared/mod
|
|
|
19
20
|
export { BUILTIN_AGENT_NAMES } from "./builtin-names.ts";
|
|
20
21
|
export { buildRuntimeName, frontmatterNameForConfig, parsePackageName } from "./identity.ts";
|
|
21
22
|
import { parseMemoryFrontmatter } from "./agent-memory.ts";
|
|
22
|
-
import { resolveTurnBudgetConfig } from "../runs/shared/turn-budget.ts";
|
|
23
23
|
import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
|
|
24
24
|
import { validatePermissionRules, type PermissionRules } from "../runs/shared/permissions.ts";
|
|
25
25
|
import { parseThinkingLevel, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
|
|
@@ -61,6 +61,7 @@ export interface BuiltinAgentOverrideBase {
|
|
|
61
61
|
thinking?: string | false;
|
|
62
62
|
systemPromptMode: SystemPromptMode;
|
|
63
63
|
inheritProjectContext: boolean;
|
|
64
|
+
inheritGlobalContext: boolean;
|
|
64
65
|
inheritSkills: boolean;
|
|
65
66
|
defaultContext?: AgentDefaultContext;
|
|
66
67
|
acceptanceRole?: AcceptanceRole;
|
|
@@ -69,9 +70,11 @@ export interface BuiltinAgentOverrideBase {
|
|
|
69
70
|
skills?: string[];
|
|
70
71
|
skillPath?: string[];
|
|
71
72
|
tools?: string[];
|
|
73
|
+
allowNestedSubagents?: boolean;
|
|
72
74
|
mcpDirectTools?: string[];
|
|
73
75
|
extensions?: string[];
|
|
74
76
|
subagentOnlyExtensions?: string[];
|
|
77
|
+
mutationTools?: string[];
|
|
75
78
|
completionGuard?: boolean;
|
|
76
79
|
toolBudget?: ToolBudgetConfig;
|
|
77
80
|
}
|
|
@@ -88,6 +91,7 @@ interface BuiltinAgentOverrideConfig {
|
|
|
88
91
|
thinking?: string | false;
|
|
89
92
|
systemPromptMode?: SystemPromptMode;
|
|
90
93
|
inheritProjectContext?: boolean;
|
|
94
|
+
inheritGlobalContext?: boolean;
|
|
91
95
|
inheritSkills?: boolean;
|
|
92
96
|
defaultContext?: AgentDefaultContext | false;
|
|
93
97
|
acceptanceRole?: AcceptanceRole | false;
|
|
@@ -95,8 +99,10 @@ interface BuiltinAgentOverrideConfig {
|
|
|
95
99
|
systemPrompt?: string;
|
|
96
100
|
skills?: string[] | false;
|
|
97
101
|
tools?: string[] | false | "inherit";
|
|
102
|
+
allowNestedSubagents?: boolean;
|
|
98
103
|
extensions?: string[] | false;
|
|
99
104
|
subagentOnlyExtensions?: string[] | false;
|
|
105
|
+
mutationTools?: string[] | false;
|
|
100
106
|
completionGuard?: boolean;
|
|
101
107
|
toolBudget?: ToolBudgetConfig | false;
|
|
102
108
|
}
|
|
@@ -126,6 +132,7 @@ export interface AgentConfig {
|
|
|
126
132
|
description: string;
|
|
127
133
|
aliases?: string[];
|
|
128
134
|
tools?: string[];
|
|
135
|
+
allowNestedSubagents?: boolean;
|
|
129
136
|
mcpDirectTools?: string[];
|
|
130
137
|
model?: string;
|
|
131
138
|
modelProvider?: string;
|
|
@@ -134,12 +141,12 @@ export interface AgentConfig {
|
|
|
134
141
|
thinking?: string | false;
|
|
135
142
|
systemPromptMode: SystemPromptMode;
|
|
136
143
|
inheritProjectContext: boolean;
|
|
144
|
+
inheritGlobalContext: boolean;
|
|
137
145
|
inheritSkills: boolean;
|
|
138
146
|
defaultContext?: AgentDefaultContext;
|
|
139
147
|
defaultAsync?: boolean;
|
|
140
148
|
defaultTimeoutMs?: number;
|
|
141
149
|
defaultToolTimeoutMs?: number;
|
|
142
|
-
defaultTurnBudget?: TurnBudgetConfig;
|
|
143
150
|
defaultAcceptance?: AcceptanceInput;
|
|
144
151
|
acceptanceRole?: AcceptanceRole;
|
|
145
152
|
systemPrompt: string;
|
|
@@ -151,6 +158,7 @@ export interface AgentConfig {
|
|
|
151
158
|
extensions?: string[];
|
|
152
159
|
extensionsFromDefault?: boolean;
|
|
153
160
|
subagentOnlyExtensions?: string[];
|
|
161
|
+
mutationTools?: string[];
|
|
154
162
|
output?: string;
|
|
155
163
|
outputMode?: OutputMode;
|
|
156
164
|
defaultReads?: string[];
|
|
@@ -172,6 +180,7 @@ type ProjectRootResolution = "nearest" | "git-root";
|
|
|
172
180
|
|
|
173
181
|
interface SubagentSettings {
|
|
174
182
|
overrides: Record<string, BuiltinAgentOverrideConfig>;
|
|
183
|
+
providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>>;
|
|
175
184
|
defaultModel?: string;
|
|
176
185
|
defaultProvider?: string;
|
|
177
186
|
defaultThinking?: string;
|
|
@@ -182,7 +191,7 @@ interface SubagentSettings {
|
|
|
182
191
|
modelScope?: ModelScopeConfig;
|
|
183
192
|
}
|
|
184
193
|
|
|
185
|
-
const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {} };
|
|
194
|
+
const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {}, providerOverrides: {} };
|
|
186
195
|
const agentFrontmatterFields = new WeakMap<AgentConfig, Set<string>>();
|
|
187
196
|
|
|
188
197
|
export interface ChainStepConfig {
|
|
@@ -262,14 +271,72 @@ export function findBlockingAgentDiagnostic(name: string, agent: AgentConfig | r
|
|
|
262
271
|
return !agents.length || (match && agentDefinitionPriority(match) > highestPriority) ? match : undefined;
|
|
263
272
|
}
|
|
264
273
|
|
|
265
|
-
|
|
274
|
+
export type AgentDefinitionDirectoryState = "absent" | "empty" | "candidates" | "unreadable" | "not-directory";
|
|
275
|
+
|
|
276
|
+
/** A definition directory actually inspected during one agent-discovery operation. */
|
|
277
|
+
export interface AgentDefinitionDirectoryReport {
|
|
278
|
+
source: AgentSource;
|
|
279
|
+
path: string;
|
|
280
|
+
state: AgentDefinitionDirectoryState;
|
|
281
|
+
candidateCount?: number;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Filesystem provenance for a failed agent resolution. Context is created from
|
|
286
|
+
* the discovery result that supplied the effective agents; callers must not
|
|
287
|
+
* pair arbitrary agent arrays with these directory reports.
|
|
288
|
+
*/
|
|
289
|
+
export interface UnknownAgentDiagnosticContext {
|
|
290
|
+
cwd: string;
|
|
291
|
+
scope: AgentScope;
|
|
292
|
+
directories: readonly AgentDefinitionDirectoryReport[];
|
|
293
|
+
agents: readonly AgentConfig[];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface AgentDiscoveryResult {
|
|
266
297
|
agents: AgentConfig[];
|
|
267
298
|
agentDiagnostics?: AgentDiscoveryDiagnostic[];
|
|
268
299
|
projectAgentsDir: string | null;
|
|
300
|
+
cwd: string;
|
|
301
|
+
scope: AgentScope;
|
|
302
|
+
directories: readonly AgentDefinitionDirectoryReport[];
|
|
269
303
|
modelScope?: ModelScopeConfig;
|
|
270
304
|
maxThinking?: ThinkingLevel;
|
|
271
305
|
}
|
|
272
306
|
|
|
307
|
+
/** Create formatter input from the exact discovery operation used for resolution. */
|
|
308
|
+
export function unknownAgentDiagnosticContext(discovered: Pick<AgentDiscoveryResult, "cwd" | "scope" | "directories" | "agents">): UnknownAgentDiagnosticContext {
|
|
309
|
+
return {
|
|
310
|
+
cwd: discovered.cwd,
|
|
311
|
+
scope: discovered.scope,
|
|
312
|
+
directories: discovered.directories,
|
|
313
|
+
agents: discovered.agents,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Render local discovery evidence without exposing filesystem error details. */
|
|
318
|
+
export function formatUnknownAgentError(name: string, context: UnknownAgentDiagnosticContext, prefix = "Unknown agent"): string {
|
|
319
|
+
const directories = context.directories.map((directory) => {
|
|
320
|
+
const state = directory.state === "candidates"
|
|
321
|
+
? `${directory.candidateCount ?? 0} candidate${directory.candidateCount === 1 ? "" : "s"}`
|
|
322
|
+
: directory.state === "empty" ? "present but empty"
|
|
323
|
+
: directory.state === "not-directory" ? "not a directory"
|
|
324
|
+
: directory.state;
|
|
325
|
+
return `- ${directory.source}: ${directory.path} (${state})`;
|
|
326
|
+
});
|
|
327
|
+
const agents = [...context.agents]
|
|
328
|
+
.sort((left, right) => left.name.localeCompare(right.name) || left.source.localeCompare(right.source))
|
|
329
|
+
.map((agent) => `- ${agent.name} (${agent.source})`);
|
|
330
|
+
return [
|
|
331
|
+
`${prefix}: ${name}`,
|
|
332
|
+
`Effective cwd: ${path.resolve(context.cwd)}`,
|
|
333
|
+
"Consulted agent-definition directories:",
|
|
334
|
+
...(directories.length ? directories : ["- (none)"]),
|
|
335
|
+
"Discovered agents:",
|
|
336
|
+
...(agents.length ? agents : ["- (none)"]),
|
|
337
|
+
].join("\n");
|
|
338
|
+
}
|
|
339
|
+
|
|
273
340
|
function getUserChainDir(): string {
|
|
274
341
|
return path.join(getAgentDir(), "chains");
|
|
275
342
|
}
|
|
@@ -381,6 +448,10 @@ function resolveSettingsPackageRoot(source: string, baseDir: string): string | u
|
|
|
381
448
|
if (normalized === "." || normalized === ".." || normalized.startsWith("./") || normalized.startsWith("../")) {
|
|
382
449
|
return path.resolve(baseDir, normalized);
|
|
383
450
|
}
|
|
451
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
452
|
+
const parsed = parseGitPackagePath(`git:${trimmed}`);
|
|
453
|
+
return parsed ? path.join(baseDir, "git", parsed.host, parsed.repoPath) : undefined;
|
|
454
|
+
}
|
|
384
455
|
return undefined;
|
|
385
456
|
}
|
|
386
457
|
|
|
@@ -647,6 +718,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
|
|
|
647
718
|
...(agent.thinking !== undefined ? { thinking: agent.thinking } : {}),
|
|
648
719
|
systemPromptMode: agent.systemPromptMode,
|
|
649
720
|
inheritProjectContext: agent.inheritProjectContext,
|
|
721
|
+
inheritGlobalContext: agent.inheritGlobalContext,
|
|
650
722
|
inheritSkills: agent.inheritSkills,
|
|
651
723
|
...(agent.defaultContext !== undefined ? { defaultContext: agent.defaultContext } : {}),
|
|
652
724
|
...(agent.acceptanceRole !== undefined ? { acceptanceRole: agent.acceptanceRole } : {}),
|
|
@@ -655,9 +727,11 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
|
|
|
655
727
|
...(agent.skills ? { skills: [...agent.skills] } : {}),
|
|
656
728
|
...(agent.skillPath ? { skillPath: [...agent.skillPath] } : {}),
|
|
657
729
|
...(agent.tools ? { tools: [...agent.tools] } : {}),
|
|
730
|
+
...(agent.allowNestedSubagents !== undefined ? { allowNestedSubagents: agent.allowNestedSubagents } : {}),
|
|
658
731
|
...(agent.mcpDirectTools ? { mcpDirectTools: [...agent.mcpDirectTools] } : {}),
|
|
659
732
|
...(!agent.extensionsFromDefault && agent.extensions ? { extensions: [...agent.extensions] } : {}),
|
|
660
733
|
...(agent.subagentOnlyExtensions ? { subagentOnlyExtensions: [...agent.subagentOnlyExtensions] } : {}),
|
|
734
|
+
...(agent.mutationTools ? { mutationTools: [...agent.mutationTools] } : {}),
|
|
661
735
|
...(agent.completionGuard !== undefined ? { completionGuard: agent.completionGuard } : {}),
|
|
662
736
|
...(agent.toolBudget !== undefined ? { toolBudget: agent.toolBudget } : {}),
|
|
663
737
|
};
|
|
@@ -678,6 +752,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
|
|
|
678
752
|
...(override.thinking !== undefined ? { thinking: override.thinking } : {}),
|
|
679
753
|
...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),
|
|
680
754
|
...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),
|
|
755
|
+
...(override.inheritGlobalContext !== undefined ? { inheritGlobalContext: override.inheritGlobalContext } : {}),
|
|
681
756
|
...(override.inheritSkills !== undefined ? { inheritSkills: override.inheritSkills } : {}),
|
|
682
757
|
...(override.defaultContext !== undefined ? { defaultContext: override.defaultContext } : {}),
|
|
683
758
|
...(override.acceptanceRole !== undefined ? { acceptanceRole: override.acceptanceRole } : {}),
|
|
@@ -685,8 +760,10 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
|
|
|
685
760
|
...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
|
|
686
761
|
...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
|
|
687
762
|
...(override.tools !== undefined ? { tools: Array.isArray(override.tools) ? [...override.tools] : override.tools } : {}),
|
|
763
|
+
...(override.allowNestedSubagents !== undefined ? { allowNestedSubagents: override.allowNestedSubagents } : {}),
|
|
688
764
|
...(override.extensions !== undefined ? { extensions: override.extensions === false ? false : [...override.extensions] } : {}),
|
|
689
765
|
...(override.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions] } : {}),
|
|
766
|
+
...(override.mutationTools !== undefined ? { mutationTools: override.mutationTools === false ? false : [...override.mutationTools] } : {}),
|
|
690
767
|
...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
|
|
691
768
|
...(override.toolBudget !== undefined ? { toolBudget: override.toolBudget === false ? false : { ...override.toolBudget, ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}) } } : {}),
|
|
692
769
|
};
|
|
@@ -736,7 +813,7 @@ export function findNearestProjectRoot(cwd: string): string | null {
|
|
|
736
813
|
return findProjectRootCandidates(cwd)[0] ?? null;
|
|
737
814
|
}
|
|
738
815
|
|
|
739
|
-
function findConfiguredProjectRoot(cwd: string): string | null {
|
|
816
|
+
export function findConfiguredProjectRoot(cwd: string): string | null {
|
|
740
817
|
const candidates = findProjectRootCandidates(cwd);
|
|
741
818
|
const nearestRoot = candidates[0];
|
|
742
819
|
if (!nearestRoot) return null;
|
|
@@ -895,6 +972,14 @@ function parseBuiltinOverrideEntry(
|
|
|
895
972
|
}
|
|
896
973
|
}
|
|
897
974
|
|
|
975
|
+
if ("inheritGlobalContext" in input) {
|
|
976
|
+
if (typeof input.inheritGlobalContext === "boolean") {
|
|
977
|
+
override.inheritGlobalContext = input.inheritGlobalContext;
|
|
978
|
+
} else {
|
|
979
|
+
throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritGlobalContext'; expected a boolean.`);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
898
983
|
if ("inheritSkills" in input) {
|
|
899
984
|
if (typeof input.inheritSkills === "boolean") {
|
|
900
985
|
override.inheritSkills = input.inheritSkills;
|
|
@@ -967,6 +1052,10 @@ function parseBuiltinOverrideEntry(
|
|
|
967
1052
|
|
|
968
1053
|
const tools = parseToolsOverride(input.tools, { filePath, name });
|
|
969
1054
|
if (tools !== undefined) override.tools = tools;
|
|
1055
|
+
if ("allowNestedSubagents" in input) {
|
|
1056
|
+
if (typeof input.allowNestedSubagents === "boolean") override.allowNestedSubagents = input.allowNestedSubagents;
|
|
1057
|
+
else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'allowNestedSubagents'; expected a boolean.`);
|
|
1058
|
+
}
|
|
970
1059
|
|
|
971
1060
|
const extensions = parseOverrideStringArrayOrFalse(input.extensions, { filePath, name, field: "extensions" });
|
|
972
1061
|
if (extensions !== undefined) override.extensions = extensions;
|
|
@@ -974,6 +1063,9 @@ function parseBuiltinOverrideEntry(
|
|
|
974
1063
|
const subagentOnlyExtensions = parseOverrideStringArrayOrFalse(input.subagentOnlyExtensions, { filePath, name, field: "subagentOnlyExtensions" });
|
|
975
1064
|
if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;
|
|
976
1065
|
|
|
1066
|
+
const mutationTools = parseOverrideStringArrayOrFalse(input.mutationTools, { filePath, name, field: "mutationTools" });
|
|
1067
|
+
if (mutationTools !== undefined) override.mutationTools = mutationTools;
|
|
1068
|
+
|
|
977
1069
|
return Object.keys(override).length > 0 ? override : undefined;
|
|
978
1070
|
}
|
|
979
1071
|
|
|
@@ -1043,9 +1135,12 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
|
|
|
1043
1135
|
const modelScope = parseModelScopeConfig(subagentsObject.modelScope, { filePath });
|
|
1044
1136
|
|
|
1045
1137
|
const parsed: Record<string, BuiltinAgentOverrideConfig> = {};
|
|
1138
|
+
const providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>> = {};
|
|
1046
1139
|
const agentOverrides = subagentsObject.agentOverrides;
|
|
1140
|
+
const agentOverridesByProvider = subagentsObject.agentOverridesByProvider;
|
|
1047
1141
|
const parsedSettings: SubagentSettings = {
|
|
1048
1142
|
overrides: parsed,
|
|
1143
|
+
providerOverrides,
|
|
1049
1144
|
...(defaultModel !== undefined ? { defaultModel } : {}),
|
|
1050
1145
|
...(defaultProvider !== undefined ? { defaultProvider } : {}),
|
|
1051
1146
|
...(defaultThinking !== undefined ? { defaultThinking } : {}),
|
|
@@ -1055,16 +1150,42 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
|
|
|
1055
1150
|
...(disableThinking !== undefined ? { disableThinking } : {}),
|
|
1056
1151
|
...(modelScope !== undefined ? { modelScope } : {}),
|
|
1057
1152
|
};
|
|
1058
|
-
if (
|
|
1059
|
-
|
|
1153
|
+
if (agentOverrides && typeof agentOverrides === "object" && !Array.isArray(agentOverrides)) {
|
|
1154
|
+
for (const [name, value] of Object.entries(agentOverrides)) {
|
|
1155
|
+
const override = parseBuiltinOverrideEntry(name, value, filePath);
|
|
1156
|
+
if (override) parsed[name] = override;
|
|
1157
|
+
}
|
|
1060
1158
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1159
|
+
if (agentOverridesByProvider !== undefined) {
|
|
1160
|
+
if (!agentOverridesByProvider || typeof agentOverridesByProvider !== "object" || Array.isArray(agentOverridesByProvider)) {
|
|
1161
|
+
throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider'; expected an object keyed by provider.`);
|
|
1162
|
+
}
|
|
1163
|
+
for (const [provider, value] of Object.entries(agentOverridesByProvider)) {
|
|
1164
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1165
|
+
throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider.${provider}'; expected an object keyed by agent.`);
|
|
1166
|
+
}
|
|
1167
|
+
const entries: Record<string, BuiltinAgentOverrideConfig> = {};
|
|
1168
|
+
for (const [agentName, agentValue] of Object.entries(value)) {
|
|
1169
|
+
const override = parseBuiltinOverrideEntry(`agentOverridesByProvider.${provider}.${agentName}`, agentValue, filePath);
|
|
1170
|
+
if (override) entries[agentName] = override;
|
|
1171
|
+
}
|
|
1172
|
+
providerOverrides[provider] = entries;
|
|
1173
|
+
}
|
|
1064
1174
|
}
|
|
1065
1175
|
return parsedSettings;
|
|
1066
1176
|
}
|
|
1067
1177
|
|
|
1178
|
+
function selectProviderOverrides(settings: SubagentSettings, provider: string | undefined): SubagentSettings {
|
|
1179
|
+
if (!provider) return settings;
|
|
1180
|
+
const selected = settings.providerOverrides[provider];
|
|
1181
|
+
if (!selected) return settings;
|
|
1182
|
+
const overrides = { ...settings.overrides };
|
|
1183
|
+
for (const [name, override] of Object.entries(selected)) {
|
|
1184
|
+
overrides[name] = { ...overrides[name], ...override };
|
|
1185
|
+
}
|
|
1186
|
+
return { ...settings, overrides };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1068
1189
|
function resolveSubagentDefaultProvider(
|
|
1069
1190
|
userSettings: SubagentSettings,
|
|
1070
1191
|
projectSettings: SubagentSettings,
|
|
@@ -1209,6 +1330,7 @@ function applyBuiltinOverride(
|
|
|
1209
1330
|
if (override.thinking !== undefined) { if (override.thinking === false) delete next.thinking; else next.thinking = override.thinking; }
|
|
1210
1331
|
if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;
|
|
1211
1332
|
if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;
|
|
1333
|
+
if (override.inheritGlobalContext !== undefined) next.inheritGlobalContext = override.inheritGlobalContext;
|
|
1212
1334
|
if (override.inheritSkills !== undefined) next.inheritSkills = override.inheritSkills;
|
|
1213
1335
|
if (override.defaultContext !== undefined) { if (override.defaultContext === false) delete next.defaultContext; else next.defaultContext = override.defaultContext; }
|
|
1214
1336
|
if (override.acceptanceRole !== undefined) { if (override.acceptanceRole === false) delete next.acceptanceRole; else next.acceptanceRole = override.acceptanceRole; }
|
|
@@ -1216,8 +1338,10 @@ function applyBuiltinOverride(
|
|
|
1216
1338
|
if (override.systemPrompt !== undefined) next.systemPrompt = override.systemPrompt;
|
|
1217
1339
|
if (override.skills !== undefined) { if (override.skills === false) delete next.skills; else next.skills = [...override.skills]; }
|
|
1218
1340
|
if (override.tools !== undefined) applyToolsOverride(next, override.tools);
|
|
1341
|
+
if (override.allowNestedSubagents !== undefined) next.allowNestedSubagents = override.allowNestedSubagents;
|
|
1219
1342
|
if (override.extensions !== undefined) { if (override.extensions === false) delete next.extensions; else next.extensions = [...override.extensions]; }
|
|
1220
1343
|
if (override.subagentOnlyExtensions !== undefined) { if (override.subagentOnlyExtensions === false) delete next.subagentOnlyExtensions; else next.subagentOnlyExtensions = [...override.subagentOnlyExtensions]; }
|
|
1344
|
+
if (override.mutationTools !== undefined) { if (override.mutationTools === false) delete next.mutationTools; else next.mutationTools = [...override.mutationTools]; }
|
|
1221
1345
|
if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
|
|
1222
1346
|
if (override.toolBudget !== undefined) { if (override.toolBudget === false) delete next.toolBudget; else next.toolBudget = override.toolBudget; }
|
|
1223
1347
|
|
|
@@ -1355,6 +1479,9 @@ function applyCustomAgentOverride(
|
|
|
1355
1479
|
if (override.inheritProjectContext !== undefined) {
|
|
1356
1480
|
fill("inheritProjectContext", ["inheritProjectContext"], override.inheritProjectContext);
|
|
1357
1481
|
}
|
|
1482
|
+
if (override.inheritGlobalContext !== undefined) {
|
|
1483
|
+
fill("inheritGlobalContext", ["inheritGlobalContext"], override.inheritGlobalContext);
|
|
1484
|
+
}
|
|
1358
1485
|
if (override.inheritSkills !== undefined) {
|
|
1359
1486
|
fill("inheritSkills", ["inheritSkills"], override.inheritSkills);
|
|
1360
1487
|
}
|
|
@@ -1376,6 +1503,9 @@ function applyCustomAgentOverride(
|
|
|
1376
1503
|
applyToolsOverride(mutable(), override.tools);
|
|
1377
1504
|
anyFilled = true;
|
|
1378
1505
|
}
|
|
1506
|
+
if (override.allowNestedSubagents !== undefined) {
|
|
1507
|
+
fill("allowNestedSubagents", ["allowNestedSubagents"], override.allowNestedSubagents);
|
|
1508
|
+
}
|
|
1379
1509
|
if (override.extensions !== undefined) {
|
|
1380
1510
|
fill("extensions", ["extensions"], override.extensions === false ? undefined : [...override.extensions]);
|
|
1381
1511
|
}
|
|
@@ -1386,6 +1516,9 @@ function applyCustomAgentOverride(
|
|
|
1386
1516
|
override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions],
|
|
1387
1517
|
);
|
|
1388
1518
|
}
|
|
1519
|
+
if (override.mutationTools !== undefined) {
|
|
1520
|
+
fill("mutationTools", ["mutationTools"], override.mutationTools === false ? undefined : [...override.mutationTools]);
|
|
1521
|
+
}
|
|
1389
1522
|
if (override.completionGuard !== undefined) {
|
|
1390
1523
|
fill("completionGuard", ["completionGuard"], override.completionGuard);
|
|
1391
1524
|
}
|
|
@@ -1425,7 +1558,7 @@ function applyCustomAgentOverrides(
|
|
|
1425
1558
|
|
|
1426
1559
|
export function buildBuiltinOverrideConfig(
|
|
1427
1560
|
base: BuiltinAgentOverrideBase,
|
|
1428
|
-
draft: Pick<AgentConfig, "model" | "modelProvider" | "fallbackModels" | "fast" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "completionGuard" | "toolBudget"> & Partial<Pick<AgentConfig, "description" | "output" | "outputMode" | "defaultReads">>,
|
|
1561
|
+
draft: Pick<AgentConfig, "model" | "modelProvider" | "fallbackModels" | "fast" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritGlobalContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "allowNestedSubagents" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "mutationTools" | "completionGuard" | "toolBudget"> & Partial<Pick<AgentConfig, "description" | "output" | "outputMode" | "defaultReads">>,
|
|
1429
1562
|
): BuiltinAgentOverrideConfig | undefined {
|
|
1430
1563
|
const override: BuiltinAgentOverrideConfig = {};
|
|
1431
1564
|
|
|
@@ -1443,6 +1576,7 @@ export function buildBuiltinOverrideConfig(
|
|
|
1443
1576
|
if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;
|
|
1444
1577
|
if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;
|
|
1445
1578
|
if (draft.inheritProjectContext !== base.inheritProjectContext) override.inheritProjectContext = draft.inheritProjectContext;
|
|
1579
|
+
if (draft.inheritGlobalContext !== base.inheritGlobalContext) override.inheritGlobalContext = draft.inheritGlobalContext;
|
|
1446
1580
|
if (draft.inheritSkills !== base.inheritSkills) override.inheritSkills = draft.inheritSkills;
|
|
1447
1581
|
if (draft.defaultContext !== base.defaultContext) override.defaultContext = draft.defaultContext ?? false;
|
|
1448
1582
|
if (draft.acceptanceRole !== base.acceptanceRole) override.acceptanceRole = draft.acceptanceRole ?? false;
|
|
@@ -1453,10 +1587,12 @@ export function buildBuiltinOverrideConfig(
|
|
|
1453
1587
|
const baseTools = joinToolList(base);
|
|
1454
1588
|
const draftTools = joinToolList(draft);
|
|
1455
1589
|
if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
|
|
1590
|
+
if (draft.allowNestedSubagents !== base.allowNestedSubagents) override.allowNestedSubagents = draft.allowNestedSubagents === true;
|
|
1456
1591
|
if (!arraysEqual(draft.extensions, base.extensions)) override.extensions = draft.extensions ? [...draft.extensions] : false;
|
|
1457
1592
|
if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {
|
|
1458
1593
|
override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;
|
|
1459
1594
|
}
|
|
1595
|
+
if (!arraysEqual(draft.mutationTools, base.mutationTools)) override.mutationTools = draft.mutationTools ? [...draft.mutationTools] : false;
|
|
1460
1596
|
if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
|
|
1461
1597
|
override.completionGuard = draft.completionGuard !== false;
|
|
1462
1598
|
}
|
|
@@ -1586,7 +1722,7 @@ export function removeBuiltinAgentOverrideFields(
|
|
|
1586
1722
|
return { path: filePath, removed: true };
|
|
1587
1723
|
}
|
|
1588
1724
|
|
|
1589
|
-
const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules"]);
|
|
1725
|
+
const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules", ".pi", ".selesai", "sync-backups"]);
|
|
1590
1726
|
|
|
1591
1727
|
function isDiscoveryNestedProjectRoot(dir: string): boolean {
|
|
1592
1728
|
return isDirectory(getProjectConfigDir(dir)) || isDirectory(path.join(dir, ".agents"));
|
|
@@ -1598,9 +1734,22 @@ function shouldPruneDiscoveryDir(rootDir: string, dir: string, dirName: string):
|
|
|
1598
1734
|
return path.resolve(dir) !== path.resolve(rootDir) && isDiscoveryNestedProjectRoot(dir);
|
|
1599
1735
|
}
|
|
1600
1736
|
|
|
1601
|
-
function listFilesRecursive(
|
|
1737
|
+
function listFilesRecursive(
|
|
1738
|
+
dir: string,
|
|
1739
|
+
predicate: (fileName: string) => boolean,
|
|
1740
|
+
rootDir = dir,
|
|
1741
|
+
visitedDirectories = new Set<string>(),
|
|
1742
|
+
): string[] {
|
|
1602
1743
|
const files: string[] = [];
|
|
1603
1744
|
if (!fs.existsSync(dir)) return files;
|
|
1745
|
+
let realDir: string;
|
|
1746
|
+
try {
|
|
1747
|
+
realDir = fs.realpathSync(dir);
|
|
1748
|
+
} catch {
|
|
1749
|
+
return files;
|
|
1750
|
+
}
|
|
1751
|
+
if (visitedDirectories.has(realDir)) return files;
|
|
1752
|
+
visitedDirectories.add(realDir);
|
|
1604
1753
|
|
|
1605
1754
|
let entries: fs.Dirent[];
|
|
1606
1755
|
try {
|
|
@@ -1611,9 +1760,17 @@ function listFilesRecursive(dir: string, predicate: (fileName: string) => boolea
|
|
|
1611
1760
|
|
|
1612
1761
|
for (const entry of entries) {
|
|
1613
1762
|
const filePath = path.join(dir, entry.name);
|
|
1614
|
-
|
|
1763
|
+
let isDirectory = entry.isDirectory();
|
|
1764
|
+
if (entry.isSymbolicLink()) {
|
|
1765
|
+
try {
|
|
1766
|
+
isDirectory = fs.statSync(filePath).isDirectory();
|
|
1767
|
+
} catch {
|
|
1768
|
+
isDirectory = false;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
if (isDirectory) {
|
|
1615
1772
|
if (!shouldPruneDiscoveryDir(rootDir, filePath, entry.name)) {
|
|
1616
|
-
files.push(...listFilesRecursive(filePath, predicate, rootDir));
|
|
1773
|
+
files.push(...listFilesRecursive(filePath, predicate, rootDir, visitedDirectories));
|
|
1617
1774
|
}
|
|
1618
1775
|
continue;
|
|
1619
1776
|
}
|
|
@@ -1624,6 +1781,81 @@ function listFilesRecursive(dir: string, predicate: (fileName: string) => boolea
|
|
|
1624
1781
|
return files;
|
|
1625
1782
|
}
|
|
1626
1783
|
|
|
1784
|
+
export interface AgentDefinitionInspection {
|
|
1785
|
+
files: string[];
|
|
1786
|
+
state: AgentDefinitionDirectoryState;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
/** Narrow filesystem seam so unavailable paths can be tested without permissions. */
|
|
1790
|
+
export interface AgentDefinitionInspectionFs {
|
|
1791
|
+
existsSync(filePath: string): boolean;
|
|
1792
|
+
realpathSync?(filePath: string): string;
|
|
1793
|
+
statSync(filePath: string): { isDirectory(): boolean };
|
|
1794
|
+
readdirSync(dir: string): fs.Dirent[];
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
const DEFAULT_AGENT_DEFINITION_INSPECTION_FS: AgentDefinitionInspectionFs = {
|
|
1798
|
+
existsSync: fs.existsSync,
|
|
1799
|
+
realpathSync: fs.realpathSync,
|
|
1800
|
+
statSync: fs.statSync,
|
|
1801
|
+
readdirSync: (dir) => fs.readdirSync(dir, { withFileTypes: true }),
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Inspect one agent-definition directory while retaining traversal failure
|
|
1806
|
+
* state. A nested unreadable directory makes the whole inspection unavailable,
|
|
1807
|
+
* preventing a partial traversal from being reported as empty or complete.
|
|
1808
|
+
*/
|
|
1809
|
+
export function inspectAgentDefinitionDirectory(dir: string, operations: AgentDefinitionInspectionFs = DEFAULT_AGENT_DEFINITION_INSPECTION_FS): AgentDefinitionInspection {
|
|
1810
|
+
const root = path.resolve(dir);
|
|
1811
|
+
try {
|
|
1812
|
+
if (!operations.existsSync(root)) return { files: [], state: "absent" };
|
|
1813
|
+
if (!operations.statSync(root).isDirectory()) return { files: [], state: "not-directory" };
|
|
1814
|
+
} catch {
|
|
1815
|
+
return { files: [], state: "unreadable" };
|
|
1816
|
+
}
|
|
1817
|
+
const files: string[] = [];
|
|
1818
|
+
let unreadable = false;
|
|
1819
|
+
const visitedDirectories = new Set<string>();
|
|
1820
|
+
const visit = (current: string): void => {
|
|
1821
|
+
let realDir: string;
|
|
1822
|
+
try {
|
|
1823
|
+
realDir = operations.realpathSync?.(current) ?? path.resolve(current);
|
|
1824
|
+
} catch {
|
|
1825
|
+
unreadable = true;
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
if (visitedDirectories.has(realDir)) return;
|
|
1829
|
+
visitedDirectories.add(realDir);
|
|
1830
|
+
|
|
1831
|
+
let entries: fs.Dirent[];
|
|
1832
|
+
try {
|
|
1833
|
+
entries = operations.readdirSync(current).sort((a, b) => a.name.localeCompare(b.name));
|
|
1834
|
+
} catch {
|
|
1835
|
+
unreadable = true;
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
for (const entry of entries) {
|
|
1839
|
+
const filePath = path.join(current, entry.name);
|
|
1840
|
+
let isDirectory = entry.isDirectory();
|
|
1841
|
+
if (entry.isSymbolicLink()) {
|
|
1842
|
+
try {
|
|
1843
|
+
isDirectory = operations.statSync(filePath).isDirectory();
|
|
1844
|
+
} catch {
|
|
1845
|
+
isDirectory = false;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
if (isDirectory) {
|
|
1849
|
+
if (!shouldPruneDiscoveryDir(root, filePath, entry.name)) visit(filePath);
|
|
1850
|
+
continue;
|
|
1851
|
+
}
|
|
1852
|
+
if ((entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md") && !entry.name.endsWith(".chain.md") && !isLegacyAgentSkillPath(root, filePath)) files.push(filePath);
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
visit(root);
|
|
1856
|
+
return { files, state: unreadable ? "unreadable" : files.length ? "candidates" : "empty" };
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1627
1859
|
function isLegacyAgentSkillPath(rootDir: string, filePath: string): boolean {
|
|
1628
1860
|
const relative = path.relative(rootDir, filePath);
|
|
1629
1861
|
const parts = relative.split(path.sep).map((part) => part.toLowerCase());
|
|
@@ -1682,24 +1914,29 @@ function parseAgentRunnerFrontmatter(raw: string | undefined, agentName: string)
|
|
|
1682
1914
|
if (runner.args !== undefined && (!Array.isArray(runner.args) || runner.args.some((arg) => typeof arg !== "string"))) {
|
|
1683
1915
|
throw new Error(`Agent '${agentName}' external-cli runner args must be an array of strings.`);
|
|
1684
1916
|
}
|
|
1917
|
+
if (runner.adapter !== undefined && !isCodeOwnedExternalCliAdapterId(runner.adapter)) throw new Error(`Agent '${agentName}' external-cli runner adapter must be ${CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL}.`);
|
|
1918
|
+
if (runner.adapter !== undefined && Array.isArray(runner.args) && runner.args.length > 0) throw new Error(`Agent '${agentName}' ${runner.adapter} adapter owns its argv; runner args are not supported.`);
|
|
1685
1919
|
if (runner.promptDelivery !== undefined && runner.promptDelivery !== "stdin") {
|
|
1686
1920
|
throw new Error(`Agent '${agentName}' external-cli runner promptDelivery must be 'stdin'.`);
|
|
1687
1921
|
}
|
|
1688
|
-
const
|
|
1922
|
+
const capabilities = parseExternalCliCapabilityNarrowing(runner.capabilities, `Agent '${agentName}' external-cli runner capabilities`);
|
|
1923
|
+
const supported = new Set(["type", "adapter", "command", "args", "promptDelivery", "capabilities"]);
|
|
1689
1924
|
const unknown = Object.keys(runner).filter((key) => !supported.has(key));
|
|
1690
1925
|
if (unknown.length > 0) throw new Error(`Agent '${agentName}' external-cli runner has unsupported fields: ${unknown.join(", ")}.`);
|
|
1691
1926
|
const runnerArgs = Array.isArray(runner.args) ? runner.args.filter((arg): arg is string => typeof arg === "string") : undefined;
|
|
1692
1927
|
return {
|
|
1693
1928
|
type: "external-cli",
|
|
1929
|
+
...(isCodeOwnedExternalCliAdapterId(runner.adapter) ? { adapter: runner.adapter } : {}),
|
|
1694
1930
|
command: runner.command.trim(),
|
|
1695
1931
|
...(runnerArgs?.length ? { args: runnerArgs } : {}),
|
|
1696
1932
|
...(runner.promptDelivery ? { promptDelivery: "stdin" as const } : {}),
|
|
1933
|
+
...(capabilities ? { capabilities } : {}),
|
|
1697
1934
|
};
|
|
1698
1935
|
}
|
|
1699
1936
|
|
|
1700
1937
|
function validateExternalRunnerProfile(frontmatter: Record<string, string>, agentName: string, runner: AgentRunnerConfig | undefined): void {
|
|
1701
1938
|
if (runner?.type !== "external-cli" && runner?.type !== "external-job") return;
|
|
1702
|
-
const unsupported = ["tools", "model", "fallbackModels", "thinking", "extensions", "subagentOnlyExtensions", "maxSubagentDepth", "completionGuard", "skills", "skill", "skillPath", "toolBudget", "permission", "permissions"]
|
|
1939
|
+
const unsupported = ["tools", "allowNestedSubagents", "model", "fallbackModels", "thinking", "extensions", "subagentOnlyExtensions", "mutationTools", "maxSubagentDepth", "completionGuard", "skills", "skill", "skillPath", "toolBudget", "permission", "permissions"]
|
|
1703
1940
|
.filter((field) => frontmatter[field] !== undefined);
|
|
1704
1941
|
if (unsupported.length > 0) {
|
|
1705
1942
|
throw new Error(`Agent '${agentName}' uses runner.type='${runner.type}' and declares unsupported Pi-only fields: ${unsupported.join(", ")}.`);
|
|
@@ -1724,9 +1961,9 @@ interface AgentDefinitionFile {
|
|
|
1724
1961
|
content: string;
|
|
1725
1962
|
}
|
|
1726
1963
|
|
|
1727
|
-
function readAgentDefinitionFiles(dir: string): AgentDefinitionFile[] {
|
|
1964
|
+
function readAgentDefinitionFiles(dir: string, inspection = inspectAgentDefinitionDirectory(dir)): AgentDefinitionFile[] {
|
|
1728
1965
|
const files: AgentDefinitionFile[] = [];
|
|
1729
|
-
for (const filePath of
|
|
1966
|
+
for (const filePath of inspection.files) {
|
|
1730
1967
|
if (isLegacyAgentSkillPath(dir, filePath)) {
|
|
1731
1968
|
continue;
|
|
1732
1969
|
}
|
|
@@ -1783,6 +2020,8 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1783
2020
|
const mcpDirectTools = parsedTools.mcpDirectTools ?? [];
|
|
1784
2021
|
const defaultReads = parseFrontmatterList(frontmatter.defaultReads);
|
|
1785
2022
|
const aliases = normalizeAgentAliases(parseFrontmatterList(frontmatter.aliases ?? frontmatter.alias), runtimeName);
|
|
2023
|
+
const profileError = validateCodeOwnedProfileRunner({ name: runtimeName, localName, aliases, runner });
|
|
2024
|
+
if (profileError) throw new Error(profileError);
|
|
1786
2025
|
const skillStr = frontmatter.skill || frontmatter.skills;
|
|
1787
2026
|
const skills = parseFrontmatterList(skillStr);
|
|
1788
2027
|
const skillPath = parseFrontmatterList(frontmatter.skillPath);
|
|
@@ -1797,6 +2036,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1797
2036
|
: frontmatter.inheritProjectContext === "false"
|
|
1798
2037
|
? false
|
|
1799
2038
|
: defaultInheritProjectContext(localName);
|
|
2039
|
+
const inheritGlobalContext = frontmatter.inheritGlobalContext === "true";
|
|
1800
2040
|
const inheritSkills = frontmatter.inheritSkills === "true"
|
|
1801
2041
|
? true
|
|
1802
2042
|
: frontmatter.inheritSkills === "false"
|
|
@@ -1829,13 +2069,6 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1829
2069
|
}
|
|
1830
2070
|
defaultToolTimeoutMs = parsed;
|
|
1831
2071
|
}
|
|
1832
|
-
let defaultTurnBudget: TurnBudgetConfig | undefined;
|
|
1833
|
-
if (frontmatter.turnBudget !== undefined && frontmatter.turnBudget.trim()) {
|
|
1834
|
-
const parsed = JSON.parse(frontmatter.turnBudget) as unknown;
|
|
1835
|
-
const resolved = resolveTurnBudgetConfig(parsed, `Agent '${localName}' turnBudget frontmatter`);
|
|
1836
|
-
if (resolved.error) throw new Error(resolved.error);
|
|
1837
|
-
defaultTurnBudget = resolved.turnBudget;
|
|
1838
|
-
}
|
|
1839
2072
|
const defaultAcceptance = parseAgentAcceptanceFrontmatter(frontmatter.acceptance, localName);
|
|
1840
2073
|
let outputMode: OutputMode | undefined;
|
|
1841
2074
|
if (frontmatter.outputMode !== undefined) {
|
|
@@ -1850,12 +2083,19 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1850
2083
|
|
|
1851
2084
|
const extensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.extensions), filePath);
|
|
1852
2085
|
const subagentOnlyExtensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.subagentOnlyExtensions), filePath);
|
|
2086
|
+
const mutationTools = parseFrontmatterList(frontmatter.mutationTools);
|
|
1853
2087
|
let fast: boolean | undefined;
|
|
1854
2088
|
if (frontmatter.fast !== undefined) {
|
|
1855
2089
|
if (frontmatter.fast === "true") fast = true;
|
|
1856
2090
|
else if (frontmatter.fast === "false") fast = false;
|
|
1857
2091
|
else throw new Error(`Agent '${localName}' has invalid fast frontmatter; expected true or false.`);
|
|
1858
2092
|
}
|
|
2093
|
+
let allowNestedSubagents: boolean | undefined;
|
|
2094
|
+
if (frontmatter.allowNestedSubagents !== undefined) {
|
|
2095
|
+
if (frontmatter.allowNestedSubagents === "true") allowNestedSubagents = true;
|
|
2096
|
+
else if (frontmatter.allowNestedSubagents === "false") allowNestedSubagents = false;
|
|
2097
|
+
else throw new Error(`Agent '${localName}' has invalid allowNestedSubagents frontmatter; expected true or false.`);
|
|
2098
|
+
}
|
|
1859
2099
|
|
|
1860
2100
|
const extraFields: Record<string, string> = {};
|
|
1861
2101
|
for (const [key, value] of Object.entries(frontmatter)) {
|
|
@@ -1899,6 +2139,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1899
2139
|
description: frontmatter.description,
|
|
1900
2140
|
...(aliases !== undefined ? { aliases } : {}),
|
|
1901
2141
|
...(rawTools !== undefined ? { tools } : {}),
|
|
2142
|
+
...(allowNestedSubagents !== undefined ? { allowNestedSubagents } : {}),
|
|
1902
2143
|
...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),
|
|
1903
2144
|
...(frontmatter.model !== undefined ? { model: frontmatter.model } : {}),
|
|
1904
2145
|
...(fallbackModels?.length ? { fallbackModels } : {}),
|
|
@@ -1906,12 +2147,12 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1906
2147
|
...(frontmatter.thinking !== undefined ? { thinking: frontmatter.thinking === "false" ? false : frontmatter.thinking } : {}),
|
|
1907
2148
|
systemPromptMode,
|
|
1908
2149
|
inheritProjectContext,
|
|
2150
|
+
inheritGlobalContext,
|
|
1909
2151
|
inheritSkills,
|
|
1910
2152
|
...(defaultContext !== undefined ? { defaultContext } : {}),
|
|
1911
2153
|
...(defaultAsync !== undefined ? { defaultAsync } : {}),
|
|
1912
2154
|
...(defaultTimeoutMs !== undefined ? { defaultTimeoutMs } : {}),
|
|
1913
2155
|
...(defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs } : {}),
|
|
1914
|
-
...(defaultTurnBudget !== undefined ? { defaultTurnBudget } : {}),
|
|
1915
2156
|
...(defaultAcceptance !== undefined ? { defaultAcceptance } : {}),
|
|
1916
2157
|
...(acceptanceRole !== undefined ? { acceptanceRole } : {}),
|
|
1917
2158
|
systemPrompt: body,
|
|
@@ -1922,6 +2163,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1922
2163
|
...(skillPath?.length ? { skillPath } : {}),
|
|
1923
2164
|
...(extensions !== undefined ? { extensions } : {}),
|
|
1924
2165
|
...(subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions } : {}),
|
|
2166
|
+
...(mutationTools?.length ? { mutationTools } : {}),
|
|
1925
2167
|
...(frontmatter.output !== undefined ? { output: frontmatter.output } : {}),
|
|
1926
2168
|
...(outputMode !== undefined ? { outputMode } : {}),
|
|
1927
2169
|
...(defaultReads?.length ? { defaultReads } : {}),
|
|
@@ -1944,8 +2186,17 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
|
|
|
1944
2186
|
return { agents, diagnostics };
|
|
1945
2187
|
}
|
|
1946
2188
|
|
|
1947
|
-
function loadAgentsFromDir(dir: string, source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir"
|
|
1948
|
-
return loadAgentsFromDefinitionFiles(readAgentDefinitionFiles(dir), source, discoveryPriority, packageSource);
|
|
2189
|
+
function loadAgentsFromDir(dir: string, source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir">, inspection = inspectAgentDefinitionDirectory(dir)): { agents: AgentConfig[]; diagnostics: AgentDiscoveryDiagnostic[] } {
|
|
2190
|
+
return loadAgentsFromDefinitionFiles(readAgentDefinitionFiles(dir, inspection), source, discoveryPriority, packageSource);
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
function reportAgentDefinitionDirectory(source: AgentSource, dir: string, inspection: AgentDefinitionInspection): AgentDefinitionDirectoryReport {
|
|
2194
|
+
return {
|
|
2195
|
+
source,
|
|
2196
|
+
path: path.resolve(dir),
|
|
2197
|
+
state: inspection.state,
|
|
2198
|
+
...(inspection.state === "candidates" ? { candidateCount: inspection.files.length } : {}),
|
|
2199
|
+
};
|
|
1949
2200
|
}
|
|
1950
2201
|
|
|
1951
2202
|
function loadChainsFromDir(dir: string, source: AgentSource): { chains: ChainConfig[]; diagnostics: ChainDiscoveryDiagnostic[] } {
|
|
@@ -1982,20 +2233,18 @@ function isDirectory(p: string): boolean {
|
|
|
1982
2233
|
}
|
|
1983
2234
|
}
|
|
1984
2235
|
|
|
1985
|
-
function resolveNearestProjectAgentDirs(cwd: string): { readDirs: string[]; preferredDir: string | null } {
|
|
2236
|
+
function resolveNearestProjectAgentDirs(cwd: string): { readDirs: string[]; candidateDirs: string[]; preferredDir: string | null } {
|
|
1986
2237
|
const projectRoot = findConfiguredProjectRoot(cwd);
|
|
1987
|
-
if (!projectRoot) return { readDirs: [], preferredDir: null };
|
|
2238
|
+
if (!projectRoot) return { readDirs: [], candidateDirs: [], preferredDir: null };
|
|
1988
2239
|
|
|
1989
2240
|
const legacyDir = path.join(projectRoot, ".agents");
|
|
1990
2241
|
const preferredDir = path.join(getProjectConfigDir(projectRoot), "agents");
|
|
2242
|
+
const candidateDirs = [legacyDir, preferredDir];
|
|
1991
2243
|
const readDirs: string[] = [];
|
|
1992
2244
|
if (isDirectory(legacyDir)) readDirs.push(legacyDir);
|
|
1993
2245
|
if (isDirectory(preferredDir)) readDirs.push(preferredDir);
|
|
1994
2246
|
|
|
1995
|
-
return {
|
|
1996
|
-
readDirs,
|
|
1997
|
-
preferredDir,
|
|
1998
|
-
};
|
|
2247
|
+
return { readDirs, candidateDirs, preferredDir };
|
|
1999
2248
|
}
|
|
2000
2249
|
|
|
2001
2250
|
function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; preferredDir: string | null } {
|
|
@@ -2009,7 +2258,9 @@ function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; pref
|
|
|
2009
2258
|
};
|
|
2010
2259
|
}
|
|
2011
2260
|
const BUILTIN_AGENTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "agents");
|
|
2012
|
-
|
|
2261
|
+
// Candidate files and inspection state must describe the same cached builtin scan.
|
|
2262
|
+
const BUILTIN_AGENT_DEFINITION_INSPECTION = inspectAgentDefinitionDirectory(BUILTIN_AGENTS_DIR);
|
|
2263
|
+
const BUILTIN_AGENT_DEFINITION_FILES = readAgentDefinitionFiles(BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION);
|
|
2013
2264
|
|
|
2014
2265
|
export const EXTRA_AGENT_DIRS_ENV = "SELESAI_SUBAGENT_EXTRA_AGENT_DIRS";
|
|
2015
2266
|
|
|
@@ -2027,82 +2278,78 @@ function extraUserAgentDirs(): string[] {
|
|
|
2027
2278
|
.filter((dir) => dir.length > 0);
|
|
2028
2279
|
}
|
|
2029
2280
|
|
|
2030
|
-
export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
|
|
2281
|
+
export function discoverAgents(cwd: string, scope: AgentScope, preferredModelProvider?: string): AgentDiscoveryResult {
|
|
2282
|
+
const effectiveCwd = path.resolve(cwd);
|
|
2031
2283
|
const userDirOld = path.join(getAgentDir(), "agents");
|
|
2032
2284
|
const userDirNew = path.join(os.homedir(), ".agents");
|
|
2033
|
-
const { readDirs: projectAgentDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(
|
|
2285
|
+
const { readDirs: projectAgentDirs, candidateDirs: projectCandidateDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(effectiveCwd);
|
|
2034
2286
|
const userSettingsPath = getUserAgentSettingsPath();
|
|
2035
|
-
const projectSettingsPath = getProjectAgentSettingsPath(
|
|
2036
|
-
const userSettings = scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath);
|
|
2037
|
-
const projectSettings = scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath);
|
|
2287
|
+
const projectSettingsPath = getProjectAgentSettingsPath(effectiveCwd);
|
|
2288
|
+
const userSettings = selectProviderOverrides(scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath), preferredModelProvider);
|
|
2289
|
+
const projectSettings = selectProviderOverrides(scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath), preferredModelProvider);
|
|
2038
2290
|
const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, projectSettingsPath);
|
|
2039
2291
|
const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath, defaultProvider);
|
|
2040
2292
|
const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
|
|
2041
2293
|
const maxThinking = resolveSubagentMaxThinking(userSettings, projectSettings, projectSettingsPath);
|
|
2042
2294
|
const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, projectSettingsPath);
|
|
2043
2295
|
const modelScope = projectSettings.modelScope ?? userSettings.modelScope;
|
|
2044
|
-
const packageSubagentPaths = collectPackageSubagentPaths(
|
|
2296
|
+
const packageSubagentPaths = collectPackageSubagentPaths(effectiveCwd, {
|
|
2045
2297
|
includeUser: scope !== "project",
|
|
2046
2298
|
includeProject: scope !== "user",
|
|
2047
2299
|
});
|
|
2300
|
+
const directories: AgentDefinitionDirectoryReport[] = [reportAgentDefinitionDirectory("builtin", BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION)];
|
|
2048
2301
|
|
|
2049
2302
|
const builtinLoaded = loadAgentsFromDefinitionFiles(BUILTIN_AGENT_DEFINITION_FILES, "builtin");
|
|
2050
2303
|
const builtinAgents = applyBuiltinOverrides(
|
|
2051
2304
|
applySubagentDefaults(builtinLoaded.agents, defaultModel, defaultProvider, defaultThinking, defaultExtensions),
|
|
2052
|
-
userSettings,
|
|
2053
|
-
projectSettings,
|
|
2054
|
-
userSettingsPath,
|
|
2055
|
-
projectSettingsPath,
|
|
2305
|
+
userSettings, projectSettings, userSettingsPath, projectSettingsPath,
|
|
2056
2306
|
);
|
|
2057
2307
|
|
|
2058
|
-
const userLoaded = scope === "project" ? [] : [...extraUserAgentDirs(), userDirOld, userDirNew]
|
|
2059
|
-
|
|
2308
|
+
const userLoaded = scope === "project" ? [] : [...extraUserAgentDirs(), userDirOld, userDirNew].map((dir, discoveryPriority) => {
|
|
2309
|
+
const inspection = inspectAgentDefinitionDirectory(dir);
|
|
2310
|
+
directories.push(reportAgentDefinitionDirectory("user", dir, inspection));
|
|
2311
|
+
return loadAgentsFromDir(dir, "user", discoveryPriority, undefined, inspection);
|
|
2312
|
+
});
|
|
2060
2313
|
const userAgents = applyCustomAgentOverrides(
|
|
2061
2314
|
applySubagentDefaults(userLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
|
|
2062
|
-
userSettings,
|
|
2063
|
-
projectSettings,
|
|
2064
|
-
userSettingsPath,
|
|
2065
|
-
projectSettingsPath,
|
|
2315
|
+
userSettings, projectSettings, userSettingsPath, projectSettingsPath,
|
|
2066
2316
|
);
|
|
2067
2317
|
|
|
2068
|
-
|
|
2318
|
+
// Report both legacy and preferred project definition paths only after the
|
|
2319
|
+
// existing configured-root resolver found a root; never synthesize cwd paths.
|
|
2320
|
+
const projectInspections = scope === "user" ? new Map<string, AgentDefinitionInspection>() : new Map(projectCandidateDirs.map((dir) => [dir, inspectAgentDefinitionDirectory(dir)]));
|
|
2321
|
+
if (scope !== "user") for (const dir of projectCandidateDirs) directories.push(reportAgentDefinitionDirectory("project", dir, projectInspections.get(dir)!));
|
|
2322
|
+
const projectLoaded = scope === "user" ? [] : projectAgentDirs.map((dir) => loadAgentsFromDir(dir, "project", dir === projectAgentsDir ? 1 : 0, undefined, projectInspections.get(dir)!));
|
|
2069
2323
|
const projectAgents = applyCustomAgentOverrides(
|
|
2070
2324
|
applySubagentDefaults(projectLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
|
|
2071
|
-
userSettings,
|
|
2072
|
-
projectSettings,
|
|
2073
|
-
userSettingsPath,
|
|
2074
|
-
projectSettingsPath,
|
|
2325
|
+
userSettings, projectSettings, userSettingsPath, projectSettingsPath,
|
|
2075
2326
|
);
|
|
2076
|
-
|
|
2327
|
+
|
|
2328
|
+
const packageLoaded = packageSubagentPaths.agents.map((entry, index) => {
|
|
2329
|
+
const inspection = inspectAgentDefinitionDirectory(entry.dir);
|
|
2330
|
+
directories.push(reportAgentDefinitionDirectory("package", entry.dir, inspection));
|
|
2331
|
+
return loadAgentsFromDir(entry.dir, "package", packageSubagentPaths.agents.length - index, entry, inspection);
|
|
2332
|
+
});
|
|
2077
2333
|
const packageMap = new Map<string, AgentConfig>();
|
|
2078
|
-
for (const loaded of packageLoaded)
|
|
2079
|
-
for (const agent of loaded.agents) {
|
|
2080
|
-
if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2334
|
+
for (const loaded of packageLoaded) for (const agent of loaded.agents) if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
|
|
2083
2335
|
const packageAgents = applyCustomAgentOverrides(
|
|
2084
2336
|
applySubagentDefaults(Array.from(packageMap.values()), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
|
|
2085
|
-
userSettings,
|
|
2086
|
-
projectSettings,
|
|
2087
|
-
userSettingsPath,
|
|
2088
|
-
projectSettingsPath,
|
|
2337
|
+
userSettings, projectSettings, userSettingsPath, projectSettingsPath,
|
|
2089
2338
|
);
|
|
2090
2339
|
const agents = applySubagentMaxThinking(
|
|
2091
|
-
mergeAgentsForScope(scope, userAgents, projectAgents, builtinAgents, packageAgents)
|
|
2092
|
-
.filter((agent) => agent.disabled !== true),
|
|
2340
|
+
mergeAgentsForScope(scope, userAgents, projectAgents, builtinAgents, packageAgents).filter((agent) => agent.disabled !== true),
|
|
2093
2341
|
maxThinking,
|
|
2094
2342
|
);
|
|
2095
|
-
|
|
2096
2343
|
const agentDiagnostics = [
|
|
2097
2344
|
...builtinLoaded.diagnostics,
|
|
2098
2345
|
...userLoaded.flatMap((loaded) => loaded.diagnostics),
|
|
2099
2346
|
...projectLoaded.flatMap((loaded) => loaded.diagnostics),
|
|
2100
2347
|
...packageLoaded.flatMap((loaded) => loaded.diagnostics),
|
|
2101
2348
|
];
|
|
2102
|
-
return { agents, agentDiagnostics, projectAgentsDir, ...(modelScope !== undefined ? { modelScope } : {}), ...(maxThinking !== undefined ? { maxThinking } : {}) };
|
|
2349
|
+
return { agents, agentDiagnostics, projectAgentsDir, cwd: effectiveCwd, scope, directories, ...(modelScope !== undefined ? { modelScope } : {}), ...(maxThinking !== undefined ? { maxThinking } : {}) };
|
|
2103
2350
|
}
|
|
2104
2351
|
|
|
2105
|
-
export function discoverAgentsAll(cwd: string): {
|
|
2352
|
+
export function discoverAgentsAll(cwd: string, preferredModelProvider?: string): {
|
|
2106
2353
|
builtin: AgentConfig[];
|
|
2107
2354
|
package: AgentConfig[];
|
|
2108
2355
|
user: AgentConfig[];
|
|
@@ -2125,8 +2372,8 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
2125
2372
|
const { readDirs: projectChainDirs, preferredDir: projectChainDir } = resolveNearestProjectChainDirs(cwd);
|
|
2126
2373
|
const userSettingsPath = getUserAgentSettingsPath();
|
|
2127
2374
|
const projectSettingsPath = getProjectAgentSettingsPath(cwd);
|
|
2128
|
-
const userSettings = readSubagentSettings(userSettingsPath);
|
|
2129
|
-
const projectSettings = readSubagentSettings(projectSettingsPath);
|
|
2375
|
+
const userSettings = selectProviderOverrides(readSubagentSettings(userSettingsPath), preferredModelProvider);
|
|
2376
|
+
const projectSettings = selectProviderOverrides(readSubagentSettings(projectSettingsPath), preferredModelProvider);
|
|
2130
2377
|
const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, projectSettingsPath);
|
|
2131
2378
|
const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath, defaultProvider);
|
|
2132
2379
|
const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
|