one-code-extension 0.4.1 → 0.6.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/README.md +16 -5
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +40 -28
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +26 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +58 -31
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +124 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +642 -0
- package/extensions/background/index.ts +614 -248
- package/extensions/background/loop-fire.ts +173 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +56 -0
- package/extensions/background/wakeup.ts +178 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +66 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +250 -78
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/cache-marks/index.ts +42 -0
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +436 -63
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +219 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/budget.ts +16 -2
- package/extensions/context-budget/index.ts +35 -15
- package/extensions/context-management/index.ts +36 -28
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +141 -25
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +420 -42
- package/extensions/file-tracker/replay.ts +137 -24
- package/extensions/file-tracker/restore.ts +66 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +45 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +209 -58
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/prompt-context.ts +59 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +26 -12
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/ledger/index.ts +46 -0
- package/extensions/ledger/wire.ts +154 -0
- package/extensions/lib/agent-cron.ts +146 -0
- package/extensions/lib/agent-loader.ts +18 -3
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-auth.ts +98 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +52 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +97 -0
- package/extensions/lib/covered-messages.ts +23 -0
- package/extensions/lib/deferred.ts +359 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/ledger/fold-memo.ts +49 -0
- package/extensions/lib/ledger/fold.ts +265 -0
- package/extensions/lib/ledger/layout.ts +72 -0
- package/extensions/lib/ledger/plan.ts +102 -0
- package/extensions/lib/ledger/records.ts +276 -0
- package/extensions/lib/ledger/state.ts +47 -0
- package/extensions/lib/ledger/validate.ts +141 -0
- package/extensions/lib/ledger/wire.ts +632 -0
- package/extensions/lib/local-command.ts +71 -19
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +178 -0
- package/extensions/lib/model-catalog/models-dev.json +18533 -0
- package/extensions/lib/model-catalog/openrouter.json +5050 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +357 -73
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +38 -2
- package/extensions/lib/plan-mode-channels.ts +42 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/previous-mark.ts +101 -0
- package/extensions/lib/process-state.ts +48 -0
- package/extensions/lib/process-tree.ts +132 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +370 -358
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +547 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +24 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +112 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +129 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +159 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +76 -12
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +90 -43
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +220 -121
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +164 -73
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/model-default/index.ts +86 -19
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1426 -398
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +11 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +276 -92
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/run-state.ts +26 -0
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +64 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +14 -7
- package/extensions/recap/index.ts +73 -71
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/announce.ts +30 -0
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +469 -132
- package/extensions/skill/invoke.ts +118 -75
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +146 -31
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +82 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1594 -852
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +5 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/parent-mode.ts +50 -0
- package/extensions/subagents/pending-claim.ts +18 -1
- package/extensions/subagents/runner.ts +135 -80
- package/extensions/subagents/runs.ts +44 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +165 -47
- package/extensions/system-prompt/template.ts +34 -51
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +204 -70
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/index.ts +366 -144
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +108 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +157 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +33 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +162 -44
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +21 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
- package/extensions/tool-search/announce.ts +0 -42
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
* `extensionFactories`, which DefaultResourceLoader always loads.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { childWriteWatcher } from "../lib/child-writes.ts";
|
|
18
|
+
import { randomBytes } from "node:crypto";
|
|
17
19
|
import os from "node:os";
|
|
18
20
|
import { getAgentDir, type ModelRuntime, SessionManager, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
19
21
|
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
20
22
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
21
23
|
import { Type } from "typebox";
|
|
22
24
|
import { whenAborted } from "../lib/abort.ts";
|
|
23
|
-
import {
|
|
25
|
+
import { persistIfLarge, sessionResultsDir } from "../lib/persisted-output.ts";
|
|
26
|
+
import { createSharedModelRuntime, disposeChildSession, finalAssistantText, openChildSession } from "../lib/agent-loader.ts";
|
|
24
27
|
import { modelSpec as modelSpecOf, supportsImageInput } from "../lib/model-policy.ts";
|
|
25
28
|
import { isModelUnavailableError } from "../auto-mode/model-select.ts";
|
|
26
29
|
import { agentPromptIdentity, PrefixWarmGate, prefixWarmKey } from "../lib/prefix-warm-gate.ts";
|
|
@@ -28,13 +31,17 @@ import type { PermissionBridge } from "../permissions/subagent-gate.ts";
|
|
|
28
31
|
import { localGateMode, MODE_ENV } from "../lib/permission-gate.ts";
|
|
29
32
|
import type { HookBridge } from "../hooks/subagent-bridge.ts";
|
|
30
33
|
import { summarizeArgs } from "../lib/tui-render.ts";
|
|
31
|
-
import {
|
|
34
|
+
import { type AgentDefinition, agentFileSources, agentToolOptions, discoverAgents, unusableAllowlistError } from "../subagents/agents.ts";
|
|
35
|
+
import { defaultDiscoverRoots, discoverPlugins } from "../lib/plugins.ts";
|
|
36
|
+
import { CHILD_EXTENSION_PATHS } from "../lib/child-extensions.ts";
|
|
37
|
+
import { oneTurnHandbackSlot, subagentHandbackExtension } from "../lib/subagent-handback.ts";
|
|
32
38
|
import type { SubagentDefault } from "../subagents/default-model.ts";
|
|
33
39
|
import { expensiveModelGate, resolveSubagentModel, subagentModelMenu } from "../subagents/model-select.ts";
|
|
34
40
|
import { withoutUnusable } from "../lib/model-unusable.ts";
|
|
35
41
|
import { cleanupWorktree, createWorktree, isGitRepo, type Worktree } from "../subagents/worktree.ts";
|
|
36
|
-
import type { AgentCallOptions, AgentCallResult, AgentEffort, AgentRunUpdate } from "./types.ts";
|
|
42
|
+
import type { AgentCallOptions, AgentCallResult, AgentEffort, AgentRunUpdate, KeptWorktree } from "./types.ts";
|
|
37
43
|
import { WorkflowScriptError } from "./types.ts";
|
|
44
|
+
import { type DeferRequest, deferLikeParentExtension, injectedByParent } from "../lib/deferred.ts";
|
|
38
45
|
|
|
39
46
|
const MAX_SCHEMA_RETRIES = 2;
|
|
40
47
|
const OUTPUT_CAP = 50_000;
|
|
@@ -52,6 +59,8 @@ export interface AgentRunnerOptions {
|
|
|
52
59
|
unusableModels?: () => ReadonlySet<string>;
|
|
53
60
|
/** An agent's provider refused its model as not usable on this account (`isModelUnavailableError`): report it so every picker skips it. */
|
|
54
61
|
onModelUnusable?: (model: string, reason: string) => void;
|
|
62
|
+
/** An agent's edit or write changed a file (lib/child-writes.ts), for the parent's file-tracker. */
|
|
63
|
+
onChildWrite?: (path: string, agent: string | undefined) => void;
|
|
55
64
|
/**
|
|
56
65
|
* The parent permissions extension's decision closure (same bridge the
|
|
57
66
|
* subagent runner uses): when present, a workflow agent's tool calls route
|
|
@@ -65,6 +74,15 @@ export interface AgentRunnerOptions {
|
|
|
65
74
|
getHookBridge?: () => HookBridge | undefined;
|
|
66
75
|
/** Each finished agent's dollar cost (review S13: workflow agents never reached the footer). */
|
|
67
76
|
onUsage?: (cost: number) => void;
|
|
77
|
+
/**
|
|
78
|
+
* The parent's live MCP tools (lib/mcp-share.ts `watchMcpTools`), injected
|
|
79
|
+
* as custom tools over the parent's connections, as the subagent runner does.
|
|
80
|
+
*/
|
|
81
|
+
getMcpTools?: () => ToolDefinition[] | Promise<ToolDefinition[]>;
|
|
82
|
+
/** The tools the parent defers (lib/deferred.ts DEFERRED_QUERY_CHANNEL): the agent defers them too, so its MCP tools are listed, not declared. */
|
|
83
|
+
getParentDeferred?: () => DeferRequest[];
|
|
84
|
+
/** Where an answer past OUTPUT_CAP is saved (`<dir>/tool-results/`): the run's directory. */
|
|
85
|
+
resultsDir?: string;
|
|
68
86
|
}
|
|
69
87
|
|
|
70
88
|
/**
|
|
@@ -199,7 +217,9 @@ export class AgentRunner {
|
|
|
199
217
|
static async create(options: AgentRunnerOptions): Promise<AgentRunner> {
|
|
200
218
|
const agentDir = getAgentDir();
|
|
201
219
|
const modelRuntime = await createSharedModelRuntime(agentDir);
|
|
202
|
-
|
|
220
|
+
// The Agent tool's registry: bundled and plugin agents too, not only the user and project folders.
|
|
221
|
+
const plugins = discoverPlugins(defaultDiscoverRoots(agentDir, options.cwd));
|
|
222
|
+
const agentCatalog = discoverAgents(agentFileSources(options.cwd, os.homedir(), plugins.agentDirs));
|
|
203
223
|
const availableModels = [...(await modelRuntime.getAvailable())];
|
|
204
224
|
return new AgentRunner(options, modelRuntime, agentCatalog, availableModels);
|
|
205
225
|
}
|
|
@@ -245,6 +265,12 @@ export class AgentRunner {
|
|
|
245
265
|
|
|
246
266
|
await this.judgeDelegation(prompt, opts, agentDef, signal);
|
|
247
267
|
|
|
268
|
+
// Before the worktree exists: a malformed schema would otherwise leak it.
|
|
269
|
+
if (opts.schema) assertObjectSchema(opts.schema);
|
|
270
|
+
|
|
271
|
+
// Also before the worktree: a rejection here would leak it the same way.
|
|
272
|
+
const mcpTools = (await this.options.getMcpTools?.()) ?? [];
|
|
273
|
+
|
|
248
274
|
let worktree: Worktree | undefined;
|
|
249
275
|
let cwd = this.options.cwd;
|
|
250
276
|
if (opts.isolation === "worktree") {
|
|
@@ -256,13 +282,27 @@ export class AgentRunner {
|
|
|
256
282
|
}
|
|
257
283
|
|
|
258
284
|
const capture: { called: boolean; value: unknown } = { called: false, value: undefined };
|
|
259
|
-
|
|
285
|
+
// An agent without a schema hands its answer back through SubagentHandback,
|
|
286
|
+
// as every child does; with a schema, structured_output is the hand-back.
|
|
287
|
+
const handback = opts.schema ? undefined : oneTurnHandbackSlot();
|
|
288
|
+
const customTools: ToolDefinition[] = [
|
|
289
|
+
...(opts.schema ? [buildStructuredOutputTool(opts.schema, capture)] : []),
|
|
290
|
+
...mcpTools,
|
|
291
|
+
];
|
|
260
292
|
|
|
293
|
+
// The same child session a subagent gets (SUBAGENTS-WORKFLOWS-REVIEW-2026-09-26
|
|
294
|
+
// H2, H3, M6): the curated child extensions, the parent's MCP tools, and the
|
|
295
|
+
// agent file's tool lists through the one shared builder, which keeps
|
|
296
|
+
// `structured_output` on an allowlist and applies `disallowedTools`.
|
|
261
297
|
const session = await openChildSession({
|
|
262
298
|
loader: {
|
|
263
299
|
cwd: this.options.cwd,
|
|
264
300
|
agentDir: getAgentDir(),
|
|
265
301
|
systemPrompt: agentDef?.systemPrompt,
|
|
302
|
+
extraExtensionPaths: CHILD_EXTENSION_PATHS,
|
|
303
|
+
// claude-context (a child extension) injects the CLAUDE.md instructions itself.
|
|
304
|
+
noContextFiles: true,
|
|
305
|
+
extraFactories: [deferLikeParentExtension(this.options.getParentDeferred?.() ?? [], injectedByParent([])), ...(handback ? [subagentHandbackExtension(handback)] : [])],
|
|
266
306
|
getPermissionBridge: this.options.getPermissionBridge,
|
|
267
307
|
getHookBridge: this.options.getHookBridge,
|
|
268
308
|
},
|
|
@@ -272,11 +312,16 @@ export class AgentRunner {
|
|
|
272
312
|
modelRuntime: this.modelRuntime,
|
|
273
313
|
model: modelSpec.model as never,
|
|
274
314
|
thinkingLevel: modelSpec.thinkingLevel as never,
|
|
275
|
-
|
|
315
|
+
...agentToolOptions(agentDef),
|
|
276
316
|
customTools,
|
|
277
317
|
sessionManager: SessionManager.inMemory(cwd),
|
|
278
318
|
},
|
|
279
319
|
onError: (error) => this.options.onNotice?.(`${opts.label ?? "agent"}: extension error in ${error.event}: ${error.error}`),
|
|
320
|
+
}).catch(async (error: unknown) => {
|
|
321
|
+
// Not yet under the prompt's try/finally: a session that fails to open
|
|
322
|
+
// must not leak the worktree and its branch.
|
|
323
|
+
if (worktree) await this.settleWorktree(worktree, opts.label, error);
|
|
324
|
+
throw error;
|
|
280
325
|
});
|
|
281
326
|
|
|
282
327
|
const unhookAbort = whenAborted(signal, () => void session.abort());
|
|
@@ -284,8 +329,11 @@ export class AgentRunner {
|
|
|
284
329
|
// refusing the agent's model (the same check the subagent runner makes, so
|
|
285
330
|
// the refusal reaches every automatic picker — lib/model-unusable.ts).
|
|
286
331
|
// Never let a bad event shape kill the agent.
|
|
332
|
+
const childWrote = childWriteWatcher(session.sessionManager?.getCwd?.() ?? this.options.cwd);
|
|
287
333
|
const unsubscribe = session.subscribe((event) => {
|
|
288
334
|
try {
|
|
335
|
+
const wrote = childWrote(event as never);
|
|
336
|
+
if (wrote) this.options.onChildWrite?.(wrote, opts.label);
|
|
289
337
|
if (event.type === "message_end") {
|
|
290
338
|
const reply = (event as { message?: { role?: string; stopReason?: string; errorMessage?: string; provider?: string; model?: string } }).message;
|
|
291
339
|
if (reply?.role === "assistant" && reply.stopReason === "error" && reply.errorMessage && reply.provider && reply.model && isModelUnavailableError(reply.errorMessage)) {
|
|
@@ -310,7 +358,17 @@ export class AgentRunner {
|
|
|
310
358
|
prefixWarmKey(agentPromptIdentity(agentDef?.name), cwd, model ? modelSpecOf(model) : undefined),
|
|
311
359
|
session,
|
|
312
360
|
);
|
|
361
|
+
let failure: unknown;
|
|
313
362
|
try {
|
|
363
|
+
// An allowlist that matched no real tool would run a tool-less agent.
|
|
364
|
+
const unusable = unusableAllowlistError(
|
|
365
|
+
agentDef,
|
|
366
|
+
session.getAllTools().map((t) => t.name),
|
|
367
|
+
);
|
|
368
|
+
if (unusable) throw new WorkflowScriptError(unusable);
|
|
369
|
+
// A stop during the waits above (MCP tools still connecting, the warm
|
|
370
|
+
// gate) aborted a session that was idle: never send the first request.
|
|
371
|
+
if (signal.aborted) throw new WorkflowScriptError("aborted");
|
|
314
372
|
await session.prompt(this.buildPrompt(prompt, Boolean(opts.schema)));
|
|
315
373
|
if (signal.aborted) throw new WorkflowScriptError("aborted");
|
|
316
374
|
|
|
@@ -318,27 +376,39 @@ export class AgentRunner {
|
|
|
318
376
|
if (opts.schema) {
|
|
319
377
|
value = await this.resolveStructuredOutput(session, capture, signal);
|
|
320
378
|
} else {
|
|
321
|
-
|
|
379
|
+
// The handed-back report, else the agent's last message.
|
|
380
|
+
value = handback?.report ?? finalAssistantText(session.messages);
|
|
322
381
|
if (typeof value !== "string" || !value.trim()) {
|
|
323
382
|
throw new Error("subagent produced no output");
|
|
324
383
|
}
|
|
325
|
-
|
|
384
|
+
// Never cut: a long answer is saved to the run directory and the script
|
|
385
|
+
// gets Claude Code's <persisted-output> block naming the file, which a
|
|
386
|
+
// later agent can read (SUBAGENTS-WORKFLOWS-REVIEW-2026-09-26 M1).
|
|
387
|
+
value = persistIfLarge(value as string, {
|
|
388
|
+
dir: this.options.resultsDir ?? sessionResultsDir(undefined),
|
|
389
|
+
id: `agent-${randomBytes(4).toString("hex")}`,
|
|
390
|
+
maxBytes: OUTPUT_CAP,
|
|
391
|
+
});
|
|
326
392
|
}
|
|
327
393
|
|
|
328
394
|
const stats = session.getSessionStats();
|
|
329
|
-
// cleanupWorktree keeps trees holding uncommitted changes; report those.
|
|
330
|
-
let
|
|
395
|
+
// cleanupWorktree keeps trees holding uncommitted changes or commits; report those.
|
|
396
|
+
let kept: Worktree | undefined;
|
|
331
397
|
if (worktree) {
|
|
332
398
|
const removed = await cleanupWorktree(this.options.cwd, worktree);
|
|
333
|
-
if (!removed)
|
|
399
|
+
if (!removed) kept = worktree;
|
|
334
400
|
worktree = undefined;
|
|
335
401
|
}
|
|
336
402
|
return {
|
|
337
403
|
value,
|
|
338
404
|
tokens: { input: stats.tokens.input, output: stats.tokens.output, total: stats.tokens.total },
|
|
339
405
|
cost: stats.cost,
|
|
340
|
-
worktreePath,
|
|
406
|
+
worktreePath: kept?.path,
|
|
407
|
+
worktreeBranch: kept?.branch,
|
|
341
408
|
};
|
|
409
|
+
} catch (error) {
|
|
410
|
+
failure = error;
|
|
411
|
+
throw error;
|
|
342
412
|
} finally {
|
|
343
413
|
// Whatever the outcome — success, failure, or an abort (a user stop, or
|
|
344
414
|
// the run finishing with this agent un-awaited) — the provider was
|
|
@@ -348,11 +418,26 @@ export class AgentRunner {
|
|
|
348
418
|
releasePrefix(false);
|
|
349
419
|
unsubscribe?.();
|
|
350
420
|
unhookAbort();
|
|
351
|
-
session
|
|
352
|
-
|
|
421
|
+
disposeChildSession(session);
|
|
422
|
+
// A failed or aborted agent can still have edited or committed in its
|
|
423
|
+
// worktree: settled after the session is gone, before the error reaches
|
|
424
|
+
// the caller, so the kept path rides on it.
|
|
425
|
+
if (worktree) await this.settleWorktree(worktree, opts.label, failure);
|
|
353
426
|
}
|
|
354
427
|
}
|
|
355
428
|
|
|
429
|
+
/**
|
|
430
|
+
* Remove a failed agent's worktree, or keep it when it holds changes or
|
|
431
|
+
* commits: then the run log names it, and the kept path rides on `error`
|
|
432
|
+
* (`keptWorktreeOf`) so the agent's end event and the run report list it.
|
|
433
|
+
*/
|
|
434
|
+
private async settleWorktree(worktree: Worktree, label: string | undefined, error: unknown): Promise<void> {
|
|
435
|
+
if (await cleanupWorktree(this.options.cwd, worktree)) return;
|
|
436
|
+
const kept: KeptWorktree = { path: worktree.path, branch: worktree.branch };
|
|
437
|
+
this.options.onNotice?.(`${label ?? "agent"}: worktree kept at ${kept.path} (branch ${kept.branch}) with its changes or commits`);
|
|
438
|
+
if (error instanceof Error) (error as Error & { keptWorktree?: KeptWorktree }).keptWorktree = kept;
|
|
439
|
+
}
|
|
440
|
+
|
|
356
441
|
private judgeDelegation(prompt: string, opts: AgentCallOptions, agentDef: AgentDefinition | undefined, signal: AbortSignal): Promise<void> {
|
|
357
442
|
return judgeWorkflowDelegation({
|
|
358
443
|
bridge: this.options.getPermissionBridge?.(),
|
|
@@ -367,7 +452,7 @@ export class AgentRunner {
|
|
|
367
452
|
|
|
368
453
|
private buildPrompt(prompt: string, structured: boolean): string {
|
|
369
454
|
if (!structured) {
|
|
370
|
-
return `${prompt}\n\
|
|
455
|
+
return `${prompt}\n\nThe report you hand back through SubagentHandback is returned verbatim to an orchestration script, not shown to a human — hand back the requested data/report only.`;
|
|
371
456
|
}
|
|
372
457
|
return `${prompt}\n\nWhen you are done, you MUST call the \`structured_output\` tool exactly once with your final result. Its arguments are the only output the caller receives.`;
|
|
373
458
|
}
|
|
@@ -398,9 +483,7 @@ export class AgentRunner {
|
|
|
398
483
|
|
|
399
484
|
/** Terminating tool capturing schema-validated output (pi validates params pre-execute). */
|
|
400
485
|
function buildStructuredOutputTool(schema: Record<string, unknown>, capture: { called: boolean; value: unknown }): ToolDefinition {
|
|
401
|
-
|
|
402
|
-
throw new WorkflowScriptError("agent() schema must be a JSON Schema with top-level type \"object\" and properties");
|
|
403
|
-
}
|
|
486
|
+
assertObjectSchema(schema);
|
|
404
487
|
return {
|
|
405
488
|
name: "structured_output",
|
|
406
489
|
label: "Structured Output",
|
|
@@ -418,6 +501,13 @@ function buildStructuredOutputTool(schema: Record<string, unknown>, capture: { c
|
|
|
418
501
|
} as ToolDefinition;
|
|
419
502
|
}
|
|
420
503
|
|
|
504
|
+
/** A structured_output schema must be an object schema with properties. */
|
|
505
|
+
function assertObjectSchema(schema: Record<string, unknown>): void {
|
|
506
|
+
if (schema.type !== "object" || typeof schema.properties !== "object") {
|
|
507
|
+
throw new WorkflowScriptError("agent() schema must be a JSON Schema with top-level type \"object\" and properties");
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
421
511
|
/** Pull the first parseable JSON object/array out of free text (```json fences first). */
|
|
422
512
|
function extractJsonObject(text: string): unknown {
|
|
423
513
|
const fenced = text.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** The workflow tool's argument preparation (pure). */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The call's arguments with `args` as the script should see it, decoded before
|
|
5
|
+
* the gate, hooks and the stored call see them. Weak models send a list or
|
|
6
|
+
* object as a JSON-encoded string despite the description (every Qwen 3.8
|
|
7
|
+
* model, battery round 7), which breaks `args.map` and `pipeline(args, …)`; a
|
|
8
|
+
* string that parses to an array or object is decoded. Any other value passes
|
|
9
|
+
* verbatim.
|
|
10
|
+
*/
|
|
11
|
+
export function prepareWorkflowArguments(raw: unknown): unknown {
|
|
12
|
+
if (!raw || typeof raw !== "object" || !("args" in raw)) return raw;
|
|
13
|
+
return { ...raw, args: decodedArgs((raw as { args: unknown }).args) };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function decodedArgs(args: unknown): unknown {
|
|
17
|
+
if (typeof args !== "string" || !/^\s*[[{]/.test(args)) return args;
|
|
18
|
+
try {
|
|
19
|
+
const parsed: unknown = JSON.parse(args);
|
|
20
|
+
return parsed !== null && typeof parsed === "object" ? parsed : args;
|
|
21
|
+
} catch {
|
|
22
|
+
return args;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The workflow tool's model-facing description: Claude Code's Workflow text
|
|
3
|
+
* and its size-guideline line (pure).
|
|
4
|
+
*
|
|
5
|
+
* The authoring reference (script API, quality patterns, resume, worked
|
|
6
|
+
* examples) is the bundled `workflow-authoring` skill, which the description
|
|
7
|
+
* tells the model to load before writing a script. The size line follows
|
|
8
|
+
* `workflowSizeGuideline` in One Code's settings (lib/one-code-settings.ts);
|
|
9
|
+
* "unrestricted" sends no line, as in Claude Code. Changes from Claude Code's
|
|
10
|
+
* text: the setting is named where Claude Code points to its /config row, and
|
|
11
|
+
* tool names are One Code's.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { WorkflowSizeGuideline } from "../lib/one-code-settings.ts";
|
|
15
|
+
|
|
16
|
+
export const WORKFLOW_DESCRIPTION_BODY = `Execute a workflow script that orchestrates multiple subagents deterministically. Workflows run in the background — this tool returns immediately with a task ID, and a <task-notification> arrives when the workflow completes. Use /workflows to watch live progress.
|
|
17
|
+
|
|
18
|
+
ONLY call this tool when the user has explicitly opted into multi-agent orchestration. Workflows can spawn dozens of agents and consume a large amount of tokens; the user must request that scale, not have it inferred. Explicit opt-in means one of:
|
|
19
|
+
- The user included the keyword "ultracode" in their prompt (you'll see a system-reminder confirming it).
|
|
20
|
+
- Ultracode is on for the session (a system-reminder confirms it) — see **Ultracode** in the workflow authoring reference.
|
|
21
|
+
- The user directly asked you to run a workflow or use multi-agent orchestration in their own words ("use a workflow", "run a workflow", "fan out agents", "orchestrate this with subagents"). The ask must be in the user's words — a task that would merely benefit from a workflow does not count.
|
|
22
|
+
- The user invoked a skill or slash command whose instructions tell you to call Workflow.
|
|
23
|
+
- The user asked you to run a specific named or saved workflow.
|
|
24
|
+
|
|
25
|
+
For any other task — even one that would clearly benefit from parallelism — do NOT call this tool. Use the Agent tool (if available) for individual subagents, or briefly describe what a multi-agent workflow could do and how much it would roughly cost, and ask the user whether to run it. Mention they can ask for one with "use a workflow" in a future message to skip the ask.
|
|
26
|
+
|
|
27
|
+
Every script must begin with \`export const meta = {...}\`: a PURE LITERAL (no variables, calls or interpolation) giving the workflow's \`name\`, a one-line \`description\` (shown in the permission dialog) and optionally \`phases\` — one \`{ title, detail? }\` per phase() call, titles matched exactly. Pass the script inline via \`script\` — do not write it to a file first, and do not also set the tool's \`name\` input (that selects a saved workflow); it is plain JavaScript, not TypeScript.
|
|
28
|
+
|
|
29
|
+
The canonical multi-stage pattern — pipeline by default, each dimension verifies as soon as its review completes:
|
|
30
|
+
export const meta = {
|
|
31
|
+
name: 'review-changes',
|
|
32
|
+
description: 'Review changed files across dimensions, verify each finding',
|
|
33
|
+
phases: [{ title: 'Review' }, { title: 'Verify' }],
|
|
34
|
+
}
|
|
35
|
+
const DIMENSIONS = [{key: 'bugs', prompt: '...'}, {key: 'perf', prompt: '...'}]
|
|
36
|
+
const results = await pipeline(
|
|
37
|
+
DIMENSIONS,
|
|
38
|
+
d => agent(d.prompt, {label: \`review:\${d.key}\`, phase: 'Review', schema: FINDINGS_SCHEMA}),
|
|
39
|
+
review => parallel(review.findings.map(f => () =>
|
|
40
|
+
agent(\`Adversarially verify: \${f.title}\`, {label: \`verify:\${f.file}\`, phase: 'Verify', schema: VERDICT_SCHEMA})
|
|
41
|
+
.then(v => ({...f, verdict: v}))
|
|
42
|
+
))
|
|
43
|
+
)
|
|
44
|
+
const confirmed = results.flat().filter(Boolean).filter(f => f.verdict?.isReal)
|
|
45
|
+
return { confirmed }
|
|
46
|
+
// Dimension 'bugs' findings verify while dimension 'perf' is still reviewing. No wasted wall-clock.
|
|
47
|
+
|
|
48
|
+
Before writing a script, load the \`workflow-authoring\` skill — the workflow authoring reference: script API and gotchas, resume, the **Ultracode** section, quality patterns, worked examples.`;
|
|
49
|
+
|
|
50
|
+
/** The agent count each size keeps a workflow under. */
|
|
51
|
+
export const WORKFLOW_SIZE_AGENTS: Record<Exclude<WorkflowSizeGuideline, "unrestricted">, number> = {
|
|
52
|
+
small: 5,
|
|
53
|
+
medium: 10,
|
|
54
|
+
large: 50,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** The size-guideline line; undefined when no guideline applies. */
|
|
58
|
+
export function workflowSizeLine(guideline: WorkflowSizeGuideline, configured: boolean): string | undefined {
|
|
59
|
+
if (guideline === "unrestricted") return undefined;
|
|
60
|
+
const opening = configured ? "A workflow size guideline is configured for this session" : "This session has the default workflow size guideline";
|
|
61
|
+
return `${opening}: ${guideline} — keep workflows under ${WORKFLOW_SIZE_AGENTS[guideline]} agents. This is a guideline, not a hard limit — follow it unless the user's prompt calls for a different scale. The user can raise or remove it with \`workflowSizeGuideline\` in ~/.onecode/settings.json.`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function workflowDescription(guideline: WorkflowSizeGuideline, configured: boolean): string {
|
|
65
|
+
const line = workflowSizeLine(guideline, configured);
|
|
66
|
+
return line ? `${WORKFLOW_DESCRIPTION_BODY}\n\n${line}` : WORKFLOW_DESCRIPTION_BODY;
|
|
67
|
+
}
|
|
@@ -25,7 +25,7 @@ import type {
|
|
|
25
25
|
JournalEntry,
|
|
26
26
|
RunProgressEvent,
|
|
27
27
|
} from "./types.ts";
|
|
28
|
-
import { WorkflowScriptError } from "./types.ts";
|
|
28
|
+
import { keptWorktreeOf, type KeptWorktree, WorkflowScriptError } from "./types.ts";
|
|
29
29
|
import type { ReplayCursor } from "./journal.ts";
|
|
30
30
|
|
|
31
31
|
export const MAX_AGENTS_PER_RUN = 1000;
|
|
@@ -186,6 +186,7 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
|
|
|
186
186
|
replayed: true,
|
|
187
187
|
prompt,
|
|
188
188
|
preview: previewValue(replayed.value),
|
|
189
|
+
...keptWorktreeField(replayed.worktreePath, replayed.worktreeBranch),
|
|
189
190
|
});
|
|
190
191
|
return replayed.value;
|
|
191
192
|
}
|
|
@@ -216,13 +217,14 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
|
|
|
216
217
|
tokens: result.tokens,
|
|
217
218
|
cost: result.cost,
|
|
218
219
|
preview: previewValue(result.value),
|
|
220
|
+
...keptWorktreeField(result.worktreePath, result.worktreeBranch),
|
|
219
221
|
});
|
|
220
222
|
return result.value;
|
|
221
223
|
} catch (error) {
|
|
222
224
|
if (options.signal.aborted) {
|
|
223
225
|
// Close the record: the viewer would otherwise show a completed or
|
|
224
226
|
// stopped run with this agent still "running".
|
|
225
|
-
options.onEvent({ type: "agentEnd", callIndex, label, phase, text: "aborted" });
|
|
227
|
+
options.onEvent({ type: "agentEnd", callIndex, label, phase, text: "aborted", ...keptWorktreeField(keptWorktreeOf(error)?.path, keptWorktreeOf(error)?.branch) });
|
|
226
228
|
throw new WorkflowScriptError("Workflow run was aborted");
|
|
227
229
|
}
|
|
228
230
|
// A script-authoring mistake (bad agentType/model, worktree without a
|
|
@@ -233,7 +235,14 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
|
|
|
233
235
|
if (error instanceof WorkflowScriptError) throw error;
|
|
234
236
|
// A failed agent resolves to null (Claude Code semantics); the
|
|
235
237
|
// failure is surfaced as a progress event, not an exception.
|
|
236
|
-
options.onEvent({
|
|
238
|
+
options.onEvent({
|
|
239
|
+
type: "agentEnd",
|
|
240
|
+
callIndex,
|
|
241
|
+
label,
|
|
242
|
+
phase,
|
|
243
|
+
text: `failed: ${(error as Error).message}`,
|
|
244
|
+
...keptWorktreeField(keptWorktreeOf(error)?.path, keptWorktreeOf(error)?.branch),
|
|
245
|
+
});
|
|
237
246
|
return null;
|
|
238
247
|
}
|
|
239
248
|
});
|
|
@@ -272,3 +281,8 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
|
|
|
272
281
|
|
|
273
282
|
return { globals, state };
|
|
274
283
|
}
|
|
284
|
+
|
|
285
|
+
/** The `worktree` field of an agentEnd event, present only for a kept worktree. */
|
|
286
|
+
function keptWorktreeField(path: string | undefined, branch: string | undefined): { worktree?: KeptWorktree } {
|
|
287
|
+
return path ? { worktree: branch ? { path, branch } : { path } } : {};
|
|
288
|
+
}
|