@tea-agent/loop-agent 0.43.0-next.17 → 0.43.0-next.3

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.
Files changed (187) hide show
  1. package/CHANGELOG.md +9 -140
  2. package/dist/application/task-lifecycle/advance.js +4 -17
  3. package/dist/application/task-lifecycle/observe.js +29 -43
  4. package/dist/application/task-lifecycle/plan-transitions.js +4 -5
  5. package/dist/build-stamp.json +3 -3
  6. package/dist/commands/client-recovery.js +55 -20
  7. package/dist/commands/new-task.js +5 -0
  8. package/dist/commands/status.js +57 -0
  9. package/dist/commands/task-contract.js +269 -0
  10. package/dist/executors/dag-pi-executor.js +230 -269
  11. package/dist/executors/pi-executor.js +0 -2
  12. package/dist/executors/pi-sdk-executor.js +39 -77
  13. package/dist/executors/shell-executor.js +2 -3
  14. package/dist/executors/shell-write-guard.js +32 -27
  15. package/dist/shared/pi-context-pressure/extension.js +16 -26
  16. package/dist/shared/pi-retry-settings.js +0 -40
  17. package/dist/shared/prompts.js +26 -0
  18. package/dist/task/config.js +2 -0
  19. package/dist/task/contract/validate-draft.js +106 -0
  20. package/dist/task/goal.js +3 -0
  21. package/dist/task/index.js +12 -0
  22. package/dist/task/lifecycle.js +1 -0
  23. package/dist/task/operator/capabilities.js +6 -0
  24. package/dist/task/operator/envelope.js +2 -0
  25. package/dist/task/operator/index.js +5 -0
  26. package/dist/task/operator/registry.js +2 -0
  27. package/dist/task/operator/types.js +1 -0
  28. package/dist/task/paths.js +1 -0
  29. package/dist/task/source-prepare/source-fidelity-pi.js +2 -2
  30. package/dist/task/source-references.js +23 -48
  31. package/dist/task/source-state.js +1 -0
  32. package/dist/task/subagent-guidance.js +1 -0
  33. package/dist/worker/console/chat/assistant-content.js +2 -23
  34. package/dist/worker/console/chat/explore-tools.js +0 -13
  35. package/dist/worker/console/chat/pi-runtime.js +1182 -221
  36. package/dist/worker/console/chat/routes.js +71 -213
  37. package/dist/worker/console/chat/sdd-data-alignment.js +9 -65
  38. package/dist/worker/console/chat/session-catalog.js +0 -32
  39. package/dist/worker/console/chat/session-store.js +6 -22
  40. package/dist/worker/console/chat/shortcuts.js +0 -6
  41. package/dist/worker/console/chat/sift-bridge.js +1 -0
  42. package/dist/worker/console/chat/tool-preview.js +0 -11
  43. package/dist/worker/console/chat/tools.js +0 -6
  44. package/dist/worker/console/console-update-and-init.js +19 -1
  45. package/dist/worker/console/console-update-runtime.js +20 -5
  46. package/dist/worker/console/index.js +20 -0
  47. package/dist/worker/console/operator-actions.js +1 -13
  48. package/dist/worker/console/routes.js +0 -8
  49. package/dist/worker/console/server.js +29 -11
  50. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-hUmM_GRf.js} +1 -1
  51. package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-Bt-xuieW.js} +1 -1
  52. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-DTqkL4DJ.js} +1 -1
  53. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-Cy0MNnzV.js} +1 -1
  54. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-DDdlT0Pd.js} +1 -1
  55. package/dist/worker/console/static/assets/channel-BpzRnZmU.js +1 -0
  56. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-3JawwNZ6.js} +1 -1
  57. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-DoTp7Cri.js} +1 -1
  58. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-CcirhZaS.js} +1 -1
  59. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-VrG21gnP.js} +1 -1
  60. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DDOgIS70.js} +1 -1
  61. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-CBjmgvJ_.js} +1 -1
  62. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-CCQSht8M.js} +1 -1
  63. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-BpGMkUUV.js} +1 -1
  64. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-DNDT41QL.js} +1 -1
  65. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-euXnDFbn.js} +1 -1
  66. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BhlMVqCc.js +1 -0
  67. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BhlMVqCc.js +1 -0
  68. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-BJ6NAeql.js} +1 -1
  69. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-F5JKIvIq.js} +1 -1
  70. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-Cwmkl_Gi.js} +1 -1
  71. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-BmCZ8815.js} +1 -1
  72. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-zWA3hUnX.js} +1 -1
  73. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-BzA-888F.js} +1 -1
  74. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-tPNheoch.js} +1 -1
  75. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-Cdi7Fyqp.js} +1 -1
  76. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-DFK9VBf1.js} +1 -1
  77. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-xCUr1kpg.js} +1 -1
  78. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-BANQHY_A.js} +1 -1
  79. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-VHJYEMkP.js} +1 -1
  80. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-DiyZQ0C6.js} +1 -1
  81. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-CZtIeBBa.js} +1 -1
  82. package/dist/worker/console/static/assets/index-BlN6ytLr.css +1 -0
  83. package/dist/worker/console/static/assets/index-CA-jfWlE.js +449 -0
  84. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-BuSspC0X.js} +1 -1
  85. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DRJZyPFy.js} +1 -1
  86. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-DIfXIVuE.js} +1 -1
  87. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-CT10_7Lt.js} +1 -1
  88. package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-ufemj74H.js} +1 -1
  89. package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-DEQe8-_m.js} +5 -5
  90. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-BRLUrbrC.js} +1 -1
  91. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-BgibKtiF.js} +1 -1
  92. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-D3eyfdV9.js} +1 -1
  93. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-DXeTk5Px.js} +1 -1
  94. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-BgXdFEe7.js} +1 -1
  95. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-CseC2A7R.js} +1 -1
  96. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-D80PFzfJ.js} +1 -1
  97. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-BWzHW7LS.js} +1 -1
  98. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-xWQYTLAn.js} +1 -1
  99. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-CLxtpZeL.js} +1 -1
  100. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CiVoq4G-.js +1 -0
  101. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-DwugtmWV.js} +2 -2
  102. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BkdgdpfR.js +8 -0
  103. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-DHEOwHIe.js} +1 -1
  104. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-pmbZKlBK.js} +1 -1
  105. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-CivHoM5q.js} +1 -1
  106. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-BfHIE7o6.js} +1 -1
  107. package/dist/worker/console/static/index.html +2 -2
  108. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +10 -122
  109. package/dist/worker/console/static-src/operator-chat/compaction-message.js +0 -7
  110. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +15 -35
  111. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +62 -136
  112. package/dist/worker/console/static-src/operator-chat/useChatStream.js +68 -159
  113. package/dist/worker/console/static-src/operator-chat/useChatThread.js +56 -75
  114. package/dist/worker/console/static-src/operator-chat/useComposer.js +78 -206
  115. package/dist/worker/console/workspace-context.js +1 -21
  116. package/dist/worker/observe/static/router.js +1 -1
  117. package/dist/worker/observe/static/styles.css +4 -7
  118. package/dist/worker/observe/static/views/dag-inspector.js +19 -12
  119. package/dist/worker/observe/static/views/dag.js +2 -2
  120. package/dist/worker/scheduler/index.js +25 -0
  121. package/dist/workflows/dag/facts.js +4 -0
  122. package/dist/workflows/dag/frontend-closeout.js +1 -1
  123. package/dist/workflows/dag/frontend-design-policy.js +1 -2
  124. package/dist/workflows/dag/frontend-implementation-contract.js +4 -8
  125. package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
  126. package/dist/workflows/dag/frontend-repair.js +76 -55
  127. package/dist/workflows/dag/frontend-review-context.js +1 -2
  128. package/dist/workflows/dag/frontend-review-scopes.js +12 -34
  129. package/dist/workflows/dag/frontend-shape-facts.js +2 -12
  130. package/dist/workflows/dag/frontend-verification-trace.js +42 -8
  131. package/dist/workflows/dag/index.js +6 -0
  132. package/dist/workflows/dag/init-hybrid.js +160 -97
  133. package/dist/workflows/dynamic/index.js +7 -0
  134. package/docs/architecture/runtime-boundaries.md +3 -3
  135. package/docs/templates/frontend-implementation-dag.json +8 -9
  136. package/package.json +3 -7
  137. package/skills/frontend-bounded-implement/SKILL.md +3 -4
  138. package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
  139. package/skills/frontend-contract/references/contract-protocol.md +1 -3
  140. package/skills/frontend-design-review/SKILL.md +7 -12
  141. package/skills/frontend-design-review/references/review-checklist.md +7 -7
  142. package/skills/frontend-plan/SKILL.md +0 -19
  143. package/skills/frontend-plan/references/decision-contract.md +19 -26
  144. package/skills/frontend-review/SKILL.md +18 -12
  145. package/skills/frontend-review/references/review-findings.md +43 -24
  146. package/dist/shared/pi-provider-recovery.js +0 -182
  147. package/dist/worker/console/chat/browser-automation.js +0 -363
  148. package/dist/worker/console/chat/browser-policy.js +0 -113
  149. package/dist/worker/console/chat/browser-routes.js +0 -162
  150. package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +0 -44
  151. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +0 -89
  152. package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +0 -202
  153. package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +0 -79
  154. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +0 -86
  155. package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +0 -38
  156. package/dist/worker/console/chat/pi-runtime/inspection-types.js +0 -28
  157. package/dist/worker/console/chat/pi-runtime/inspection.js +0 -439
  158. package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +0 -153
  159. package/dist/worker/console/chat/pi-runtime/sdk-session.js +0 -5
  160. package/dist/worker/console/chat/scm-routes.js +0 -217
  161. package/dist/worker/console/chat/scm-service.js +0 -283
  162. package/dist/worker/console/chat/scm-tools.js +0 -111
  163. package/dist/worker/console/chat/session-mode-view.js +0 -49
  164. package/dist/worker/console/chat/session-mode.js +0 -220
  165. package/dist/worker/console/chat/terminal-routes.js +0 -216
  166. package/dist/worker/console/chat/terminal-sessions.js +0 -348
  167. package/dist/worker/console/chat/terminal-tools.js +0 -211
  168. package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
  169. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
  170. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
  171. package/dist/worker/console/static/assets/index-B9goN3S5.css +0 -1
  172. package/dist/worker/console/static/assets/index-wXlQohNs.js +0 -469
  173. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
  174. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
  175. package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +0 -10
  176. package/dist/worker/console/static-src/operator-chat/chat-link.js +0 -94
  177. package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +0 -24
  178. package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +0 -192
  179. package/dist/worker/console/static-src/operator-chat/process-label.js +0 -41
  180. package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +0 -13
  181. package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +0 -10
  182. package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +0 -51
  183. package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +0 -21
  184. package/dist/worker/console/workspace-initialization.js +0 -209
  185. package/dist/workflows/dag/frontend-capacity.js +0 -9
  186. package/dist/workflows/dag/frontend-plan-completeness.js +0 -186
  187. package/dist/workflows/dag/frontend-plan-recovery-policy.js +0 -18
