@caupulican/pi-adaptative 0.84.1 → 0.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +14 -8
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +14 -8
- package/dist/bundled-resources/skills/deduplicate-by-evidence/SKILL.md +7 -5
- package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +63 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +4 -2
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +3 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +6 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +1 -0
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +7 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +28 -0
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +2 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +46 -11
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/doctor.d.ts +1 -1
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +5 -4
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +1 -0
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +6 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/session-task-profile-store.d.ts +31 -0
- package/dist/core/orchestration/session-task-profile-store.d.ts.map +1 -0
- package/dist/core/orchestration/session-task-profile-store.js +138 -0
- package/dist/core/orchestration/session-task-profile-store.js.map +1 -0
- package/dist/core/orchestration/task-profile-writer.d.ts +58 -0
- package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -0
- package/dist/core/orchestration/task-profile-writer.js +165 -0
- package/dist/core/orchestration/task-profile-writer.js.map +1 -0
- package/dist/core/runtime-builder.d.ts +3 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +14 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/security/untrusted-boundary.d.ts.map +1 -1
- package/dist/core/security/untrusted-boundary.js +4 -6
- package/dist/core/security/untrusted-boundary.js.map +1 -1
- package/dist/core/session-role.d.ts.map +1 -1
- package/dist/core/session-role.js +1 -0
- package/dist/core/session-role.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +21 -23
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.js +1 -1
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -6
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -26
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate.js +4 -4
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +32 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +137 -69
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +22 -7
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +128 -55
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-intent.d.ts +70 -0
- package/dist/core/tools/file-mutation-intent.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-intent.js +325 -0
- package/dist/core/tools/file-mutation-intent.js.map +1 -0
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +41 -18
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/index.d.ts +3 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +31 -8
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/profile-writer.d.ts +33 -0
- package/dist/core/tools/profile-writer.d.ts.map +1 -0
- package/dist/core/tools/profile-writer.js +67 -0
- package/dist/core/tools/profile-writer.js.map +1 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +6 -11
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +2 -0
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
- package/dist/core/tools/tmux-dispatch.js +16 -2
- package/dist/core/tools/tmux-dispatch.js.map +1 -1
- package/dist/core/tools/write.d.ts +24 -7
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +182 -107
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jscpd-cli.d.ts +3 -0
- package/dist/jscpd-cli.d.ts.map +1 -0
- package/dist/jscpd-cli.js +22 -0
- package/dist/jscpd-cli.js.map +1 -0
- package/dist/modes/interactive/components/profile-resource-editor.js +2 -2
- package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +85 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/bundled-jscpd.d.ts +20 -0
- package/dist/utils/bundled-jscpd.d.ts.map +1 -0
- package/dist/utils/bundled-jscpd.js +154 -0
- package/dist/utils/bundled-jscpd.js.map +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +11 -0
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +22 -0
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/index.md +3 -0
- package/docs/managed-data-tools.md +15 -0
- package/docs/quickstart.md +2 -2
- package/docs/tool-boundary-performance-roadmap-2026-08-02.md +166 -0
- package/docs/tool-repair.md +1 -1
- package/docs/worker-profiles.md +16 -0
- package/examples/extensions/built-in-tool-renderer.ts +12 -5
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +8 -7
- package/examples/extensions/prompt-customizer.ts +4 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/ssh.ts +113 -24
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +112 -12
- package/package.json +7 -5
|
@@ -172,18 +172,13 @@ export function createTaskStepsToolDefinition(deps) {
|
|
|
172
172
|
return {
|
|
173
173
|
name: "task_steps",
|
|
174
174
|
label: "Task Steps",
|
|
175
|
-
description: "
|
|
176
|
-
promptSnippet: "Track
|
|
175
|
+
description: "Track the session's ordered multi-step checklist with status, notes, and evidence. Use goal for durable outcomes and delegate for workers.",
|
|
176
|
+
promptSnippet: "Track multi-step session work.",
|
|
177
177
|
promptGuidelines: [
|
|
178
|
-
"Use
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"Mark steps completed as soon as evidence is gathered, and attach concise evidence or a blocker reason through update.",
|
|
183
|
-
"Use action=intake with a complete steps array when preserving a raw multi-item dump; retain every item and do not silently drop entries.",
|
|
184
|
-
"When a goal is active, set requirementIds on each step that advances a goal requirement; do not rely on repeating requirement text.",
|
|
185
|
-
"Drain task_steps before final responses: leave no stale in_progress step, and explicitly discuss or defer remaining pending or blocked work.",
|
|
186
|
-
"Use goal for the durable goal ledger and delegate/delegate_status for worker lanes; do not emulate background execution inside task_steps.",
|
|
178
|
+
"Use for complex or explicitly tracked work; skip simple one-step work. Keep one step in_progress.",
|
|
179
|
+
"Batch known transitions. Address the first open step; record evidence or a blocker, and never call only to narrate unchanged state.",
|
|
180
|
+
"Use intake to preserve every supplied item; link steps to active goal requirementIds.",
|
|
181
|
+
"Before final output, clear stale in_progress state and discuss or defer remaining work. Goal owns outcomes; delegate/delegate_status own workers.",
|
|
187
182
|
],
|
|
188
183
|
parameters: taskStepsSchema,
|
|
189
184
|
renderShell: "self",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-steps.js","sourceRoot":"","sources":["../../../src/core/tools/task-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EACN,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,uBAAuB,EACvB,YAAY,EAIZ,cAAc,GACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAE3B,gBAAgB,GAChB,MAAM,0BAA0B,CAAC;AAElC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAEvG,SAAS,sBAAsB,CAAC,yBAAiC;IAChE,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QACvC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;YACzD,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,yBAAyB;SACtC,CAAC,CACF;QACD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;KACtG,CAAC;AACH,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAClC;IACC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IACnG,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC,CAC3G;IACD,GAAG,sBAAsB,CAAC,qDAAqD,CAAC;CAChF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAClC;IACC,MAAM,EAAE,IAAI,CAAC,KAAK,CACjB;QACC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;KACtB,EACD,EAAE,WAAW,EAAE,sDAAsD,EAAE,CACvE;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;QAC3B,QAAQ,EAAE,cAAc;QACxB,WAAW,EAAE,0FAA0F;KACvG,CAAC,CACF;IACD,EAAE,EAAE,IAAI,CAAC,QAAQ,CAChB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EAAE,0FAA0F;KACvG,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,GAAG,sBAAsB,CAAC,+EAA+E,CAAC;IAC1G,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,mEAAmE,EAAE,CAAC,CAClG;IACD,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC,CAAC;IAC/G,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;CAC9E,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AA0BF,SAAS,eAAe,CAAC,KAAyB;IACjD,OAAO;QACN,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACxB,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CACd,KAAqB;IAErB,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CACvC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,CACpE,CAAC,MAAM,CAAC;IACT,OAAO;QACN,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC7B,aAAa;QACb,uBAAuB,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC1D,CAAC;AACH,CAAC;AAED,2GAA2G;AAC3G,SAAS,qBAAqB,CAAC,MAAgC,EAAE,WAAgC;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;QACnC,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,EAAE;gBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;IACF,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC7B,MAAsB,EACtB,KAAqB,EACrB,UAA+B;IAE/B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACrH,OAAO,KAAK,CAAC,KAAK;SAChB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACvG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,MAAuB,EAAE,KAAa,EAAE,KAAsB;IAClF,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,cAAc,MAAM,YAAY,KAAK,EAAE,EAAE,CAAC;QACnF,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAiC;KACjH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA6B,EAAE,QAAiB;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO;YACN,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YACxC,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,qBAAqB;SACjD,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;IACvE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;IACxD,MAAM,OAAO,GAAG;QACf,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,SAAS;QACtD,GAAG,IAAI,CAAC,MAAM,OAAO;QACrB,GAAG,IAAI,OAAO;QACd,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,SAAS;QACxD,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAe;YACvB,IAAI,EAAE,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS;SAC1H,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAe,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAe;YACvB,IAAI,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,yBAAyB,OAAO,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,uBAAuB;SACpI,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAkB,EAAE,IAAI,EAAE,+CAA+C,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK;QAC3B,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YACnB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;gBAClB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oBAC5C,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,MAAM,CAAC;IACb,OAAO;QACN,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM;QACN,OAAO;QACP,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,0BAA0B;QACtF,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;KAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,IAA+B;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,OAAO;QACN,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,YAAY;QACnB,WAAW,EACV,uVAAuV;QACxV,aAAa,EAAE,kEAAkE;QACjF,gBAAgB,EAAE;YACjB,gKAAgK;YAChK,6FAA6F;YAC7F,6JAA6J;YAC7J,kLAAkL;YAClL,uHAAuH;YACvH,0IAA0I;YAC1I,qIAAqI;YACrI,8IAA8I;YAC9I,4IAA4I;SAC5I;QACD,UAAU,EAAE,eAAe;QAC3B,WAAW,EAAE,MAAM;QACnB,UAAU;YACT,OAAO,sBAAsB,EAAE,CAAC;QACjC,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK;YAClD,IAAI,SAAS;gBAAE,OAAO,sBAAsB,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,OAA2C,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO,IAAI,2BAA2B,CAAC,KAAK,EAAE;oBAC7C,KAAK,EAAE,YAAY;oBACnB,MAAM,EAAE,OAAO;oBACf,SAAS,EAAE,qCAAqC;iBAChD,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,sBAAsB,EAAE,CAAC;YAClE,OAAO,IAAI,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjG,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAyB;YACnD,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,OAAO,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,KAAK,GAAG,MAAM,CAAC;YACnB,IAAI,eAAmC,CAAC;YACxC,IAAI,cAAc,GAAsB,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACJ,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;oBACtB,KAAK,KAAK;wBACT,IAAI,CAAC,KAAK,CAAC,KAAK;4BAAE,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC;wBACrF,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACpD,cAAc,GAAG,qBAAqB,CACrC,MAAM,EACN,KAAK,EACL,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAC/C,CAAC;wBACF,MAAM;oBACP,KAAK,QAAQ;wBACZ,IAAI,CAAC,KAAK,CAAC,KAAK;4BACf,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,0CAA0C,EAAE,OAAO,CAAC,CAAC;wBACvF,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACpD,cAAc,GAAG,qBAAqB,CACrC,MAAM,EACN,KAAK,EACL,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAC/C,CAAC;wBACF,MAAM;oBACP,KAAK,KAAK;wBACT,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;wBAC9D,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;4BACtB,8EAA8E;4BAC9E,2EAA2E;4BAC3E,eAAe,GAAG,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;wBAChF,CAAC;wBACD,MAAM;oBACP,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE;4BACpB,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,0CAA0C,EAAE,OAAO,CAAC,CAAC;wBACvF,MAAM,QAAQ,GAAG,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;wBACjE,KAAK,GAAG,cAAc,CACrB,KAAK,EACL,KAAK,CAAC,EAAE,EACR;4BACC,OAAO,EAAE,KAAK,CAAC,OAAO;4BACtB,UAAU,EAAE,KAAK,CAAC,UAAU;4BAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,KAAK,EAAE,KAAK,CAAC,KAAK;4BAClB,cAAc,EAAE,KAAK,CAAC,cAAc;4BACpC,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;yBACxB,EACD,SAAS,CACT,CAAC;wBACF,+EAA+E;wBAC/E,8EAA8E;wBAC9E,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC9E,MAAM;oBACP,CAAC;oBACD,KAAK,OAAO;wBACX,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACzC,MAAM;oBACP,KAAK,SAAS;wBACb,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBAC3C,MAAM;oBACP,KAAK,MAAM;wBACV,IAAI,KAAK,CAAC,cAAc;4BAAE,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACrE,MAAM;gBACR,CAAC;gBAED,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC;gBACtE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;gBAClG,IAAI,OAAO;oBAAE,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAE5C,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,MAAM,WAAW,GAAa,EAAE,CAAC;gBACjC,IAAI,eAAe,EAAE,CAAC;oBACrB,WAAW,CAAC,IAAI,CACf,yCAAyC,eAAe,+BAA+B,CACvF,CAAC;gBACH,CAAC;gBACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,WAAW,CAAC,IAAI,CAAC,0DAA0D,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1G,CAAC;gBACD,IAAI,WAAW,CAAC,uBAAuB,EAAE,CAAC;oBACzC,WAAW,CAAC,IAAI,CACf,iHAAiH,CACjH,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE5E,MAAM,YAAY,GACjB,KAAK,CAAC,MAAM,KAAK,MAAM;oBACtB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,cAAc,KAAK,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC;gBAC5F,OAAO;oBACN,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,GAAG,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE;gCAC9C,eAAe,EAAE,KAAK,CAAC,aAAa;gCACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;6BACxB,CAAC,GAAG,OAAO,EAAE;yBACd;qBACD;oBACD,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,OAAO,EAAE,IAAI;wBACb,KAAK;wBACL,GAAG,WAAW;wBACd,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,iBAAiB,EAAE,eAAe;wBAClC,cAAc,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;qBACvC;iBAChC,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;YACnG,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\taddTaskStep,\n\tclearTaskSteps,\n\tcompactTaskSteps,\n\tcreateTaskStepsState,\n\tfindOpenDuplicateStep,\n\tformatTaskSteps,\n\thasUnverifiedCompletedStep,\n\tMAX_TASK_STEPS,\n\tresolveTaskStepSelector,\n\tsetTaskSteps,\n\ttype TaskStep,\n\ttype TaskStepInput,\n\ttype TaskStepsState,\n\tupdateTaskStep,\n} from \"../tasks/task-state.ts\";\nimport {\n\temptyOrchestrationCall,\n\tOrchestrationPanelComponent,\n\ttype OrchestrationPanelModel,\n\ttaskStepPanelRow,\n} from \"./orchestration-panel.ts\";\n\nconst statusSchema = Type.Union([\n\tType.Literal(\"pending\"),\n\tType.Literal(\"in_progress\"),\n\tType.Literal(\"completed\"),\n\tType.Literal(\"blocked\"),\n\tType.Literal(\"cancelled\"),\n]);\n\nconst prioritySchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"normal\"), Type.Literal(\"high\")]);\n\nfunction optionalTaskStepFields(requirementIdsDescription: string) {\n\treturn {\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\trequirementIds: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1, maxLength: 200 }), {\n\t\t\t\tmaxItems: 32,\n\t\t\t\tdescription: requirementIdsDescription,\n\t\t\t}),\n\t\t),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t};\n}\n\nconst stepInputSchema = Type.Object(\n\t{\n\t\tcontent: Type.String({ minLength: 1, maxLength: 2_000, description: \"Imperative task step text.\" }),\n\t\tactiveForm: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 2_000, description: \"Short present-progress label for active UI.\" }),\n\t\t),\n\t\t...optionalTaskStepFields(\"Goal requirement ids this foreground step advances.\"),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst taskStepsSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[\n\t\t\t\tType.Literal(\"set\"),\n\t\t\t\tType.Literal(\"add\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"clear\"),\n\t\t\t\tType.Literal(\"compact\"),\n\t\t\t\tType.Literal(\"intake\"),\n\t\t\t],\n\t\t\t{ description: \"Checklist action. Use list to read without mutation.\" },\n\t\t),\n\t\tsteps: Type.Optional(\n\t\t\tType.Array(stepInputSchema, {\n\t\t\t\tmaxItems: MAX_TASK_STEPS,\n\t\t\t\tdescription: \"Complete replacement list for set/intake. Intake preserves every supplied item in order.\",\n\t\t\t}),\n\t\t),\n\t\tid: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"For update: current/active, exact step id, unique id prefix, or unique content selector.\",\n\t\t\t}),\n\t\t),\n\t\tcontent: Type.Optional(Type.String({ minLength: 1, maxLength: 2_000 })),\n\t\tactiveForm: Type.Optional(Type.String({ maxLength: 2_000 })),\n\t\t...optionalTaskStepFields(\"Goal requirement ids this foreground step advances; [] clears existing links.\"),\n\t\tclearCompleted: Type.Optional(\n\t\t\tType.Boolean({ description: \"For list: compact completed and cancelled steps before rendering.\" }),\n\t\t),\n\t\tshowCompleted: Type.Optional(Type.Boolean({ description: \"Include completed and cancelled steps in output.\" })),\n\t\tmaxItems: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_TASK_STEPS })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type TaskStepsToolInput = Static<typeof taskStepsSchema>;\nexport type TaskStepsAction = TaskStepsToolInput[\"action\"];\n\nexport interface TaskStepsToolDetails {\n\taction: TaskStepsAction;\n\tapplied: boolean;\n\terror?: string;\n\tstate?: TaskStepsState;\n\tstepCount?: number;\n\topenStepCount?: number;\n\tverificationNudgeNeeded?: boolean;\n\tshowCompleted?: boolean;\n\t/** Set when `add` was a no-op because an open step already carries this content. */\n\tduplicateOfStepId?: string;\n\t/** Step ids silently demoted to pending because another step became active in this call. */\n\tdemotedStepIds?: readonly string[];\n}\n\nexport interface TaskStepsToolDependencies {\n\tgetTaskStepsState: () => TaskStepsState | undefined;\n\tsaveTaskStepsState: (state: TaskStepsState) => void;\n\tnow?: () => string;\n}\n\nfunction toTaskStepInput(input: TaskStepsToolInput): TaskStepInput {\n\treturn {\n\t\tcontent: input.content ?? \"\",\n\t\tactiveForm: input.activeForm,\n\t\tstatus: input.status,\n\t\tpriority: input.priority,\n\t\towner: input.owner,\n\t\trequirementIds: input.requirementIds,\n\t\tnote: input.note,\n\t\tevidence: input.evidence,\n\t};\n}\n\nfunction counts(\n\tstate: TaskStepsState,\n): Pick<TaskStepsToolDetails, \"stepCount\" | \"openStepCount\" | \"verificationNudgeNeeded\"> {\n\tconst openStepCount = state.steps.filter(\n\t\t(step) => step.status !== \"completed\" && step.status !== \"cancelled\",\n\t).length;\n\treturn {\n\t\tstepCount: state.steps.length,\n\t\topenStepCount,\n\t\tverificationNudgeNeeded: hasUnverifiedCompletedStep(state),\n\t};\n}\n\n/** Ids (from `resultSteps`, index-aligned with `inputs`) whose status was set explicitly by the caller. */\nfunction explicitStatusStepIds(inputs: readonly TaskStepInput[], resultSteps: readonly TaskStep[]): Set<string> {\n\tconst ids = new Set<string>();\n\tinputs.forEach((stepInput, index) => {\n\t\tif (stepInput.status !== undefined) {\n\t\t\tconst id = resultSteps[index]?.id;\n\t\t\tif (id) ids.add(id);\n\t\t}\n\t});\n\treturn ids;\n}\n\n/**\n * Steps that were in_progress before this call and are pending after, excluding any step whose\n * new status was set explicitly by the caller (an explicit change is not a \"silent\" demotion).\n */\nfunction computeDemotedStepIds(\n\tbefore: TaskStepsState,\n\tafter: TaskStepsState,\n\texcludeIds: ReadonlySet<string>,\n): string[] {\n\tconst beforeActiveIds = new Set(before.steps.filter((step) => step.status === \"in_progress\").map((step) => step.id));\n\treturn after.steps\n\t\t.filter((step) => beforeActiveIds.has(step.id) && step.status === \"pending\" && !excludeIds.has(step.id))\n\t\t.map((step) => step.id);\n}\n\nfunction errorResult(action: TaskStepsAction, error: string, state?: TaskStepsState) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text: `task_steps ${action} failed: ${error}` }],\n\t\tdetails: { action, applied: false, error, state, ...(state ? counts(state) : {}) } satisfies TaskStepsToolDetails,\n\t};\n}\n\nfunction taskStepsPanelModel(details: TaskStepsToolDetails, expanded: boolean): OrchestrationPanelModel {\n\tconst state = details.state;\n\tif (!state) {\n\t\treturn {\n\t\t\tlabel: \"task steps\",\n\t\t\taction: details.action,\n\t\t\tstatus: details.error ? \"error\" : \"idle\",\n\t\t\temptyText: details.error ?? \"No checklist state.\",\n\t\t};\n\t}\n\tconst active = state.steps.filter((step) => step.status === \"in_progress\");\n\tconst blocked = state.steps.filter((step) => step.status === \"blocked\");\n\tconst pending = state.steps.filter((step) => step.status === \"pending\");\n\tconst completed = state.steps.filter((step) => step.status === \"completed\");\n\tconst cancelled = state.steps.filter((step) => step.status === \"cancelled\");\n\tconst open = [...active, ...blocked, ...pending];\n\tconst terminal = details.showCompleted ? [...completed, ...cancelled] : [];\n\tconst candidates = [...open, ...terminal];\n\tconst limit = expanded ? 24 : 8;\n\tconst rows = candidates.slice(0, limit).map(taskStepPanelRow);\n\tconst archivedDone = state.archive.completed + state.archive.cancelled;\n\tconst done = completed.length + state.archive.completed;\n\tconst summary = [\n\t\tactive.length ? `${active.length} working` : undefined,\n\t\t`${open.length} open`,\n\t\t`${done} done`,\n\t\tblocked.length ? `${blocked.length} blocked` : undefined,\n\t\tarchivedDone ? `${archivedDone} archived` : undefined,\n\t].filter((value): value is string => value !== undefined);\n\tconst notices = [];\n\tif (!details.showCompleted && completed.length + cancelled.length > 0) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${completed.length + cancelled.length} finished step${completed.length + cancelled.length === 1 ? \"\" : \"s\"} hidden`,\n\t\t});\n\t}\n\tif (details.duplicateOfStepId) {\n\t\tnotices.push({ status: \"info\" as const, text: \"Duplicate open step ignored.\" });\n\t}\n\tif (details.demotedStepIds?.length) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${details.demotedStepIds.length} previous working step${details.demotedStepIds.length === 1 ? \"\" : \"s\"} returned to pending.`,\n\t\t});\n\t}\n\tif (details.verificationNudgeNeeded) {\n\t\tnotices.push({ status: \"warning\" as const, text: \"Completed work still needs attached evidence.\" });\n\t}\n\tconst status = details.error\n\t\t? \"error\"\n\t\t: blocked.length > 0\n\t\t\t? \"warning\"\n\t\t\t: active.length > 0\n\t\t\t\t? \"running\"\n\t\t\t\t: open.length === 0 && state.steps.length > 0\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: \"idle\";\n\treturn {\n\t\tlabel: \"task steps\",\n\t\taction: details.action,\n\t\tstatus,\n\t\tsummary,\n\t\trows,\n\t\tnotices,\n\t\temptyText: state.steps.length === 0 ? \"No tracked steps.\" : \"All open steps are done.\",\n\t\thiddenRowCount: Math.max(0, candidates.length - rows.length),\n\t};\n}\n\nexport function createTaskStepsToolDefinition(deps: TaskStepsToolDependencies): ToolDefinition {\n\tconst now = deps.now ?? (() => new Date().toISOString());\n\treturn {\n\t\tname: \"task_steps\",\n\t\tlabel: \"Task Steps\",\n\t\tdescription:\n\t\t\t\"Maintain the current session's native ordered checklist for multi-step work. Supports pending, in_progress, completed, blocked, and cancelled steps with notes and evidence. State is isolated to and persisted with the active session; use native goal for durable outcome requirements and native delegate/delegate_status for background workers.\",\n\t\tpromptSnippet: \"Track and drain multi-step work with a native session checklist.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use task_steps for complex work, explicit task-tracking requests, and harness/self-improvement work; keep exactly one step in_progress while actively working.\",\n\t\t\t\"Skip task_steps for simple single-action work unless the user explicitly requests tracking.\",\n\t\t\t\"Coalesce multiple checklist transitions into one set call when the complete next state is known; do not call task_steps only to narrate unchanged progress.\",\n\t\t\t\"Always address the first open task step before unrelated work: start it, complete/block/cancel it with evidence, ask one clarifying question, or explicitly defer or reorder it.\",\n\t\t\t\"Mark steps completed as soon as evidence is gathered, and attach concise evidence or a blocker reason through update.\",\n\t\t\t\"Use action=intake with a complete steps array when preserving a raw multi-item dump; retain every item and do not silently drop entries.\",\n\t\t\t\"When a goal is active, set requirementIds on each step that advances a goal requirement; do not rely on repeating requirement text.\",\n\t\t\t\"Drain task_steps before final responses: leave no stale in_progress step, and explicitly discuss or defer remaining pending or blocked work.\",\n\t\t\t\"Use goal for the durable goal ledger and delegate/delegate_status for worker lanes; do not emulate background execution inside task_steps.\",\n\t\t],\n\t\tparameters: taskStepsSchema,\n\t\trenderShell: \"self\",\n\t\trenderCall() {\n\t\t\treturn emptyOrchestrationCall();\n\t\t},\n\t\trenderResult(result, { expanded, isPartial }, theme) {\n\t\t\tif (isPartial) return emptyOrchestrationCall();\n\t\t\tconst details = result.details as TaskStepsToolDetails | undefined;\n\t\t\tif (!details) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"task steps\",\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\temptyText: \"No task-step details were returned.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!expanded && details.applied) return emptyOrchestrationCall();\n\t\t\treturn new OrchestrationPanelComponent(theme, taskStepsPanelModel(details, expanded), expanded);\n\t\t},\n\t\tasync execute(_toolCallId, input: TaskStepsToolInput) {\n\t\t\tconst timestamp = now();\n\t\t\tconst current = deps.getTaskStepsState();\n\t\t\tconst before = current ?? createTaskStepsState(timestamp);\n\t\t\tlet state = before;\n\t\t\tlet duplicateStepId: string | undefined;\n\t\t\tlet demotedStepIds: readonly string[] = [];\n\t\t\ttry {\n\t\t\t\tswitch (input.action) {\n\t\t\t\t\tcase \"set\":\n\t\t\t\t\t\tif (!input.steps) return errorResult(input.action, \"set requires steps[].\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"intake\":\n\t\t\t\t\t\tif (!input.steps)\n\t\t\t\t\t\t\treturn errorResult(input.action, \"intake requires a complete steps[] list.\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"add\":\n\t\t\t\t\t\tstate = addTaskStep(state, toTaskStepInput(input), timestamp);\n\t\t\t\t\t\tif (state === before) {\n\t\t\t\t\t\t\t// The reducer returned the unchanged state: an open step already carries this\n\t\t\t\t\t\t\t// content, so nothing was created. Name the existing step in the response.\n\t\t\t\t\t\t\tduplicateStepId = findOpenDuplicateStep(before.steps, input.content ?? \"\")?.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!input.id?.trim())\n\t\t\t\t\t\t\treturn errorResult(input.action, \"update requires id or a unique selector.\", current);\n\t\t\t\t\t\tconst selected = resolveTaskStepSelector(before.steps, input.id);\n\t\t\t\t\t\tstate = updateTaskStep(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tinput.id,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontent: input.content,\n\t\t\t\t\t\t\t\tactiveForm: input.activeForm,\n\t\t\t\t\t\t\t\tstatus: input.status,\n\t\t\t\t\t\t\t\tpriority: input.priority,\n\t\t\t\t\t\t\t\towner: input.owner,\n\t\t\t\t\t\t\t\trequirementIds: input.requirementIds,\n\t\t\t\t\t\t\t\tnote: input.note,\n\t\t\t\t\t\t\t\tevidence: input.evidence,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Exclude the explicitly targeted step: its own status change was requested by\n\t\t\t\t\t\t// the caller, so it is never a \"silent\" demotion even if it moved to pending.\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(before, state, new Set([selected.id]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\":\n\t\t\t\t\t\tstate = clearTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"compact\":\n\t\t\t\t\t\tstate = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\tif (input.clearCompleted) state = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst isNoopDuplicateAdd = input.action === \"add\" && state === before;\n\t\t\t\tconst mutated = (input.action !== \"list\" || input.clearCompleted === true) && !isNoopDuplicateAdd;\n\t\t\t\tif (mutated) deps.saveTaskStepsState(state);\n\n\t\t\t\tconst stateCounts = counts(state);\n\t\t\t\tconst noticeLines: string[] = [];\n\t\t\t\tif (duplicateStepId) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t`Duplicate open step ignored; existing ${duplicateStepId} already tracks this content.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (demotedStepIds.length > 0) {\n\t\t\t\t\tnoticeLines.push(`Demoted to pending because another step became active: ${demotedStepIds.join(\", \")}.`);\n\t\t\t\t}\n\t\t\t\tif (stateCounts.verificationNudgeNeeded) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t\"Reminder: a completed step has no evidence attached; attach evidence via update before treating it as verified.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst notices = noticeLines.length > 0 ? `\\n${noticeLines.join(\"\\n\")}` : \"\";\n\n\t\t\t\tconst headerAction =\n\t\t\t\t\tinput.action === \"list\"\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: `task_steps ${input.action} ${duplicateStepId ? \"ignored (duplicate)\" : \"recorded\"}.\\n`;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${headerAction}${formatTaskSteps(state, {\n\t\t\t\t\t\t\t\tincludeTerminal: input.showCompleted,\n\t\t\t\t\t\t\t\tmaxItems: input.maxItems,\n\t\t\t\t\t\t\t})}${notices}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tapplied: true,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t...stateCounts,\n\t\t\t\t\t\tshowCompleted: input.showCompleted,\n\t\t\t\t\t\tduplicateOfStepId: duplicateStepId,\n\t\t\t\t\t\tdemotedStepIds: demotedStepIds.length > 0 ? demotedStepIds : undefined,\n\t\t\t\t\t} satisfies TaskStepsToolDetails,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn errorResult(input.action, error instanceof Error ? error.message : String(error), current);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"task-steps.js","sourceRoot":"","sources":["../../../src/core/tools/task-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EACN,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,uBAAuB,EACvB,YAAY,EAIZ,cAAc,GACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAE3B,gBAAgB,GAChB,MAAM,0BAA0B,CAAC;AAElC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAEvG,SAAS,sBAAsB,CAAC,yBAAiC;IAChE,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QACvC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;YACzD,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,yBAAyB;SACtC,CAAC,CACF;QACD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;KACtG,CAAC;AACH,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAClC;IACC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IACnG,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC,CAC3G;IACD,GAAG,sBAAsB,CAAC,qDAAqD,CAAC;CAChF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAClC;IACC,MAAM,EAAE,IAAI,CAAC,KAAK,CACjB;QACC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;KACtB,EACD,EAAE,WAAW,EAAE,sDAAsD,EAAE,CACvE;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;QAC3B,QAAQ,EAAE,cAAc;QACxB,WAAW,EAAE,0FAA0F;KACvG,CAAC,CACF;IACD,EAAE,EAAE,IAAI,CAAC,QAAQ,CAChB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EAAE,0FAA0F;KACvG,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,GAAG,sBAAsB,CAAC,+EAA+E,CAAC;IAC1G,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,mEAAmE,EAAE,CAAC,CAClG;IACD,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC,CAAC;IAC/G,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;CAC9E,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AA0BF,SAAS,eAAe,CAAC,KAAyB;IACjD,OAAO;QACN,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACxB,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CACd,KAAqB;IAErB,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CACvC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,CACpE,CAAC,MAAM,CAAC;IACT,OAAO;QACN,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC7B,aAAa;QACb,uBAAuB,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC1D,CAAC;AACH,CAAC;AAED,2GAA2G;AAC3G,SAAS,qBAAqB,CAAC,MAAgC,EAAE,WAAgC;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;QACnC,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,EAAE;gBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;IACF,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC7B,MAAsB,EACtB,KAAqB,EACrB,UAA+B;IAE/B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACrH,OAAO,KAAK,CAAC,KAAK;SAChB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACvG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,MAAuB,EAAE,KAAa,EAAE,KAAsB;IAClF,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,cAAc,MAAM,YAAY,KAAK,EAAE,EAAE,CAAC;QACnF,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAiC;KACjH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA6B,EAAE,QAAiB;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO;YACN,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YACxC,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,qBAAqB;SACjD,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;IACvE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;IACxD,MAAM,OAAO,GAAG;QACf,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,SAAS;QACtD,GAAG,IAAI,CAAC,MAAM,OAAO;QACrB,GAAG,IAAI,OAAO;QACd,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,SAAS;QACxD,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAe;YACvB,IAAI,EAAE,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS;SAC1H,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAe,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAe;YACvB,IAAI,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,yBAAyB,OAAO,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,uBAAuB;SACpI,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAkB,EAAE,IAAI,EAAE,+CAA+C,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK;QAC3B,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YACnB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;gBAClB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oBAC5C,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,MAAM,CAAC;IACb,OAAO;QACN,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM;QACN,OAAO;QACP,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,0BAA0B;QACtF,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;KAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,IAA+B;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,OAAO;QACN,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,YAAY;QACnB,WAAW,EACV,4IAA4I;QAC7I,aAAa,EAAE,gCAAgC;QAC/C,gBAAgB,EAAE;YACjB,mGAAmG;YACnG,qIAAqI;YACrI,uFAAuF;YACvF,mJAAmJ;SACnJ;QACD,UAAU,EAAE,eAAe;QAC3B,WAAW,EAAE,MAAM;QACnB,UAAU;YACT,OAAO,sBAAsB,EAAE,CAAC;QACjC,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK;YAClD,IAAI,SAAS;gBAAE,OAAO,sBAAsB,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,OAA2C,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO,IAAI,2BAA2B,CAAC,KAAK,EAAE;oBAC7C,KAAK,EAAE,YAAY;oBACnB,MAAM,EAAE,OAAO;oBACf,SAAS,EAAE,qCAAqC;iBAChD,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,sBAAsB,EAAE,CAAC;YAClE,OAAO,IAAI,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjG,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAyB;YACnD,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,OAAO,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,KAAK,GAAG,MAAM,CAAC;YACnB,IAAI,eAAmC,CAAC;YACxC,IAAI,cAAc,GAAsB,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACJ,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;oBACtB,KAAK,KAAK;wBACT,IAAI,CAAC,KAAK,CAAC,KAAK;4BAAE,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC;wBACrF,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACpD,cAAc,GAAG,qBAAqB,CACrC,MAAM,EACN,KAAK,EACL,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAC/C,CAAC;wBACF,MAAM;oBACP,KAAK,QAAQ;wBACZ,IAAI,CAAC,KAAK,CAAC,KAAK;4BACf,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,0CAA0C,EAAE,OAAO,CAAC,CAAC;wBACvF,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACpD,cAAc,GAAG,qBAAqB,CACrC,MAAM,EACN,KAAK,EACL,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAC/C,CAAC;wBACF,MAAM;oBACP,KAAK,KAAK;wBACT,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;wBAC9D,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;4BACtB,8EAA8E;4BAC9E,2EAA2E;4BAC3E,eAAe,GAAG,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;wBAChF,CAAC;wBACD,MAAM;oBACP,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE;4BACpB,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,0CAA0C,EAAE,OAAO,CAAC,CAAC;wBACvF,MAAM,QAAQ,GAAG,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;wBACjE,KAAK,GAAG,cAAc,CACrB,KAAK,EACL,KAAK,CAAC,EAAE,EACR;4BACC,OAAO,EAAE,KAAK,CAAC,OAAO;4BACtB,UAAU,EAAE,KAAK,CAAC,UAAU;4BAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,KAAK,EAAE,KAAK,CAAC,KAAK;4BAClB,cAAc,EAAE,KAAK,CAAC,cAAc;4BACpC,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;yBACxB,EACD,SAAS,CACT,CAAC;wBACF,+EAA+E;wBAC/E,8EAA8E;wBAC9E,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC9E,MAAM;oBACP,CAAC;oBACD,KAAK,OAAO;wBACX,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACzC,MAAM;oBACP,KAAK,SAAS;wBACb,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBAC3C,MAAM;oBACP,KAAK,MAAM;wBACV,IAAI,KAAK,CAAC,cAAc;4BAAE,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;wBACrE,MAAM;gBACR,CAAC;gBAED,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC;gBACtE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;gBAClG,IAAI,OAAO;oBAAE,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAE5C,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,MAAM,WAAW,GAAa,EAAE,CAAC;gBACjC,IAAI,eAAe,EAAE,CAAC;oBACrB,WAAW,CAAC,IAAI,CACf,yCAAyC,eAAe,+BAA+B,CACvF,CAAC;gBACH,CAAC;gBACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,WAAW,CAAC,IAAI,CAAC,0DAA0D,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1G,CAAC;gBACD,IAAI,WAAW,CAAC,uBAAuB,EAAE,CAAC;oBACzC,WAAW,CAAC,IAAI,CACf,iHAAiH,CACjH,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE5E,MAAM,YAAY,GACjB,KAAK,CAAC,MAAM,KAAK,MAAM;oBACtB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,cAAc,KAAK,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC;gBAC5F,OAAO;oBACN,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,GAAG,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE;gCAC9C,eAAe,EAAE,KAAK,CAAC,aAAa;gCACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;6BACxB,CAAC,GAAG,OAAO,EAAE;yBACd;qBACD;oBACD,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,OAAO,EAAE,IAAI;wBACb,KAAK;wBACL,GAAG,WAAW;wBACd,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,iBAAiB,EAAE,eAAe;wBAClC,cAAc,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;qBACvC;iBAChC,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;YACnG,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\taddTaskStep,\n\tclearTaskSteps,\n\tcompactTaskSteps,\n\tcreateTaskStepsState,\n\tfindOpenDuplicateStep,\n\tformatTaskSteps,\n\thasUnverifiedCompletedStep,\n\tMAX_TASK_STEPS,\n\tresolveTaskStepSelector,\n\tsetTaskSteps,\n\ttype TaskStep,\n\ttype TaskStepInput,\n\ttype TaskStepsState,\n\tupdateTaskStep,\n} from \"../tasks/task-state.ts\";\nimport {\n\temptyOrchestrationCall,\n\tOrchestrationPanelComponent,\n\ttype OrchestrationPanelModel,\n\ttaskStepPanelRow,\n} from \"./orchestration-panel.ts\";\n\nconst statusSchema = Type.Union([\n\tType.Literal(\"pending\"),\n\tType.Literal(\"in_progress\"),\n\tType.Literal(\"completed\"),\n\tType.Literal(\"blocked\"),\n\tType.Literal(\"cancelled\"),\n]);\n\nconst prioritySchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"normal\"), Type.Literal(\"high\")]);\n\nfunction optionalTaskStepFields(requirementIdsDescription: string) {\n\treturn {\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\trequirementIds: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1, maxLength: 200 }), {\n\t\t\t\tmaxItems: 32,\n\t\t\t\tdescription: requirementIdsDescription,\n\t\t\t}),\n\t\t),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t};\n}\n\nconst stepInputSchema = Type.Object(\n\t{\n\t\tcontent: Type.String({ minLength: 1, maxLength: 2_000, description: \"Imperative task step text.\" }),\n\t\tactiveForm: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 2_000, description: \"Short present-progress label for active UI.\" }),\n\t\t),\n\t\t...optionalTaskStepFields(\"Goal requirement ids this foreground step advances.\"),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst taskStepsSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[\n\t\t\t\tType.Literal(\"set\"),\n\t\t\t\tType.Literal(\"add\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"clear\"),\n\t\t\t\tType.Literal(\"compact\"),\n\t\t\t\tType.Literal(\"intake\"),\n\t\t\t],\n\t\t\t{ description: \"Checklist action. Use list to read without mutation.\" },\n\t\t),\n\t\tsteps: Type.Optional(\n\t\t\tType.Array(stepInputSchema, {\n\t\t\t\tmaxItems: MAX_TASK_STEPS,\n\t\t\t\tdescription: \"Complete replacement list for set/intake. Intake preserves every supplied item in order.\",\n\t\t\t}),\n\t\t),\n\t\tid: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"For update: current/active, exact step id, unique id prefix, or unique content selector.\",\n\t\t\t}),\n\t\t),\n\t\tcontent: Type.Optional(Type.String({ minLength: 1, maxLength: 2_000 })),\n\t\tactiveForm: Type.Optional(Type.String({ maxLength: 2_000 })),\n\t\t...optionalTaskStepFields(\"Goal requirement ids this foreground step advances; [] clears existing links.\"),\n\t\tclearCompleted: Type.Optional(\n\t\t\tType.Boolean({ description: \"For list: compact completed and cancelled steps before rendering.\" }),\n\t\t),\n\t\tshowCompleted: Type.Optional(Type.Boolean({ description: \"Include completed and cancelled steps in output.\" })),\n\t\tmaxItems: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_TASK_STEPS })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type TaskStepsToolInput = Static<typeof taskStepsSchema>;\nexport type TaskStepsAction = TaskStepsToolInput[\"action\"];\n\nexport interface TaskStepsToolDetails {\n\taction: TaskStepsAction;\n\tapplied: boolean;\n\terror?: string;\n\tstate?: TaskStepsState;\n\tstepCount?: number;\n\topenStepCount?: number;\n\tverificationNudgeNeeded?: boolean;\n\tshowCompleted?: boolean;\n\t/** Set when `add` was a no-op because an open step already carries this content. */\n\tduplicateOfStepId?: string;\n\t/** Step ids silently demoted to pending because another step became active in this call. */\n\tdemotedStepIds?: readonly string[];\n}\n\nexport interface TaskStepsToolDependencies {\n\tgetTaskStepsState: () => TaskStepsState | undefined;\n\tsaveTaskStepsState: (state: TaskStepsState) => void;\n\tnow?: () => string;\n}\n\nfunction toTaskStepInput(input: TaskStepsToolInput): TaskStepInput {\n\treturn {\n\t\tcontent: input.content ?? \"\",\n\t\tactiveForm: input.activeForm,\n\t\tstatus: input.status,\n\t\tpriority: input.priority,\n\t\towner: input.owner,\n\t\trequirementIds: input.requirementIds,\n\t\tnote: input.note,\n\t\tevidence: input.evidence,\n\t};\n}\n\nfunction counts(\n\tstate: TaskStepsState,\n): Pick<TaskStepsToolDetails, \"stepCount\" | \"openStepCount\" | \"verificationNudgeNeeded\"> {\n\tconst openStepCount = state.steps.filter(\n\t\t(step) => step.status !== \"completed\" && step.status !== \"cancelled\",\n\t).length;\n\treturn {\n\t\tstepCount: state.steps.length,\n\t\topenStepCount,\n\t\tverificationNudgeNeeded: hasUnverifiedCompletedStep(state),\n\t};\n}\n\n/** Ids (from `resultSteps`, index-aligned with `inputs`) whose status was set explicitly by the caller. */\nfunction explicitStatusStepIds(inputs: readonly TaskStepInput[], resultSteps: readonly TaskStep[]): Set<string> {\n\tconst ids = new Set<string>();\n\tinputs.forEach((stepInput, index) => {\n\t\tif (stepInput.status !== undefined) {\n\t\t\tconst id = resultSteps[index]?.id;\n\t\t\tif (id) ids.add(id);\n\t\t}\n\t});\n\treturn ids;\n}\n\n/**\n * Steps that were in_progress before this call and are pending after, excluding any step whose\n * new status was set explicitly by the caller (an explicit change is not a \"silent\" demotion).\n */\nfunction computeDemotedStepIds(\n\tbefore: TaskStepsState,\n\tafter: TaskStepsState,\n\texcludeIds: ReadonlySet<string>,\n): string[] {\n\tconst beforeActiveIds = new Set(before.steps.filter((step) => step.status === \"in_progress\").map((step) => step.id));\n\treturn after.steps\n\t\t.filter((step) => beforeActiveIds.has(step.id) && step.status === \"pending\" && !excludeIds.has(step.id))\n\t\t.map((step) => step.id);\n}\n\nfunction errorResult(action: TaskStepsAction, error: string, state?: TaskStepsState) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text: `task_steps ${action} failed: ${error}` }],\n\t\tdetails: { action, applied: false, error, state, ...(state ? counts(state) : {}) } satisfies TaskStepsToolDetails,\n\t};\n}\n\nfunction taskStepsPanelModel(details: TaskStepsToolDetails, expanded: boolean): OrchestrationPanelModel {\n\tconst state = details.state;\n\tif (!state) {\n\t\treturn {\n\t\t\tlabel: \"task steps\",\n\t\t\taction: details.action,\n\t\t\tstatus: details.error ? \"error\" : \"idle\",\n\t\t\temptyText: details.error ?? \"No checklist state.\",\n\t\t};\n\t}\n\tconst active = state.steps.filter((step) => step.status === \"in_progress\");\n\tconst blocked = state.steps.filter((step) => step.status === \"blocked\");\n\tconst pending = state.steps.filter((step) => step.status === \"pending\");\n\tconst completed = state.steps.filter((step) => step.status === \"completed\");\n\tconst cancelled = state.steps.filter((step) => step.status === \"cancelled\");\n\tconst open = [...active, ...blocked, ...pending];\n\tconst terminal = details.showCompleted ? [...completed, ...cancelled] : [];\n\tconst candidates = [...open, ...terminal];\n\tconst limit = expanded ? 24 : 8;\n\tconst rows = candidates.slice(0, limit).map(taskStepPanelRow);\n\tconst archivedDone = state.archive.completed + state.archive.cancelled;\n\tconst done = completed.length + state.archive.completed;\n\tconst summary = [\n\t\tactive.length ? `${active.length} working` : undefined,\n\t\t`${open.length} open`,\n\t\t`${done} done`,\n\t\tblocked.length ? `${blocked.length} blocked` : undefined,\n\t\tarchivedDone ? `${archivedDone} archived` : undefined,\n\t].filter((value): value is string => value !== undefined);\n\tconst notices = [];\n\tif (!details.showCompleted && completed.length + cancelled.length > 0) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${completed.length + cancelled.length} finished step${completed.length + cancelled.length === 1 ? \"\" : \"s\"} hidden`,\n\t\t});\n\t}\n\tif (details.duplicateOfStepId) {\n\t\tnotices.push({ status: \"info\" as const, text: \"Duplicate open step ignored.\" });\n\t}\n\tif (details.demotedStepIds?.length) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${details.demotedStepIds.length} previous working step${details.demotedStepIds.length === 1 ? \"\" : \"s\"} returned to pending.`,\n\t\t});\n\t}\n\tif (details.verificationNudgeNeeded) {\n\t\tnotices.push({ status: \"warning\" as const, text: \"Completed work still needs attached evidence.\" });\n\t}\n\tconst status = details.error\n\t\t? \"error\"\n\t\t: blocked.length > 0\n\t\t\t? \"warning\"\n\t\t\t: active.length > 0\n\t\t\t\t? \"running\"\n\t\t\t\t: open.length === 0 && state.steps.length > 0\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: \"idle\";\n\treturn {\n\t\tlabel: \"task steps\",\n\t\taction: details.action,\n\t\tstatus,\n\t\tsummary,\n\t\trows,\n\t\tnotices,\n\t\temptyText: state.steps.length === 0 ? \"No tracked steps.\" : \"All open steps are done.\",\n\t\thiddenRowCount: Math.max(0, candidates.length - rows.length),\n\t};\n}\n\nexport function createTaskStepsToolDefinition(deps: TaskStepsToolDependencies): ToolDefinition {\n\tconst now = deps.now ?? (() => new Date().toISOString());\n\treturn {\n\t\tname: \"task_steps\",\n\t\tlabel: \"Task Steps\",\n\t\tdescription:\n\t\t\t\"Track the session's ordered multi-step checklist with status, notes, and evidence. Use goal for durable outcomes and delegate for workers.\",\n\t\tpromptSnippet: \"Track multi-step session work.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use for complex or explicitly tracked work; skip simple one-step work. Keep one step in_progress.\",\n\t\t\t\"Batch known transitions. Address the first open step; record evidence or a blocker, and never call only to narrate unchanged state.\",\n\t\t\t\"Use intake to preserve every supplied item; link steps to active goal requirementIds.\",\n\t\t\t\"Before final output, clear stale in_progress state and discuss or defer remaining work. Goal owns outcomes; delegate/delegate_status own workers.\",\n\t\t],\n\t\tparameters: taskStepsSchema,\n\t\trenderShell: \"self\",\n\t\trenderCall() {\n\t\t\treturn emptyOrchestrationCall();\n\t\t},\n\t\trenderResult(result, { expanded, isPartial }, theme) {\n\t\t\tif (isPartial) return emptyOrchestrationCall();\n\t\t\tconst details = result.details as TaskStepsToolDetails | undefined;\n\t\t\tif (!details) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"task steps\",\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\temptyText: \"No task-step details were returned.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!expanded && details.applied) return emptyOrchestrationCall();\n\t\t\treturn new OrchestrationPanelComponent(theme, taskStepsPanelModel(details, expanded), expanded);\n\t\t},\n\t\tasync execute(_toolCallId, input: TaskStepsToolInput) {\n\t\t\tconst timestamp = now();\n\t\t\tconst current = deps.getTaskStepsState();\n\t\t\tconst before = current ?? createTaskStepsState(timestamp);\n\t\t\tlet state = before;\n\t\t\tlet duplicateStepId: string | undefined;\n\t\t\tlet demotedStepIds: readonly string[] = [];\n\t\t\ttry {\n\t\t\t\tswitch (input.action) {\n\t\t\t\t\tcase \"set\":\n\t\t\t\t\t\tif (!input.steps) return errorResult(input.action, \"set requires steps[].\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"intake\":\n\t\t\t\t\t\tif (!input.steps)\n\t\t\t\t\t\t\treturn errorResult(input.action, \"intake requires a complete steps[] list.\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"add\":\n\t\t\t\t\t\tstate = addTaskStep(state, toTaskStepInput(input), timestamp);\n\t\t\t\t\t\tif (state === before) {\n\t\t\t\t\t\t\t// The reducer returned the unchanged state: an open step already carries this\n\t\t\t\t\t\t\t// content, so nothing was created. Name the existing step in the response.\n\t\t\t\t\t\t\tduplicateStepId = findOpenDuplicateStep(before.steps, input.content ?? \"\")?.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!input.id?.trim())\n\t\t\t\t\t\t\treturn errorResult(input.action, \"update requires id or a unique selector.\", current);\n\t\t\t\t\t\tconst selected = resolveTaskStepSelector(before.steps, input.id);\n\t\t\t\t\t\tstate = updateTaskStep(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tinput.id,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontent: input.content,\n\t\t\t\t\t\t\t\tactiveForm: input.activeForm,\n\t\t\t\t\t\t\t\tstatus: input.status,\n\t\t\t\t\t\t\t\tpriority: input.priority,\n\t\t\t\t\t\t\t\towner: input.owner,\n\t\t\t\t\t\t\t\trequirementIds: input.requirementIds,\n\t\t\t\t\t\t\t\tnote: input.note,\n\t\t\t\t\t\t\t\tevidence: input.evidence,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Exclude the explicitly targeted step: its own status change was requested by\n\t\t\t\t\t\t// the caller, so it is never a \"silent\" demotion even if it moved to pending.\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(before, state, new Set([selected.id]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\":\n\t\t\t\t\t\tstate = clearTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"compact\":\n\t\t\t\t\t\tstate = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\tif (input.clearCompleted) state = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst isNoopDuplicateAdd = input.action === \"add\" && state === before;\n\t\t\t\tconst mutated = (input.action !== \"list\" || input.clearCompleted === true) && !isNoopDuplicateAdd;\n\t\t\t\tif (mutated) deps.saveTaskStepsState(state);\n\n\t\t\t\tconst stateCounts = counts(state);\n\t\t\t\tconst noticeLines: string[] = [];\n\t\t\t\tif (duplicateStepId) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t`Duplicate open step ignored; existing ${duplicateStepId} already tracks this content.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (demotedStepIds.length > 0) {\n\t\t\t\t\tnoticeLines.push(`Demoted to pending because another step became active: ${demotedStepIds.join(\", \")}.`);\n\t\t\t\t}\n\t\t\t\tif (stateCounts.verificationNudgeNeeded) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t\"Reminder: a completed step has no evidence attached; attach evidence via update before treating it as verified.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst notices = noticeLines.length > 0 ? `\\n${noticeLines.join(\"\\n\")}` : \"\";\n\n\t\t\t\tconst headerAction =\n\t\t\t\t\tinput.action === \"list\"\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: `task_steps ${input.action} ${duplicateStepId ? \"ignored (duplicate)\" : \"recorded\"}.\\n`;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${headerAction}${formatTaskSteps(state, {\n\t\t\t\t\t\t\t\tincludeTerminal: input.showCompleted,\n\t\t\t\t\t\t\t\tmaxItems: input.maxItems,\n\t\t\t\t\t\t\t})}${notices}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tapplied: true,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t...stateCounts,\n\t\t\t\t\t\tshowCompleted: input.showCompleted,\n\t\t\t\t\t\tduplicateOfStepId: duplicateStepId,\n\t\t\t\t\t\tdemotedStepIds: demotedStepIds.length > 0 ? demotedStepIds : undefined,\n\t\t\t\t\t} satisfies TaskStepsToolDetails,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn errorResult(input.action, error instanceof Error ? error.message : String(error), current);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
|
@@ -6,6 +6,8 @@ import type { LaneWorkerRefusal } from "../model-capability.ts";
|
|
|
6
6
|
* with no direct dependency on `AgentSession`/`ExtensionRunner`/`BackgroundLaneController`.
|
|
7
7
|
*/
|
|
8
8
|
export interface TmuxDispatchDeps {
|
|
9
|
+
/** Runtime platform seam. Native Windows has no supported tmux backend; WSL reports `linux`. */
|
|
10
|
+
platform?: NodeJS.Platform;
|
|
9
11
|
/** Look up a registered tool by name -- the SAME seam the model's own tool calls resolve
|
|
10
12
|
* through (`AgentSession.getToolDefinition` -> `RuntimeBuilder.getToolDefinition`). `undefined`
|
|
11
13
|
* when the tmux extension is not loaded in this session -- an honest, non-fatal skip, not a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-dispatch.d.ts","sourceRoot":"","sources":["../../../src/core/tools/tmux-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;uCAGmC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAChE;;0BAEsB;IACtB,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;IAC/C;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACnE;;iDAE6C;IAC7C,SAAS,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACtB,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClF;;;;;;;OAOG;IACH,yBAAyB,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;CAChE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG5D;
|
|
1
|
+
{"version":3,"file":"tmux-dispatch.d.ts","sourceRoot":"","sources":["../../../src/core/tools/tmux-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B;;;uCAGmC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAChE;;0BAEsB;IACtB,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;IAC/C;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACnE;;iDAE6C;IAC7C,SAAS,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACtB,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClF;;;;;;;OAOG;IACH,yBAAyB,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;CAChE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG5D;AAaD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+EnD"}
|
|
@@ -30,12 +30,27 @@ export async function dispatchTmuxWorker(deps, args) {
|
|
|
30
30
|
if (deps.evaluateWorkerLaneRefusal?.() !== undefined) {
|
|
31
31
|
return { skipReason: "worker_capability_insufficient" };
|
|
32
32
|
}
|
|
33
|
+
if ((deps.platform ?? process.platform) === "win32")
|
|
34
|
+
return { skipReason: "tmux_unavailable" };
|
|
33
35
|
const toolDef = deps.getToolDefinition("tmux_agent_manager");
|
|
34
36
|
if (!toolDef)
|
|
35
37
|
return { skipReason: "tmux_extension_not_loaded" };
|
|
36
38
|
const goalId = deps.getGoalId();
|
|
37
39
|
const ctx = deps.createExtensionContext();
|
|
38
|
-
|
|
40
|
+
const toolCallId = `goal-dispatch:${goalId ?? "?"}:${args.requirementId}`;
|
|
41
|
+
try {
|
|
42
|
+
const guardResult = await toolDef.execute(`${toolCallId}:guard`, { action: "guard" }, ctx.signal, undefined, ctx);
|
|
43
|
+
const guard = guardResult.details?.guard;
|
|
44
|
+
if (guard?.allowed !== true)
|
|
45
|
+
return { skipReason: "tmux_unavailable" };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// A guard failure is side-effect free. Treat it as backend unavailability so the goal owner can
|
|
49
|
+
// safely choose its native worker fallback without fabricating a tmux lane.
|
|
50
|
+
return { skipReason: "tmux_unavailable" };
|
|
51
|
+
}
|
|
52
|
+
// Availability first, then lane-first: when worktree-sync is wired, create the lane only after
|
|
53
|
+
// tmux's pure guard succeeds and BEFORE any fire_task call so a
|
|
39
54
|
// creation refusal (max lanes, invalid key, git error, ...) aborts cleanly with no tmux/pane side
|
|
40
55
|
// effect ever having run. The specific engine refusal code is deliberately collapsed onto the one
|
|
41
56
|
// stable `worktree_create_failed` skip reason -- same narrow `{laneId?, skipReason?}` contract
|
|
@@ -67,7 +82,6 @@ export async function dispatchTmuxWorker(deps, args) {
|
|
|
67
82
|
: { provider: "pi", name: "goal-worker" },
|
|
68
83
|
],
|
|
69
84
|
};
|
|
70
|
-
const toolCallId = `goal-dispatch:${goalId ?? "?"}:${args.requirementId}`;
|
|
71
85
|
let result;
|
|
72
86
|
try {
|
|
73
87
|
result = await toolDef.execute(toolCallId, params, ctx.signal, undefined, ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-dispatch.js","sourceRoot":"","sources":["../../../src/core/tools/tmux-dispatch.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport type { LaneWorkerRefusal } from \"../model-capability.ts\";\n\n/**\n * Dependencies for {@link dispatchTmuxWorker}, injected from the construction site\n * (`RuntimeBuilder`) so the adapter itself stays a small, unit-testable, faux-tool-driven module\n * with no direct dependency on `AgentSession`/`ExtensionRunner`/`BackgroundLaneController`.\n */\nexport interface TmuxDispatchDeps {\n\t/** Look up a registered tool by name -- the SAME seam the model's own tool calls resolve\n\t * through (`AgentSession.getToolDefinition` -> `RuntimeBuilder.getToolDefinition`). `undefined`\n\t * when the tmux extension is not loaded in this session -- an honest, non-fatal skip, not a\n\t * crash and not a silent no-op. */\n\tgetToolDefinition: (name: string) => ToolDefinition | undefined;\n\t/** Build a fresh, non-turn-bound `ExtensionContext` for this call\n\t * (`ExtensionRunner.createContext()`) -- safe to invoke from the goal/idle path, outside any\n\t * live model turn. */\n\tcreateExtensionContext: () => ExtensionContext;\n\t/**\n\t * Confirm that the tmux extension's caller-chosen lane id (reconstructed below from the\n\t * `fire_task` result's `details.job`) was durably registered by the host. The returned id is\n\t * identity-preserving and is the same value `Requirement.boundLaneId` uses.\n\t */\n\tresolveManagedLaneId: (callerLaneId: string) => string | undefined;\n\t/** Active goal id, threaded onto the `fire_task` call so the dispatched lane is goal-tagged\n\t * (`ManagedLaneEvent.goalId`) -- `undefined` when no goal is active (dispatch still proceeds;\n\t * the resulting lane is simply untagged). */\n\tgetGoalId: () => string | undefined;\n\t/**\n\t * Worktree-sync lane-first dispatch (opt-in -- wired ONLY inside `runtime-builder.ts`'s\n\t * `worktreeSync.enabled` block, via the engine's `createLane`): when present, `dispatchTmuxWorker`\n\t * creates a fresh worktree-sync lane for this requirement BEFORE issuing any `fire_task` call, so\n\t * a creation refusal aborts cleanly before any tmux/pane side effect ever runs -- never a\n\t * half-made lane, never a fabricated worktree. On success the dispatched agent's `cwd` is the new\n\t * lane worktree and it carries `worktreeLane` (threaded to the tmux extension's launch profile --\n\t * see `dispatch-grant.ts`'s `buildLaunchProfileFlags`). Absent dep -> existing byte-identical\n\t * `params.agents` (no `cwd`/`worktreeLane`), exactly as before this field existed.\n\t */\n\tcreateLaneWorktree?: (args: {\n\t\tgoalId?: string;\n\t\trequirementId: string;\n\t}) => Promise<{ laneKey: string; worktreePath: string } | { skipReason: string }>;\n\t/**\n\t * Lane-worker capability eligibility (opt-in -- wired only from `runtime-builder.ts`, backed by\n\t * `AgentSession.getLaneWorkerRefusal`): checked FIRST, before `createLaneWorktree`, so an\n\t * ineligible model's dispatch is refused before any lane/pane side effect ever runs. This is the\n\t * parent's best-effort check only -- the dispatched child session refuses authoritatively at its\n\t * own startup (main.ts) regardless of what the parent decides here. Absent dep -> no capability\n\t * check runs, byte-identical to before this field existed.\n\t */\n\tevaluateWorkerLaneRefusal?: () => LaneWorkerRefusal | undefined;\n}\n\n/**\n * Classify a `fire_task` launch failure into an honest, stable skip reason. For an UNATTENDED\n * caller (`ctx.hasUI === false`, always true from the goal/idle path) `authorizeLaunch`'s ONLY\n * refusal throw is the no-standing-grant error (`tmux-agent-manager/index.ts`'s `authorizeLaunch`,\n * message containing the stable phrase \"no standing grant\") -- matched here by substring since the\n * extension throws a plain `Error`, not a tagged error code (documented follow-up hardening, not\n * blocking). Every other thrown error (a bad jobId, a live session-name collision,\n * an environment failure) maps onto the generic `\"tmux_dispatch_failed\"` -- still surfaced through\n * the existing `dispatchSkipReason` contract, never a crash and never a silently-ignored failure.\n */\nexport function classifyDispatchError(error: unknown): string {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn message.includes(\"no standing grant\") ? \"no_standing_grant\" : \"tmux_dispatch_failed\";\n}\n\ninterface FireTaskResultDetails {\n\tjob?: {\n\t\tid?: string;\n\t\tagents?: ReadonlyArray<{ id?: string }>;\n\t};\n}\n\n/**\n * Structurally dispatch ONE persistent tmux worker agent for a single goal requirement, by\n * invoking the SAME `tmux_agent_manager` `fire_task` tool call the model itself would make. Core\n * -- not model discretion -- decides WHEN this fires (the goal tool's `dispatchTarget:\"tmux\"`\n * routing gates the call); the launch itself always still goes through the extension's own\n * grant-gated `authorizeLaunch`, so an ungranted unattended call is honestly refused here (never a\n * silent launch, never a fabricated laneId) and the refusal is surfaced through the existing\n * `dispatchSkipReason` contract on the goal tool's response.\n */\nexport async function dispatchTmuxWorker(\n\tdeps: TmuxDispatchDeps,\n\targs: { requirementId: string; instructions: string },\n): Promise<{ laneId?: string; skipReason?: string }> {\n\t// Capability check FIRST -- before the tool-definition lookup and before createLaneWorktree --\n\t// so an ineligible model's dispatch is refused with zero lane/pane/tool side effect. The coarse\n\t// \"worker_capability_insufficient\" skip reason is the stable contract code on the goal tool's\n\t// response; the granular reason (class/window/tool-calling) lives only in the refusal object\n\t// itself, surfaced by the caller for logging (see model-capability.ts's formatLaneWorkerRefusal).\n\tif (deps.evaluateWorkerLaneRefusal?.() !== undefined) {\n\t\treturn { skipReason: \"worker_capability_insufficient\" };\n\t}\n\n\tconst toolDef = deps.getToolDefinition(\"tmux_agent_manager\");\n\tif (!toolDef) return { skipReason: \"tmux_extension_not_loaded\" };\n\n\tconst goalId = deps.getGoalId();\n\tconst ctx = deps.createExtensionContext();\n\n\t// Lane-first: when worktree-sync is wired, create the lane BEFORE any fire_task call so a\n\t// creation refusal (max lanes, invalid key, git error, ...) aborts cleanly with no tmux/pane side\n\t// effect ever having run. The specific engine refusal code is deliberately collapsed onto the one\n\t// stable `worktree_create_failed` skip reason -- same narrow `{laneId?, skipReason?}` contract\n\t// every other skip path here already uses; the engine's own detail lives in its audit log, not in\n\t// this narrow return.\n\tlet laneWorktree: { laneKey: string; worktreePath: string } | undefined;\n\tif (deps.createLaneWorktree) {\n\t\tconst created = await deps.createLaneWorktree({ goalId, requirementId: args.requirementId });\n\t\tif (\"skipReason\" in created) return { skipReason: \"worktree_create_failed\" };\n\t\tlaneWorktree = created;\n\t}\n\n\t// Single-agent 1:1 mapping: a bare fire_task with no `agents` defaults to a THREE-agent\n\t// team (pi/agy/codex -- `DEFAULT_AGENT_PROVIDERS`), which would mint three lanes for one\n\t// requirement. A goal-bound dispatch must map to exactly one lane, so `agents` is always\n\t// passed explicitly here.\n\tconst params = {\n\t\taction: \"fire_task\",\n\t\ttask: args.instructions,\n\t\tgoalId,\n\t\tagents: [\n\t\t\tlaneWorktree\n\t\t\t\t? {\n\t\t\t\t\t\tprovider: \"pi\",\n\t\t\t\t\t\tname: \"goal-worker\",\n\t\t\t\t\t\tcwd: laneWorktree.worktreePath,\n\t\t\t\t\t\tworktreeLane: laneWorktree.laneKey,\n\t\t\t\t\t}\n\t\t\t\t: { provider: \"pi\", name: \"goal-worker\" },\n\t\t],\n\t};\n\tconst toolCallId = `goal-dispatch:${goalId ?? \"?\"}:${args.requirementId}`;\n\n\tlet result: Awaited<ReturnType<ToolDefinition[\"execute\"]>>;\n\ttry {\n\t\tresult = await toolDef.execute(toolCallId, params, ctx.signal, undefined, ctx);\n\t} catch (error) {\n\t\treturn { skipReason: classifyDispatchError(error) };\n\t}\n\n\t// Correlate: the extension reports its dispatch under its OWN caller-chosen laneId\n\t// (`tmux:${job.id}:${agent.id}`, reconstructed here from the tool result's `details.job` --\n\t// the same format `agentLaneId` builds extension-side) which the host's `recordManagedLane`\n\t// bridge preserves as the canonical durable id; `resolveManagedLaneId` confirms that the\n\t// matching dispatch report reached the host before the goal binds it.\n\tconst job = (result.details as FireTaskResultDetails | undefined)?.job;\n\tconst primary = job?.agents?.[0];\n\tif (!job?.id || !primary?.id) return { skipReason: \"tmux_dispatch_incomplete\" };\n\n\tconst callerLaneId = `tmux:${job.id}:${primary.id}`;\n\tconst registeredLaneId = deps.resolveManagedLaneId(callerLaneId);\n\treturn registeredLaneId === callerLaneId ? { laneId: callerLaneId } : { skipReason: \"lane_correlation_failed\" };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tmux-dispatch.js","sourceRoot":"","sources":["../../../src/core/tools/tmux-dispatch.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport type { LaneWorkerRefusal } from \"../model-capability.ts\";\n\n/**\n * Dependencies for {@link dispatchTmuxWorker}, injected from the construction site\n * (`RuntimeBuilder`) so the adapter itself stays a small, unit-testable, faux-tool-driven module\n * with no direct dependency on `AgentSession`/`ExtensionRunner`/`BackgroundLaneController`.\n */\nexport interface TmuxDispatchDeps {\n\t/** Runtime platform seam. Native Windows has no supported tmux backend; WSL reports `linux`. */\n\tplatform?: NodeJS.Platform;\n\t/** Look up a registered tool by name -- the SAME seam the model's own tool calls resolve\n\t * through (`AgentSession.getToolDefinition` -> `RuntimeBuilder.getToolDefinition`). `undefined`\n\t * when the tmux extension is not loaded in this session -- an honest, non-fatal skip, not a\n\t * crash and not a silent no-op. */\n\tgetToolDefinition: (name: string) => ToolDefinition | undefined;\n\t/** Build a fresh, non-turn-bound `ExtensionContext` for this call\n\t * (`ExtensionRunner.createContext()`) -- safe to invoke from the goal/idle path, outside any\n\t * live model turn. */\n\tcreateExtensionContext: () => ExtensionContext;\n\t/**\n\t * Confirm that the tmux extension's caller-chosen lane id (reconstructed below from the\n\t * `fire_task` result's `details.job`) was durably registered by the host. The returned id is\n\t * identity-preserving and is the same value `Requirement.boundLaneId` uses.\n\t */\n\tresolveManagedLaneId: (callerLaneId: string) => string | undefined;\n\t/** Active goal id, threaded onto the `fire_task` call so the dispatched lane is goal-tagged\n\t * (`ManagedLaneEvent.goalId`) -- `undefined` when no goal is active (dispatch still proceeds;\n\t * the resulting lane is simply untagged). */\n\tgetGoalId: () => string | undefined;\n\t/**\n\t * Worktree-sync lane-first dispatch (opt-in -- wired ONLY inside `runtime-builder.ts`'s\n\t * `worktreeSync.enabled` block, via the engine's `createLane`): when present, `dispatchTmuxWorker`\n\t * creates a fresh worktree-sync lane for this requirement BEFORE issuing any `fire_task` call, so\n\t * a creation refusal aborts cleanly before any tmux/pane side effect ever runs -- never a\n\t * half-made lane, never a fabricated worktree. On success the dispatched agent's `cwd` is the new\n\t * lane worktree and it carries `worktreeLane` (threaded to the tmux extension's launch profile --\n\t * see `dispatch-grant.ts`'s `buildLaunchProfileFlags`). Absent dep -> existing byte-identical\n\t * `params.agents` (no `cwd`/`worktreeLane`), exactly as before this field existed.\n\t */\n\tcreateLaneWorktree?: (args: {\n\t\tgoalId?: string;\n\t\trequirementId: string;\n\t}) => Promise<{ laneKey: string; worktreePath: string } | { skipReason: string }>;\n\t/**\n\t * Lane-worker capability eligibility (opt-in -- wired only from `runtime-builder.ts`, backed by\n\t * `AgentSession.getLaneWorkerRefusal`): checked FIRST, before `createLaneWorktree`, so an\n\t * ineligible model's dispatch is refused before any lane/pane side effect ever runs. This is the\n\t * parent's best-effort check only -- the dispatched child session refuses authoritatively at its\n\t * own startup (main.ts) regardless of what the parent decides here. Absent dep -> no capability\n\t * check runs, byte-identical to before this field existed.\n\t */\n\tevaluateWorkerLaneRefusal?: () => LaneWorkerRefusal | undefined;\n}\n\n/**\n * Classify a `fire_task` launch failure into an honest, stable skip reason. For an UNATTENDED\n * caller (`ctx.hasUI === false`, always true from the goal/idle path) `authorizeLaunch`'s ONLY\n * refusal throw is the no-standing-grant error (`tmux-agent-manager/index.ts`'s `authorizeLaunch`,\n * message containing the stable phrase \"no standing grant\") -- matched here by substring since the\n * extension throws a plain `Error`, not a tagged error code (documented follow-up hardening, not\n * blocking). Every other thrown error (a bad jobId, a live session-name collision,\n * an environment failure) maps onto the generic `\"tmux_dispatch_failed\"` -- still surfaced through\n * the existing `dispatchSkipReason` contract, never a crash and never a silently-ignored failure.\n */\nexport function classifyDispatchError(error: unknown): string {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn message.includes(\"no standing grant\") ? \"no_standing_grant\" : \"tmux_dispatch_failed\";\n}\n\ninterface FireTaskResultDetails {\n\tjob?: {\n\t\tid?: string;\n\t\tagents?: ReadonlyArray<{ id?: string }>;\n\t};\n}\n\ninterface TmuxGuardResultDetails {\n\tguard?: { allowed?: boolean };\n}\n\n/**\n * Structurally dispatch ONE persistent tmux worker agent for a single goal requirement, by\n * invoking the SAME `tmux_agent_manager` `fire_task` tool call the model itself would make. Core\n * -- not model discretion -- decides WHEN this fires (the goal tool's `dispatchTarget:\"tmux\"`\n * routing gates the call); the launch itself always still goes through the extension's own\n * grant-gated `authorizeLaunch`, so an ungranted unattended call is honestly refused here (never a\n * silent launch, never a fabricated laneId) and the refusal is surfaced through the existing\n * `dispatchSkipReason` contract on the goal tool's response.\n */\nexport async function dispatchTmuxWorker(\n\tdeps: TmuxDispatchDeps,\n\targs: { requirementId: string; instructions: string },\n): Promise<{ laneId?: string; skipReason?: string }> {\n\t// Capability check FIRST -- before the tool-definition lookup and before createLaneWorktree --\n\t// so an ineligible model's dispatch is refused with zero lane/pane/tool side effect. The coarse\n\t// \"worker_capability_insufficient\" skip reason is the stable contract code on the goal tool's\n\t// response; the granular reason (class/window/tool-calling) lives only in the refusal object\n\t// itself, surfaced by the caller for logging (see model-capability.ts's formatLaneWorkerRefusal).\n\tif (deps.evaluateWorkerLaneRefusal?.() !== undefined) {\n\t\treturn { skipReason: \"worker_capability_insufficient\" };\n\t}\n\tif ((deps.platform ?? process.platform) === \"win32\") return { skipReason: \"tmux_unavailable\" };\n\n\tconst toolDef = deps.getToolDefinition(\"tmux_agent_manager\");\n\tif (!toolDef) return { skipReason: \"tmux_extension_not_loaded\" };\n\n\tconst goalId = deps.getGoalId();\n\tconst ctx = deps.createExtensionContext();\n\tconst toolCallId = `goal-dispatch:${goalId ?? \"?\"}:${args.requirementId}`;\n\ttry {\n\t\tconst guardResult = await toolDef.execute(`${toolCallId}:guard`, { action: \"guard\" }, ctx.signal, undefined, ctx);\n\t\tconst guard = (guardResult.details as TmuxGuardResultDetails | undefined)?.guard;\n\t\tif (guard?.allowed !== true) return { skipReason: \"tmux_unavailable\" };\n\t} catch {\n\t\t// A guard failure is side-effect free. Treat it as backend unavailability so the goal owner can\n\t\t// safely choose its native worker fallback without fabricating a tmux lane.\n\t\treturn { skipReason: \"tmux_unavailable\" };\n\t}\n\n\t// Availability first, then lane-first: when worktree-sync is wired, create the lane only after\n\t// tmux's pure guard succeeds and BEFORE any fire_task call so a\n\t// creation refusal (max lanes, invalid key, git error, ...) aborts cleanly with no tmux/pane side\n\t// effect ever having run. The specific engine refusal code is deliberately collapsed onto the one\n\t// stable `worktree_create_failed` skip reason -- same narrow `{laneId?, skipReason?}` contract\n\t// every other skip path here already uses; the engine's own detail lives in its audit log, not in\n\t// this narrow return.\n\tlet laneWorktree: { laneKey: string; worktreePath: string } | undefined;\n\tif (deps.createLaneWorktree) {\n\t\tconst created = await deps.createLaneWorktree({ goalId, requirementId: args.requirementId });\n\t\tif (\"skipReason\" in created) return { skipReason: \"worktree_create_failed\" };\n\t\tlaneWorktree = created;\n\t}\n\n\t// Single-agent 1:1 mapping: a bare fire_task with no `agents` defaults to a THREE-agent\n\t// team (pi/agy/codex -- `DEFAULT_AGENT_PROVIDERS`), which would mint three lanes for one\n\t// requirement. A goal-bound dispatch must map to exactly one lane, so `agents` is always\n\t// passed explicitly here.\n\tconst params = {\n\t\taction: \"fire_task\",\n\t\ttask: args.instructions,\n\t\tgoalId,\n\t\tagents: [\n\t\t\tlaneWorktree\n\t\t\t\t? {\n\t\t\t\t\t\tprovider: \"pi\",\n\t\t\t\t\t\tname: \"goal-worker\",\n\t\t\t\t\t\tcwd: laneWorktree.worktreePath,\n\t\t\t\t\t\tworktreeLane: laneWorktree.laneKey,\n\t\t\t\t\t}\n\t\t\t\t: { provider: \"pi\", name: \"goal-worker\" },\n\t\t],\n\t};\n\tlet result: Awaited<ReturnType<ToolDefinition[\"execute\"]>>;\n\ttry {\n\t\tresult = await toolDef.execute(toolCallId, params, ctx.signal, undefined, ctx);\n\t} catch (error) {\n\t\treturn { skipReason: classifyDispatchError(error) };\n\t}\n\n\t// Correlate: the extension reports its dispatch under its OWN caller-chosen laneId\n\t// (`tmux:${job.id}:${agent.id}`, reconstructed here from the tool result's `details.job` --\n\t// the same format `agentLaneId` builds extension-side) which the host's `recordManagedLane`\n\t// bridge preserves as the canonical durable id; `resolveManagedLaneId` confirms that the\n\t// matching dispatch report reached the host before the goal binds it.\n\tconst job = (result.details as FireTaskResultDetails | undefined)?.job;\n\tconst primary = job?.agents?.[0];\n\tif (!job?.id || !primary?.id) return { skipReason: \"tmux_dispatch_incomplete\" };\n\n\tconst callerLaneId = `tmux:${job.id}:${primary.id}`;\n\tconst registeredLaneId = deps.resolveManagedLaneId(callerLaneId);\n\treturn registeredLaneId === callerLaneId ? { laneId: callerLaneId } : { skipReason: \"lane_correlation_failed\" };\n}\n"]}
|
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
import type { AgentTool } from "@caupulican/pi-agent-core";
|
|
2
2
|
import { type Static, Type } from "typebox";
|
|
3
3
|
import type { ToolDefinition } from "../extensions/types.ts";
|
|
4
|
-
|
|
4
|
+
import { FileMutationIntentController } from "./file-mutation-intent.ts";
|
|
5
|
+
declare const writeSchema: Type.TUnion<[Type.TObject<{
|
|
6
|
+
action: Type.TLiteral<"prepare">;
|
|
5
7
|
path: Type.TString;
|
|
8
|
+
}>, Type.TObject<{
|
|
9
|
+
action: Type.TLiteral<"commit">;
|
|
10
|
+
path: Type.TString;
|
|
11
|
+
intentId: Type.TString;
|
|
6
12
|
content: Type.TString;
|
|
7
|
-
}
|
|
13
|
+
}>, Type.TObject<{
|
|
14
|
+
action: Type.TLiteral<"commit">;
|
|
15
|
+
path: Type.TString;
|
|
16
|
+
intentId: Type.TString;
|
|
17
|
+
contentRef: Type.TString;
|
|
18
|
+
}>]>;
|
|
8
19
|
export type WriteToolInput = Static<typeof writeSchema>;
|
|
9
20
|
/**
|
|
10
21
|
* Pluggable operations for the write tool.
|
|
11
22
|
* Override these to delegate file writing to remote systems (for example SSH).
|
|
12
23
|
*/
|
|
13
24
|
export interface WriteOperations {
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
/** Read existing file contents when available for encoding preservation */
|
|
17
|
-
readFile?: (absolutePath: string) => Promise<Buffer>;
|
|
25
|
+
/** Atomically create a new file and fail if any entry already occupies the path. */
|
|
26
|
+
createFile: (absolutePath: string, content: string) => Promise<void>;
|
|
18
27
|
/** Create directory recursively */
|
|
19
28
|
mkdir: (dir: string) => Promise<void>;
|
|
20
29
|
}
|
|
21
30
|
export interface WriteToolOptions {
|
|
22
31
|
/** Custom operations for file writing. Default: local filesystem */
|
|
23
32
|
operations?: WriteOperations;
|
|
33
|
+
/** Session-owned two-phase intent and exact-content-reference authority. */
|
|
34
|
+
intentController?: FileMutationIntentController;
|
|
35
|
+
}
|
|
36
|
+
export interface WriteToolDetails {
|
|
37
|
+
phase: "prepared" | "committed";
|
|
38
|
+
intentId?: string;
|
|
39
|
+
contentRef?: string;
|
|
40
|
+
byteCount?: number;
|
|
24
41
|
}
|
|
25
|
-
export declare function createWriteToolDefinition(cwd: string, options?: WriteToolOptions): ToolDefinition<typeof writeSchema,
|
|
42
|
+
export declare function createWriteToolDefinition(cwd: string, options?: WriteToolOptions): ToolDefinition<typeof writeSchema, WriteToolDetails>;
|
|
26
43
|
export declare function createWriteTool(cwd: string, options?: WriteToolOptions): AgentTool<typeof writeSchema>;
|
|
27
44
|
export {};
|
|
28
45
|
//# sourceMappingURL=write.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAA6B,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAYpG,QAAA,MAAM,WAAW;;;;;;;;;;;;;IAsBf,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,oFAAoF;IACpF,UAAU,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,mCAAmC;IACnC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAOD,MAAM,WAAW,gBAAgB;IAChC,oEAAoE;IACpE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA8LD,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACxB,cAAc,CAAC,OAAO,WAAW,EAAE,gBAAgB,CAAC,CAkItD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,OAAO,WAAW,CAAC,CAEtG"}
|