@esso0428/pi-subagents 0.17.6 → 0.17.7

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 (260) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/CONTRIBUTING.md +4 -0
  3. package/dist/abortable.d.ts +13 -0
  4. package/dist/abortable.d.ts.map +1 -0
  5. package/dist/abortable.js +43 -0
  6. package/dist/abortable.js.map +1 -0
  7. package/dist/agent-color.d.ts +36 -0
  8. package/dist/agent-color.d.ts.map +1 -0
  9. package/dist/agent-color.js +124 -0
  10. package/dist/agent-color.js.map +1 -0
  11. package/dist/agent-file-toggle.d.ts +126 -0
  12. package/dist/agent-file-toggle.d.ts.map +1 -0
  13. package/dist/agent-file-toggle.js +259 -0
  14. package/dist/agent-file-toggle.js.map +1 -0
  15. package/dist/agent-history.d.ts +4 -0
  16. package/dist/agent-history.d.ts.map +1 -1
  17. package/dist/agent-history.js +47 -1
  18. package/dist/agent-history.js.map +1 -1
  19. package/dist/agent-manager.d.ts +370 -56
  20. package/dist/agent-manager.d.ts.map +1 -1
  21. package/dist/agent-manager.js +1123 -409
  22. package/dist/agent-manager.js.map +1 -1
  23. package/dist/agent-runner.d.ts +100 -10
  24. package/dist/agent-runner.d.ts.map +1 -1
  25. package/dist/agent-runner.js +166 -21
  26. package/dist/agent-runner.js.map +1 -1
  27. package/dist/agent-types.d.ts +57 -5
  28. package/dist/agent-types.d.ts.map +1 -1
  29. package/dist/agent-types.js +164 -32
  30. package/dist/agent-types.js.map +1 -1
  31. package/dist/child-context.d.ts +3 -0
  32. package/dist/child-context.d.ts.map +1 -0
  33. package/dist/child-context.js +13 -0
  34. package/dist/child-context.js.map +1 -0
  35. package/dist/cross-extension-rpc.d.ts +23 -3
  36. package/dist/cross-extension-rpc.d.ts.map +1 -1
  37. package/dist/cross-extension-rpc.js +79 -17
  38. package/dist/cross-extension-rpc.js.map +1 -1
  39. package/dist/custom-agents.d.ts +38 -1
  40. package/dist/custom-agents.d.ts.map +1 -1
  41. package/dist/custom-agents.js +164 -12
  42. package/dist/custom-agents.js.map +1 -1
  43. package/dist/index.d.ts +34 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1908 -495
  46. package/dist/index.js.map +1 -1
  47. package/dist/invocation-config.d.ts +87 -2
  48. package/dist/invocation-config.d.ts.map +1 -1
  49. package/dist/invocation-config.js +71 -3
  50. package/dist/invocation-config.js.map +1 -1
  51. package/dist/mention-clone.d.ts +88 -0
  52. package/dist/mention-clone.d.ts.map +1 -0
  53. package/dist/mention-clone.js +154 -0
  54. package/dist/mention-clone.js.map +1 -0
  55. package/dist/mention.d.ts +82 -0
  56. package/dist/mention.d.ts.map +1 -0
  57. package/dist/mention.js +132 -0
  58. package/dist/mention.js.map +1 -0
  59. package/dist/model-resolver.d.ts +17 -0
  60. package/dist/model-resolver.d.ts.map +1 -1
  61. package/dist/model-resolver.js +15 -0
  62. package/dist/model-resolver.js.map +1 -1
  63. package/dist/model-scope.d.ts +50 -0
  64. package/dist/model-scope.d.ts.map +1 -0
  65. package/dist/model-scope.js +49 -0
  66. package/dist/model-scope.js.map +1 -0
  67. package/dist/nested-tools.d.ts +57 -0
  68. package/dist/nested-tools.d.ts.map +1 -0
  69. package/dist/nested-tools.js +301 -0
  70. package/dist/nested-tools.js.map +1 -0
  71. package/dist/output-file.d.ts +22 -3
  72. package/dist/output-file.d.ts.map +1 -1
  73. package/dist/output-file.js +58 -7
  74. package/dist/output-file.js.map +1 -1
  75. package/dist/prompts.d.ts +23 -0
  76. package/dist/prompts.d.ts.map +1 -1
  77. package/dist/prompts.js +20 -2
  78. package/dist/prompts.js.map +1 -1
  79. package/dist/schedule.d.ts.map +1 -1
  80. package/dist/schedule.js +36 -15
  81. package/dist/schedule.js.map +1 -1
  82. package/dist/settings.d.ts +228 -2
  83. package/dist/settings.d.ts.map +1 -1
  84. package/dist/settings.js +94 -0
  85. package/dist/settings.js.map +1 -1
  86. package/dist/status-note.d.ts +49 -1
  87. package/dist/status-note.d.ts.map +1 -1
  88. package/dist/status-note.js +62 -1
  89. package/dist/status-note.js.map +1 -1
  90. package/dist/structured-output.d.ts +62 -0
  91. package/dist/structured-output.d.ts.map +1 -0
  92. package/dist/structured-output.js +113 -0
  93. package/dist/structured-output.js.map +1 -0
  94. package/dist/types.d.ts +176 -10
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/ui/agent-mention.d.ts +83 -0
  97. package/dist/ui/agent-mention.d.ts.map +1 -0
  98. package/dist/ui/agent-mention.js +188 -0
  99. package/dist/ui/agent-mention.js.map +1 -0
  100. package/dist/ui/agent-widget.d.ts +96 -75
  101. package/dist/ui/agent-widget.d.ts.map +1 -1
  102. package/dist/ui/agent-widget.js +397 -420
  103. package/dist/ui/agent-widget.js.map +1 -1
  104. package/dist/ui/conversation-blocks.d.ts.map +1 -1
  105. package/dist/ui/conversation-blocks.js +6 -0
  106. package/dist/ui/conversation-blocks.js.map +1 -1
  107. package/dist/ui/conversation-timeline.d.ts +10 -2
  108. package/dist/ui/conversation-timeline.d.ts.map +1 -1
  109. package/dist/ui/conversation-timeline.js +130 -23
  110. package/dist/ui/conversation-timeline.js.map +1 -1
  111. package/dist/ui/conversation-viewer.d.ts +15 -5
  112. package/dist/ui/conversation-viewer.d.ts.map +1 -1
  113. package/dist/ui/conversation-viewer.js +202 -50
  114. package/dist/ui/conversation-viewer.js.map +1 -1
  115. package/dist/ui/fleet-list.d.ts +198 -0
  116. package/dist/ui/fleet-list.d.ts.map +1 -0
  117. package/dist/ui/fleet-list.js +487 -0
  118. package/dist/ui/fleet-list.js.map +1 -0
  119. package/dist/ui/schedule-menu.d.ts.map +1 -1
  120. package/dist/ui/schedule-menu.js +6 -7
  121. package/dist/ui/schedule-menu.js.map +1 -1
  122. package/dist/ui/select-item.d.ts +28 -0
  123. package/dist/ui/select-item.d.ts.map +1 -0
  124. package/dist/ui/select-item.js +35 -0
  125. package/dist/ui/select-item.js.map +1 -0
  126. package/dist/ui/workflow-card.d.ts +176 -0
  127. package/dist/ui/workflow-card.d.ts.map +1 -0
  128. package/dist/ui/workflow-card.js +333 -0
  129. package/dist/ui/workflow-card.js.map +1 -0
  130. package/dist/ui/workflow-dialog.d.ts +306 -0
  131. package/dist/ui/workflow-dialog.d.ts.map +1 -0
  132. package/dist/ui/workflow-dialog.js +844 -0
  133. package/dist/ui/workflow-dialog.js.map +1 -0
  134. package/dist/ui/workflow-menu.d.ts +61 -0
  135. package/dist/ui/workflow-menu.d.ts.map +1 -0
  136. package/dist/ui/workflow-menu.js +148 -0
  137. package/dist/ui/workflow-menu.js.map +1 -0
  138. package/dist/usage.d.ts +86 -1
  139. package/dist/usage.d.ts.map +1 -1
  140. package/dist/usage.js +72 -1
  141. package/dist/usage.js.map +1 -1
  142. package/dist/workflow/collisions.d.ts +96 -0
  143. package/dist/workflow/collisions.d.ts.map +1 -0
  144. package/dist/workflow/collisions.js +89 -0
  145. package/dist/workflow/collisions.js.map +1 -0
  146. package/dist/workflow/entry.d.ts +33 -0
  147. package/dist/workflow/entry.d.ts.map +1 -0
  148. package/dist/workflow/entry.js +30 -0
  149. package/dist/workflow/entry.js.map +1 -0
  150. package/dist/workflow/host.d.ts +63 -0
  151. package/dist/workflow/host.d.ts.map +1 -0
  152. package/dist/workflow/host.js +363 -0
  153. package/dist/workflow/host.js.map +1 -0
  154. package/dist/workflow/journal.d.ts +98 -0
  155. package/dist/workflow/journal.d.ts.map +1 -0
  156. package/dist/workflow/journal.js +121 -0
  157. package/dist/workflow/journal.js.map +1 -0
  158. package/dist/workflow/json-schema.d.ts +52 -0
  159. package/dist/workflow/json-schema.d.ts.map +1 -0
  160. package/dist/workflow/json-schema.js +112 -0
  161. package/dist/workflow/json-schema.js.map +1 -0
  162. package/dist/workflow/meta.d.ts +68 -0
  163. package/dist/workflow/meta.d.ts.map +1 -0
  164. package/dist/workflow/meta.js +318 -0
  165. package/dist/workflow/meta.js.map +1 -0
  166. package/dist/workflow/progress.d.ts +225 -0
  167. package/dist/workflow/progress.d.ts.map +1 -0
  168. package/dist/workflow/progress.js +362 -0
  169. package/dist/workflow/progress.js.map +1 -0
  170. package/dist/workflow/runtime.d.ts +335 -0
  171. package/dist/workflow/runtime.d.ts.map +1 -0
  172. package/dist/workflow/runtime.js +831 -0
  173. package/dist/workflow/runtime.js.map +1 -0
  174. package/dist/workflow/saved.d.ts +91 -0
  175. package/dist/workflow/saved.d.ts.map +1 -0
  176. package/dist/workflow/saved.js +204 -0
  177. package/dist/workflow/saved.js.map +1 -0
  178. package/dist/workflow/task.d.ts +137 -0
  179. package/dist/workflow/task.d.ts.map +1 -0
  180. package/dist/workflow/task.js +208 -0
  181. package/dist/workflow/task.js.map +1 -0
  182. package/dist/workflow/tool-description.d.ts +39 -0
  183. package/dist/workflow/tool-description.d.ts.map +1 -0
  184. package/dist/workflow/tool-description.js +200 -0
  185. package/dist/workflow/tool-description.js.map +1 -0
  186. package/dist/workflow/worker-source.d.ts +48 -0
  187. package/dist/workflow/worker-source.d.ts.map +1 -0
  188. package/dist/workflow/worker-source.js +779 -0
  189. package/dist/workflow/worker-source.js.map +1 -0
  190. package/dist/worktree.d.ts +10 -3
  191. package/dist/worktree.d.ts.map +1 -1
  192. package/dist/worktree.js +58 -54
  193. package/dist/worktree.js.map +1 -1
  194. package/dist/xml.d.ts +11 -0
  195. package/dist/xml.d.ts.map +1 -0
  196. package/dist/xml.js +13 -0
  197. package/dist/xml.js.map +1 -0
  198. package/docs/rpc.md +183 -0
  199. package/docs/superpowers/plans/2026-09-30-upstream-event-workflow-partial-history.md +195 -0
  200. package/docs/superpowers/specs/2026-09-30-upstream-event-workflow-partial-history-design.md +49 -0
  201. package/docs/workflows.md +437 -0
  202. package/examples/agent-tool-description.md +7 -7
  203. package/examples/workflows/compose.js +51 -0
  204. package/examples/workflows/fan-out-audit.js +47 -0
  205. package/examples/workflows/gated-fix.js +60 -0
  206. package/examples/workflows/lib/count-child.js +27 -0
  207. package/examples/workflows/review-panel.js +63 -0
  208. package/examples/workflows/structured-findings.js +78 -0
  209. package/package.json +1 -1
  210. package/src/abortable.ts +43 -0
  211. package/src/agent-color.ts +161 -0
  212. package/src/agent-file-toggle.ts +269 -0
  213. package/src/agent-history.ts +54 -2
  214. package/src/agent-manager.ts +1263 -402
  215. package/src/agent-runner.ts +251 -27
  216. package/src/agent-types.ts +188 -32
  217. package/src/child-context.ts +15 -0
  218. package/src/cross-extension-rpc.ts +96 -20
  219. package/src/custom-agents.ts +170 -13
  220. package/src/index.ts +2024 -537
  221. package/src/invocation-config.ts +118 -3
  222. package/src/mention-clone.ts +196 -0
  223. package/src/mention.ts +141 -0
  224. package/src/model-resolver.ts +18 -0
  225. package/src/model-scope.ts +70 -0
  226. package/src/nested-tools.ts +424 -0
  227. package/src/output-file.ts +61 -6
  228. package/src/prompts.ts +45 -2
  229. package/src/schedule.ts +35 -14
  230. package/src/settings.ts +312 -2
  231. package/src/status-note.ts +66 -1
  232. package/src/structured-output.ts +130 -0
  233. package/src/types.ts +177 -10
  234. package/src/ui/agent-mention.ts +216 -0
  235. package/src/ui/agent-widget.ts +389 -441
  236. package/src/ui/conversation-blocks.ts +6 -0
  237. package/src/ui/conversation-timeline.ts +139 -25
  238. package/src/ui/conversation-viewer.ts +212 -48
  239. package/src/ui/fleet-list.ts +558 -0
  240. package/src/ui/schedule-menu.ts +9 -8
  241. package/src/ui/select-item.ts +45 -0
  242. package/src/ui/workflow-card.ts +470 -0
  243. package/src/ui/workflow-dialog.ts +1115 -0
  244. package/src/ui/workflow-menu.ts +193 -0
  245. package/src/usage.ts +109 -2
  246. package/src/workflow/collisions.ts +123 -0
  247. package/src/workflow/entry.ts +47 -0
  248. package/src/workflow/host.ts +403 -0
  249. package/src/workflow/journal.ts +164 -0
  250. package/src/workflow/json-schema.ts +128 -0
  251. package/src/workflow/meta.ts +325 -0
  252. package/src/workflow/progress.ts +550 -0
  253. package/src/workflow/runtime.ts +1219 -0
  254. package/src/workflow/saved.ts +217 -0
  255. package/src/workflow/task.ts +302 -0
  256. package/src/workflow/tool-description.ts +200 -0
  257. package/src/workflow/worker-source.ts +781 -0
  258. package/src/worktree.ts +69 -55
  259. package/src/xml.ts +13 -0
  260. package/vitest.config.ts +0 -18
