@ashx-j/lunr-dev 0.2.13-dev.4.1 → 0.2.13-dev.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +4 -4
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +2 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-settings-tools.d.ts +4 -0
- package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-settings-tools.js +120 -0
- package/dist/builtin-extensions/lunr-settings-tools.js.map +1 -0
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts +2 -2
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js +3 -3
- package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts +2 -2
- package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/api/delegation.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/api/delegation.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +2 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +5 -11
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +12 -15
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +3 -3
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +14 -27
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +6 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +2 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +6 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js +4 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js +3 -35
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +5 -12
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +14 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +28 -22
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +9 -4
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +4 -7
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts +3 -3
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js +7 -6
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +6 -4
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +15 -10
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -2
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +75 -43
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/catalog/models.json +1 -1
- package/dist/catalog/providers/amazon-bedrock.json +1 -1
- package/dist/catalog/providers/anthropic.json +1 -1
- package/dist/catalog/providers/cloudflare-ai-gateway.json +1 -1
- package/dist/catalog/providers/fireworks.json +1 -1
- package/dist/catalog/providers/github-copilot.json +1 -1
- package/dist/catalog/providers/google-vertex.json +1 -1
- package/dist/catalog/providers/google.json +1 -1
- package/dist/catalog/providers/huggingface.json +1 -1
- package/dist/catalog/providers/nvidia.json +1 -1
- package/dist/catalog/providers/opencode-go.json +1 -1
- package/dist/catalog/providers/opencode.json +1 -1
- package/dist/catalog/providers/openrouter.json +1 -1
- package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
- package/dist/catalog/publication.json +3 -3
- package/dist/core/agent-session-runtime.d.ts +5 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +7 -2
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +20 -5
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/context-breakdown.d.ts +2 -0
- package/dist/core/context-breakdown.d.ts.map +1 -1
- package/dist/core/context-breakdown.js +6 -2
- package/dist/core/context-breakdown.js.map +1 -1
- package/dist/core/injected-prompt.d.ts +3 -3
- package/dist/core/injected-prompt.d.ts.map +1 -1
- package/dist/core/injected-prompt.js +2 -7
- package/dist/core/injected-prompt.js.map +1 -1
- package/dist/core/large-subagent-launch.d.ts +13 -0
- package/dist/core/large-subagent-launch.d.ts.map +1 -0
- package/dist/core/large-subagent-launch.js +54 -0
- package/dist/core/large-subagent-launch.js.map +1 -0
- package/dist/core/model-instructions.d.ts +24 -0
- package/dist/core/model-instructions.d.ts.map +1 -0
- package/dist/core/model-instructions.js +123 -0
- package/dist/core/model-instructions.js.map +1 -0
- package/dist/core/permissions.d.ts +11 -10
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +61 -45
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +10 -1
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/resource-loader.d.ts +3 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +13 -4
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-bridges.d.ts +4 -0
- package/dist/core/runtime-bridges.d.ts.map +1 -0
- package/dist/core/runtime-bridges.js +16 -0
- package/dist/core/runtime-bridges.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +17 -16
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +13 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +32 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-tools-bridge.d.ts +35 -0
- package/dist/core/settings-tools-bridge.d.ts.map +1 -0
- package/dist/core/settings-tools-bridge.js +56 -0
- package/dist/core/settings-tools-bridge.js.map +1 -0
- package/dist/core/swarm.d.ts +0 -31
- package/dist/core/swarm.d.ts.map +1 -1
- package/dist/core/swarm.js +2 -76
- package/dist/core/swarm.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +3 -2
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +4 -3
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +3 -2
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/router.d.ts +1 -1
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +1 -1
- package/dist/gateway/router.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -9
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/injected-prompt-message.d.ts +1 -1
- package/dist/modes/interactive/components/injected-prompt-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/injected-prompt-message.js +1 -1
- package/dist/modes/interactive/components/injected-prompt-message.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +61 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +31 -23
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/startup/interactive-shell.d.ts.map +1 -1
- package/dist/startup/interactive-shell.js +2 -1
- package/dist/startup/interactive-shell.js.map +1 -1
- package/docs/features.md +7 -6
- package/docs/quickstart.md +3 -2
- package/docs/settings.md +3 -1
- package/docs/termux.md +1 -1
- package/docs/usage.md +2 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-status.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/async-status.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC7G,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3F,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAoB,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACrI,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAwF/F,SAAS,eAAe,CAAC,KAAc,EAAU;IAChD,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,CAC9D;AAED,SAAS,eAAe,CAAC,KAAc,EAAW;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC5B,KAAK,KAAK,IAAI;WACd,MAAM,IAAI,KAAK;WACd,KAA+B,CAAC,IAAI,KAAK,QAAQ,CAAC;AAAA,CACvD;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,KAAa,EAAW;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC;QACJ,OAAO,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,qCAAqC,SAAS,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YAC7F,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC,CAAC;IACJ,CAAC;AAAA,CACD;AAED,SAAS,eAAe,CAAC,UAA8B,EAAsB;IAC5E,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,CAAC;QACJ,OAAO,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,wCAAwC,UAAU,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YACjG,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC,CAAC;IACJ,CAAC;AAAA,CACD;AAED,SAAS,wBAAwB,CAAC,QAAgB,EAAE,MAAmB,EAA8D;IACpI,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC;IACtH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrJ,MAAM,WAAW,GAAG,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,OAAO;QACN,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,eAAe,CAAC,UAAU,CAAC,IAAI,WAAW,EAAE,cAAc,IAAI,WAAW,EAAE,SAAS,IAAI,MAAM,CAAC,SAAS;KACjJ,CAAC;AAAA,CACF;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,MAAsC,EAAE,cAAc,GAAa,EAAE,EAAE,WAAyB,EAAmB;IAC7J,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC9G,CAAC;IACD,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,CAAC;IAC7D,MAAM,cAAc,GAAG,uBAAuB,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACpG,IAAI,cAAc,GAAuB,EAAE,CAAC;IAC5C,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC;YACJ,yEAAyE;YACzE,8DAA8D;YAC9D,cAAc,GAAG,mBAAmB,CAAC,WAAW,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,IAAI,CAAC,8BAA8B,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;IACF,CAAC;IACD,MAAM,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC;QAC7C,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC;QAC/C,OAAO;YACN,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3F,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjG,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7D,CAAC;IAAA,CACF,CAAC,CAAC;IACH,yBAAyB,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;IACpG,OAAO;QACN,EAAE,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC3C,QAAQ;QACR,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,aAAa;QACb,cAAc;QACd,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,MAAM,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrG,GAAG,CAAC,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,KAAK,EAAE,eAAe;QACtB,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;AAAA,CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,MAAsC,EAAmB;IAC/G,OAAO,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAAA,CACzC;AAED,SAAS,QAAQ,CAAC,IAAuB,EAAqB;IAC7D,MAAM,IAAI,GAAG,CAAC,KAA+B,EAAU,EAAE,CAAC;QACzD,QAAQ,KAAK,EAAE,CAAC;YACf,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC;YACzB,KAAK,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxB,KAAK,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxB,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC;YACzB,KAAK,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxB,KAAK,UAAU,EAAE,OAAO,CAAC,CAAC;QAC3B,CAAC;IAAA,CACD,CAAC;IACF,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,OAAO,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAClC,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC;QACvD,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC;QACvD,OAAO,KAAK,GAAG,KAAK,CAAC;IAAA,CACrB,CAAC,CAAC;AAAA,CACH;AAED,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,OAAO,GAAwB,EAAE,EAAqB;IACzG,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,iCAAiC,YAAY,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YAC5F,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,MAAM,IAAI,GAAsB,EAAE,CAAC;IACnC,sEAAsE;IACtE,6EAA6E;IAC7E,yEAAyE;IACzE,wEAAwE;IACxE,sCAAsC;IACtC,IAAI,gBAAsD,CAAC;IAC3D,MAAM,kBAAkB,GAAG,CAAC,SAAiB,EAA2B,EAAE,CAAC;QAC1E,IAAI,CAAC,gBAAgB;YAAE,gBAAgB,GAAG,qBAAqB,EAAE,CAAC;QAClE,OAAO,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAAA,CACvC,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,KAAK,KAAK;YACjD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,iBAAiB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACzG,MAAM,MAAM,GAAG,CAAC,cAAc,EAAE,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,CAA4C,CAAC;QAC3G,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,yEAAyE;QACzE,2EAA2E;QAC3E,uEAAuE;QACvE,SAAS;QACT,IAAI,aAAa,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,SAAS;QAChE,IAAI,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS;YAAE,SAAS;QAC1E,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,IAAI,WAAoC,CAAC;QACzC,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC;gBACJ,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC1E,IAAI,WAAW;oBAAE,+BAA+B,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACzI,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,cAAc,CAAC,IAAI,CAAC,8BAA8B,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7E,CAAC;QACF,CAAC;QACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAC/E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7E;AAED,SAAS,mBAAmB,CAAC,KAAsS,EAAsB;IACxV,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,WAAW,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC;SAC9K,IAAI,KAAK,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACpE,IAAI,KAAK,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAClE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,wBAAwB,KAAK,CAAC,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;SAC1K,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,CAAC,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;SAC1I,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/I,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,QAAQ,CAAC,SAAS,eAAe,KAAK,CAAC,QAAQ,CAAC,OAAO,aAAa,KAAK,CAAC,QAAQ,CAAC,SAAS,eAAe,KAAK,CAAC,QAAQ,CAAC,MAAM,YAAY,KAAK,CAAC,QAAQ,CAAC,SAAS,YAAY,CAAC,CAAC;IACnO,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAChF,OAAO,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC/F;AAED,SAAS,cAAc,CAAC,IAAyB,EAAU;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,GAAG,OAAO,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3F,IAAI,aAAa;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/E,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAAA,CACzB;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAqD,EAAsB;IACnH,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;AAAA,CAClG;AAED,MAAM,UAAU,2BAA2B,CAAC,GAA4G,EAAU;IACjK,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;IACvD,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7F,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,KAAK,SAAS;QAChD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,WAAY,IAAI,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,WAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzG,CAAC,CAAC,SAAS,CAAC;IACb,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7F,MAAM,UAAU,GAAG,qBAAqB,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC;QAClH,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC;QAC/C,OAAO,QAAQ,WAAW,CAAC,SAAS,GAAG,CAAC,IAAI,cAAc,uBAAsB,UAAU,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC;IAC1H,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChF,MAAM,WAAW,GAAG,sBAAsB,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QACpF,OAAO,QAAQ,WAAW,GAAG,CAAC,IAAI,cAAc,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,WAAW,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC;AAAA,CACzG;AAED,SAAS,eAAe,CAAC,GAAoB,EAAU;IACtD,MAAM,SAAS,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,cAAc,kBAAkB,GAAG,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1H,OAAO,GAAG,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,MAAM,SAAS,GAAG,OAAO,MAAM,GAAG,EAAE,CAAC;AAAA,CACrH;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAuB,EAAE,OAAO,GAAG,mBAAmB,EAAU;IAClG,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC;IAE7D,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,GAAG,0BAA0B,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACrG,MAAM,UAAU,GAAG,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxF,KAAK,CAAC,IAAI,CAAC,GAAG,0BAA0B,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACtF,IAAI,GAAG,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACnD,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;QACpF,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACnE,IAAI,GAAG,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AAAA,CAClC","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { formatDuration, formatModelSelection, formatTokens, shortenPath } from \"../../shared/formatters.ts\";\nimport { formatActivityLabel, formatParallelOutcome } from \"../../shared/status-format.ts\";\nimport { type ActivityState, type AsyncJobStep, type AsyncParallelGroupStatus, type AsyncStatus, type CostSummary, type NestedRunSummary, type SteeringStatus, type SubagentRunMode, type TokenUsage, type TurnBudgetState } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\nimport { attachRootChildrenToSteps, buildNestedRouteIndex, type NestedRoute, projectNestedEvents } from \"../shared/nested-events.ts\";\nimport { formatNestedRunStatusLines } from \"../shared/nested-render.ts\";\nimport { flatToLogicalStepIndex, normalizeParallelGroups } from \"./parallel-groups.ts\";\nimport { reconcileAsyncRun, reconcileNestedAsyncDescendants } from \"./stale-run-reconciler.ts\";\n\ninterface AsyncRunStepSummary {\n\tindex: number;\n\tagent: string;\n\tlabel?: string;\n\tphase?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tstatus: AsyncJobStep[\"status\"];\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolArgs?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\trecentTools?: Array<{ tool: string; args: string; endMs: number }>;\n\trecentOutput?: string[];\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tdurationMs?: number;\n\ttokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tskills?: string[];\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tattemptedModels?: string[];\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\tchildren?: NestedRunSummary[];\n}\n\nexport interface AsyncRunSummary {\n\tid: string;\n\tasyncDir: string;\n\tsessionId?: string;\n\tstate: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\terror?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tmode: SubagentRunMode;\n\tcwd?: string;\n\tstartedAt: number;\n\tlastUpdate?: number;\n\tendedAt?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tpendingAppends?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps: AsyncRunStepSummary[];\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tsessionFile?: string;\n\tnestedChildren?: NestedRunSummary[];\n\tnestedWarnings?: string[];\n}\n\ninterface AsyncRunListOptions {\n\tstates?: Array<AsyncRunSummary[\"state\"]>;\n\tsessionId?: string;\n\tlimit?: number;\n\tresultsDir?: string;\n\tkill?: (pid: number, signal?: NodeJS.Signals | 0) => boolean;\n\tnow?: () => number;\n\treconcile?: boolean;\n}\n\nfunction getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n\treturn typeof error === \"object\"\n\t\t&& error !== null\n\t\t&& \"code\" in error\n\t\t&& (error as NodeJS.ErrnoException).code === \"ENOENT\";\n}\n\nfunction isAsyncRunDir(root: string, entry: string): boolean {\n\tconst entryPath = path.join(root, entry);\n\ttry {\n\t\treturn fs.statSync(entryPath).isDirectory();\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return false;\n\t\tthrow new Error(`Failed to inspect async run path '${entryPath}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n}\n\nfunction outputFileMtime(outputFile: string | undefined): number | undefined {\n\tif (!outputFile) return undefined;\n\ttry {\n\t\treturn fs.statSync(outputFile).mtimeMs;\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return undefined;\n\t\tthrow new Error(`Failed to inspect async output file '${outputFile}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n}\n\nfunction deriveAsyncActivityState(asyncDir: string, status: AsyncStatus): { activityState?: ActivityState; lastActivityAt?: number } {\n\tif (status.state !== \"running\") return { activityState: status.activityState, lastActivityAt: status.lastActivityAt };\n\tconst outputPath = status.outputFile ? (path.isAbsolute(status.outputFile) ? status.outputFile : path.join(asyncDir, status.outputFile)) : undefined;\n\tconst currentStep = typeof status.currentStep === \"number\" ? status.steps?.[status.currentStep] : undefined;\n\treturn {\n\t\tactivityState: status.activityState,\n\t\tlastActivityAt: status.lastActivityAt ?? outputFileMtime(outputPath) ?? currentStep?.lastActivityAt ?? currentStep?.startedAt ?? status.startedAt,\n\t};\n}\n\nfunction statusToSummary(asyncDir: string, status: AsyncStatus & { cwd?: string }, nestedWarnings: string[] = [], nestedRoute?: NestedRoute): AsyncRunSummary {\n\tif (status.sessionId !== undefined && typeof status.sessionId !== \"string\") {\n\t\tthrow new Error(`Invalid async status '${path.join(asyncDir, \"status.json\")}': sessionId must be a string.`);\n\t}\n\tconst { activityState, lastActivityAt } = deriveAsyncActivityState(asyncDir, status);\n\tconst steps = status.steps ?? [];\n\tconst chainStepCount = status.chainStepCount ?? steps.length;\n\tconst parallelGroups = normalizeParallelGroups(status.parallelGroups, steps.length, chainStepCount);\n\tlet nestedChildren: NestedRunSummary[] = [];\n\tif (nestedWarnings.length === 0 && nestedRoute) {\n\t\ttry {\n\t\t\t// The route is resolved by the caller via buildNestedRouteIndex, so this\n\t\t\t// avoids a fresh scan of the nested-events directory per run.\n\t\t\tnestedChildren = projectNestedEvents(nestedRoute)?.children ?? [];\n\t\t} catch (error) {\n\t\t\tnestedWarnings.push(`Nested status unavailable: ${getErrorMessage(error)}`);\n\t\t}\n\t}\n\tconst summarizedSteps = steps.map((step, index) => {\n\t\tconst stepActivityState = step.activityState;\n\t\tconst stepLastActivityAt = step.lastActivityAt;\n\t\treturn {\n\t\t\tindex,\n\t\t\tagent: step.agent,\n\t\t\t...(step.label ? { label: step.label } : {}),\n\t\t\t...(step.phase ? { phase: step.phase } : {}),\n\t\t\t...(step.outputName ? { outputName: step.outputName } : {}),\n\t\t\t...(step.structured ? { structured: step.structured } : {}),\n\t\t\tstatus: step.status,\n\t\t\t...(stepActivityState ? { activityState: stepActivityState } : {}),\n\t\t\t...(stepLastActivityAt ? { lastActivityAt: stepLastActivityAt } : {}),\n\t\t\t...(step.currentTool ? { currentTool: step.currentTool } : {}),\n\t\t\t...(step.currentToolArgs ? { currentToolArgs: step.currentToolArgs } : {}),\n\t\t\t...(step.currentToolStartedAt ? { currentToolStartedAt: step.currentToolStartedAt } : {}),\n\t\t\t...(step.currentPath ? { currentPath: step.currentPath } : {}),\n\t\t\t...(step.recentTools ? { recentTools: step.recentTools.map((tool) => ({ ...tool })) } : {}),\n\t\t\t...(step.recentOutput ? { recentOutput: [...step.recentOutput] } : {}),\n\t\t\t...(step.turnCount !== undefined ? { turnCount: step.turnCount } : {}),\n\t\t\t...(step.toolCount !== undefined ? { toolCount: step.toolCount } : {}),\n\t\t\t...(step.steering ? { steering: step.steering } : {}),\n\t\t\t...(step.durationMs !== undefined ? { durationMs: step.durationMs } : {}),\n\t\t\t...(step.tokens ? { tokens: step.tokens } : {}),\n\t\t\t...(step.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t\t...(step.skills ? { skills: step.skills } : {}),\n\t\t\t...(step.model ? { model: step.model } : {}),\n\t\t\t...(step.thinking ? { thinking: step.thinking } : {}),\n\t\t\t...(step.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t\t...(step.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t\t...(step.error ? { error: step.error } : {}),\n\t\t\t...(step.timedOut !== undefined ? { timedOut: step.timedOut } : {}),\n\t\t\t...(step.stopped !== undefined ? { stopped: step.stopped } : {}),\n\t\t\t...(step.turnBudget ? { turnBudget: step.turnBudget } : {}),\n\t\t\t...(step.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: step.turnBudgetExceeded } : {}),\n\t\t\t...(step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {}),\n\t\t\t...(step.children?.length ? { children: step.children } : {}),\n\t\t};\n\t});\n\tattachRootChildrenToSteps(status.runId || path.basename(asyncDir), summarizedSteps, nestedChildren);\n\treturn {\n\t\tid: status.runId || path.basename(asyncDir),\n\t\tasyncDir,\n\t\t...(status.sessionId ? { sessionId: status.sessionId } : {}),\n\t\tstate: status.state,\n\t\t...(status.error ? { error: status.error } : {}),\n\t\tactivityState,\n\t\tlastActivityAt,\n\t\tcurrentTool: status.currentTool,\n\t\tcurrentToolStartedAt: status.currentToolStartedAt,\n\t\tcurrentPath: status.currentPath,\n\t\tturnCount: status.turnCount,\n\t\ttoolCount: status.toolCount,\n\t\tsteering: status.steering,\n\t\tmode: status.mode,\n\t\tcwd: status.cwd,\n\t\tstartedAt: status.startedAt,\n\t\tlastUpdate: status.lastUpdate,\n\t\tendedAt: status.endedAt,\n\t\t...(status.timeoutMs !== undefined ? { timeoutMs: status.timeoutMs } : {}),\n\t\t...(status.deadlineAt !== undefined ? { deadlineAt: status.deadlineAt } : {}),\n\t\t...(status.timedOut !== undefined ? { timedOut: status.timedOut } : {}),\n\t\t...(status.stopped !== undefined ? { stopped: status.stopped } : {}),\n\t\t...(status.turnBudget ? { turnBudget: status.turnBudget } : {}),\n\t\t...(status.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: status.turnBudgetExceeded } : {}),\n\t\t...(status.wrapUpRequested !== undefined ? { wrapUpRequested: status.wrapUpRequested } : {}),\n\t\tcurrentStep: status.currentStep,\n\t\t...(status.chainStepCount !== undefined ? { chainStepCount: status.chainStepCount } : {}),\n\t\t...(status.pendingAppends !== undefined ? { pendingAppends: status.pendingAppends } : {}),\n\t\t...(parallelGroups.length ? { parallelGroups } : {}),\n\t\tsteps: summarizedSteps,\n\t\t...(nestedChildren.length ? { nestedChildren } : {}),\n\t\t...(nestedWarnings.length ? { nestedWarnings } : {}),\n\t\t...(status.sessionDir ? { sessionDir: status.sessionDir } : {}),\n\t\t...(status.outputFile ? { outputFile: status.outputFile } : {}),\n\t\t...(status.totalTokens ? { totalTokens: status.totalTokens } : {}),\n\t\t...(status.totalCost ? { totalCost: status.totalCost } : {}),\n\t\t...(status.sessionFile ? { sessionFile: status.sessionFile } : {}),\n\t};\n}\n\nexport function summarizeAsyncStatus(asyncDir: string, status: AsyncStatus & { cwd?: string }): AsyncRunSummary {\n\treturn statusToSummary(asyncDir, status);\n}\n\nfunction sortRuns(runs: AsyncRunSummary[]): AsyncRunSummary[] {\n\tconst rank = (state: AsyncRunSummary[\"state\"]): number => {\n\t\tswitch (state) {\n\t\t\tcase \"running\": return 0;\n\t\t\tcase \"queued\": return 1;\n\t\t\tcase \"failed\": return 2;\n\t\t\tcase \"stopped\": return 2;\n\t\t\tcase \"paused\": return 2;\n\t\t\tcase \"complete\": return 3;\n\t\t}\n\t};\n\treturn [...runs].sort((a, b) => {\n\t\tconst byState = rank(a.state) - rank(b.state);\n\t\tif (byState !== 0) return byState;\n\t\tconst aTime = a.lastUpdate ?? a.endedAt ?? a.startedAt;\n\t\tconst bTime = b.lastUpdate ?? b.endedAt ?? b.startedAt;\n\t\treturn bTime - aTime;\n\t});\n}\n\nexport function listAsyncRuns(asyncDirRoot: string, options: AsyncRunListOptions = {}): AsyncRunSummary[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = fs.readdirSync(asyncDirRoot).filter((entry) => isAsyncRunDir(asyncDirRoot, entry));\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return [];\n\t\tthrow new Error(`Failed to list async runs in '${asyncDirRoot}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n\n\tconst allowedStates = options.states ? new Set(options.states) : undefined;\n\tconst runs: AsyncRunSummary[] = [];\n\t// Route resolution for every run shares a single index built from the\n\t// nested-events directory, so the per-run lookup is O(1) instead of scanning\n\t// the directory once per run. The index is built lazily on first use, so\n\t// load-time restoration (which only wants queued/running runs) skips it\n\t// entirely when no active runs match.\n\tlet nestedRouteIndex: Map<string, NestedRoute> | undefined;\n\tconst resolveNestedRoute = (rootRunId: string): NestedRoute | undefined => {\n\t\tif (!nestedRouteIndex) nestedRouteIndex = buildNestedRouteIndex();\n\t\treturn nestedRouteIndex.get(rootRunId);\n\t};\n\tfor (const entry of entries) {\n\t\tconst asyncDir = path.join(asyncDirRoot, entry);\n\t\tconst reconciliation = options.reconcile === false\n\t\t\t? undefined\n\t\t\t: reconcileAsyncRun(asyncDir, { resultsDir: options.resultsDir, kill: options.kill, now: options.now });\n\t\tconst status = (reconciliation?.status ?? readStatus(asyncDir)) as (AsyncStatus & { cwd?: string }) | null;\n\t\tif (!status) continue;\n\t\t// Filter before the nested-route lookup: the lookup builds an index over\n\t\t// the nested-events directory, so deferring it for filtered-out runs keeps\n\t\t// restoration at load from scanning that directory when no active runs\n\t\t// match.\n\t\tif (allowedStates && !allowedStates.has(status.state)) continue;\n\t\tif (options.sessionId && status.sessionId !== options.sessionId) continue;\n\t\tconst nestedWarnings: string[] = [];\n\t\tlet nestedRoute: NestedRoute | undefined;\n\t\tif (options.reconcile !== false) {\n\t\t\ttry {\n\t\t\t\tnestedRoute = resolveNestedRoute(status.runId || path.basename(asyncDir));\n\t\t\t\tif (nestedRoute) reconcileNestedAsyncDescendants(nestedRoute, { resultsDir: options.resultsDir, kill: options.kill, now: options.now });\n\t\t\t} catch (error) {\n\t\t\t\tnestedWarnings.push(`Nested status unavailable: ${getErrorMessage(error)}`);\n\t\t\t}\n\t\t}\n\t\tconst summary = statusToSummary(asyncDir, status, nestedWarnings, nestedRoute);\n\t\truns.push(summary);\n\t}\n\n\tconst sorted = sortRuns(runs);\n\treturn options.limit !== undefined ? sorted.slice(0, options.limit) : sorted;\n}\n\nfunction formatActivityFacts(input: { activityState?: ActivityState; lastActivityAt?: number; currentTool?: string; currentToolStartedAt?: number; currentPath?: string; turnCount?: number; toolCount?: number; steering?: SteeringStatus; turnBudget?: TurnBudgetState; turnBudgetExceeded?: boolean; wrapUpRequested?: boolean }): string | undefined {\n\tconst facts: string[] = [];\n\tif (input.currentTool && input.currentToolStartedAt !== undefined) facts.push(`tool ${input.currentTool} ${formatDuration(Math.max(0, Date.now() - input.currentToolStartedAt))}`);\n\telse if (input.currentTool) facts.push(`tool ${input.currentTool}`);\n\tif (input.currentPath) facts.push(shortenPath(input.currentPath));\n\tif (input.turnCount !== undefined) facts.push(`${input.turnCount} turns`);\n\tif (input.turnBudgetExceeded && input.turnBudget) facts.push(`turn budget exceeded ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}+${input.turnBudget.graceTurns}`);\n\telse if (input.wrapUpRequested && input.turnBudget) facts.push(`wrap-up requested ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}`);\n\telse if (input.turnBudget) facts.push(`turn budget ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}+${input.turnBudget.graceTurns}`);\n\tif (input.toolCount !== undefined) facts.push(`${input.toolCount} tools`);\n\tif (input.steering) facts.push(`steering ${input.steering.scheduled} scheduled, ${input.steering.pending} pending, ${input.steering.delivered} delivered, ${input.steering.failed} failed, ${input.steering.recovered} recovered`);\n\tconst activity = formatActivityLabel(input.lastActivityAt, input.activityState);\n\treturn activity || facts.length ? [activity, ...facts].filter(Boolean).join(\" | \") : undefined;\n}\n\nfunction formatStepLine(step: AsyncRunStepSummary): string {\n\tconst display = step.label ? `${step.label} (${step.agent})` : step.agent;\n\tconst phase = step.phase ? `[${step.phase}] ` : \"\";\n\tconst parts = [`${step.index + 1}. ${phase}${display}`, step.status];\n\tconst activity = formatActivityFacts(step);\n\tif (activity) parts.push(activity);\n\tconst modelThinking = formatModelSelection(step.modelSelection, step.model, step.thinking);\n\tif (modelThinking) parts.push(modelThinking);\n\tif (step.durationMs !== undefined) parts.push(formatDuration(step.durationMs));\n\tif (step.tokens) parts.push(`${formatTokens(step.tokens.total)} tok`);\n\treturn parts.join(\" | \");\n}\n\nexport function formatAsyncRunOutputPath(run: Pick<AsyncRunSummary, \"asyncDir\" | \"outputFile\">): string | undefined {\n\tif (!run.outputFile) return undefined;\n\treturn path.isAbsolute(run.outputFile) ? run.outputFile : path.join(run.asyncDir, run.outputFile);\n}\n\nexport function formatAsyncRunProgressLabel(run: Pick<AsyncRunSummary, \"mode\" | \"state\" | \"currentStep\" | \"chainStepCount\" | \"parallelGroups\" | \"steps\">): string {\n\tconst stepCount = run.steps.length || 1;\n\tconst chainStepCount = run.chainStepCount ?? stepCount;\n\tconst groups = normalizeParallelGroups(run.parallelGroups, run.steps.length, chainStepCount);\n\tconst activeGroup = run.currentStep !== undefined\n\t\t? groups.find((group) => run.currentStep! >= group.start && run.currentStep! < group.start + group.count)\n\t\t: undefined;\n\tif (activeGroup) {\n\t\tconst groupSteps = run.steps.slice(activeGroup.start, activeGroup.start + activeGroup.count);\n\t\tconst groupLabel = formatParallelOutcome(groupSteps, activeGroup.count, { showRunning: run.state === \"running\" });\n\t\tif (run.mode === \"parallel\") return groupLabel;\n\t\treturn `step ${activeGroup.stepIndex + 1}/${chainStepCount} · parallel group: ${groupLabel}`;\n\t}\n\tif (run.mode === \"parallel\") return formatParallelOutcome(run.steps, stepCount, { showRunning: run.state === \"running\" });\n\tif (run.mode === \"chain\" && run.currentStep !== undefined && groups.length > 0) {\n\t\tconst logicalStep = flatToLogicalStepIndex(run.currentStep, chainStepCount, groups);\n\t\treturn `step ${logicalStep + 1}/${chainStepCount}`;\n\t}\n\treturn run.currentStep !== undefined ? `step ${run.currentStep + 1}/${stepCount}` : `steps ${stepCount}`;\n}\n\nfunction formatRunHeader(run: AsyncRunSummary): string {\n\tconst stepLabel = formatAsyncRunProgressLabel(run);\n\tconst cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);\n\tconst activity = formatActivityFacts(run);\n\tconst pending = run.pendingAppends ? ` | ${run.pendingAppends} pending append${run.pendingAppends === 1 ? \"\" : \"s\"}` : \"\";\n\treturn `${run.id} | ${run.state}${activity ? ` | ${activity}` : \"\"} | ${run.mode} | ${stepLabel}${pending} | ${cwd}`;\n}\n\nexport function formatAsyncRunList(runs: AsyncRunSummary[], heading = \"Active async runs\"): string {\n\tif (runs.length === 0) return `No ${heading.toLowerCase()}.`;\n\n\tconst lines = [`${heading}: ${runs.length}`, \"\"];\n\tfor (const run of runs) {\n\t\tlines.push(`- ${formatRunHeader(run)}`);\n\t\tfor (const step of run.steps) {\n\t\t\tlines.push(` ${formatStepLine(step)}`);\n\t\t\tlines.push(...formatNestedRunStatusLines(step.children, { indent: \" \", maxLines: 12 }));\n\t\t}\n\t\tconst attached = new Set(run.steps.flatMap((step) => step.children?.map((child) => child.id) ?? []));\n\t\tconst unattached = run.nestedChildren?.filter((child) => !attached.has(child.id)) ?? [];\n\t\tlines.push(...formatNestedRunStatusLines(unattached, { indent: \" \", maxLines: 12 }));\n\t\tif (run.error) lines.push(` Error: ${run.error}`);\n\t\tfor (const warning of run.nestedWarnings ?? []) lines.push(` Warning: ${warning}`);\n\t\tconst outputPath = formatAsyncRunOutputPath(run);\n\t\tif (outputPath) lines.push(` output: ${shortenPath(outputPath)}`);\n\t\tif (run.sessionFile) lines.push(` session: ${shortenPath(run.sessionFile)}`);\n\t\tlines.push(\"\");\n\t}\n\treturn lines.join(\"\\n\").trimEnd();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"async-status.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/async-status.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { formatDuration, formatModelSelection, formatTokens, shortenPath } from \"../../shared/formatters.ts\";\nimport { formatActivityLabel, formatParallelOutcome } from \"../../shared/status-format.ts\";\nimport { type ActivityState, type AsyncJobStep, type AsyncParallelGroupStatus, type AsyncStatus, type CostSummary, type NestedRunSummary, type SteeringStatus, type SubagentRunMode, type TokenUsage, type TurnBudgetState } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\nimport { attachRootChildrenToSteps, buildNestedRouteIndex, type NestedRoute, projectNestedEvents } from \"../shared/nested-events.ts\";\nimport { formatNestedRunStatusLines } from \"../shared/nested-render.ts\";\nimport { flatToLogicalStepIndex, normalizeParallelGroups } from \"./parallel-groups.ts\";\nimport { reconcileAsyncRun, reconcileNestedAsyncDescendants } from \"./stale-run-reconciler.ts\";\n\ninterface AsyncRunStepSummary {\n\tindex: number;\n\tagent: string;\n\tlabel?: string;\n\tphase?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tstatus: AsyncJobStep[\"status\"];\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolArgs?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\trecentTools?: Array<{ tool: string; args: string; endMs: number }>;\n\trecentOutput?: string[];\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tdurationMs?: number;\n\ttokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tskills?: string[];\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tattemptedModels?: string[];\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\tchildren?: NestedRunSummary[];\n}\n\nexport interface AsyncRunSummary {\n\tid: string;\n\tasyncDir: string;\n\tsessionId?: string;\n\tstate: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\terror?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tmode: SubagentRunMode;\n\tcwd?: string;\n\tstartedAt: number;\n\tlastUpdate?: number;\n\tendedAt?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tpendingAppends?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps: AsyncRunStepSummary[];\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tsessionFile?: string;\n\tnestedChildren?: NestedRunSummary[];\n\tnestedWarnings?: string[];\n}\n\ninterface AsyncRunListOptions {\n\tstates?: Array<AsyncRunSummary[\"state\"]>;\n\tsessionId?: string;\n\tlimit?: number;\n\tresultsDir?: string;\n\tkill?: (pid: number, signal?: NodeJS.Signals | 0) => boolean;\n\tnow?: () => number;\n\treconcile?: boolean;\n}\n\nfunction getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n\treturn typeof error === \"object\"\n\t\t&& error !== null\n\t\t&& \"code\" in error\n\t\t&& (error as NodeJS.ErrnoException).code === \"ENOENT\";\n}\n\nfunction isAsyncRunDir(root: string, entry: string): boolean {\n\tconst entryPath = path.join(root, entry);\n\ttry {\n\t\treturn fs.statSync(entryPath).isDirectory();\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return false;\n\t\tthrow new Error(`Failed to inspect async run path '${entryPath}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n}\n\nfunction outputFileMtime(outputFile: string | undefined): number | undefined {\n\tif (!outputFile) return undefined;\n\ttry {\n\t\treturn fs.statSync(outputFile).mtimeMs;\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return undefined;\n\t\tthrow new Error(`Failed to inspect async output file '${outputFile}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n}\n\nfunction deriveAsyncActivityState(asyncDir: string, status: AsyncStatus): { activityState?: ActivityState; lastActivityAt?: number } {\n\tif (status.state !== \"running\") return { activityState: status.activityState, lastActivityAt: status.lastActivityAt };\n\tconst outputPath = status.outputFile ? (path.isAbsolute(status.outputFile) ? status.outputFile : path.join(asyncDir, status.outputFile)) : undefined;\n\tconst currentStep = typeof status.currentStep === \"number\" ? status.steps?.[status.currentStep] : undefined;\n\treturn {\n\t\tactivityState: status.activityState,\n\t\tlastActivityAt: status.lastActivityAt ?? outputFileMtime(outputPath) ?? currentStep?.lastActivityAt ?? currentStep?.startedAt ?? status.startedAt,\n\t};\n}\n\nfunction statusToSummary(asyncDir: string, status: AsyncStatus & { cwd?: string }, nestedWarnings: string[] = [], nestedRoute?: NestedRoute): AsyncRunSummary {\n\tif (status.sessionId !== undefined && typeof status.sessionId !== \"string\") {\n\t\tthrow new Error(`Invalid async status '${path.join(asyncDir, \"status.json\")}': sessionId must be a string.`);\n\t}\n\tconst { activityState, lastActivityAt } = deriveAsyncActivityState(asyncDir, status);\n\tconst steps = status.steps ?? [];\n\tconst chainStepCount = status.chainStepCount ?? steps.length;\n\tconst parallelGroups = normalizeParallelGroups(status.parallelGroups, steps.length, chainStepCount);\n\tlet nestedChildren: NestedRunSummary[] = [];\n\tif (nestedWarnings.length === 0 && nestedRoute) {\n\t\ttry {\n\t\t\t// The route is resolved by the caller via buildNestedRouteIndex, so this\n\t\t\t// avoids a fresh scan of the nested-events directory per run.\n\t\t\tnestedChildren = projectNestedEvents(nestedRoute)?.children ?? [];\n\t\t} catch (error) {\n\t\t\tnestedWarnings.push(`Nested status unavailable: ${getErrorMessage(error)}`);\n\t\t}\n\t}\n\tconst summarizedSteps = steps.map((step, index) => {\n\t\tconst stepActivityState = step.activityState;\n\t\tconst stepLastActivityAt = step.lastActivityAt;\n\t\treturn {\n\t\t\tindex,\n\t\t\tagent: step.agent,\n\t\t\t...(step.label ? { label: step.label } : {}),\n\t\t\t...(step.phase ? { phase: step.phase } : {}),\n\t\t\t...(step.outputName ? { outputName: step.outputName } : {}),\n\t\t\t...(step.structured ? { structured: step.structured } : {}),\n\t\t\tstatus: step.status,\n\t\t\t...(stepActivityState ? { activityState: stepActivityState } : {}),\n\t\t\t...(stepLastActivityAt ? { lastActivityAt: stepLastActivityAt } : {}),\n\t\t\t...(step.currentTool ? { currentTool: step.currentTool } : {}),\n\t\t\t...(step.currentToolArgs ? { currentToolArgs: step.currentToolArgs } : {}),\n\t\t\t...(step.currentToolStartedAt ? { currentToolStartedAt: step.currentToolStartedAt } : {}),\n\t\t\t...(step.currentPath ? { currentPath: step.currentPath } : {}),\n\t\t\t...(step.recentTools ? { recentTools: step.recentTools.map((tool) => ({ ...tool })) } : {}),\n\t\t\t...(step.recentOutput ? { recentOutput: [...step.recentOutput] } : {}),\n\t\t\t...(step.turnCount !== undefined ? { turnCount: step.turnCount } : {}),\n\t\t\t...(step.toolCount !== undefined ? { toolCount: step.toolCount } : {}),\n\t\t\t...(step.steering ? { steering: step.steering } : {}),\n\t\t\t...(step.durationMs !== undefined ? { durationMs: step.durationMs } : {}),\n\t\t\t...(step.tokens ? { tokens: step.tokens } : {}),\n\t\t\t...(step.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t\t...(step.skills ? { skills: step.skills } : {}),\n\t\t\t...(step.model ? { model: step.model } : {}),\n\t\t\t...(step.thinking ? { thinking: step.thinking } : {}),\n\t\t\t...(step.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t\t...(step.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t\t...(step.error ? { error: step.error } : {}),\n\t\t\t...(step.timedOut !== undefined ? { timedOut: step.timedOut } : {}),\n\t\t\t...(step.stopped !== undefined ? { stopped: step.stopped } : {}),\n\t\t\t...(step.turnBudget ? { turnBudget: step.turnBudget } : {}),\n\t\t\t...(step.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: step.turnBudgetExceeded } : {}),\n\t\t\t...(step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {}),\n\t\t\t...(step.children?.length ? { children: step.children } : {}),\n\t\t};\n\t});\n\tattachRootChildrenToSteps(status.runId || path.basename(asyncDir), summarizedSteps, nestedChildren);\n\treturn {\n\t\tid: status.runId || path.basename(asyncDir),\n\t\tasyncDir,\n\t\t...(status.sessionId ? { sessionId: status.sessionId } : {}),\n\t\tstate: status.state,\n\t\t...(status.error ? { error: status.error } : {}),\n\t\tactivityState,\n\t\tlastActivityAt,\n\t\tcurrentTool: status.currentTool,\n\t\tcurrentToolStartedAt: status.currentToolStartedAt,\n\t\tcurrentPath: status.currentPath,\n\t\tturnCount: status.turnCount,\n\t\ttoolCount: status.toolCount,\n\t\tsteering: status.steering,\n\t\tmode: status.mode,\n\t\tcwd: status.cwd,\n\t\tstartedAt: status.startedAt,\n\t\tlastUpdate: status.lastUpdate,\n\t\tendedAt: status.endedAt,\n\t\t...(status.timeoutMs !== undefined ? { timeoutMs: status.timeoutMs } : {}),\n\t\t...(status.deadlineAt !== undefined ? { deadlineAt: status.deadlineAt } : {}),\n\t\t...(status.timedOut !== undefined ? { timedOut: status.timedOut } : {}),\n\t\t...(status.stopped !== undefined ? { stopped: status.stopped } : {}),\n\t\t...(status.turnBudget ? { turnBudget: status.turnBudget } : {}),\n\t\t...(status.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: status.turnBudgetExceeded } : {}),\n\t\t...(status.wrapUpRequested !== undefined ? { wrapUpRequested: status.wrapUpRequested } : {}),\n\t\tcurrentStep: status.currentStep,\n\t\t...(status.chainStepCount !== undefined ? { chainStepCount: status.chainStepCount } : {}),\n\t\t...(status.pendingAppends !== undefined ? { pendingAppends: status.pendingAppends } : {}),\n\t\t...(parallelGroups.length ? { parallelGroups } : {}),\n\t\tsteps: summarizedSteps,\n\t\t...(nestedChildren.length ? { nestedChildren } : {}),\n\t\t...(nestedWarnings.length ? { nestedWarnings } : {}),\n\t\t...(status.sessionDir ? { sessionDir: status.sessionDir } : {}),\n\t\t...(status.outputFile ? { outputFile: status.outputFile } : {}),\n\t\t...(status.totalTokens ? { totalTokens: status.totalTokens } : {}),\n\t\t...(status.totalCost ? { totalCost: status.totalCost } : {}),\n\t\t...(status.sessionFile ? { sessionFile: status.sessionFile } : {}),\n\t};\n}\n\nexport function summarizeAsyncStatus(asyncDir: string, status: AsyncStatus & { cwd?: string }): AsyncRunSummary {\n\treturn statusToSummary(asyncDir, status);\n}\n\nfunction sortRuns(runs: AsyncRunSummary[]): AsyncRunSummary[] {\n\tconst rank = (state: AsyncRunSummary[\"state\"]): number => {\n\t\tswitch (state) {\n\t\t\tcase \"running\": return 0;\n\t\t\tcase \"queued\": return 1;\n\t\t\tcase \"failed\": return 2;\n\t\t\tcase \"stopped\": return 2;\n\t\t\tcase \"paused\": return 2;\n\t\t\tcase \"complete\": return 3;\n\t\t}\n\t};\n\treturn [...runs].sort((a, b) => {\n\t\tconst byState = rank(a.state) - rank(b.state);\n\t\tif (byState !== 0) return byState;\n\t\tconst aTime = a.lastUpdate ?? a.endedAt ?? a.startedAt;\n\t\tconst bTime = b.lastUpdate ?? b.endedAt ?? b.startedAt;\n\t\treturn bTime - aTime;\n\t});\n}\n\nexport function listAsyncRuns(asyncDirRoot: string, options: AsyncRunListOptions = {}): AsyncRunSummary[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = fs.readdirSync(asyncDirRoot).filter((entry) => isAsyncRunDir(asyncDirRoot, entry));\n\t} catch (error) {\n\t\tif (isNotFoundError(error)) return [];\n\t\tthrow new Error(`Failed to list async runs in '${asyncDirRoot}': ${getErrorMessage(error)}`, {\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t});\n\t}\n\n\tconst allowedStates = options.states ? new Set(options.states) : undefined;\n\tconst runs: AsyncRunSummary[] = [];\n\t// Route resolution for every run shares a single index built from the\n\t// nested-events directory, so the per-run lookup is O(1) instead of scanning\n\t// the directory once per run. The index is built lazily on first use, so\n\t// load-time restoration (which only wants queued/running runs) skips it\n\t// entirely when no active runs match.\n\tlet nestedRouteIndex: Map<string, NestedRoute> | undefined;\n\tconst resolveNestedRoute = (rootRunId: string): NestedRoute | undefined => {\n\t\tif (!nestedRouteIndex) nestedRouteIndex = buildNestedRouteIndex();\n\t\treturn nestedRouteIndex.get(rootRunId);\n\t};\n\tfor (const entry of entries) {\n\t\tconst asyncDir = path.join(asyncDirRoot, entry);\n\t\tconst reconciliation = options.reconcile === false\n\t\t\t? undefined\n\t\t\t: reconcileAsyncRun(asyncDir, { resultsDir: options.resultsDir, kill: options.kill, now: options.now });\n\t\tconst status = (reconciliation?.status ?? readStatus(asyncDir)) as (AsyncStatus & { cwd?: string }) | null;\n\t\tif (!status) continue;\n\t\t// Filter before the nested-route lookup: the lookup builds an index over\n\t\t// the nested-events directory, so deferring it for filtered-out runs keeps\n\t\t// restoration at load from scanning that directory when no active runs\n\t\t// match.\n\t\tif (allowedStates && !allowedStates.has(status.state)) continue;\n\t\tif (options.sessionId && status.sessionId !== options.sessionId) continue;\n\t\tconst nestedWarnings: string[] = [];\n\t\tlet nestedRoute: NestedRoute | undefined;\n\t\tif (options.reconcile !== false) {\n\t\t\ttry {\n\t\t\t\tnestedRoute = resolveNestedRoute(status.runId || path.basename(asyncDir));\n\t\t\t\tif (nestedRoute) reconcileNestedAsyncDescendants(nestedRoute, { resultsDir: options.resultsDir, kill: options.kill, now: options.now });\n\t\t\t} catch (error) {\n\t\t\t\tnestedWarnings.push(`Nested status unavailable: ${getErrorMessage(error)}`);\n\t\t\t}\n\t\t}\n\t\tconst summary = statusToSummary(asyncDir, status, nestedWarnings, nestedRoute);\n\t\truns.push(summary);\n\t}\n\n\tconst sorted = sortRuns(runs);\n\treturn options.limit !== undefined ? sorted.slice(0, options.limit) : sorted;\n}\n\nfunction formatActivityFacts(input: { activityState?: ActivityState; lastActivityAt?: number; currentTool?: string; currentToolStartedAt?: number; currentPath?: string; turnCount?: number; toolCount?: number; steering?: SteeringStatus; turnBudget?: TurnBudgetState; turnBudgetExceeded?: boolean; wrapUpRequested?: boolean }): string | undefined {\n\tconst facts: string[] = [];\n\tif (input.currentTool && input.currentToolStartedAt !== undefined) facts.push(`tool ${input.currentTool} ${formatDuration(Math.max(0, Date.now() - input.currentToolStartedAt))}`);\n\telse if (input.currentTool) facts.push(`tool ${input.currentTool}`);\n\tif (input.currentPath) facts.push(shortenPath(input.currentPath));\n\tif (input.turnCount !== undefined) facts.push(`${input.turnCount} turns`);\n\tif (input.turnBudgetExceeded && input.turnBudget) facts.push(`turn budget exceeded ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}+${input.turnBudget.graceTurns}`);\n\telse if (input.wrapUpRequested && input.turnBudget) facts.push(`wrap-up requested ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}`);\n\telse if (input.turnBudget) facts.push(`turn budget ${input.turnBudget.turnCount}/${input.turnBudget.maxTurns}+${input.turnBudget.graceTurns}`);\n\tif (input.toolCount !== undefined) facts.push(`${input.toolCount} tools`);\n\tif (input.steering) facts.push(`steering ${input.steering.scheduled} scheduled, ${input.steering.pending} pending, ${input.steering.delivered} delivered, ${input.steering.failed} failed, ${input.steering.recovered} recovered`);\n\tconst activity = formatActivityLabel(input.lastActivityAt, input.activityState);\n\treturn activity || facts.length ? [activity, ...facts].filter(Boolean).join(\" | \") : undefined;\n}\n\nfunction formatStepLine(step: AsyncRunStepSummary): string {\n\tconst display = step.label ? `${step.label} (${step.agent})` : step.agent;\n\tconst phase = step.phase ? `[${step.phase}] ` : \"\";\n\tconst parts = [`${step.index + 1}. ${phase}${display}`, step.status];\n\tconst activity = formatActivityFacts(step);\n\tif (activity) parts.push(activity);\n\tconst modelThinking = formatModelSelection(step.modelSelection, step.model, step.thinking);\n\tif (modelThinking) parts.push(modelThinking);\n\tif (step.durationMs !== undefined) {\n\t\tconst duration = step.durationMs + (step.status === \"running\" && step.lastActivityAt !== undefined ? Math.max(0, Date.now() - step.lastActivityAt) : 0);\n\t\tparts.push(`${step.status === \"running\" ? \"\" : \"ran for \"}${formatDuration(duration)}`);\n\t}\n\tif (step.tokens) parts.push(`${formatTokens(step.tokens.total)} tok`);\n\treturn parts.join(\" | \");\n}\n\nexport function formatAsyncRunOutputPath(run: Pick<AsyncRunSummary, \"asyncDir\" | \"outputFile\">): string | undefined {\n\tif (!run.outputFile) return undefined;\n\treturn path.isAbsolute(run.outputFile) ? run.outputFile : path.join(run.asyncDir, run.outputFile);\n}\n\nexport function formatAsyncRunProgressLabel(run: Pick<AsyncRunSummary, \"mode\" | \"state\" | \"currentStep\" | \"chainStepCount\" | \"parallelGroups\" | \"steps\">): string {\n\tconst stepCount = run.steps.length || 1;\n\tconst chainStepCount = run.chainStepCount ?? stepCount;\n\tconst groups = normalizeParallelGroups(run.parallelGroups, run.steps.length, chainStepCount);\n\tconst activeGroup = run.currentStep !== undefined\n\t\t? groups.find((group) => run.currentStep! >= group.start && run.currentStep! < group.start + group.count)\n\t\t: undefined;\n\tif (activeGroup) {\n\t\tconst groupSteps = run.steps.slice(activeGroup.start, activeGroup.start + activeGroup.count);\n\t\tconst groupLabel = formatParallelOutcome(groupSteps, activeGroup.count, { showRunning: run.state === \"running\" });\n\t\tif (run.mode === \"parallel\") return groupLabel;\n\t\treturn `step ${activeGroup.stepIndex + 1}/${chainStepCount} · parallel group: ${groupLabel}`;\n\t}\n\tif (run.mode === \"parallel\") return formatParallelOutcome(run.steps, stepCount, { showRunning: run.state === \"running\" });\n\tif (run.mode === \"chain\" && run.currentStep !== undefined && groups.length > 0) {\n\t\tconst logicalStep = flatToLogicalStepIndex(run.currentStep, chainStepCount, groups);\n\t\treturn `step ${logicalStep + 1}/${chainStepCount}`;\n\t}\n\treturn run.currentStep !== undefined ? `step ${run.currentStep + 1}/${stepCount}` : `steps ${stepCount}`;\n}\n\nfunction formatRunHeader(run: AsyncRunSummary): string {\n\tconst stepLabel = formatAsyncRunProgressLabel(run);\n\tconst cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);\n\tconst activity = formatActivityFacts(run);\n\tconst pending = run.pendingAppends ? ` | ${run.pendingAppends} pending append${run.pendingAppends === 1 ? \"\" : \"s\"}` : \"\";\n\treturn `${run.id} | ${run.state}${activity ? ` | ${activity}` : \"\"} | ${run.mode} | ${stepLabel}${pending} | ${cwd}`;\n}\n\nexport function formatAsyncRunList(runs: AsyncRunSummary[], heading = \"Active async runs\"): string {\n\tif (runs.length === 0) return `No ${heading.toLowerCase()}.`;\n\n\tconst lines = [`${heading}: ${runs.length}`, \"\"];\n\tfor (const run of runs) {\n\t\tlines.push(`- ${formatRunHeader(run)}`);\n\t\tfor (const step of run.steps) {\n\t\t\tlines.push(` ${formatStepLine(step)}`);\n\t\t\tlines.push(...formatNestedRunStatusLines(step.children, { indent: \" \", maxLines: 12 }));\n\t\t}\n\t\tconst attached = new Set(run.steps.flatMap((step) => step.children?.map((child) => child.id) ?? []));\n\t\tconst unattached = run.nestedChildren?.filter((child) => !attached.has(child.id)) ?? [];\n\t\tlines.push(...formatNestedRunStatusLines(unattached, { indent: \" \", maxLines: 12 }));\n\t\tif (run.error) lines.push(` Error: ${run.error}`);\n\t\tfor (const warning of run.nestedWarnings ?? []) lines.push(` Warning: ${warning}`);\n\t\tconst outputPath = formatAsyncRunOutputPath(run);\n\t\tif (outputPath) lines.push(` output: ${shortenPath(outputPath)}`);\n\t\tif (run.sessionFile) lines.push(` session: ${shortenPath(run.sessionFile)}`);\n\t\tlines.push(\"\");\n\t}\n\treturn lines.join(\"\\n\").trimEnd();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-clarify.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Chain Clarification TUI Component\n *\n * Shows templates and resolved behaviors for each step in a chain.\n * Supports runtime editing of templates, output paths, reads lists, and progress toggle.\n */\n\nimport type { Theme } from \"@ashx-j/lunr-dev\";\nimport type { Component, TUI } from \"@ashx-j/lunr-tui\";\nimport { matchesKey, visibleWidth, truncateToWidth } from \"@ashx-j/lunr-tui\";\nimport type { ChildRuntimeConfig } from \"../../shared/types.ts\";\nimport type { ResolvedStepBehavior } from \"../../shared/settings.ts\";\nimport { resolveModelCandidate, splitThinkingSuffix } from \"../shared/model-fallback.ts\";\nimport { findModelInfo, getSupportedThinkingLevels, type ModelInfo, type ThinkingLevel } from \"../../shared/model-info.ts\";\n\ntype ClarifyMode = 'single' | 'parallel' | 'chain';\n\nexport interface BehaviorOverride {\n\toutput?: string | false;\n\treads?: string[] | false;\n\tprogress?: boolean;\n\tmodel?: string;\n\tskills?: string[] | false;\n}\n\nexport interface ChainClarifyResult {\n\tconfirmed: boolean;\n\ttemplates: string[];\n\tbehaviorOverrides: (BehaviorOverride | undefined)[];\n\trunInBackground?: boolean;\n}\n\ntype EditMode = \"template\" | \"output\" | \"reads\" | \"model\" | \"thinking\" | \"skills\";\n\n\ninterface TextEditorState {\n\tbuffer: string;\n\tcursor: number;\n\tviewportOffset: number;\n}\n\nfunction createEditorState(initial = \"\"): TextEditorState {\n\treturn { buffer: initial, cursor: 0, viewportOffset: 0 };\n}\n\nfunction wrapText(text: string, width: number): { lines: string[]; starts: number[] } {\n\tif (width <= 0) return { lines: [text], starts: [0] };\n\tif (text.length === 0) return { lines: [\"\"], starts: [0] };\n\n\tconst lines: string[] = [];\n\tconst starts: number[] = [];\n\tlet offset = 0;\n\tconst segments = text.split(\"\\n\");\n\tfor (const [index, segment] of segments.entries()) {\n\t\tif (segment.length === 0) {\n\t\t\tstarts.push(offset);\n\t\t\tlines.push(\"\");\n\t\t} else {\n\t\t\tlet lineStart = 0;\n\t\t\tlet pos = 0;\n\t\t\tlet lineWidth = 0;\n\t\t\twhile (pos < segment.length) {\n\t\t\t\tconst char = String.fromCodePoint(segment.codePointAt(pos)!);\n\t\t\t\tconst charWidth = visibleWidth(char);\n\t\t\t\tif (lineWidth > 0 && lineWidth + charWidth > width) {\n\t\t\t\t\tstarts.push(offset + lineStart);\n\t\t\t\t\tlines.push(segment.slice(lineStart, pos));\n\t\t\t\t\tlineStart = pos;\n\t\t\t\t\tlineWidth = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpos += char.length;\n\t\t\t\tlineWidth += charWidth;\n\t\t\t}\n\t\t\tstarts.push(offset + lineStart);\n\t\t\tlines.push(segment.slice(lineStart));\n\t\t}\n\t\toffset += segment.length + (index < segments.length - 1 ? 1 : 0);\n\t}\n\tif (!text.endsWith(\"\\n\") && text.length > 0 && visibleWidth(lines[lines.length - 1] ?? \"\") === width) {\n\t\tstarts.push(text.length);\n\t\tlines.push(\"\");\n\t}\n\treturn { lines, starts };\n}\n\nfunction getCursorDisplayPos(cursor: number, starts: number[]): { line: number; col: number } {\n\tfor (let i = starts.length - 1; i >= 0; i--) {\n\t\tif (cursor >= starts[i]!) return { line: i, col: cursor - starts[i]! };\n\t}\n\treturn { line: 0, col: 0 };\n}\n\nfunction ensureCursorVisible(cursorLine: number, viewportHeight: number, currentOffset: number): number {\n\tif (cursorLine < currentOffset) return Math.max(0, cursorLine);\n\tif (cursorLine >= currentOffset + viewportHeight) return Math.max(0, cursorLine - viewportHeight + 1);\n\treturn Math.max(0, currentOffset);\n}\n\nfunction isWordChar(ch: string): boolean {\n\tconst code = ch.charCodeAt(0);\n\treturn (code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122) || code === 95;\n}\n\nfunction wordBackward(buffer: string, cursor: number): number {\n\tlet pos = cursor;\n\twhile (pos > 0 && !isWordChar(buffer[pos - 1]!)) pos--;\n\twhile (pos > 0 && isWordChar(buffer[pos - 1]!)) pos--;\n\treturn pos;\n}\n\nfunction wordForward(buffer: string, cursor: number): number {\n\tlet pos = cursor;\n\twhile (pos < buffer.length && isWordChar(buffer[pos]!)) pos++;\n\twhile (pos < buffer.length && !isWordChar(buffer[pos]!)) pos++;\n\treturn pos;\n}\n\nfunction normalizeInsertText(data: string): string | null {\n\tlet text = data.split(\"\\x1b[200~\").join(\"\").split(\"\\x1b[201~\").join(\"\");\n\ttext = text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\tconst newline = text.indexOf(\"\\n\");\n\tif (newline !== -1) text = text.slice(0, newline);\n\ttext = text.replace(/\\t/g, \" \");\n\tif (text.length === 0) return null;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text.charCodeAt(i) < 32) return null;\n\t}\n\treturn text;\n}\n\nfunction handleEditorInput(state: TextEditorState, data: string, textWidth: number): TextEditorState | null {\n\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\") || matchesKey(data, \"return\")) return null;\n\n\tconst { lines: wrapped, starts } = wrapText(state.buffer, textWidth);\n\tconst cursorPos = getCursorDisplayPos(state.cursor, starts);\n\n\tif (matchesKey(data, \"alt+left\") || matchesKey(data, \"ctrl+left\")) return { ...state, cursor: wordBackward(state.buffer, state.cursor) };\n\tif (matchesKey(data, \"alt+right\") || matchesKey(data, \"ctrl+right\")) return { ...state, cursor: wordForward(state.buffer, state.cursor) };\n\tif (matchesKey(data, \"left\")) return state.cursor > 0 ? { ...state, cursor: state.cursor - 1 } : state;\n\tif (matchesKey(data, \"right\")) return state.cursor < state.buffer.length ? { ...state, cursor: state.cursor + 1 } : state;\n\tif (matchesKey(data, \"up\") && cursorPos.line > 0) {\n\t\tconst targetLine = cursorPos.line - 1;\n\t\treturn { ...state, cursor: starts[targetLine]! + Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0) };\n\t}\n\tif (matchesKey(data, \"down\") && cursorPos.line < wrapped.length - 1) {\n\t\tconst targetLine = cursorPos.line + 1;\n\t\treturn { ...state, cursor: starts[targetLine]! + Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0) };\n\t}\n\tif (matchesKey(data, \"home\")) return { ...state, cursor: starts[cursorPos.line]! };\n\tif (matchesKey(data, \"end\")) return { ...state, cursor: starts[cursorPos.line]! + (wrapped[cursorPos.line]?.length ?? 0) };\n\tif (matchesKey(data, \"ctrl+home\")) return { ...state, cursor: 0 };\n\tif (matchesKey(data, \"ctrl+end\")) return { ...state, cursor: state.buffer.length };\n\tif (matchesKey(data, \"alt+backspace\")) {\n\t\tconst target = wordBackward(state.buffer, state.cursor);\n\t\treturn target === state.cursor ? state : { ...state, buffer: state.buffer.slice(0, target) + state.buffer.slice(state.cursor), cursor: target };\n\t}\n\tif (matchesKey(data, \"backspace\")) {\n\t\treturn state.cursor > 0\n\t\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor - 1) + state.buffer.slice(state.cursor), cursor: state.cursor - 1 }\n\t\t\t: state;\n\t}\n\tif (matchesKey(data, \"delete\")) {\n\t\treturn state.cursor < state.buffer.length\n\t\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor) + state.buffer.slice(state.cursor + 1) }\n\t\t\t: state;\n\t}\n\n\tconst insert = normalizeInsertText(data);\n\treturn insert\n\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor) + insert + state.buffer.slice(state.cursor), cursor: state.cursor + insert.length }\n\t\t: null;\n}\n\nfunction renderWithCursor(text: string, cursorPos: number): string {\n\tconst before = text.slice(0, cursorPos);\n\tconst cursorChar = text[cursorPos] ?? \" \";\n\tconst after = text.slice(cursorPos + 1);\n\treturn `${before}\\x1b[7m${cursorChar}\\x1b[27m${after}`;\n}\n\nfunction renderEditor(state: TextEditorState, width: number, viewportHeight: number): string[] {\n\tconst { lines: wrapped, starts } = wrapText(state.buffer, width);\n\tconst cursorPos = getCursorDisplayPos(state.cursor, starts);\n\tconst lines: string[] = [];\n\tfor (let i = 0; i < viewportHeight; i++) {\n\t\tconst lineIdx = state.viewportOffset + i;\n\t\tlet content = lineIdx < wrapped.length ? wrapped[lineIdx] ?? \"\" : \"\";\n\t\tif (lineIdx === cursorPos.line) content = renderWithCursor(content, cursorPos.col);\n\t\tlines.push(content);\n\t}\n\treturn lines;\n}\n\n/**\n * TUI component for chain clarification.\n * Factory signature matches ctx.ui.custom: (tui, theme, kb, done) => Component\n */\nexport class ChainClarifyComponent implements Component {\n\treadonly width = 84;\n\n\tprivate selectedStep = 0;\n\tprivate editingStep: number | null = null;\n\tprivate editMode: EditMode = \"template\";\n\tprivate editState: TextEditorState = createEditorState();\n\n\tprivate readonly EDIT_VIEWPORT_HEIGHT = 12;\n\tprivate behaviorOverrides: Map<number, BehaviorOverride> = new Map();\n\tprivate modelSearchQuery: string = \"\";\n\tprivate modelSelectedIndex: number = 0;\n\tprivate filteredModels: ModelInfo[] = [];\n\tprivate readonly MODEL_SELECTOR_HEIGHT = 10;\n\tprivate thinkingSelectedIndex: number = 0;\n\tprivate skillSearchQuery: string = \"\";\n\tprivate skillSelectedNames: Set<string> = new Set();\n\tprivate skillCursorIndex: number = 0;\n\tprivate filteredSkills: Array<{ name: string; source: string; description?: string }> = [];\n\tprivate noticeMessage: { text: string; type: \"info\" | \"error\" } | null = null;\n\tprivate noticeMessageTimer: ReturnType<typeof setTimeout> | null = null;\n\t/** Run in background (async) mode */\n\tprivate runInBackground = false;\n\tprivate tui: TUI;\n\tprivate theme: Theme;\n\tprivate agentConfigs: ChildRuntimeConfig[];\n\tprivate templates: string[];\n\tprivate originalTask: string;\n\tprivate chainDir: string | undefined;\n\tprivate resolvedBehaviors: ResolvedStepBehavior[];\n\tprivate availableModels: ModelInfo[];\n\tprivate preferredProvider: string | undefined;\n\tprivate availableSkills: Array<{ name: string; source: string; description?: string }>;\n\tprivate done: (result: ChainClarifyResult) => void;\n\tprivate mode: ClarifyMode;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tagentConfigs: ChildRuntimeConfig[],\n\t\ttemplates: string[],\n\t\toriginalTask: string,\n\t\tchainDir: string | undefined,\n\t\tresolvedBehaviors: ResolvedStepBehavior[],\n\t\tavailableModels: ModelInfo[],\n\t\tpreferredProvider: string | undefined,\n\t\tavailableSkills: Array<{ name: string; source: string; description?: string }>,\n\t\tdone: (result: ChainClarifyResult) => void,\n\t\tmode: ClarifyMode = 'chain',\n\t) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.agentConfigs = agentConfigs;\n\t\tthis.templates = templates;\n\t\tthis.originalTask = originalTask;\n\t\tthis.chainDir = chainDir;\n\t\tthis.resolvedBehaviors = resolvedBehaviors;\n\t\tthis.availableModels = availableModels;\n\t\tthis.preferredProvider = preferredProvider;\n\t\tthis.availableSkills = availableSkills;\n\t\tthis.done = done;\n\t\tthis.mode = mode;\n\t\tthis.filteredModels = [...availableModels];\n\t\tthis.filteredSkills = [...availableSkills];\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Helper methods for rendering\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Pad string to specified visible width */\n\tprivate pad(s: string, len: number): string {\n\t\tconst vis = visibleWidth(s);\n\t\treturn s + \" \".repeat(Math.max(0, len - vis));\n\t}\n\n\t/** Create a row with border characters */\n\tprivate row(content: string): string {\n\t\tconst innerW = this.width - 2;\n\t\treturn this.theme.fg(\"border\", \"│\") + this.pad(content, innerW) + this.theme.fg(\"border\", \"│\");\n\t}\n\n\t/** Render centered header line with border */\n\tprivate renderHeader(text: string): string {\n\t\tconst innerW = this.width - 2;\n\t\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\t\tconst padLeft = Math.floor(padLen / 2);\n\t\tconst padRight = padLen - padLeft;\n\t\treturn (\n\t\t\tthis.theme.fg(\"border\", \"╭\" + \"─\".repeat(padLeft)) +\n\t\t\tthis.theme.fg(\"accent\", text) +\n\t\t\tthis.theme.fg(\"border\", \"─\".repeat(padRight) + \"╮\")\n\t\t);\n\t}\n\n\t/** Render centered footer line with border */\n\tprivate renderFooter(text: string): string {\n\t\tconst innerW = this.width - 2;\n\t\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\t\tconst padLeft = Math.floor(padLen / 2);\n\t\tconst padRight = padLen - padLeft;\n\t\treturn (\n\t\t\tthis.theme.fg(\"border\", \"╰\" + \"─\".repeat(padLeft)) +\n\t\t\tthis.theme.fg(\"dim\", text) +\n\t\t\tthis.theme.fg(\"border\", \"─\".repeat(padRight) + \"╯\")\n\t\t);\n\t}\n\n\t/** Exit edit mode and reset state */\n\tprivate exitEditMode(): void {\n\t\tthis.editingStep = null;\n\t\tthis.editState = createEditorState();\n\t\tthis.tui.requestRender();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Full edit mode methods\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Render the full-edit takeover view */\n\tprivate renderFullEditMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst textWidth = innerW - 2; // 1 char padding on each side\n\t\tconst lines: string[] = [];\n\n\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\tthis.editState = {\n\t\t\t...this.editState,\n\t\t\tviewportOffset: ensureCursorVisible(\n\t\t\t\tcursorPos.line,\n\t\t\t\tthis.EDIT_VIEWPORT_HEIGHT,\n\t\t\t\tthis.editState.viewportOffset,\n\t\t\t),\n\t\t};\n\n\t\t// Header (truncate agent name to prevent overflow)\n\t\tconst fieldName = this.editMode === \"template\" ? \"task\" : this.editMode;\n\t\tconst rawAgentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst maxAgentLen = innerW - 30; // Reserve space for \" Editing X (Step/Task N: ) \"\n\t\tconst agentName = rawAgentName.length > maxAgentLen\n\t\t\t? rawAgentName.slice(0, maxAgentLen - 1) + \"…\"\n\t\t\t: rawAgentName;\n\t\t// Use mode-appropriate terminology\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Editing ${fieldName} (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst editorLines = renderEditor(this.editState, textWidth, this.EDIT_VIEWPORT_HEIGHT);\n\t\tfor (const line of editorLines) {\n\t\t\tlines.push(this.row(` ${line}`));\n\t\t}\n\n\t\tconst linesBelow = wrapped.length - this.editState.viewportOffset - this.EDIT_VIEWPORT_HEIGHT;\n\t\tconst hasMore = linesBelow > 0;\n\t\tconst hasLess = this.editState.viewportOffset > 0;\n\t\tlet scrollInfo = \"\";\n\t\tif (hasLess) scrollInfo += \"↑\";\n\t\tif (hasMore) scrollInfo += `↓ ${linesBelow}+`;\n\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst footerText = scrollInfo\n\t\t\t? ` [Esc] Done • [Ctrl+C] Discard • ${scrollInfo} `\n\t\t\t: \" [Esc] Done • [Ctrl+C] Discard \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Behavior helpers\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Get effective behavior for a step (with user overrides applied) */\n\tprivate getEffectiveBehavior(stepIndex: number): ResolvedStepBehavior {\n\t\tconst base = this.resolvedBehaviors[stepIndex]!;\n\t\tconst override = this.behaviorOverrides.get(stepIndex);\n\t\tif (!override) return base;\n\n\t\treturn {\n\t\t\toutput: override.output !== undefined ? override.output : base.output,\n\t\t\toutputMode: base.outputMode,\n\t\t\treads: override.reads !== undefined ? override.reads : base.reads,\n\t\t\tprogress: override.progress !== undefined ? override.progress : base.progress,\n\t\t\tskills: override.skills !== undefined ? override.skills : base.skills,\n\t\t\tmodel: override.model !== undefined ? override.model : base.model,\n\t\t};\n\t}\n\n\t/** Get the effective model for a step (override or agent default) */\n\tprivate getEffectiveModel(stepIndex: number): string {\n\t\tconst override = this.behaviorOverrides.get(stepIndex);\n\t\tif (override?.model) return this.resolveModelFullId(override.model);\n\n\t\tconst baseModel = this.resolvedBehaviors[stepIndex]?.model;\n\t\tif (baseModel) return this.resolveModelFullId(baseModel);\n\t\treturn \"default\";\n\t}\n\n\t/** Resolve a model name to its full provider/model format */\n\tprivate resolveModelFullId(modelName: string): string {\n\t\treturn resolveModelCandidate(modelName, this.availableModels, this.preferredProvider) ?? modelName;\n\t}\n\n\t/** Update a behavior override for a step */\n\tprivate updateBehavior(stepIndex: number, field: keyof BehaviorOverride, value: string | boolean | string[] | false): void {\n\t\tconst existing = this.behaviorOverrides.get(stepIndex) ?? {};\n\t\tthis.behaviorOverrides.set(stepIndex, { ...existing, [field]: value });\n\t}\n\n\tprivate showNotice(text: string, type: \"info\" | \"error\"): void {\n\t\tthis.noticeMessage = { text, type };\n\t\tif (this.noticeMessageTimer) clearTimeout(this.noticeMessageTimer);\n\t\tthis.noticeMessageTimer = setTimeout(() => {\n\t\t\tthis.noticeMessage = null;\n\t\t\tthis.noticeMessageTimer = null;\n\t\t\tthis.tui.requestRender();\n\t\t}, 2000);\n\t\tthis.tui.requestRender();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.editingStep !== null) {\n\t\t\tif (this.editMode === \"model\") {\n\t\t\t\tthis.handleModelSelectorInput(data);\n\t\t\t} else if (this.editMode === \"thinking\") {\n\t\t\t\tthis.handleThinkingSelectorInput(data);\n\t\t\t} else if (this.editMode === \"skills\") {\n\t\t\t\tthis.handleSkillSelectorInput(data);\n\t\t\t} else {\n\t\t\t\tthis.handleEditInput(data);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.done({ confirmed: false, templates: [], behaviorOverrides: [] });\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst overrides: (BehaviorOverride | undefined)[] = [];\n\t\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\t\toverrides.push(this.behaviorOverrides.get(i));\n\t\t\t}\n\t\t\tthis.done({ confirmed: true, templates: this.templates, behaviorOverrides: overrides, runInBackground: this.runInBackground });\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.selectedStep = Math.max(0, this.selectedStep - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tconst maxStep = Math.max(0, this.agentConfigs.length - 1);\n\t\t\tthis.selectedStep = Math.min(maxStep, this.selectedStep + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"e\") {\n\t\t\tthis.enterEditMode(\"template\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"m\") {\n\t\t\tthis.enterModelSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"t\") {\n\t\t\tthis.enterThinkingSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"s\") {\n\t\t\tthis.editingStep = this.selectedStep;\n\t\t\tthis.editMode = \"skills\";\n\t\t\tthis.skillSearchQuery = \"\";\n\t\t\tthis.skillCursorIndex = 0;\n\t\t\tthis.filteredSkills = [...this.availableSkills];\n\t\t\tconst current = this.getEffectiveBehavior(this.selectedStep).skills;\n\t\t\tthis.skillSelectedNames.clear();\n\t\t\tif (current !== false && current.length > 0) {\n\t\t\t\tcurrent.forEach((skillName) => this.skillSelectedNames.add(skillName));\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"w\" && this.mode !== 'parallel') {\n\t\t\tthis.enterEditMode(\"output\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"r\" && this.mode === 'chain') {\n\t\t\tthis.enterEditMode(\"reads\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"p\" && this.mode === 'chain') {\n\t\t\tconst anyEnabled = this.agentConfigs.some((_, i) => this.getEffectiveBehavior(i).progress);\n\t\t\tconst newState = !anyEnabled;\n\t\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\t\tthis.updateBehavior(i, \"progress\", newState);\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"b\") {\n\t\t\tthis.runInBackground = !this.runInBackground;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t}\n\n\tprivate enterEditMode(mode: EditMode): void {\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = mode;\n\t\tlet buffer = \"\";\n\n\t\tif (mode === \"template\") {\n\t\t\tconst template = this.templates[this.selectedStep] ?? \"\";\n\t\t\tbuffer = template.split(\"\\n\")[0] ?? \"\";\n\t\t} else if (mode === \"output\") {\n\t\t\tconst behavior = this.getEffectiveBehavior(this.selectedStep);\n\t\t\tbuffer = behavior.output === false ? \"\" : (behavior.output || \"\");\n\t\t} else if (mode === \"reads\") {\n\t\t\tconst behavior = this.getEffectiveBehavior(this.selectedStep);\n\t\t\tbuffer = behavior.reads === false ? \"\" : (behavior.reads?.join(\", \") || \"\");\n\t\t}\n\n\t\tthis.editState = createEditorState(buffer);\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Enter model selector mode */\n\tprivate enterModelSelector(): void {\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = \"model\";\n\t\tthis.modelSearchQuery = \"\";\n\t\tthis.modelSelectedIndex = 0;\n\t\tthis.filteredModels = [...this.availableModels];\n\t\tconst currentModel = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep)).baseModel;\n\t\tconst currentIndex = this.filteredModels.findIndex((m) => m.fullId === currentModel || m.id === currentModel);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis.modelSelectedIndex = currentIndex;\n\t\t}\n\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Filter models based on search query */\n\tprivate filterModels(): void {\n\t\tconst query = this.modelSearchQuery.toLowerCase();\n\t\tif (!query) {\n\t\t\tthis.filteredModels = [...this.availableModels];\n\t\t} else {\n\t\t\tthis.filteredModels = this.availableModels.filter((m) =>\n\t\t\t\tm.fullId.toLowerCase().includes(query) ||\n\t\t\t\tm.id.toLowerCase().includes(query) ||\n\t\t\t\tm.provider.toLowerCase().includes(query)\n\t\t\t);\n\t\t}\n\t\tthis.modelSelectedIndex = Math.min(this.modelSelectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t}\n\n\tprivate handleModelSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selected = this.filteredModels[this.modelSelectedIndex];\n\t\t\tif (selected) {\n\t\t\t\tconst { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.editingStep!));\n\t\t\t\tconst requestedLevel = thinkingSuffix.slice(1);\n\t\t\t\tconst selectedModel = findModelInfo(selected.fullId, this.availableModels, this.preferredProvider);\n\t\t\t\tconst suffix = getSupportedThinkingLevels(selectedModel).some((level) => level === requestedLevel) ? thinkingSuffix : \"\";\n\t\t\t\tthis.updateBehavior(this.editingStep!, \"model\", `${selected.fullId}${suffix}`);\n\t\t\t}\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tif (this.filteredModels.length > 0) {\n\t\t\t\tthis.modelSelectedIndex = this.modelSelectedIndex === 0\n\t\t\t\t\t? this.filteredModels.length - 1\n\t\t\t\t\t: this.modelSelectedIndex - 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tif (this.filteredModels.length > 0) {\n\t\t\t\tthis.modelSelectedIndex = this.modelSelectedIndex === this.filteredModels.length - 1\n\t\t\t\t\t? 0\n\t\t\t\t\t: this.modelSelectedIndex + 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"backspace\")) {\n\t\t\tif (this.modelSearchQuery.length > 0) {\n\t\t\t\tthis.modelSearchQuery = this.modelSearchQuery.slice(0, -1);\n\t\t\t\tthis.filterModels();\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.length === 1 && data.charCodeAt(0) >= 32) {\n\t\t\tthis.modelSearchQuery += data;\n\t\t\tthis.filterModels();\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate getAvailableThinkingLevels(stepIndex: number): ThinkingLevel[] {\n\t\treturn getSupportedThinkingLevels(findModelInfo(this.getEffectiveModel(stepIndex), this.availableModels, this.preferredProvider));\n\t}\n\n\t/** Enter thinking level selector mode */\n\tprivate enterThinkingSelector(): void {\n\t\tif (!this.getEffectiveBehavior(this.selectedStep).model) {\n\t\t\tthis.showNotice(\"Select a model first\", \"error\");\n\t\t\treturn;\n\t\t}\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = \"thinking\";\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.selectedStep);\n\t\tconst { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep));\n\t\tconst suffix = thinkingSuffix.slice(1);\n\t\tconst levelIdx = levels.findIndex((level) => level === suffix);\n\t\tthis.thinkingSelectedIndex = levelIdx >= 0 ? levelIdx : Math.max(0, levels.indexOf(\"off\"));\n\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate handleThinkingSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.editingStep!);\n\t\tif (levels.length === 0) return;\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selectedLevel = levels[this.thinkingSelectedIndex] ?? \"off\";\n\t\t\tthis.applyThinkingLevel(selectedLevel);\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.thinkingSelectedIndex = this.thinkingSelectedIndex === 0\n\t\t\t\t? levels.length - 1\n\t\t\t\t: this.thinkingSelectedIndex - 1;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tthis.thinkingSelectedIndex = this.thinkingSelectedIndex === levels.length - 1\n\t\t\t\t? 0\n\t\t\t\t: this.thinkingSelectedIndex + 1;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** Apply thinking level to the current step's model */\n\tprivate applyThinkingLevel(level: ThinkingLevel): void {\n\t\tconst stepIndex = this.editingStep!;\n\t\tconst currentModel = this.getEffectiveBehavior(stepIndex).model;\n\t\tif (!currentModel) return;\n\n\t\tconst { baseModel } = splitThinkingSuffix(currentModel);\n\t\tconst newModel = level === \"off\" ? baseModel : `${baseModel}:${level}`;\n\t\tthis.updateBehavior(stepIndex, \"model\", newModel);\n\t}\n\n\tprivate filterSkills(): void {\n\t\tconst query = this.skillSearchQuery.toLowerCase();\n\t\tif (!query) {\n\t\t\tthis.filteredSkills = [...this.availableSkills];\n\t\t} else {\n\t\t\tthis.filteredSkills = this.availableSkills.filter((s) =>\n\t\t\t\ts.name.toLowerCase().includes(query) ||\n\t\t\t\t(s.description?.toLowerCase().includes(query) ?? false),\n\t\t\t);\n\t\t}\n\t\tthis.skillCursorIndex = Math.min(this.skillCursorIndex, Math.max(0, this.filteredSkills.length - 1));\n\t}\n\n\tprivate handleSkillSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selected = [...this.skillSelectedNames];\n\t\t\tthis.updateBehavior(this.editingStep!, \"skills\", selected);\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \" \") {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tconst skill = this.filteredSkills[this.skillCursorIndex];\n\t\t\t\tif (skill) {\n\t\t\t\t\tif (this.skillSelectedNames.has(skill.name)) {\n\t\t\t\t\t\tthis.skillSelectedNames.delete(skill.name);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.skillSelectedNames.add(skill.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tthis.skillCursorIndex = this.skillCursorIndex === 0\n\t\t\t\t\t? this.filteredSkills.length - 1\n\t\t\t\t\t: this.skillCursorIndex - 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tthis.skillCursorIndex = this.skillCursorIndex === this.filteredSkills.length - 1\n\t\t\t\t\t? 0\n\t\t\t\t\t: this.skillCursorIndex + 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"backspace\")) {\n\t\t\tif (this.skillSearchQuery.length > 0) {\n\t\t\t\tthis.skillSearchQuery = this.skillSearchQuery.slice(0, -1);\n\t\t\t\tthis.filterSkills();\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.length === 1 && data.charCodeAt(0) >= 32) {\n\t\t\tthis.skillSearchQuery += data;\n\t\t\tthis.filterSkills();\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate handleEditInput(data: string): void {\n\t\tconst textWidth = this.width - 4; // Must match render: innerW - 2 = (width - 2) - 2\n\t\tif (matchesKey(data, \"shift+up\") || matchesKey(data, \"pageup\")) {\n\t\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\t\tconst targetLine = Math.max(0, cursorPos.line - this.EDIT_VIEWPORT_HEIGHT);\n\t\t\tconst targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);\n\t\t\tthis.editState = { ...this.editState, cursor: starts[targetLine] + targetCol };\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"shift+down\") || matchesKey(data, \"pagedown\")) {\n\t\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\t\tconst targetLine = Math.min(wrapped.length - 1, cursorPos.line + this.EDIT_VIEWPORT_HEIGHT);\n\t\t\tconst targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);\n\t\t\tthis.editState = { ...this.editState, cursor: starts[targetLine] + targetCol };\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"tab\")) return;\n\n\t\tconst nextState = handleEditorInput(this.editState, data, textWidth);\n\t\tif (nextState) {\n\t\t\tthis.editState = nextState;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"escape\")) {\n\t\t\tthis.saveEdit();\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate saveEdit(): void {\n\t\tconst stepIndex = this.editingStep!;\n\n\t\tif (this.editMode === \"template\") {\n\t\t\t// For template, preserve other lines if they existed\n\t\t\tconst original = this.templates[stepIndex] ?? \"\";\n\t\t\tconst originalLines = original.split(\"\\n\");\n\t\t\toriginalLines[0] = this.editState.buffer;\n\t\t\tthis.templates[stepIndex] = originalLines.join(\"\\n\");\n\t\t} else if (this.editMode === \"output\") {\n\t\t\t// Capture OLD output before updating (for downstream propagation)\n\t\t\tconst oldBehavior = this.getEffectiveBehavior(stepIndex);\n\t\t\tconst oldOutput = typeof oldBehavior.output === \"string\" ? oldBehavior.output : null;\n\n\t\t\t// Empty string or whitespace means disable output\n\t\t\tconst trimmed = this.editState.buffer.trim();\n\t\t\tconst newOutput = trimmed === \"\" ? false : trimmed;\n\t\t\tthis.updateBehavior(stepIndex, \"output\", newOutput);\n\n\t\t\t// Propagate output filename change to downstream steps' reads\n\t\t\tif (oldOutput && typeof newOutput === \"string\" && oldOutput !== newOutput) {\n\t\t\t\tthis.propagateOutputChange(stepIndex, oldOutput, newOutput);\n\t\t\t}\n\t\t} else if (this.editMode === \"reads\") {\n\t\t\t// Parse comma-separated list, empty means disable reads\n\t\t\tconst trimmed = this.editState.buffer.trim();\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tthis.updateBehavior(stepIndex, \"reads\", false);\n\t\t\t} else {\n\t\t\t\tconst files = trimmed.split(\",\").map(f => f.trim()).filter(f => f !== \"\");\n\t\t\t\tthis.updateBehavior(stepIndex, \"reads\", files.length > 0 ? files : false);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * When a step's output filename changes, update downstream steps that read from it.\n\t * This maintains the chain dependency automatically.\n\t */\n\tprivate propagateOutputChange(changedStepIndex: number, oldOutput: string, newOutput: string): void {\n\t\t// Check all downstream steps (steps that come after the changed step)\n\t\tfor (let i = changedStepIndex + 1; i < this.agentConfigs.length; i++) {\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\t\t\t\n\t\t\t// Skip if reads is disabled or empty\n\t\t\tif (behavior.reads === false || !behavior.reads || behavior.reads.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if this step reads the old output file\n\t\t\tconst readsArray = behavior.reads;\n\t\t\tconst oldIndex = readsArray.indexOf(oldOutput);\n\t\t\t\n\t\t\tif (oldIndex !== -1) {\n\t\t\t\t// Replace old filename with new filename in reads\n\t\t\t\tconst newReads = [...readsArray];\n\t\t\t\tnewReads[oldIndex] = newOutput;\n\t\t\t\tthis.updateBehavior(i, \"reads\", newReads);\n\t\t\t}\n\t\t}\n\t}\n\n\trender(_width: number): string[] {\n\t\tif (this.editingStep !== null) {\n\t\t\tif (this.editMode === \"model\") {\n\t\t\t\treturn this.renderModelSelector();\n\t\t\t}\n\t\t\tif (this.editMode === \"thinking\") {\n\t\t\t\treturn this.renderThinkingSelector();\n\t\t\t}\n\t\t\tif (this.editMode === \"skills\") {\n\t\t\t\treturn this.renderSkillSelector();\n\t\t\t}\n\t\t\treturn this.renderFullEditMode();\n\t\t}\n\t\t// Mode-based navigation rendering\n\t\tswitch (this.mode) {\n\t\t\tcase 'single': return this.renderSingleMode();\n\t\t\tcase 'parallel': return this.renderParallelMode();\n\t\t\tcase 'chain': return this.renderChainMode();\n\t\t}\n\t}\n\n\t/** Render the model selector view */\n\tprivate renderModelSelector(): string[] {\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\t// Header (mode-aware terminology)\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Select Model (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst searchPrefix = th.fg(\"dim\", \"Search: \");\n\t\tconst cursor = \"\\x1b[7m \\x1b[27m\"; // Reverse video space for cursor\n\t\tconst searchDisplay = this.modelSearchQuery + cursor;\n\t\tlines.push(this.row(` ${searchPrefix}${searchDisplay}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst currentModel = this.getEffectiveModel(this.editingStep!);\n\t\tconst currentModelBase = splitThinkingSuffix(currentModel).baseModel;\n\t\tconst currentLabel = th.fg(\"dim\", \"Current: \");\n\t\tlines.push(this.row(` ${currentLabel}${th.fg(\"warning\", currentModel)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tif (this.filteredModels.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No matching models\")}`));\n\t\t} else {\n\t\t\tconst maxVisible = this.MODEL_SELECTOR_HEIGHT;\n\t\t\tlet startIdx = 0;\n\n\t\t\tif (this.filteredModels.length > maxVisible) {\n\t\t\t\tstartIdx = Math.max(0, this.modelSelectedIndex - Math.floor(maxVisible / 2));\n\t\t\t\tstartIdx = Math.min(startIdx, this.filteredModels.length - maxVisible);\n\t\t\t}\n\n\t\t\tconst endIdx = Math.min(startIdx + maxVisible, this.filteredModels.length);\n\n\t\t\tif (startIdx > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↑ ${startIdx} more`)}`));\n\t\t\t}\n\n\t\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\t\tconst model = this.filteredModels[i]!;\n\t\t\t\tconst isSelected = i === this.modelSelectedIndex;\n\t\t\t\tconst isCurrent = model.fullId === currentModelBase || model.id === currentModelBase;\n\t\t\t\tconst prefix = isSelected ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst modelText = isSelected ? th.fg(\"accent\", model.id) : model.id;\n\t\t\t\tconst providerBadge = th.fg(\"dim\", ` [${model.provider}]`);\n\t\t\t\tconst currentBadge = isCurrent ? th.fg(\"success\", \" current\") : \"\";\n\n\t\t\t\tlines.push(this.row(` ${prefix}${modelText}${providerBadge}${currentBadge}`));\n\t\t\t}\n\n\t\t\tconst remaining = this.filteredModels.length - endIdx;\n\t\t\tif (remaining > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↓ ${remaining} more`)}`));\n\t\t\t}\n\t\t}\n\n\t\tconst contentLines = lines.length;\n\t\tconst targetHeight = 18;\n\t\tfor (let i = contentLines; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tconst footerText = \" [Enter] Select • [Esc] Cancel • Type to search \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\t/** Render the thinking level selector view */\n\tprivate renderThinkingSelector(): string[] {\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Thinking Level (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst currentModel = this.getEffectiveModel(this.editingStep!);\n\t\tconst currentLabel = th.fg(\"dim\", \"Model: \");\n\t\tlines.push(this.row(` ${currentLabel}${th.fg(\"accent\", currentModel)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Select thinking level (extended thinking budget):\")}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst levelDescriptions: Record<ThinkingLevel, string> = {\n\t\t\t\"off\": \"No extended thinking\",\n\t\t\t\"minimal\": \"Brief reasoning\",\n\t\t\t\"low\": \"Light reasoning\",\n\t\t\t\"medium\": \"Moderate reasoning\",\n\t\t\t\"high\": \"Deep reasoning\",\n\t\t\t\"xhigh\": \"Maximum reasoning (ultrathink)\",\n\t\t\t\"max\": \"Maximum available reasoning\",\n\t\t};\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.editingStep!);\n\t\tif (levels.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No supported thinking levels\")}`));\n\t\t} else {\n\t\t\tfor (let i = 0; i < levels.length; i++) {\n\t\t\t\tconst level = levels[i]!;\n\t\t\t\tconst isSelected = i === this.thinkingSelectedIndex;\n\t\t\t\tconst prefix = isSelected ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst levelText = isSelected ? th.fg(\"accent\", level) : level;\n\t\t\t\tconst desc = th.fg(\"dim\", ` - ${levelDescriptions[level]}`);\n\t\t\t\tlines.push(this.row(` ${prefix}${levelText}${desc}`));\n\t\t\t}\n\t\t}\n\n\t\tconst contentLines = lines.length;\n\t\tconst targetHeight = 16;\n\t\tfor (let i = contentLines; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tconst footerText = levels.length === 0\n\t\t\t? \" [Esc] Cancel \"\n\t\t\t: \" [Enter] Select • [Esc] Cancel • ↑↓ Navigate \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderSkillSelector(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single'\n\t\t\t? agentName\n\t\t\t: this.mode === 'parallel'\n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}`\n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tlines.push(this.renderHeader(` Select Skills (${stepLabel}) `));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst cursor = \"\\x1b[7m \\x1b[27m\";\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Search: \")}${this.skillSearchQuery}${cursor}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst selected = [...this.skillSelectedNames].join(\", \") || th.fg(\"dim\", \"(none)\");\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Selected: \")}${truncateToWidth(selected, innerW - 12)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst selectorHeight = 10;\n\t\tif (this.filteredSkills.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No matching skills\")}`));\n\t\t} else {\n\t\t\tlet startIdx = 0;\n\t\t\tif (this.filteredSkills.length > selectorHeight) {\n\t\t\t\tstartIdx = Math.max(0, this.skillCursorIndex - Math.floor(selectorHeight / 2));\n\t\t\t\tstartIdx = Math.min(startIdx, this.filteredSkills.length - selectorHeight);\n\t\t\t}\n\t\t\tconst endIdx = Math.min(startIdx + selectorHeight, this.filteredSkills.length);\n\n\t\t\tif (startIdx > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↑ ${startIdx} more`)}`));\n\t\t\t}\n\n\t\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\t\tconst skill = this.filteredSkills[i]!;\n\t\t\t\tconst isCursor = i === this.skillCursorIndex;\n\t\t\t\tconst isSelected = this.skillSelectedNames.has(skill.name);\n\n\t\t\t\tconst prefix = isCursor ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst checkbox = isSelected ? th.fg(\"success\", \"[x]\") : \"[ ]\";\n\t\t\t\tconst nameText = isCursor ? th.fg(\"accent\", skill.name) : skill.name;\n\t\t\t\tconst sourceBadge = th.fg(\"dim\", ` [${skill.source}]`);\n\t\t\t\tconst desc = skill.description\n\t\t\t\t\t? th.fg(\"dim\", ` - ${truncateToWidth(skill.description, 25)}`)\n\t\t\t\t\t: \"\";\n\n\t\t\t\tlines.push(this.row(` ${prefix}${checkbox} ${nameText}${sourceBadge}${desc}`));\n\t\t\t}\n\n\t\t\tconst remaining = this.filteredSkills.length - endIdx;\n\t\t\tif (remaining > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↓ ${remaining} more`)}`));\n\t\t\t}\n\t\t}\n\n\t\tconst targetHeight = 18;\n\t\tfor (let i = lines.length; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tlines.push(this.renderFooter(\" [Enter] Confirm • [Space] Toggle • [Esc] Cancel \"));\n\t\treturn lines;\n\t}\n\n\tprivate getShortcutHelpText(): string {\n\t\tconst th = this.theme;\n\t\tconst shortcut = (key: string, label: string) =>\n\t\t\tth.fg(\"accent\", `[${key}]`) + th.fg(\"dim\", label);\n\t\tconst backgroundState = this.runInBackground ? \"ON\" : \"OFF\";\n\t\tconst background = shortcut(\"b\", `Background:${backgroundState}`);\n\n\t\tswitch (this.mode) {\n\t\t\tcase 'single':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"m\", \"Model\")} ${shortcut(\"t\", \"Think\")} ${shortcut(\"w\", \"Output\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t\tcase 'parallel':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"m\", \"Model\")} ${shortcut(\"t\", \"Think\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t\tcase 'chain':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"m\", \"Model\")} ${shortcut(\"t\", \"Think\")} ${shortcut(\"w\", \"Output\")} ${shortcut(\"r\", \"Reads\")} ${shortcut(\"p\", \"Prog\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t}\n\t}\n\n\tprivate getFooterText(): string {\n\t\treturn this.mode === 'single'\n\t\t\t? \" [Enter] Run • [Esc] Cancel \"\n\t\t\t: \" [Enter] Run • [Esc] Cancel • [↑↓] Navigate \";\n\t}\n\n\tprivate appendNotice(lines: string[]): void {\n\t\tif (!this.noticeMessage) return;\n\t\tconst color = this.noticeMessage.type === \"error\" ? \"error\" : \"success\";\n\t\tlines.push(this.row(` ${this.theme.fg(color, this.noticeMessage.text)}`));\n\t}\n\n\tprivate renderSingleMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[0]?.name ?? \"unknown\";\n\t\tconst maxHeaderLen = innerW - 4;\n\t\tconst headerText = ` Agent: ${truncateToWidth(agentName, maxHeaderLen - 9)} `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst config = this.agentConfigs[0]!;\n\t\tconst behavior = this.getEffectiveBehavior(0);\n\n\t\tconst stepLabel = config.name;\n\t\tlines.push(this.row(` ${th.fg(\"accent\", \"▶ \" + stepLabel)}`));\n\n\t\tconst template = (this.templates[0] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\tconst taskLabel = th.fg(\"dim\", \"task: \");\n\t\tlines.push(this.row(` ${taskLabel}${truncateToWidth(template, innerW - 12)}`));\n\n\t\tconst effectiveModel = this.getEffectiveModel(0);\n\t\tconst override = this.behaviorOverrides.get(0);\n\t\tconst isOverridden = override?.model !== undefined;\n\t\tconst modelValue = isOverridden\n\t\t\t? th.fg(\"warning\", effectiveModel) + th.fg(\"dim\", \" ✎\")\n\t\t\t: effectiveModel;\n\t\tconst modelLabel = th.fg(\"dim\", \"model: \");\n\t\tlines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));\n\n\t\tconst writesValue = behavior.output === false\n\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t: (behavior.output || th.fg(\"dim\", \"(none)\"));\n\t\tconst writesLabel = th.fg(\"dim\", \"writes: \");\n\t\tlines.push(this.row(` ${writesLabel}${truncateToWidth(writesValue, innerW - 14)}`));\n\n\t\tconst skillsValue = behavior.skills === false\n\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderParallelMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst headerText = ` Parallel Tasks (${this.agentConfigs.length}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\tconst config = this.agentConfigs[i]!;\n\t\t\tconst isSelected = i === this.selectedStep;\n\n\t\t\tconst color = isSelected ? \"accent\" : \"dim\";\n\t\t\tconst prefix = isSelected ? \"▶ \" : \" \";\n\t\t\tconst taskPrefix = `Task ${i + 1}: `;\n\t\t\tconst maxNameLen = innerW - 4 - prefix.length - taskPrefix.length;\n\t\t\tconst agentName = config.name.length > maxNameLen\n\t\t\t\t? config.name.slice(0, maxNameLen - 1) + \"…\"\n\t\t\t\t: config.name;\n\t\t\tconst taskLabel = `${taskPrefix}${agentName}`;\n\t\t\tlines.push(this.row(` ${th.fg(color, prefix + taskLabel)}`));\n\n\t\t\tconst template = (this.templates[i] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\t\tconst taskTextLabel = th.fg(\"dim\", \"task: \");\n\t\t\tlines.push(this.row(` ${taskTextLabel}${truncateToWidth(template, innerW - 12)}`));\n\n\t\t\tconst effectiveModel = this.getEffectiveModel(i);\n\t\t\tconst override = this.behaviorOverrides.get(i);\n\t\t\tconst isOverridden = override?.model !== undefined;\n\t\t\tconst modelValue = isOverridden\n\t\t\t\t? th.fg(\"warning\", effectiveModel) + th.fg(\"dim\", \" ✎\")\n\t\t\t\t: effectiveModel;\n\t\t\tconst modelLabel = th.fg(\"dim\", \"model: \");\n\t\t\tlines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));\n\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\t\t\tconst skillsValue = behavior.skills === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tif (this.agentConfigs.length > 0) lines.pop();\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderChainMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst chainLabel = this.agentConfigs.map((c) => c.name).join(\" → \");\n\t\tconst maxHeaderLen = innerW - 4;\n\t\tconst headerText = ` Chain: ${truncateToWidth(chainLabel, maxHeaderLen - 9)} `;\n\t\tlines.push(this.renderHeader(headerText));\n\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst taskPreview = truncateToWidth(this.originalTask, innerW - 16);\n\t\tlines.push(this.row(` Original Task: ${taskPreview}`));\n\t\tconst chainDirPreview = truncateToWidth(this.chainDir ?? \"\", innerW - 12);\n\t\tlines.push(this.row(` Chain Dir: ${th.fg(\"dim\", chainDirPreview)}`));\n\n\t\tconst progressEnabled = this.agentConfigs.some((_, i) => this.getEffectiveBehavior(i).progress);\n\t\tconst progressValue = progressEnabled ? th.fg(\"success\", \"enabled\") : th.fg(\"dim\", \"disabled\");\n\t\tlines.push(this.row(` Progress: ${progressValue} ${th.fg(\"dim\", \"(press [p] to toggle)\")}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\tconst config = this.agentConfigs[i]!;\n\t\t\tconst isSelected = i === this.selectedStep;\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\n\t\t\tconst color = isSelected ? \"accent\" : \"dim\";\n\t\t\tconst prefix = isSelected ? \"▶ \" : \" \";\n\t\t\tconst stepPrefix = `Step ${i + 1}: `;\n\t\t\tconst maxNameLen = innerW - 4 - prefix.length - stepPrefix.length;\n\t\t\tconst agentName = config.name.length > maxNameLen\n\t\t\t\t? config.name.slice(0, maxNameLen - 1) + \"…\"\n\t\t\t\t: config.name;\n\t\t\tconst stepLabel = `${stepPrefix}${agentName}`;\n\t\t\tlines.push(\n\t\t\t\tthis.row(` ${th.fg(color, prefix + stepLabel)}`),\n\t\t\t);\n\n\t\t\tconst template = (this.templates[i] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\t\tconst highlighted = template\n\t\t\t\t.replace(/\\{task\\}/g, th.fg(\"success\", \"{task}\"))\n\t\t\t\t.replace(/\\{previous\\}/g, th.fg(\"warning\", \"{previous}\"))\n\t\t\t\t.replace(/\\{chain_dir\\}/g, th.fg(\"accent\", \"{chain_dir}\"));\n\n\t\t\tconst templateLabel = th.fg(\"dim\", \"task: \");\n\t\t\tlines.push(this.row(` ${templateLabel}${truncateToWidth(highlighted, innerW - 12)}`));\n\n\t\t\tconst effectiveModel = this.getEffectiveModel(i);\n\t\t\tconst override = this.behaviorOverrides.get(i);\n\t\t\tconst isOverridden = override?.model !== undefined;\n\t\t\tconst modelValue = isOverridden\n\t\t\t\t? th.fg(\"warning\", effectiveModel) + th.fg(\"dim\", \" ✎\")\n\t\t\t\t: effectiveModel;\n\t\t\tconst modelLabel = th.fg(\"dim\", \"model: \");\n\t\t\tlines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));\n\n\t\t\tconst writesValue = behavior.output === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.output || th.fg(\"dim\", \"(none)\"));\n\t\t\tconst writesLabel = th.fg(\"dim\", \"writes: \");\n\t\t\tlines.push(this.row(` ${writesLabel}${truncateToWidth(writesValue, innerW - 14)}`));\n\n\t\t\tconst readsValue = behavior.reads === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.reads && behavior.reads.length > 0\n\t\t\t\t\t? behavior.reads.join(\", \")\n\t\t\t\t\t: th.fg(\"dim\", \"(none)\"));\n\t\t\tconst readsLabel = th.fg(\"dim\", \"reads: \");\n\t\t\tlines.push(this.row(` ${readsLabel}${truncateToWidth(readsValue, innerW - 13)}`));\n\n\t\t\tconst skillsValue = behavior.skills === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\t\tif (progressEnabled) {\n\t\t\t\tconst isFirstStep = i === 0;\n\t\t\t\tconst progressAction = isFirstStep \n\t\t\t\t\t? th.fg(\"success\", \"writes progress.md\")\n\t\t\t\t\t: th.fg(\"accent\", \"reads progress.md\");\n\t\t\t\tconst progressLabel = th.fg(\"dim\", \"progress: \");\n\t\t\t\tlines.push(this.row(` ${progressLabel}${progressAction}`));\n\t\t\t}\n\n\t\t\tif (i < this.agentConfigs.length - 1) {\n\t\t\t\tconst nextStepUsePrevious = (this.templates[i + 1] ?? \"\").includes(\"{previous}\");\n\t\t\t\tif (nextStepUsePrevious) {\n\t\t\t\t\tconst indicator = th.fg(\"dim\", \" ↳ response → \") + th.fg(\"warning\", \"{previous}\");\n\t\t\t\t\tlines.push(this.row(indicator));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tif (this.agentConfigs.length > 0) lines.pop();\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n\tdispose(): void {\n\t\tif (this.noticeMessageTimer) clearTimeout(this.noticeMessageTimer);\n\t\tthis.noticeMessageTimer = null;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chain-clarify.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Chain Clarification TUI Component\n *\n * Shows templates and resolved behaviors for each step in a chain.\n * Supports runtime editing of templates, output paths, reads lists, and progress toggle.\n */\n\nimport type { Theme } from \"@ashx-j/lunr-dev\";\nimport type { Component, TUI } from \"@ashx-j/lunr-tui\";\nimport { matchesKey, visibleWidth, truncateToWidth } from \"@ashx-j/lunr-tui\";\nimport type { ChildRuntimeConfig } from \"../../shared/types.ts\";\nimport type { ResolvedStepBehavior } from \"../../shared/settings.ts\";\nimport { resolveModelCandidate, splitThinkingSuffix } from \"../shared/model-fallback.ts\";\nimport { findModelInfo, getSupportedThinkingLevels, type ModelInfo, type ThinkingLevel } from \"../../shared/model-info.ts\";\n\ntype ClarifyMode = 'single' | 'parallel' | 'chain';\n\nexport interface BehaviorOverride {\n\toutput?: string | false;\n\treads?: string[] | false;\n\tprogress?: boolean;\n\tmodel?: string;\n\tskills?: string[] | false;\n}\n\nexport interface ChainClarifyResult {\n\tconfirmed: boolean;\n\ttemplates: string[];\n\tbehaviorOverrides: (BehaviorOverride | undefined)[];\n\trunInBackground?: boolean;\n}\n\ntype EditMode = \"template\" | \"output\" | \"reads\" | \"model\" | \"thinking\" | \"skills\";\n\n\ninterface TextEditorState {\n\tbuffer: string;\n\tcursor: number;\n\tviewportOffset: number;\n}\n\nfunction createEditorState(initial = \"\"): TextEditorState {\n\treturn { buffer: initial, cursor: 0, viewportOffset: 0 };\n}\n\nfunction wrapText(text: string, width: number): { lines: string[]; starts: number[] } {\n\tif (width <= 0) return { lines: [text], starts: [0] };\n\tif (text.length === 0) return { lines: [\"\"], starts: [0] };\n\n\tconst lines: string[] = [];\n\tconst starts: number[] = [];\n\tlet offset = 0;\n\tconst segments = text.split(\"\\n\");\n\tfor (const [index, segment] of segments.entries()) {\n\t\tif (segment.length === 0) {\n\t\t\tstarts.push(offset);\n\t\t\tlines.push(\"\");\n\t\t} else {\n\t\t\tlet lineStart = 0;\n\t\t\tlet pos = 0;\n\t\t\tlet lineWidth = 0;\n\t\t\twhile (pos < segment.length) {\n\t\t\t\tconst char = String.fromCodePoint(segment.codePointAt(pos)!);\n\t\t\t\tconst charWidth = visibleWidth(char);\n\t\t\t\tif (lineWidth > 0 && lineWidth + charWidth > width) {\n\t\t\t\t\tstarts.push(offset + lineStart);\n\t\t\t\t\tlines.push(segment.slice(lineStart, pos));\n\t\t\t\t\tlineStart = pos;\n\t\t\t\t\tlineWidth = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpos += char.length;\n\t\t\t\tlineWidth += charWidth;\n\t\t\t}\n\t\t\tstarts.push(offset + lineStart);\n\t\t\tlines.push(segment.slice(lineStart));\n\t\t}\n\t\toffset += segment.length + (index < segments.length - 1 ? 1 : 0);\n\t}\n\tif (!text.endsWith(\"\\n\") && text.length > 0 && visibleWidth(lines[lines.length - 1] ?? \"\") === width) {\n\t\tstarts.push(text.length);\n\t\tlines.push(\"\");\n\t}\n\treturn { lines, starts };\n}\n\nfunction getCursorDisplayPos(cursor: number, starts: number[]): { line: number; col: number } {\n\tfor (let i = starts.length - 1; i >= 0; i--) {\n\t\tif (cursor >= starts[i]!) return { line: i, col: cursor - starts[i]! };\n\t}\n\treturn { line: 0, col: 0 };\n}\n\nfunction ensureCursorVisible(cursorLine: number, viewportHeight: number, currentOffset: number): number {\n\tif (cursorLine < currentOffset) return Math.max(0, cursorLine);\n\tif (cursorLine >= currentOffset + viewportHeight) return Math.max(0, cursorLine - viewportHeight + 1);\n\treturn Math.max(0, currentOffset);\n}\n\nfunction isWordChar(ch: string): boolean {\n\tconst code = ch.charCodeAt(0);\n\treturn (code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122) || code === 95;\n}\n\nfunction wordBackward(buffer: string, cursor: number): number {\n\tlet pos = cursor;\n\twhile (pos > 0 && !isWordChar(buffer[pos - 1]!)) pos--;\n\twhile (pos > 0 && isWordChar(buffer[pos - 1]!)) pos--;\n\treturn pos;\n}\n\nfunction wordForward(buffer: string, cursor: number): number {\n\tlet pos = cursor;\n\twhile (pos < buffer.length && isWordChar(buffer[pos]!)) pos++;\n\twhile (pos < buffer.length && !isWordChar(buffer[pos]!)) pos++;\n\treturn pos;\n}\n\nfunction normalizeInsertText(data: string): string | null {\n\tlet text = data.split(\"\\x1b[200~\").join(\"\").split(\"\\x1b[201~\").join(\"\");\n\ttext = text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\tconst newline = text.indexOf(\"\\n\");\n\tif (newline !== -1) text = text.slice(0, newline);\n\ttext = text.replace(/\\t/g, \" \");\n\tif (text.length === 0) return null;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text.charCodeAt(i) < 32) return null;\n\t}\n\treturn text;\n}\n\nfunction handleEditorInput(state: TextEditorState, data: string, textWidth: number): TextEditorState | null {\n\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\") || matchesKey(data, \"return\")) return null;\n\n\tconst { lines: wrapped, starts } = wrapText(state.buffer, textWidth);\n\tconst cursorPos = getCursorDisplayPos(state.cursor, starts);\n\n\tif (matchesKey(data, \"alt+left\") || matchesKey(data, \"ctrl+left\")) return { ...state, cursor: wordBackward(state.buffer, state.cursor) };\n\tif (matchesKey(data, \"alt+right\") || matchesKey(data, \"ctrl+right\")) return { ...state, cursor: wordForward(state.buffer, state.cursor) };\n\tif (matchesKey(data, \"left\")) return state.cursor > 0 ? { ...state, cursor: state.cursor - 1 } : state;\n\tif (matchesKey(data, \"right\")) return state.cursor < state.buffer.length ? { ...state, cursor: state.cursor + 1 } : state;\n\tif (matchesKey(data, \"up\") && cursorPos.line > 0) {\n\t\tconst targetLine = cursorPos.line - 1;\n\t\treturn { ...state, cursor: starts[targetLine]! + Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0) };\n\t}\n\tif (matchesKey(data, \"down\") && cursorPos.line < wrapped.length - 1) {\n\t\tconst targetLine = cursorPos.line + 1;\n\t\treturn { ...state, cursor: starts[targetLine]! + Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0) };\n\t}\n\tif (matchesKey(data, \"home\")) return { ...state, cursor: starts[cursorPos.line]! };\n\tif (matchesKey(data, \"end\")) return { ...state, cursor: starts[cursorPos.line]! + (wrapped[cursorPos.line]?.length ?? 0) };\n\tif (matchesKey(data, \"ctrl+home\")) return { ...state, cursor: 0 };\n\tif (matchesKey(data, \"ctrl+end\")) return { ...state, cursor: state.buffer.length };\n\tif (matchesKey(data, \"alt+backspace\")) {\n\t\tconst target = wordBackward(state.buffer, state.cursor);\n\t\treturn target === state.cursor ? state : { ...state, buffer: state.buffer.slice(0, target) + state.buffer.slice(state.cursor), cursor: target };\n\t}\n\tif (matchesKey(data, \"backspace\")) {\n\t\treturn state.cursor > 0\n\t\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor - 1) + state.buffer.slice(state.cursor), cursor: state.cursor - 1 }\n\t\t\t: state;\n\t}\n\tif (matchesKey(data, \"delete\")) {\n\t\treturn state.cursor < state.buffer.length\n\t\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor) + state.buffer.slice(state.cursor + 1) }\n\t\t\t: state;\n\t}\n\n\tconst insert = normalizeInsertText(data);\n\treturn insert\n\t\t? { ...state, buffer: state.buffer.slice(0, state.cursor) + insert + state.buffer.slice(state.cursor), cursor: state.cursor + insert.length }\n\t\t: null;\n}\n\nfunction renderWithCursor(text: string, cursorPos: number): string {\n\tconst before = text.slice(0, cursorPos);\n\tconst cursorChar = text[cursorPos] ?? \" \";\n\tconst after = text.slice(cursorPos + 1);\n\treturn `${before}\\x1b[7m${cursorChar}\\x1b[27m${after}`;\n}\n\nfunction renderEditor(state: TextEditorState, width: number, viewportHeight: number): string[] {\n\tconst { lines: wrapped, starts } = wrapText(state.buffer, width);\n\tconst cursorPos = getCursorDisplayPos(state.cursor, starts);\n\tconst lines: string[] = [];\n\tfor (let i = 0; i < viewportHeight; i++) {\n\t\tconst lineIdx = state.viewportOffset + i;\n\t\tlet content = lineIdx < wrapped.length ? wrapped[lineIdx] ?? \"\" : \"\";\n\t\tif (lineIdx === cursorPos.line) content = renderWithCursor(content, cursorPos.col);\n\t\tlines.push(content);\n\t}\n\treturn lines;\n}\n\n/**\n * TUI component for chain clarification.\n * Factory signature matches ctx.ui.custom: (tui, theme, kb, done) => Component\n */\nexport class ChainClarifyComponent implements Component {\n\treadonly width = 84;\n\n\tprivate selectedStep = 0;\n\tprivate editingStep: number | null = null;\n\tprivate editMode: EditMode = \"template\";\n\tprivate editState: TextEditorState = createEditorState();\n\n\tprivate readonly EDIT_VIEWPORT_HEIGHT = 12;\n\tprivate behaviorOverrides: Map<number, BehaviorOverride> = new Map();\n\tprivate modelSearchQuery: string = \"\";\n\tprivate modelSelectedIndex: number = 0;\n\tprivate filteredModels: ModelInfo[] = [];\n\tprivate readonly MODEL_SELECTOR_HEIGHT = 10;\n\tprivate thinkingSelectedIndex: number = 0;\n\tprivate skillSearchQuery: string = \"\";\n\tprivate skillSelectedNames: Set<string> = new Set();\n\tprivate skillCursorIndex: number = 0;\n\tprivate filteredSkills: Array<{ name: string; source: string; description?: string }> = [];\n\tprivate noticeMessage: { text: string; type: \"info\" | \"error\" } | null = null;\n\tprivate noticeMessageTimer: ReturnType<typeof setTimeout> | null = null;\n\t/** Run in background (async) mode */\n\tprivate runInBackground = false;\n\tprivate tui: TUI;\n\tprivate theme: Theme;\n\tprivate agentConfigs: ChildRuntimeConfig[];\n\tprivate templates: string[];\n\tprivate originalTask: string;\n\tprivate chainDir: string | undefined;\n\tprivate resolvedBehaviors: ResolvedStepBehavior[];\n\tprivate availableModels: ModelInfo[];\n\tprivate preferredProvider: string | undefined;\n\tprivate availableSkills: Array<{ name: string; source: string; description?: string }>;\n\tprivate done: (result: ChainClarifyResult) => void;\n\tprivate mode: ClarifyMode;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tagentConfigs: ChildRuntimeConfig[],\n\t\ttemplates: string[],\n\t\toriginalTask: string,\n\t\tchainDir: string | undefined,\n\t\tresolvedBehaviors: ResolvedStepBehavior[],\n\t\tavailableModels: ModelInfo[],\n\t\tpreferredProvider: string | undefined,\n\t\tavailableSkills: Array<{ name: string; source: string; description?: string }>,\n\t\tdone: (result: ChainClarifyResult) => void,\n\t\tmode: ClarifyMode = 'chain',\n\t) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.agentConfigs = agentConfigs;\n\t\tthis.templates = templates;\n\t\tthis.originalTask = originalTask;\n\t\tthis.chainDir = chainDir;\n\t\tthis.resolvedBehaviors = resolvedBehaviors;\n\t\tthis.availableModels = availableModels;\n\t\tthis.preferredProvider = preferredProvider;\n\t\tthis.availableSkills = availableSkills;\n\t\tthis.done = done;\n\t\tthis.mode = mode;\n\t\tthis.filteredModels = [...availableModels];\n\t\tthis.filteredSkills = [...availableSkills];\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Helper methods for rendering\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Pad string to specified visible width */\n\tprivate pad(s: string, len: number): string {\n\t\tconst vis = visibleWidth(s);\n\t\treturn s + \" \".repeat(Math.max(0, len - vis));\n\t}\n\n\t/** Create a row with border characters */\n\tprivate row(content: string): string {\n\t\tconst innerW = this.width - 2;\n\t\treturn this.theme.fg(\"border\", \"│\") + this.pad(content, innerW) + this.theme.fg(\"border\", \"│\");\n\t}\n\n\t/** Render centered header line with border */\n\tprivate renderHeader(text: string): string {\n\t\tconst innerW = this.width - 2;\n\t\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\t\tconst padLeft = Math.floor(padLen / 2);\n\t\tconst padRight = padLen - padLeft;\n\t\treturn (\n\t\t\tthis.theme.fg(\"border\", \"╭\" + \"─\".repeat(padLeft)) +\n\t\t\tthis.theme.fg(\"accent\", text) +\n\t\t\tthis.theme.fg(\"border\", \"─\".repeat(padRight) + \"╮\")\n\t\t);\n\t}\n\n\t/** Render centered footer line with border */\n\tprivate renderFooter(text: string): string {\n\t\tconst innerW = this.width - 2;\n\t\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\t\tconst padLeft = Math.floor(padLen / 2);\n\t\tconst padRight = padLen - padLeft;\n\t\treturn (\n\t\t\tthis.theme.fg(\"border\", \"╰\" + \"─\".repeat(padLeft)) +\n\t\t\tthis.theme.fg(\"dim\", text) +\n\t\t\tthis.theme.fg(\"border\", \"─\".repeat(padRight) + \"╯\")\n\t\t);\n\t}\n\n\t/** Exit edit mode and reset state */\n\tprivate exitEditMode(): void {\n\t\tthis.editingStep = null;\n\t\tthis.editState = createEditorState();\n\t\tthis.tui.requestRender();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Full edit mode methods\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Render the full-edit takeover view */\n\tprivate renderFullEditMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst textWidth = innerW - 2; // 1 char padding on each side\n\t\tconst lines: string[] = [];\n\n\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\tthis.editState = {\n\t\t\t...this.editState,\n\t\t\tviewportOffset: ensureCursorVisible(\n\t\t\t\tcursorPos.line,\n\t\t\t\tthis.EDIT_VIEWPORT_HEIGHT,\n\t\t\t\tthis.editState.viewportOffset,\n\t\t\t),\n\t\t};\n\n\t\t// Header (truncate agent name to prevent overflow)\n\t\tconst fieldName = this.editMode === \"template\" ? \"task\" : this.editMode;\n\t\tconst rawAgentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst maxAgentLen = innerW - 30; // Reserve space for \" Editing X (Step/Task N: ) \"\n\t\tconst agentName = rawAgentName.length > maxAgentLen\n\t\t\t? rawAgentName.slice(0, maxAgentLen - 1) + \"…\"\n\t\t\t: rawAgentName;\n\t\t// Use mode-appropriate terminology\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Editing ${fieldName} (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst editorLines = renderEditor(this.editState, textWidth, this.EDIT_VIEWPORT_HEIGHT);\n\t\tfor (const line of editorLines) {\n\t\t\tlines.push(this.row(` ${line}`));\n\t\t}\n\n\t\tconst linesBelow = wrapped.length - this.editState.viewportOffset - this.EDIT_VIEWPORT_HEIGHT;\n\t\tconst hasMore = linesBelow > 0;\n\t\tconst hasLess = this.editState.viewportOffset > 0;\n\t\tlet scrollInfo = \"\";\n\t\tif (hasLess) scrollInfo += \"↑\";\n\t\tif (hasMore) scrollInfo += `↓ ${linesBelow}+`;\n\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst footerText = scrollInfo\n\t\t\t? ` [Esc] Done • [Ctrl+C] Discard • ${scrollInfo} `\n\t\t\t: \" [Esc] Done • [Ctrl+C] Discard \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Behavior helpers\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/** Get effective behavior for a step (with user overrides applied) */\n\tprivate getEffectiveBehavior(stepIndex: number): ResolvedStepBehavior {\n\t\tconst base = this.resolvedBehaviors[stepIndex]!;\n\t\tconst override = this.behaviorOverrides.get(stepIndex);\n\t\tif (!override) return base;\n\n\t\treturn {\n\t\t\toutput: override.output !== undefined ? override.output : base.output,\n\t\t\toutputMode: base.outputMode,\n\t\t\treads: override.reads !== undefined ? override.reads : base.reads,\n\t\t\tprogress: override.progress !== undefined ? override.progress : base.progress,\n\t\t\tskills: override.skills !== undefined ? override.skills : base.skills,\n\t\t\tmodel: override.model !== undefined ? override.model : base.model,\n\t\t};\n\t}\n\n\t/** Get the effective model for a step (override or agent default) */\n\tprivate getEffectiveModel(stepIndex: number): string {\n\t\tconst override = this.behaviorOverrides.get(stepIndex);\n\t\tif (override?.model) return this.resolveModelFullId(override.model);\n\n\t\tconst baseModel = this.resolvedBehaviors[stepIndex]?.model;\n\t\tif (baseModel) return this.resolveModelFullId(baseModel);\n\t\treturn \"default\";\n\t}\n\n\t/** Resolve a model name to its full provider/model format */\n\tprivate resolveModelFullId(modelName: string): string {\n\t\treturn resolveModelCandidate(modelName, this.availableModels, this.preferredProvider) ?? modelName;\n\t}\n\n\t/** Update a behavior override for a step */\n\tprivate updateBehavior(stepIndex: number, field: keyof BehaviorOverride, value: string | boolean | string[] | false): void {\n\t\tconst existing = this.behaviorOverrides.get(stepIndex) ?? {};\n\t\tthis.behaviorOverrides.set(stepIndex, { ...existing, [field]: value });\n\t}\n\n\tprivate showNotice(text: string, type: \"info\" | \"error\"): void {\n\t\tthis.noticeMessage = { text, type };\n\t\tif (this.noticeMessageTimer) clearTimeout(this.noticeMessageTimer);\n\t\tthis.noticeMessageTimer = setTimeout(() => {\n\t\t\tthis.noticeMessage = null;\n\t\t\tthis.noticeMessageTimer = null;\n\t\t\tthis.tui.requestRender();\n\t\t}, 2000);\n\t\tthis.tui.requestRender();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.editingStep !== null) {\n\t\t\tif (this.editMode === \"model\") {\n\t\t\t\tthis.handleModelSelectorInput(data);\n\t\t\t} else if (this.editMode === \"thinking\") {\n\t\t\t\tthis.handleThinkingSelectorInput(data);\n\t\t\t} else if (this.editMode === \"skills\") {\n\t\t\t\tthis.handleSkillSelectorInput(data);\n\t\t\t} else {\n\t\t\t\tthis.handleEditInput(data);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.done({ confirmed: false, templates: [], behaviorOverrides: [] });\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst overrides: (BehaviorOverride | undefined)[] = [];\n\t\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\t\toverrides.push(this.behaviorOverrides.get(i));\n\t\t\t}\n\t\t\tthis.done({ confirmed: true, templates: this.templates, behaviorOverrides: overrides, runInBackground: this.runInBackground });\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.selectedStep = Math.max(0, this.selectedStep - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tconst maxStep = Math.max(0, this.agentConfigs.length - 1);\n\t\t\tthis.selectedStep = Math.min(maxStep, this.selectedStep + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"e\") {\n\t\t\tthis.enterEditMode(\"template\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"s\") {\n\t\t\tthis.editingStep = this.selectedStep;\n\t\t\tthis.editMode = \"skills\";\n\t\t\tthis.skillSearchQuery = \"\";\n\t\t\tthis.skillCursorIndex = 0;\n\t\t\tthis.filteredSkills = [...this.availableSkills];\n\t\t\tconst current = this.getEffectiveBehavior(this.selectedStep).skills;\n\t\t\tthis.skillSelectedNames.clear();\n\t\t\tif (current !== false && current.length > 0) {\n\t\t\t\tcurrent.forEach((skillName) => this.skillSelectedNames.add(skillName));\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"w\" && this.mode !== 'parallel') {\n\t\t\tthis.enterEditMode(\"output\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"r\" && this.mode === 'chain') {\n\t\t\tthis.enterEditMode(\"reads\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"p\" && this.mode === 'chain') {\n\t\t\tconst anyEnabled = this.agentConfigs.some((_, i) => this.getEffectiveBehavior(i).progress);\n\t\t\tconst newState = !anyEnabled;\n\t\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\t\tthis.updateBehavior(i, \"progress\", newState);\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \"b\") {\n\t\t\tthis.runInBackground = !this.runInBackground;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t}\n\n\tprivate enterEditMode(mode: EditMode): void {\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = mode;\n\t\tlet buffer = \"\";\n\n\t\tif (mode === \"template\") {\n\t\t\tconst template = this.templates[this.selectedStep] ?? \"\";\n\t\t\tbuffer = template.split(\"\\n\")[0] ?? \"\";\n\t\t} else if (mode === \"output\") {\n\t\t\tconst behavior = this.getEffectiveBehavior(this.selectedStep);\n\t\t\tbuffer = behavior.output === false ? \"\" : (behavior.output || \"\");\n\t\t} else if (mode === \"reads\") {\n\t\t\tconst behavior = this.getEffectiveBehavior(this.selectedStep);\n\t\t\tbuffer = behavior.reads === false ? \"\" : (behavior.reads?.join(\", \") || \"\");\n\t\t}\n\n\t\tthis.editState = createEditorState(buffer);\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Enter model selector mode */\n\tprivate enterModelSelector(): void {\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = \"model\";\n\t\tthis.modelSearchQuery = \"\";\n\t\tthis.modelSelectedIndex = 0;\n\t\tthis.filteredModels = [...this.availableModels];\n\t\tconst currentModel = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep)).baseModel;\n\t\tconst currentIndex = this.filteredModels.findIndex((m) => m.fullId === currentModel || m.id === currentModel);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis.modelSelectedIndex = currentIndex;\n\t\t}\n\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Filter models based on search query */\n\tprivate filterModels(): void {\n\t\tconst query = this.modelSearchQuery.toLowerCase();\n\t\tif (!query) {\n\t\t\tthis.filteredModels = [...this.availableModels];\n\t\t} else {\n\t\t\tthis.filteredModels = this.availableModels.filter((m) =>\n\t\t\t\tm.fullId.toLowerCase().includes(query) ||\n\t\t\t\tm.id.toLowerCase().includes(query) ||\n\t\t\t\tm.provider.toLowerCase().includes(query)\n\t\t\t);\n\t\t}\n\t\tthis.modelSelectedIndex = Math.min(this.modelSelectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t}\n\n\tprivate handleModelSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selected = this.filteredModels[this.modelSelectedIndex];\n\t\t\tif (selected) {\n\t\t\t\tconst { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.editingStep!));\n\t\t\t\tconst requestedLevel = thinkingSuffix.slice(1);\n\t\t\t\tconst selectedModel = findModelInfo(selected.fullId, this.availableModels, this.preferredProvider);\n\t\t\t\tconst suffix = getSupportedThinkingLevels(selectedModel).some((level) => level === requestedLevel) ? thinkingSuffix : \"\";\n\t\t\t\tthis.updateBehavior(this.editingStep!, \"model\", `${selected.fullId}${suffix}`);\n\t\t\t}\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tif (this.filteredModels.length > 0) {\n\t\t\t\tthis.modelSelectedIndex = this.modelSelectedIndex === 0\n\t\t\t\t\t? this.filteredModels.length - 1\n\t\t\t\t\t: this.modelSelectedIndex - 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tif (this.filteredModels.length > 0) {\n\t\t\t\tthis.modelSelectedIndex = this.modelSelectedIndex === this.filteredModels.length - 1\n\t\t\t\t\t? 0\n\t\t\t\t\t: this.modelSelectedIndex + 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"backspace\")) {\n\t\t\tif (this.modelSearchQuery.length > 0) {\n\t\t\t\tthis.modelSearchQuery = this.modelSearchQuery.slice(0, -1);\n\t\t\t\tthis.filterModels();\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.length === 1 && data.charCodeAt(0) >= 32) {\n\t\t\tthis.modelSearchQuery += data;\n\t\t\tthis.filterModels();\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate getAvailableThinkingLevels(stepIndex: number): ThinkingLevel[] {\n\t\treturn getSupportedThinkingLevels(findModelInfo(this.getEffectiveModel(stepIndex), this.availableModels, this.preferredProvider));\n\t}\n\n\t/** Enter thinking level selector mode */\n\tprivate enterThinkingSelector(): void {\n\t\tif (!this.getEffectiveBehavior(this.selectedStep).model) {\n\t\t\tthis.showNotice(\"Select a model first\", \"error\");\n\t\t\treturn;\n\t\t}\n\t\tthis.editingStep = this.selectedStep;\n\t\tthis.editMode = \"thinking\";\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.selectedStep);\n\t\tconst { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep));\n\t\tconst suffix = thinkingSuffix.slice(1);\n\t\tconst levelIdx = levels.findIndex((level) => level === suffix);\n\t\tthis.thinkingSelectedIndex = levelIdx >= 0 ? levelIdx : Math.max(0, levels.indexOf(\"off\"));\n\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate handleThinkingSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.editingStep!);\n\t\tif (levels.length === 0) return;\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selectedLevel = levels[this.thinkingSelectedIndex] ?? \"off\";\n\t\t\tthis.applyThinkingLevel(selectedLevel);\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.thinkingSelectedIndex = this.thinkingSelectedIndex === 0\n\t\t\t\t? levels.length - 1\n\t\t\t\t: this.thinkingSelectedIndex - 1;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tthis.thinkingSelectedIndex = this.thinkingSelectedIndex === levels.length - 1\n\t\t\t\t? 0\n\t\t\t\t: this.thinkingSelectedIndex + 1;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** Apply thinking level to the current step's model */\n\tprivate applyThinkingLevel(level: ThinkingLevel): void {\n\t\tconst stepIndex = this.editingStep!;\n\t\tconst currentModel = this.getEffectiveBehavior(stepIndex).model;\n\t\tif (!currentModel) return;\n\n\t\tconst { baseModel } = splitThinkingSuffix(currentModel);\n\t\tconst newModel = level === \"off\" ? baseModel : `${baseModel}:${level}`;\n\t\tthis.updateBehavior(stepIndex, \"model\", newModel);\n\t}\n\n\tprivate filterSkills(): void {\n\t\tconst query = this.skillSearchQuery.toLowerCase();\n\t\tif (!query) {\n\t\t\tthis.filteredSkills = [...this.availableSkills];\n\t\t} else {\n\t\t\tthis.filteredSkills = this.availableSkills.filter((s) =>\n\t\t\t\ts.name.toLowerCase().includes(query) ||\n\t\t\t\t(s.description?.toLowerCase().includes(query) ?? false),\n\t\t\t);\n\t\t}\n\t\tthis.skillCursorIndex = Math.min(this.skillCursorIndex, Math.max(0, this.filteredSkills.length - 1));\n\t}\n\n\tprivate handleSkillSelectorInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tconst selected = [...this.skillSelectedNames];\n\t\t\tthis.updateBehavior(this.editingStep!, \"skills\", selected);\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data === \" \") {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tconst skill = this.filteredSkills[this.skillCursorIndex];\n\t\t\t\tif (skill) {\n\t\t\t\t\tif (this.skillSelectedNames.has(skill.name)) {\n\t\t\t\t\t\tthis.skillSelectedNames.delete(skill.name);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.skillSelectedNames.add(skill.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tthis.skillCursorIndex = this.skillCursorIndex === 0\n\t\t\t\t\t? this.filteredSkills.length - 1\n\t\t\t\t\t: this.skillCursorIndex - 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tif (this.filteredSkills.length > 0) {\n\t\t\t\tthis.skillCursorIndex = this.skillCursorIndex === this.filteredSkills.length - 1\n\t\t\t\t\t? 0\n\t\t\t\t\t: this.skillCursorIndex + 1;\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"backspace\")) {\n\t\t\tif (this.skillSearchQuery.length > 0) {\n\t\t\t\tthis.skillSearchQuery = this.skillSearchQuery.slice(0, -1);\n\t\t\t\tthis.filterSkills();\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (data.length === 1 && data.charCodeAt(0) >= 32) {\n\t\t\tthis.skillSearchQuery += data;\n\t\t\tthis.filterSkills();\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate handleEditInput(data: string): void {\n\t\tconst textWidth = this.width - 4; // Must match render: innerW - 2 = (width - 2) - 2\n\t\tif (matchesKey(data, \"shift+up\") || matchesKey(data, \"pageup\")) {\n\t\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\t\tconst targetLine = Math.max(0, cursorPos.line - this.EDIT_VIEWPORT_HEIGHT);\n\t\t\tconst targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);\n\t\t\tthis.editState = { ...this.editState, cursor: starts[targetLine] + targetCol };\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"shift+down\") || matchesKey(data, \"pagedown\")) {\n\t\t\tconst { lines: wrapped, starts } = wrapText(this.editState.buffer, textWidth);\n\t\t\tconst cursorPos = getCursorDisplayPos(this.editState.cursor, starts);\n\t\t\tconst targetLine = Math.min(wrapped.length - 1, cursorPos.line + this.EDIT_VIEWPORT_HEIGHT);\n\t\t\tconst targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);\n\t\t\tthis.editState = { ...this.editState, cursor: starts[targetLine] + targetCol };\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"tab\")) return;\n\n\t\tconst nextState = handleEditorInput(this.editState, data, textWidth);\n\t\tif (nextState) {\n\t\t\tthis.editState = nextState;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"escape\")) {\n\t\t\tthis.saveEdit();\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.exitEditMode();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate saveEdit(): void {\n\t\tconst stepIndex = this.editingStep!;\n\n\t\tif (this.editMode === \"template\") {\n\t\t\t// For template, preserve other lines if they existed\n\t\t\tconst original = this.templates[stepIndex] ?? \"\";\n\t\t\tconst originalLines = original.split(\"\\n\");\n\t\t\toriginalLines[0] = this.editState.buffer;\n\t\t\tthis.templates[stepIndex] = originalLines.join(\"\\n\");\n\t\t} else if (this.editMode === \"output\") {\n\t\t\t// Capture OLD output before updating (for downstream propagation)\n\t\t\tconst oldBehavior = this.getEffectiveBehavior(stepIndex);\n\t\t\tconst oldOutput = typeof oldBehavior.output === \"string\" ? oldBehavior.output : null;\n\n\t\t\t// Empty string or whitespace means disable output\n\t\t\tconst trimmed = this.editState.buffer.trim();\n\t\t\tconst newOutput = trimmed === \"\" ? false : trimmed;\n\t\t\tthis.updateBehavior(stepIndex, \"output\", newOutput);\n\n\t\t\t// Propagate output filename change to downstream steps' reads\n\t\t\tif (oldOutput && typeof newOutput === \"string\" && oldOutput !== newOutput) {\n\t\t\t\tthis.propagateOutputChange(stepIndex, oldOutput, newOutput);\n\t\t\t}\n\t\t} else if (this.editMode === \"reads\") {\n\t\t\t// Parse comma-separated list, empty means disable reads\n\t\t\tconst trimmed = this.editState.buffer.trim();\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tthis.updateBehavior(stepIndex, \"reads\", false);\n\t\t\t} else {\n\t\t\t\tconst files = trimmed.split(\",\").map(f => f.trim()).filter(f => f !== \"\");\n\t\t\t\tthis.updateBehavior(stepIndex, \"reads\", files.length > 0 ? files : false);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * When a step's output filename changes, update downstream steps that read from it.\n\t * This maintains the chain dependency automatically.\n\t */\n\tprivate propagateOutputChange(changedStepIndex: number, oldOutput: string, newOutput: string): void {\n\t\t// Check all downstream steps (steps that come after the changed step)\n\t\tfor (let i = changedStepIndex + 1; i < this.agentConfigs.length; i++) {\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\t\t\t\n\t\t\t// Skip if reads is disabled or empty\n\t\t\tif (behavior.reads === false || !behavior.reads || behavior.reads.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if this step reads the old output file\n\t\t\tconst readsArray = behavior.reads;\n\t\t\tconst oldIndex = readsArray.indexOf(oldOutput);\n\t\t\t\n\t\t\tif (oldIndex !== -1) {\n\t\t\t\t// Replace old filename with new filename in reads\n\t\t\t\tconst newReads = [...readsArray];\n\t\t\t\tnewReads[oldIndex] = newOutput;\n\t\t\t\tthis.updateBehavior(i, \"reads\", newReads);\n\t\t\t}\n\t\t}\n\t}\n\n\trender(_width: number): string[] {\n\t\tif (this.editingStep !== null) {\n\t\t\tif (this.editMode === \"model\") {\n\t\t\t\treturn this.renderModelSelector();\n\t\t\t}\n\t\t\tif (this.editMode === \"thinking\") {\n\t\t\t\treturn this.renderThinkingSelector();\n\t\t\t}\n\t\t\tif (this.editMode === \"skills\") {\n\t\t\t\treturn this.renderSkillSelector();\n\t\t\t}\n\t\t\treturn this.renderFullEditMode();\n\t\t}\n\t\t// Mode-based navigation rendering\n\t\tswitch (this.mode) {\n\t\t\tcase 'single': return this.renderSingleMode();\n\t\t\tcase 'parallel': return this.renderParallelMode();\n\t\t\tcase 'chain': return this.renderChainMode();\n\t\t}\n\t}\n\n\t/** Render the model selector view */\n\tprivate renderModelSelector(): string[] {\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\t// Header (mode-aware terminology)\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Select Model (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst searchPrefix = th.fg(\"dim\", \"Search: \");\n\t\tconst cursor = \"\\x1b[7m \\x1b[27m\"; // Reverse video space for cursor\n\t\tconst searchDisplay = this.modelSearchQuery + cursor;\n\t\tlines.push(this.row(` ${searchPrefix}${searchDisplay}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst currentModel = this.getEffectiveModel(this.editingStep!);\n\t\tconst currentModelBase = splitThinkingSuffix(currentModel).baseModel;\n\t\tconst currentLabel = th.fg(\"dim\", \"Current: \");\n\t\tlines.push(this.row(` ${currentLabel}${th.fg(\"warning\", currentModel)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tif (this.filteredModels.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No matching models\")}`));\n\t\t} else {\n\t\t\tconst maxVisible = this.MODEL_SELECTOR_HEIGHT;\n\t\t\tlet startIdx = 0;\n\n\t\t\tif (this.filteredModels.length > maxVisible) {\n\t\t\t\tstartIdx = Math.max(0, this.modelSelectedIndex - Math.floor(maxVisible / 2));\n\t\t\t\tstartIdx = Math.min(startIdx, this.filteredModels.length - maxVisible);\n\t\t\t}\n\n\t\t\tconst endIdx = Math.min(startIdx + maxVisible, this.filteredModels.length);\n\n\t\t\tif (startIdx > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↑ ${startIdx} more`)}`));\n\t\t\t}\n\n\t\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\t\tconst model = this.filteredModels[i]!;\n\t\t\t\tconst isSelected = i === this.modelSelectedIndex;\n\t\t\t\tconst isCurrent = model.fullId === currentModelBase || model.id === currentModelBase;\n\t\t\t\tconst prefix = isSelected ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst modelText = isSelected ? th.fg(\"accent\", model.id) : model.id;\n\t\t\t\tconst providerBadge = th.fg(\"dim\", ` [${model.provider}]`);\n\t\t\t\tconst currentBadge = isCurrent ? th.fg(\"success\", \" current\") : \"\";\n\n\t\t\t\tlines.push(this.row(` ${prefix}${modelText}${providerBadge}${currentBadge}`));\n\t\t\t}\n\n\t\t\tconst remaining = this.filteredModels.length - endIdx;\n\t\t\tif (remaining > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↓ ${remaining} more`)}`));\n\t\t\t}\n\t\t}\n\n\t\tconst contentLines = lines.length;\n\t\tconst targetHeight = 18;\n\t\tfor (let i = contentLines; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tconst footerText = \" [Enter] Select • [Esc] Cancel • Type to search \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\t/** Render the thinking level selector view */\n\tprivate renderThinkingSelector(): string[] {\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single' \n\t\t\t? agentName \n\t\t\t: this.mode === 'parallel' \n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}` \n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tconst headerText = ` Thinking Level (${stepLabel}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst currentModel = this.getEffectiveModel(this.editingStep!);\n\t\tconst currentLabel = th.fg(\"dim\", \"Model: \");\n\t\tlines.push(this.row(` ${currentLabel}${th.fg(\"accent\", currentModel)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Select thinking level (extended thinking budget):\")}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst levelDescriptions: Record<ThinkingLevel, string> = {\n\t\t\t\"off\": \"No extended thinking\",\n\t\t\t\"minimal\": \"Brief reasoning\",\n\t\t\t\"low\": \"Light reasoning\",\n\t\t\t\"medium\": \"Moderate reasoning\",\n\t\t\t\"high\": \"Deep reasoning\",\n\t\t\t\"xhigh\": \"Maximum reasoning (ultrathink)\",\n\t\t\t\"max\": \"Maximum available reasoning\",\n\t\t};\n\n\t\tconst levels = this.getAvailableThinkingLevels(this.editingStep!);\n\t\tif (levels.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No supported thinking levels\")}`));\n\t\t} else {\n\t\t\tfor (let i = 0; i < levels.length; i++) {\n\t\t\t\tconst level = levels[i]!;\n\t\t\t\tconst isSelected = i === this.thinkingSelectedIndex;\n\t\t\t\tconst prefix = isSelected ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst levelText = isSelected ? th.fg(\"accent\", level) : level;\n\t\t\t\tconst desc = th.fg(\"dim\", ` - ${levelDescriptions[level]}`);\n\t\t\t\tlines.push(this.row(` ${prefix}${levelText}${desc}`));\n\t\t\t}\n\t\t}\n\n\t\tconst contentLines = lines.length;\n\t\tconst targetHeight = 16;\n\t\tfor (let i = contentLines; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tconst footerText = levels.length === 0\n\t\t\t? \" [Esc] Cancel \"\n\t\t\t: \" [Enter] Select • [Esc] Cancel • ↑↓ Navigate \";\n\t\tlines.push(this.renderFooter(footerText));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderSkillSelector(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[this.editingStep!]?.name ?? \"unknown\";\n\t\tconst stepLabel = this.mode === 'single'\n\t\t\t? agentName\n\t\t\t: this.mode === 'parallel'\n\t\t\t\t? `Task ${this.editingStep! + 1}: ${agentName}`\n\t\t\t\t: `Step ${this.editingStep! + 1}: ${agentName}`;\n\t\tlines.push(this.renderHeader(` Select Skills (${stepLabel}) `));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst cursor = \"\\x1b[7m \\x1b[27m\";\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Search: \")}${this.skillSearchQuery}${cursor}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst selected = [...this.skillSelectedNames].join(\", \") || th.fg(\"dim\", \"(none)\");\n\t\tlines.push(this.row(` ${th.fg(\"dim\", \"Selected: \")}${truncateToWidth(selected, innerW - 12)}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst selectorHeight = 10;\n\t\tif (this.filteredSkills.length === 0) {\n\t\t\tlines.push(this.row(` ${th.fg(\"dim\", \"No matching skills\")}`));\n\t\t} else {\n\t\t\tlet startIdx = 0;\n\t\t\tif (this.filteredSkills.length > selectorHeight) {\n\t\t\t\tstartIdx = Math.max(0, this.skillCursorIndex - Math.floor(selectorHeight / 2));\n\t\t\t\tstartIdx = Math.min(startIdx, this.filteredSkills.length - selectorHeight);\n\t\t\t}\n\t\t\tconst endIdx = Math.min(startIdx + selectorHeight, this.filteredSkills.length);\n\n\t\t\tif (startIdx > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↑ ${startIdx} more`)}`));\n\t\t\t}\n\n\t\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\t\tconst skill = this.filteredSkills[i]!;\n\t\t\t\tconst isCursor = i === this.skillCursorIndex;\n\t\t\t\tconst isSelected = this.skillSelectedNames.has(skill.name);\n\n\t\t\t\tconst prefix = isCursor ? th.fg(\"accent\", \"→ \") : \" \";\n\t\t\t\tconst checkbox = isSelected ? th.fg(\"success\", \"[x]\") : \"[ ]\";\n\t\t\t\tconst nameText = isCursor ? th.fg(\"accent\", skill.name) : skill.name;\n\t\t\t\tconst sourceBadge = th.fg(\"dim\", ` [${skill.source}]`);\n\t\t\t\tconst desc = skill.description\n\t\t\t\t\t? th.fg(\"dim\", ` - ${truncateToWidth(skill.description, 25)}`)\n\t\t\t\t\t: \"\";\n\n\t\t\t\tlines.push(this.row(` ${prefix}${checkbox} ${nameText}${sourceBadge}${desc}`));\n\t\t\t}\n\n\t\t\tconst remaining = this.filteredSkills.length - endIdx;\n\t\t\tif (remaining > 0) {\n\t\t\t\tlines.push(this.row(` ${th.fg(\"dim\", ` ↓ ${remaining} more`)}`));\n\t\t\t}\n\t\t}\n\n\t\tconst targetHeight = 18;\n\t\tfor (let i = lines.length; i < targetHeight; i++) {\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tlines.push(this.renderFooter(\" [Enter] Confirm • [Space] Toggle • [Esc] Cancel \"));\n\t\treturn lines;\n\t}\n\n\tprivate getShortcutHelpText(): string {\n\t\tconst th = this.theme;\n\t\tconst shortcut = (key: string, label: string) =>\n\t\t\tth.fg(\"accent\", `[${key}]`) + th.fg(\"dim\", label);\n\t\tconst backgroundState = this.runInBackground ? \"ON\" : \"OFF\";\n\t\tconst background = shortcut(\"b\", `Background:${backgroundState}`);\n\n\t\tswitch (this.mode) {\n\t\t\tcase 'single':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"w\", \"Output\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t\tcase 'parallel':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t\tcase 'chain':\n\t\t\t\treturn ` ${shortcut(\"e\", \"Task\")} ${shortcut(\"w\", \"Output\")} ${shortcut(\"r\", \"Reads\")} ${shortcut(\"p\", \"Prog\")} ${shortcut(\"s\", \"Skills\")} ${background}`;\n\t\t}\n\t}\n\n\tprivate getFooterText(): string {\n\t\treturn this.mode === 'single'\n\t\t\t? \" [Enter] Run • [Esc] Cancel \"\n\t\t\t: \" [Enter] Run • [Esc] Cancel • [↑↓] Navigate \";\n\t}\n\n\tprivate appendNotice(lines: string[]): void {\n\t\tif (!this.noticeMessage) return;\n\t\tconst color = this.noticeMessage.type === \"error\" ? \"error\" : \"success\";\n\t\tlines.push(this.row(` ${this.theme.fg(color, this.noticeMessage.text)}`));\n\t}\n\n\tprivate renderSingleMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst agentName = this.agentConfigs[0]?.name ?? \"unknown\";\n\t\tconst maxHeaderLen = innerW - 4;\n\t\tconst headerText = ` Agent: ${truncateToWidth(agentName, maxHeaderLen - 9)} `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst config = this.agentConfigs[0]!;\n\t\tconst behavior = this.getEffectiveBehavior(0);\n\n\t\tconst stepLabel = config.name;\n\t\tlines.push(this.row(` ${th.fg(\"accent\", \"▶ \" + stepLabel)}`));\n\n\t\tconst template = (this.templates[0] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\tconst taskLabel = th.fg(\"dim\", \"task: \");\n\t\tlines.push(this.row(` ${taskLabel}${truncateToWidth(template, innerW - 12)}`));\n\n\t\tconst writesValue = behavior.output === false\n\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t: (behavior.output || th.fg(\"dim\", \"(none)\"));\n\t\tconst writesLabel = th.fg(\"dim\", \"writes: \");\n\t\tlines.push(this.row(` ${writesLabel}${truncateToWidth(writesValue, innerW - 14)}`));\n\n\t\tconst skillsValue = behavior.skills === false\n\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderParallelMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst headerText = ` Parallel Tasks (${this.agentConfigs.length}) `;\n\t\tlines.push(this.renderHeader(headerText));\n\t\tlines.push(this.row(\"\"));\n\n\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\tconst config = this.agentConfigs[i]!;\n\t\t\tconst isSelected = i === this.selectedStep;\n\n\t\t\tconst color = isSelected ? \"accent\" : \"dim\";\n\t\t\tconst prefix = isSelected ? \"▶ \" : \" \";\n\t\t\tconst taskPrefix = `Task ${i + 1}: `;\n\t\t\tconst maxNameLen = innerW - 4 - prefix.length - taskPrefix.length;\n\t\t\tconst agentName = config.name.length > maxNameLen\n\t\t\t\t? config.name.slice(0, maxNameLen - 1) + \"…\"\n\t\t\t\t: config.name;\n\t\t\tconst taskLabel = `${taskPrefix}${agentName}`;\n\t\t\tlines.push(this.row(` ${th.fg(color, prefix + taskLabel)}`));\n\n\t\t\tconst template = (this.templates[i] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\t\tconst taskTextLabel = th.fg(\"dim\", \"task: \");\n\t\t\tlines.push(this.row(` ${taskTextLabel}${truncateToWidth(template, innerW - 12)}`));\n\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\t\t\tconst skillsValue = behavior.skills === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tif (this.agentConfigs.length > 0) lines.pop();\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tprivate renderChainMode(): string[] {\n\t\tconst innerW = this.width - 2;\n\t\tconst th = this.theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst chainLabel = this.agentConfigs.map((c) => c.name).join(\" → \");\n\t\tconst maxHeaderLen = innerW - 4;\n\t\tconst headerText = ` Chain: ${truncateToWidth(chainLabel, maxHeaderLen - 9)} `;\n\t\tlines.push(this.renderHeader(headerText));\n\n\t\tlines.push(this.row(\"\"));\n\n\t\tconst taskPreview = truncateToWidth(this.originalTask, innerW - 16);\n\t\tlines.push(this.row(` Original Task: ${taskPreview}`));\n\t\tconst chainDirPreview = truncateToWidth(this.chainDir ?? \"\", innerW - 12);\n\t\tlines.push(this.row(` Chain Dir: ${th.fg(\"dim\", chainDirPreview)}`));\n\n\t\tconst progressEnabled = this.agentConfigs.some((_, i) => this.getEffectiveBehavior(i).progress);\n\t\tconst progressValue = progressEnabled ? th.fg(\"success\", \"enabled\") : th.fg(\"dim\", \"disabled\");\n\t\tlines.push(this.row(` Progress: ${progressValue} ${th.fg(\"dim\", \"(press [p] to toggle)\")}`));\n\t\tlines.push(this.row(\"\"));\n\n\t\tfor (let i = 0; i < this.agentConfigs.length; i++) {\n\t\t\tconst config = this.agentConfigs[i]!;\n\t\t\tconst isSelected = i === this.selectedStep;\n\t\t\tconst behavior = this.getEffectiveBehavior(i);\n\n\t\t\tconst color = isSelected ? \"accent\" : \"dim\";\n\t\t\tconst prefix = isSelected ? \"▶ \" : \" \";\n\t\t\tconst stepPrefix = `Step ${i + 1}: `;\n\t\t\tconst maxNameLen = innerW - 4 - prefix.length - stepPrefix.length;\n\t\t\tconst agentName = config.name.length > maxNameLen\n\t\t\t\t? config.name.slice(0, maxNameLen - 1) + \"…\"\n\t\t\t\t: config.name;\n\t\t\tconst stepLabel = `${stepPrefix}${agentName}`;\n\t\t\tlines.push(\n\t\t\t\tthis.row(` ${th.fg(color, prefix + stepLabel)}`),\n\t\t\t);\n\n\t\t\tconst template = (this.templates[i] ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\t\tconst highlighted = template\n\t\t\t\t.replace(/\\{task\\}/g, th.fg(\"success\", \"{task}\"))\n\t\t\t\t.replace(/\\{previous\\}/g, th.fg(\"warning\", \"{previous}\"))\n\t\t\t\t.replace(/\\{chain_dir\\}/g, th.fg(\"accent\", \"{chain_dir}\"));\n\n\t\t\tconst templateLabel = th.fg(\"dim\", \"task: \");\n\t\t\tlines.push(this.row(` ${templateLabel}${truncateToWidth(highlighted, innerW - 12)}`));\n\n\t\t\tconst writesValue = behavior.output === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.output || th.fg(\"dim\", \"(none)\"));\n\t\t\tconst writesLabel = th.fg(\"dim\", \"writes: \");\n\t\t\tlines.push(this.row(` ${writesLabel}${truncateToWidth(writesValue, innerW - 14)}`));\n\n\t\t\tconst readsValue = behavior.reads === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.reads && behavior.reads.length > 0\n\t\t\t\t\t? behavior.reads.join(\", \")\n\t\t\t\t\t: th.fg(\"dim\", \"(none)\"));\n\t\t\tconst readsLabel = th.fg(\"dim\", \"reads: \");\n\t\t\tlines.push(this.row(` ${readsLabel}${truncateToWidth(readsValue, innerW - 13)}`));\n\n\t\t\tconst skillsValue = behavior.skills === false\n\t\t\t\t? th.fg(\"dim\", \"(disabled)\")\n\t\t\t\t: (behavior.skills?.length ? behavior.skills.join(\", \") : th.fg(\"dim\", \"(none)\"));\n\t\t\tconst skillsLabel = th.fg(\"dim\", \"skills: \");\n\t\t\tlines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));\n\n\t\t\tif (progressEnabled) {\n\t\t\t\tconst isFirstStep = i === 0;\n\t\t\t\tconst progressAction = isFirstStep \n\t\t\t\t\t? th.fg(\"success\", \"writes progress.md\")\n\t\t\t\t\t: th.fg(\"accent\", \"reads progress.md\");\n\t\t\t\tconst progressLabel = th.fg(\"dim\", \"progress: \");\n\t\t\t\tlines.push(this.row(` ${progressLabel}${progressAction}`));\n\t\t\t}\n\n\t\t\tif (i < this.agentConfigs.length - 1) {\n\t\t\t\tconst nextStepUsePrevious = (this.templates[i + 1] ?? \"\").includes(\"{previous}\");\n\t\t\t\tif (nextStepUsePrevious) {\n\t\t\t\t\tconst indicator = th.fg(\"dim\", \" ↳ response → \") + th.fg(\"warning\", \"{previous}\");\n\t\t\t\t\tlines.push(this.row(indicator));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(this.row(\"\"));\n\t\t}\n\n\t\tif (this.agentConfigs.length > 0) lines.pop();\n\t\tlines.push(this.row(this.getShortcutHelpText()));\n\t\tthis.appendNotice(lines);\n\t\tlines.push(this.renderFooter(this.getFooterText()));\n\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n\tdispose(): void {\n\t\tif (this.noticeMessageTimer) clearTimeout(this.noticeMessageTimer);\n\t\tthis.noticeMessageTimer = null;\n\t}\n}\n"]}
|
|
@@ -401,14 +401,6 @@ export class ChainClarifyComponent {
|
|
|
401
401
|
this.enterEditMode("template");
|
|
402
402
|
return;
|
|
403
403
|
}
|
|
404
|
-
if (data === "m") {
|
|
405
|
-
this.enterModelSelector();
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
if (data === "t") {
|
|
409
|
-
this.enterThinkingSelector();
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
404
|
if (data === "s") {
|
|
413
405
|
this.editingStep = this.selectedStep;
|
|
414
406
|
this.editMode = "skills";
|
|
@@ -963,11 +955,11 @@ export class ChainClarifyComponent {
|
|
|
963
955
|
const background = shortcut("b", `Background:${backgroundState}`);
|
|
964
956
|
switch (this.mode) {
|
|
965
957
|
case 'single':
|
|
966
|
-
return ` ${shortcut("e", "Task")} ${shortcut("
|
|
958
|
+
return ` ${shortcut("e", "Task")} ${shortcut("w", "Output")} ${shortcut("s", "Skills")} ${background}`;
|
|
967
959
|
case 'parallel':
|
|
968
|
-
return ` ${shortcut("e", "Task")} ${shortcut("
|
|
960
|
+
return ` ${shortcut("e", "Task")} ${shortcut("s", "Skills")} ${background}`;
|
|
969
961
|
case 'chain':
|
|
970
|
-
return ` ${shortcut("e", "Task")} ${shortcut("
|
|
962
|
+
return ` ${shortcut("e", "Task")} ${shortcut("w", "Output")} ${shortcut("r", "Reads")} ${shortcut("p", "Prog")} ${shortcut("s", "Skills")} ${background}`;
|
|
971
963
|
}
|
|
972
964
|
}
|
|
973
965
|
getFooterText() {
|
|
@@ -997,14 +989,6 @@ export class ChainClarifyComponent {
|
|
|
997
989
|
const template = (this.templates[0] ?? "").split("\n")[0] ?? "";
|
|
998
990
|
const taskLabel = th.fg("dim", "task: ");
|
|
999
991
|
lines.push(this.row(` ${taskLabel}${truncateToWidth(template, innerW - 12)}`));
|
|
1000
|
-
const effectiveModel = this.getEffectiveModel(0);
|
|
1001
|
-
const override = this.behaviorOverrides.get(0);
|
|
1002
|
-
const isOverridden = override?.model !== undefined;
|
|
1003
|
-
const modelValue = isOverridden
|
|
1004
|
-
? th.fg("warning", effectiveModel) + th.fg("dim", " ✎")
|
|
1005
|
-
: effectiveModel;
|
|
1006
|
-
const modelLabel = th.fg("dim", "model: ");
|
|
1007
|
-
lines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));
|
|
1008
992
|
const writesValue = behavior.output === false
|
|
1009
993
|
? th.fg("dim", "(disabled)")
|
|
1010
994
|
: (behavior.output || th.fg("dim", "(none)"));
|
|
@@ -1042,14 +1026,6 @@ export class ChainClarifyComponent {
|
|
|
1042
1026
|
const template = (this.templates[i] ?? "").split("\n")[0] ?? "";
|
|
1043
1027
|
const taskTextLabel = th.fg("dim", "task: ");
|
|
1044
1028
|
lines.push(this.row(` ${taskTextLabel}${truncateToWidth(template, innerW - 12)}`));
|
|
1045
|
-
const effectiveModel = this.getEffectiveModel(i);
|
|
1046
|
-
const override = this.behaviorOverrides.get(i);
|
|
1047
|
-
const isOverridden = override?.model !== undefined;
|
|
1048
|
-
const modelValue = isOverridden
|
|
1049
|
-
? th.fg("warning", effectiveModel) + th.fg("dim", " ✎")
|
|
1050
|
-
: effectiveModel;
|
|
1051
|
-
const modelLabel = th.fg("dim", "model: ");
|
|
1052
|
-
lines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));
|
|
1053
1029
|
const behavior = this.getEffectiveBehavior(i);
|
|
1054
1030
|
const skillsValue = behavior.skills === false
|
|
1055
1031
|
? th.fg("dim", "(disabled)")
|
|
@@ -1102,14 +1078,6 @@ export class ChainClarifyComponent {
|
|
|
1102
1078
|
.replace(/\{chain_dir\}/g, th.fg("accent", "{chain_dir}"));
|
|
1103
1079
|
const templateLabel = th.fg("dim", "task: ");
|
|
1104
1080
|
lines.push(this.row(` ${templateLabel}${truncateToWidth(highlighted, innerW - 12)}`));
|
|
1105
|
-
const effectiveModel = this.getEffectiveModel(i);
|
|
1106
|
-
const override = this.behaviorOverrides.get(i);
|
|
1107
|
-
const isOverridden = override?.model !== undefined;
|
|
1108
|
-
const modelValue = isOverridden
|
|
1109
|
-
? th.fg("warning", effectiveModel) + th.fg("dim", " ✎")
|
|
1110
|
-
: effectiveModel;
|
|
1111
|
-
const modelLabel = th.fg("dim", "model: ");
|
|
1112
|
-
lines.push(this.row(` ${modelLabel}${truncateToWidth(modelValue, innerW - 13)}`));
|
|
1113
1081
|
const writesValue = behavior.output === false
|
|
1114
1082
|
? th.fg("dim", "(disabled)")
|
|
1115
1083
|
: (behavior.output || th.fg("dim", "(none)"));
|