@marcoscale98/pi-extensible-workflows 5.17.0-fork.1 → 6.2.1-fork.1

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 (128) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +2 -2
  3. package/dist/src/agent-execution.d.ts +43 -10
  4. package/dist/src/agent-execution.js +442 -162
  5. package/dist/src/background-widget.d.ts +5 -1
  6. package/dist/src/background-widget.js +5 -10
  7. package/dist/src/decoders.d.ts +2 -3
  8. package/dist/src/decoders.js +59 -37
  9. package/dist/src/execution.d.ts +6 -2
  10. package/dist/src/execution.js +48 -7
  11. package/dist/src/host-delivery.js +5 -8
  12. package/dist/src/host-navigator.js +5 -2
  13. package/dist/src/host-phases.d.ts +1 -0
  14. package/dist/src/host-recovery.d.ts +11 -8
  15. package/dist/src/host-recovery.js +14 -22
  16. package/dist/src/host-runtime.js +56 -5
  17. package/dist/src/host-view.d.ts +6 -1
  18. package/dist/src/host-view.js +46 -20
  19. package/dist/src/host.d.ts +2 -2
  20. package/dist/src/host.js +246 -118
  21. package/dist/src/index.d.ts +1 -2
  22. package/dist/src/index.js +1985 -1690
  23. package/dist/src/index.js.map +3 -3
  24. package/dist/src/paths.d.ts +8 -5
  25. package/dist/src/paths.js +24 -13
  26. package/dist/src/persistence.d.ts +1 -0
  27. package/dist/src/persistence.js +1 -0
  28. package/dist/src/pi-runtime-runner.js +4 -1
  29. package/dist/src/registry.d.ts +9 -7
  30. package/dist/src/registry.js +29 -71
  31. package/dist/src/runtime/agent-runner.d.ts +2 -0
  32. package/dist/src/script-tools.d.ts +27 -0
  33. package/dist/src/script-tools.js +87 -0
  34. package/dist/src/session-lease.d.ts +1 -1
  35. package/dist/src/session-lease.js +45 -11
  36. package/dist/src/settings.d.ts +19 -3
  37. package/dist/src/settings.js +63 -50
  38. package/dist/src/store.d.ts +3 -1
  39. package/dist/src/store.js +17 -1
  40. package/dist/src/trajectory.d.ts +12 -3
  41. package/dist/src/trajectory.js +32 -11
  42. package/dist/src/types.d.ts +129 -45
  43. package/dist/src/types.js +5 -8
  44. package/dist/src/utils.d.ts +21 -1
  45. package/dist/src/utils.js +46 -6
  46. package/dist/src/validation.d.ts +14 -3
  47. package/dist/src/validation.js +143 -87
  48. package/dist/starter/index.js +8 -11
  49. package/dist/starter/index.js.map +1 -1
  50. package/dist/starter/review-loop.d.ts +0 -13
  51. package/dist/starter/review-loop.js +8 -9
  52. package/dist/subagents/index.js +904 -956
  53. package/dist/subagents/index.js.map +3 -3
  54. package/dist/subagents/src/contracts.d.ts +48 -31
  55. package/dist/subagents/src/contracts.js +20 -9
  56. package/dist/subagents/src/index.d.ts +1 -1
  57. package/dist/subagents/src/index.js +14 -8
  58. package/dist/subagents/src/manager.js +52 -73
  59. package/dist/subagents/src/navigator.js +3 -14
  60. package/dist/subagents/src/view.d.ts +1 -1
  61. package/dist/subagents/src/view.js +15 -68
  62. package/dist/subagents/src/worktree.js +1 -1
  63. package/dist/trajectory/assets/index.html +35 -13
  64. package/dist/trajectory/index.js +576 -932
  65. package/dist/trajectory/index.js.map +3 -3
  66. package/dist/trajectory/src/assets/index.html +35 -13
  67. package/dist/trajectory/src/index.js +134 -104
  68. package/dist/trajectory/src/server.js +268 -27
  69. package/dist/trajectory/src/server.js.map +3 -3
  70. package/dist/trajectory/src/startup-mutex.d.ts +17 -0
  71. package/dist/trajectory/src/startup-mutex.js +172 -0
  72. package/examples/workflow-extension-template/README.md +4 -7
  73. package/examples/workflow-extension-template/extension.test.mjs +4 -8
  74. package/examples/workflow-extension-template/index.js +0 -3
  75. package/package.json +10 -10
  76. package/skills/pi-extensible-workflows/SKILL.md +12 -8
  77. package/src/agent-execution.ts +412 -164
  78. package/src/background-widget.ts +5 -11
  79. package/src/decoders.ts +51 -37
  80. package/src/execution.ts +46 -9
  81. package/src/host-delivery.ts +5 -8
  82. package/src/host-navigator.ts +4 -2
  83. package/src/host-phases.ts +1 -1
  84. package/src/host-recovery.ts +23 -28
  85. package/src/host-runtime.ts +44 -6
  86. package/src/host-view.ts +41 -16
  87. package/src/host.ts +229 -142
  88. package/src/index.ts +1 -2
  89. package/src/paths.ts +18 -9
  90. package/src/persistence.ts +1 -0
  91. package/src/pi-runtime-runner.ts +3 -1
  92. package/src/registry.ts +28 -64
  93. package/src/runtime/agent-runner.ts +2 -0
  94. package/src/script-tools.ts +76 -0
  95. package/src/session-lease.ts +34 -6
  96. package/src/settings.ts +56 -50
  97. package/src/store.ts +18 -2
  98. package/src/trajectory.ts +32 -15
  99. package/src/types.ts +82 -34
  100. package/src/utils.ts +42 -5
  101. package/src/validation.ts +121 -80
  102. package/starter/index.ts +0 -1
  103. package/starter/review-loop.ts +8 -9
  104. package/starter/roles/developer.md +0 -1
  105. package/starter/roles/oracle.md +0 -1
  106. package/starter/roles/researcher.md +0 -1
  107. package/starter/roles/reviewer.md +0 -1
  108. package/starter/roles/scout.md +0 -1
  109. package/subagents/README.md +10 -16
  110. package/subagents/src/contracts.ts +21 -11
  111. package/subagents/src/index.ts +17 -8
  112. package/subagents/src/manager.ts +48 -128
  113. package/subagents/src/navigator.ts +4 -13
  114. package/subagents/src/view.ts +16 -63
  115. package/subagents/src/worktree.ts +1 -1
  116. package/trajectory/src/assets/index.html +35 -13
  117. package/trajectory/src/index.ts +112 -91
  118. package/trajectory/src/server.ts +46 -10
  119. package/trajectory/src/startup-mutex.ts +127 -0
  120. package/dist/src/roles.d.ts +0 -70
  121. package/dist/src/roles.js +0 -325
  122. package/dist/starter/roles/developer.md +0 -6
  123. package/dist/starter/roles/oracle.md +0 -18
  124. package/dist/starter/roles/researcher.md +0 -20
  125. package/dist/starter/roles/reviewer.md +0 -19
  126. package/dist/starter/roles/scout.md +0 -18
  127. package/examples/workflow-extension-template/roles/reviewer.md +0 -4
  128. package/src/roles.ts +0 -326
