@astralyn/pi 0.84.5 → 0.84.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +4 -0
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/extensions/index.d.ts +1 -1
  6. package/dist/core/extensions/index.d.ts.map +1 -1
  7. package/dist/core/extensions/index.js.map +1 -1
  8. package/dist/core/extensions/runner.d.ts +1 -0
  9. package/dist/core/extensions/runner.d.ts.map +1 -1
  10. package/dist/core/extensions/runner.js +6 -0
  11. package/dist/core/extensions/runner.js.map +1 -1
  12. package/dist/core/extensions/types.d.ts +11 -0
  13. package/dist/core/extensions/types.d.ts.map +1 -1
  14. package/dist/core/extensions/types.js.map +1 -1
  15. package/dist/core/tools/bash.d.ts +5 -0
  16. package/dist/core/tools/bash.d.ts.map +1 -1
  17. package/dist/core/tools/bash.js +1 -1
  18. package/dist/core/tools/bash.js.map +1 -1
  19. package/dist/extensions/background/index.d.ts +95 -20
  20. package/dist/extensions/background/index.d.ts.map +1 -1
  21. package/dist/extensions/background/index.js +470 -136
  22. package/dist/extensions/background/index.js.map +1 -1
  23. package/dist/extensions/background/manager.d.ts +14 -0
  24. package/dist/extensions/background/manager.d.ts.map +1 -1
  25. package/dist/extensions/background/manager.js +125 -24
  26. package/dist/extensions/background/manager.js.map +1 -1
  27. package/dist/extensions/background/registry.d.ts +82 -0
  28. package/dist/extensions/background/registry.d.ts.map +1 -1
  29. package/dist/extensions/background/registry.js +237 -6
  30. package/dist/extensions/background/registry.js.map +1 -1
  31. package/dist/extensions/background/render.d.ts +35 -11
  32. package/dist/extensions/background/render.d.ts.map +1 -1
  33. package/dist/extensions/background/render.js +180 -30
  34. package/dist/extensions/background/render.js.map +1 -1
  35. package/dist/extensions/router/dialog-host.d.ts +60 -0
  36. package/dist/extensions/router/dialog-host.d.ts.map +1 -0
  37. package/dist/extensions/router/dialog-host.js +196 -0
  38. package/dist/extensions/router/dialog-host.js.map +1 -0
  39. package/dist/extensions/router/probe.d.ts.map +1 -1
  40. package/dist/extensions/router/probe.js +2 -0
  41. package/dist/extensions/router/probe.js.map +1 -1
  42. package/dist/extensions/router/ui.d.ts.map +1 -1
  43. package/dist/extensions/router/ui.js +117 -67
  44. package/dist/extensions/router/ui.js.map +1 -1
  45. package/dist/extensions/subagent/activity.d.ts +3 -5
  46. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  47. package/dist/extensions/subagent/activity.js +8 -89
  48. package/dist/extensions/subagent/activity.js.map +1 -1
  49. package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
  50. package/dist/extensions/subagent/agents-command.js +391 -161
  51. package/dist/extensions/subagent/agents-command.js.map +1 -1
  52. package/dist/extensions/subagent/agents.d.ts +2 -0
  53. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  54. package/dist/extensions/subagent/agents.js +7 -1
  55. package/dist/extensions/subagent/agents.js.map +1 -1
  56. package/dist/extensions/subagent/budget.d.ts +15 -0
  57. package/dist/extensions/subagent/budget.d.ts.map +1 -0
  58. package/dist/extensions/subagent/budget.js +96 -0
  59. package/dist/extensions/subagent/budget.js.map +1 -0
  60. package/dist/extensions/subagent/cancellation.d.ts +29 -0
  61. package/dist/extensions/subagent/cancellation.d.ts.map +1 -0
  62. package/dist/extensions/subagent/cancellation.js +73 -0
  63. package/dist/extensions/subagent/cancellation.js.map +1 -0
  64. package/dist/extensions/subagent/index.d.ts.map +1 -1
  65. package/dist/extensions/subagent/index.js +5 -22
  66. package/dist/extensions/subagent/index.js.map +1 -1
  67. package/dist/extensions/subagent/model-selection.d.ts +16 -0
  68. package/dist/extensions/subagent/model-selection.d.ts.map +1 -0
  69. package/dist/extensions/subagent/model-selection.js +51 -0
  70. package/dist/extensions/subagent/model-selection.js.map +1 -0
  71. package/dist/extensions/subagent/render.d.ts +6 -1
  72. package/dist/extensions/subagent/render.d.ts.map +1 -1
  73. package/dist/extensions/subagent/render.js +23 -12
  74. package/dist/extensions/subagent/render.js.map +1 -1
  75. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  76. package/dist/extensions/subagent/resolve.js +2 -21
  77. package/dist/extensions/subagent/resolve.js.map +1 -1
  78. package/dist/extensions/subagent/runner.d.ts +4 -5
  79. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  80. package/dist/extensions/subagent/runner.js +71 -264
  81. package/dist/extensions/subagent/runner.js.map +1 -1
  82. package/dist/extensions/subagent/sdk-runner.d.ts +13 -11
  83. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  84. package/dist/extensions/subagent/sdk-runner.js +167 -148
  85. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  86. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  87. package/dist/extensions/subagent/settings.js +11 -4
  88. package/dist/extensions/subagent/settings.js.map +1 -1
  89. package/dist/extensions/subagent/state.d.ts +89 -0
  90. package/dist/extensions/subagent/state.d.ts.map +1 -0
  91. package/dist/extensions/subagent/state.js +294 -0
  92. package/dist/extensions/subagent/state.js.map +1 -0
  93. package/dist/extensions/subagent/text.d.ts +4 -0
  94. package/dist/extensions/subagent/text.d.ts.map +1 -1
  95. package/dist/extensions/subagent/text.js +75 -0
  96. package/dist/extensions/subagent/text.js.map +1 -1
  97. package/dist/extensions/subagent/types.d.ts +3 -8
  98. package/dist/extensions/subagent/types.d.ts.map +1 -1
  99. package/dist/extensions/subagent/types.js.map +1 -1
  100. package/dist/extensions/subagent/ui/choices.d.ts +36 -0
  101. package/dist/extensions/subagent/ui/choices.d.ts.map +1 -0
  102. package/dist/extensions/subagent/ui/choices.js +54 -0
  103. package/dist/extensions/subagent/ui/choices.js.map +1 -0
  104. package/dist/extensions/subagent/ui/model-list.d.ts +1 -0
  105. package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
  106. package/dist/extensions/subagent/ui/model-list.js +15 -18
  107. package/dist/extensions/subagent/ui/model-list.js.map +1 -1
  108. package/dist/index.d.ts +1 -1
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js.map +1 -1
  111. package/docs/bundled/README.md +1 -1
  112. package/docs/bundled/extensions/background.md +55 -20
  113. package/docs/extensions.md +13 -0
  114. package/npm-shrinkwrap.json +2 -2
  115. package/package.json +1 -1
  116. package/dist/extensions/subagent/retry.d.ts +0 -17
  117. package/dist/extensions/subagent/retry.d.ts.map +0 -1
  118. package/dist/extensions/subagent/retry.js +0 -41
  119. package/dist/extensions/subagent/retry.js.map +0 -1
