@dreki-gg/pi-subagent 0.8.2 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @dreki-gg/pi-subagent
2
2
 
3
+ ## 0.8.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6f0b219`](https://github.com/dreki-gg/pi-extensions/commit/6f0b219ac357ce1607a7a8211fd1c66bd35c62f1) Thanks [@jalbarrang](https://github.com/jalbarrang)! - fix(subagent): resolve TDZ crash when onMessage/onToolResult callbacks fire before spawnResult is assigned
8
+
9
+ Previously, `runSingleAgent` declared `const spawnResult = await spawnPiAgent({...})` and referenced `spawnResult` inside the `onMessage`/`onToolResult` callbacks. Since callbacks fire during the await (before the const is assigned), this caused a `ReferenceError: Cannot access 'spawnResult' before initialization`. Now uses `let` with a guard to safely accumulate messages when the result is not yet available.
10
+
3
11
  ## 0.8.2
4
12
 
5
13
  ### Patch Changes
@@ -27,14 +27,16 @@ import {
27
27
  SettingsManager,
28
28
  } from '@earendil-works/pi-coding-agent';
29
29
  import type { ResolvedPaths } from '@earendil-works/pi-coding-agent';
30
- import { Box, Container, Markdown, Spacer, Text, type AutocompleteItem } from '@earendil-works/pi-tui';
31
- import { Type } from 'typebox';
32
30
  import {
33
- type AgentConfig,
34
- type AgentScope,
35
- type AgentSource,
36
- discoverAgents,
37
- } from './agents.js';
31
+ Box,
32
+ Container,
33
+ Markdown,
34
+ Spacer,
35
+ Text,
36
+ type AutocompleteItem,
37
+ } from '@earendil-works/pi-tui';
38
+ import { Type } from 'typebox';
39
+ import { type AgentConfig, type AgentScope, type AgentSource, discoverAgents } from './agents.js';
38
40
  import { formatRunAgentUsage, parseRunAgentArgs } from './run-agent-args.js';
39
41
  import { runAgent } from './agent-runner.js';
40
42
  import { extractRecentConversation } from './synthesis.js';
@@ -247,7 +249,6 @@ async function mapWithConcurrencyLimit<TIn, TOut>(
247
249
  return results;
248
250
  }
249
251
 
250
-
251
252
  type OnUpdateCallback = (partial: AgentToolResult<SubagentDetails>) => void;
252
253
 
253
254
  async function runSingleAgent(
@@ -303,7 +304,8 @@ async function runSingleAgent(
303
304
  }
304
305
  };
305
306
 
