pi-subagents 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +246 -525
  3. package/agents/oracle.md +1 -0
  4. package/package.json +12 -4
  5. package/prompts/parallel-context-build.md +1 -1
  6. package/prompts/parallel-handoff-plan.md +1 -1
  7. package/prompts/review-loop.md +1 -1
  8. package/skills/pi-subagents/SKILL.md +6 -6
  9. package/skills/pi-subagents/references/constraints-and-recipes.md +19 -26
  10. package/skills/pi-subagents/references/execution-controls.md +98 -97
  11. package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  12. package/skills/pi-subagents/references/prompting-and-roles.md +18 -27
  13. package/src/agents/agent-management.ts +155 -65
  14. package/src/agents/agent-serializer.ts +19 -0
  15. package/src/agents/agents.ts +154 -71
  16. package/src/agents/chain-serializer.ts +10 -7
  17. package/src/agents/frontmatter.ts +5 -3
  18. package/src/agents/identity.ts +1 -1
  19. package/src/agents/proactive-skills.ts +13 -10
  20. package/src/agents/skills.ts +23 -6
  21. package/src/api/control-channel.ts +4 -0
  22. package/src/api/delegation.ts +26 -194
  23. package/src/api/external-runs.ts +129 -0
  24. package/src/api/intercom-bridge.ts +3 -0
  25. package/src/api/pi-args.ts +5 -0
  26. package/src/api/preflight.ts +3 -3
  27. package/src/api/shared-types.ts +19 -0
  28. package/src/extension/config.ts +10 -0
  29. package/src/extension/control-notices.ts +5 -39
  30. package/src/extension/doctor.ts +10 -9
  31. package/src/extension/fanout-child.ts +7 -4
  32. package/src/extension/index.ts +232 -68
  33. package/src/extension/rpc.ts +18 -12
  34. package/src/extension/schemas.ts +48 -37
  35. package/src/extension/tool-description.ts +36 -86
  36. package/src/inspectors/herdr/actions.ts +229 -0
  37. package/src/inspectors/herdr/client.ts +130 -0
  38. package/src/inspectors/herdr/inspector-runner.ts +141 -0
  39. package/src/inspectors/herdr/project-panes.ts +154 -0
  40. package/src/integrations/herdr-status.ts +330 -0
  41. package/src/intercom/intercom-bridge.ts +3 -2
  42. package/src/intercom/result-intercom.ts +5 -1
  43. package/src/missions/actions.ts +372 -0
  44. package/src/missions/lifecycle.ts +314 -0
  45. package/src/missions/store.ts +442 -0
  46. package/src/missions/types.ts +135 -0
  47. package/src/policy/authority.ts +46 -0
  48. package/src/profiles/profiles.ts +29 -3
  49. package/src/runs/background/async-execution.ts +98 -49
  50. package/src/runs/background/async-job-tracker.ts +10 -2
  51. package/src/runs/background/async-resume.ts +6 -6
  52. package/src/runs/background/async-status.ts +29 -1
  53. package/src/runs/background/auto-drain.ts +3 -3
  54. package/src/runs/background/chain-append.ts +3 -2
  55. package/src/runs/background/control-channel.ts +9 -7
  56. package/src/runs/background/fleet-view.ts +3 -4
  57. package/src/runs/background/notify.ts +2 -1
  58. package/src/runs/background/process-terminal.ts +5 -5
  59. package/src/runs/background/result-watcher.ts +13 -5
  60. package/src/runs/background/run-id-resolver.ts +3 -3
  61. package/src/runs/background/run-status.ts +35 -8
  62. package/src/runs/background/scheduled-runs.ts +602 -375
  63. package/src/runs/background/stale-run-reconciler.ts +3 -3
  64. package/src/runs/background/subagent-runner.ts +608 -445
  65. package/src/runs/background/subagent-wait.ts +50 -9
  66. package/src/runs/background/wait-subscriptions.ts +253 -0
  67. package/src/runs/background/wait-tool.ts +12 -4
  68. package/src/runs/foreground/async-steering-action.ts +3 -3
  69. package/src/runs/foreground/chain-clarify.ts +8 -4
  70. package/src/runs/foreground/chain-execution.ts +56 -30
  71. package/src/runs/foreground/execution.ts +15 -2
  72. package/src/runs/foreground/subagent-executor.ts +1023 -273
  73. package/src/runs/shared/acceptance.ts +28 -6
  74. package/src/runs/shared/child-protocol.ts +302 -22
  75. package/src/runs/shared/dynamic-fanout.ts +1 -1
  76. package/src/runs/shared/external-cli-runner.ts +130 -0
  77. package/src/runs/shared/long-running-guard.ts +42 -1
  78. package/src/runs/shared/nested-events.ts +59 -5
  79. package/src/runs/shared/nested-render.ts +9 -4
  80. package/src/runs/shared/parallel-handoff.ts +86 -2
  81. package/src/runs/shared/parallel-utils.ts +11 -2
  82. package/src/runs/shared/permissions.ts +95 -0
  83. package/src/runs/shared/pi-args.ts +11 -1
  84. package/src/runs/shared/pi-spawn.ts +11 -1
  85. package/src/runs/shared/run-history.ts +1 -1
  86. package/src/runs/shared/subagent-prompt-runtime.ts +36 -5
  87. package/src/runs/shared/subagent-startup-retry.ts +5 -2
  88. package/src/runs/shared/turn-budget.ts +6 -6
  89. package/src/runs/shared/worktree.ts +122 -12
  90. package/src/shared/accessible-dir.ts +29 -7
  91. package/src/shared/artifacts.ts +18 -1
  92. package/src/shared/fork-context.ts +3 -2
  93. package/src/shared/launch-contract.ts +1 -0
  94. package/src/shared/settings.ts +10 -0
  95. package/src/shared/types.ts +156 -14
  96. package/src/shared/utils.ts +8 -6
  97. package/src/slash/delegation-adapters.ts +32 -194
  98. package/src/slash/delegation-request.ts +43 -126
  99. package/src/slash/prompt-template-bridge.ts +158 -205
  100. package/src/slash/prompt-workflows.ts +21 -57
  101. package/src/slash/slash-bridge.ts +14 -0
  102. package/src/slash/slash-commands.ts +31 -632
  103. package/src/slash/subagents-admin.ts +18 -14
  104. package/src/tui/fleet-status.ts +156 -21
  105. package/src/tui/fleet-transcript.ts +110 -5
  106. package/src/tui/fleet.ts +56 -24
  107. package/src/tui/render.ts +291 -109
  108. package/src/types/pi-runtime-compat.d.ts +14 -0
  109. package/src/watchdog/lsp-diagnostics.ts +12 -7
  110. package/src/watchdog/model-selection.ts +2 -2
  111. package/src/watchdog/permission-arbiter.ts +145 -0
  112. package/src/watchdog/register-child.ts +1 -1
  113. package/src/watchdog/register-main.ts +1 -1
  114. package/src/watchdog/review.ts +4 -1
  115. package/src/watchdog/runtime.ts +3 -2
  116. package/src/workflows/chat-progress.ts +140 -0
  117. package/src/workflows/scripted-workflow.ts +415 -0
  118. package/agents/advisor.md +0 -73
  119. package/src/extension/chain-validation.ts +0 -181
