@narumitw/pi-subagents 3.4.1 → 3.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +147 -0
- package/README.md +17 -11
- package/dist/chunks/{settings-ui-24GHO6E2.ts → settings-ui-KOX3DMZP.ts} +4 -1
- package/dist/chunks/{settings-ui-24GHO6E2.ts.map → settings-ui-KOX3DMZP.ts.map} +2 -2
- package/dist/index.ts +48 -20
- package/dist/index.ts.map +2 -2
- package/package.json +8 -7
- package/src/message-renderers.ts +4 -10
- package/src/settings-ui.ts +3 -0
- package/src/tools.ts +10 -6
- package/src/widget-renderer.ts +33 -2
- package/src/widget.ts +7 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# @narumitw/pi-subagents
|
|
2
|
+
|
|
3
|
+
## 3.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cf7b63d: Put editor widget names and short current count/state summaries in their divider lines. Remove duplicate body titles while retaining safety text, detail rows, privacy modes, and standalone RPC/tool output. In fullscreen Pi, click anywhere in a widget to collapse it to one named line, then click that line to restore the latest content. Preserve independent, session-local disclosure through updates without taking editor focus, changing domain data, or stopping background work. Existing owner controls provide keyboard restoration; regular-mode mouse input remains terminal-owned.
|
|
8
|
+
|
|
9
|
+
The Kit minor release supplies the named widget state and publisher disclosure APIs. Changesets raises all adopting consumers' Kit dependency floors in the same Version PR. Publish and verify the exact Kit artifact before its consumers.
|
|
10
|
+
- Updated dependencies [cf7b63d]
|
|
11
|
+
- @narumitw/pi-tui-kit@0.70.0
|
|
12
|
+
|
|
13
|
+
## 3.4.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 54f2700: Preserve fullscreen viewport capture through custom list wrappers so default and configured paging keys reach the focused list. Keep native transcript search, unrelated overlays, free-text modes, paste, and hard cancellation unchanged. Filter Kit key hints according to each screen's capture policy.
|
|
18
|
+
|
|
19
|
+
Update Recall and File Context to the current Kit dependency range. The selected consumer releases require the fixed Kit patch through Changesets dependency-floor updates.
|
|
20
|
+
- e484010: Include the existing package-root CHANGELOG.md in extension tarballs so Pi can show native update notices. Keep Changesets version headings and Pi's first-observation and collapseChangelog behavior unchanged.
|
|
21
|
+
- 5120d4d: Preserve TypeBox enum inference for direct imports and Pi's extension loader without changing provider-visible schemas or validation rules. Import Notes schemas from TypeBox, declare its host-provided peer, and complete Worktree's command result contract for the updated Pi APIs.
|
|
22
|
+
- 51e74e1: Use the host-injected key formatter for completion and broker-message expansion hints. Omit hints when the action is unbound or the host does not supply renderer key formatting, while preserving expanded content and terminal sanitization.
|
|
23
|
+
- Updated dependencies [54f2700]
|
|
24
|
+
- Updated dependencies [6c76ef1]
|
|
25
|
+
- @narumitw/pi-tui-kit@0.69.0
|
|
26
|
+
|
|
27
|
+
## 3.4.1
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- 5803891: Wake an idle main agent when a subagent job reaches a terminal state. Keep steering delivery for a running main agent and suppress stale completions after session replacement or shutdown.
|
|
32
|
+
|
|
33
|
+
## 3.4.0
|
|
34
|
+
|
|
35
|
+
### Minor Changes
|
|
36
|
+
|
|
37
|
+
- a21d39b: Add opt-in editor status presentation helpers for stable snapshot publication, session-local view controls, and bounded whole-snapshot collections. Keep the existing EditorStatusWidget API unchanged.
|
|
38
|
+
|
|
39
|
+
Retain visible Progress, Subagents, and Herdr widgets during updates. Add bounded summaries, manual view and item controls, and explicit one-shot compaction policies to Progress and Subagents without changing task state or persistent defaults. Preserve Progress completion retention and keep Herdr observation policies local. Keep tree navigation and manual context compaction separate from response-cycle tracking.
|
|
40
|
+
- 106ef89: Add optional `provider` and `model` parameters to `subagent_spawn`. Each omitted value inherits independently from the effective parent model at spawn time. Explicit IDs use exact matching without fallback, including listed case-distinct and provider-prefixed IDs. Only the child checks model registration and current availability. The requested pair bypasses CLI pattern matching and is bound exactly before the child receives its task. A missing or unavailable model fails the job after `subagent_spawn` returns its `jobId`.
|
|
41
|
+
|
|
42
|
+
Unlisted custom model IDs previously accepted through Pi's CLI now fail, including inherited IDs. Register each exact model in Pi's `models.json` or attach a trusted extension that registers it in the child. Parent-only providers, runtime API keys, and virtual routing state are not forwarded. Reload or replace the session after upgrading to load the new tool schema.
|
|
43
|
+
|
|
44
|
+
Reject oversized provider and model IDs before character validation. Schema bounds and runtime byte checks use the existing shared 16 KiB child-bootstrap limit without adding a shorter naming limit.
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- 1e33872: Use task-first widget rows and hide job IDs and tool names by default while preserving saved preferences. Show thinking only when it differs from the main agent's level captured at spawn. Omit redundant running labels and unset timeout text; show elapsed time for running jobs and queued status for waiting jobs.
|
|
49
|
+
- 99b7c92: Show provider and model IDs in expanded widget rows only when they differ from the main agent's effective values captured at spawn, matching thinking-level display. Keep inherited and explicit-equal values hidden, and preserve each job's comparison after parent model changes.
|
|
50
|
+
- Updated dependencies [a21d39b]
|
|
51
|
+
- Updated dependencies [f68aa54]
|
|
52
|
+
- Updated dependencies [b062d21]
|
|
53
|
+
- @narumitw/pi-tui-kit@0.68.0
|
|
54
|
+
|
|
55
|
+
## 3.3.3
|
|
56
|
+
|
|
57
|
+
### Patch Changes
|
|
58
|
+
|
|
59
|
+
- Updated dependencies [57eeae7]
|
|
60
|
+
- @narumitw/pi-tui-kit@0.67.0
|
|
61
|
+
|
|
62
|
+
## 3.3.2
|
|
63
|
+
|
|
64
|
+
### Patch Changes
|
|
65
|
+
|
|
66
|
+
- 168248c: Reuse published TUI Kit frame metadata, masked input, configured-key syntax, and interaction ownership while retaining extension-owned settings and cancellation policy. Keep malformed Ticker key strings from suppressing valid reorder shortcuts, and drain Usage settings saves after cancellation.
|
|
67
|
+
|
|
68
|
+
## 3.3.1
|
|
69
|
+
|
|
70
|
+
### Patch Changes
|
|
71
|
+
|
|
72
|
+
- 9edf94b: Show each active job’s spawn-time thinking level in the above-editor widget.
|
|
73
|
+
|
|
74
|
+
## 3.3.0
|
|
75
|
+
|
|
76
|
+
### Minor Changes
|
|
77
|
+
|
|
78
|
+
- 53730f9: Add the `/subagents` job manager and `/subagents settings` route. Support confirmed active-job cancellation and persistent widget, job ID, tool, and timing display preferences without changing model tools or job execution.
|
|
79
|
+
|
|
80
|
+
### Patch Changes
|
|
81
|
+
|
|
82
|
+
- 9f80b89: Reuse published Kit interaction ownership for native Progress and Subagents settings while preserving ordered saves, rollback, and durable-save recovery after the screen closes.
|
|
83
|
+
|
|
84
|
+
Share passive widget framing in Subagents, Tool, Plan Mode, and Cache Hit Monitor. Keep domain rendering and lifecycle ownership local, bound narrow and invalid widths, and retain lazy loading of Kit menus and other interactive APIs.
|
|
85
|
+
- 3dd82ec: Add transcript expansion and collapse for child requests and responses using Pi's configured tool-output expansion key.
|
|
86
|
+
- Updated dependencies [077137a]
|
|
87
|
+
- Updated dependencies [9f80b89]
|
|
88
|
+
- Updated dependencies [efc474c]
|
|
89
|
+
- @narumitw/pi-tui-kit@0.66.0
|
|
90
|
+
|
|
91
|
+
## 3.2.1
|
|
92
|
+
|
|
93
|
+
### Patch Changes
|
|
94
|
+
|
|
95
|
+
- dfc020b: Show a sanitized, shortened preview of each active subagent's existing task in the TUI widget without changing the spawn schema or inspection metadata.
|
|
96
|
+
|
|
97
|
+
## 3.2.0
|
|
98
|
+
|
|
99
|
+
### Minor Changes
|
|
100
|
+
|
|
101
|
+
- ca27497: Allow subagent jobs to select Pi's native codemode tool explicitly, with startup readiness verification and unchanged default tools.
|
|
102
|
+
|
|
103
|
+
## 3.1.1
|
|
104
|
+
|
|
105
|
+
### Patch Changes
|
|
106
|
+
|
|
107
|
+
- 68c4b95: Update runtime dependencies and preserve Pi tool-context types through the LSP session lifecycle guard for compatibility with current Pi releases.
|
|
108
|
+
|
|
109
|
+
## 3.1.0
|
|
110
|
+
|
|
111
|
+
### Minor Changes
|
|
112
|
+
|
|
113
|
+
- aec9773: Allow each subagent job to attach validated local skills and trusted extensions with an attested initial tool allowlist.
|
|
114
|
+
|
|
115
|
+
## 3.0.2
|
|
116
|
+
|
|
117
|
+
### Patch Changes
|
|
118
|
+
|
|
119
|
+
- 8abd5b7: Keep generated extension runtime graphs inside Pi's Jiti-loaded TypeScript path to avoid duplicate peer-runtime evaluation during startup. Add measured generated runtimes for Context Management, Herdr, and TypeSafe Search.
|
|
120
|
+
|
|
121
|
+
## 3.0.1
|
|
122
|
+
|
|
123
|
+
### Patch Changes
|
|
124
|
+
|
|
125
|
+
- 99f0bcc: Start subagent jobs from Pi's bundled executable when the package manifest points to a source-only CLI path.
|
|
126
|
+
|
|
127
|
+
## 3.0.0
|
|
128
|
+
|
|
129
|
+
### Major Changes
|
|
130
|
+
|
|
131
|
+
- 99c304e: Replace the legacy orchestration runtime with subagent jobs and authenticated main-agent messaging.
|
|
132
|
+
|
|
133
|
+
Remove `/subagents`, extension settings, persisted and retained agents, the previous blocking orchestration interfaces, custom agent catalogs, advanced orchestration, alternate transports, trust-aware cwd policy, and extension-owned worktrees.
|
|
134
|
+
|
|
135
|
+
Use `subagent_spawn`, `subagent_inspect`, `subagent_cancel`, `subagent_wait`, and the context-specific main-agent and child `subagent_send` contracts directly or through a user-designed skill after upgrading, and start a fresh Pi session so stored calls do not request removed tool names or the legacy `subagent_send` schema.
|
|
136
|
+
|
|
137
|
+
Main agents can send requests to queued or running jobs, and children can send requests to main, while either side answers with the same request ID through `subagent_send`.
|
|
138
|
+
|
|
139
|
+
A queued main-agent request interrupts active child response waits without consuming the original child requests, so RPC steering can proceed and those waits can be retried.
|
|
140
|
+
|
|
141
|
+
The package no longer registers or publishes a delegation skill, while the repository keeps `using-pi-subagents` as an example for designing one.
|
|
142
|
+
|
|
143
|
+
Completion messages follow Pi's global tool-output expansion state and configured `app.tools.expand` binding.
|
|
144
|
+
|
|
145
|
+
### Patch Changes
|
|
146
|
+
|
|
147
|
+
- e55825e: Update the repository-only example skill to require independent work or a concrete context-isolation benefit before delegating to a subagent.
|
package/README.md
CHANGED
|
@@ -22,18 +22,19 @@ Pi Subagents runs Pi jobs in separate child processes and supports authenticated
|
|
|
22
22
|
|
|
23
23
|
## 📦 Install
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
The npm package still contains the legacy 2.x runtime and does not provide the tools below.
|
|
27
|
-
|
|
28
|
-
Install the repository source as one Pi package:
|
|
25
|
+
Install from npm:
|
|
29
26
|
|
|
30
27
|
```bash
|
|
31
|
-
pi install
|
|
28
|
+
pi install npm:@narumitw/pi-subagents
|
|
32
29
|
```
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
Try it for one invocation:
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
```bash
|
|
34
|
+
pi -e npm:@narumitw/pi-subagents
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To install from a local checkout, clone the repository, install dependencies, build its generated runtime, and install its package directory:
|
|
37
38
|
|
|
38
39
|
```bash
|
|
39
40
|
git clone https://github.com/narumiruna/pi-extensions.git
|
|
@@ -73,8 +74,9 @@ Use messaging only when needed:
|
|
|
73
74
|
- Answer a child-originated request by calling `subagent_send` with its `requestId`.
|
|
74
75
|
|
|
75
76
|
Completion messages and child requests and responses follow Pi's global tool-output expansion state and the `app.tools.expand` binding (`Ctrl+O` by default).
|
|
76
|
-
Collapsed messages show a summary and the configured expansion
|
|
77
|
-
|
|
77
|
+
Collapsed messages show a summary and the host's configured expansion keys.
|
|
78
|
+
The hint is omitted when the action is unbound or an older host does not supply renderer key formatting.
|
|
79
|
+
Expanded messages show the full content; this display state does not change the content sent to the model.
|
|
78
80
|
|
|
79
81
|
## 💬 Commands
|
|
80
82
|
|
|
@@ -93,7 +95,7 @@ The widget is TUI-only and contains only queued or running jobs. Each row starts
|
|
|
93
95
|
For example, with a main-agent thinking level of `high` at spawn:
|
|
94
96
|
|
|
95
97
|
```text
|
|
96
|
-
Subagents ·
|
|
98
|
+
─ ▾ Subagents · 1 running · 1 queued ───────
|
|
97
99
|
▶ Review widget tests · 12s
|
|
98
100
|
○ Audit settings · thinking: medium · queued
|
|
99
101
|
```
|
|
@@ -106,9 +108,13 @@ The task preview removes terminal controls, collapses whitespace, and uses at mo
|
|
|
106
108
|
Task text is visible in this local widget, but `subagent_inspect` continues to omit it. Optional tool names include selected core and extension tools, not fixed communication tools.
|
|
107
109
|
The widget omits attachment paths and resource totals, disappears when no jobs remain active, and clears when the session ends.
|
|
108
110
|
|
|
111
|
+
The separator shows **Subagents** and current running and queued counts, including while collapsed. In fullscreen TUI mode, click anywhere in the widget, including blank columns, to collapse it to that separator. Click the separator to restore the latest jobs without moving keyboard focus.
|
|
112
|
+
Disclosure survives job updates, temporary absence, and host remounts. Select a visible view in `/subagents` to restore disclosure with the keyboard. Session start and tree navigation reset it.
|
|
113
|
+
Collapse does not change jobs, settings, item views, pins, or automatic rules.
|
|
114
|
+
|
|
109
115
|
Ordinary updates refresh the mounted widget without changing its position among other widgets. Hiding and showing it again can change that position.
|
|
110
116
|
The widget uses at most ten rows, including one separator, and reserves eight terminal rows for the editor and footer. This is a local height limit, not a calculation of space left by other widgets.
|
|
111
|
-
With
|
|
117
|
+
With no available rows it renders nothing. One available row shows only the separator with current counts and omitted-row information. Summary view also uses only the separator, but does not count its intentionally absent job rows as omitted. Narrow layouts clip each line to the terminal width.
|
|
112
118
|
|
|
113
119
|
In `/subagents`, **Widget view** provides details, summary, hide/show, pin/unpin, automatic compaction, and item-view reset controls.
|
|
114
120
|
These controls are session-local and do not write settings. Manual hide remains in effect across job changes until you show the widget again.
|
|
@@ -108,6 +108,9 @@ async function showSubagentSettings(ctx, options) {
|
|
|
108
108
|
() => complete("back")
|
|
109
109
|
);
|
|
110
110
|
return {
|
|
111
|
+
get capturesViewportInput() {
|
|
112
|
+
return list.capturesViewportInput;
|
|
113
|
+
},
|
|
111
114
|
render(width) {
|
|
112
115
|
if (!current()) complete("stale");
|
|
113
116
|
renderedWidth = Number.isFinite(width) ? Math.max(0, Math.floor(width)) : 0;
|
|
@@ -182,4 +185,4 @@ async function showSubagentSettings(ctx, options) {
|
|
|
182
185
|
export {
|
|
183
186
|
showSubagentSettings
|
|
184
187
|
};
|
|
185
|
-
//# sourceMappingURL=settings-ui-
|
|
188
|
+
//# sourceMappingURL=settings-ui-KOX3DMZP.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/settings-ui.ts"],
|
|
4
|
-
"sourcesContent": ["import { stripVTControlCharacters } from \"node:util\";\nimport { type ExtensionCommandContext, getSettingsListTheme } from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, type SettingItem, SettingsList, Text, type TuiMouseEvent } from \"@earendil-works/pi-tui\";\nimport {\n HorizontalRule,\n renderBoundedFrameLayout,\n runCustomInteraction,\n sanitizeTerminalText,\n} from \"@narumitw/pi-tui-kit\";\nimport type { SubagentSettings } from \"./settings.js\";\n\ninterface SubagentSettingsUIOptions {\n signal: AbortSignal;\n isCurrent(): boolean;\n get(): SubagentSettings;\n save(key: keyof SubagentSettings, value: boolean, signal: AbortSignal): Promise<SubagentSettings>;\n apply(settings: SubagentSettings): void;\n}\n\ntype CloseReason = \"back\" | \"close\" | \"stale\";\n\nconst SETTINGS: { key: keyof SubagentSettings; label: string; description: string }[] = [\n { key: \"showWidget\", label: \"Show widget\", description: \"Show subagent jobs above the editor.\" },\n { key: \"showJobId\", label: \"Show job ID\", description: \"Show job IDs in the widget.\" },\n { key: \"showTools\", label: \"Show tools\", description: \"Show active tools in the widget.\" },\n { key: \"showTiming\", label: \"Show timing\", description: \"Show job timing in the widget.\" },\n];\n\nexport async function showSubagentSettings(\n ctx: ExtensionCommandContext,\n options: SubagentSettingsUIOptions,\n): Promise<CloseReason> {\n const result = await runCustomInteraction<CloseReason>(ctx, {\n signal: options.signal,\n isCurrent: options.isCurrent,\n // The command owner reports interaction failures and non-TUI settings paths.\n onError: () => {},\n create({ tui, theme, signal, complete }) {\n let queue = Promise.resolve();\n const current = () => !signal.aborted && options.isCurrent();\n const revisions = new Map<string, number>();\n const pending = new Map<string, number>();\n const mouseRows = new Map<number, number>();\n let renderedWidth = 0;\n let contentHeight = 0;\n let mousePressed = false;\n const reportFailure = (message: string) => {\n if (!current()) return;\n try {\n ctx.ui.notify(sanitizeTerminalText(`Could not save pi-subagents.json: ${message}`), \"error\");\n } catch {\n // The host can dispose its notifier after the ownership check.\n }\n };\n const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg(\"border\", text) });\n // Keep native SettingsList semantics, but use this screen's callback theme.\n const listTheme = {\n ...getSettingsListTheme(),\n label: (text: string, selected: boolean) => (selected ? theme.fg(\"accent\", text) : text),\n value: (text: string, selected: boolean) => theme.fg(selected ? \"accent\" : \"muted\", text),\n description: (text: string) => theme.fg(\"dim\", text),\n cursor: theme.fg(\"accent\", \"\u2192 \"),\n hint: (text: string) => theme.fg(\"dim\", text),\n };\n const initial = options.get();\n const items: SettingItem[] = SETTINGS.map(({ key, label, description }) => ({\n id: key,\n label,\n description,\n currentValue: String(initial[key]),\n values: [\"true\", \"false\"],\n }));\n const list = new SettingsList(\n items,\n items.length,\n listTheme,\n (id, value) => {\n if (!current()) return;\n const key = id as keyof SubagentSettings;\n const revision = (revisions.get(id) ?? 0) + 1;\n revisions.set(id, revision);\n pending.set(id, revision);\n queue = queue\n .then(async () => {\n if (!current()) {\n complete(\"stale\");\n return;\n }\n const before = { ...options.get() };\n let effective = before;\n try {\n const settings = await options.save(key, value === \"true\", signal);\n // A successful rename is durable, even when closing aborted the save signal.\n if (!options.isCurrent()) {\n complete(\"stale\");\n return;\n }\n options.apply(settings);\n effective = options.get();\n } catch (error) {\n if (!options.isCurrent()) {\n complete(\"stale\");\n return;\n }\n let message = error instanceof Error ? error.message : String(error);\n try {\n options.apply(before);\n } catch (rollbackError) {\n message += `; could not restore effective settings: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;\n }\n reportFailure(message);\n }\n if (!current()) return;\n if (pending.get(id) === revision) pending.delete(id);\n // Saving rereads the full document, including unrelated manual edits. Keep newer\n // optimistic choices, but refresh every row with no outstanding user change.\n for (const { key: settingKey } of SETTINGS) {\n if (!pending.has(settingKey)) list.updateValue(settingKey, String(effective[settingKey]));\n }\n tui.requestRender();\n })\n .catch((error: unknown) => {\n // A failed action must not prevent later requests from entering the queue.\n reportFailure(error instanceof Error ? error.message : String(error));\n });\n },\n () => complete(\"back\"),\n );\n return {\n render(width: number) {\n if (!current()) complete(\"stale\");\n renderedWidth = Number.isFinite(width) ? Math.max(0, Math.floor(width)) : 0;\n listTheme.cursor = theme.fg(\"accent\", \"\u2192 \");\n // The native footer hardcodes keys. Advertise only the hard-cancel key owned here;\n // configured native navigation, change, and Back actions remain unchanged.\n const content = list.render(Math.max(4, renderedWidth)).slice(0, -2);\n contentHeight = content.length;\n const focusedRow = content.findIndex((line) => stripVTControlCharacters(line).startsWith(\"\u2192\"));\n mouseRows.clear();\n\n const terminalRows = Number.isFinite(tui.terminal.rows) ? Math.floor(tui.terminal.rows) : 24;\n const frame = renderBoundedFrameLayout({\n width: renderedWidth,\n maxRows: Math.max(1, terminalRows - 3),\n rule: rule.render(renderedWidth)[0] ?? \"\",\n title: new Text(theme.fg(\"accent\", theme.bold(\"Subagents Settings\")), 0, 0).render(renderedWidth),\n context: [theme.fg(\"muted\", \"Saved changes apply immediately.\")],\n content,\n hints: new Text(theme.fg(\"muted\", \"Ctrl+C close\"), 0, 0).render(renderedWidth),\n priorityRows: focusedRow < 0 ? [] : [focusedRow],\n focusedRow,\n });\n for (const { frameIndex, contentIndex } of frame.contentRows) mouseRows.set(frameIndex, contentIndex);\n return frame.lines;\n },\n invalidate() {\n mouseRows.clear();\n mousePressed = false;\n list.invalidate();\n },\n handleInput(data: string) {\n if (!current()) return complete(\"stale\");\n mouseRows.clear();\n mousePressed = false;\n if (matchesKey(data, Key.ctrl(\"c\"))) complete(\"close\");\n else {\n // SettingsList uses Pi's effective native keybindings for standard actions.\n list.handleInput(data);\n }\n tui.requestRender();\n },\n handleMouse(event: TuiMouseEvent) {\n if (!current()) {\n complete(\"stale\");\n return;\n }\n const nativeRow = mouseRows.get(event.y);\n if (nativeRow === undefined || event.x < 0 || event.x >= renderedWidth) {\n if (event.button === \"left\" && (event.type === \"press\" || event.type === \"click\")) mousePressed = false;\n return;\n }\n const nativeEvent = { ...event, y: nativeRow, width: renderedWidth, height: contentHeight };\n if (event.type === \"click\" && event.button === \"left\" && !mousePressed) {\n list.handleMouse({ ...nativeEvent, type: \"press\" });\n }\n const result = list.handleMouse(nativeEvent);\n if (event.type === \"press\" && event.button === \"left\") mousePressed = result?.handled === true;\n if (event.type === \"click\" || event.type === \"wheel\") mousePressed = false;\n if (result?.handled && result.render !== false) tui.requestRender();\n return result;\n },\n waitForPending() {\n return queue;\n },\n dispose() {\n mouseRows.clear();\n mousePressed = false;\n },\n };\n },\n });\n if (result.kind === \"error\") throw result.error;\n return result.kind === \"completed\" ? result.value : result.kind === \"unsupported\" ? \"back\" : \"stale\";\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { stripVTControlCharacters } from \"node:util\";\nimport { type ExtensionCommandContext, getSettingsListTheme } from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, type SettingItem, SettingsList, Text, type TuiMouseEvent } from \"@earendil-works/pi-tui\";\nimport {\n HorizontalRule,\n renderBoundedFrameLayout,\n runCustomInteraction,\n sanitizeTerminalText,\n} from \"@narumitw/pi-tui-kit\";\nimport type { SubagentSettings } from \"./settings.js\";\n\ninterface SubagentSettingsUIOptions {\n signal: AbortSignal;\n isCurrent(): boolean;\n get(): SubagentSettings;\n save(key: keyof SubagentSettings, value: boolean, signal: AbortSignal): Promise<SubagentSettings>;\n apply(settings: SubagentSettings): void;\n}\n\ntype CloseReason = \"back\" | \"close\" | \"stale\";\n\nconst SETTINGS: { key: keyof SubagentSettings; label: string; description: string }[] = [\n { key: \"showWidget\", label: \"Show widget\", description: \"Show subagent jobs above the editor.\" },\n { key: \"showJobId\", label: \"Show job ID\", description: \"Show job IDs in the widget.\" },\n { key: \"showTools\", label: \"Show tools\", description: \"Show active tools in the widget.\" },\n { key: \"showTiming\", label: \"Show timing\", description: \"Show job timing in the widget.\" },\n];\n\nexport async function showSubagentSettings(\n ctx: ExtensionCommandContext,\n options: SubagentSettingsUIOptions,\n): Promise<CloseReason> {\n const result = await runCustomInteraction<CloseReason>(ctx, {\n signal: options.signal,\n isCurrent: options.isCurrent,\n // The command owner reports interaction failures and non-TUI settings paths.\n onError: () => {},\n create({ tui, theme, signal, complete }) {\n let queue = Promise.resolve();\n const current = () => !signal.aborted && options.isCurrent();\n const revisions = new Map<string, number>();\n const pending = new Map<string, number>();\n const mouseRows = new Map<number, number>();\n let renderedWidth = 0;\n let contentHeight = 0;\n let mousePressed = false;\n const reportFailure = (message: string) => {\n if (!current()) return;\n try {\n ctx.ui.notify(sanitizeTerminalText(`Could not save pi-subagents.json: ${message}`), \"error\");\n } catch {\n // The host can dispose its notifier after the ownership check.\n }\n };\n const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg(\"border\", text) });\n // Keep native SettingsList semantics, but use this screen's callback theme.\n const listTheme = {\n ...getSettingsListTheme(),\n label: (text: string, selected: boolean) => (selected ? theme.fg(\"accent\", text) : text),\n value: (text: string, selected: boolean) => theme.fg(selected ? \"accent\" : \"muted\", text),\n description: (text: string) => theme.fg(\"dim\", text),\n cursor: theme.fg(\"accent\", \"\u2192 \"),\n hint: (text: string) => theme.fg(\"dim\", text),\n };\n const initial = options.get();\n const items: SettingItem[] = SETTINGS.map(({ key, label, description }) => ({\n id: key,\n label,\n description,\n currentValue: String(initial[key]),\n values: [\"true\", \"false\"],\n }));\n const list = new SettingsList(\n items,\n items.length,\n listTheme,\n (id, value) => {\n if (!current()) return;\n const key = id as keyof SubagentSettings;\n const revision = (revisions.get(id) ?? 0) + 1;\n revisions.set(id, revision);\n pending.set(id, revision);\n queue = queue\n .then(async () => {\n if (!current()) {\n complete(\"stale\");\n return;\n }\n const before = { ...options.get() };\n let effective = before;\n try {\n const settings = await options.save(key, value === \"true\", signal);\n // A successful rename is durable, even when closing aborted the save signal.\n if (!options.isCurrent()) {\n complete(\"stale\");\n return;\n }\n options.apply(settings);\n effective = options.get();\n } catch (error) {\n if (!options.isCurrent()) {\n complete(\"stale\");\n return;\n }\n let message = error instanceof Error ? error.message : String(error);\n try {\n options.apply(before);\n } catch (rollbackError) {\n message += `; could not restore effective settings: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;\n }\n reportFailure(message);\n }\n if (!current()) return;\n if (pending.get(id) === revision) pending.delete(id);\n // Saving rereads the full document, including unrelated manual edits. Keep newer\n // optimistic choices, but refresh every row with no outstanding user change.\n for (const { key: settingKey } of SETTINGS) {\n if (!pending.has(settingKey)) list.updateValue(settingKey, String(effective[settingKey]));\n }\n tui.requestRender();\n })\n .catch((error: unknown) => {\n // A failed action must not prevent later requests from entering the queue.\n reportFailure(error instanceof Error ? error.message : String(error));\n });\n },\n () => complete(\"back\"),\n );\n return {\n get capturesViewportInput() {\n return list.capturesViewportInput;\n },\n render(width: number) {\n if (!current()) complete(\"stale\");\n renderedWidth = Number.isFinite(width) ? Math.max(0, Math.floor(width)) : 0;\n listTheme.cursor = theme.fg(\"accent\", \"\u2192 \");\n // The native footer hardcodes keys. Advertise only the hard-cancel key owned here;\n // configured native navigation, change, and Back actions remain unchanged.\n const content = list.render(Math.max(4, renderedWidth)).slice(0, -2);\n contentHeight = content.length;\n const focusedRow = content.findIndex((line) => stripVTControlCharacters(line).startsWith(\"\u2192\"));\n mouseRows.clear();\n\n const terminalRows = Number.isFinite(tui.terminal.rows) ? Math.floor(tui.terminal.rows) : 24;\n const frame = renderBoundedFrameLayout({\n width: renderedWidth,\n maxRows: Math.max(1, terminalRows - 3),\n rule: rule.render(renderedWidth)[0] ?? \"\",\n title: new Text(theme.fg(\"accent\", theme.bold(\"Subagents Settings\")), 0, 0).render(renderedWidth),\n context: [theme.fg(\"muted\", \"Saved changes apply immediately.\")],\n content,\n hints: new Text(theme.fg(\"muted\", \"Ctrl+C close\"), 0, 0).render(renderedWidth),\n priorityRows: focusedRow < 0 ? [] : [focusedRow],\n focusedRow,\n });\n for (const { frameIndex, contentIndex } of frame.contentRows) mouseRows.set(frameIndex, contentIndex);\n return frame.lines;\n },\n invalidate() {\n mouseRows.clear();\n mousePressed = false;\n list.invalidate();\n },\n handleInput(data: string) {\n if (!current()) return complete(\"stale\");\n mouseRows.clear();\n mousePressed = false;\n if (matchesKey(data, Key.ctrl(\"c\"))) complete(\"close\");\n else {\n // SettingsList uses Pi's effective native keybindings for standard actions.\n list.handleInput(data);\n }\n tui.requestRender();\n },\n handleMouse(event: TuiMouseEvent) {\n if (!current()) {\n complete(\"stale\");\n return;\n }\n const nativeRow = mouseRows.get(event.y);\n if (nativeRow === undefined || event.x < 0 || event.x >= renderedWidth) {\n if (event.button === \"left\" && (event.type === \"press\" || event.type === \"click\")) mousePressed = false;\n return;\n }\n const nativeEvent = { ...event, y: nativeRow, width: renderedWidth, height: contentHeight };\n if (event.type === \"click\" && event.button === \"left\" && !mousePressed) {\n list.handleMouse({ ...nativeEvent, type: \"press\" });\n }\n const result = list.handleMouse(nativeEvent);\n if (event.type === \"press\" && event.button === \"left\") mousePressed = result?.handled === true;\n if (event.type === \"click\" || event.type === \"wheel\") mousePressed = false;\n if (result?.handled && result.render !== false) tui.requestRender();\n return result;\n },\n waitForPending() {\n return queue;\n },\n dispose() {\n mouseRows.clear();\n mousePressed = false;\n },\n };\n },\n });\n if (result.kind === \"error\") throw result.error;\n return result.kind === \"completed\" ? result.value : result.kind === \"unsupported\" ? \"back\" : \"stale\";\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["result"]
|
|
7
7
|
}
|
package/dist/index.ts
CHANGED
|
@@ -53,7 +53,7 @@ function sanitizeSubagentDisplayText(value) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// src/message-renderers.ts
|
|
56
|
-
import { getMarkdownTheme
|
|
56
|
+
import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
|
|
57
57
|
import { Box, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
|
|
58
58
|
var COMPLETION_MESSAGE_TYPE = "pi-subagents-completion";
|
|
59
59
|
var BROKER_MESSAGE_TYPE = "pi-subagents-message";
|
|
@@ -82,13 +82,9 @@ function registerMessageRenderers(pi) {
|
|
|
82
82
|
new Spacer(1)
|
|
83
83
|
];
|
|
84
84
|
if (!options.expanded) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
0,
|
|
89
|
-
0
|
|
90
|
-
)
|
|
91
|
-
);
|
|
85
|
+
const expansionKey = options.keyText?.("app.tools.expand");
|
|
86
|
+
const hint = expansionKey ? theme.fg("muted", ` (${expansionKey} to expand)`) : "";
|
|
87
|
+
children.push(new Text(theme.fg("customMessageText", summary) + hint, 0, 0));
|
|
92
88
|
} else {
|
|
93
89
|
const content = typeof message.content === "string" ? message.content : message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
94
90
|
children.push(
|
|
@@ -2258,9 +2254,11 @@ var SpawnParameters = Type.Object(
|
|
|
2258
2254
|
),
|
|
2259
2255
|
tools: Type.Optional(
|
|
2260
2256
|
Type.Array(
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2257
|
+
Type.Unsafe(
|
|
2258
|
+
StringEnum(CHILD_CORE_TOOL_NAMES, {
|
|
2259
|
+
description: "Available Pi core child work tool name."
|
|
2260
|
+
})
|
|
2261
|
+
),
|
|
2264
2262
|
{
|
|
2265
2263
|
description: "Child work tools. Defaults to read, grep, find, and ls. Communication tools are always added.",
|
|
2266
2264
|
maxItems: MAX_TOOLS
|
|
@@ -2310,9 +2308,11 @@ var SpawnParameters = Type.Object(
|
|
|
2310
2308
|
)
|
|
2311
2309
|
),
|
|
2312
2310
|
thinkingLevel: Type.Optional(
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2311
|
+
Type.Unsafe(
|
|
2312
|
+
StringEnum(SUBAGENT_THINKING_LEVELS, {
|
|
2313
|
+
description: "Child thinking level. Defaults to the main agent's effective level."
|
|
2314
|
+
})
|
|
2315
|
+
)
|
|
2316
2316
|
),
|
|
2317
2317
|
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" }))
|
|
2318
2318
|
},
|
|
@@ -2663,10 +2663,34 @@ var SUBAGENT_WIDGET_MAX_ROWS = 10;
|
|
|
2663
2663
|
function subagentWidgetRowBudget(rows) {
|
|
2664
2664
|
return Number.isFinite(rows) ? Math.min(SUBAGENT_WIDGET_MAX_ROWS, Math.max(0, Math.floor(rows) - SUBAGENT_WIDGET_RESERVED_ROWS)) : 0;
|
|
2665
2665
|
}
|
|
2666
|
-
function
|
|
2666
|
+
function subagentWidgetSummary(snapshot, maxRows) {
|
|
2667
|
+
const { jobs, items, mode } = snapshot;
|
|
2668
|
+
const budget = normalizeRowBudget(maxRows);
|
|
2669
|
+
if (!isVisible(snapshot) || budget === 0) return "";
|
|
2670
|
+
const shown = mode === "compact" ? items.length : Math.min(items.length, budget - 1);
|
|
2671
|
+
const omitted = jobs.length - shown;
|
|
2672
|
+
const removed = jobs.length - items.length;
|
|
2673
|
+
const running = jobs.filter((job) => job.state === "running").length;
|
|
2674
|
+
const counts = `${running} running \xB7 ${jobs.length - running} queued`;
|
|
2675
|
+
return `${counts}${omitted > 0 ? ` \xB7 ${omitted} not shown${removed > 0 ? ` (${removed} removed)` : ""}` : ""}`;
|
|
2676
|
+
}
|
|
2677
|
+
function normalizeRowBudget(maxRows) {
|
|
2678
|
+
return Number.isFinite(maxRows) ? Math.max(0, Math.floor(maxRows)) : 0;
|
|
2679
|
+
}
|
|
2680
|
+
function isVisible({ jobs, items, settings, mode }) {
|
|
2681
|
+
return settings.showWidget && mode !== "hidden" && jobs.length > 0 && items.length > 0;
|
|
2682
|
+
}
|
|
2683
|
+
function renderSubagentWidgetSnapshot(snapshot, theme, width, maxRows, includeHeader = true) {
|
|
2667
2684
|
const { jobs, items, settings, mode } = snapshot;
|
|
2668
|
-
const budget =
|
|
2669
|
-
if (!
|
|
2685
|
+
const budget = normalizeRowBudget(maxRows);
|
|
2686
|
+
if (!isVisible(snapshot) || budget < (includeHeader ? 2 : 1)) return [];
|
|
2687
|
+
if (!includeHeader) {
|
|
2688
|
+
const shown = mode === "compact" ? [] : items.slice(0, budget - 1);
|
|
2689
|
+
return new EditorStatusWidget({
|
|
2690
|
+
theme,
|
|
2691
|
+
renderBody: () => shown.map(({ value, mode: itemMode }) => renderJob(value, theme, settings, itemMode === "compact"))
|
|
2692
|
+
}).render(width);
|
|
2693
|
+
}
|
|
2670
2694
|
const running = jobs.filter((job) => job.state === "running").length;
|
|
2671
2695
|
const counts = `Subagents \xB7 ${jobs.length} active \xB7 ${running} running \xB7 ${jobs.length - running} queued`;
|
|
2672
2696
|
const removed = jobs.length - items.length;
|
|
@@ -2842,9 +2866,11 @@ function createSubagentWidgetController(runtime) {
|
|
|
2842
2866
|
view = createEditorStatusView({ onChange: publish, canCompact: () => settings.showWidget && jobs.length > 0 });
|
|
2843
2867
|
publisher = createEditorStatusPublisher({
|
|
2844
2868
|
key: SUBAGENT_WIDGET_KEY,
|
|
2869
|
+
name: "Subagents",
|
|
2845
2870
|
context: ctx,
|
|
2846
2871
|
isCurrent,
|
|
2847
|
-
|
|
2872
|
+
summary: (snapshot, _width, rows) => subagentWidgetSummary(snapshot, subagentWidgetRowBudget(rows)),
|
|
2873
|
+
render: (snapshot, theme, width, rows) => renderSubagentWidgetSnapshot(snapshot, theme, width, subagentWidgetRowBudget(rows), false)
|
|
2848
2874
|
});
|
|
2849
2875
|
if (phase === "maintenance") cyclePhase = phase;
|
|
2850
2876
|
else if (phase !== "idle") startCycle(phase);
|
|
@@ -2853,7 +2879,9 @@ function createSubagentWidgetController(runtime) {
|
|
|
2853
2879
|
controls = {
|
|
2854
2880
|
state: () => ({ mode: ownedView.mode, pinned: ownedView.pinned, trigger: ownedView.trigger }),
|
|
2855
2881
|
setMode: (mode) => {
|
|
2856
|
-
if (isCurrent())
|
|
2882
|
+
if (!isCurrent()) return;
|
|
2883
|
+
if (mode !== "hidden") publisher?.setCollapsed(false);
|
|
2884
|
+
ownedView.setMode(mode);
|
|
2857
2885
|
},
|
|
2858
2886
|
setPinned: (pinned) => {
|
|
2859
2887
|
if (isCurrent()) ownedView.setPinned(pinned);
|
|
@@ -2973,7 +3001,7 @@ function subagents(pi, dependencies = {}) {
|
|
|
2973
3001
|
ctx.ui.notify(sanitizeSubagentDisplayText(`Edit user settings: ${store.userPath}. Then run /reload.`), "info");
|
|
2974
3002
|
return "back";
|
|
2975
3003
|
}
|
|
2976
|
-
const { showSubagentSettings } = await import("./chunks/settings-ui-
|
|
3004
|
+
const { showSubagentSettings } = await import("./chunks/settings-ui-KOX3DMZP.ts");
|
|
2977
3005
|
if (signal.aborted || !isCurrent()) return "stale";
|
|
2978
3006
|
return showSubagentSettings(ctx, {
|
|
2979
3007
|
signal,
|