@@ -1,64 +1,99 @@
1
1
  # background — background bash tasks
2
2
 
3
- Adds `bg_bash`, `bg_logs`, and `bg_kill` tools plus the `/bg` command. Long-running commands (dev servers, watch builds, slow tests) run in the background while the agent keeps working; when a task ends, its status, exit code, and a tail of its output arrive automatically as a notification.
3
+ Adds the `bg` tool (actions: `create`, `read`, `wait`, `kill`, `list`) plus the `/bg` command. Long-running commands (dev servers, watch builds, slow tests) run in the background while the agent keeps working; when a task ends, its status, exit code, and a tail of its output arrive automatically as a notification.
4
4
 
5
- ## Tools
5
+ ## Tool
6
6
 
7
- `bg_bash` starts a command and returns immediately with a task id and output file path:
7
+ All five operations share one tool. Every call sets `action`; the remaining parameters belong to that action.
8
+
9
+ ### create
10
+
11
+ Starts a command in the background and returns immediately with a task id and an output file path:
8
12
 
9
13
  ```json
10
- { "command": "npm run build", "timeout": 300 }
14
+ { "action": "create", "command": "npm run build", "description": "build", "timeout": 300 }
11
15
  ```
12
16
 
13
- The optional `timeout` is in seconds; on expiry the task is killed and reported as `timeout`. The tool result only reports the start — the completion notification is the single source of truth for the outcome, so there is never a need to poll with sleep loops or repeated `bg_logs` calls.
17
+ - `description` is a short model-written label (e.g. `dev server`) shown in `/bg`, task listings, and the completion notification.
18
+ - `timeout` is in seconds; on expiry the task is killed and reported as `timeout`.
19
+ - The command runs detached — appending `&` is never needed and would lose exit-code tracking.
20
+
21
+ The tool result only reports the start. The completion notification is the single source of truth for the outcome, so there is never a need to poll with sleep loops or repeated reads.
14
22
 