@@ -13,10 +13,10 @@ export declare const SUBAGENTS_RUN_PARAMETERS: Type.TObject<{
13
13
  label: Type.TOptional<Type.TString>;
14
14
  model: Type.TOptional<Type.TString>;
15
15
  tools: Type.TOptional<Type.TArray<Type.TString>>;
16
+ excludeTools: Type.TOptional<Type.TArray<Type.TString>>;
16
17
  skills: Type.TOptional<Type.TArray<Type.TString>>;
17
18
  extensions: Type.TOptional<Type.TArray<Type.TString>>;
18
19
  contextFiles: Type.TOptional<Type.TArray<Type.TString>>;
19
- role: Type.TOptional<Type.TString>;
20
20
  worktree: Type.TOptional<Type.TString>;
21
21
  outputSchema: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
22
22
  retries: Type.TOptional<Type.TInteger>;
@@ -24,6 +24,7 @@ export declare const SUBAGENTS_RUN_PARAMETERS: Type.TObject<{
24
24
  }>;
25
25
  export declare const SUBAGENTS_INSPECT_PARAMETERS: Type.TObject<{
26
26
  id: Type.TOptional<Type.TString>;
27
+ scope: Type.TOptional<Type.TUnion<[Type.TLiteral<"session">, Type.TLiteral<"all">]>>;
27
28
  }>;
28
29
  export declare const SUBAGENTS_ID_PARAMETERS: Type.TObject<{
29
30
  id: Type.TString;
@@ -38,37 +39,54 @@ export declare const SUBAGENTS_STOP_PARAMETERS: Type.TObject<{
38
39
  export declare const SUBAGENTS_RETRY_PARAMETERS: Type.TObject<{
39
40
  id: Type.TString;
40
41
  }>;
41
- export declare const SUBAGENTS_TOOL_SCHEMAS: {
42
- readonly subagents_run: Type.TObject<{
43
- prompt: Type.TString;
44
- mode: Type.TOptional<Type.TUnion<[Type.TLiteral<"background">, Type.TLiteral<"foreground">]>>;
45
- label: Type.TOptional<Type.TString>;
46
- model: Type.TOptional<Type.TString>;
47
- tools: Type.TOptional<Type.TArray<Type.TString>>;
48
- skills: Type.TOptional<Type.TArray<Type.TString>>;
49
- extensions: Type.TOptional<Type.TArray<Type.TString>>;
50
- contextFiles: Type.TOptional<Type.TArray<Type.TString>>;
51
- role: Type.TOptional<Type.TString>;
52
- worktree: Type.TOptional<Type.TString>;
53
- outputSchema: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
54
- retries: Type.TOptional<Type.TInteger>;
55
- timeoutMs: Type.TOptional<Type.TUnion<[Type.TInteger, Type.TNull]>>;
56
- }>;
57
- readonly subagents_inspect: Type.TObject<{
58
- id: Type.TOptional<Type.TString>;
59
- }>;
60
- readonly subagents_steer: Type.TObject<{
61
- id: Type.TString;
42
+ export declare const SUBAGENT_STATUS_OUTPUT: Type.TObject<{
43
+ id: Type.TString;
44
+ state: Type.TString;
45
+ sessionId: Type.TOptional<Type.TString>;
46
+ startedAt: Type.TOptional<Type.TNumber>;
47
+ finishedAt: Type.TOptional<Type.TNumber>;
48
+ attempts: Type.TOptional<Type.TNumber>;
49
+ attemptDetails: Type.TOptional<Type.TArray<Type.TUnknown>>;
50
+ worktree: Type.TOptional<Type.TObject<{
51
+ path: Type.TString;
52
+ branch: Type.TString;
53
+ }>>;
54
+ error: Type.TOptional<Type.TObject<{
55
+ code: Type.TString;
56
+ message: Type.TString;
57
+ }>>;
58
+ progress: Type.TOptional<Type.TUnknown>;
59
+ value: Type.TOptional<Type.TUnknown>;
60
+ }>;
61
+ export declare const SUBAGENTS_INSPECT_OUTPUT: Type.TUnion<[Type.TObject<{
62
+ id: Type.TString;
63
+ state: Type.TString;
64
+ sessionId: Type.TOptional<Type.TString>;
65
+ startedAt: Type.TOptional<Type.TNumber>;
66
+ finishedAt: Type.TOptional<Type.TNumber>;
67
+ attempts: Type.TOptional<Type.TNumber>;
68
+ attemptDetails: Type.TOptional<Type.TArray<Type.TUnknown>>;
69
+ worktree: Type.TOptional<Type.TObject<{
70
+ path: Type.TString;
71
+ branch: Type.TString;
72
+ }>>;
73
+ error: Type.TOptional<Type.TObject<{
74
+ code: Type.TString;
62
75
  message: Type.TString;
63
- }>;
64
- readonly subagents_stop: Type.TObject<{
65
- id: Type.TString;
66
- }>;
67
- readonly subagents_retry: Type.TObject<{
68
- id: Type.TString;
69
- }>;
76
+ }>>;
77
+ progress: Type.TOptional<Type.TUnknown>;
78
+ value: Type.TOptional<Type.TUnknown>;
79
+ }>, Type.TArray<Type.TObject<{
80
+ id: Type.TString;
81
+ state: Type.TString;
82
+ }>>]>;
83
+ export declare const SUBAGENTS_STEER_OUTPUT: Type.TObject<{
84
+ id: Type.TString;
85
+ accepted: Type.TBoolean;
86
+ }>;
87
+ export type SubagentRunRequest = Static<typeof SUBAGENTS_RUN_PARAMETERS> & {
88
+ readonly [key: string]: unknown;
70
89
  };
71
- export type SubagentRunRequest = Static<typeof SUBAGENTS_RUN_PARAMETERS>;
72
90
  export declare function normalizeSubagentRunRequest(value: unknown): SubagentRunRequest;
73
91
  export type SubagentInspectRequest = Static<typeof SUBAGENTS_INSPECT_PARAMETERS>;
74
92
  export type SubagentIdRequest = Static<typeof SUBAGENTS_ID_PARAMETERS>;
@@ -101,7 +119,6 @@ export interface SubagentStatus {
101
119
  export interface SubagentNotification {
102
120
  readonly id: string;
103
121
  readonly label?: string;
104
- readonly role?: string;
105
122
  readonly state: "completed" | "failed";
106
123
  readonly error?: {
107
124
  readonly code: string;
@@ -22,17 +22,18 @@ export const SUBAGENTS_RUN_PARAMETERS = Type.Object({
22
22
  label: Type.Optional(Type.String({ description: "Optional display label for the subagent" })),
23
23
  model: Type.Optional(Type.String({ description: "Optional model as provider/model:thinking or alias[:thinking]" })),
24
24
  tools: Type.Optional(Type.Array(Type.String(), { description: "Optional ordered tool selectors; candidates start enabled and !* restricts the set" })),
25
+ excludeTools: Type.Optional(Type.Array(Type.String(), { description: "Optional exact tool names removed after preparation; no patterns, cannot remove workflow_result" })),
25
26
  skills: Type.Optional(Type.Array(Type.String(), { description: "Optional ordered skill selectors; candidates start enabled and !* restricts the set" })),
26
27
  extensions: Type.Optional(Type.Array(Type.String(), { description: "Optional ordered extension selectors; candidates start enabled and !* restricts the set" })),
27
28
  contextFiles: Type.Optional(Type.Array(Type.String(), { description: "Optional context-file scopes: global, project, cwd" })),
28
- role: Type.Optional(Type.String({ description: "Workflow role name" })),
29
29
  worktree: Type.Optional(Type.String({ description: "Optional named worktree; requires a clean working tree" })),
30
30
  outputSchema: Type.Optional(Type.Record(Type.String(), Type.Unknown(), { description: "Optional JSON schema for the result" })),
31
31
  retries: Type.Optional(Type.Integer({ minimum: 0, maximum: SUBAGENT_MAX_RETRIES, description: "Optional retry count; at most 255 retries" })),
32
32
  timeoutMs: Type.Optional(Type.Union([Type.Integer({ minimum: 1, description: "Optional execution timeout in milliseconds" }), Type.Null()])),
33
- }, { additionalProperties: false });
33
+ }, { additionalProperties: true });
34
34
  export const SUBAGENTS_INSPECT_PARAMETERS = Type.Object({
35
35
  id: Type.Optional(Type.String({ description: "Subagent ID; omit to list ordered run summaries" })),
36
+ scope: Type.Optional(Type.Union([Type.Literal("session"), Type.Literal("all")], { description: "List scope when id is omitted: session (default) lists runs from the current Pi session; all lists every stored run" })),
36
37
  }, { additionalProperties: false });
37
38
  export const SUBAGENTS_ID_PARAMETERS = Type.Object({
38
39
  id: Type.String({ description: "Subagent ID" }),
@@ -47,13 +48,23 @@ export const SUBAGENTS_STOP_PARAMETERS = Type.Object({
47
48
  export const SUBAGENTS_RETRY_PARAMETERS = Type.Object({
48
49
  id: Type.String({ description: "Failed or stopped subagent ID to retry" }),
49
50
  }, { additionalProperties: false });
50
- export const SUBAGENTS_TOOL_SCHEMAS = {
51
- subagents_run: SUBAGENTS_RUN_PARAMETERS,
52
- subagents_inspect: SUBAGENTS_INSPECT_PARAMETERS,
53
- subagents_steer: SUBAGENTS_STEER_PARAMETERS,
54
- subagents_stop: SUBAGENTS_STOP_PARAMETERS,
55
- subagents_retry: SUBAGENTS_RETRY_PARAMETERS,
56
- };
51
+ // Structured results codemode scripts receive instead of the JSON text; nested records stay loose so they cannot drift from persistence.
52
+ export const SUBAGENT_STATUS_OUTPUT = Type.Object({
53
+ id: Type.String(),
54
+ state: Type.String(),
55
+ sessionId: Type.Optional(Type.String()),
56
+ startedAt: Type.Optional(Type.Number()),
57
+ finishedAt: Type.Optional(Type.Number()),
58
+ attempts: Type.Optional(Type.Number()),
59
+ attemptDetails: Type.Optional(Type.Array(Type.Unknown())),
60
+ worktree: Type.Optional(Type.Object({ path: Type.String(), branch: Type.String() })),
61
+ error: Type.Optional(Type.Object({ code: Type.String(), message: Type.String() })),
62
+ progress: Type.Optional(Type.Unknown()),
63
+ value: Type.Optional(Type.Unknown()),
64
+ });
65
+ // One run when id is given, otherwise the ordered run summaries; the summaries stay short in the codemode description.
66
+ export const SUBAGENTS_INSPECT_OUTPUT = Type.Union([SUBAGENT_STATUS_OUTPUT, Type.Array(Type.Object({ id: Type.String(), state: Type.String() }))]);
67
+ export const SUBAGENTS_STEER_OUTPUT = Type.Object({ id: Type.String(), accepted: Type.Boolean() });
57
68
  export function normalizeSubagentRunRequest(value) {
58
69
  if (!Value.Check(SUBAGENTS_RUN_PARAMETERS, value))
59
70
  throw new WorkflowError("INVALID_METADATA", "Invalid subagents_run parameters");
@@ -5,7 +5,7 @@ export { attemptValue, statusValue, subagentErrorValue } from "./decode.js";
5
5
  export { createSubagentManager, createUnavailableSubagentManager } from "./manager.js";
6
6
  export { createRunStoreWorktreeAdapter, defaultWorktreeHome } from "./worktree.js";
7
7
  export type { SubagentWorktreeAdapter, SubagentWorktreeContext, SubagentWorktreeHandle, SubagentWorktreeRunStore } from "./worktree.js";
8
- type SubagentsExtensionAPI = Pick<ExtensionAPI, "registerTool"> & Partial<Pick<ExtensionAPI, "getActiveTools" | "on" | "sendMessage" | "registerCommand" | "appendEntry" | "registerEntryRenderer">>;
8
+ type SubagentsExtensionAPI = Pick<ExtensionAPI, "registerTool"> & Partial<Pick<ExtensionAPI, "events" | "getActiveTools" | "getAllTools" | "on" | "sendMessage" | "registerCommand" | "appendEntry" | "registerEntryRenderer">>;
9
9
  export declare function createSubagentTools(manager: SubagentManager): readonly ToolDefinition[];
10
10
  export declare function createSubagentsExtension(options?: SubagentsExtensionOptions, activeTools?: () => readonly string[], notify?: (notification: SubagentNotification) => void | Promise<void>, onStatus?: (status: Readonly<SubagentStatus>, request: Readonly<SubagentRunRequest>) => void, onResourceWarning?: (message: string) => void): SubagentsExtension;
11
11
  export declare function registerSubagentsExtension(pi: SubagentsExtensionAPI, options?: SubagentsExtensionOptions): SubagentsExtension;
@@ -1,12 +1,12 @@
1
1
  import { join } from "node:path";
2
2
  import { defineTool, getAgentDir } from "@earendil-works/pi-coding-agent";
3
3
  import { Value } from "typebox/value";
4
- import { WorkflowError, loadingRegistry } from "../../src/index.js";
4
+ import { WorkflowError, loadCodemodeToolsSetting, loadingRegistry, reachableTools, workflowToolExposure } from "../../src/index.js";
5
5
  import { clearSubagentManager, setSubagentManager } from "../../src/subagent-manager-handle.js";
6
6
  import { createSubagentManager } from "./manager.js";
7
7
  import { registerSubagentNavigator } from "./navigator.js";
8
8
  import { createSubagentBackgroundWidget, renderSubagentCall, renderSubagentControlCall, renderSubagentControlResult, renderSubagentInspectCall, renderSubagentInspectResult, renderSubagentResult } from "./view.js";
9
- import { normalizeSubagentRunRequest, SUBAGENTS_ID_PARAMETERS, SUBAGENTS_INSPECT_PARAMETERS, SUBAGENTS_RETRY_PARAMETERS, SUBAGENTS_RUN_PARAMETERS, SUBAGENTS_STEER_PARAMETERS, SUBAGENTS_STOP_PARAMETERS, } from "./contracts.js";
9
+ import { normalizeSubagentRunRequest, SUBAGENT_STATUS_OUTPUT, SUBAGENTS_ID_PARAMETERS, SUBAGENTS_INSPECT_OUTPUT, SUBAGENTS_INSPECT_PARAMETERS, SUBAGENTS_RETRY_PARAMETERS, SUBAGENTS_RUN_PARAMETERS, SUBAGENTS_STEER_OUTPUT, SUBAGENTS_STEER_PARAMETERS, SUBAGENTS_STOP_PARAMETERS, } from "./contracts.js";
10
10
  export * from "./contracts.js";
11
11
  export { attemptValue, statusValue, subagentErrorValue } from "./decode.js";
12
12
  export { createSubagentManager, createUnavailableSubagentManager } from "./manager.js";
@@ -41,7 +41,7 @@ function serialize(value) {
41
41
  }
42
42
  }
43
43
  function toolResult(value) {
44
- return { content: [{ type: "text", text: serialize(value) }], details: value };
44
+ return { content: [{ type: "text", text: serialize(value) }], details: value, structuredContent: value };
45
45
  }
46
46
  function managerContext(toolCallId, signal, onUpdate, context) {
47
47
  return {
@@ -63,6 +63,7 @@ export function createSubagentTools(manager) {
63
63
  "Do not poll a running ID; use subagents_inspect({ id }) when you need its current status or terminal result.",
64
64
  ],
65
65
  parameters: SUBAGENTS_RUN_PARAMETERS,
66
+ outputSchema: SUBAGENT_STATUS_OUTPUT,
66
67
  async execute(toolCallId, params, signal, onUpdate, context) {
67
68
  return toolResult(await manager.run(validateSubagentRunRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
68
69
  },
@@ -72,8 +73,9 @@ export function createSubagentTools(manager) {
72
73
  defineTool({
73
74
  name: "subagents_inspect",
74
75
  label: "Subagents Inspect",
75
- description: "Inspect durable subagent runs. Omit id for ordered run summaries, or provide id for detailed status, progress, activity, accounting, tool calls, timestamps, worktree metadata, and a terminal value or error when available.",
76
+ description: "Inspect durable subagent runs. Omit id for ordered run summaries of the current session (scope all for every session), or provide id for detailed status, progress, activity, accounting, tool calls, timestamps, worktree metadata, and a terminal value or error when available.",
76
77
  parameters: SUBAGENTS_INSPECT_PARAMETERS,
78
+ outputSchema: SUBAGENTS_INSPECT_OUTPUT,
77
79
  async execute(toolCallId, params, signal, onUpdate, context) {
78
80
  return toolResult(await manager.inspect(validateSubagentInspectRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
79
81
  },
@@ -85,6 +87,7 @@ export function createSubagentTools(manager) {
85
87
  label: "Subagents Steer",
86
88
  description: "Send a message to a running subagent. The message is queued safely if its steering handler is not ready; settled runs cannot be steered.",
87
89
  parameters: SUBAGENTS_STEER_PARAMETERS,
90
+ outputSchema: SUBAGENTS_STEER_OUTPUT,
88
91
  async execute(toolCallId, params, signal, onUpdate, context) {
89
92
  return toolResult(await manager.steer(validateSubagentSteerRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
90
93
  },
@@ -96,6 +99,7 @@ export function createSubagentTools(manager) {
96
99
  label: "Subagents Stop",
97
100
  description: "Stop one running subagent, abort its active session, persist state \"stopped\", and clean its worktree without affecting sibling runs.",
98
101
  parameters: SUBAGENTS_STOP_PARAMETERS,
102
+ outputSchema: SUBAGENT_STATUS_OUTPUT,
99
103
  async execute(toolCallId, params, signal, onUpdate, context) {
100
104
  return toolResult(await manager.stop(validateSubagentIdRequest(params, "subagents_stop"), managerContext(toolCallId, signal, onUpdate, context)));
101
105
  },
@@ -107,6 +111,7 @@ export function createSubagentTools(manager) {
107
111
  label: "Subagents Retry",
108
112
  description: "Start a fresh run from a failed or stopped subagent's persisted request. The new run gets a new ID and preserves its original background or foreground mode.",
109
113
  parameters: SUBAGENTS_RETRY_PARAMETERS,
114
+ outputSchema: SUBAGENT_STATUS_OUTPUT,
110
115
  async execute(toolCallId, params, signal, onUpdate, context) {
111
116
  return toolResult(await manager.retry(validateSubagentIdRequest(params, "subagents_retry"), managerContext(toolCallId, signal, onUpdate, context)));
112
117
  },
@@ -117,8 +122,7 @@ export function createSubagentTools(manager) {
117
122
  }
118
123
  function notificationContent(notification) {
119
124
  const label = notification.label?.trim();
120
- const role = notification.role?.trim() || "none";
121
- const identity = label ? `${label} role=${role} (${notification.id})` : `${notification.id} role=${role}`;
125
+ const identity = label ? `${label} (${notification.id})` : notification.id;
122
126
  if (notification.state === "completed")
123
127
  return `Subagent ${identity} completed. Inspect it with subagents_inspect({ id: "${notification.id}" }).`;
124
128
  return `Subagent ${identity} failed: ${notification.error?.message ?? "unknown error"}. Inspect it with subagents_inspect({ id: "${notification.id}" }).`;
@@ -145,7 +149,8 @@ export function createSubagentsExtension(options = {}, activeTools, notify, onSt
145
149
  }
146
150
  export function registerSubagentsExtension(pi, options = {}) {
147
151
  const getActiveTools = pi.getActiveTools;
148
- const activeTools = getActiveTools === undefined ? undefined : () => getActiveTools.call(pi);
152
+ const getAllTools = pi.getAllTools;
153
+ const activeTools = getActiveTools === undefined ? undefined : () => reachableTools({ getActiveTools: () => getActiveTools.call(pi), ...(getAllTools === undefined ? {} : { getAllTools: () => getAllTools.call(pi) }) });
149
154
  const sendMessage = pi.sendMessage;
150
155
  const notify = sendMessage === undefined ? undefined : (notification) => {
151
156
  sendMessage.call(pi, { customType: "subagents", content: notificationContent(notification), display: true, details: notification }, { deliverAs: "steer", triggerTurn: true });
@@ -157,8 +162,9 @@ export function registerSubagentsExtension(pi, options = {}) {
157
162
  const widget = createSubagentBackgroundWidget({ ...(appendEntry === undefined ? {} : { appendEntry: (customType, data) => { appendEntry.call(pi, customType, data); } }), ...(pi.registerEntryRenderer === undefined ? {} : { registerEntryRenderer: pi.registerEntryRenderer.bind(pi) }) });
158
163
  const extension = createSubagentsExtension(options, activeTools, notify, (status, request) => { widget.update(status, request); const registry = loadingRegistry(); if (typeof registry.observeSubagentStatus === "function")
159
164
  registry.observeSubagentStatus(status, request); }, onResourceWarning);
165
+ const codemodeTools = loadCodemodeToolsSetting(options.managerDependencies?.agentDir);
160
166
  for (const tool of extension.tools)
161
- pi.registerTool(tool);
167
+ pi.registerTool({ ...tool, ...workflowToolExposure(tool.name, codemodeTools) });
162
168
  if (pi.registerCommand !== undefined)
163
169
  registerSubagentNavigator(pi.registerCommand.bind(pi), extension.manager, storageDirectory(options), options.clipboard);
164
170
  if (pi.on !== undefined) {
@@ -2,12 +2,11 @@ import { randomUUID } from "node:crypto";
2
2
  import { chmod, link, mkdir, open, readFile, readdir, rename, rm, stat } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
5
- import { addAccounting, deepFreeze, errorCode, errorText, finiteNumber, isNodeError, isThinkingLevel, jsonValue, object, loadingRegistry, localAgentTransport, resolveAgentResourcePolicy, resolveWorkflowSettings, roleNameOf, sanitizeDisplayText, sumAccounting, structuralPath, validateModelAliasAvailability, WorkflowAgentExecutor, WorkflowError, workflowProjectSettingsPath, workflowSettingsPath, SerialLane, } from "../../src/index.js";
6
- import { decodeAgentDefinition, decodeWorkflowExtensions } from "../../src/decoders.js";
7
- import { loadAgentDefinitions } from "../../src/roles.js";
5
+ import { addAccounting, errorCode, errorText, finiteNumber, isNodeError, isThinkingLevel, jsonValue, object, loadingRegistry, localAgentTransport, resolveAgentResourcePolicy, resolveWorkflowSettings, sanitizeDisplayText, sumAccounting, structuralPath, validateModelAliasAvailability, WorkflowAgentExecutor, WorkflowError, workflowSettingsPath, SerialLane } from "../../src/index.js";
6
+ import { decodePreparedAgentConfiguration } from "../../src/decoders.js";
8
7
  import { atomicJson, json as readJson, processAlive } from "../../src/persistence.js";
9
8
  import { accountingValue, activityValue, legacyAccountingValue, worktreeValue } from "./decode.js";
10
- import { SUBAGENT_ATTEMPT_DETAILS_LIMIT, SUBAGENT_MAX_RETRIES, SUBAGENT_SYSTEM_PROMPT_LIMIT, SUBAGENTS_TOOL_NAMES, normalizeSubagentRunRequest, } from "./contracts.js";
9
+ import { SUBAGENT_ATTEMPT_DETAILS_LIMIT, SUBAGENT_MAX_RETRIES, SUBAGENT_SYSTEM_PROMPT_LIMIT, SUBAGENTS_TOOL_NAMES, normalizeSubagentRunRequest } from "./contracts.js";
11
10
  import { createRunStoreWorktreeAdapter, defaultWorktreeHome } from "./worktree.js";
12
11
  const WORKFLOW_NAME = "subagents";
13
12
  const STORAGE_DIRECTORY = "subagents";
@@ -44,25 +43,11 @@ function rootModel(context) {
44
43
  const thinking = context.extensionContext.thinkingLevel;
45
44
  return { provider: model.provider, model: model.id, ...(thinking === undefined ? {} : { thinking }) };
46
45
  }
47
- function standaloneExtensionSettingsPath(cwd, agentDir, trustedProject, external) {
48
- return trustedProject && external.projectExtensionSettings !== undefined ? workflowProjectSettingsPath(cwd) : workflowSettingsPath(agentDir);
49
- }
50
- function validateStandaloneExtensionSources(context, external, registry, agentDir) {
51
- const cwd = context.extensionContext.cwd;
52
- const globalSettingsPath = workflowSettingsPath(agentDir);
53
- const trustedProject = context.extensionContext.isProjectTrusted();
54
- if (external.globalExtensionSettings !== undefined)
55
- registry.validateExtensionSettings(external.globalExtensionSettings, { source: "global", cwd, projectTrusted: trustedProject, settingsPath: globalSettingsPath });
56
- if (trustedProject && external.projectExtensionSettings !== undefined)
57
- registry.validateExtensionSettings(external.projectExtensionSettings, { source: "project", cwd, projectTrusted: true, settingsPath: workflowProjectSettingsPath(cwd) });
58
- }
59
- function executionRoot(context, dependencies, signal, runId, worktree, external) {
46
+ function executionRoot(context, dependencies, signal, runId, worktree) {
60
47
  const extensionContext = context.extensionContext;
61
48
  const model = rootModel(context);
62
49
  const agentDir = dependencies.agentDir ?? getAgentDir();
63
50
  const currentTrustedProject = extensionContext.isProjectTrusted();
64
- if (external.projectTrusted && !currentTrustedProject)
65
- throw new WorkflowError("RESUME_INCOMPATIBLE", "Cannot retry standalone configuration from an untrusted project");
66
51
  const trustedProject = currentTrustedProject;
67
52
  const settingsPath = workflowSettingsPath(agentDir);
68
53
  const settings = resolveWorkflowSettings(extensionContext.cwd, trustedProject, settingsPath);
@@ -85,11 +70,15 @@ function executionRoot(context, dependencies, signal, runId, worktree, external)
85
70
  signal,
86
71
  };
87
72
  const registry = loadingRegistry();
88
- validateStandaloneExtensionSources(context, external, registry, agentDir);
89
- const extensionSettings = trustedProject && external.projectExtensionSettings !== undefined ? external.projectExtensionSettings : external.globalExtensionSettings;
90
- const extensionSettingsPath = standaloneExtensionSettingsPath(extensionContext.cwd, agentDir, trustedProject, external);
73
+ if (settings.global.extensionSettings !== undefined)
74
+ registry.validateExtensionSettings(settings.global.extensionSettings, { source: "global", cwd: extensionContext.cwd, projectTrusted: trustedProject, settingsPath: settings.globalSettingsPath });
75
+ if (trustedProject && settings.project.extensionSettings !== undefined)
76
+ registry.validateExtensionSettings(settings.project.extensionSettings, { source: "project", cwd: extensionContext.cwd, projectTrusted: true, settingsPath: settings.projectSettingsPath });
77
+ const extensionSettings = settings.effective.extensionSettings;
78
+ const extensionSettingsPath = settings.sources.extensionSettings ?? settingsPath;
91
79
  return {
92
80
  cwd: extensionContext.cwd,
81
+ projectTrusted: trustedProject,
93
82
  model,
94
83
  tools,
95
84
  resourceSelectors: resourcePolicy.effective,
@@ -99,9 +88,10 @@ function executionRoot(context, dependencies, signal, runId, worktree, external)
99
88
  availableModels,
100
89
  knownModels,
101
90
  ...(Object.keys(staticAliases).length ? { modelAliases: staticAliases } : {}),
91
+ dynamicModelAliasNames: [],
102
92
  settingsPath: settings.sources.modelAliases,
103
93
  extensionSettingsPath,
104
- agentDefinitions: external.agentDefinitions,
94
+ agentPreparationHooks: registry.agentPreparationHooks(),
105
95
  agentSetupHooks: registry.agentSetupHooks(),
106
96
  validateExtensionSettings: registry.validateExtensionSettings,
107
97
  agentResourcePolicy: () => structuredClone(resourcePolicy),
@@ -118,11 +108,10 @@ async function addDynamicAliases(context, signal, root) {
118
108
  const trustedProject = resourcePolicy?.projectTrusted ?? context.extensionContext.isProjectTrusted();
119
109
  const dynamicAliases = await registry.resolveModelAliases({ cwd: context.extensionContext.cwd, projectTrusted: trustedProject, rootModel: root.model, knownModels: root.knownModels ?? new Set(), availableModels: root.availableModels ?? new Set(), signal }, new Set(Object.keys(staticAliases)));
120
110
  validateModelAliasAvailability(dynamicAliases, Object.keys(dynamicAliases), root.availableModels ?? new Set(), root.knownModels ?? new Set(), root.settingsPath);
121
- return { ...root, modelAliases: { ...dynamicAliases, ...staticAliases } };
111
+ return { ...root, modelAliases: { ...dynamicAliases, ...staticAliases }, dynamicModelAliasNames: Object.keys(dynamicAliases) };
122
112
  }
123
113
  function executionOptions(request, onAttempt, onProgress) {
124
- const role = request.role;
125
- const label = request.label ?? roleNameOf(role) ?? "subagent";
114
+ const label = request.label ?? "subagent";
126
115
  return {
127
116
  label,
128
117
  workflowName: WORKFLOW_NAME,
@@ -131,11 +120,11 @@ function executionOptions(request, onAttempt, onProgress) {
131
120
  ...(request.skills === undefined ? {} : { skills: request.skills }),
132
121
  ...(request.extensions === undefined ? {} : { extensions: request.extensions }),
133
122
  ...(request.contextFiles === undefined ? {} : { contextFiles: request.contextFiles }),
134
- ...(role === undefined ? {} : { role }),
135
123
  ...(request.worktree === undefined ? {} : { worktreeOwner: structuralPath("worktree", "named", request.worktree) }),
136
124
  ...(request.outputSchema === undefined ? {} : { schema: request.outputSchema }),
137
125
  ...(request.retries === undefined ? {} : { retries: request.retries }),
138
126
  ...(request.timeoutMs === undefined ? {} : { timeoutMs: request.timeoutMs }),
127
+ agentOptions: Object.fromEntries(Object.entries(request).filter(([key]) => !["prompt", "mode", "worktree"].includes(key))),
139
128
  onAttempt,
140
129
  onProgress,
141
130
  };
@@ -326,36 +315,9 @@ function checkedRequest(request) {
326
315
  return normalizeSubagentRunRequest(request);
327
316
  }
328
317
  function decodePersistedStandaloneExternalConfiguration(value) {
329
- if (!object(value) || !jsonValue(value) || typeof value.projectTrusted !== "boolean")
330
- return undefined;
331
- const globalExtensionSettings = value.globalExtensionSettings === undefined ? undefined : decodeWorkflowExtensions(value.globalExtensionSettings);
332
- const projectExtensionSettings = value.projectExtensionSettings === undefined ? undefined : decodeWorkflowExtensions(value.projectExtensionSettings);
333
- if (value.globalExtensionSettings !== undefined && globalExtensionSettings === undefined || value.projectExtensionSettings !== undefined && projectExtensionSettings === undefined)
334
- return undefined;
335
- if (!object(value.agentDefinitions))
318
+ if (!object(value) || value.version !== 1)
336
319
  return undefined;
337
- const agentDefinitions = Object.create(null);
338
- for (const [name, definition] of Object.entries(value.agentDefinitions)) {
339
- const decoded = decodeAgentDefinition(definition);
340
- if (decoded === undefined)
341
- return undefined;
342
- agentDefinitions[name] = decoded;
343
- }
344
- return deepFreeze({ projectTrusted: value.projectTrusted, ...(globalExtensionSettings === undefined ? {} : { globalExtensionSettings }), ...(projectExtensionSettings === undefined ? {} : { projectExtensionSettings }), agentDefinitions });
345
- }
346
- function standaloneExternalConfiguration(context, dependencies) {
347
- const cwd = context.extensionContext.cwd;
348
- const trustedProject = context.extensionContext.isProjectTrusted();
349
- const agentDir = dependencies.agentDir ?? getAgentDir();
350
- const resolution = resolveWorkflowSettings(cwd, trustedProject, workflowSettingsPath(agentDir));
351
- const globalExtensionSettings = resolution.global.extensionSettings;
352
- const projectExtensionSettings = resolution.project.extensionSettings;
353
- return deepFreeze({
354
- projectTrusted: trustedProject,
355
- ...(globalExtensionSettings === undefined ? {} : { globalExtensionSettings: structuredClone(globalExtensionSettings) }),
356
- ...(projectExtensionSettings === undefined ? {} : { projectExtensionSettings: structuredClone(projectExtensionSettings) }),
357
- agentDefinitions: structuredClone(loadAgentDefinitions(cwd, agentDir, trustedProject)),
358
- });
320
+ return decodePreparedAgentConfiguration(value.configuration);
359
321
  }
360
322
  function checkedId(request) {
361
323
  if (typeof request.id !== "string" || !validSubagentId(request.id))
@@ -715,7 +677,8 @@ async function createRunStorage(root, id, request, status, external) {
715
677
  created = true;
716
678
  await chmod(directory, 0o700);
717
679
  await atomicJson(requestPath(directory), request);
718
- await atomicJson(configurationPath(directory), external);
680
+ if (external !== undefined)
681
+ await atomicJson(configurationPath(directory), { version: 1, configuration: external });
719
682
  await atomicJson(statusPath(directory), status);
720
683
  return directory;
721
684
  }
@@ -935,6 +898,7 @@ function unavailable(operation) {
935
898
  class PersistentSubagentManager {
936
899
  dependencies;
937
900
  activeRuns = new Map();
901
+ pendingStarts = new Set();
938
902
  activeRunCount = 0;
939
903
  terminalSummaries = new Map();
940
904
  reconciliationErrors = new Map();
@@ -991,8 +955,8 @@ class PersistentSubagentManager {
991
955
  throw new WorkflowError("CANCELLED", "Subagent manager is disposed");
992
956
  if (context.signal?.aborted)
993
957
  throw new WorkflowError("CANCELLED", "Subagent cancelled");
994
- const external = frozenExternal ?? standaloneExternalConfiguration(context, this.dependencies);
995
- if (external.projectTrusted && !context.extensionContext.isProjectTrusted())
958
+ const external = frozenExternal;
959
+ if (external?.projectTrusted && !context.extensionContext.isProjectTrusted())
996
960
  throw new WorkflowError("RESUME_INCOMPATIBLE", "Cannot retry standalone configuration from an untrusted project");
997
961
  const id = randomUUID();
998
962
  const startedAt = Date.now();
@@ -1009,9 +973,16 @@ class PersistentSubagentManager {
1009
973
  this.activeRunCount += 1;
1010
974
  const controller = new AbortController();
1011
975
  const initialStatus = { id, sessionId, state: "running", startedAt, owner: { ...owner } };
976
+ let finishStart;
977
+ const pendingStart = new Promise((resolve) => { finishStart = resolve; });
978
+ this.pendingStarts.add(pendingStart);
1012
979
  let directory;
1013
980
  try {
1014
981
  directory = await createRunStorage(storageDirectory(this.dependencies), id, snapshot, initialStatus, external);
982
+ if (this.disposePromise !== undefined || context.signal?.aborted) {
983
+ await atomicJson(statusPath(directory), reconciledStatus(initialStatus, "stopped", Date.now()));
984
+ throw new WorkflowError("CANCELLED", "Subagent cancelled");
985
+ }
1015
986
  }
1016
987
  catch (error) {
1017
988
  this.activeRunCount -= 1;
@@ -1019,6 +990,10 @@ class PersistentSubagentManager {
1019
990
  throw error;
1020
991
  throw internalStorageError(error, `Unable to start subagent ${id}`);
1021
992
  }
993
+ finally {
994
+ this.pendingStarts.delete(pendingStart);
995
+ finishStart();
996
+ }
1022
997
  const current = {};
1023
998
  let resolveTerminal;
1024
999
  const terminal = new Promise((resolve) => { resolveTerminal = resolve; });
@@ -1049,13 +1024,9 @@ class PersistentSubagentManager {
1049
1024
  throw new WorkflowError("CANCELLED", "Subagent cancelled");
1050
1025
  }
1051
1026
  }
1052
- const baseRoot = executionRoot(context, this.dependencies, controller.signal, id, worktree, external);
1053
- const root = loadingRegistry().modelAliases().length === 0 ? baseRoot : await addDynamicAliases(context, controller.signal, baseRoot);
1027
+ const baseRoot = executionRoot(context, this.dependencies, controller.signal, id, worktree);
1028
+ const root = external !== undefined || loadingRegistry().modelAliases().length === 0 ? baseRoot : await addDynamicAliases(context, controller.signal, baseRoot);
1054
1029
  const transport = this.dependencies.transport ?? localAgentTransport;
1055
- const injectedExecutor = this.dependencies.createExecutor?.(root, transport);
1056
- executorOwnership.default = injectedExecutor === undefined;
1057
- if (current.run)
1058
- current.run.executorOwnsSession = executorOwnership.default;
1059
1030
  const setSteer = (handler) => {
1060
1031
  const run = current.run;
1061
1032
  if (run)
@@ -1106,6 +1077,15 @@ class PersistentSubagentManager {
1106
1077
  return;
1107
1078
  emitUpdate(run);
1108
1079
  }, (progress) => this.recordProgress(current.run, progress));
1080
+ if (external !== undefined)
1081
+ options.configuration = structuredClone(external);
1082
+ options.onConfiguration = (configuration) => atomicJson(configurationPath(directory), { version: 1, configuration });
1083
+ const cwd = worktree?.cwd ?? root.cwd;
1084
+ options.configuration = await new WorkflowAgentExecutor(root, transport).prepare(options, cwd, controller.signal);
1085
+ const injectedExecutor = this.dependencies.createExecutor?.({ ...root, extensionSettings: options.configuration.settings }, transport);
1086
+ executorOwnership.default = injectedExecutor === undefined;
1087
+ if (current.run)
1088
+ current.run.executorOwnsSession = executorOwnership.default;
1109
1089
  if (injectedExecutor)
1110
1090
  return injectedExecutor.execute(snapshot.prompt, options, controller.signal, setSteer);
1111
1091
  return new WorkflowAgentExecutor(root, transport).execute(snapshot.prompt, options, controller.signal, [], setSteer);
@@ -1156,9 +1136,9 @@ class PersistentSubagentManager {
1156
1136
  }
1157
1137
  return inspection;
1158
1138
  }
1159
- return this.inspectList();
1139
+ return this.inspectList(request.scope === "all" ? undefined : context.extensionContext.sessionManager.getSessionId());
1160
1140
  }
1161
- async inspectList() {
1141
+ async inspectList(sessionId) {
1162
1142
  const root = storageDirectory(this.dependencies);
1163
1143
  await secureDirectory(root);
1164
1144
  const entries = await readdir(root, { withFileTypes: true });
@@ -1172,7 +1152,7 @@ class PersistentSubagentManager {
1172
1152
  try {
1173
1153
  const active = this.activeRuns.get(entry.name);
1174
1154
  const status = publicStatus(active ? persistedStatus(active) : this.terminalSummaries.get(entry.name) ?? await loadPersistedStatus(root, entry.name, false));
1175
- if (status.startedAt === undefined)
1155
+ if (status.startedAt === undefined || (sessionId !== undefined && status.sessionId !== sessionId))
1176
1156
  continue;
1177
1157
  statuses.push({ status, startedAt: status.startedAt });
1178
1158
  }
@@ -1228,11 +1208,11 @@ class PersistentSubagentManager {
1228
1208
  async dispose() {
1229
1209
  if (this.disposePromise)
1230
1210
  return this.disposePromise;
1211
+ this.disposed = true;
1231
1212
  this.disposePromise = (async () => {
1232
1213
  await this.initialization;
1233
- this.disposed = true;
1234
1214
  const runs = [...this.activeRuns.values()];
1235
- await Promise.allSettled(runs.map((run) => this.stopRun(run, true)));
1215
+ await Promise.allSettled([...this.pendingStarts, ...runs.map((run) => this.stopRun(run, true))]);
1236
1216
  await Promise.allSettled([...this.notificationPromises]);
1237
1217
  const owner = this.storageOwner;
1238
1218
  this.storageOwner = undefined;
@@ -1610,9 +1590,8 @@ class PersistentSubagentManager {
1610
1590
  if (!notify || run.notificationSent || run.disposed)
1611
1591
  return;
1612
1592
  run.notificationSent = true;
1613
- const role = roleNameOf(run.request.role) ?? "none";
1614
- const label = run.request.label?.trim() || (role === "none" ? "subagent" : role);
1615
- const notification = { id: run.id, label, role, state: run.state, ...(run.error === undefined ? {} : { error: run.error }) };
1593
+ const label = run.request.label?.trim() || "subagent";
1594
+ const notification = { id: run.id, label, state: run.state, ...(run.error === undefined ? {} : { error: run.error }) };
1616
1595
  const pending = Promise.resolve().then(() => notify(notification));
1617
1596
  this.notificationPromises.add(pending);
1618
1597
  void pending.then(() => { this.notificationPromises.delete(pending); }, () => { this.notificationPromises.delete(pending); });
@@ -60,17 +60,9 @@ async function inspectEntry(manager, storageDirectory, entry, context) {
60
60
  entry: { status: inspected.status, ...(request.request === undefined ? {} : { request: request.request }), ...(request.error === undefined ? {} : { requestError: request.error }) },
61
61
  };
62
62
  }
63
- function requestRole(request) {
64
- const role = request?.role;
65
- if (typeof role === "string" && role.trim())
66
- return role.trim();
67
- const override = objectValue(role);
68
- return typeof override?.name === "string" && override.name.trim() ? override.name.trim() : "none";
69
- }
70
63
  function shortId(id) { return id.length > 12 ? id.slice(0, 8) : id; }
71
64
  function entryName(entry) {
72
- const role = requestRole(entry.request);
73
- return boundedText(entry.request?.label?.trim() || (role === "none" ? shortId(entry.status.id) : role), 256);
65
+ return boundedText(entry.request?.label?.trim() || shortId(entry.status.id), 256);
74
66
  }
75
67
  /** Names for a list of runs; a repeated name carries its short ID, as in the `/workflow` picker, so every row stays unique. */
76
68
  function listNames(entries) {
@@ -108,7 +100,7 @@ function usageAccounting(status) {
108
100
  return status.progress?.accounting;
109
101
  }
110
102
  function detailPresentation(inspection) {
111
- const { status, request } = inspection.entry;
103
+ const { status } = inspection.entry;
112
104
  const attempt = latestAttempt(status);
113
105
  const state = status.progress?.state;
114
106
  const activity = status.progress?.activity;
@@ -117,14 +109,12 @@ function detailPresentation(inspection) {
117
109
  const lastEventAt = status.progress?.lastEventAt;
118
110
  const attempts = status.attempts ?? attempt?.attempt;
119
111
  const accounting = usageAccounting(status);
120
- const role = requestRole(request);
121
112
  const error = status.error ?? attempt?.error;
122
113
  return {
123
114
  state: status.state,
124
115
  ...(activity === undefined ? {} : { activity: { kind: activity.kind, text: boundedText(activity.text) } }),
125
116
  ...(lastEventAt === undefined ? {} : { lastEventAt }),
126
117
  ...(model === undefined ? {} : { model: { provider: boundedText(model.provider, 256), model: boundedText(model.model, 256), ...(model.thinking === undefined ? {} : { thinking: model.thinking }) } }),
127
- ...(role === "none" ? {} : { role: boundedText(role, 256) }),
128
118
  ...(tools === undefined ? {} : { tools: tools.slice(0, 256).map((tool) => boundedText(tool, 256)) }),
129
119
  ...(attempts === undefined ? {} : { attempts }),
130
120
  ...(status.startedAt === undefined ? {} : { startedAt: status.startedAt }),
@@ -178,8 +168,7 @@ function standaloneActionContext(manager, inspection, context) {
178
168
  const session = attempt.session;
179
169
  const live = liveData?.liveSession && session && liveData.liveSession.reference.transport === session.transport && liveData.liveSession.reference.sessionId === session.sessionId ? liveData.liveSession : undefined;
180
170
  const label = request?.label?.trim();
181
- const role = requestRole(request);
182
- const name = label || (role === "none" ? "subagent" : role);
171
+ const name = label || "subagent";
183
172
  const ui = {
184
173
  notify: (message, level = "info") => { context.ui.notify(message, level); },
185
174
  confirm: (title, message) => context.ui.confirm(title, message),
@@ -42,7 +42,6 @@ type SubagentReceipt = {
42
42
  readonly label: string;
43
43
  readonly state: string;
44
44
  readonly model?: string;
45
- readonly role?: string;
46
45
  readonly tools?: readonly string[];
47
46
  readonly input: number;
48
47
  readonly output: number;
@@ -65,6 +64,7 @@ export declare function createSubagentBackgroundWidget(host?: ReceiptHost): {
65
64
  };
66
65
  export declare function renderSubagentInspectCall(args: {
67
66
  id?: string;
67
+ scope?: string;
68
68
  }, theme: Theme): {
69
69
  render(width: number): string[];
70
70
  invalidate(): void;