@@ -1,38 +0,0 @@
1
- /**
2
- * Session-bound todo_write custom tool.
3
- * Description is mode-aware; ConsolePiRuntime owns when to register it.
4
- */
5
- import { PI_TODO_WRITE_DESCRIPTION, } from "../../session-mode.js";
6
- const TODO_WRITE_DESCRIPTION = "Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (no partial updates, no per-item edits). Before starting multi-step work, add one todo per concrete step. Keep at least one todo `in_progress` while work remains. Mark a todo `completed` immediately when it is done (do not batch completions) and resend the full list as progress or DAG state advances. Skip the list for simple Q&A, read-only lookups, and single-step tasks. Use it for multi-step implementation and whenever you prepare, run, or supervise a DAG — call `todo_write` before entering the DAG tool chain. Phrase DAG todos as user-facing phases users can understand, not copies of internal DAG nodes. Statuses: `pending` / `in_progress` / `completed`.";
7
- export async function buildTodoWriteTool(options) {
8
- const [{ Type }, { defineTool }] = await Promise.all([
9
- import("typebox"),
10
- import("@earendil-works/pi-coding-agent"),
11
- ]);
12
- const description = options.sessionMode === "pi"
13
- ? PI_TODO_WRITE_DESCRIPTION
14
- : TODO_WRITE_DESCRIPTION;
15
- return defineTool({
16
- name: "todo_write",
17
- label: "Update todo list",
18
- description,
19
- promptSnippet: description,
20
- parameters: Type.Object({
21
- todos: Type.Array(Type.Object({
22
- content: Type.String({ description: "Short imperative task description." }),
23
- status: Type.Union([
24
- Type.Literal("pending"),
25
- Type.Literal("in_progress"),
26
- Type.Literal("completed"),
27
- ]),
28
- }, { additionalProperties: false })),
29
- }, { additionalProperties: false }),
30
- async execute(toolCallId, params) {
31
- const result = options.registry.write(options.sessionId, toolCallId, params.todos);
32
- return {
33
- content: [{ type: "text", text: JSON.stringify(result) }],
34
- details: result,
35
- };
36
- },
37
- });
38
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Live runtime snapshot types and the structured critical-failure error.
3
- * Projection and inventory collection live in inspection.ts; ConsolePiRuntime
4
- * remains the owner of live session lookup and preference-cache refresh.
5
- */
6
- export const THINKING_LEVELS = [
7
- "off",
8
- "minimal",
9
- "low",
10
- "medium",
11
- "high",
12
- "xhigh",
13
- "max",
14
- ];
15
- /**
16
- * Structured critical-failure error for snapshot projection (RF-02). Model
17
- * enumeration or system prompt projection failures throw this so consuming
18
- * routes can return 503 PI_RUNTIME_UNAVAILABLE instead of a fake-empty 200.
19
- * Partial ResourceLoader / package-inventory failures are NOT critical — they
20
- * keep the 200 snapshot and surface as structured diagnostics instead.
21
- */
22
- export class RuntimeSnapshotUnavailableError extends Error {
23
- code = "PI_RUNTIME_UNAVAILABLE";
24
- constructor(message) {
25
- super(message);
26
- this.name = "RuntimeSnapshotUnavailableError";
27
- }
28
- }
@@ -1,439 +0,0 @@
1
- /**
2
- * Runtime inspection: browser-safe snapshot projection, slash-command
3
- * inventory, and ResourceLoader/package/MCP collection. Does not own
4
- * session lifecycle, preference-file cache, or prompt/reload locks.
5
- */
6
- import { RUNTIME_CONTEXT_TEXT_MAX, redactRuntimeText, } from "../runtime-context.js";
7
- import { isAutoInvocationEnabled, skillResourceId, } from "../resource-preferences-store.js";
8
- /**
9
- * Browser-safe projection of a live runtime snapshot (design §2.2 / RF-03).
10
- *
11
- * Every browser-visible string runs the shared secret-scrub chain
12
- * (scrubSecrets + ghp_/Bearer redaction via redactRuntimeText) and a fixed
13
- * per-field length limit: 200 (names/spec/source/origin), 400 (paths/errors/
14
- * diagnostic messages), 600 (skill descriptions), 80 (package versions);
15
- * truncation uses the fixed `…[truncated N chars …]` marker. The server-only
16
- * `raw` prompt and the RAW-based `sha256`/`characters` pass through untouched,
17
- * and real empty lists stay empty.
18
- *
19
- * Pure + deterministic and exported so the route harness reuses the exact
20
- * production implementation (same code path as getRuntimeSnapshot).
21
- */
22
- export function projectRuntimeSnapshot(input) {
23
- const field = (value, max) => value === undefined ? undefined : redactRuntimeText(value, max);
24
- const projectSkill = (skill) => ({
25
- name: field(skill.name, 200) ?? "",
26
- description: field(skill.description, 600) ?? "",
27
- path: field(skill.path, 400) ?? "",
28
- ...(skill.baseDir ? { baseDir: field(skill.baseDir, 400) } : {}),
29
- scope: skill.scope,
30
- source: field(skill.source, 200) ?? "",
31
- resourceId: field(skill.resourceId, 200) ?? "",
32
- autoInvocationEnabled: skill.autoInvocationEnabled,
33
- diagnostics: skill.diagnostics.map((diag) => field(diag, 400) ?? ""),
34
- });
35
- const projectExtension = (ext) => ({
36
- name: field(ext.name, 200) ?? "",
37
- path: field(ext.path, 400) ?? "",
38
- ...(ext.resolvedPath
39
- ? { resolvedPath: field(ext.resolvedPath, 400) }
40
- : {}),
41
- source: field(ext.source, 200) ?? "",
42
- scope: ext.scope,
43
- ...(ext.origin ? { origin: field(ext.origin, 200) } : {}),
44
- enabled: ext.enabled,
45
- ...(ext.error ? { error: field(ext.error, 400) } : {}),
46
- });
47
- const projectPackage = (pkg) => ({
48
- spec: field(pkg.spec, 200) ?? "",
49
- scope: pkg.scope,
50
- enabled: pkg.enabled,
51
- ...(pkg.version ? { version: field(pkg.version, 80) } : {}),
52
- ...(pkg.configuredVersion
53
- ? { configuredVersion: field(pkg.configuredVersion, 80) }
54
- : {}),
55
- ...(pkg.packageName ? { packageName: field(pkg.packageName, 200) } : {}),
56
- ...(pkg.path ? { path: field(pkg.path, 400) } : {}),
57
- ...(pkg.installedPath ? { installedPath: field(pkg.installedPath, 400) } : {}),
58
- ...(pkg.cwd ? { cwd: field(pkg.cwd, 400) } : {}),
59
- resolved: pkg.resolved.map((resource) => ({
60
- type: resource.type,
61
- name: field(resource.name, 200) ?? "",
62
- path: field(resource.path, 400) ?? "",
63
- source: field(resource.source, 200) ?? "",
64
- scope: resource.scope,
65
- })),
66
- diagnostics: pkg.diagnostics.map((diag) => field(diag, 400) ?? ""),
67
- });
68
- const projectMcpTool = (tool) => ({
69
- name: field(tool.name, 200) ?? "",
70
- description: field(tool.description, 600) ?? "",
71
- ...(tool.server ? { server: field(tool.server, 200) } : {}),
72
- source: field(tool.source, 200) ?? "",
73
- scope: tool.scope,
74
- ...(tool.path ? { path: field(tool.path, 400) } : {}),
75
- active: tool.active,
76
- });
77
- const projectMcp = (mcp) => ({
78
- servers: mcp.servers.map((server) => ({
79
- name: field(server.name, 200) ?? "",
80
- scope: server.scope,
81
- status: server.status,
82
- enabled: server.enabled,
83
- ...(server.transport ? { transport: field(server.transport, 80) } : {}),
84
- ...(server.command ? { command: field(server.command, 400) } : {}),
85
- ...(server.url ? { url: field(server.url, 400) } : {}),
86
- ...(server.configPath ? { configPath: field(server.configPath, 400) } : {}),
87
- tools: server.tools.map(projectMcpTool),
88
- })),
89
- unassignedTools: mcp.unassignedTools.map(projectMcpTool),
90
- });
91
- const projectDiagnostic = (diag) => ({
92
- type: diag.type,
93
- ...(diag.code ? { code: diag.code } : {}),
94
- message: field(diag.message, 400) ?? "",
95
- ...(diag.path ? { path: field(diag.path, 400) } : {}),
96
- ...(diag.retryable !== undefined
97
- ? { retryable: diag.retryable }
98
- : {}),
99
- });
100
- return {
101
- sessionId: input.sessionId,
102
- revision: input.revision,
103
- loadedAt: input.loadedAt,
104
- selection: {
105
- ...(input.selection.model
106
- ? {
107
- model: {
108
- provider: input.selection.model.provider,
109
- id: input.selection.model.id,
110
- ...(input.selection.model.name
111
- ? { name: field(input.selection.model.name, 200) }
112
- : {}),
113
- },
114
- }
115
- : {}),
116
- thinkingSelection: input.selection.thinkingSelection,
117
- ...(input.selection.effectiveThinkingLevel
118
- ? { effectiveThinkingLevel: input.selection.effectiveThinkingLevel }
119
- : {}),
120
- },
121
- models: input.models.map((model) => ({
122
- provider: model.provider,
123
- id: model.id,
124
- ...(model.name ? { name: field(model.name, 200) } : {}),
125
- ...(model.hasCredentials !== undefined
126
- ? { hasCredentials: model.hasCredentials }
127
- : {}),
128
- })),
129
- thinkingLevels: input.thinkingLevels.map((option) => ({ ...option })),
130
- systemPrompt: {
131
- ...(input.systemPrompt.raw !== undefined
132
- ? { raw: input.systemPrompt.raw }
133
- : {}),
134
- text: redactRuntimeText(input.systemPrompt.text, RUNTIME_CONTEXT_TEXT_MAX),
135
- sha256: input.systemPrompt.sha256,
136
- characters: input.systemPrompt.characters,
137
- },
138
- activeTools: [...input.activeTools],
139
- contextFiles: input.contextFiles.map((file) => ({
140
- path: field(file.path, 400) ?? "",
141
- characters: file.characters,
142
- })),
143
- skills: input.skills.map(projectSkill),
144
- extensions: input.extensions.map(projectExtension),
145
- packages: input.packages.map(projectPackage),
146
- mcp: projectMcp(input.mcp ?? { servers: [], unassignedTools: [] }),
147
- diagnostics: input.diagnostics.map(projectDiagnostic),
148
- hasBash: input.hasBash,
149
- };
150
- }
151
- /**
152
- * Browser-safe slash command projection for UI-11.
153
- * Sources: current Session extension commands, prompt templates, skills.
154
- * Never returns prompt/skill file bodies. Same-name conflict priority:
155
- * extension > skill > prompt.
156
- */
157
- export function collectSlashCommands(input) {
158
- const scrub = (value) => {
159
- const raw = String(value ?? "");
160
- return raw
161
- .replace(/\/Users\/[^\s]+/gi, "~")
162
- .replace(/[A-Za-z]:\\Users\\[^\s]+/gi, "~")
163
- .slice(0, 240);
164
- };
165
- const session = input.session;
166
- if (!session)
167
- return { commands: [] };
168
- const SOURCE_RANK = {
169
- extension: 0,
170
- skill: 1,
171
- prompt: 2,
172
- };
173
- const byKey = new Map();
174
- const sourceWarnings = [];
175
- const push = (command, label, description, source) => {
176
- const name = command.startsWith("/") ? command : `/${command}`;
177
- const key = name.toLowerCase();
178
- if (!key || key === "/")
179
- return;
180
- const next = {
181
- command: name,
182
- label: (label || name).slice(0, 80),
183
- description: scrub(description),
184
- source,
185
- };
186
- const existing = byKey.get(key);
187
- if (!existing || SOURCE_RANK[source] < SOURCE_RANK[existing.source]) {
188
- byKey.set(key, next);
189
- }
190
- };
191
- try {
192
- const cmds = session.extensionRunner?.getRegisteredCommands?.() ?? [];
193
- for (const cmd of cmds) {
194
- const name = cmd.invocationName || cmd.name;
195
- if (!name)
196
- continue;
197
- push(String(name), String(cmd.name || name), String(cmd.description || ""), "extension");
198
- }
199
- }
200
- catch (error) {
201
- sourceWarnings.push(`extension: ${scrub(error instanceof Error ? error.message : String(error))}`);
202
- }
203
- try {
204
- for (const tpl of session.promptTemplates ?? []) {
205
- if (!tpl?.name)
206
- continue;
207
- push(String(tpl.name), String(tpl.name), String(tpl.description || ""), "prompt");
208
- }
209
- }
210
- catch (error) {
211
- sourceWarnings.push(`prompt: ${scrub(error instanceof Error ? error.message : String(error))}`);
212
- }
213
- try {
214
- const skills = input.resourceLoader?.getSkills?.()?.skills ?? [];
215
- for (const skill of skills) {
216
- if (!skill?.name)
217
- continue;
218
- const command = skill.name.startsWith("skill:")
219
- ? `/${skill.name}`
220
- : `/skill:${skill.name}`;
221
- push(command, skill.name, String(skill.description || ""), "skill");
222
- }
223
- }
224
- catch (error) {
225
- sourceWarnings.push(`skill: ${scrub(error instanceof Error ? error.message : String(error))}`);
226
- }
227
- const warning = sourceWarnings.length > 0
228
- ? sourceWarnings.join("; ").slice(0, 160)
229
- : undefined;
230
- return {
231
- commands: [...byKey.values()],
232
- ...(warning ? { warning } : {}),
233
- };
234
- }
235
- /**
236
- * Collect ResourceLoader / package / MCP inventories for a live session.
237
- * Preference-file loading stays with ConsolePiRuntime; this function only
238
- * consumes already-loaded prefs (or a captured load error).
239
- */
240
- export async function collectRuntimeInventories(input) {
241
- const contextFiles = [];
242
- const skills = [];
243
- const extensions = [];
244
- const diagnostics = [];
245
- const resolvedResources = [];
246
- const resourceFailure = (subface, error) => {
247
- diagnostics.push({
248
- type: "error",
249
- code: "RESOURCE_LOAD_FAILED",
250
- message: `${subface} inventory failed: ${error instanceof Error ? error.message : String(error)}`,
251
- retryable: true,
252
- });
253
- };
254
- if (input.skillPrefsError !== undefined) {
255
- diagnostics.push({
256
- type: "error",
257
- code: "PI_RESOURCE_PREFERENCES_MALFORMED",
258
- message: input.skillPrefsError instanceof Error
259
- ? input.skillPrefsError.message
260
- : String(input.skillPrefsError),
261
- retryable: true,
262
- });
263
- }
264
- const resourceLoader = input.resourceLoader;
265
- if (resourceLoader) {
266
- try {
267
- const agentsFiles = resourceLoader.getAgentsFiles?.();
268
- for (const file of agentsFiles?.agentsFiles ?? []) {
269
- if (!file.path)
270
- continue;
271
- contextFiles.push({
272
- path: file.path,
273
- characters: file.content?.length ?? 0,
274
- });
275
- }
276
- }
277
- catch (error) {
278
- resourceFailure("context files", error);
279
- }
280
- try {
281
- const skillsResult = resourceLoader.getSkills?.();
282
- for (const skill of skillsResult?.skills ?? []) {
283
- const resourceId = skillResourceId({
284
- name: skill.name,
285
- filePath: skill.filePath,
286
- });
287
- const prefEnabled = isAutoInvocationEnabled(input.skillPrefs, resourceId);
288
- const autoInvocationEnabled = prefEnabled && skill.disableModelInvocation !== true;
289
- skills.push({
290
- name: skill.name,
291
- description: skill.description ?? "",
292
- path: skill.filePath,
293
- ...(skill.baseDir ? { baseDir: skill.baseDir } : {}),
294
- scope: skill.sourceInfo?.scope ?? "unknown",
295
- source: skill.sourceInfo?.source ?? "",
296
- resourceId,
297
- autoInvocationEnabled,
298
- diagnostics: [],
299
- });
300
- resolvedResources.push({
301
- type: "skill",
302
- name: skill.name,
303
- path: skill.filePath,
304
- source: skill.sourceInfo?.source ?? "",
305
- scope: skill.sourceInfo?.scope ?? "unknown",
306
- });
307
- }
308
- for (const diag of skillsResult?.diagnostics ?? []) {
309
- if (!diag?.message)
310
- continue;
311
- diagnostics.push({
312
- type: diag.type ?? "warning",
313
- message: diag.message,
314
- ...(diag.path ? { path: diag.path } : {}),
315
- });
316
- }
317
- }
318
- catch (error) {
319
- resourceFailure("skills", error);
320
- }
321
- try {
322
- const extResult = resourceLoader.getExtensions?.();
323
- for (const ext of extResult?.extensions ?? []) {
324
- const path = ext.resolvedPath ?? ext.path ?? "";
325
- extensions.push({
326
- name: ext.sourceInfo?.source ?? ext.path ?? "extension",
327
- path,
328
- ...(ext.resolvedPath ? { resolvedPath: ext.resolvedPath } : {}),
329
- source: ext.sourceInfo?.source ?? "",
330
- scope: ext.sourceInfo?.scope ?? "unknown",
331
- ...(ext.sourceInfo?.origin ? { origin: ext.sourceInfo.origin } : {}),
332
- enabled: true,
333
- });
334
- resolvedResources.push({
335
- type: "extension",
336
- name: ext.sourceInfo?.source ?? ext.path ?? "extension",
337
- path,
338
- source: ext.sourceInfo?.source ?? "",
339
- scope: ext.sourceInfo?.scope ?? "unknown",
340
- });
341
- }
342
- for (const err of extResult?.errors ?? []) {
343
- if (!err?.error)
344
- continue;
345
- diagnostics.push({
346
- type: "error",
347
- message: err.error,
348
- ...(err.path ? { path: err.path } : {}),
349
- });
350
- }
351
- }
352
- catch (error) {
353
- resourceFailure("extensions", error);
354
- }
355
- try {
356
- const promptsResult = resourceLoader.getPrompts?.();
357
- for (const prompt of promptsResult?.prompts ?? []) {
358
- resolvedResources.push({
359
- type: "prompt",
360
- name: prompt.name,
361
- path: prompt.filePath,
362
- source: prompt.sourceInfo?.source ?? "",
363
- scope: prompt.sourceInfo?.scope ?? "unknown",
364
- });
365
- }
366
- for (const diag of promptsResult?.diagnostics ?? []) {
367
- if (!diag?.message)
368
- continue;
369
- diagnostics.push({
370
- type: diag.type ?? "warning",
371
- message: diag.message,
372
- ...(diag.path ? { path: diag.path } : {}),
373
- });
374
- }
375
- }
376
- catch (error) {
377
- resourceFailure("prompts", error);
378
- }
379
- try {
380
- const themesResult = resourceLoader.getThemes?.();
381
- for (const theme of themesResult?.themes ?? []) {
382
- if (!theme.path)
383
- continue;
384
- resolvedResources.push({
385
- type: "theme",
386
- name: theme.name ?? theme.path,
387
- path: theme.path,
388
- source: "",
389
- scope: "unknown",
390
- });
391
- }
392
- for (const diag of themesResult?.diagnostics ?? []) {
393
- if (!diag?.message)
394
- continue;
395
- diagnostics.push({
396
- type: diag.type ?? "warning",
397
- message: diag.message,
398
- ...(diag.path ? { path: diag.path } : {}),
399
- });
400
- }
401
- }
402
- catch (error) {
403
- resourceFailure("themes", error);
404
- }
405
- }
406
- const { readPackageInventory } = await import("../pi-console-config.js");
407
- let packages = [];
408
- try {
409
- packages = (await readPackageInventory(input.agentDir, input.cwd, resolvedResources));
410
- }
411
- catch (error) {
412
- packages = [];
413
- diagnostics.push({
414
- type: "error",
415
- code: "PACKAGE_INVENTORY_FAILED",
416
- message: error instanceof Error ? error.message : String(error),
417
- retryable: true,
418
- });
419
- }
420
- const { readMcpInventory } = await import("../mcp-inventory.js");
421
- let mcp = { servers: [], unassignedTools: [] };
422
- try {
423
- mcp = await readMcpInventory({
424
- agentDir: input.agentDir,
425
- cwd: input.cwd,
426
- tools: (Array.isArray(input.tools) ? input.tools : []),
427
- activeToolNames: input.activeToolNames,
428
- });
429
- }
430
- catch (error) {
431
- diagnostics.push({
432
- type: "error",
433
- code: "MCP_INVENTORY_FAILED",
434
- message: error instanceof Error ? error.message : String(error),
435
- retryable: true,
436
- });
437
- }
438
- return { contextFiles, skills, extensions, packages, mcp, diagnostics };
439
- }
@@ -1,153 +0,0 @@
1
- /**
2
- * Concrete Pi SDK adapter for Console Chat. Lazy-loads the ESM SDK and
3
- * implements session-file safety (wx/0600, missing-file fail-closed).
4
- */
5
- import { access, mkdir, rm, writeFile } from "node:fs/promises";
6
- import path from "node:path";
7
- export async function safeGetAgentDir(bindings) {
8
- try {
9
- return await bindings.getAgentDir();
10
- }
11
- catch {
12
- // Fall back to a Console-app-data scoped agent dir so we never accidentally
13
- // touch the user's real ~/.pi/agent config if getAgentDir throws.
14
- return path.join(process.cwd(), ".harness", "console", "pi-agent-dir");
15
- }
16
- }
17
- /**
18
- * Cached SDK module loader. The pi-coding-agent package is ESM-only, so we
19
- * must use dynamic import() (not require). Cached to avoid repeated imports.
20
- */
21
- let cachedSdk;
22
- async function loadSdk() {
23
- if (!cachedSdk) {
24
- cachedSdk = import("@earendil-works/pi-coding-agent");
25
- }
26
- return cachedSdk;
27
- }
28
- /**
29
- * Default production bindings backed by the real Pi SDK (services mode).
30
- * Dynamically imported so the worker bundle does not hard-fail if the SDK is
31
- * absent at module load (discovered lazily by pi-readiness instead).
32
- */
33
- export function createDefaultPiSdkBindings() {
34
- return {
35
- getAgentDir: async () => {
36
- const sdk = (await loadSdk());
37
- return sdk.getAgentDir();
38
- },
39
- createServices: async (opts) => {
40
- const sdk = (await loadSdk());
41
- // createAgentSessionServices returns the full AgentSessionServices object
42
- // directly (cwd/agentDir/modelRuntime/settingsManager/resourceLoader).
43
- // Wrap it so our type contract is satisfied.
44
- const result = await sdk.createAgentSessionServices({
45
- cwd: opts.cwd,
46
- agentDir: opts.agentDir,
47
- resourceLoaderOptions: opts.resourceLoaderOptions,
48
- });
49
- return { services: result };
50
- },
51
- createSessionFromServices: async (opts) => {
52
- const sdk = (await loadSdk());
53
- return sdk.createAgentSessionFromServices({
54
- services: opts.services,
55
- sessionManager: opts.sessionManager,
56
- ...(opts.tools ? { tools: opts.tools } : {}),
57
- ...(opts.noTools ? { noTools: opts.noTools } : {}),
58
- ...(opts.excludeTools ? { excludeTools: opts.excludeTools } : {}),
59
- ...(opts.customTools ? { customTools: opts.customTools } : {}),
60
- ...(opts.model ? { model: opts.model } : {}),
61
- });
62
- },
63
- createSessionManager: async (opts) => {
64
- const sdk = (await loadSdk());
65
- return sdk.SessionManager.create(opts.cwd, opts.sessionDir, {
66
- id: opts.sessionId,
67
- });
68
- },
69
- materializeSessionShell: async (opts) => {
70
- const sdk = (await loadSdk());
71
- const manager = opts.sessionManager;
72
- if (typeof manager.setSessionFile !== "function") {
73
- throw new Error("Pi SessionManager cannot materialize a session file");
74
- }
75
- let created = false;
76
- try {
77
- await mkdir(path.dirname(opts.sessionFile), { recursive: true });
78
- // Match Pi's documented session header. Rebinding through the public
79
- // SessionManager API marks it flushed, so Pi appends the first user
80
- // entry instead of trying to create the already-present file later.
81
- await writeFile(opts.sessionFile, `${JSON.stringify({
82
- type: "session",
83
- version: typeof sdk.CURRENT_SESSION_VERSION === "number"
84
- ? sdk.CURRENT_SESSION_VERSION
85
- : 3,
86
- id: opts.sessionId,
87
- timestamp: new Date().toISOString(),
88
- cwd: opts.cwd,
89
- })}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
90
- created = true;
91
- manager.setSessionFile(opts.sessionFile);
92
- }
93
- catch (error) {
94
- if (created)
95
- await rm(opts.sessionFile, { force: true }).catch(() => undefined);
96
- throw error;
97
- }
98
- },
99
- createInMemorySessionManager: async (opts) => {
100
- const sdk = (await loadSdk());
101
- return sdk.SessionManager.inMemory(opts.cwd);
102
- },
103
- forkSessionManager: async (opts) => {
104
- const sdk = (await loadSdk());
105
- return sdk.SessionManager.forkFrom(opts.sourcePath, opts.targetCwd, opts.targetSessionDir, { id: opts.targetSessionId });
106
- },
107
- openSessionManager: async (opts) => {
108
- const sdk = (await loadSdk());
109
- try {
110
- // Pi SessionManager.open(missingPath) does NOT throw — it creates a
111
- // fresh in-memory session with a random UUID. That would reopen the
112
- // wrong conversation under the durable Console sessionId. Fail closed
113
- // before open when the persisted file is absent.
114
- await access(opts.sessionFile);
115
- }
116
- catch (error) {
117
- const code = error && typeof error === "object" && "code" in error
118
- ? String(error.code ?? "")
119
- : "";
120
- if (code === "ENOENT") {
121
- throw Object.assign(new Error(`SESSION_FILE_MISSING: ${opts.sessionFile}`), { code: "SESSION_FILE_MISSING", cause: error });
122
- }
123
- // File exists but is unreadable (permissions / I/O) — caller maps
124
- // undefined to 503 rather than silently creating a fresh session.
125
- return undefined;
126
- }
127
- return sdk.SessionManager.open(opts.sessionFile);
128
- },
129
- resolveModel: (opts) => {
130
- const rt = opts.modelRuntime;
131
- if (typeof rt?.getModel !== "function")
132
- return undefined;
133
- try {
134
- return rt.getModel(opts.provider, opts.modelId);
135
- }
136
- catch {
137
- return undefined;
138
- }
139
- },
140
- listAvailableModels: (opts) => {
141
- const rt = opts.modelRuntime;
142
- const available = rt?.snapshot?.available ?? [];
143
- const configured = rt?.snapshot?.configuredProviders;
144
- const isConfigured = (provider) => configured instanceof Set ? configured.has(provider) : false;
145
- return available.map((m) => ({
146
- id: m.id,
147
- name: m.name,
148
- provider: m.provider,
149
- hasCredentials: isConfigured(m.provider),
150
- }));
151
- },
152
- };
153
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Pi SDK session contracts used by Console Chat. Kept below pi-runtime.ts so
3
- * adapters and subagents can import types without a runtime cycle.
4
- */
5
- export {};