@duckmind/dm-windows-x64 0.61.4 → 0.61.9
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +211 -67
- package/extensions/dm-subagents/agents/claude-code-writer.md +15 -0
- package/extensions/dm-subagents/agents/claude-code.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec-writer.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec.md +15 -0
- package/extensions/dm-subagents/agents/cursor-agent-writer.md +14 -0
- package/extensions/dm-subagents/agents/cursor-agent.md +14 -0
- package/extensions/dm-subagents/agents/delegate.md +3 -2
- package/extensions/dm-subagents/agents/oracle.md +10 -5
- package/extensions/dm-subagents/agents/researcher.md +2 -2
- package/extensions/dm-subagents/agents/reviewer.md +17 -7
- package/extensions/dm-subagents/agents/scout.md +5 -5
- package/extensions/dm-subagents/agents/worker.md +6 -2
- package/extensions/dm-subagents/async-retention-discovery-worker.mjs +167 -0
- package/extensions/dm-subagents/index.js +4 -0
- package/extensions/dm-subagents/inspector-runner.mjs +10 -0
- package/extensions/dm-subagents/install.mjs +3 -2
- package/extensions/dm-subagents/package.json +2 -2
- package/extensions/dm-subagents/prompts/council.md +60 -0
- package/extensions/dm-subagents/prompts/parallel-review.md +5 -1
- package/extensions/dm-subagents/prompts/review-loop.md +13 -7
- package/extensions/dm-subagents/skills/council-mode/SKILL.md +59 -0
- package/extensions/dm-subagents/skills/council-mode/references/pass-contracts.md +150 -0
- package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +96 -911
- package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +70 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +539 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +161 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +51 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +295 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +73 -0
- package/extensions/dm-subagents/src/agents/agent-management.js +716 -484
- package/extensions/dm-subagents/src/agents/agent-refinements.js +563 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +70 -5
- package/extensions/dm-subagents/src/agents/agents.js +1447 -299
- package/extensions/dm-subagents/src/agents/builtin-names.js +15 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -7
- package/extensions/dm-subagents/src/agents/frontmatter.js +64 -14
- package/extensions/dm-subagents/src/agents/identity.js +1 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +14 -11
- package/extensions/dm-subagents/src/agents/runtime-agent-events.js +49 -0
- package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +412 -0
- package/extensions/dm-subagents/src/agents/skills.js +52 -35
- package/extensions/dm-subagents/src/api/agents.js +6 -0
- package/extensions/dm-subagents/src/api/background-work.js +151 -0
- package/extensions/dm-subagents/src/api/capability-ceiling.js +12 -0
- package/extensions/dm-subagents/src/api/control-channel.js +3 -0
- package/extensions/dm-subagents/src/api/delegation.js +5 -0
- package/extensions/dm-subagents/src/api/dm-args.js +3 -0
- package/extensions/dm-subagents/src/api/external-job-provider.js +137 -0
- package/extensions/dm-subagents/src/api/external-runs.js +233 -0
- package/extensions/dm-subagents/src/api/intercom-bridge.js +3 -0
- package/extensions/dm-subagents/src/api/preflight.js +322 -0
- package/extensions/dm-subagents/src/api/project-panes.js +11 -0
- package/extensions/dm-subagents/src/api/shared-types.js +4 -0
- package/extensions/dm-subagents/src/extension/config.js +175 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -43
- package/extensions/dm-subagents/src/extension/doctor.js +71 -17
- package/extensions/dm-subagents/src/extension/fanout-child.js +49 -32
- package/extensions/dm-subagents/src/extension/index.js +711 -265
- package/extensions/dm-subagents/src/extension/public-execution.js +114 -0
- package/extensions/dm-subagents/src/extension/rpc.js +427 -22
- package/extensions/dm-subagents/src/extension/schemas.js +158 -65
- package/extensions/dm-subagents/src/extension/steering-notices.js +23 -0
- package/extensions/dm-subagents/src/extension/subagent-guide.js +31 -0
- package/extensions/dm-subagents/src/extension/tool-description.js +92 -74
- package/extensions/dm-subagents/src/extension/tool-result.js +7 -0
- package/extensions/dm-subagents/src/inspectors/herdr/actions.js +218 -0
- package/extensions/dm-subagents/src/inspectors/herdr/client.js +123 -0
- package/extensions/dm-subagents/src/inspectors/herdr/focus.js +47 -0
- package/extensions/dm-subagents/src/inspectors/herdr/inspector-runner.js +160 -0
- package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +618 -0
- package/extensions/dm-subagents/src/inspectors/herdr/session-roots-codec.js +21 -0
- package/extensions/dm-subagents/src/inspectors/herdr/shell-command.js +15 -0
- package/extensions/dm-subagents/src/integrations/herdr-status.js +377 -0
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +17 -13
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +371 -79
- package/extensions/dm-subagents/src/intercom/result-intercom.js +47 -7
- package/extensions/dm-subagents/src/missions/actions.js +394 -0
- package/extensions/dm-subagents/src/missions/goal-driver.js +149 -0
- package/extensions/dm-subagents/src/missions/lifecycle.js +331 -0
- package/extensions/dm-subagents/src/missions/store.js +548 -0
- package/extensions/dm-subagents/src/missions/types.js +9 -0
- package/extensions/dm-subagents/src/missions/workflow-state.js +245 -0
- package/extensions/dm-subagents/src/policy/authority.js +37 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +36 -18
- package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +427 -0
- package/extensions/dm-subagents/src/runs/background/active-run-index.js +122 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +925 -137
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +515 -148
- package/extensions/dm-subagents/src/runs/background/async-resume.js +378 -51
- package/extensions/dm-subagents/src/runs/background/async-retention.js +828 -0
- package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +31 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +259 -22
- package/extensions/dm-subagents/src/runs/background/auto-drain.js +46 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +50 -15
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +67 -12
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +5 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +3 -11
- package/extensions/dm-subagents/src/runs/background/completion-replay.js +245 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +423 -36
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +132 -59
- package/extensions/dm-subagents/src/runs/background/index-segment.js +38 -0
- package/extensions/dm-subagents/src/runs/background/inspect-rpc.js +373 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +357 -57
- package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +86 -0
- package/extensions/dm-subagents/src/runs/background/process-terminal.js +269 -0
- package/extensions/dm-subagents/src/runs/background/result-delivery-ownership.js +34 -0
- package/extensions/dm-subagents/src/runs/background/result-files.js +469 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +540 -75
- package/extensions/dm-subagents/src/runs/background/resume-guidance.js +44 -0
- package/extensions/dm-subagents/src/runs/background/retained-children.js +119 -0
- package/extensions/dm-subagents/src/runs/background/run-id-query.js +5 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +93 -9
- package/extensions/dm-subagents/src/runs/background/run-status.js +303 -32
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +784 -376
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +75 -34
- package/extensions/dm-subagents/src/runs/background/steering.js +221 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +3106 -844
- package/extensions/dm-subagents/src/runs/background/subagent-wait.js +529 -0
- package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +106 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -1
- package/extensions/dm-subagents/src/runs/background/wait-completions.js +155 -0
- package/extensions/dm-subagents/src/runs/background/wait-config.js +46 -0
- package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +278 -0
- package/extensions/dm-subagents/src/runs/background/wait-tool.js +47 -0
- package/extensions/dm-subagents/src/runs/foreground/async-dismiss-action.js +81 -0
- package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +245 -0
- package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +74 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1401 -342
- package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +133 -0
- package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +148 -0
- package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +139 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +4278 -1441
- package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +278 -0
- package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +155 -0
- package/extensions/dm-subagents/src/runs/shared/abort-recovery.js +97 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +597 -148
- package/extensions/dm-subagents/src/runs/shared/agent-contract.js +35 -0
- package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +472 -0
- package/extensions/dm-subagents/src/runs/shared/background-process-options.js +6 -0
- package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +175 -0
- package/extensions/dm-subagents/src/runs/shared/child-identity.js +32 -0
- package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +65 -0
- package/extensions/dm-subagents/src/runs/shared/child-protocol.js +447 -0
- package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +120 -0
- package/extensions/dm-subagents/src/runs/shared/codex-exec-adapter.js +129 -0
- package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +40 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +140 -83
- package/extensions/dm-subagents/src/runs/shared/context-mode.js +38 -0
- package/extensions/dm-subagents/src/runs/shared/cursor-agent-adapter.js +101 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +445 -72
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +27 -16
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +19 -6
- package/extensions/dm-subagents/src/runs/shared/extension-bindings.js +81 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +134 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +98 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +419 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +404 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-runner.js +334 -0
- package/extensions/dm-subagents/src/runs/shared/fast-mode-extension.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/host-step-status.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +104 -0
- package/extensions/dm-subagents/src/runs/shared/launch-cwd.js +17 -0
- package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +190 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +48 -3
- package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +387 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +212 -137
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +131 -0
- package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +207 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +225 -55
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +85 -28
- package/extensions/dm-subagents/src/runs/shared/mutation-evidence.js +182 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +264 -102
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +15 -5
- package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +505 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +653 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +29 -12
- package/extensions/dm-subagents/src/runs/shared/permissions.js +108 -0
- package/extensions/dm-subagents/src/runs/shared/process-signal.js +13 -0
- package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +257 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +133 -13
- package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +62 -0
- package/extensions/dm-subagents/src/runs/shared/session-lease.js +225 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +129 -27
- package/extensions/dm-subagents/src/runs/shared/spawn-budget.js +95 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +129 -10
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +66 -11
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +548 -70
- package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +50 -0
- package/extensions/dm-subagents/src/runs/shared/task-intent.js +130 -0
- package/extensions/dm-subagents/src/runs/shared/tool-availability.js +59 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +7 -5
- package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +64 -0
- package/extensions/dm-subagents/src/runs/shared/usage-budget.js +74 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +721 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +168 -19
- package/extensions/dm-subagents/src/shared/accessible-dir.js +35 -0
- package/extensions/dm-subagents/src/shared/agent-stream-options.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +170 -11
- package/extensions/dm-subagents/src/shared/atomic-json.js +36 -38
- package/extensions/dm-subagents/src/shared/capacity-resilient-json.js +77 -0
- package/extensions/dm-subagents/src/shared/child-session-name.js +15 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +57 -2
- package/extensions/dm-subagents/src/shared/completion-owner.js +7 -0
- package/extensions/dm-subagents/src/shared/display-text.js +142 -0
- package/extensions/dm-subagents/src/shared/extension-context.js +17 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +9 -0
- package/extensions/dm-subagents/src/shared/file-system-retry.js +56 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +96 -33
- package/extensions/dm-subagents/src/shared/formatters.js +21 -7
- package/extensions/dm-subagents/src/shared/launch-contract.js +94 -0
- package/extensions/dm-subagents/src/shared/model-info.js +10 -5
- package/extensions/dm-subagents/src/shared/node-executable.js +19 -0
- package/extensions/dm-subagents/src/shared/prompt-resources.js +10 -0
- package/extensions/dm-subagents/src/shared/pruned-fork.js +427 -0
- package/extensions/dm-subagents/src/shared/session-file-trust.js +19 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +14 -3
- package/extensions/dm-subagents/src/shared/settings.js +39 -47
- package/extensions/dm-subagents/src/shared/shortcuts.js +16 -0
- package/extensions/dm-subagents/src/shared/status-format.js +9 -2
- package/extensions/dm-subagents/src/shared/thinking-ceiling.js +41 -0
- package/extensions/dm-subagents/src/shared/types.js +47 -7
- package/extensions/dm-subagents/src/shared/utf8.js +12 -0
- package/extensions/dm-subagents/src/shared/utils.js +151 -131
- package/extensions/dm-subagents/src/shared/watch-strategy.js +3 -0
- package/extensions/dm-subagents/src/shared/workflow-child-permit.js +84 -0
- package/extensions/dm-subagents/src/slash/delegation-adapters.js +274 -0
- package/extensions/dm-subagents/src/slash/delegation-json.js +113 -0
- package/extensions/dm-subagents/src/slash/delegation-request.js +152 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +294 -243
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +35 -73
- package/extensions/dm-subagents/src/slash/selector.js +101 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +17 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +722 -732
- package/extensions/dm-subagents/src/slash/slash-live-state.js +37 -19
- package/extensions/dm-subagents/src/slash/subagents-admin.js +410 -0
- package/extensions/dm-subagents/src/tui/fleet-status.js +824 -0
- package/extensions/dm-subagents/src/tui/fleet-transcript.js +479 -0
- package/extensions/dm-subagents/src/tui/fleet.js +1326 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +22 -0
- package/extensions/dm-subagents/src/tui/render.js +1511 -261
- package/extensions/dm-subagents/src/watchdog/change-signature.js +220 -0
- package/extensions/dm-subagents/src/watchdog/child-status.js +151 -0
- package/extensions/dm-subagents/src/watchdog/emission-guard.js +90 -0
- package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +484 -0
- package/extensions/dm-subagents/src/watchdog/model-selection.js +154 -0
- package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +138 -0
- package/extensions/dm-subagents/src/watchdog/register-child.js +112 -0
- package/extensions/dm-subagents/src/watchdog/register-main.js +419 -0
- package/extensions/dm-subagents/src/watchdog/render.js +54 -0
- package/extensions/dm-subagents/src/watchdog/review.js +251 -0
- package/extensions/dm-subagents/src/watchdog/runtime.js +803 -0
- package/extensions/dm-subagents/src/watchdog/scope.js +56 -0
- package/extensions/dm-subagents/src/watchdog/settings.js +515 -0
- package/extensions/dm-subagents/src/watchdog/tool-actions.js +151 -0
- package/extensions/dm-subagents/src/watchdog/turn-delta.js +169 -0
- package/extensions/dm-subagents/src/watchdog/types.js +29 -0
- package/extensions/dm-subagents/src/watchdog/warning-format.js +58 -0
- package/extensions/dm-subagents/src/workflows/chat-progress.js +116 -0
- package/extensions/dm-subagents/src/workflows/host-command.js +227 -0
- package/extensions/dm-subagents/src/workflows/scripted-workflow.js +2011 -0
- package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +116 -0
- package/extensions/dm-subagents/src/workflows/workflow-preflight.js +243 -0
- package/extensions/dm-subagents/src/workflows/workflow-receipt.js +387 -0
- package/extensions/dm-subagents/src/workflows/workflow-settlement.js +189 -0
- package/package.json +4 -3
- package/extensions/dm-fff/package.json +0 -21
- package/extensions/dm-fff/src/index.js +0 -691
- package/extensions/dm-fff/src/query.js +0 -60
- package/extensions/dm-subagents/agents/context-builder.md +0 -46
- package/extensions/dm-subagents/agents/planner.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-context-build.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-handoff-plan.md +0 -61
- package/extensions/dm-subagents/src/runs/background/wait.js +0 -206
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +0 -1013
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +0 -981
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +0 -50
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, parseExternalCliCapabilityNarrowing, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.js";
|
|
2
|
+
import { validateAcceptanceInput } from "../runs/shared/acceptance.js";
|
|
3
|
+
import { validatePermissionRules } from "../runs/shared/permissions.js";
|
|
4
|
+
import { validateToolBudgetConfig } from "../runs/shared/tool-budget.js";
|
|
5
|
+
import { BUILTIN_AGENT_NAMES } from "./builtin-names.js";
|
|
6
|
+
export const RUNTIME_AGENT_REGISTRY_KEY = "dm-subagents.runtime-agents.v1";
|
|
7
|
+
const MAX_RUNTIME_AGENTS_PER_PI = 200;
|
|
8
|
+
const MAX_AGENT_NAME_LENGTH = 128;
|
|
9
|
+
const MAX_DESCRIPTION_LENGTH = 4096;
|
|
10
|
+
const MAX_SYSTEM_PROMPT_LENGTH = 1024 * 1024;
|
|
11
|
+
const MAX_FIELD_STRING_LENGTH = 8192;
|
|
12
|
+
function defaultSystemPromptMode(name) {
|
|
13
|
+
return name === "delegate" ? "append" : "replace";
|
|
14
|
+
}
|
|
15
|
+
function defaultInheritProjectContext(name) {
|
|
16
|
+
return name === "delegate";
|
|
17
|
+
}
|
|
18
|
+
function defaultInheritSkills() {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
function registry() {
|
|
22
|
+
const key = Symbol.for(RUNTIME_AGENT_REGISTRY_KEY);
|
|
23
|
+
const globalObject = globalThis;
|
|
24
|
+
const existing = globalObject[key];
|
|
25
|
+
if (existing === undefined) {
|
|
26
|
+
const created = { version: 1, byPi: new WeakMap };
|
|
27
|
+
globalObject[key] = created;
|
|
28
|
+
return created;
|
|
29
|
+
}
|
|
30
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
31
|
+
throw new Error(`Malformed runtime agent registry at Symbol.for("${RUNTIME_AGENT_REGISTRY_KEY}").`);
|
|
32
|
+
}
|
|
33
|
+
const candidate = existing;
|
|
34
|
+
if (candidate.version !== 1 || !(candidate.byPi instanceof WeakMap)) {
|
|
35
|
+
throw new Error(`Unsupported runtime agent registry at Symbol.for("${RUNTIME_AGENT_REGISTRY_KEY}").`);
|
|
36
|
+
}
|
|
37
|
+
return candidate;
|
|
38
|
+
}
|
|
39
|
+
function validatePi(value) {
|
|
40
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
41
|
+
throw new Error("Runtime agent dm must be an ExtensionAPI object.");
|
|
42
|
+
const dm = value;
|
|
43
|
+
if (typeof dm.on !== "function" || typeof dm.registerTool !== "function")
|
|
44
|
+
throw new Error("Runtime agent dm must be an ExtensionAPI object.");
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
function validateString(value, field, maxLength) {
|
|
48
|
+
if (typeof value !== "string" || value.length === 0 || value.trim() !== value) {
|
|
49
|
+
throw new Error(`${field} must be a non-empty string without leading or trailing whitespace.`);
|
|
50
|
+
}
|
|
51
|
+
if (value.length > maxLength)
|
|
52
|
+
throw new Error(`${field} must be at most ${maxLength} characters.`);
|
|
53
|
+
if (value.includes("\x00"))
|
|
54
|
+
throw new Error(`${field} must not contain NUL characters.`);
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function validateOptionalString(value, field, maxLength = MAX_FIELD_STRING_LENGTH) {
|
|
58
|
+
if (value === undefined)
|
|
59
|
+
return;
|
|
60
|
+
return validateString(value, field, maxLength);
|
|
61
|
+
}
|
|
62
|
+
function validateStringList(value, field) {
|
|
63
|
+
if (value === undefined)
|
|
64
|
+
return;
|
|
65
|
+
if (!Array.isArray(value))
|
|
66
|
+
throw new Error(`${field} must be an array of strings when provided.`);
|
|
67
|
+
return [...new Set(value.map((entry, index) => validateString(entry, `${field}[${index}]`, MAX_FIELD_STRING_LENGTH)))];
|
|
68
|
+
}
|
|
69
|
+
function validatePositiveInteger(value, field) {
|
|
70
|
+
if (value === undefined)
|
|
71
|
+
return;
|
|
72
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0)
|
|
73
|
+
throw new Error(`${field} must be a positive integer when provided.`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
function validateBoolean(value, field) {
|
|
77
|
+
if (value === undefined)
|
|
78
|
+
return;
|
|
79
|
+
if (typeof value !== "boolean")
|
|
80
|
+
throw new Error(`${field} must be a boolean when provided.`);
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
function isJsonSerializable(value) {
|
|
84
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
85
|
+
return true;
|
|
86
|
+
if (typeof value === "number")
|
|
87
|
+
return Number.isFinite(value);
|
|
88
|
+
if (Array.isArray(value))
|
|
89
|
+
return value.every(isJsonSerializable);
|
|
90
|
+
if (value && typeof value === "object")
|
|
91
|
+
return Object.values(value).every(isJsonSerializable);
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
function validateRunner(value) {
|
|
95
|
+
if (value === undefined)
|
|
96
|
+
return;
|
|
97
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
98
|
+
throw new Error("Runtime agent definition runner must be an object when provided.");
|
|
99
|
+
const runner = value;
|
|
100
|
+
if (runner.type === "dm") {
|
|
101
|
+
if (Object.keys(runner).some((key) => key !== "type"))
|
|
102
|
+
throw new Error("Runtime agent definition DM runner supports only 'type'.");
|
|
103
|
+
return { type: "dm" };
|
|
104
|
+
}
|
|
105
|
+
if (runner.type === "external-job") {
|
|
106
|
+
if (typeof runner.provider !== "string" || !runner.provider.trim() || runner.provider.trim() !== runner.provider)
|
|
107
|
+
throw new Error("Runtime agent definition external-job runner requires a non-empty trimmed provider string.");
|
|
108
|
+
if (runner.options !== undefined && (!runner.options || typeof runner.options !== "object" || Array.isArray(runner.options) || !isJsonSerializable(runner.options)))
|
|
109
|
+
throw new Error("Runtime agent definition external-job runner options must be a JSON-serializable object.");
|
|
110
|
+
const supported = new Set(["type", "provider", "options"]);
|
|
111
|
+
const unknown = Object.keys(runner).filter((key) => !supported.has(key));
|
|
112
|
+
if (unknown.length > 0)
|
|
113
|
+
throw new Error(`Runtime agent definition external-job runner has unsupported fields: ${unknown.join(", ")}.`);
|
|
114
|
+
return { type: "external-job", provider: runner.provider, ...runner.options ? { options: runner.options } : {} };
|
|
115
|
+
}
|
|
116
|
+
if (runner.type !== "external-cli")
|
|
117
|
+
throw new Error("Runtime agent definition runner.type must be 'dm', 'external-cli', or 'external-job'.");
|
|
118
|
+
if (typeof runner.command !== "string" || !runner.command.trim())
|
|
119
|
+
throw new Error("Runtime agent definition external-cli runner requires a non-empty command string.");
|
|
120
|
+
if (runner.args !== undefined && (!Array.isArray(runner.args) || runner.args.some((arg) => typeof arg !== "string")))
|
|
121
|
+
throw new Error("Runtime agent definition external-cli runner args must be an array of strings.");
|
|
122
|
+
if (runner.adapter !== undefined && !isCodeOwnedExternalCliAdapterId(runner.adapter))
|
|
123
|
+
throw new Error(`Runtime agent definition external-cli runner adapter must be ${CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL}.`);
|
|
124
|
+
if (runner.adapter !== undefined && Array.isArray(runner.args) && runner.args.length > 0)
|
|
125
|
+
throw new Error(`Runtime agent definition ${runner.adapter} adapter owns its argv; runner args are not supported.`);
|
|
126
|
+
if (runner.promptDelivery !== undefined && runner.promptDelivery !== "stdin")
|
|
127
|
+
throw new Error("Runtime agent definition external-cli runner promptDelivery must be 'stdin'.");
|
|
128
|
+
const capabilities = parseExternalCliCapabilityNarrowing(runner.capabilities, "Runtime agent definition external-cli runner capabilities");
|
|
129
|
+
const supported = new Set(["type", "adapter", "command", "args", "promptDelivery", "capabilities"]);
|
|
130
|
+
const unknown = Object.keys(runner).filter((key) => !supported.has(key));
|
|
131
|
+
if (unknown.length > 0)
|
|
132
|
+
throw new Error(`Runtime agent definition external-cli runner has unsupported fields: ${unknown.join(", ")}.`);
|
|
133
|
+
const args = runner.args;
|
|
134
|
+
return { type: "external-cli", ...isCodeOwnedExternalCliAdapterId(runner.adapter) ? { adapter: runner.adapter } : {}, command: runner.command.trim(), ...args?.length ? { args } : {}, ...runner.promptDelivery ? { promptDelivery: "stdin" } : {}, ...capabilities ? { capabilities } : {} };
|
|
135
|
+
}
|
|
136
|
+
function validateAcceptance(value) {
|
|
137
|
+
const errors = validateAcceptanceInput(value, "Runtime agent definition defaultAcceptance");
|
|
138
|
+
if (errors.length > 0)
|
|
139
|
+
throw new Error(errors.join(" "));
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
function validateToolBudget(value) {
|
|
143
|
+
const result = validateToolBudgetConfig(value, "Runtime agent definition toolBudget");
|
|
144
|
+
if (result.error)
|
|
145
|
+
throw new Error(result.error);
|
|
146
|
+
return result.budget;
|
|
147
|
+
}
|
|
148
|
+
function validateDefinition(value) {
|
|
149
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
150
|
+
throw new Error("Runtime agent definition must be an object.");
|
|
151
|
+
const definition = value;
|
|
152
|
+
const supported = new Set([
|
|
153
|
+
"description",
|
|
154
|
+
"systemPrompt",
|
|
155
|
+
"aliases",
|
|
156
|
+
"tools",
|
|
157
|
+
"allowNestedSubagents",
|
|
158
|
+
"mcpDirectTools",
|
|
159
|
+
"model",
|
|
160
|
+
"fallbackModels",
|
|
161
|
+
"thinking",
|
|
162
|
+
"systemPromptMode",
|
|
163
|
+
"inheritProjectContext",
|
|
164
|
+
"inheritGlobalContext",
|
|
165
|
+
"inheritSkills",
|
|
166
|
+
"defaultContext",
|
|
167
|
+
"defaultAsync",
|
|
168
|
+
"defaultTimeoutMs",
|
|
169
|
+
"defaultToolTimeoutMs",
|
|
170
|
+
"defaultAcceptance",
|
|
171
|
+
"acceptanceRole",
|
|
172
|
+
"runner",
|
|
173
|
+
"skills",
|
|
174
|
+
"skillPath",
|
|
175
|
+
"extensions",
|
|
176
|
+
"subagentOnlyExtensions",
|
|
177
|
+
"mutationTools",
|
|
178
|
+
"output",
|
|
179
|
+
"outputMode",
|
|
180
|
+
"defaultReads",
|
|
181
|
+
"defaultProgress",
|
|
182
|
+
"interactive",
|
|
183
|
+
"maxSubagentDepth",
|
|
184
|
+
"completionGuard",
|
|
185
|
+
"toolBudget",
|
|
186
|
+
"permissions"
|
|
187
|
+
]);
|
|
188
|
+
const unknown = Object.keys(definition).filter((key) => !supported.has(key));
|
|
189
|
+
if (unknown.length > 0)
|
|
190
|
+
throw new Error(`Runtime agent definition has unknown fields: ${unknown.join(", ")}.`);
|
|
191
|
+
const systemPromptMode = definition.systemPromptMode;
|
|
192
|
+
if (systemPromptMode !== undefined && systemPromptMode !== "append" && systemPromptMode !== "replace")
|
|
193
|
+
throw new Error("Runtime agent definition systemPromptMode must be 'append' or 'replace'.");
|
|
194
|
+
const defaultContext = definition.defaultContext;
|
|
195
|
+
if (defaultContext !== undefined && defaultContext !== "fresh" && defaultContext !== "fork")
|
|
196
|
+
throw new Error("Runtime agent definition defaultContext must be 'fresh' or 'fork'.");
|
|
197
|
+
const thinking = definition.thinking;
|
|
198
|
+
if (thinking !== undefined && thinking !== false && typeof thinking !== "string")
|
|
199
|
+
throw new Error("Runtime agent definition thinking must be a string or false when provided.");
|
|
200
|
+
const acceptanceRole = definition.acceptanceRole;
|
|
201
|
+
if (acceptanceRole !== undefined && acceptanceRole !== "read-only" && acceptanceRole !== "writer")
|
|
202
|
+
throw new Error("Runtime agent definition acceptanceRole must be 'read-only' or 'writer'.");
|
|
203
|
+
const outputMode = definition.outputMode;
|
|
204
|
+
if (outputMode !== undefined && outputMode !== "inline" && outputMode !== "file-only")
|
|
205
|
+
throw new Error("Runtime agent definition outputMode must be 'inline' or 'file-only'.");
|
|
206
|
+
const aliases = validateStringList(definition.aliases, "Runtime agent definition aliases");
|
|
207
|
+
const tools = validateStringList(definition.tools, "Runtime agent definition tools");
|
|
208
|
+
const allowNestedSubagents = validateBoolean(definition.allowNestedSubagents, "Runtime agent definition allowNestedSubagents");
|
|
209
|
+
const mcpDirectTools = validateStringList(definition.mcpDirectTools, "Runtime agent definition mcpDirectTools");
|
|
210
|
+
const model = validateOptionalString(definition.model, "Runtime agent definition model");
|
|
211
|
+
const fallbackModels = validateStringList(definition.fallbackModels, "Runtime agent definition fallbackModels");
|
|
212
|
+
const inheritProjectContext = validateBoolean(definition.inheritProjectContext, "Runtime agent definition inheritProjectContext");
|
|
213
|
+
const inheritGlobalContext = validateBoolean(definition.inheritGlobalContext, "Runtime agent definition inheritGlobalContext");
|
|
214
|
+
const inheritSkills = validateBoolean(definition.inheritSkills, "Runtime agent definition inheritSkills");
|
|
215
|
+
const defaultAsync = validateBoolean(definition.defaultAsync, "Runtime agent definition defaultAsync");
|
|
216
|
+
const defaultTimeoutMs = validatePositiveInteger(definition.defaultTimeoutMs, "Runtime agent definition defaultTimeoutMs");
|
|
217
|
+
const defaultToolTimeoutMs = validatePositiveInteger(definition.defaultToolTimeoutMs, "Runtime agent definition defaultToolTimeoutMs");
|
|
218
|
+
const defaultAcceptance = validateAcceptance(definition.defaultAcceptance);
|
|
219
|
+
const runner = validateRunner(definition.runner);
|
|
220
|
+
const skills = validateStringList(definition.skills, "Runtime agent definition skills");
|
|
221
|
+
const skillPath = validateStringList(definition.skillPath, "Runtime agent definition skillPath");
|
|
222
|
+
const extensions = validateStringList(definition.extensions, "Runtime agent definition extensions");
|
|
223
|
+
const subagentOnlyExtensions = validateStringList(definition.subagentOnlyExtensions, "Runtime agent definition subagentOnlyExtensions");
|
|
224
|
+
const mutationTools = validateStringList(definition.mutationTools, "Runtime agent definition mutationTools");
|
|
225
|
+
const output = validateOptionalString(definition.output, "Runtime agent definition output");
|
|
226
|
+
const defaultReads = validateStringList(definition.defaultReads, "Runtime agent definition defaultReads");
|
|
227
|
+
const defaultProgress = validateBoolean(definition.defaultProgress, "Runtime agent definition defaultProgress");
|
|
228
|
+
const interactive = validateBoolean(definition.interactive, "Runtime agent definition interactive");
|
|
229
|
+
const maxSubagentDepth = validatePositiveInteger(definition.maxSubagentDepth, "Runtime agent definition maxSubagentDepth");
|
|
230
|
+
const completionGuard = validateBoolean(definition.completionGuard, "Runtime agent definition completionGuard");
|
|
231
|
+
const toolBudget = validateToolBudget(definition.toolBudget);
|
|
232
|
+
const permissions = validatePermissionRules(definition.permissions, "Runtime agent definition permissions");
|
|
233
|
+
return {
|
|
234
|
+
description: validateString(definition.description, "Runtime agent definition description", MAX_DESCRIPTION_LENGTH),
|
|
235
|
+
systemPrompt: validateString(definition.systemPrompt, "Runtime agent definition systemPrompt", MAX_SYSTEM_PROMPT_LENGTH),
|
|
236
|
+
...aliases ? { aliases } : {},
|
|
237
|
+
...tools ? { tools } : {},
|
|
238
|
+
...allowNestedSubagents !== undefined ? { allowNestedSubagents } : {},
|
|
239
|
+
...mcpDirectTools ? { mcpDirectTools } : {},
|
|
240
|
+
...model ? { model } : {},
|
|
241
|
+
...fallbackModels ? { fallbackModels } : {},
|
|
242
|
+
...thinking !== undefined ? { thinking } : {},
|
|
243
|
+
...systemPromptMode !== undefined ? { systemPromptMode } : {},
|
|
244
|
+
...inheritProjectContext !== undefined ? { inheritProjectContext } : {},
|
|
245
|
+
...inheritGlobalContext !== undefined ? { inheritGlobalContext } : {},
|
|
246
|
+
...inheritSkills !== undefined ? { inheritSkills } : {},
|
|
247
|
+
...defaultContext !== undefined ? { defaultContext } : {},
|
|
248
|
+
...defaultAsync !== undefined ? { defaultAsync } : {},
|
|
249
|
+
...defaultTimeoutMs !== undefined ? { defaultTimeoutMs } : {},
|
|
250
|
+
...defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs } : {},
|
|
251
|
+
...defaultAcceptance !== undefined ? { defaultAcceptance } : {},
|
|
252
|
+
...acceptanceRole !== undefined ? { acceptanceRole } : {},
|
|
253
|
+
...runner !== undefined ? { runner } : {},
|
|
254
|
+
...skills ? { skills } : {},
|
|
255
|
+
...skillPath ? { skillPath } : {},
|
|
256
|
+
...extensions ? { extensions } : {},
|
|
257
|
+
...subagentOnlyExtensions ? { subagentOnlyExtensions } : {},
|
|
258
|
+
...mutationTools ? { mutationTools } : {},
|
|
259
|
+
...output ? { output } : {},
|
|
260
|
+
...outputMode !== undefined ? { outputMode } : {},
|
|
261
|
+
...defaultReads ? { defaultReads } : {},
|
|
262
|
+
...defaultProgress !== undefined ? { defaultProgress } : {},
|
|
263
|
+
...interactive !== undefined ? { interactive } : {},
|
|
264
|
+
...maxSubagentDepth !== undefined ? { maxSubagentDepth } : {},
|
|
265
|
+
...completionGuard !== undefined ? { completionGuard } : {},
|
|
266
|
+
...toolBudget !== undefined ? { toolBudget } : {},
|
|
267
|
+
...permissions !== undefined ? { permissions } : {}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function normalizeAliases(rawAliases, agentName) {
|
|
271
|
+
const aliases = [...new Set((rawAliases ?? []).map((alias) => alias.trim()).filter(Boolean))].filter((alias) => alias !== agentName);
|
|
272
|
+
return aliases.length > 0 ? aliases : undefined;
|
|
273
|
+
}
|
|
274
|
+
function identityKeys(agent) {
|
|
275
|
+
return [agent.name, ...agent.localName ? [agent.localName] : [], ...agent.aliases ?? []];
|
|
276
|
+
}
|
|
277
|
+
function assertNoIdentityCollisions(agents, context) {
|
|
278
|
+
const seen = new Map;
|
|
279
|
+
for (const agent of agents) {
|
|
280
|
+
for (const key of identityKeys(agent)) {
|
|
281
|
+
const previous = seen.get(key);
|
|
282
|
+
if (previous !== undefined)
|
|
283
|
+
throw new Error(`${context} collision for '${key}' between '${previous}' and '${agent.name}'.`);
|
|
284
|
+
seen.set(key, agent.name);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function assertNoRuntimeCollision(agent, existing) {
|
|
289
|
+
const existingKeys = new Map;
|
|
290
|
+
for (const registered of existing) {
|
|
291
|
+
for (const key of identityKeys(registered))
|
|
292
|
+
existingKeys.set(key, registered.name);
|
|
293
|
+
}
|
|
294
|
+
for (const key of identityKeys(agent)) {
|
|
295
|
+
const previous = existingKeys.get(key);
|
|
296
|
+
if (previous !== undefined)
|
|
297
|
+
throw new Error(`Runtime agent '${agent.name}' collides with runtime agent '${previous}' on name or alias '${key}'.`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function assertNoBuiltinCollision(agent) {
|
|
301
|
+
for (const key of identityKeys(agent)) {
|
|
302
|
+
if (BUILTIN_AGENT_NAMES.includes(key))
|
|
303
|
+
throw new Error(`Runtime agent '${agent.name}' collides with builtin agent '${key}'.`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function toAgentConfig(name, definition) {
|
|
307
|
+
const aliases = normalizeAliases(definition.aliases, name);
|
|
308
|
+
const agent = {
|
|
309
|
+
name,
|
|
310
|
+
description: definition.description,
|
|
311
|
+
...aliases ? { aliases } : {},
|
|
312
|
+
...definition.runner !== undefined ? { runner: definition.runner } : {},
|
|
313
|
+
...definition.tools !== undefined ? { tools: [...definition.tools] } : {},
|
|
314
|
+
...definition.allowNestedSubagents !== undefined ? { allowNestedSubagents: definition.allowNestedSubagents } : {},
|
|
315
|
+
...definition.mcpDirectTools !== undefined ? { mcpDirectTools: [...definition.mcpDirectTools] } : {},
|
|
316
|
+
...definition.model !== undefined ? { model: definition.model } : {},
|
|
317
|
+
...definition.fallbackModels !== undefined ? { fallbackModels: [...definition.fallbackModels] } : {},
|
|
318
|
+
...definition.thinking !== undefined ? { thinking: definition.thinking } : {},
|
|
319
|
+
systemPromptMode: definition.systemPromptMode ?? defaultSystemPromptMode(name),
|
|
320
|
+
inheritProjectContext: definition.inheritProjectContext ?? defaultInheritProjectContext(name),
|
|
321
|
+
inheritGlobalContext: definition.inheritGlobalContext ?? false,
|
|
322
|
+
inheritSkills: definition.inheritSkills ?? defaultInheritSkills(),
|
|
323
|
+
...definition.defaultContext !== undefined ? { defaultContext: definition.defaultContext } : {},
|
|
324
|
+
...definition.defaultAsync !== undefined ? { defaultAsync: definition.defaultAsync } : {},
|
|
325
|
+
...definition.defaultTimeoutMs !== undefined ? { defaultTimeoutMs: definition.defaultTimeoutMs } : {},
|
|
326
|
+
...definition.defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs: definition.defaultToolTimeoutMs } : {},
|
|
327
|
+
...definition.defaultAcceptance !== undefined ? { defaultAcceptance: definition.defaultAcceptance } : {},
|
|
328
|
+
...definition.acceptanceRole !== undefined ? { acceptanceRole: definition.acceptanceRole } : {},
|
|
329
|
+
systemPrompt: definition.systemPrompt,
|
|
330
|
+
source: "runtime",
|
|
331
|
+
filePath: `runtime:${name}`,
|
|
332
|
+
...definition.skills !== undefined ? { skills: [...definition.skills] } : {},
|
|
333
|
+
...definition.skillPath !== undefined ? { skillPath: [...definition.skillPath] } : {},
|
|
334
|
+
...definition.extensions !== undefined ? { extensions: [...definition.extensions] } : {},
|
|
335
|
+
...definition.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...definition.subagentOnlyExtensions] } : {},
|
|
336
|
+
...definition.mutationTools !== undefined ? { mutationTools: [...definition.mutationTools] } : {},
|
|
337
|
+
...definition.output !== undefined ? { output: definition.output } : {},
|
|
338
|
+
...definition.outputMode !== undefined ? { outputMode: definition.outputMode } : {},
|
|
339
|
+
...definition.defaultReads !== undefined ? { defaultReads: [...definition.defaultReads] } : {},
|
|
340
|
+
...definition.defaultProgress !== undefined ? { defaultProgress: definition.defaultProgress } : {},
|
|
341
|
+
...definition.interactive !== undefined ? { interactive: definition.interactive } : {},
|
|
342
|
+
...definition.maxSubagentDepth !== undefined ? { maxSubagentDepth: definition.maxSubagentDepth } : {},
|
|
343
|
+
...definition.completionGuard !== undefined ? { completionGuard: definition.completionGuard } : {},
|
|
344
|
+
...definition.toolBudget !== undefined ? { toolBudget: definition.toolBudget } : {},
|
|
345
|
+
...definition.permissions !== undefined ? { permissions: definition.permissions } : {}
|
|
346
|
+
};
|
|
347
|
+
assertNoIdentityCollisions([agent], `Runtime agent '${name}'`);
|
|
348
|
+
return agent;
|
|
349
|
+
}
|
|
350
|
+
export function registerRuntimeAgent(input) {
|
|
351
|
+
const dm = validatePi(input.dm);
|
|
352
|
+
const name = validateString(input.name, "Runtime agent name", MAX_AGENT_NAME_LENGTH);
|
|
353
|
+
const definition = validateDefinition(input.definition);
|
|
354
|
+
const agent = toAgentConfig(name, definition);
|
|
355
|
+
const profileError = validateCodeOwnedProfileRunner(agent);
|
|
356
|
+
if (profileError)
|
|
357
|
+
throw new Error(profileError);
|
|
358
|
+
assertNoBuiltinCollision(agent);
|
|
359
|
+
const current = registry();
|
|
360
|
+
const records = current.byPi.get(dm) ?? [];
|
|
361
|
+
if (records.length >= MAX_RUNTIME_AGENTS_PER_PI)
|
|
362
|
+
throw new Error(`Runtime agent registry supports at most ${MAX_RUNTIME_AGENTS_PER_PI} agents per DM runtime.`);
|
|
363
|
+
assertNoRuntimeCollision(agent, records.map((record) => record.agent));
|
|
364
|
+
const record = { dm, agent };
|
|
365
|
+
records.push(record);
|
|
366
|
+
current.byPi.set(dm, records);
|
|
367
|
+
let disposed = false;
|
|
368
|
+
return {
|
|
369
|
+
dispose() {
|
|
370
|
+
if (disposed)
|
|
371
|
+
return;
|
|
372
|
+
disposed = true;
|
|
373
|
+
const latest = current.byPi.get(dm);
|
|
374
|
+
if (!latest)
|
|
375
|
+
return;
|
|
376
|
+
const next = latest.filter((entry) => entry !== record);
|
|
377
|
+
if (next.length > 0)
|
|
378
|
+
current.byPi.set(dm, next);
|
|
379
|
+
else
|
|
380
|
+
current.byPi.delete(dm);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
export function clearRuntimeAgentsForPi(dm) {
|
|
385
|
+
registry().byPi.delete(dm);
|
|
386
|
+
}
|
|
387
|
+
export function listRuntimeAgentConfigs(dm) {
|
|
388
|
+
return (registry().byPi.get(dm) ?? []).map((record) => ({ ...record.agent, aliases: record.agent.aliases ? [...record.agent.aliases] : undefined }));
|
|
389
|
+
}
|
|
390
|
+
function assertNoConfiguredCollision(configuredAgents, runtimeAgents) {
|
|
391
|
+
const configured = new Map;
|
|
392
|
+
for (const agent of configuredAgents) {
|
|
393
|
+
for (const key of identityKeys(agent))
|
|
394
|
+
configured.set(key, agent.name);
|
|
395
|
+
}
|
|
396
|
+
for (const agent of runtimeAgents) {
|
|
397
|
+
for (const key of identityKeys(agent)) {
|
|
398
|
+
const previous = configured.get(key);
|
|
399
|
+
if (previous !== undefined) {
|
|
400
|
+
throw new Error(`Runtime agent '${agent.name}' collides with configured agent '${previous}' on name or alias '${key}'.`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
export function mergeRuntimeAgents(dm, discovered, configuredAgents = discovered.agents) {
|
|
406
|
+
const runtimeAgents = listRuntimeAgentConfigs(dm).filter((agent) => agent.disabled !== true);
|
|
407
|
+
if (runtimeAgents.length === 0)
|
|
408
|
+
return discovered;
|
|
409
|
+
assertNoIdentityCollisions(runtimeAgents, "Runtime agent registration");
|
|
410
|
+
assertNoConfiguredCollision(configuredAgents, runtimeAgents);
|
|
411
|
+
return { ...discovered, agents: [...discovered.agents, ...runtimeAgents] };
|
|
412
|
+
}
|
|
@@ -2,6 +2,7 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
5
6
|
import { getAgentDir, getProjectConfigDir } from "../shared/utils.js";
|
|
6
7
|
const skillCache = new Map;
|
|
7
8
|
const MAX_CACHE_SIZE = 50;
|
|
@@ -59,20 +60,32 @@ function extractSkillPathsFromPackageRoot(packageRoot, source, bestEffort = fals
|
|
|
59
60
|
const pkg = bestEffort ? readJsonFileBestEffort(packageJsonPath) : readOptionalJsonFile(packageJsonPath, "package manifest");
|
|
60
61
|
if (!pkg || typeof pkg !== "object" || Array.isArray(pkg))
|
|
61
62
|
return [];
|
|
62
|
-
const
|
|
63
|
-
if (!
|
|
63
|
+
const dm = pkg.dm;
|
|
64
|
+
if (!dm || typeof dm !== "object" || Array.isArray(dm))
|
|
64
65
|
return [];
|
|
65
|
-
const skills =
|
|
66
|
+
const skills = dm.skills;
|
|
66
67
|
if (!Array.isArray(skills))
|
|
67
68
|
return [];
|
|
68
69
|
return skills.filter((entry) => typeof entry === "string").map((entry) => ({ path: path.resolve(packageRoot, entry), source }));
|
|
69
70
|
}
|
|
70
71
|
let cachedGlobalNpmRoot = null;
|
|
71
72
|
function getGlobalNpmRoot() {
|
|
73
|
+
const offline = process.env.PI_OFFLINE?.toLowerCase();
|
|
74
|
+
if (offline === "1" || offline === "true" || offline === "yes")
|
|
75
|
+
return null;
|
|
72
76
|
if (cachedGlobalNpmRoot !== null)
|
|
73
77
|
return cachedGlobalNpmRoot;
|
|
78
|
+
const windowsGlobalRoot = process.platform === "win32" && process.env.APPDATA ? path.join(process.env.APPDATA, "npm", "node_modules") : undefined;
|
|
79
|
+
if (windowsGlobalRoot) {
|
|
80
|
+
try {
|
|
81
|
+
if (fs.statSync(windowsGlobalRoot).isDirectory()) {
|
|
82
|
+
cachedGlobalNpmRoot = fs.realpathSync(windowsGlobalRoot);
|
|
83
|
+
return cachedGlobalNpmRoot;
|
|
84
|
+
}
|
|
85
|
+
} catch {}
|
|
86
|
+
}
|
|
74
87
|
try {
|
|
75
|
-
cachedGlobalNpmRoot = execSync("npm root -g", { encoding: "utf-8", timeout: 5000 }).trim();
|
|
88
|
+
cachedGlobalNpmRoot = fs.realpathSync(execSync("npm root -g", { encoding: "utf-8", timeout: 5000, windowsHide: true }).trim());
|
|
76
89
|
return cachedGlobalNpmRoot;
|
|
77
90
|
} catch {
|
|
78
91
|
cachedGlobalNpmRoot = "";
|
|
@@ -315,22 +328,12 @@ function chooseHigherPrioritySkill(existing, candidate) {
|
|
|
315
328
|
return existing;
|
|
316
329
|
return candidate.order < existing.order ? candidate : existing;
|
|
317
330
|
}
|
|
331
|
+
function parseSkillDescription(content) {
|
|
332
|
+
return parseFrontmatter(content).frontmatter.description;
|
|
333
|
+
}
|
|
318
334
|
function maybeReadSkillDescription(filePath) {
|
|
319
335
|
try {
|
|
320
|
-
|
|
321
|
-
const normalized = content.replace(/\r\n/g, `
|
|
322
|
-
`);
|
|
323
|
-
if (!normalized.startsWith("---"))
|
|
324
|
-
return;
|
|
325
|
-
const endIndex = normalized.indexOf(`
|
|
326
|
-
---`, 3);
|
|
327
|
-
if (endIndex === -1)
|
|
328
|
-
return;
|
|
329
|
-
const frontmatter = normalized.slice(3, endIndex).trim();
|
|
330
|
-
const match = frontmatter.match(/^description:\s*(.+)$/m);
|
|
331
|
-
if (!match)
|
|
332
|
-
return;
|
|
333
|
-
return match[1]?.trim().replace(/^['\"]|['\"]$/g, "");
|
|
336
|
+
return parseSkillDescription(fs.readFileSync(filePath, "utf-8"));
|
|
334
337
|
} catch {
|
|
335
338
|
return;
|
|
336
339
|
}
|
|
@@ -345,15 +348,17 @@ function collectFilesystemSkills(cwd, agentDir, skillPaths) {
|
|
|
345
348
|
if (!fs.existsSync(resolvedFile))
|
|
346
349
|
return;
|
|
347
350
|
const source = inferSkillSource(resolvedFile, cwd, agentDir, sourceHint);
|
|
351
|
+
const description = maybeReadSkillDescription(resolvedFile);
|
|
348
352
|
const existingIndex = seen.get(resolvedFile);
|
|
349
353
|
if (existingIndex !== undefined) {
|
|
350
354
|
const existing = entries[existingIndex];
|
|
351
355
|
if (existing && (SOURCE_PRIORITY[source] ?? 0) > (SOURCE_PRIORITY[existing.source] ?? 0)) {
|
|
356
|
+
const { description: _description, ...existingWithoutDescription } = existing;
|
|
352
357
|
entries[existingIndex] = {
|
|
353
|
-
...
|
|
358
|
+
...existingWithoutDescription,
|
|
354
359
|
name,
|
|
355
360
|
source,
|
|
356
|
-
description:
|
|
361
|
+
...description !== undefined ? { description } : {}
|
|
357
362
|
};
|
|
358
363
|
}
|
|
359
364
|
return;
|
|
@@ -363,7 +368,7 @@ function collectFilesystemSkills(cwd, agentDir, skillPaths) {
|
|
|
363
368
|
name,
|
|
364
369
|
filePath: resolvedFile,
|
|
365
370
|
source,
|
|
366
|
-
description:
|
|
371
|
+
...description !== undefined ? { description } : {},
|
|
367
372
|
order: order++
|
|
368
373
|
});
|
|
369
374
|
};
|
|
@@ -501,12 +506,12 @@ function readSkill(skillName, skillPath, source) {
|
|
|
501
506
|
}
|
|
502
507
|
const raw = fs.readFileSync(skillPath, "utf-8");
|
|
503
508
|
const content = stripSkillFrontmatter(raw);
|
|
504
|
-
const description =
|
|
509
|
+
const description = parseSkillDescription(raw);
|
|
505
510
|
const skill = {
|
|
506
511
|
name: skillName,
|
|
507
512
|
path: skillPath,
|
|
508
513
|
content,
|
|
509
|
-
description,
|
|
514
|
+
...description !== undefined ? { description } : {},
|
|
510
515
|
source
|
|
511
516
|
};
|
|
512
517
|
skillCache.set(skillPath, { mtime: stat.mtimeMs, skill });
|
|
@@ -520,9 +525,21 @@ function readSkill(skillName, skillPath, source) {
|
|
|
520
525
|
return;
|
|
521
526
|
}
|
|
522
527
|
}
|
|
523
|
-
export function resolveSkills(skillNames, cwd) {
|
|
528
|
+
export function resolveSkills(skillNames, cwd, localSkillPaths, localBaseDir) {
|
|
524
529
|
const resolved = [];
|
|
525
530
|
const missing = [];
|
|
531
|
+
const localByName = new Map;
|
|
532
|
+
if (localSkillPaths?.length) {
|
|
533
|
+
const agentDir = getAgentDir();
|
|
534
|
+
const localEntries = collectFilesystemSkills(cwd, agentDir, localSkillPaths.map((entry) => ({
|
|
535
|
+
path: path.resolve(localBaseDir ?? cwd, entry),
|
|
536
|
+
source: "unknown"
|
|
537
|
+
})));
|
|
538
|
+
for (const entry of localEntries) {
|
|
539
|
+
if (!localByName.has(entry.name))
|
|
540
|
+
localByName.set(entry.name, entry);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
526
543
|
for (const name of skillNames) {
|
|
527
544
|
const trimmed = name.trim();
|
|
528
545
|
if (!trimmed)
|
|
@@ -531,22 +548,22 @@ export function resolveSkills(skillNames, cwd) {
|
|
|
531
548
|
missing.push(trimmed);
|
|
532
549
|
continue;
|
|
533
550
|
}
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
551
|
+
const local = localByName.get(trimmed);
|
|
552
|
+
let skill = local ? readSkill(trimmed, local.filePath, local.source) : undefined;
|
|
553
|
+
if (!skill) {
|
|
554
|
+
const location = resolveSkillPath(trimmed, cwd);
|
|
555
|
+
if (location)
|
|
556
|
+
skill = readSkill(trimmed, location.path, location.source);
|
|
538
557
|
}
|
|
539
|
-
|
|
540
|
-
if (skill) {
|
|
558
|
+
if (skill)
|
|
541
559
|
resolved.push(skill);
|
|
542
|
-
|
|
560
|
+
else
|
|
543
561
|
missing.push(trimmed);
|
|
544
|
-
}
|
|
545
562
|
}
|
|
546
563
|
return { resolved, missing };
|
|
547
564
|
}
|
|
548
|
-
export function resolveSkillsWithFallback(skillNames, primaryCwd, fallbackCwd) {
|
|
549
|
-
const primary = resolveSkills(skillNames, primaryCwd);
|
|
565
|
+
export function resolveSkillsWithFallback(skillNames, primaryCwd, fallbackCwd, localSkillPaths, localBaseDir) {
|
|
566
|
+
const primary = resolveSkills(skillNames, primaryCwd, localSkillPaths, localBaseDir);
|
|
550
567
|
if (!fallbackCwd || primary.missing.length === 0)
|
|
551
568
|
return primary;
|
|
552
569
|
if (path.resolve(primaryCwd) === path.resolve(fallbackCwd))
|
|
@@ -605,7 +622,7 @@ export function discoverAvailableSkills(cwd) {
|
|
|
605
622
|
return skills.filter((s) => s.name !== SUBAGENT_ORCHESTRATION_SKILL).map((s) => ({
|
|
606
623
|
name: s.name,
|
|
607
624
|
source: s.source,
|
|
608
|
-
description: s.description
|
|
625
|
+
...s.description !== undefined ? { description: s.description } : {}
|
|
609
626
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
610
627
|
}
|
|
611
628
|
export function clearSkillCache() {
|