@bastani/atomic 0.8.13-0 → 0.8.14-0
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 +24 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/host-html-template.ts +1 -1
- package/dist/builtin/mcp/init.ts +15 -2
- package/dist/builtin/mcp/mcp-callback-server.ts +10 -9
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/ui-session.ts +9 -6
- package/dist/builtin/subagents/CHANGELOG.md +8 -1
- package/dist/builtin/subagents/README.md +39 -32
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
- package/dist/builtin/subagents/src/agents/agent-management.ts +6 -1
- package/dist/builtin/subagents/src/agents/agent-serializer.ts +2 -0
- package/dist/builtin/subagents/src/agents/agents.ts +44 -19
- package/dist/builtin/subagents/src/extension/config.ts +16 -0
- package/dist/builtin/subagents/src/extension/fanout-child.ts +246 -0
- package/dist/builtin/subagents/src/extension/index.ts +466 -603
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +6 -4
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +109 -1
- package/dist/builtin/subagents/src/runs/background/async-execution.ts +124 -19
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +41 -6
- package/dist/builtin/subagents/src/runs/background/async-resume.ts +28 -15
- package/dist/builtin/subagents/src/runs/background/async-status.ts +60 -30
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +111 -54
- package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +83 -0
- package/dist/builtin/subagents/src/runs/background/run-status.ts +79 -3
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +46 -1
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +66 -14
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +10 -3
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +14 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +320 -23
- package/dist/builtin/subagents/src/runs/shared/completion-guard.ts +23 -1
- package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +369 -0
- package/dist/builtin/subagents/src/runs/shared/nested-events.ts +935 -0
- package/dist/builtin/subagents/src/runs/shared/nested-path.ts +52 -0
- package/dist/builtin/subagents/src/runs/shared/nested-render.ts +115 -0
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +1 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +82 -9
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/single-output.ts +12 -2
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +32 -10
- package/dist/builtin/subagents/src/runs/shared/worktree.ts +3 -2
- package/dist/builtin/subagents/src/shared/artifacts.ts +0 -1
- package/dist/builtin/subagents/src/shared/types.ts +96 -1
- package/dist/builtin/subagents/src/shared/utils.ts +10 -2
- package/dist/builtin/subagents/src/slash/slash-commands.ts +468 -625
- package/dist/builtin/subagents/src/tui/render.ts +1227 -2093
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +24 -0
- package/dist/builtin/workflows/README.md +28 -11
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +323 -40
- package/dist/builtin/workflows/builtin/ralph.ts +362 -176
- package/dist/builtin/workflows/package.json +2 -5
- package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
- package/dist/builtin/workflows/skills/skill-creator/LICENSE.txt +202 -0
- package/dist/builtin/workflows/skills/skill-creator/SKILL.md +489 -0
- package/dist/builtin/workflows/skills/skill-creator/agents/analyzer.md +274 -0
- package/dist/builtin/workflows/skills/skill-creator/agents/comparator.md +202 -0
- package/dist/builtin/workflows/skills/skill-creator/agents/grader.md +223 -0
- package/dist/builtin/workflows/skills/skill-creator/assets/eval_review.html +146 -0
- package/dist/builtin/workflows/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/dist/builtin/workflows/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/dist/builtin/workflows/skills/skill-creator/references/schemas.md +430 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/__init__.py +0 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/generate_report.py +326 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/improve_description.py +247 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/package_skill.py +136 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/run_eval.py +310 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/run_loop.py +328 -0
- package/dist/builtin/workflows/skills/skill-creator/scripts/utils.py +47 -0
- package/dist/builtin/workflows/src/extension/index.ts +869 -93
- package/dist/builtin/workflows/src/extension/render-call.ts +34 -1
- package/dist/builtin/workflows/src/extension/render-result.ts +126 -21
- package/dist/builtin/workflows/src/extension/runtime.ts +91 -3
- package/dist/builtin/workflows/src/extension/wiring.ts +38 -12
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +62 -5
- package/dist/builtin/workflows/src/runs/background/runner.ts +3 -3
- package/dist/builtin/workflows/src/runs/background/status.ts +42 -8
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +410 -95
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +5 -2
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +8 -0
- package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +6 -4
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +3 -2
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +138 -5
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +30 -0
- package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +78 -120
- package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +193 -0
- package/dist/builtin/workflows/src/shared/store-types.ts +26 -1
- package/dist/builtin/workflows/src/shared/store.ts +145 -17
- package/dist/builtin/workflows/src/shared/timing.ts +6 -2
- package/dist/builtin/workflows/src/shared/workflow-failures.ts +375 -0
- package/dist/builtin/workflows/src/tui/chat-surface.ts +68 -17
- package/dist/builtin/workflows/src/tui/connectors.ts +2 -2
- package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +24 -26
- package/dist/builtin/workflows/src/tui/graph-canvas.ts +4 -8
- package/dist/builtin/workflows/src/tui/graph-view.ts +17 -14
- package/dist/builtin/workflows/src/tui/header.ts +38 -0
- package/dist/builtin/workflows/src/tui/inline-form-card.ts +161 -238
- package/dist/builtin/workflows/src/tui/inline-form-editor.ts +68 -73
- package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +2 -3
- package/dist/builtin/workflows/src/tui/inline-form-store.ts +2 -1
- package/dist/builtin/workflows/src/tui/inputs-overlay.ts +1 -3
- package/dist/builtin/workflows/src/tui/inputs-picker.ts +286 -399
- package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +11 -0
- package/dist/builtin/workflows/src/tui/node-card.ts +2 -1
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -1
- package/dist/builtin/workflows/src/tui/prompt-card.ts +46 -19
- package/dist/builtin/workflows/src/tui/run-detail.ts +63 -80
- package/dist/builtin/workflows/src/tui/session-confirm.ts +9 -3
- package/dist/builtin/workflows/src/tui/session-picker.ts +19 -16
- package/dist/builtin/workflows/src/tui/stage-chat-layout.ts +88 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +368 -879
- package/dist/builtin/workflows/src/tui/status-helpers.ts +4 -0
- package/dist/builtin/workflows/src/tui/status-list.ts +67 -75
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +50 -12
- package/dist/builtin/workflows/src/tui/submit-pane.ts +164 -0
- package/dist/builtin/workflows/src/tui/switcher.ts +27 -4
- package/dist/builtin/workflows/src/tui/text-helpers.ts +98 -4
- package/dist/builtin/workflows/src/tui/widget.ts +90 -68
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +23 -2
- package/dist/builtin/workflows/src/tui/workflow-list.ts +44 -68
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -3
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -10
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +2 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +6 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +16 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +8 -9
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +8 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.js +6 -3
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +12 -29
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +5 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-manager.d.ts +8 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +145 -58
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +6 -20
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +38 -31
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +9 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +32 -24
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -15
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +8 -22
- package/dist/core/skills.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +5 -4
- package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/state/questionnaire-session.js +34 -11
- package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts +1 -0
- package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/state/selectors/contract.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/state/selectors/projections.js +1 -0
- package/dist/core/tools/ask-user-question/state/selectors/projections.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/state-reducer.d.ts +1 -2
- package/dist/core/tools/ask-user-question/state/state-reducer.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/state/state-reducer.js +26 -9
- package/dist/core/tools/ask-user-question/state/state-reducer.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/state.d.ts +4 -0
- package/dist/core/tools/ask-user-question/state/state.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/state/state.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts +1 -0
- package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/option-list-view.js +1 -0
- package/dist/core/tools/ask-user-question/view/components/option-list-view.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts +9 -6
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +28 -7
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/props-adapter.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/props-adapter.js +4 -1
- package/dist/core/tools/ask-user-question/view/props-adapter.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +56 -53
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +3 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +8 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +3 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +44 -81
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +27 -12
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +2 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +3 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -5
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +2 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +11 -4
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +2 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +39 -21
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +9 -8
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +12 -2
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +20 -35
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/chat-input-actions.d.ts +24 -0
- package/dist/modes/interactive/chat-input-actions.d.ts.map +1 -0
- package/dist/modes/interactive/chat-input-actions.js +179 -0
- package/dist/modes/interactive/chat-input-actions.js.map +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +14 -3
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts +157 -0
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-session-host.js +1007 -0
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +14 -5
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +9 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +29 -4
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +18 -67
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/child-process.d.ts +1 -0
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +8 -0
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +3 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js +14 -8
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +124 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +7 -27
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +75 -115
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/paths.d.ts +16 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +49 -7
- package/dist/utils/paths.js.map +1 -1
- package/docs/changelog.mdx +29 -0
- package/docs/compaction.md +1 -1
- package/docs/custom-provider.md +2 -2
- package/docs/development.md +1 -1
- package/docs/docs.json +98 -143
- package/docs/extensions.md +29 -16
- package/docs/favicon.svg +29 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/images/workflow-command.png +0 -0
- package/docs/images/workflow-graph.png +0 -0
- package/docs/images/workflow-input-picker.png +0 -0
- package/docs/images/workflow-list.png +0 -0
- package/docs/index.md +10 -1
- package/docs/logo.svg +59 -0
- package/docs/packages.md +3 -3
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +98 -2
- package/docs/rpc.md +8 -8
- package/docs/sdk.md +23 -12
- package/docs/sessions.md +1 -1
- package/docs/skills.md +15 -1
- package/docs/termux.md +11 -1
- package/docs/themes.md +6 -6
- package/docs/tui.md +18 -18
- package/docs/usage.md +1 -1
- package/docs/workflows.md +172 -2
- package/examples/extensions/subagent/index.ts +2 -1
- package/package.json +6 -6
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/SKILL.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/element-attributes.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/playwright-tests.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/request-mocking.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/running-code.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/session-management.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/spec-driven-testing.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/storage-state.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/test-generation.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/tracing.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/video-recording.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/SKILL.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/deep-modules.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/interface-design.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/mocking.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/refactoring.md +0 -0
- /package/dist/builtin/{workflows → subagents}/skills/tdd/tests.md +0 -0
|
@@ -6,7 +6,7 @@ import * as fs from "node:fs";
|
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { CONFIG_DIR_NAME, getAgentConfigPaths, getProjectConfigDirs } from "@bastani/atomic";
|
|
9
|
+
import { CONFIG_DIR_NAME, getAgentConfigPaths, getEnvValue, getProjectConfigDirs } from "@bastani/atomic";
|
|
10
10
|
import type { OutputMode } from "../shared/types.ts";
|
|
11
11
|
import { KNOWN_FIELDS } from "./agent-serializer.ts";
|
|
12
12
|
import { parseChain } from "./chain-serializer.ts";
|
|
@@ -46,6 +46,7 @@ export interface BuiltinAgentOverrideBase {
|
|
|
46
46
|
skills?: string[];
|
|
47
47
|
tools?: string[];
|
|
48
48
|
mcpDirectTools?: string[];
|
|
49
|
+
completionGuard?: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
interface BuiltinAgentOverrideConfig {
|
|
@@ -60,6 +61,7 @@ interface BuiltinAgentOverrideConfig {
|
|
|
60
61
|
systemPrompt?: string;
|
|
61
62
|
skills?: string[] | false;
|
|
62
63
|
tools?: string[] | false;
|
|
64
|
+
completionGuard?: boolean;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
interface BuiltinAgentOverrideInfo {
|
|
@@ -92,6 +94,7 @@ export interface AgentConfig {
|
|
|
92
94
|
defaultProgress?: boolean;
|
|
93
95
|
interactive?: boolean;
|
|
94
96
|
maxSubagentDepth?: number;
|
|
97
|
+
completionGuard?: boolean;
|
|
95
98
|
disabled?: boolean;
|
|
96
99
|
extraFields?: Record<string, string>;
|
|
97
100
|
override?: BuiltinAgentOverrideInfo;
|
|
@@ -191,6 +194,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
|
|
|
191
194
|
skills: agent.skills ? [...agent.skills] : undefined,
|
|
192
195
|
tools: agent.tools ? [...agent.tools] : undefined,
|
|
193
196
|
mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,
|
|
197
|
+
completionGuard: agent.completionGuard,
|
|
194
198
|
};
|
|
195
199
|
}
|
|
196
200
|
|
|
@@ -209,6 +213,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
|
|
|
209
213
|
...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
|
|
210
214
|
...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
|
|
211
215
|
...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),
|
|
216
|
+
...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
|
|
212
217
|
};
|
|
213
218
|
}
|
|
214
219
|
|
|
@@ -354,6 +359,14 @@ function parseBuiltinOverrideEntry(
|
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
|
|
362
|
+
if ("completionGuard" in input) {
|
|
363
|
+
if (typeof input.completionGuard === "boolean") {
|
|
364
|
+
override.completionGuard = input.completionGuard;
|
|
365
|
+
} else {
|
|
366
|
+
throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
357
370
|
if ("systemPrompt" in input) {
|
|
358
371
|
if (typeof input.systemPrompt === "string") override.systemPrompt = input.systemPrompt;
|
|
359
372
|
else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);
|
|
@@ -399,6 +412,22 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
|
|
|
399
412
|
return { overrides: parsed, disableBuiltins };
|
|
400
413
|
}
|
|
401
414
|
|
|
415
|
+
function readMergedSubagentSettings(filePaths: string[]): { settings: SubagentSettings; path: string | null } {
|
|
416
|
+
let settings = EMPTY_SUBAGENT_SETTINGS;
|
|
417
|
+
let path: string | null = null;
|
|
418
|
+
for (let i = filePaths.length - 1; i >= 0; i--) {
|
|
419
|
+
const filePath = filePaths[i]!;
|
|
420
|
+
if (!fs.existsSync(filePath)) continue;
|
|
421
|
+
const next = readSubagentSettings(filePath);
|
|
422
|
+
settings = {
|
|
423
|
+
disableBuiltins: next.disableBuiltins ?? settings.disableBuiltins,
|
|
424
|
+
overrides: { ...settings.overrides, ...next.overrides },
|
|
425
|
+
};
|
|
426
|
+
path = filePath;
|
|
427
|
+
}
|
|
428
|
+
return { settings, path };
|
|
429
|
+
}
|
|
430
|
+
|
|
402
431
|
function applyBuiltinOverride(
|
|
403
432
|
agent: AgentConfig,
|
|
404
433
|
override: BuiltinAgentOverrideConfig,
|
|
@@ -426,26 +455,11 @@ function applyBuiltinOverride(
|
|
|
426
455
|
next.tools = tools;
|
|
427
456
|
next.mcpDirectTools = mcpDirectTools;
|
|
428
457
|
}
|
|
458
|
+
if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
|
|
429
459
|
|
|
430
460
|
return next;
|
|
431
461
|
}
|
|
432
462
|
|
|
433
|
-
function readMergedSubagentSettings(filePaths: string[]): { settings: SubagentSettings; path: string | null } {
|
|
434
|
-
let settings = EMPTY_SUBAGENT_SETTINGS;
|
|
435
|
-
let path: string | null = null;
|
|
436
|
-
for (let i = filePaths.length - 1; i >= 0; i--) {
|
|
437
|
-
const filePath = filePaths[i]!;
|
|
438
|
-
if (!fs.existsSync(filePath)) continue;
|
|
439
|
-
const next = readSubagentSettings(filePath);
|
|
440
|
-
settings = {
|
|
441
|
-
disableBuiltins: next.disableBuiltins ?? settings.disableBuiltins,
|
|
442
|
-
overrides: { ...settings.overrides, ...next.overrides },
|
|
443
|
-
};
|
|
444
|
-
path = filePath;
|
|
445
|
-
}
|
|
446
|
-
return { settings, path };
|
|
447
|
-
}
|
|
448
|
-
|
|
449
463
|
function applyBuiltinOverrides(
|
|
450
464
|
builtinAgents: AgentConfig[],
|
|
451
465
|
userSettings: SubagentSettings,
|
|
@@ -481,7 +495,7 @@ function applyBuiltinOverrides(
|
|
|
481
495
|
|
|
482
496
|
export function buildBuiltinOverrideConfig(
|
|
483
497
|
base: BuiltinAgentOverrideBase,
|
|
484
|
-
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools">,
|
|
498
|
+
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "completionGuard">,
|
|
485
499
|
): BuiltinAgentOverrideConfig | undefined {
|
|
486
500
|
const override: BuiltinAgentOverrideConfig = {};
|
|
487
501
|
|
|
@@ -499,6 +513,9 @@ export function buildBuiltinOverrideConfig(
|
|
|
499
513
|
const baseTools = joinToolList(base);
|
|
500
514
|
const draftTools = joinToolList(draft);
|
|
501
515
|
if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
|
|
516
|
+
if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
|
|
517
|
+
override.completionGuard = draft.completionGuard !== false;
|
|
518
|
+
}
|
|
502
519
|
|
|
503
520
|
return Object.keys(override).length > 0 ? override : undefined;
|
|
504
521
|
}
|
|
@@ -664,6 +681,11 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
664
681
|
}
|
|
665
682
|
|
|
666
683
|
const parsedMaxSubagentDepth = Number(frontmatter.maxSubagentDepth);
|
|
684
|
+
const completionGuard = frontmatter.completionGuard === "false"
|
|
685
|
+
? false
|
|
686
|
+
: frontmatter.completionGuard === "true"
|
|
687
|
+
? true
|
|
688
|
+
: undefined;
|
|
667
689
|
|
|
668
690
|
agents.push({
|
|
669
691
|
name: runtimeName,
|
|
@@ -692,6 +714,7 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
692
714
|
Number.isInteger(parsedMaxSubagentDepth) && parsedMaxSubagentDepth >= 0
|
|
693
715
|
? parsedMaxSubagentDepth
|
|
694
716
|
: undefined,
|
|
717
|
+
completionGuard,
|
|
695
718
|
extraFields: Object.keys(extraFields).length > 0 ? extraFields : undefined,
|
|
696
719
|
});
|
|
697
720
|
}
|
|
@@ -843,7 +866,9 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
843
866
|
...Array.from(chainMap.values()),
|
|
844
867
|
];
|
|
845
868
|
|
|
846
|
-
const
|
|
869
|
+
const legacyUserAgentDir = userDirOld[0]!;
|
|
870
|
+
// ATOMIC_CODING_AGENT_DIR is already applied by getUserAgentDirs(); prefer that resolved path over ~/.agents.
|
|
871
|
+
const userDir = getEnvValue("ATOMIC_CODING_AGENT_DIR") ? legacyUserAgentDir : fs.existsSync(userDirNew) ? userDirNew : legacyUserAgentDir;
|
|
847
872
|
|
|
848
873
|
return { builtin, user, project, chains, userDir, projectDir, userChainDir, projectChainDir, userSettingsPath, projectSettingsPath };
|
|
849
874
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { getAgentConfigPaths } from "@bastani/atomic";
|
|
3
|
+
import type { ExtensionConfig } from "../shared/types.ts";
|
|
4
|
+
|
|
5
|
+
export function loadConfig(): ExtensionConfig {
|
|
6
|
+
for (const configPath of getAgentConfigPaths("extensions", "subagent", "config.json")) {
|
|
7
|
+
try {
|
|
8
|
+
if (fs.existsSync(configPath)) {
|
|
9
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8")) as ExtensionConfig;
|
|
10
|
+
}
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.error(`Failed to load subagent config from '${configPath}':`, error);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { APP_NAME, getEnvValue } from "@bastani/atomic";
|
|
6
|
+
import type { ExtensionAPI, ToolDefinition } from "@bastani/atomic";
|
|
7
|
+
|
|
8
|
+
import { discoverAgents } from "../agents/agents.ts";
|
|
9
|
+
import { resolveSubagentIntercomTarget } from "../intercom/intercom-bridge.ts";
|
|
10
|
+
import { deliverSubagentIntercomMessageEvent } from "../intercom/result-intercom.ts";
|
|
11
|
+
import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
|
|
12
|
+
import { readNestedControlRequests, resolveNestedRouteFromEnv, writeNestedControlResult, type NestedRoute } from "../runs/shared/nested-events.ts";
|
|
13
|
+
import { SUBAGENT_CHILD_ENV, SUBAGENT_FANOUT_CHILD_ENV } from "../runs/shared/pi-args.ts";
|
|
14
|
+
import { getArtifactsDir } from "../shared/artifacts.ts";
|
|
15
|
+
import { type Details, type SubagentState } from "../shared/types.ts";
|
|
16
|
+
import { loadConfig } from "./config.ts";
|
|
17
|
+
import { SubagentParams } from "./schemas.ts";
|
|
18
|
+
|
|
19
|
+
function getSubagentSessionRoot(parentSessionFile: string | null): string {
|
|
20
|
+
if (parentSessionFile) {
|
|
21
|
+
const baseName = path.basename(parentSessionFile, ".jsonl");
|
|
22
|
+
const sessionsDir = path.dirname(parentSessionFile);
|
|
23
|
+
return path.join(sessionsDir, baseName);
|
|
24
|
+
}
|
|
25
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), `${APP_NAME}-subagent-session-`));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function expandTilde(p: string): string {
|
|
29
|
+
return p.startsWith("~/") ? path.join(os.homedir(), p.slice(2)) : p;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createChildSafeState(): SubagentState {
|
|
33
|
+
return {
|
|
34
|
+
baseCwd: "",
|
|
35
|
+
currentSessionId: null,
|
|
36
|
+
asyncJobs: new Map(),
|
|
37
|
+
foregroundRuns: new Map(),
|
|
38
|
+
foregroundControls: new Map(),
|
|
39
|
+
lastForegroundControlId: null,
|
|
40
|
+
pendingForegroundControlNotices: new Map(),
|
|
41
|
+
cleanupTimers: new Map(),
|
|
42
|
+
lastUiContext: null,
|
|
43
|
+
poller: null,
|
|
44
|
+
completionSeen: new Map(),
|
|
45
|
+
watcher: null,
|
|
46
|
+
watcherRestartTimer: null,
|
|
47
|
+
// Child-safe stub: the parent extension owns watcher/coalescer/cleanup state.
|
|
48
|
+
resultFileCoalescer: {
|
|
49
|
+
schedule: () => false,
|
|
50
|
+
clear: () => {},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const MAX_SEEN_REQUEST_IDS = 1024;
|
|
56
|
+
const TRIMMED_SEEN_REQUEST_IDS = 512;
|
|
57
|
+
const MAX_PENDING_RESULTS = 256;
|
|
58
|
+
const MAX_PENDING_RESULT_ATTEMPTS = 10;
|
|
59
|
+
const MAX_PENDING_RESULT_AGE_MS = 60_000;
|
|
60
|
+
const NESTED_CONTROL_INBOX_TIMER_KEY = "fanout-child:nested-control-inbox";
|
|
61
|
+
|
|
62
|
+
type NestedControlResultPayload = Parameters<typeof writeNestedControlResult>[1];
|
|
63
|
+
|
|
64
|
+
interface PendingControlResult {
|
|
65
|
+
result: NestedControlResultPayload;
|
|
66
|
+
firstFailureAt: number;
|
|
67
|
+
attempts: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function rememberSeenRequest(seen: Set<string>, requestId: string): void {
|
|
71
|
+
seen.add(requestId);
|
|
72
|
+
if (seen.size <= MAX_SEEN_REQUEST_IDS) return;
|
|
73
|
+
const keep = [...seen].slice(-TRIMMED_SEEN_REQUEST_IDS);
|
|
74
|
+
seen.clear();
|
|
75
|
+
for (const id of keep) seen.add(id);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function dropControlRequestFile(filePath: string, requestId: string): void {
|
|
79
|
+
try {
|
|
80
|
+
fs.unlinkSync(filePath);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(`Failed to remove processed nested control request '${requestId}' at '${filePath}':`, error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function shouldDropPendingResult(pending: PendingControlResult, pendingSize: number, now: number): boolean {
|
|
87
|
+
return pending.attempts >= MAX_PENDING_RESULT_ATTEMPTS
|
|
88
|
+
|| now - pending.firstFailureAt >= MAX_PENDING_RESULT_AGE_MS
|
|
89
|
+
|| pendingSize > MAX_PENDING_RESULTS;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function buildNestedControlResult(
|
|
93
|
+
pi: ExtensionAPI,
|
|
94
|
+
state: SubagentState,
|
|
95
|
+
request: ReturnType<typeof readNestedControlRequests>[number],
|
|
96
|
+
): Promise<NestedControlResultPayload> {
|
|
97
|
+
return (async () => {
|
|
98
|
+
let ok = false;
|
|
99
|
+
let message = "Control request failed.";
|
|
100
|
+
try {
|
|
101
|
+
const control = state.foregroundControls.get(request.targetRunId);
|
|
102
|
+
if (!control) {
|
|
103
|
+
message = `Nested run ${request.targetRunId} is not active in this fanout child.`;
|
|
104
|
+
} else if (request.action === "interrupt") {
|
|
105
|
+
ok = control.interrupt?.() === true;
|
|
106
|
+
message = ok
|
|
107
|
+
? `Interrupt requested for nested run ${request.targetRunId}.`
|
|
108
|
+
: `Nested run ${request.targetRunId} has no active child step to interrupt.`;
|
|
109
|
+
} else if (!request.message?.trim()) {
|
|
110
|
+
message = "Nested resume requires message.";
|
|
111
|
+
} else if (!control.currentAgent) {
|
|
112
|
+
message = `Nested run ${request.targetRunId} has no active child message route.`;
|
|
113
|
+
} else {
|
|
114
|
+
const index = control.currentIndex ?? 0;
|
|
115
|
+
const target = resolveSubagentIntercomTarget(request.targetRunId, control.currentAgent, index);
|
|
116
|
+
ok = await deliverSubagentIntercomMessageEvent(
|
|
117
|
+
pi.events,
|
|
118
|
+
target,
|
|
119
|
+
`Follow-up for nested run ${request.targetRunId} (${control.currentAgent}):\n\n${request.message.trim()}`,
|
|
120
|
+
500,
|
|
121
|
+
{ source: "nested-resume", runId: request.targetRunId, agent: control.currentAgent, index },
|
|
122
|
+
);
|
|
123
|
+
message = ok
|
|
124
|
+
? `Delivered follow-up to live nested run ${request.targetRunId}.`
|
|
125
|
+
: `Nested child intercom target is not registered: ${target}`;
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
message = error instanceof Error ? error.message : String(error);
|
|
129
|
+
}
|
|
130
|
+
return { ts: Date.now(), requestId: request.requestId, targetRunId: request.targetRunId, ok, message };
|
|
131
|
+
})();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function startNestedControlInboxListener(pi: ExtensionAPI, state: SubagentState): NodeJS.Timeout | undefined {
|
|
135
|
+
let route: NestedRoute | undefined;
|
|
136
|
+
try {
|
|
137
|
+
route = resolveNestedRouteFromEnv();
|
|
138
|
+
} catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
if (!route) return undefined;
|
|
142
|
+
const seen = new Set<string>();
|
|
143
|
+
const inFlight = new Set<string>();
|
|
144
|
+
const pendingResults = new Map<string, PendingControlResult>();
|
|
145
|
+
const timer = setInterval(() => {
|
|
146
|
+
try {
|
|
147
|
+
for (const request of readNestedControlRequests(route)) {
|
|
148
|
+
if (seen.has(request.requestId) || inFlight.has(request.requestId)) continue;
|
|
149
|
+
inFlight.add(request.requestId);
|
|
150
|
+
void (async () => {
|
|
151
|
+
try {
|
|
152
|
+
const pending = pendingResults.get(request.requestId);
|
|
153
|
+
const result = pending?.result ?? await buildNestedControlResult(pi, state, request);
|
|
154
|
+
try {
|
|
155
|
+
writeNestedControlResult(route, result);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
const nextPending: PendingControlResult = {
|
|
159
|
+
result,
|
|
160
|
+
firstFailureAt: pending?.firstFailureAt ?? now,
|
|
161
|
+
attempts: (pending?.attempts ?? 0) + 1,
|
|
162
|
+
};
|
|
163
|
+
pendingResults.set(request.requestId, nextPending);
|
|
164
|
+
if (shouldDropPendingResult(nextPending, pendingResults.size, now)) {
|
|
165
|
+
pendingResults.delete(request.requestId);
|
|
166
|
+
rememberSeenRequest(seen, request.requestId);
|
|
167
|
+
dropControlRequestFile(request.filePath, request.requestId);
|
|
168
|
+
console.error(`Dropping nested control result for request '${request.requestId}' targeting '${request.targetRunId}' after ${nextPending.attempts} failed write attempts via inbox '${route.controlInbox}':`, error);
|
|
169
|
+
} else if (nextPending.attempts === 1) {
|
|
170
|
+
console.error(`Failed to write nested control result for request '${request.requestId}' targeting '${request.targetRunId}' via inbox '${route.controlInbox}'; keeping request for retry:`, error);
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
pendingResults.delete(request.requestId);
|
|
175
|
+
rememberSeenRequest(seen, request.requestId);
|
|
176
|
+
dropControlRequestFile(request.filePath, request.requestId);
|
|
177
|
+
} finally {
|
|
178
|
+
inFlight.delete(request.requestId);
|
|
179
|
+
}
|
|
180
|
+
})();
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(`Failed to poll nested control inbox '${route.controlInbox}' for root '${route.rootRunId}':`, error);
|
|
184
|
+
}
|
|
185
|
+
}, 200);
|
|
186
|
+
timer.unref?.();
|
|
187
|
+
state.cleanupTimers.set(NESTED_CONTROL_INBOX_TIMER_KEY, timer);
|
|
188
|
+
return timer;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI): void {
|
|
192
|
+
if (getEnvValue(SUBAGENT_CHILD_ENV) !== "1" || getEnvValue(SUBAGENT_FANOUT_CHILD_ENV) !== "1") return;
|
|
193
|
+
|
|
194
|
+
const globalStore = globalThis as Record<string, unknown>;
|
|
195
|
+
const registeredKey = "__atomicSubagentFanoutChildRegisteredApis";
|
|
196
|
+
const cleanupKey = "__atomicSubagentFanoutChildRuntimeCleanup";
|
|
197
|
+
const registeredApis = globalStore[registeredKey] instanceof WeakSet
|
|
198
|
+
? globalStore[registeredKey] as WeakSet<ExtensionAPI>
|
|
199
|
+
: new WeakSet<ExtensionAPI>();
|
|
200
|
+
globalStore[registeredKey] = registeredApis;
|
|
201
|
+
if (registeredApis.has(pi)) return;
|
|
202
|
+
const previousRuntimeCleanup = globalStore[cleanupKey];
|
|
203
|
+
if (typeof previousRuntimeCleanup === "function") {
|
|
204
|
+
try {
|
|
205
|
+
previousRuntimeCleanup();
|
|
206
|
+
} catch {
|
|
207
|
+
// Best effort cleanup for stale fanout-child timers from an older reload.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
registeredApis.add(pi);
|
|
211
|
+
|
|
212
|
+
const config = loadConfig();
|
|
213
|
+
const state = createChildSafeState();
|
|
214
|
+
const executor = createSubagentExecutor({
|
|
215
|
+
pi,
|
|
216
|
+
state,
|
|
217
|
+
config,
|
|
218
|
+
asyncByDefault: config.asyncByDefault === true,
|
|
219
|
+
tempArtifactsDir: getArtifactsDir(null),
|
|
220
|
+
getSubagentSessionRoot,
|
|
221
|
+
expandTilde,
|
|
222
|
+
discoverAgents,
|
|
223
|
+
allowMutatingManagementActions: false,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const tool: ToolDefinition<typeof SubagentParams, Details> = {
|
|
227
|
+
name: "subagent",
|
|
228
|
+
label: "Subagent",
|
|
229
|
+
description: [
|
|
230
|
+
"Delegate to subagents from child-safe fanout mode.",
|
|
231
|
+
"Allowed management/control actions: list, get, status, interrupt, resume, doctor.",
|
|
232
|
+
"Agent config mutation actions create, update, and delete are blocked in this mode.",
|
|
233
|
+
].join("\n"),
|
|
234
|
+
parameters: SubagentParams,
|
|
235
|
+
execute(id, params, signal, onUpdate, ctx) {
|
|
236
|
+
return executor.execute(id, params as SubagentParamsLike, signal, onUpdate, ctx);
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
pi.registerTool(tool);
|
|
241
|
+
startNestedControlInboxListener(pi, state);
|
|
242
|
+
globalStore[cleanupKey] = () => {
|
|
243
|
+
for (const timer of state.cleanupTimers.values()) clearInterval(timer);
|
|
244
|
+
state.cleanupTimers.clear();
|
|
245
|
+
};
|
|
246
|
+
}
|