@yusukeshib/pi-babysit 0.6.24 → 0.6.26
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/README.md +10 -4
- package/index.ts +57 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -167,10 +167,12 @@ sessions, and click again to return to running-only. Both modes show newest firs
|
|
|
167
167
|
ten per page; `< 1/4 >` shows the current/total page when needed. Click the
|
|
168
168
|
arrows to page. Rows occupy one line, previewing the description (or the command
|
|
169
169
|
for older processes and task for older agents), with `…` when clipped. Click an
|
|
170
|
-
AGENT or PROCESS row to
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
AGENT or PROCESS row to expand a **log viewer directly below that row**. The summary
|
|
171
|
+
title, list header, and all other rows remain visible with their original colors.
|
|
172
|
+
Only one row is expanded at a time; selecting another closes the previous one.
|
|
173
|
+
The viewer is capped at ten lines including its existing row header and footer;
|
|
174
|
+
all saved history remains available by scrolling. Click the same row again to
|
|
175
|
+
collapse it, preserving the list's mode and page.
|
|
174
176
|
There is no separate Close button or Esc binding. The viewer uses Pi's `ScrollView` for
|
|
175
177
|
scroll position and follow behavior, with a widget-local scrollbar styled using
|
|
176
178
|
Pi's scrollbar theme. Wheel, scrollbar drag/track clicks, and ↑/↓ navigate the
|
|
@@ -233,6 +235,10 @@ targeted pattern over a broad tail, and do not read a potentially large log file
|
|
|
233
235
|
in full. Subagent crashes return structured errors plus the full log path, never
|
|
234
236
|
a raw RPC JSON tail.
|
|
235
237
|
|
|
238
|
+
Subagents run in RPC mode with normal Pi session persistence enabled, using
|
|
239
|
+
Pi's configured session storage (by default `~/.pi/agent/sessions/`). Each worker
|
|
240
|
+
has its own Pi session, separate from the parent and from babysit's output log.
|
|
241
|
+
|
|
236
242
|
Subagent logs compact Pi's streaming `message_update` events before they are
|
|
237
243
|
recorded. Pi repeats the complete growing assistant message and partial snapshot
|
|
238
244
|
on every token; pi-babysit retains only the incremental delta. Compact RPC
|
package/index.ts
CHANGED
|
@@ -2319,7 +2319,7 @@ async function spawnSubagent(
|
|
|
2319
2319
|
// Long-lived RPC worker: the task is NOT passed as argv — it is injected
|
|
2320
2320
|
// below as an RPC `prompt` command, whose response we validate so spawn
|
|
2321
2321
|
// failures (bad model, missing API key) are loud instead of a silent exit=1.
|
|
2322
|
-
const piArgs: string[] = ["--mode", "rpc"
|
|
2322
|
+
const piArgs: string[] = ["--mode", "rpc"];
|
|
2323
2323
|
const model = opts.model ?? opts.agent?.model;
|
|
2324
2324
|
if (model) piArgs.push("--model", model);
|
|
2325
2325
|
const tools = opts.tools ?? opts.agent?.tools;
|
|
@@ -2625,7 +2625,7 @@ interface WidgetMouseEvent {
|
|
|
2625
2625
|
}
|
|
2626
2626
|
|
|
2627
2627
|
/**
|
|
2628
|
-
* Compact session list. Item presses
|
|
2628
|
+
* Compact session list. Item presses toggle the session's inline viewer.
|
|
2629
2629
|
*/
|
|
2630
2630
|
export function createWidgetComponent(
|
|
2631
2631
|
summaryLines: string[],
|
|
@@ -2683,6 +2683,9 @@ export function createWidgetComponent(
|
|
|
2683
2683
|
}
|
|
2684
2684
|
return lines;
|
|
2685
2685
|
},
|
|
2686
|
+
getSessionLine(id: string) {
|
|
2687
|
+
return targetByLine.findIndex((target) => target?.type === "session" && target.id === id);
|
|
2688
|
+
},
|
|
2686
2689
|
handleMouse(event: WidgetMouseEvent) {
|
|
2687
2690
|
if (event.button !== "left") return undefined;
|
|
2688
2691
|
const target = targetByLine[event.y];
|
|
@@ -2727,7 +2730,19 @@ export function createSessionWidget(options: {
|
|
|
2727
2730
|
let displays: WidgetSessionDisplay[] = [];
|
|
2728
2731
|
let viewer: ReturnType<typeof createLogViewer> | undefined;
|
|
2729
2732
|
let source: FileLogSource | undefined;
|
|
2730
|
-
let
|
|
2733
|
+
let summaryLines: string[] = [];
|
|
2734
|
+
let listHeight = 0;
|
|
2735
|
+
let viewerRow = -1;
|
|
2736
|
+
let viewerLines = 0;
|
|
2737
|
+
let dragging = false;
|
|
2738
|
+
let list = createWidgetComponent([], [], toggle, listState);
|
|
2739
|
+
function rebuildList() {
|
|
2740
|
+
list = createWidgetComponent(summaryLines, displays, toggle, listState);
|
|
2741
|
+
}
|
|
2742
|
+
function toggle(id: string) {
|
|
2743
|
+
if (selectedId === id) close();
|
|
2744
|
+
else open(id);
|
|
2745
|
+
}
|
|
2731
2746
|
function refreshViewer() {
|
|
2732
2747
|
if (!selectedId || !viewer) return;
|
|
2733
2748
|
const log = options.readLog(selectedId);
|
|
@@ -2747,18 +2762,30 @@ export function createSessionWidget(options: {
|
|
|
2747
2762
|
}
|
|
2748
2763
|
function close() {
|
|
2749
2764
|
selectedId = undefined;
|
|
2765
|
+
viewerRow = -1;
|
|
2766
|
+
viewerLines = 0;
|
|
2767
|
+
dragging = false;
|
|
2750
2768
|
viewer?.dispose();
|
|
2751
2769
|
viewer = undefined;
|
|
2752
2770
|
source = undefined;
|
|
2753
2771
|
options.requestRender();
|
|
2754
2772
|
}
|
|
2755
2773
|
function open(id: string) {
|
|
2774
|
+
if (!displays.some((session) => session.id === id)) {
|
|
2775
|
+
displays = [...displays, { id, header: id, tail: [], viewable: true, active: true }];
|
|
2776
|
+
}
|
|
2777
|
+
if (listState.mode === "running" && !displays.find((session) => session.id === id)?.active)
|
|
2778
|
+
listState.mode = "all";
|
|
2779
|
+
const visible = listState.mode === "running" ? displays.filter((session) => session.active) : displays;
|
|
2780
|
+
listState.page = Math.floor(visible.findIndex((session) => session.id === id) / WIDGET_SESSION_PAGE_SIZE);
|
|
2781
|
+
rebuildList();
|
|
2782
|
+
dragging = false;
|
|
2756
2783
|
viewer?.dispose();
|
|
2757
2784
|
source = undefined;
|
|
2758
2785
|
selectedId = id;
|
|
2759
2786
|
viewer = createLogViewer({
|
|
2760
2787
|
...options,
|
|
2761
|
-
getHeight: () => Math.min(WIDGET_VIEWER_MAX_LINES, options.getHeight()),
|
|
2788
|
+
getHeight: () => Math.max(3, Math.min(WIDGET_VIEWER_MAX_LINES, options.getHeight() - listHeight + 1)),
|
|
2762
2789
|
onClose: close,
|
|
2763
2790
|
});
|
|
2764
2791
|
refreshViewer();
|
|
@@ -2774,15 +2801,36 @@ export function createSessionWidget(options: {
|
|
|
2774
2801
|
},
|
|
2775
2802
|
update(summary: string[], sessions: WidgetSessionDisplay[]) {
|
|
2776
2803
|
displays = sessions;
|
|
2777
|
-
|
|
2804
|
+
summaryLines = summary;
|
|
2805
|
+
rebuildList();
|
|
2806
|
+
if (selectedId && !sessions.some((session) => session.id === selectedId && (listState.mode === "all" || session.active))) close();
|
|
2778
2807
|
refreshViewer();
|
|
2779
2808
|
options.requestRender();
|
|
2780
2809
|
},
|
|
2781
|
-
render(width: number) {
|
|
2810
|
+
render(width: number) {
|
|
2811
|
+
const lines = list.render(width);
|
|
2812
|
+
listHeight = lines.length;
|
|
2813
|
+
viewerRow = selectedId ? list.getSessionLine(selectedId) : -1;
|
|
2814
|
+
viewerLines = 0;
|
|
2815
|
+
if (viewer && viewerRow >= 0) {
|
|
2816
|
+
// Keep the original styled row as the toggle header.
|
|
2817
|
+
const body = viewer.render(width).slice(1);
|
|
2818
|
+
viewerLines = body.length;
|
|
2819
|
+
lines.splice(viewerRow + 1, 0, ...body);
|
|
2820
|
+
}
|
|
2821
|
+
return lines;
|
|
2822
|
+
},
|
|
2782
2823
|
handleMouse(event: TuiMouseEvent) {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2824
|
+
if (viewer && viewerRow >= 0 && (dragging || (event.y > viewerRow && event.y <= viewerRow + viewerLines))) {
|
|
2825
|
+
const result = viewer.handleMouse({ ...event, y: event.y - viewerRow });
|
|
2826
|
+
if (result && "capture" in result && result.capture) dragging = true;
|
|
2827
|
+
if (event.type === "release") dragging = false;
|
|
2828
|
+
return result;
|
|
2829
|
+
}
|
|
2830
|
+
const mode = listState.mode, page = listState.page;
|
|
2831
|
+
const result = list.handleMouse({ ...event, y: event.y > viewerRow && viewerRow >= 0 ? event.y - viewerLines : event.y });
|
|
2832
|
+
if (mode !== listState.mode || page !== listState.page) close();
|
|
2833
|
+
return result;
|
|
2786
2834
|
},
|
|
2787
2835
|
handleKey(data: string) { return viewer?.handleKey(data) ?? false; },
|
|
2788
2836
|
invalidate() { list.invalidate(); viewer?.invalidate(); },
|