@@ -10,6 +10,8 @@ import type { FSWatcher } from "node:fs";
10
10
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
11
11
  import type { ModelScopeConfig } from "../runs/shared/model-scope.ts";
12
12
  import type { ResolvedSubagentCapabilityCeiling, SubagentCapabilityAudit } from "../runs/shared/capability-ceiling.ts";
13
+ import type { AuthorityPolicyConfig } from "../policy/authority.ts";
14
+ import type { GlobalMissionIndexRecord, MissionRecord, MissionStoreConfig } from "../missions/types.ts";
13
15
 
14
16
  // ============================================================================
15
17
  // Basic Types
@@ -73,7 +75,7 @@ export interface ChainCheckpointState {
73
75
 
74
76
  export interface WorkflowGraphSnapshot {
75
77
  runId: string;
76
- mode: "chain" | "parallel" | "single";
78
+ mode: SubagentRunMode;
77
79
  phases: Array<{ title: string; nodeIds: string[] }>;
78
80
  nodes: WorkflowGraphNode[];
79
81
  currentNodeId?: string;
@@ -226,7 +228,8 @@ export interface ControlEvent {
226
228
 
227
229
  export type SubagentResultStatus = "completed" | "failed" | "paused" | "stopped" | "detached";
228
230
  export type SubagentOutputState = "present" | "absent" | "unknown";
229
- export type SubagentRunMode = "single" | "parallel" | "chain";
231
+ export type SubagentRunMode = "single" | "parallel" | "chain" | "workflow";
232
+ export type SubagentResultMode = SubagentRunMode;
230
233
 
231
234
  export interface ParallelHandoffPatch {
232
235
  path: string;
@@ -258,6 +261,8 @@ export interface ParallelHandoffCleanupTask {
258
261
  branch: string;
259
262
  worktreeRemoved: boolean;
260
263
  branchRemoved: boolean;
264
+ preserved?: boolean;
265
+ reason?: string;
261
266
  errors?: string[];
262
267
  }
263
268
 
@@ -375,6 +380,8 @@ interface ProcessTerminalBaseV1 {
375
380
  runId: string;
376
381
  childIndex?: number;
377
382
  runnerProcessInstanceId: string;
383
+ observedAt?: number;
384
+ reason?: ProcessTerminalReason;
378
385
  resumeDisposition?: "resumable" | "non-resumable" | "unavailable";
379
386
  }
380
387
 
@@ -393,7 +400,7 @@ export type ProcessTerminalV1 =
393
400
  });
394
401
 
395
402
  export type SteeringActionState = "delivered" | "scheduled" | "pending" | "partial" | "recovered" | "failed";
396
- export type SteeringTargetState = "scheduled" | "routed" | "delivered" | "late" | "failed" | "recovered";
403
+ export type SteeringTargetState = "scheduled" | "pending" | "routed" | "delivered" | "late" | "failed" | "recovered";
397
404
 
398
405
  export interface SteeringTargetStatus {
399
406
  index: number;
@@ -489,6 +496,7 @@ export interface SteeringRecoveryDescriptor {
489
496
  maxSubagentDepth: number;
490
497
  maxOutput?: MaxOutputConfig;
491
498
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
499
+ launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
492
500
  share: boolean;
493
501
  sessionDir?: string;
494
502
  artifactsDir?: string;
@@ -497,7 +505,7 @@ export interface SteeringRecoveryDescriptor {
497
505
 
498
506
  export type PublicNestedStepSummary = Pick<
499
507
  NestedStepSummary,
500
- "agent" | "status" | "sessionFile" | "transcriptPath" | "transcriptError" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "startedAt" | "endedAt" | "error" | "timedOut" | "stopped"
508
+ "agent" | "status" | "model" | "thinking" | "sessionFile" | "transcriptPath" | "transcriptError" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "startedAt" | "endedAt" | "error" | "timedOut" | "stopped"
501
509
  > & {
502
510
  children?: PublicNestedRunSummary[];
503
511
  };
@@ -510,7 +518,7 @@ export type CostSummary = {
510
518
 
511
519
  export type PublicNestedRunSummary = Pick<
512
520
  NestedRunSummary,
513
- "id" | "parentRunId" | "parentStepIndex" | "parentAgent" | "depth" | "path" | "asyncDir" | "sessionId" | "sessionFile" | "intercomTarget" | "ownerIntercomTarget" | "leafIntercomTarget" | "ownerState" | "mode" | "state" | "agent" | "agents" | "currentStep" | "chainStepCount" | "parallelGroups" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "totalTokens" | "totalCost" | "startedAt" | "endedAt" | "lastUpdate" | "error" | "timeoutMs" | "deadlineAt" | "timedOut" | "stopped" | "turnBudget" | "turnBudgetExceeded" | "wrapUpRequested"
521
+ "id" | "parentRunId" | "parentStepIndex" | "parentAgent" | "depth" | "path" | "asyncDir" | "sessionId" | "sessionFile" | "intercomTarget" | "ownerIntercomTarget" | "leafIntercomTarget" | "ownerState" | "mode" | "state" | "agent" | "agents" | "model" | "thinking" | "currentStep" | "chainStepCount" | "parallelGroups" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "totalTokens" | "totalCost" | "startedAt" | "endedAt" | "lastUpdate" | "error" | "timeoutMs" | "deadlineAt" | "timedOut" | "stopped" | "turnBudget" | "turnBudgetExceeded" | "wrapUpRequested"
514
522
  > & {
515
523
  steps?: PublicNestedStepSummary[];
516
524
  children?: PublicNestedRunSummary[];
@@ -597,8 +605,21 @@ export interface ToolCallSummary {
597
605
  }
598
606
 
599
607
  interface ProgressSummary {
608
+ index?: number;
609
+ agent?: string;
610
+ status?: AgentProgress["status"];
611
+ activityState?: ActivityState;
612
+ skills?: string[];
613
+ lastActivityAt?: number;
614
+ currentTool?: string;
615
+ currentToolArgs?: string;
616
+ currentToolStartedAt?: number;
617
+ recentTools?: Array<{ tool: string; args: string; endMs: number }>;
618
+ recentOutput?: string[];
600
619
  toolCount: number;
601
620
  tokens: number;
621
+ model?: string;
622
+ thinking?: string;
602
623
  durationMs: number;
603
624
  }
604
625
 
@@ -659,8 +680,8 @@ export interface AcceptanceConfig {
659
680
  reason?: string;
660
681
  }
661
682
 
662
- /** Bare "none" is not accepted: use { level: "none", reason: "..." }; false remains a deprecated shorthand. */
663
- export type AcceptanceInput = Exclude<AcceptanceLevel, "none"> | false | AcceptanceConfig;
683
+ /** Bare "none" and "verified" are not accepted; verified policies require object form with runtime commands. */
684
+ export type AcceptanceInput = Exclude<AcceptanceLevel, "none" | "verified"> | false | AcceptanceConfig;
664
685
 
665
686
  export interface ResolvedAcceptanceGate extends AcceptanceGate {
666
687
  id: string;
@@ -913,7 +934,7 @@ export interface SpawnBudgetSnapshot {
913
934
  }
914
935
 
915
936
  export interface Details {
916
- mode: SubagentRunMode | "management";
937
+ mode: SubagentResultMode | "management";
917
938
  runId?: string;
918
939
  /** Run-level context summary. "mixed" when children resolved to different modes. */
919
940
  context?: "fresh" | "fork" | "mixed";
@@ -964,6 +985,42 @@ export interface Details {
964
985
  runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
965
986
  /** Original launch contract whose persisted session is being revived. */
966
987
  sourceLaunchContractDigest?: string;
988
+ /** Durable mission attached to this run, when mission mode was explicitly used. */
989
+ missionId?: string;
990
+ missionPath?: string;
991
+ /** Non-fatal automatic mission persistence failure. */
992
+ missionWarning?: string;
993
+ mission?: MissionRecord;
994
+ workflow?: {
995
+ value?: unknown;
996
+ trace: Array<{
997
+ operation: "run" | "status";
998
+ key: string;
999
+ state: "started" | "completed" | "failed" | "reused";
1000
+ runId?: string;
1001
+ phase?: string;
1002
+ label?: string;
1003
+ durationMs?: number;
1004
+ error?: string;
1005
+ }>;
1006
+ emits: unknown[];
1007
+ console: Array<{ level: "log" | "info" | "warn" | "error"; text: string }>;
1008
+ };
1009
+ chatProgress?: {
1010
+ mode: "off" | "terminal" | "milestones" | "live-card";
1011
+ repoRelation: "same" | "other";
1012
+ repoLabel?: string;
1013
+ };
1014
+ missions?: {
1015
+ records?: MissionRecord[];
1016
+ globalEntries?: GlobalMissionIndexRecord[];
1017
+ warnings: string[];
1018
+ };
1019
+ /** Project-scoped recurring schedule records and run history for management actions. */
1020
+ schedules?: {
1021
+ records?: unknown[];
1022
+ runs?: unknown[];
1023
+ };
967
1024
  }
968
1025
 
969
1026
  // ============================================================================
@@ -1016,6 +1073,8 @@ export interface NestedRunAddress {
1016
1073
  export interface NestedStepSummary {
1017
1074
  agent: string;
1018
1075
  status: "pending" | "running" | "complete" | "completed" | "failed" | "paused" | "stopped" | "rejected";
1076
+ model?: string;
1077
+ thinking?: string;
1019
1078
  sessionFile?: string;
1020
1079
  transcriptPath?: string;
1021
1080
  transcriptError?: string;
@@ -1065,6 +1124,8 @@ export interface NestedRunSummary extends NestedRunAddress {
1065
1124
  state: NestedRunState;
1066
1125
  agent?: string;
1067
1126
  agents?: string[];
1127
+ model?: string;
1128
+ thinking?: string;
1068
1129
  currentStep?: number;
1069
1130
  chainStepCount?: number;
1070
1131
  parallelGroups?: AsyncParallelGroupStatus[];
@@ -1130,6 +1191,42 @@ export interface AsyncStartedEvent {
1130
1191
  turnBudget?: TurnBudgetState;
1131
1192
  nestedRoute?: NestedRouteInfo;
1132
1193
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1194
+ parentWorkflowRunId?: string;
1195
+ workflowKey?: string;
1196
+ }
1197
+
1198
+ export type AgentRunnerConfig =
1199
+ | { type: "pi" }
1200
+ | {
1201
+ type: "external-cli";
1202
+ command: string;
1203
+ args?: string[];
1204
+ promptDelivery?: "stdin";
1205
+ };
1206
+
1207
+ export interface ExternalCliRunnerStatus {
1208
+ type: "external-cli";
1209
+ command: string;
1210
+ args: string[];
1211
+ promptDelivery: "stdin";
1212
+ capabilities: {
1213
+ stop: true;
1214
+ steer: false;
1215
+ resume: false;
1216
+ structuredOutput: false;
1217
+ toolEvents: false;
1218
+ };
1219
+ }
1220
+
1221
+ export interface ExternalProcessStatus {
1222
+ pid?: number;
1223
+ startedAt: number;
1224
+ endedAt?: number;
1225
+ durationMs?: number;
1226
+ exitCode?: number | null;
1227
+ processSignal?: string | null;
1228
+ stdoutPath: string;
1229
+ stderrPath: string;
1133
1230
  }
1134
1231
 
1135
1232
  export interface AsyncStatus {
@@ -1137,6 +1234,7 @@ export interface AsyncStatus {
1137
1234
  runId: string;
1138
1235
  sessionId?: string;
1139
1236
  mode: SubagentRunMode;
1237
+ context?: "fresh" | "fork" | "mixed";
1140
1238
  isNested?: boolean;
1141
1239
  state: "queued" | "running" | "complete" | "failed" | "paused" | "stopped" | "rejected";
1142
1240
  error?: string;
@@ -1175,14 +1273,21 @@ export interface AsyncStatus {
1175
1273
  runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1176
1274
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1177
1275
  capabilityAudit?: SubagentCapabilityAudit;
1276
+ workflow?: Details["workflow"];
1277
+ parentWorkflowRunId?: string;
1278
+ workflowKey?: string;
1178
1279
  steps?: Array<{
1179
1280
  agent: string;
1281
+ runner?: ExternalCliRunnerStatus;
1282
+ externalProcess?: ExternalProcessStatus;
1180
1283
  /** Resolved launch context for this child step. */
1181
1284
  context?: "fresh" | "fork";
1182
1285
  /** Short caller-facing task/goal shown in fleet surfaces when available. */
1183
1286
  description?: string;
1184
1287
  phase?: string;
1185
1288
  label?: string;
1289
+ workflowKey?: string;
1290
+ parentWorkflowRunId?: string;
1186
1291
  outputName?: string;
1187
1292
  structured?: boolean;
1188
1293
  checkpoint?: ChainCheckpointState;
@@ -1228,7 +1333,7 @@ export interface AsyncStatus {
1228
1333
  agentContract?: AgentContract;
1229
1334
  launchContractDigest?: string;
1230
1335
  launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1231
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1336
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1232
1337
  execution?: ExecutionProjection;
1233
1338
  review?: ReviewProjection;
1234
1339
  effects?: EffectsProjection;
@@ -1240,7 +1345,6 @@ export interface AsyncStatus {
1240
1345
  sessionDir?: string;
1241
1346
  outputFile?: string;
1242
1347
  totalTokens?: TokenUsage;
1243
- usageBudget?: UsageBudgetState;
1244
1348
  totalCost?: CostSummary;
1245
1349
  sessionFile?: string;
1246
1350
  outputs?: ChainOutputMap;
@@ -1304,6 +1408,9 @@ export interface AsyncJobState {
1304
1408
  controlEventCursor?: number;
1305
1409
  nestedRoute?: NestedRouteInfo;
1306
1410
  nestedChildren?: NestedRunSummary[];
1411
+ parentWorkflowRunId?: string;
1412
+ workflowKey?: string;
1413
+ workflow?: Details["workflow"];
1307
1414
  }
1308
1415
 
1309
1416
  export interface ForegroundResumeChild {
@@ -1414,11 +1521,26 @@ export interface ForegroundRunControl {
1414
1521
  detach?: () => boolean;
1415
1522
  }
1416
1523
 
1524
+ export interface WaitSubscriptionRecord {
1525
+ version: 1;
1526
+ token: string;
1527
+ sessionId: string;
1528
+ targetKind: "async" | "foreground";
1529
+ runId: string;
1530
+ requestedId: string;
1531
+ createdAt: number;
1532
+ expiresAt: number;
1533
+ }
1534
+
1417
1535
  export interface SubagentState {
1418
1536
  baseCwd: string;
1419
1537
  currentSessionId: string | null;
1420
1538
  /** Runtime-owned artifact resolution inputs used by Fleet transcript targeting. */
1421
1539
  artifactDirPreference?: ArtifactDirPreference;
1540
+ /** Runtime authority snapshot used by optional inspector controls. */
1541
+ authorityPolicy?: AuthorityPolicyConfig;
1542
+ /** Runtime mission-store snapshot used by optional inspector context. */
1543
+ missionStoreConfig?: MissionStoreConfig;
1422
1544
  parentSessionFile?: string | null;
1423
1545
  /** Last valid parent session model observed for this session; used when continuation contexts omit ctx.model. */
1424
1546
  lastParentModel?: { provider: string; id: string };
@@ -1438,7 +1560,6 @@ export interface SubagentState {
1438
1560
  foregroundRuns?: Map<string, ForegroundResumeRun>;
1439
1561
  foregroundControls: Map<string, ForegroundRunControl>;
1440
1562
  lastForegroundControlId: string | null;
1441
- pendingForegroundControlNotices?: Map<string, ReturnType<typeof setTimeout>>;
1442
1563
  cleanupTimers: Map<string, ReturnType<typeof setTimeout>>;
1443
1564
  lastUiContext: ExtensionContext | null;
1444
1565
  poller: NodeJS.Timeout | null;
@@ -1449,6 +1570,10 @@ export interface SubagentState {
1449
1570
  schedule(file: string, delayMs?: number): boolean;
1450
1571
  clear(): void;
1451
1572
  };
1573
+ /** Current-session durable non-blocking wait registrations. */
1574
+ waitSubscriptions?: Map<string, WaitSubscriptionRecord>;
1575
+ /** Live in-process workflow controllers. Durable status remains on disk after settlement. */
1576
+ workflowControllers?: Map<string, AbortController>;
1452
1577
  }
1453
1578
 
1454
1579
  // ============================================================================
@@ -1492,6 +1617,8 @@ export const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom
1492
1617
  // ============================================================================
1493
1618
 
1494
1619
  export interface RunSyncOptions {
1620
+ /** Opt-in global permission rules; missing tools remain allowed. */
1621
+ permissions?: import("../runs/shared/permissions.ts").PermissionConfig;
1495
1622
  /** Session id of the direct parent session for permission-system ask forwarding. */
1496
1623
  parentSessionId?: string;
1497
1624
  /** Resolved launch context for this child. */
@@ -1590,10 +1717,10 @@ export interface ProactiveSkillSubagentsConfig {
1590
1717
  }
1591
1718
 
1592
1719
  export type ToolDescriptionMode = "full" | "compact" | "custom";
1720
+ export type InlineToolDisplay = "rich" | "summary";
1593
1721
 
1594
1722
  export interface ScheduledRunsConfig {
1595
1723
  enabled?: boolean;
1596
- maxLatenessMs?: number;
1597
1724
  maxPending?: number;
1598
1725
  }
1599
1726
 
@@ -1605,10 +1732,12 @@ export interface ExtensionConfig {
1605
1732
  fleetView?: boolean;
1606
1733
  /** Place the persistent FleetView above or below the editor. Defaults to belowEditor. */
1607
1734
  fleetViewPlacement?: FleetViewPlacement;
1608
- /** Show the legacy above-editor async runs widget. Defaults to true only when fleetView is disabled. */
1735
+ /** Show the under-editor async runs widget. Defaults to true, including when FleetView is enabled. */
1609
1736
  asyncWidget?: boolean;
1610
1737
  /** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */
1611
1738
  toolDescriptionMode?: ToolDescriptionMode;
1739
+ /** Inline chat rendering for the subagent tool. Defaults to rich. */
1740
+ inlineToolDisplay?: InlineToolDisplay;
1612
1741
  forceTopLevelAsync?: boolean;
1613
1742
  waitTool?: WaitToolConfig;
1614
1743
  defaultSessionDir?: string;
@@ -1622,6 +1751,8 @@ export interface ExtensionConfig {
1622
1751
  completionBatch?: CompletionBatchConfig;
1623
1752
  turnBudget?: TurnBudgetConfig;
1624
1753
  toolBudget?: ToolBudgetConfig;
1754
+ /** Opt-in native tool permissions. Bash remains outside this policy. */
1755
+ permissions?: import("../runs/shared/permissions.ts").PermissionConfig;
1625
1756
  usageBudget?: UsageBudgetConfig;
1626
1757
  parallel?: TopLevelParallelConfig;
1627
1758
  chain?: ExtensionChainConfig;
@@ -1633,6 +1764,10 @@ export interface ExtensionConfig {
1633
1764
  intercomBridge?: IntercomBridgeConfig;
1634
1765
  proactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;
1635
1766
  scheduledRuns?: ScheduledRunsConfig;
1767
+ /** Durable mission behavior. Missions are automatic by default; set enabled:false to disable auto-create. Explicit mission actions/fields still work. */
1768
+ missions?: MissionStoreConfig;
1769
+ /** Small fixed authority policy for the supported operational actions. */
1770
+ authorityPolicy?: AuthorityPolicyConfig;
1636
1771
  }
1637
1772
 
1638
1773
  // ============================================================================
@@ -1715,6 +1850,13 @@ export const RESULTS_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-results");
1715
1850
  export const ASYNC_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-runs");
1716
1851
  export const CHAIN_RUNS_DIR = path.join(TEMP_ROOT_DIR, "chain-runs");
1717
1852
  export const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, "artifacts");
1853
+
1854
+ export const DIRS = {
1855
+ results: RESULTS_DIR,
1856
+ async: ASYNC_DIR,
1857
+ chain: CHAIN_RUNS_DIR,
1858
+ artifacts: TEMP_ARTIFACTS_DIR,
1859
+ };
1718
1860
  export const WIDGET_KEY = "subagent-async";
1719
1861
  export const SLASH_RESULT_TYPE = "subagent-slash-result";
1720
1862
  export const SLASH_TEXT_RESULT_TYPE = "subagent-slash-text-result";
@@ -1726,7 +1868,7 @@ export const SLASH_SUBAGENT_CANCEL_EVENT = "subagent:slash:cancel";
1726
1868
  export const POLL_INTERVAL_MS = 250;
1727
1869
  export const MAX_WIDGET_JOBS = 4;
1728
1870
  export const DEFAULT_SUBAGENT_MAX_DEPTH = 2;
1729
- export const SUBAGENT_ACTIONS = ["list", "get", "models", "create", "update", "delete", "eject", "disable", "enable", "reset", "status", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "append-step", "approve-checkpoint", "reject-checkpoint", "doctor", "watchdog.status", "watchdog.check", "watchdog.configure", "watchdog.recommend-model", "schedule", "schedule-list", "schedule-status", "schedule-cancel"] as const;
1871
+ export const SUBAGENT_ACTIONS = ["list", "get", "models", "create", "update", "delete", "eject", "disable", "enable", "reset", "mission.create", "mission.list", "mission.show", "mission.update", "mission.attach-run", "mission.close", "worktree.discard", "inspector.open", "inspector.status", "inspector.close", "project.open", "project.status", "project.close", "status", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "append-step", "approve-checkpoint", "reject-checkpoint", "doctor", "watchdog.status", "watchdog.check", "watchdog.configure", "watchdog.recommend-model", "schedule.create", "schedule.list", "schedule.show", "schedule.history", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"] as const;
1730
1872
 
1731
1873
  export const DEFAULT_FORK_PREAMBLE =
1732
1874
  "You are a delegated subagent running from a fork of the parent session. " +
@@ -256,7 +256,8 @@ export function findLatestSessionFile(sessionDir: string): string | null {
256
256
  };
257
257
  })
258
258
  .sort((a, b) => b.mtime - a.mtime);
259
- return files.length > 0 ? files[0].path : null;
259
+ const latest = files[0];
260
+ return latest ? latest.path : null;
260
261
  }
261
262
 
262
263
  /**
@@ -280,7 +281,7 @@ export function getFinalOutput(messages: Message[]): string {
280
281
  const validTextParts: string[] = [];
281
282
  for (let i = messages.length - 1; i >= 0; i--) {
282
283
  const msg = messages[i];
283
- if (msg.role !== "assistant") continue;
284
+ if (!msg || msg.role !== "assistant") continue;
284
285
  const hasAssistantError = ("errorMessage" in msg && typeof msg.errorMessage === "string" && msg.errorMessage.length > 0)
285
286
  || ("stopReason" in msg && msg.stopReason === "error");
286
287
  if (hasAssistantError) continue;
@@ -290,7 +291,7 @@ export function getFinalOutput(messages: Message[]): string {
290
291
  .join("\n");
291
292
  for (let j = msg.content.length - 1; j >= 0; j--) {
292
293
  const part = msg.content[j];
293
- if (part.type !== "text" || part.text.trim().length === 0) continue;
294
+ if (!part || part.type !== "text" || part.text.trim().length === 0) continue;
294
295
  validTextParts.push(part.text);
295
296
  if (/```acceptance[-_]report\s*\n[\s\S]*?```/i.test(part.text)) return messageText;
296
297
  for (const match of part.text.matchAll(/```(?:json|jsonc|json5)\s*\n([\s\S]*?)```/gi)) {
@@ -481,7 +482,7 @@ export function detectSubagentError(messages: Message[]): ErrorInfo {
481
482
  let lastAssistantTextIndex = -1;
482
483
  for (let i = messages.length - 1; i >= 0; i--) {
483
484
  const msg = messages[i];
484
- if (msg.role === "assistant") {
485
+ if (msg?.role === "assistant") {
485
486
  const hasText = Array.isArray(msg.content) && msg.content.some(
486
487
  (c) => c.type === "text" && "text" in c && typeof c.text === "string" && c.text.trim().length > 0,
487
488
  );
@@ -496,7 +497,7 @@ export function detectSubagentError(messages: Message[]): ErrorInfo {
496
497
 
497
498
  for (let i = messages.length - 1; i >= scanStart; i--) {
498
499
  const msg = messages[i];
499
- if (msg.role !== "toolResult") continue;
500
+ if (!msg || msg.role !== "toolResult") continue;
500
501
  const toolName = "toolName" in msg && typeof msg.toolName === "string" ? msg.toolName : undefined;
501
502
  const isError = "isError" in msg && msg.isError === true;
502
503
 
@@ -505,9 +506,10 @@ export function detectSubagentError(messages: Message[]): ErrorInfo {
505
506
  const text = msg.content.find((c) => c.type === "text");
506
507
  const details = text && "text" in text ? text.text : undefined;
507
508
  const exitMatch = details?.match(/exit(?:ed)?\s*(?:with\s*)?(?:code|status)?\s*[:\s]?\s*(\d+)/i);
509
+ const exitCodeText = exitMatch?.[1];
508
510
  return {
509
511
  hasError: true,
510
- exitCode: exitMatch ? parseInt(exitMatch[1], 10) : 1,
512
+ exitCode: exitCodeText ? parseInt(exitCodeText, 10) : 1,
511
513
  errorType: toolName || "tool",
512
514
  details: details?.slice(0, 200),
513
515
  };