15
- `bg_logs` reads a bounded slice of a task's output file while it runs or after it ends:
23
+ ### read
24
+
25
+ Reads a bounded slice of a task's output file while it runs or after it ends:
16
26
 
17
27
  ```json
18
- { "taskId": "bg-3f2a91", "mode": "tail", "bytes": 8192 }
28
+ { "action": "read", "taskId": "bg-3f2a91", "mode": "tail", "bytes": 8192 }
19
29
  ```
20
30
 
21
- `mode` defaults to `tail`; `bytes` defaults to 8KB and clamps between 256 bytes and 50KB. Truncated reads state the omission up front and always include the full output path.
31
+ `mode` defaults to `tail`; `bytes` defaults to 8KB and clamps between 256 bytes and 50KB. Truncated reads state the omission up front and always include the full output path; reads of a running task say `still running`. The output file is a plain file — the built-in read tool also works on it for line-based paging.
32
+
33
+ ### wait
22
34
 
23
- `bg_kill` stops a single running task by killing its whole process tree:
35
+ Blocks until a task finishes, within a bound:
24
36
 
25
37
  ```json
26
- { "taskId": "bg-3f2a91" }
38
+ { "action": "wait", "taskId": "bg-3f2a91", "waitMs": 20000, "sinceBytes": 4096 }
27
39
  ```
28
40
 
29
- Killing does not bypass the normal pipeline: the task still finalizes as `killed` and its completion notification still arrives.
41
+ - `waitMs` defaults to 20000 and clamps between 1000 and 60000.
42
+ - `sinceBytes` (taken from a previous read/wait result) restricts the returned output to what was written after that offset; without it the last 32KB is returned. Offsets past EOF (for example after output truncation) fall back to the tail and say so.
43
+
44
+ If the task finishes within the window, the result is delivered inline — status, exit code, runtime, and the bounded output delta — and the followUp notification is suppressed, so the completion is delivered exactly once. If the window expires, the result says the task is still running, includes a small tail peek so progress stays visible, and the notification fires later as usual. This is the only sanctioned way to wait; sleeping to emulate it is never correct.
45
+
46
+ ### kill
47
+
48
+ Stops a single running task by killing its whole process tree:
49
+
50
+ ```json
51
+ { "action": "kill", "taskId": "bg-3f2a91" }
52
+ ```
53
+
54
+ Killing does not bypass the normal pipeline: the task still finalizes as `killed` and its completion is delivered wherever it was awaited — inline via `wait`, or as the notification otherwise.
55
+
56
+ ### list
57
+
58
+ Lists currently known tasks — running tasks first, then the five most recently finished, with any overflow folded into a trailing note:
59
+
60
+ ```json
61
+ { "action": "list" }
62
+ ```
30
63
 