@@ -0,0 +1,318 @@
1
+ /**
2
+ * meta.ts — extract and validate a workflow script's `meta` block.
3
+ *
4
+ * Workflow scripts open with `export const meta = { ... }`, but the script body
5
+ * runs through `node:vm`, which has no module loader — `export` is a syntax
6
+ * error there. The block also has to be readable *before* execution, because the
7
+ * declared phases seed the progress groups the UI renders from the first frame.
8
+ *
9
+ * Claude Code solves this by parsing with acorn and requiring `meta` to be a
10
+ * pure literal (no variables, calls, spreads, or template interpolation). We
11
+ * take the same contract without the dependency: scan to the matching brace,
12
+ * then evaluate *only* that fragment in an empty vm context. A pure literal has
13
+ * nothing to call, so evaluating it cannot reach anything — and anything that
14
+ * isn't a pure literal either throws (unbound identifier) or is rejected below.
15
+ *
16
+ * The scanner is string-, comment-, and regex-aware. That matters: a workflow's
17
+ * `detail` text routinely contains braces, and `phases: [{ title: "a}b" }]` must
18
+ * not terminate the scan early.
19
+ */
20
+ import { createContext, Script } from "node:vm";
21
+ export class WorkflowMetaError extends Error {
22
+ }
23
+ /**
24
+ * Wall-clock bound on evaluating the `meta` fragment. Generous for a literal —
25
+ * this exists only to stop a pathological one from hanging the host thread.
26
+ */
27
+ const META_EVAL_TIMEOUT_MS = 100;
28
+ const PURE_LITERAL_HINT = "The `meta` object must be a PURE LITERAL — no variables, function calls, spreads, or template interpolation.";
29
+ /** Matches `export const meta =` allowing arbitrary inner whitespace. */
30
+ const META_DECLARATION = /(^|[\r\n])[ \t]*export[ \t\r\n]+const[ \t\r\n]+meta[ \t\r\n]*=/;
31
+ /**
32
+ * Whether `source` even claims to be a workflow script.
33
+ *
34
+ * The cheap half of {@link extractMeta}, exported so a directory of `.js` files
35
+ * can be told apart from a directory of workflows without evaluating anything.
36
+ * A saved-workflow folder is a normal folder — it may hold a build artifact, a
37
+ * config, someone's scratch script — and those should neither be offered as
38
+ * workflows nor produce a parser error when named.
39
+ */
40
+ export function hasMetaDeclaration(source) {
41
+ return META_DECLARATION.test(source);
42
+ }
43
+ /**
44
+ * Find the index just past the object literal that starts at `open`.
45
+ *
46
+ * Tracks string, template, comment, and regex context so braces inside them do
47
+ * not move the depth counter.
48
+ */
49
+ function scanObjectLiteral(source, open) {
50
+ let depth = 0;
51
+ let i = open;
52
+ let sawInterpolation = false;
53
+ // What we are currently inside of. "code" means brace counting is live.
54
+ let mode = "code";
55
+ // Template literals nest: `${ {a:1} }` re-enters code, and the closing brace
56
+ // of that substitution must not be read as the object's. One depth per level.
57
+ const templateStack = [];
58
+ while (i < source.length) {
59
+ const c = source[i];
60
+ const next = source[i + 1];
61
+ if (mode === "line-comment") {
62
+ if (c === "\n")
63
+ mode = "code";
64
+ i++;
65
+ continue;
66
+ }
67
+ if (mode === "block-comment") {
68
+ if (c === "*" && next === "/") {
69
+ mode = "code";
70
+ i += 2;
71
+ continue;
72
+ }
73
+ i++;
74
+ continue;
75
+ }
76
+ if (mode === "single" || mode === "double" || mode === "regex") {
77
+ if (c === "\\") {
78
+ i += 2;
79
+ continue;
80
+ }
81
+ if (mode === "single" && c === "'")
82
+ mode = "code";
83
+ else if (mode === "double" && c === '"')
84
+ mode = "code";
85
+ else if (mode === "regex" && c === "/")
86
+ mode = "code";
87
+ // An unterminated regex/string can't run past a newline; bail to code so a
88
+ // misdetected regex (see below) cannot swallow the rest of the literal.
89
+ else if (c === "\n" && mode !== "double")
90
+ mode = "code";
91
+ i++;
92
+ continue;
93
+ }
94
+ if (mode === "template") {
95
+ if (c === "\\") {
96
+ i += 2;
97
+ continue;
98
+ }
99
+ if (c === "`") {
100
+ mode = "code";
101
+ i++;
102
+ continue;
103
+ }
104
+ if (c === "$" && next === "{") {
105
+ sawInterpolation = true;
106
+ templateStack.push(depth);
107
+ depth++;
108
+ mode = "code";
109
+ i += 2;
110
+ continue;
111
+ }
112
+ i++;
113
+ continue;
114
+ }
115
+ // mode === "code"
116
+ if (c === "/" && next === "/") {
117
+ mode = "line-comment";
118
+ i += 2;
119
+ continue;
120
+ }
121
+ if (c === "/" && next === "*") {
122
+ mode = "block-comment";
123
+ i += 2;
124
+ continue;
125
+ }
126
+ if (c === "'") {
127
+ mode = "single";
128
+ i++;
129
+ continue;
130
+ }
131
+ if (c === '"') {
132
+ mode = "double";
133
+ i++;
134
+ continue;
135
+ }
136
+ if (c === "`") {
137
+ mode = "template";
138
+ i++;
139
+ continue;
140
+ }
141
+ if (c === "/" && isRegexPosition(source, i)) {
142
+ mode = "regex";
143
+ i++;
144
+ continue;
145
+ }
146
+ if (c === "{") {
147
+ depth++;
148
+ i++;
149
+ continue;
150
+ }
151
+ if (c === "}") {
152
+ depth--;
153
+ i++;
154
+ if (templateStack.length > 0 && depth === templateStack[templateStack.length - 1]) {
155
+ templateStack.pop();
156
+ mode = "template";
157
+ continue;
158
+ }
159
+ if (depth === 0)
160
+ return { end: i, sawInterpolation };
161
+ continue;
162
+ }
163
+ i++;
164
+ }
165
+ return { end: -1, sawInterpolation };
166
+ }
167
+ /**
168
+ * Decide whether the `/` at `i` opens a regex literal rather than a division.
169
+ *
170
+ * Walks back past whitespace and comments to the previous significant char: a
171
+ * regex can only follow an operator or opener, never a value. This is the usual
172
+ * heuristic and it is sufficient here, because the only thing riding on it is
173
+ * not miscounting braces inside a `meta` literal — and a `meta` literal
174
+ * containing division is already not a pure literal.
175
+ */
176
+ function isRegexPosition(source, i) {
177
+ let j = i - 1;
178
+ while (j >= 0 && /\s/.test(source[j]))
179
+ j--;
180
+ if (j < 0)
181
+ return true;
182
+ const prev = source[j];
183
+ // Identifier/number/closer before `/` means division.
184
+ return !/[\w$)\]]/.test(prev);
185
+ }
186
+ function fail(message) {
187
+ throw new WorkflowMetaError(message);
188
+ }
189
+ function assertPhases(value) {
190
+ if (value === undefined)
191
+ return undefined;
192
+ if (!Array.isArray(value))
193
+ fail("`meta.phases` must be an array of { title, detail?, model? } objects.");
194
+ return value.map((entry, index) => {
195
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
196
+ fail(`\`meta.phases[${index}]\` must be an object with a \`title\`.`);
197
+ }
198
+ const { title, detail, model } = entry;
199
+ if (typeof title !== "string" || title.trim() === "") {
200
+ fail(`\`meta.phases[${index}].title\` must be a non-empty string.`);
201
+ }
202
+ if (detail !== undefined && typeof detail !== "string") {
203
+ fail(`\`meta.phases[${index}].detail\` must be a string.`);
204
+ }
205
+ if (model !== undefined && typeof model !== "string") {
206
+ fail(`\`meta.phases[${index}].model\` must be a string.`);
207
+ }
208
+ return { title, ...(detail !== undefined ? { detail } : {}), ...(model !== undefined ? { model } : {}) };
209
+ });
210
+ }
211
+ /**
212
+ * Pull `meta` off the front of a workflow script and hand back the runnable body.
213
+ *
214
+ * Throws {@link WorkflowMetaError} with author-facing guidance for every
215
+ * rejection — these messages are shown verbatim to whoever wrote the script.
216
+ */
217
+ export function extractMeta(source) {
218
+ const declaration = META_DECLARATION.exec(source);
219
+ if (!declaration) {
220
+ fail("A workflow script must begin with `export const meta = { name, description }`.\n" +
221
+ PURE_LITERAL_HINT);
222
+ }
223
+ const open = source.indexOf("{", declaration.index + declaration[0].length);
224
+ if (open === -1)
225
+ fail("`export const meta` must be assigned an object literal.\n" + PURE_LITERAL_HINT);
226
+ const { end: close, sawInterpolation } = scanObjectLiteral(source, open);
227
+ if (close === -1)
228
+ fail("`meta` object literal is never closed — check for an unbalanced `{`.");
229
+ // Caught here rather than by evaluation: a self-contained substitution such as
230
+ // `` `a${1 + 1}b` `` resolves without touching a single global, so it would
231
+ // sail through the empty-context check below and silently produce "a2b".
232
+ if (sawInterpolation) {
233
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: quoting the syntax being rejected
234
+ fail("`meta` must not use template interpolation (`${...}`).\n" + PURE_LITERAL_HINT);
235
+ }
236
+ const fragment = source.slice(open, close);
237
+ let value;
238
+ try {
239
+ // Empty context: a pure literal needs no globals, so anything reaching for
240
+ // one (a variable, a helper call) throws here and is reported as impure.
241
+ //
242
+ // The timeout is not belt-and-braces. An IIFE needs no globals either, so
243
+ // `name: (() => { while (true); })()` is evaluable — and this runs on the
244
+ // host thread, before the script ever reaches the worker. Without a bound it
245
+ // would wedge pi itself. `timeout` only governs synchronous execution, which
246
+ // is all a literal can contain.
247
+ value = new Script(`(${fragment})`, { filename: "workflow-meta.js" })
248
+ .runInContext(createContext({}), { timeout: META_EVAL_TIMEOUT_MS });
249
+ }
250
+ catch (error) {
251
+ const detail = error instanceof Error ? error.message : String(error);
252
+ if (/timed out|Script execution/i.test(detail)) {
253
+ fail(`\`meta\` did not finish evaluating within ${META_EVAL_TIMEOUT_MS}ms — it must be a literal, not a computation.\n` +
254
+ PURE_LITERAL_HINT);
255
+ }
256
+ fail(`\`meta\` could not be evaluated: ${detail}\n${PURE_LITERAL_HINT}`);
257
+ }
258
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
259
+ fail("`meta` must be an object literal.\n" + PURE_LITERAL_HINT);
260
+ }
261
+ const raw = value;
262
+ if (typeof raw.name !== "string" || raw.name.trim() === "") {
263
+ fail("`meta.name` is required and must be a non-empty string.");
264
+ }
265
+ if (typeof raw.description !== "string" || raw.description.trim() === "") {
266
+ fail("`meta.description` is required and must be a non-empty string.");
267
+ }
268
+ if (raw.whenToUse !== undefined && typeof raw.whenToUse !== "string") {
269
+ fail("`meta.whenToUse` must be a string.");
270
+ }
271
+ const phases = assertPhases(raw.phases);
272
+ const meta = {
273
+ name: raw.name,
274
+ description: raw.description,
275
+ ...(raw.whenToUse !== undefined ? { whenToUse: raw.whenToUse } : {}),
276
+ ...(phases !== undefined ? { phases } : {}),
277
+ };
278
+ // Strip only the `export ` keyword. Replacing it with spaces rather than
279
+ // deleting it keeps every subsequent offset — and therefore every reported
280
+ // line and column — identical to the source the author wrote.
281
+ const exportAt = source.indexOf("export", declaration.index);
282
+ const body = `${source.slice(0, exportAt)}${" ".repeat(6)}${source.slice(exportAt + 6)}`;
283
+ return { meta, body };
284
+ }
285
+ /**
286
+ * `meta.name` for a call line, without re-parsing on every frame.
287
+ *
288
+ * `renderCall` runs on every repaint, and extraction evaluates a literal in a
289
+ * vm — cheap, but not free at that cadence. Keyed by the exact source, so an
290
+ * edit-and-rerun cycle re-reads it and a hit is always the answer a fresh parse
291
+ * would give.
292
+ */
293
+ const workflowNames = new Map();
294
+ /** The label a `SubagentWorkflow` call renders under, from whichever field it carries. */
295
+ export function workflowCallName(args) {
296
+ const source = args.script;
297
+ if (source === undefined || source === "") {
298
+ // A path-only call would need a synchronous file read per repaint to do
299
+ // better than this, and the file name is what the author will recognize.
300
+ if (args.scriptPath !== undefined)
301
+ return args.scriptPath.split(/[/\\]/).pop() ?? "workflow";
302
+ // A saved workflow is already named by the caller; no read needed at all.
303
+ return args.name !== undefined && args.name !== "" ? args.name : "workflow";
304
+ }
305
+ const cached = workflowNames.get(source);
306
+ if (cached !== undefined)
307
+ return cached;
308
+ let name = "workflow";
309
+ try {
310
+ name = extractMeta(source).meta.name;
311
+ }
312
+ catch {
313
+ // An invalid script still gets a call line; `execute` reports why.
314
+ }
315
+ workflowNames.set(source, name);
316
+ return name;
317
+ }
318
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/workflow/meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * progress.ts — the workflow progress model, ported from Claude Code.
3
+ *
4
+ * Progress is an **append-only event log**, not a tree. Agent entries are keyed
5
+ * by `index` and last-write-wins, so a running agent is updated by appending a
6
+ * fresh entry with the same index rather than mutating anything. Every view —
7
+ * the inline card, the workflows dialog, the fleet widget — derives its shape
8
+ * by collapsing that log. Keeping the log authoritative is what lets a batched
9
+ * update carry several agents' changes in one message from the worker.
10
+ *
11
+ * Two vocabularies, deliberately distinct:
12
+ * - entry `state` is only start | progress | done | error, with `skipped`,
13
+ * `blocked` and `cached` as separate booleans;
14
+ * - the display state adds queued, running, interrupted, skipped, blocked and
15
+ * failed, and is *derived* (see `displayState`).
16
+ * Mixing them up is the easiest way to get the rendering wrong, which is why
17
+ * the derivation lives here as one function rather than inline in each renderer.
18
+ *
19
+ * Everything in this file is pure and framework-free so the whole model is
20
+ * unit-testable without a terminal.
21
+ */
22
+ import type { WorkflowMeta, WorkflowPhaseMeta } from "./meta.js";
23
+ /** Raw entry lifecycle, as written by the runtime. */
24
+ export type WorkflowEntryState = "start" | "progress" | "done" | "error";
25
+ /** Derived per-agent state, as rendered. */
26
+ export type WorkflowDisplayState = "queued" | "running" | "done" | "failed" | "skipped" | "blocked" | "interrupted";
27
+ /** Why an agent is on a later attempt, shown next to its row. */
28
+ export type AttemptReason = "throttled" | "user-retry" | "stalled";
29
+ export interface WorkflowPhaseEntry {
30
+ type: "workflow_phase";
31
+ index: number;
32
+ title: string;
33
+ }
34
+ export interface WorkflowLogEntry {
35
+ type: "workflow_log";
36
+ message: string;
37
+ }
38
+ export interface WorkflowAgentEntry {
39
+ type: "workflow_agent";
40
+ /** Stable identity. Re-emitting this index replaces the previous entry. */
41
+ index: number;
42
+ label: string;
43
+ /**
44
+ * Absent when the agent ran before any `phase()` call. That is the signal —
45
+ * not a default of 0 — that turns the whole run into one "Agents" group.
46
+ */
47
+ phaseIndex?: number;
48
+ phaseTitle?: string;
49
+ state: WorkflowEntryState;
50
+ agentId?: string;
51
+ /**
52
+ * The manager's `AgentRecord` id, once the child has one.
53
+ *
54
+ * Distinct from {@link agentId}, which is the run's own `wf-agent-N` handle
55
+ * and means nothing outside the runtime. This is what the inspector's `c`
56
+ * key opens a conversation viewer on, so it is reported the moment the
57
+ * manager issues it rather than with the effective model — a child that dies
58
+ * before its session resolves still has a conversation worth reading.
59
+ */
60
+ recordId?: string;
61
+ agentType?: string;
62
+ /**
63
+ * Short model label for tight rows, e.g. `haiku 4.5`.
64
+ *
65
+ * Seeded from what the script asked for and then REPLACED by what the child
66
+ * actually ran on, once its session exists to report one — the same
67
+ * effective-not-requested rule every other subagent surface follows (#168).
68
+ * An `agent()` that named no model therefore starts blank and fills in.
69
+ */
70
+ model?: string;
71
+ /** Canonical `provider/model-id`, for the dialog, which has room for it. */
72
+ modelId?: string;
73
+ /** The level actually in effect, once the child's session reports one. */
74
+ thinking?: string;
75
+ /**
76
+ * What the call asked for, kept only when it did not get it — pi clamped the
77
+ * level, or an agent file's frontmatter outranked the option (#182). Rendered
78
+ * as `(asked max)` beside the effective value rather than silently replacing
79
+ * it.
80
+ */
81
+ requestedThinking?: string;
82
+ requestedModel?: string;
83
+ fallbackModel?: string;
84
+ isolation?: "worktree";
85
+ error?: string;
86
+ skipped?: boolean;
87
+ blocked?: boolean;
88
+ cached?: boolean;
89
+ queuedAt?: number;
90
+ startedAt?: number;
91
+ lastProgressAt?: number;
92
+ attempt?: number;
93
+ lastAttemptReason?: AttemptReason;
94
+ promptPreview?: string;
95
+ resultPreview?: string;
96
+ tokens?: number;
97
+ toolCalls?: number;
98
+ durationMs?: number;
99
+ }
100
+ export type WorkflowEntry = WorkflowPhaseEntry | WorkflowLogEntry | WorkflowAgentEntry;
101
+ /** Overall run status, mirroring the task record. */
102
+ export type WorkflowRunStatus = "running" | "completed" | "failed" | "killed" | "paused";
103
+ export interface CollapsedProgress {
104
+ agents: WorkflowAgentEntry[];
105
+ logs: string[];
106
+ phaseTitles: Map<number, string>;
107
+ }
108
+ export interface PhaseGroup {
109
+ title: string;
110
+ status: "not-started" | "running" | "done" | "failed";
111
+ agents: WorkflowAgentEntry[];
112
+ doneCount: number;
113
+ totalCount: number;
114
+ tokens: number;
115
+ durationMs: number;
116
+ }
117
+ export interface WorkflowStats {
118
+ done: number;
119
+ failedCount: number;
120
+ running: boolean;
121
+ total: number;
122
+ started: number;
123
+ complete: boolean;
124
+ }
125
+ /**
126
+ * Fold the event log into its latest state.
127
+ *
128
+ * Agent entries collapse by index (last write wins); logs accumulate in order;
129
+ * phase titles are a lookup for grouping.
130
+ */
131
+ export declare function collapse(progress: readonly WorkflowEntry[]): CollapsedProgress;
132
+ /**
133
+ * Derive what to render for one agent.
134
+ *
135
+ * `workflowActive` is false once the run has stopped: anything still mid-flight
136
+ * at that point was cut off rather than finished, hence "interrupted".
137
+ */
138
+ export declare function displayState(entry: WorkflowAgentEntry, workflowActive: boolean): WorkflowDisplayState;
139
+ /** True while an entry is still expected to change. */
140
+ export declare function isLive(entry: WorkflowAgentEntry): boolean;
141
+ /**
142
+ * Build the phase groups a renderer walks.
143
+ *
144
+ * When nothing declared or emitted a phase, every agent collapses into a single
145
+ * group titled "Agents" so the tree still has one level of structure.
146
+ */
147
+ export declare function buildPhaseGroups(progress: readonly WorkflowEntry[], declared?: readonly WorkflowPhaseMeta[]): PhaseGroup[];
148
+ /**
149
+ * Aggregate counts for the header line.
150
+ *
151
+ * `agentCount` is the number the runtime has *scheduled*, which can exceed the
152
+ * number that has emitted an entry — a fan-out reports its size before its
153
+ * agents start, so the total does not visibly climb as they trickle in.
154
+ */
155
+ export declare function stats(progress: readonly WorkflowEntry[], agentCount?: number): WorkflowStats;
156
+ /** Elapsed run time, excluding any time spent paused. */
157
+ export declare function elapsedMs(task: {
158
+ startTime: number;
159
+ endTime?: number;
160
+ totalPausedMs?: number;
161
+ }, now: number): number;
162
+ /** `1m12s` / `9s` / `340ms`, matching how the rest of the extension reads. */
163
+ export declare function formatDuration(ms: number): string;
164
+ export interface WorkflowHeader {
165
+ name: string;
166
+ subtext: string;
167
+ stats: string;
168
+ }
169
+ /**
170
+ * The one-line summary above the tree: `3/7 agents · 1m12s`, plus a terminal
171
+ * suffix once the run stops. Deliberately carries no phase count.
172
+ */
173
+ export declare function header(task: {
174
+ status: WorkflowRunStatus;
175
+ workflowName?: string;
176
+ summary?: string;
177
+ description?: string;
178
+ startTime: number;
179
+ endTime?: number;
180
+ totalPausedMs?: number;
181
+ }, meta: WorkflowMeta | undefined, groups: readonly PhaseGroup[], agentCount: number, now: number): WorkflowHeader;
182
+ export declare const DEFAULT_AGENT_CAP = 25;
183
+ export declare const DEFAULT_TOKEN_CAP = 1500000;
184
+ /** Assumed spend per agent before any has reported, for the projection. */
185
+ export declare const ASSUMED_TOKENS_PER_AGENT = 70000;
186
+ export interface SizeWarning {
187
+ axis: "agents" | "tokens" | "both";
188
+ scheduledAgents: number;
189
+ totalTokens: number;
190
+ projectedTokens: number;
191
+ agentCap: number;
192
+ tokenCap: number;
193
+ }
194
+ /**
195
+ * Warn when a run is about to get expensive.
196
+ *
197
+ * The projection matters more than the current total: a 200-agent fan-out is
198
+ * worth flagging at agent 3, not after it has already spent the budget.
199
+ */
200
+ export declare function sizeWarning(input: {
201
+ scheduledAgents: number;
202
+ startedAgents: number;
203
+ totalTokens: number;
204
+ agentCap?: number;
205
+ tokenCap?: number;
206
+ }): SizeWarning | undefined;
207
+ /**
208
+ * Render a phase title as an activity: `Scan` → `Scanning`.
209
+ *
210
+ * Only applied in the footer, where the line reads as "what is happening now".
211
+ * Anything that is not a plain short word is left untouched.
212
+ */
213
+ export declare function gerund(word: string): string;
214
+ /**
215
+ * The footer's "what is this run doing" label.
216
+ *
217
+ * One active phase shows its position; two concurrent phases are joined, since
218
+ * a barrier-free pipeline routinely has work in more than one at a time.
219
+ */
220
+ export declare function footerPhaseLabel(input: {
221
+ titles: readonly string[];
222
+ positionStart: number;
223
+ totalPhases: number;
224
+ }): string;
225
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/workflow/progress.ts"],"names":[],"mappings":"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"}