306
- const spawnResult = await spawnPiAgent({
307
+ let spawnResult: Awaited<ReturnType<typeof spawnPiAgent>> | undefined;
308
+ spawnResult = await spawnPiAgent({
307
309
  cwd: cwd ?? defaultCwd,
308
310
  agentName: agent.name,
309
311
  task,
@@ -313,15 +315,23 @@ async function runSingleAgent(
313
315
  tools: agent.tools,
314
316
  signal,
315
317
  onMessage: (msg) => {
316
- currentResult.messages = spawnResult.messages;
317
- currentResult.usage = spawnResult.usage;
318
- currentResult.model = spawnResult.model ?? currentResult.model;
319
- currentResult.stopReason = spawnResult.stopReason;
320
- currentResult.errorMessage = spawnResult.errorMessage;
318
+ if (!spawnResult) {
319
+ currentResult.messages = [...currentResult.messages, msg];
320
+ } else {
321
+ currentResult.messages = spawnResult.messages;
322
+ currentResult.usage = spawnResult.usage;
323
+ currentResult.model = spawnResult.model ?? currentResult.model;
324
+ currentResult.stopReason = spawnResult.stopReason;
325
+ currentResult.errorMessage = spawnResult.errorMessage;
326
+ }
321
327
  emitUpdate();
322
328
  },
323
- onToolResult: () => {
324
- currentResult.messages = spawnResult.messages;
329
+ onToolResult: (msg) => {
330
+ if (!spawnResult) {
331
+ currentResult.messages = [...currentResult.messages, msg];
332
+ } else {
333
+ currentResult.messages = spawnResult.messages;
334
+ }
325
335
  emitUpdate();
326
336
  },
327
337
  });
@@ -373,13 +383,19 @@ const SubagentParams = Type.Object({
373
383
  Type.String({ description: 'Optional default model override for the run or all steps/tasks' }),
374
384
  ),
375
385
  thinking: Type.Optional(
376
- Type.String({ description: 'Optional default reasoning level override for the run or all steps/tasks' }),
386
+ Type.String({
387
+ description: 'Optional default reasoning level override for the run or all steps/tasks',
388
+ }),
377
389
  ),
378
390
  tasks: Type.Optional(
379
- Type.Array(TaskItem, { description: 'Array of {agent, task, model?, thinking?} for parallel execution' }),
391
+ Type.Array(TaskItem, {
392
+ description: 'Array of {agent, task, model?, thinking?} for parallel execution',
393
+ }),
380
394
  ),
381
395
  chain: Type.Optional(
382
- Type.Array(ChainItem, { description: 'Array of {agent, task, model?, thinking?} for sequential execution' }),
396
+ Type.Array(ChainItem, {
397
+ description: 'Array of {agent, task, model?, thinking?} for sequential execution',
398
+ }),
383
399
  ),
384
400
  agentScope: Type.Optional(AgentScopeSchema),
385
401
  confirmProjectAgents: Type.Optional(
@@ -424,9 +440,7 @@ export default function (pi: ExtensionAPI) {
424
440
  if (!trimmedEnd) return replacement;
425
441
  if (/\s$/.test(argumentText)) return `${trimmedEnd} ${replacement}`;
426
442
  const lastSpace = trimmedEnd.lastIndexOf(' ');
427
- return lastSpace === -1
428
- ? replacement
429
- : `${trimmedEnd.slice(0, lastSpace + 1)}${replacement}`;
443
+ return lastSpace === -1 ? replacement : `${trimmedEnd.slice(0, lastSpace + 1)}${replacement}`;
430
444
  }
431
445
 
432
446
  function buildArgumentCompletions(
@@ -456,9 +470,9 @@ export default function (pi: ExtensionAPI) {
456
470
  return discoverAgents(autocompleteCwd, scope, resolvedPaths).agents;
457
471
  }
458
472
 
459
- async function getAutocompleteModels(scope: AgentScope): Promise<
460
- Array<{ value: string; label?: string; description?: string }>
461
- > {
473
+ async function getAutocompleteModels(
474
+ scope: AgentScope,
475
+ ): Promise<Array<{ value: string; label?: string; description?: string }>> {
462
476
  const items = new Map<string, { value: string; label?: string; description?: string }>();
463
477
 
464
478
  try {
@@ -1238,7 +1252,9 @@ export default function (pi: ExtensionAPI) {
1238
1252
  title,
1239
1253
  modeLine,
1240
1254
  theme.fg('muted', `Task: ${details.task}`),
1241
- failed && details.errorMessage ? theme.fg('error', `Error: ${details.errorMessage}`) : previewLines,
1255
+ failed && details.errorMessage
1256
+ ? theme.fg('error', `Error: ${details.errorMessage}`)
1257
+ : previewLines,
1242
1258
  usageLine ? theme.fg('dim', usageLine) : undefined,
1243
1259
  theme.fg('muted', '(Ctrl+O to expand)'),
1244
1260
  ]
@@ -1347,7 +1363,10 @@ export default function (pi: ExtensionAPI) {
1347
1363
  { value: '--model', description: 'Override the agent model for this run' },
1348
1364
  { value: '--thinking', description: 'Override the reasoning level for this run' },
1349
1365
  { value: '--reasoning-level', description: 'Alias for --thinking' },
1350
- { value: '--yes-project-agents', description: 'Skip the project-agent trust confirmation prompt' },
1366
+ {
1367
+ value: '--yes-project-agents',
1368
+ description: 'Skip the project-agent trust confirmation prompt',
1369
+ },
1351
1370
  ...agents.map((agent) => ({
1352
1371
  value: agent.name,
1353
1372
  label: agent.name,
@@ -1363,7 +1382,8 @@ export default function (pi: ExtensionAPI) {
1363
1382
  return;
1364
1383
  }
1365
1384
 
1366
- const { agentName, explicitTask, agentScope, confirmProjectAgents, model, thinking } = parsed.options;
1385
+ const { agentName, explicitTask, agentScope, confirmProjectAgents, model, thinking } =
1386
+ parsed.options;
1367
1387
  if (!agentName) {
1368
1388
  ctx.ui.notify(formatRunAgentUsage(), 'warning');
1369
1389
  return;
@@ -1394,7 +1414,10 @@ export default function (pi: ExtensionAPI) {
1394
1414
  const conversation = extractRecentConversation(ctx);
1395
1415
  const task = buildRunAgentTask(conversation, explicitTask);
1396
1416
  if (!task) {
1397
- ctx.ui.notify(`No conversation context and no task specified.\n\n${formatRunAgentUsage()}`, 'warning');
1417
+ ctx.ui.notify(
1418
+ `No conversation context and no task specified.\n\n${formatRunAgentUsage()}`,
1419
+ 'warning',
1420
+ );
1398
1421
  return;
1399
1422
  }
1400
1423
 
@@ -1486,5 +1509,4 @@ export default function (pi: ExtensionAPI) {
1486
1509
  await runAndReport(ctx.cwd, ctx.ui, (message) => pi.sendMessage(message), false);
1487
1510
  },
1488
1511
  });
1489
-
1490
1512
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dreki-gg/pi-subagent",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Subagent tool and direct agent runs for pi — isolated agents, parallel scouts, manager workflows, and bundled prompts",
5
5
  "keywords": [
6
6
  "pi-package"