31
64
  Task ids accept a unique prefix (with or without the `bg-` part); an ambiguous prefix is an error listing the candidates.
32
65
 
33
66
  ## Completion delivery
34
67
 
35
- When a task ends, the extension sends a `background-task` notification: a small XML message carrying the task id, terminal status, exit code, runtime, output file path, and the sanitized last ~4KB of output. While the agent is streaming, the notification queues behind the current run and is delivered when the run settles; when the agent is idle, it wakes a new turn so the result is acted on immediately.
68
+ When a task ends, the extension sends a `background-task` notification: a small XML message carrying the task id, terminal status, exit code, runtime, output file path, the optional description, and the sanitized last ~4KB of output. While the agent is streaming, the notification queues behind the current run and is delivered when the run settles; when the agent is idle, it wakes a new turn so the result is acted on immediately.
36
69
 
37
- The transcript renders this notification as a one-line summary (`✓ bg-3f2a91 npm run build — completed, exit 0 in 34s`) with the output path below; expanding it shows the embedded output tail.
70
+ The transcript renders this notification as a one-line summary (`✓ bg-3f2a91 npm run build — completed, exit 0 in 34s`; with a description: `✓ bg-3f2a91 dev server (npm run build) — completed, exit 0 in 34s`) with the output file's name below; expanding it shows the full output path and the embedded output tail.
38
71
 
39
72
  ## /bg
40
73
 
41
- `/bg` opens an inline task menu in the editor slot (like `/model`); the chat transcript stays visible above it. The list shows each task's status glyph, id, duration, and command; `Enter` opens the selected task's live output view, which replaces the menu.
74
+ `/bg` opens an inline task menu in the editor slot (like `/model`); the chat transcript stays visible above it. The list shows each task's status glyph, id, duration, and label (the description over the first command line); `Enter` opens the selected task's live output view, which replaces the menu.
42
75
 
43
76
  | Key | In the task list | In the output view |
44
77
  |---|---|---|
45
- | `↑` / `↓` | Select task | — |
78
+ | `↑` / `↓` | Select task | Scroll one line (freezes following) |
46
79
  | `Enter` | Open the selected task's output | — |
47
80
  | `k` | Kill the selected running task | Kill the viewed task |
48
- | `PgUp` / `PgDn` | — | Scroll the output; `PgUp` freezes it, scrolling back to the bottom resumes following |
81
+ | `PgUp` / `PgDn` | — | Scroll a page; `PgUp` freezes following, scrolling back to the bottom resumes it |
49
82
  | `Esc` | Close the menu | Back to the task list |
50
83
 
51
- The output view polls the output file once per second and only ever reads the last 128KB. Outside an interactive TUI, `/bg` prints a bounded task summary instead.
84
+ While a `bg wait` call is pending, its transcript row refreshes once per second (`bg wait bg-3f · waiting 12s/20s · +3.2KB new output`) until the result settles. The task list separates running tasks from finished ones with a `── finished ──` divider and adapts its visible rows to short terminal windows. The output view polls the output file once per second and only ever reads the last 128KB — and only when the task's output actually grew; a finished task's output is read once. Outside an interactive TUI, `/bg` prints a bounded task summary instead.
52
85
 
53
86
  ## Statusline
54
87
 
55
- Running and finished counts appear in the footer as `bg 2 running · 1 done`; the segment disappears when no tasks exist.
88
+ Running and finished counts appear in the footer as `bg 2 running · 1 done`; tasks the stall watchdog has flagged are reported separately as `bg 2 running · 1 waiting for input · 1 done` (flagged tasks are running tasks, so the counts add up); the segment disappears when no tasks exist.
56
89
 
57
90
  ## Limits and lifecycle
58
91
 
59
92
  - Background tasks inherit the session's `PI_*` environment variables (`PI_SESSION_ID`, `PI_MODEL`, …) just like the built-in bash tool, snapshotted when the task starts.
