gsd-pi 2.35.0 → 2.36.0-dev.d612764

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 (194) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +7 -2
  3. package/dist/resource-loader.d.ts +1 -1
  4. package/dist/resource-loader.js +13 -1
  5. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  6. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  7. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  8. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  9. package/dist/resources/extensions/bg-shell/types.js +0 -2
  10. package/dist/resources/extensions/cmux/index.js +321 -0
  11. package/dist/resources/extensions/context7/index.js +5 -0
  12. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  13. package/dist/resources/extensions/google-search/index.js +5 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +334 -104
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  16. package/dist/resources/extensions/gsd/auto-loop.js +28 -3
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +15 -3
  18. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  19. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  20. package/dist/resources/extensions/gsd/auto.js +75 -4
  21. package/dist/resources/extensions/gsd/commands-cmux.js +120 -0
  22. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  23. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  24. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  25. package/dist/resources/extensions/gsd/commands-rate.js +31 -0
  26. package/dist/resources/extensions/gsd/commands.js +94 -2
  27. package/dist/resources/extensions/gsd/docs/preferences-reference.md +25 -0
  28. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  29. package/dist/resources/extensions/gsd/files.js +11 -2
  30. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  31. package/dist/resources/extensions/gsd/guided-flow.js +8 -2
  32. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  33. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  34. package/dist/resources/extensions/gsd/index.js +31 -33
  35. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  36. package/dist/resources/extensions/gsd/milestone-ids.js +3 -2
  37. package/dist/resources/extensions/gsd/notifications.js +10 -1
  38. package/dist/resources/extensions/gsd/paths.js +74 -7
  39. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  40. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  41. package/dist/resources/extensions/gsd/preferences-validation.js +45 -1
  42. package/dist/resources/extensions/gsd/preferences.js +15 -0
  43. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  44. package/dist/resources/extensions/gsd/prompts/research-milestone.md +4 -3
  45. package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -2
  46. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  47. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  48. package/dist/resources/extensions/gsd/session-lock.js +53 -2
  49. package/dist/resources/extensions/gsd/state.js +2 -1
  50. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  51. package/dist/resources/extensions/gsd/templates/preferences.md +6 -0
  52. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  53. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  54. package/dist/resources/extensions/search-the-web/native-search.js +45 -4
  55. package/dist/resources/extensions/shared/mod.js +1 -1
  56. package/dist/resources/extensions/shared/sanitize.js +30 -0
  57. package/dist/resources/extensions/shared/terminal.js +5 -0
  58. package/dist/resources/extensions/subagent/index.js +186 -74
  59. package/dist/resources/skills/core-web-vitals/SKILL.md +1 -1
  60. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +1 -1
  61. package/dist/resources/skills/github-workflows/SKILL.md +0 -2
  62. package/dist/resources/skills/web-quality-audit/SKILL.md +0 -2
  63. package/package.json +2 -1
  64. package/packages/pi-agent-core/dist/agent.d.ts +10 -2
  65. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  66. package/packages/pi-agent-core/dist/agent.js +19 -8
  67. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  68. package/packages/pi-agent-core/src/agent.ts +31 -10
  69. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  70. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  71. package/packages/pi-ai/src/providers/openai-responses.ts +1 -1
  72. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  73. package/packages/pi-coding-agent/dist/core/agent-session.js +20 -4
  74. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  75. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/resource-loader.js +13 -2
  77. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  78. package/packages/pi-coding-agent/package.json +1 -1
  79. package/packages/pi-coding-agent/src/core/agent-session.ts +36 -12
  80. package/packages/pi-coding-agent/src/core/resource-loader.ts +13 -2
  81. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  82. package/packages/pi-tui/dist/terminal-image.js +4 -0
  83. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  84. package/packages/pi-tui/src/terminal-image.ts +5 -0
  85. package/pkg/package.json +1 -1
  86. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  87. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  88. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  89. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  90. package/src/resources/extensions/bg-shell/types.ts +0 -12
  91. package/src/resources/extensions/cmux/index.ts +384 -0
  92. package/src/resources/extensions/context7/index.ts +7 -0
  93. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  94. package/src/resources/extensions/google-search/index.ts +7 -0
  95. package/src/resources/extensions/gsd/auto-dashboard.ts +363 -116
  96. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  97. package/src/resources/extensions/gsd/auto-loop.ts +64 -2
  98. package/src/resources/extensions/gsd/auto-model-selection.ts +23 -2
  99. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  100. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  101. package/src/resources/extensions/gsd/auto.ts +82 -3
  102. package/src/resources/extensions/gsd/commands-cmux.ts +143 -0
  103. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  104. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  105. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  106. package/src/resources/extensions/gsd/commands-rate.ts +55 -0
  107. package/src/resources/extensions/gsd/commands.ts +97 -2
  108. package/src/resources/extensions/gsd/docs/preferences-reference.md +25 -0
  109. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  110. package/src/resources/extensions/gsd/files.ts +12 -2
  111. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  112. package/src/resources/extensions/gsd/guided-flow.ts +8 -2
  113. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  114. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  115. package/src/resources/extensions/gsd/index.ts +37 -32
  116. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  117. package/src/resources/extensions/gsd/milestone-ids.ts +3 -2
  118. package/src/resources/extensions/gsd/notifications.ts +10 -1
  119. package/src/resources/extensions/gsd/paths.ts +73 -7
  120. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  121. package/src/resources/extensions/gsd/preferences-types.ts +13 -0
  122. package/src/resources/extensions/gsd/preferences-validation.ts +42 -1
  123. package/src/resources/extensions/gsd/preferences.ts +18 -1
  124. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  125. package/src/resources/extensions/gsd/prompts/research-milestone.md +4 -3
  126. package/src/resources/extensions/gsd/prompts/research-slice.md +3 -2
  127. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  128. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  129. package/src/resources/extensions/gsd/session-lock.ts +59 -2
  130. package/src/resources/extensions/gsd/state.ts +2 -1
  131. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  132. package/src/resources/extensions/gsd/templates/preferences.md +6 -0
  133. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +2 -0
  134. package/src/resources/extensions/gsd/tests/cmux.test.ts +98 -0
  135. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  136. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  137. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  138. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  139. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  140. package/src/resources/extensions/gsd/tests/preferences.test.ts +35 -2
  141. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +26 -0
  142. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  143. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  144. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +7 -0
  145. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  146. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  147. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  148. package/src/resources/extensions/search-the-web/native-search.ts +50 -4
  149. package/src/resources/extensions/shared/mod.ts +1 -1
  150. package/src/resources/extensions/shared/sanitize.ts +36 -0
  151. package/src/resources/extensions/shared/terminal.ts +5 -0
  152. package/src/resources/extensions/subagent/index.ts +242 -91
  153. package/src/resources/skills/core-web-vitals/SKILL.md +1 -1
  154. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +1 -1
  155. package/src/resources/skills/github-workflows/SKILL.md +0 -2
  156. package/src/resources/skills/web-quality-audit/SKILL.md +0 -2
  157. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  158. package/dist/resources/skills/swiftui/SKILL.md +0 -208
  159. package/dist/resources/skills/swiftui/references/animations.md +0 -921
  160. package/dist/resources/skills/swiftui/references/architecture.md +0 -1561
  161. package/dist/resources/skills/swiftui/references/layout-system.md +0 -1186
  162. package/dist/resources/skills/swiftui/references/navigation.md +0 -1492
  163. package/dist/resources/skills/swiftui/references/networking-async.md +0 -214
  164. package/dist/resources/skills/swiftui/references/performance.md +0 -1706
  165. package/dist/resources/skills/swiftui/references/platform-integration.md +0 -204
  166. package/dist/resources/skills/swiftui/references/state-management.md +0 -1443
  167. package/dist/resources/skills/swiftui/references/swiftdata.md +0 -297
  168. package/dist/resources/skills/swiftui/references/testing-debugging.md +0 -247
  169. package/dist/resources/skills/swiftui/references/uikit-appkit-interop.md +0 -218
  170. package/dist/resources/skills/swiftui/workflows/add-feature.md +0 -191
  171. package/dist/resources/skills/swiftui/workflows/build-new-app.md +0 -311
  172. package/dist/resources/skills/swiftui/workflows/debug-swiftui.md +0 -192
  173. package/dist/resources/skills/swiftui/workflows/optimize-performance.md +0 -197
  174. package/dist/resources/skills/swiftui/workflows/ship-app.md +0 -203
  175. package/dist/resources/skills/swiftui/workflows/write-tests.md +0 -235
  176. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
  177. package/src/resources/skills/swiftui/SKILL.md +0 -208
  178. package/src/resources/skills/swiftui/references/animations.md +0 -921
  179. package/src/resources/skills/swiftui/references/architecture.md +0 -1561
  180. package/src/resources/skills/swiftui/references/layout-system.md +0 -1186
  181. package/src/resources/skills/swiftui/references/navigation.md +0 -1492
  182. package/src/resources/skills/swiftui/references/networking-async.md +0 -214
  183. package/src/resources/skills/swiftui/references/performance.md +0 -1706
  184. package/src/resources/skills/swiftui/references/platform-integration.md +0 -204
  185. package/src/resources/skills/swiftui/references/state-management.md +0 -1443
  186. package/src/resources/skills/swiftui/references/swiftdata.md +0 -297
  187. package/src/resources/skills/swiftui/references/testing-debugging.md +0 -247
  188. package/src/resources/skills/swiftui/references/uikit-appkit-interop.md +0 -218
  189. package/src/resources/skills/swiftui/workflows/add-feature.md +0 -191
  190. package/src/resources/skills/swiftui/workflows/build-new-app.md +0 -311
  191. package/src/resources/skills/swiftui/workflows/debug-swiftui.md +0 -192
  192. package/src/resources/skills/swiftui/workflows/optimize-performance.md +0 -197
  193. package/src/resources/skills/swiftui/workflows/ship-app.md +0 -203
  194. package/src/resources/skills/swiftui/workflows/write-tests.md +0 -235