93
+ - Tasks run through the session's configured shell (`shellPath`) and honor `shellCommandPrefix`, matching the built-in bash tool. The prefix is applied at execution time only — it never appears in task labels or notifications.
60
94
  - Output streams directly to a system-temp file (`pi-bg-<id>.log`), never into the project or into memory. Memory holds only a byte counter.
61
95
  - Output is capped at 20MB. Hitting the cap kills the task and marks it `failed` rather than silently truncating.
62
- - At most 8 tasks may run concurrently; `bg_bash` reports the running tasks when the limit is reached.
63
- - Aborting the current turn (Esc) does not kill background tasks — that is what `bg_kill` and `/bg` are for.
96
+ - At most 8 tasks may run concurrently; `create` reports the running tasks when the limit is reached.
97
+ - Aborting the current turn (Esc) does not kill background tasks — that is what `kill` and `/bg` are for.
64
98
  - Session shutdown, `/reload`, new sessions, and session switches kill all running tasks; those kills are silent (no notification flood). There is no restart reattachment: finished-task records live only for the current session.
99
+ - Output files outlive the session for later inspection (the `read` action and notifications keep pointing at them); Pi never deletes them automatically — the system temp directory's own cleanup policy applies.
@@ -1079,6 +1079,19 @@ ctx.compact({
1079
1079
  });
1080
1080
  ```
1081
1081
 
1082
+ ### ctx.getShellSettings()
1083
+
1084
+ Returns the session's shell settings (`shellPath`, `commandPrefix`) exactly as the built-in bash tool uses them. Returns `undefined` on hosts that do not provide shell settings; fall back to reading settings from disk if your extension must. Optional on `ExtensionContext` for the same reason.
1085
+
1086
+ ```typescript
1087
+ pi.on("session_start", (_event, ctx) => {
1088
+ const shell = ctx.getShellSettings?.();
1089
+ if (shell?.commandPrefix) {
1090
+ // Commands spawned by this extension should honor the same prefix as bash.
1091
+ }
1092
+ });
1093
+ ```
1094
+
1082
1095
  ### ctx.getSystemPrompt()
1083
1096
 
1084
1097
  Returns Pi's current system prompt string.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@astralyn/pi",
3
- "version": "0.84.5",
3
+ "version": "0.84.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@astralyn/pi",
9
- "version": "0.84.5",
9
+ "version": "0.84.7",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-agent-core": "0.84.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astralyn/pi",
3
- "version": "0.84.5",
3
+ "version": "0.84.7",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -1,17 +0,0 @@
1
- import type { SubagentRunDetails } from "./types.ts";
2
- export interface BeginSubagentRetryOptions {
3
- attempt: number;
4
- maxAttempts: number;
5
- delayMs: number;
6
- error: string;
7
- }
8
- export interface SubagentRetryView {
9
- attempt: number;
10
- maxAttempts: number;
11
- remainingSeconds: number;
12
- error: string;
13
- }
14
- export declare function beginSubagentRetry(run: SubagentRunDetails, options: BeginSubagentRetryOptions): void;
15
- export declare function clearSubagentRetry(run: SubagentRunDetails): void;
16
- export declare function getSubagentRetryView(run: SubagentRunDetails, now?: number): SubagentRetryView | undefined;
17
- //# sourceMappingURL=retry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/retry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACd;AAWD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAWpG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAGhE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,SAAa,GAAG,iBAAiB,GAAG,SAAS,CAY7G"}
@@ -1,41 +0,0 @@
1
- import { boundText } from "./activity.js";
2
- import { RETRY_ERROR_TEXT_LIMIT } from "./constants.js";
3
- function positiveInteger(value, fallback) {
4
- return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
5
- }
6
- function retryError(error) {
7
- const normalized = error.replace(/\s+/gu, " ").trim();
8
- return boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\s+/gu, " ").trim();
9
- }
10
- export function beginSubagentRetry(run, options) {
11
- const attempt = positiveInteger(options.attempt, 1);
12
- const maxAttempts = Math.max(attempt, positiveInteger(options.maxAttempts, attempt));
13
- const delayMs = Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 0;
14
- run.retry = {
15
- attempt,
16
- maxAttempts,
17
- deadline: Date.now() + delayMs,
18
- error: retryError(options.error),
19
- };
20
- run.currentActivity = `Retrying (${attempt}/${maxAttempts})…`;
21
- }
22
- export function clearSubagentRetry(run) {
23
- run.retry = undefined;
24
- if (run.currentActivity?.startsWith("Retrying"))
25
- run.currentActivity = undefined;
26
- }
27
- export function getSubagentRetryView(run, now = Date.now()) {
28
- const retry = run.retry;
29
- if (!retry || !Number.isFinite(retry.deadline))
30
- return undefined;
31
- const attempt = positiveInteger(retry.attempt, 1);
32
- const maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));
33
- const currentTime = Number.isFinite(now) ? now : retry.deadline;
34
- return {
35
- attempt,
36
- maxAttempts,
37
- remainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),
38
- error: retryError(typeof retry.error === "string" ? retry.error : ""),
39
- };
40
- }
41
- //# sourceMappingURL=retry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/extensions/subagent/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAiBxD,SAAS,eAAe,CAAC,KAAa,EAAE,QAAgB;IACvD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3E,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,OAAO,SAAS,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAuB,EAAE,OAAkC;IAC7F,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,GAAG,CAAC,KAAK,GAAG;QACX,OAAO;QACP,WAAW;QACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;QAC9B,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;KAChC,CAAC;IACF,GAAG,CAAC,eAAe,GAAG,aAAa,OAAO,IAAI,WAAW,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAuB;IACzD,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;IACtB,IAAI,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,UAAU,CAAC;QAAE,GAAG,CAAC,eAAe,GAAG,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAuB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC7E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IACjE,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAChE,OAAO;QACN,OAAO;QACP,WAAW;QACX,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/E,KAAK,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;AACH,CAAC","sourcesContent":["import { boundText } from \"./activity.ts\";\nimport { RETRY_ERROR_TEXT_LIMIT } from \"./constants.ts\";\nimport type { SubagentRunDetails } from \"./types.ts\";\n\nexport interface BeginSubagentRetryOptions {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terror: string;\n}\n\nexport interface SubagentRetryView {\n\tattempt: number;\n\tmaxAttempts: number;\n\tremainingSeconds: number;\n\terror: string;\n}\n\nfunction positiveInteger(value: number, fallback: number): number {\n\treturn Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;\n}\n\nfunction retryError(error: string): string {\n\tconst normalized = error.replace(/\\s+/gu, \" \").trim();\n\treturn boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\\s+/gu, \" \").trim();\n}\n\nexport function beginSubagentRetry(run: SubagentRunDetails, options: BeginSubagentRetryOptions): void {\n\tconst attempt = positiveInteger(options.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(options.maxAttempts, attempt));\n\tconst delayMs = Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 0;\n\trun.retry = {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tdeadline: Date.now() + delayMs,\n\t\terror: retryError(options.error),\n\t};\n\trun.currentActivity = `Retrying (${attempt}/${maxAttempts})…`;\n}\n\nexport function clearSubagentRetry(run: SubagentRunDetails): void {\n\trun.retry = undefined;\n\tif (run.currentActivity?.startsWith(\"Retrying\")) run.currentActivity = undefined;\n}\n\nexport function getSubagentRetryView(run: SubagentRunDetails, now = Date.now()): SubagentRetryView | undefined {\n\tconst retry = run.retry;\n\tif (!retry || !Number.isFinite(retry.deadline)) return undefined;\n\tconst attempt = positiveInteger(retry.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));\n\tconst currentTime = Number.isFinite(now) ? now : retry.deadline;\n\treturn {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tremainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),\n\t\terror: retryError(typeof retry.error === \"string\" ? retry.error : \"\"),\n\t};\n}\n"]}