@@ -20,9 +20,12 @@ import { StringEnum } from "@gsd/pi-ai";
20
20
  import { getMarkdownTheme } from "@gsd/pi-coding-agent";
21
21
  import { Container, Markdown, Spacer, Text } from "@gsd/pi-tui";
22
22
  import { Type } from "@sinclair/typebox";
23
+ import { formatTokenCount } from "../shared/mod.js";
23
24
  import { discoverAgents } from "./agents.js";
24
25
  import { createIsolation, mergeDeltaPatches, readIsolationMode, } from "./isolation.js";
25
26
  import { registerWorker, updateWorker } from "./worker-registry.js";
27
+ import { loadEffectiveGSDPreferences } from "../gsd/preferences.js";
28
+ import { CmuxClient, shellEscape } from "../cmux/index.js";
26
29
  const MAX_PARALLEL_TASKS = 8;
27
30
  const MAX_CONCURRENCY = 4;
28
31
  const COLLAPSED_ITEM_COUNT = 10;
@@ -58,31 +61,22 @@ async function stopLiveSubagents() {
58
61
  }
59
62
  }
60
63
  }
61
- function formatTokens(count) {
62
- if (count < 1000)
63
- return count.toString();
64
- if (count < 10000)
65
- return `${(count / 1000).toFixed(1)}k`;
66
- if (count < 1000000)
67
- return `${Math.round(count / 1000)}k`;
68
- return `${(count / 1000000).toFixed(1)}M`;
69
- }
70
64
  function formatUsageStats(usage, model) {
71
65
  const parts = [];
72
66
  if (usage.turns)
73
67
  parts.push(`${usage.turns} turn${usage.turns > 1 ? "s" : ""}`);
74
68
  if (usage.input)
75
- parts.push(`↑${formatTokens(usage.input)}`);
69
+ parts.push(`↑${formatTokenCount(usage.input)}`);
76
70
  if (usage.output)
77
- parts.push(`↓${formatTokens(usage.output)}`);
71
+ parts.push(`↓${formatTokenCount(usage.output)}`);
78
72
  if (usage.cacheRead)
79
- parts.push(`R${formatTokens(usage.cacheRead)}`);
73
+ parts.push(`R${formatTokenCount(usage.cacheRead)}`);
80
74
  if (usage.cacheWrite)
81
- parts.push(`W${formatTokens(usage.cacheWrite)}`);
75
+ parts.push(`W${formatTokenCount(usage.cacheWrite)}`);
82
76
  if (usage.cost)
83
77
  parts.push(`$${(Number(usage.cost) || 0).toFixed(4)}`);
84
78
  if (usage.contextTokens && usage.contextTokens > 0) {
85
- parts.push(`ctx:${formatTokens(usage.contextTokens)}`);
79
+ parts.push(`ctx:${formatTokenCount(usage.contextTokens)}`);
86
80
  }
87
81
  if (model)
88
82
  parts.push(model);
@@ -199,6 +193,66 @@ function writePromptToTempFile(agentName, prompt) {
199
193
  fs.writeFileSync(filePath, prompt, { encoding: "utf-8", mode: 0o600 });
200
194
  return { dir: tmpDir, filePath };
201
195
  }
196
+ function buildSubagentProcessArgs(agent, task, tmpPromptPath) {
197
+ const args = ["--mode", "json", "-p", "--no-session"];
198
+ if (agent.model)
199
+ args.push("--model", agent.model);
200
+ if (agent.tools && agent.tools.length > 0)
201
+ args.push("--tools", agent.tools.join(","));
202
+ if (tmpPromptPath)
203
+ args.push("--append-system-prompt", tmpPromptPath);
204
+ args.push(`Task: ${task}`);
205
+ return args;
206
+ }
207
+ function processSubagentEventLine(line, currentResult, emitUpdate) {
208
+ if (!line.trim())
209
+ return;
210
+ let event;
211
+ try {
212
+ event = JSON.parse(line);
213
+ }
214
+ catch {
215
+ return;
216
+ }
217
+ if (event.type === "message_end" && event.message) {
218
+ const msg = event.message;
219
+ currentResult.messages.push(msg);
220
+ if (msg.role === "assistant") {
221
+ currentResult.usage.turns++;
222
+ const usage = msg.usage;
223
+ if (usage) {
224
+ currentResult.usage.input += usage.input || 0;
225
+ currentResult.usage.output += usage.output || 0;
226
+ currentResult.usage.cacheRead += usage.cacheRead || 0;
227
+ currentResult.usage.cacheWrite += usage.cacheWrite || 0;
228
+ currentResult.usage.cost += usage.cost?.total || 0;
229
+ currentResult.usage.contextTokens = usage.totalTokens || 0;
230
+ }
231
+ if (!currentResult.model && msg.model)
232
+ currentResult.model = msg.model;
233
+ if (msg.stopReason)
234
+ currentResult.stopReason = msg.stopReason;
235
+ if (msg.errorMessage)
236
+ currentResult.errorMessage = msg.errorMessage;
237
+ }
238
+ emitUpdate();
239
+ }
240
+ if (event.type === "tool_result_end" && event.message) {
241
+ currentResult.messages.push(event.message);
242
+ emitUpdate();
243
+ }
244
+ }
245
+ async function waitForFile(filePath, signal, timeoutMs = 30 * 60 * 1000) {
246
+ const started = Date.now();
247
+ while (Date.now() - started < timeoutMs) {
248
+ if (signal?.aborted)
249
+ return false;
250
+ if (fs.existsSync(filePath))
251
+ return true;
252
+ await new Promise((resolve) => setTimeout(resolve, 150));
253
+ }
254
+ return false;
255
+ }
202
256
  async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails) {
203
257
  const agent = agents.find((a) => a.name === agentName);
204
258
  if (!agent) {
@@ -214,11 +268,6 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
214
268
  step,
215
269
  };
216
270
  }
217
- const args = ["--mode", "json", "-p", "--no-session"];
218
- if (agent.model)
219
- args.push("--model", agent.model);
220
- if (agent.tools && agent.tools.length > 0)
221
- args.push("--tools", agent.tools.join(","));
222
271
  let tmpPromptDir = null;
223
272
  let tmpPromptPath = null;
224
273
  const currentResult = {
@@ -245,9 +294,8 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
245
294
  const tmp = writePromptToTempFile(agent.name, agent.systemPrompt);
246
295
  tmpPromptDir = tmp.dir;
247
296
  tmpPromptPath = tmp.filePath;
248
- args.push("--append-system-prompt", tmpPromptPath);
249
297
  }
250
- args.push(`Task: ${task}`);
298
+ const args = buildSubagentProcessArgs(agent, task, tmpPromptPath);
251
299
  let wasAborted = false;
252
300
  const exitCode = await new Promise((resolve) => {
253
301
  const bundledPaths = (process.env.GSD_BUNDLED_EXTENSION_PATHS ?? "").split(path.delimiter).map(s => s.trim()).filter(Boolean);
@@ -255,50 +303,12 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
255
303
  const proc = spawn(process.execPath, [process.env.GSD_BIN_PATH, ...extensionArgs, ...args], { cwd: cwd ?? defaultCwd, shell: false, stdio: ["ignore", "pipe", "pipe"] });
256
304
  liveSubagentProcesses.add(proc);
257
305
  let buffer = "";
258
- const processLine = (line) => {
259
- if (!line.trim())
260
- return;
261
- let event;
262
- try {
263
- event = JSON.parse(line);
264
- }
265
- catch {
266
- return;
267
- }
268
- if (event.type === "message_end" && event.message) {
269
- const msg = event.message;
270
- currentResult.messages.push(msg);
271
- if (msg.role === "assistant") {
272
- currentResult.usage.turns++;
273
- const usage = msg.usage;
274
- if (usage) {
275
- currentResult.usage.input += usage.input || 0;
276
- currentResult.usage.output += usage.output || 0;
277
- currentResult.usage.cacheRead += usage.cacheRead || 0;
278
- currentResult.usage.cacheWrite += usage.cacheWrite || 0;
279
- currentResult.usage.cost += usage.cost?.total || 0;
280
- currentResult.usage.contextTokens = usage.totalTokens || 0;
281
- }
282
- if (!currentResult.model && msg.model)
283
- currentResult.model = msg.model;
284
- if (msg.stopReason)
285
- currentResult.stopReason = msg.stopReason;
286
- if (msg.errorMessage)
287
- currentResult.errorMessage = msg.errorMessage;
288
- }
289
- emitUpdate();
290
- }
291
- if (event.type === "tool_result_end" && event.message) {
292
- currentResult.messages.push(event.message);
293
- emitUpdate();
294
- }
295
- };
296
306
  proc.stdout.on("data", (data) => {
297
307
  buffer += data.toString();
298
308
  const lines = buffer.split("\n");
299
309
  buffer = lines.pop() || "";
300
310
  for (const line of lines)
301
- processLine(line);
311
+ processSubagentEventLine(line, currentResult, emitUpdate);
302
312
  });
303
313
  proc.stderr.on("data", (data) => {
304
314
  currentResult.stderr += data.toString();
@@ -306,7 +316,7 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
306
316
  proc.on("close", (code) => {
307
317
  liveSubagentProcesses.delete(proc);
308
318
  if (buffer.trim())
309
- processLine(buffer);
319
+ processSubagentEventLine(buffer, currentResult, emitUpdate);
310
320
  resolve(code ?? 0);
311
321
  });
312
322
  proc.on("error", () => {
@@ -350,6 +360,103 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
350
360
  }
351
361
  }
352
362
  }
363
+ async function runSingleAgentInCmuxSplit(cmuxClient, direction, defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails) {
364
+ const agent = agents.find((a) => a.name === agentName);
365
+ if (!agent) {
366
+ return runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails);
367
+ }
368
+ let tmpPromptDir = null;
369
+ let tmpPromptPath = null;
370
+ let tmpOutputDir = null;
371
+ const currentResult = {
372
+ agent: agentName,
373
+ agentSource: agent.source,
374
+ task,
375
+ exitCode: 0,
376
+ messages: [],
377
+ stderr: "",
378
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
379
+ model: agent.model,
380
+ step,
381
+ };
382
+ const emitUpdate = () => {
383
+ if (onUpdate) {
384
+ onUpdate({
385
+ content: [{ type: "text", text: getFinalOutput(currentResult.messages) || "(running...)" }],
386
+ details: makeDetails([currentResult]),
387
+ });
388
+ }
389
+ };
390
+ try {
391
+ if (agent.systemPrompt.trim()) {
392
+ const tmp = writePromptToTempFile(agent.name, agent.systemPrompt);
393
+ tmpPromptDir = tmp.dir;
394
+ tmpPromptPath = tmp.filePath;
395
+ }
396
+ tmpOutputDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-cmux-"));
397
+ const stdoutPath = path.join(tmpOutputDir, "stdout.jsonl");
398
+ const stderrPath = path.join(tmpOutputDir, "stderr.log");
399
+ const exitPath = path.join(tmpOutputDir, "exit.code");
400
+ const cmuxSurfaceId = await cmuxClient.createSplit(direction);
401
+ if (!cmuxSurfaceId) {
402
+ return runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails);
403
+ }
404
+ const bundledPaths = (process.env.GSD_BUNDLED_EXTENSION_PATHS ?? "").split(path.delimiter).map((s) => s.trim()).filter(Boolean);
405
+ const extensionArgs = bundledPaths.flatMap((p) => ["--extension", p]);
406
+ const processArgs = [process.env.GSD_BIN_PATH, ...extensionArgs, ...buildSubagentProcessArgs(agent, task, tmpPromptPath)];
407
+ const innerScript = [
408
+ `cd ${shellEscape(cwd ?? defaultCwd)}`,
409
+ "set -o pipefail",
410
+ `${shellEscape(process.execPath)} ${processArgs.map(shellEscape).join(" ")} 2> >(tee ${shellEscape(stderrPath)} >&2) | tee ${shellEscape(stdoutPath)}`,
411
+ "status=${PIPESTATUS[0]}",
412
+ `printf '%s' "$status" > ${shellEscape(exitPath)}`,
413
+ ].join("; ");
414
+ const sent = await cmuxClient.sendSurface(cmuxSurfaceId, `bash -lc ${shellEscape(innerScript)}`);
415
+ if (!sent) {
416
+ return runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails);
417
+ }
418
+ const finished = await waitForFile(exitPath, signal);
419
+ if (!finished) {
420
+ currentResult.exitCode = 1;
421
+ currentResult.stderr = "cmux split execution timed out or was aborted";
422
+ return currentResult;
423
+ }
424
+ if (fs.existsSync(stdoutPath)) {
425
+ const stdout = fs.readFileSync(stdoutPath, "utf-8");
426
+ for (const line of stdout.split("\n")) {
427
+ processSubagentEventLine(line, currentResult, emitUpdate);
428
+ }
429
+ }
430
+ if (fs.existsSync(stderrPath)) {
431
+ currentResult.stderr = fs.readFileSync(stderrPath, "utf-8");
432
+ }
433
+ currentResult.exitCode = Number.parseInt(fs.readFileSync(exitPath, "utf-8").trim() || "1", 10) || 0;
434
+ return currentResult;
435
+ }
436
+ finally {
437
+ if (tmpPromptPath)
438
+ try {
439
+ fs.unlinkSync(tmpPromptPath);
440
+ }
441
+ catch {
442
+ /* ignore */
443
+ }
444
+ if (tmpPromptDir)
445
+ try {
446
+ fs.rmdirSync(tmpPromptDir);
447
+ }
448
+ catch {
449
+ /* ignore */
450
+ }
451
+ if (tmpOutputDir)
452
+ try {
453
+ fs.rmSync(tmpOutputDir, { recursive: true, force: true });
454
+ }
455
+ catch {
456
+ /* ignore */
457
+ }
458
+ }
459
+ }
353
460
  const TaskItem = Type.Object({
354
461
  agent: Type.String({ description: "Name of the agent to invoke" }),
355
462
  task: Type.String({ description: "Task to delegate to the agent" }),
@@ -420,6 +527,8 @@ export default function (pi) {
420
527
  const discovery = discoverAgents(ctx.cwd, agentScope);
421
528
  const agents = discovery.agents;
422
529
  const confirmProjectAgents = params.confirmProjectAgents ?? false;
530
+ const cmuxClient = CmuxClient.fromPreferences(loadEffectiveGSDPreferences()?.preferences);
531
+ const cmuxSplitsEnabled = cmuxClient.getConfig().splits;
423
532
  // Resolve isolation mode
424
533
  const isolationMode = readIsolationMode();
425
534
  const useIsolation = Boolean(params.isolated) && isolationMode !== "none";
@@ -549,23 +658,24 @@ export default function (pi) {
549
658
  const batchSize = params.tasks.length;
550
659
  const results = await mapWithConcurrencyLimit(params.tasks, MAX_CONCURRENCY, async (t, index) => {
551
660
  const workerId = registerWorker(t.agent, t.task, index, batchSize, batchId);
552
- let result = await runSingleAgent(ctx.cwd, agents, t.agent, t.task, t.cwd, undefined, signal,
553
- // Per-task update callback
554
- (partial) => {
555
- if (partial.details?.results[0]) {
556
- allResults[index] = partial.details.results[0];
557
- emitParallelUpdate();
558
- }
559
- }, makeDetails("parallel"));
560
- // Auto-retry failed tasks (likely API rate limit or transient error)
561
- const isFailed = result.exitCode !== 0 || (result.messages.length === 0 && !signal?.aborted);
562
- if (isFailed && MAX_RETRIES > 0 && !signal?.aborted) {
563
- result = await runSingleAgent(ctx.cwd, agents, t.agent, t.task, t.cwd, undefined, signal, (partial) => {
661
+ const runTask = () => cmuxSplitsEnabled
662
+ ? runSingleAgentInCmuxSplit(cmuxClient, index % 2 === 0 ? "right" : "down", ctx.cwd, agents, t.agent, t.task, t.cwd, undefined, signal, (partial) => {
663
+ if (partial.details?.results[0]) {
664
+ allResults[index] = partial.details.results[0];
665
+ emitParallelUpdate();
666
+ }
667
+ }, makeDetails("parallel"))
668
+ : runSingleAgent(ctx.cwd, agents, t.agent, t.task, t.cwd, undefined, signal, (partial) => {
564
669
  if (partial.details?.results[0]) {
565
670
  allResults[index] = partial.details.results[0];
566
671
  emitParallelUpdate();
567
672
  }
568
673
  }, makeDetails("parallel"));
674
+ let result = await runTask();
675
+ // Auto-retry failed tasks (likely API rate limit or transient error)
676
+ const isFailed = result.exitCode !== 0 || (result.messages.length === 0 && !signal?.aborted);
677
+ if (isFailed && MAX_RETRIES > 0 && !signal?.aborted) {
678
+ result = await runTask();
569
679
  }
570
680
  updateWorker(workerId, result.exitCode === 0 ? "completed" : "failed");
571
681
  allResults[index] = result;
@@ -599,7 +709,9 @@ export default function (pi) {
599
709
  const taskId = crypto.randomUUID();
600
710
  isolation = await createIsolation(effectiveCwd, taskId, isolationMode);
601
711
  }
602
- const result = await runSingleAgent(ctx.cwd, agents, params.agent, params.task, isolation ? isolation.workDir : params.cwd, undefined, signal, onUpdate, makeDetails("single"));
712
+ const result = cmuxSplitsEnabled
713
+ ? await runSingleAgentInCmuxSplit(cmuxClient, "right", ctx.cwd, agents, params.agent, params.task, isolation ? isolation.workDir : params.cwd, undefined, signal, onUpdate, makeDetails("single"))
714
+ : await runSingleAgent(ctx.cwd, agents, params.agent, params.task, isolation ? isolation.workDir : params.cwd, undefined, signal, onUpdate, makeDetails("single"));
603
715
  // Capture and merge delta if isolated
604
716
  if (isolation) {
605
717
  const patches = await isolation.captureDelta();
@@ -438,4 +438,4 @@ startTransition(() => setExpensiveState(newValue));
438
438
  - [web.dev LCP](https://web.dev/articles/lcp)
439
439
  - [web.dev INP](https://web.dev/articles/inp)
440
440
  - [web.dev CLS](https://web.dev/articles/cls)
441
- - [Performance skill](../performance/SKILL.md)
441
+ - [Code Optimizer skill](../code-optimizer/SKILL.md)
@@ -42,7 +42,7 @@ The file must `export default function(pi: ExtensionAPI) { ... }`.
42
42
 
43
43
  ## Step 4: Check for Common Mistakes
44
44
 
45
- Read `references/key-rules-gotchas.md` and verify each rule against the extension code.
45
+ Read `../references/key-rules-gotchas.md` and verify each rule against the extension code.
46
46
 
47
47
  ## Step 5: Add Debugging
48
48
 
@@ -88,5 +88,3 @@ EVIDENCE: [output from ci_monitor.cjs]
88
88
  ## References
89
89
 
90
90
  - `references/gh/SKILL.md` — gh CLI reference
91
- - `scripts/ci_monitor.cjs` — CI monitoring tool
92
- - `scripts/ci_monitor.md` — Tool usage documentation
@@ -163,8 +163,6 @@ When performing an audit, structure findings as:
163
163
  ## References
164
164
 
165
165
  For detailed guidelines on specific areas:
166
- - [Performance Optimization](../performance/SKILL.md)
167
166
  - [Core Web Vitals](../core-web-vitals/SKILL.md)
168
167
  - [Accessibility](../accessibility/SKILL.md)
169
- - [SEO](../seo/SKILL.md)
170
168
  - [Best Practices](../best-practices/SKILL.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-pi",
3
- "version": "2.35.0",
3
+ "version": "2.36.0-dev.d612764",
4
4
  "description": "GSD — Get Shit Done coding agent",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -50,6 +50,7 @@
50
50
  "copy-themes": "node scripts/copy-themes.cjs",
51
51
  "copy-export-html": "node scripts/copy-export-html.cjs",
52
52
  "test:unit": "node --import ./src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/gsd/tests/*.test.ts src/resources/extensions/gsd/tests/*.test.mjs src/tests/*.test.ts",
53
+ "test:marketplace": "GSD_TEST_CLONE_MARKETPLACES=1 node --import ./src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/gsd/tests/claude-import-tui.test.ts src/resources/extensions/gsd/tests/plugin-importer-live.test.ts src/tests/marketplace-discovery.test.ts",
53
54
  "test:coverage": "c8 --reporter=text --reporter=lcov --exclude='src/resources/extensions/gsd/tests/**' --exclude='src/tests/**' --exclude='scripts/**' --exclude='native/**' --exclude='node_modules/**' --check-coverage --statements=50 --lines=50 --branches=20 --functions=20 node --import ./src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/gsd/tests/*.test.ts src/resources/extensions/gsd/tests/*.test.mjs src/tests/*.test.ts",
54
55
  "test:integration": "node --import ./src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/gsd/tests/*integration*.test.ts src/tests/integration/*.test.ts",
55
56
  "test": "npm run test:unit && npm run test:integration",
@@ -140,15 +140,23 @@ export declare class Agent {
140
140
  * Queue a steering message to interrupt the agent mid-run.
141
141
  * Delivered after current tool execution, skips remaining tools.
142
142
  */
143
- steer(m: AgentMessage): void;
143
+ steer(m: AgentMessage, origin?: "user" | "system"): void;
144
144
  /**
145
145
  * Queue a follow-up message to be processed after the agent finishes.
146
146
  * Delivered only when agent has no more tool calls or steering messages.
147
147
  */
148
- followUp(m: AgentMessage): void;
148
+ followUp(m: AgentMessage, origin?: "user" | "system"): void;
149
149
  clearSteeringQueue(): void;
150
150
  clearFollowUpQueue(): void;
151
151
  clearAllQueues(): void;
152
+ /**
153
+ * Drain user-origin messages from queues, leaving system messages in place.
154
+ * Used during abort to preserve messages the user explicitly typed.
155
+ */
156
+ drainUserMessages(): {
157
+ steering: AgentMessage[];
158
+ followUp: AgentMessage[];
159
+ };
152
160
  hasQueuedMessages(): boolean;
153
161
  private dequeueSteeringMessages;
154
162
  private dequeueFollowUpMessages;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,mBAAmB,EAGxB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAEX,UAAU,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,SAAS,EAKT,QAAQ,EACR,aAAa,EACb,MAAM,YAAY,CAAC;AASpB,MAAM,WAAW,YAAY;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAEnC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE5E;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE/F;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;IAEvC;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;IAEvC;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAEnF;;OAEG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAE7C;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAWD,qBAAa,KAAK;IACjB,OAAO,CAAC,MAAM,CAUZ;IAEF,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAA+D;IACnF,OAAO,CAAC,gBAAgB,CAAC,CAA8E;IACvG,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,YAAY,CAA0B;IACvC,QAAQ,EAAE,QAAQ,CAAC;IAC1B,OAAO,CAAC,UAAU,CAAC,CAAS;IACrB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1F,OAAO,CAAC,UAAU,CAAC,CAAmC;IACtD,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,oBAAoB,CAAC,CAAa;IAC1C,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAC3C,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,eAAe,CAAC,CAAoC;IAC5D,OAAO,CAAC,cAAc,CAAC,CAAmC;gBAE9C,IAAI,GAAE,YAAiB;IAenC;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED;;;OAGG;IACH,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAEtC;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,eAAe,GAAG,SAAS,CAEjD;IAED;;OAEG;IACH,IAAI,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,EAErD;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,SAAS;IAI7B;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,GAAG,SAAS,CAExC;IAED;;;OAGG;IACH,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAE5C;IAED;;;OAGG;IACH,iBAAiB,CAAC,EAAE,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAI9D;;;OAGG;IACH,gBAAgB,CAAC,EAAE,EAAE,eAAe,CAAC,eAAe,CAAC,GAAG,IAAI;IAI5D,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAMlD,eAAe,CAAC,CAAC,EAAE,MAAM;IAIzB,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC;IAItB,gBAAgB,CAAC,CAAC,EAAE,aAAa;IAIjC,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe;IAI7C,eAAe,IAAI,KAAK,GAAG,eAAe;IAI1C,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe;IAI7C,eAAe,IAAI,KAAK,GAAG,eAAe;IAI1C,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE;IAI5B,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE;IAIlC,aAAa,CAAC,CAAC,EAAE,YAAY;IAI7B;;;OAGG;IACH,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,GAAE,MAAM,GAAG,QAAmB;IAI3D;;;OAGG;IACH,QAAQ,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,GAAE,MAAM,GAAG,QAAmB;IAI9D,kBAAkB;IAIlB,kBAAkB;IAIlB,cAAc;IAKd;;;OAGG;IACH,iBAAiB,IAAI;QAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE;IAQ3E,iBAAiB,IAAI,OAAO;IAI5B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,uBAAuB;IAe/B,aAAa;IAIb,KAAK;IAIL,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,KAAK;IAUL,yCAAyC;IACnC,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCnE;;OAEG;IACG,QAAQ;IA4Bd;;;;OAIG;YACW,QAAQ;IAuItB,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,IAAI;CAKZ"}
@@ -145,15 +145,15 @@ export class Agent {
145
145
  * Queue a steering message to interrupt the agent mid-run.
146
146
  * Delivered after current tool execution, skips remaining tools.
147
147
  */
148
- steer(m) {
149
- this.steeringQueue.push(m);
148
+ steer(m, origin = "system") {
149
+ this.steeringQueue.push({ message: m, origin });
150
150
  }
151
151
  /**
152
152
  * Queue a follow-up message to be processed after the agent finishes.
153
153
  * Delivered only when agent has no more tool calls or steering messages.
154
154
  */
155
- followUp(m) {
156
- this.followUpQueue.push(m);
155
+ followUp(m, origin = "system") {
156
+ this.followUpQueue.push({ message: m, origin });
157
157
  }
158
158
  clearSteeringQueue() {
159
159
  this.steeringQueue = [];
@@ -165,6 +165,17 @@ export class Agent {
165
165
  this.steeringQueue = [];
166
166
  this.followUpQueue = [];
167
167
  }
168
+ /**
169
+ * Drain user-origin messages from queues, leaving system messages in place.
170
+ * Used during abort to preserve messages the user explicitly typed.
171
+ */
172
+ drainUserMessages() {
173
+ const userSteering = this.steeringQueue.filter((e) => e.origin === "user").map((e) => e.message);
174
+ const userFollowUp = this.followUpQueue.filter((e) => e.origin === "user").map((e) => e.message);
175
+ this.steeringQueue = this.steeringQueue.filter((e) => e.origin !== "user");
176
+ this.followUpQueue = this.followUpQueue.filter((e) => e.origin !== "user");
177
+ return { steering: userSteering, followUp: userFollowUp };
178
+ }
168
179
  hasQueuedMessages() {
169
180
  return this.steeringQueue.length > 0 || this.followUpQueue.length > 0;
170
181
  }
@@ -173,11 +184,11 @@ export class Agent {
173
184
  if (this.steeringQueue.length > 0) {
174
185
  const first = this.steeringQueue[0];
175
186
  this.steeringQueue = this.steeringQueue.slice(1);
176
- return [first];
187
+ return [first.message];
177
188
  }
178
189
  return [];
179
190
  }
180
- const steering = this.steeringQueue.slice();
191
+ const steering = this.steeringQueue.map((e) => e.message);
181
192
  this.steeringQueue = [];
182
193
  return steering;
183
194
  }
@@ -186,11 +197,11 @@ export class Agent {
186
197
  if (this.followUpQueue.length > 0) {
187
198
  const first = this.followUpQueue[0];
188
199
  this.followUpQueue = this.followUpQueue.slice(1);
189
- return [first];
200
+ return [first.message];
190
201
  }
191
202
  return [];
192
203
  }
193
- const followUp = this.followUpQueue.slice();
204
+ const followUp = this.followUpQueue.map((e) => e.message);
194
205
  this.followUpQueue = [];
195
206
  return followUp;
196
207
  }