@dougbots/avenor-pi 0.7.1 → 0.8.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.
- package/dist/index.d.ts +6 -0
- package/dist/index.js +54 -9
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ interface RunStatusEntry {
|
|
|
11
11
|
agent: string;
|
|
12
12
|
pendingPermission?: boolean;
|
|
13
13
|
permissionDescription?: string;
|
|
14
|
+
/** OS PID of the spawned pi process (pi backend only), for discovering child supervisors. */
|
|
15
|
+
pid?: number;
|
|
16
|
+
/** Backend type, used to determine whether to look for child supervisors. */
|
|
17
|
+
backend?: string;
|
|
18
|
+
/** Count of active (non-terminal) runs on this run's child supervisor, if discovered. */
|
|
19
|
+
nestedCount?: number;
|
|
14
20
|
}
|
|
15
21
|
//#endregion
|
|
16
22
|
//#region src/index.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Input, Key, Text, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
|
-
import
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { Supervisor, answerPermissionTool, dial, eventsTool, followUpTool, inspectTool, observeRun, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool } from "@dougbots/avenor-core";
|
|
4
5
|
//#region src/watch.ts
|
|
5
6
|
const ANSI_PATTERN = /[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[a-zA-Z\d]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g;
|
|
6
7
|
const TRANSCRIPT_SCROLL_STEP = 4;
|
|
@@ -653,7 +654,8 @@ function renderStatusLines(entries) {
|
|
|
653
654
|
const emoji = statusEmoji(e.status);
|
|
654
655
|
const perm = e.pendingPermission ? " 🔒" : "";
|
|
655
656
|
const phase = e.phaseLabel ? ` [${e.phaseLabel}]` : "";
|
|
656
|
-
|
|
657
|
+
const nested = e.nestedCount ? ` +${e.nestedCount}` : "";
|
|
658
|
+
return `${emoji} ${e.label} — ${e.status}${phase}${perm}${nested}`;
|
|
657
659
|
});
|
|
658
660
|
}
|
|
659
661
|
function compactWhitespace(text, limit = 100) {
|
|
@@ -756,6 +758,29 @@ function createExtension(deps = defaultDeps) {
|
|
|
756
758
|
return;
|
|
757
759
|
}
|
|
758
760
|
}
|
|
761
|
+
/**
|
|
762
|
+
* Count active (non-terminal) runs on a child supervisor discovered via
|
|
763
|
+
* the spawned pi process's PID. The child pi process creates its own
|
|
764
|
+
* avenor supervisor at `avenor-mcp-<pid>.sock`; we dial it briefly to
|
|
765
|
+
* list runs and count those still active. Returns 0 on any failure
|
|
766
|
+
* (socket not yet ready, supervisor idle-shut-down, etc.).
|
|
767
|
+
*/
|
|
768
|
+
async function countNestedRuns(pid) {
|
|
769
|
+
if (!pid) return 0;
|
|
770
|
+
const socketPath = path.join(socketsRoot(), `avenor-mcp-${pid}.sock`);
|
|
771
|
+
let client;
|
|
772
|
+
try {
|
|
773
|
+
client = await Promise.race([deps.dial(socketPath, { callTimeoutMs: 2e3 }), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("dial timeout")), 2e3))]);
|
|
774
|
+
return (await client.list()).filter((r) => {
|
|
775
|
+
const status = String(r.status ?? "running").toLowerCase();
|
|
776
|
+
return status === "running" || status === "idle";
|
|
777
|
+
}).length;
|
|
778
|
+
} catch {
|
|
779
|
+
return 0;
|
|
780
|
+
} finally {
|
|
781
|
+
client?.close();
|
|
782
|
+
}
|
|
783
|
+
}
|
|
759
784
|
async function pollRuns() {
|
|
760
785
|
const liveMap = /* @__PURE__ */ new Map();
|
|
761
786
|
try {
|
|
@@ -779,7 +804,9 @@ function createExtension(deps = defaultDeps) {
|
|
|
779
804
|
phaseLabel: live.phase_label,
|
|
780
805
|
agent: run.agent,
|
|
781
806
|
pendingPermission: !!live.pending_permission,
|
|
782
|
-
permissionDescription: live.pending_permission?.description
|
|
807
|
+
permissionDescription: live.pending_permission?.description,
|
|
808
|
+
pid: live.pid,
|
|
809
|
+
backend: live.backend
|
|
783
810
|
});
|
|
784
811
|
continue;
|
|
785
812
|
}
|
|
@@ -799,7 +826,9 @@ function createExtension(deps = defaultDeps) {
|
|
|
799
826
|
phaseLabel: result.phase_label,
|
|
800
827
|
agent: run.agent,
|
|
801
828
|
pendingPermission: !!result.pending_permission,
|
|
802
|
-
permissionDescription: result.pending_permission?.description
|
|
829
|
+
permissionDescription: result.pending_permission?.description,
|
|
830
|
+
pid: result.pid,
|
|
831
|
+
backend: result.backend
|
|
803
832
|
});
|
|
804
833
|
} catch (err) {
|
|
805
834
|
console.error(`avenor pollRuns: statusTool failed for ${run.runId}`, err);
|
|
@@ -812,7 +841,9 @@ function createExtension(deps = defaultDeps) {
|
|
|
812
841
|
phaseLabel: previous?.phase_label,
|
|
813
842
|
agent: run.agent,
|
|
814
843
|
pendingPermission: !!previous?.pending_permission,
|
|
815
|
-
permissionDescription: previous?.pending_permission?.description
|
|
844
|
+
permissionDescription: previous?.pending_permission?.description,
|
|
845
|
+
pid: previous?.pid,
|
|
846
|
+
backend: previous?.backend
|
|
816
847
|
});
|
|
817
848
|
}
|
|
818
849
|
}
|
|
@@ -824,8 +855,16 @@ function createExtension(deps = defaultDeps) {
|
|
|
824
855
|
phaseLabel: live.phase_label,
|
|
825
856
|
agent: live.agent ?? "unknown",
|
|
826
857
|
pendingPermission: !!live.pending_permission,
|
|
827
|
-
permissionDescription: live.pending_permission?.description
|
|
858
|
+
permissionDescription: live.pending_permission?.description,
|
|
859
|
+
pid: live.pid,
|
|
860
|
+
backend: live.backend
|
|
828
861
|
});
|
|
862
|
+
const nestedPids = entries.filter((e) => e.backend === "pi" && e.pid && !isTerminalStatus(e.status)).map((e) => e.pid);
|
|
863
|
+
if (nestedPids.length > 0) {
|
|
864
|
+
const nestedCounts = await Promise.all(nestedPids.map((pid) => countNestedRuns(pid)));
|
|
865
|
+
let idx = 0;
|
|
866
|
+
for (const entry of entries) if (entry.backend === "pi" && entry.pid && !isTerminalStatus(entry.status)) entry.nestedCount = nestedCounts[idx++] ?? 0;
|
|
867
|
+
}
|
|
829
868
|
return entries;
|
|
830
869
|
}
|
|
831
870
|
function updateWidget(entries) {
|
|
@@ -833,7 +872,11 @@ function createExtension(deps = defaultDeps) {
|
|
|
833
872
|
const lines = renderStatusLines(entries);
|
|
834
873
|
if (lines.length > 0) {
|
|
835
874
|
sessionCtx.ui.setWidget("avenor-status", lines);
|
|
836
|
-
|
|
875
|
+
const statusStr = lines.map((line) => line.slice(0, 60)).join(" ");
|
|
876
|
+
const nestedTotal = entries.filter((e) => !isTerminalStatus(e.status)).reduce((sum, e) => sum + (e.nestedCount ?? 0), 0);
|
|
877
|
+
const total = lines.length + nestedTotal;
|
|
878
|
+
const statusWithTotal = nestedTotal > 0 ? `${statusStr} total:${total}` : statusStr;
|
|
879
|
+
sessionCtx.ui.setStatus("avenor", statusWithTotal);
|
|
837
880
|
} else {
|
|
838
881
|
sessionCtx.ui.setWidget("avenor-status", void 0);
|
|
839
882
|
sessionCtx.ui.setStatus("avenor", "");
|
|
@@ -1415,14 +1458,16 @@ function createExtension(deps = defaultDeps) {
|
|
|
1415
1458
|
run_id: Type.String({ description: "Run ID with the pending permission" }),
|
|
1416
1459
|
option_id: Type.String({ description: "allow_once | allow_always | deny" }),
|
|
1417
1460
|
request_id: Type.Optional(Type.String({ description: "Permission request ID (auto-discovered if omitted)" })),
|
|
1418
|
-
supervisor_id: Type.Optional(Type.String({ description: "Reuse an existing supervisor by socket path" }))
|
|
1461
|
+
supervisor_id: Type.Optional(Type.String({ description: "Reuse an existing supervisor by socket path" })),
|
|
1462
|
+
message: Type.Optional(Type.String({ description: "Optional write-in response text. Required only when the selected option declares requiresMessage: true." }))
|
|
1419
1463
|
}),
|
|
1420
1464
|
async execute(_toolCallId, params) {
|
|
1421
1465
|
const result = await deps.answerPermissionTool({
|
|
1422
1466
|
runId: params.run_id,
|
|
1423
1467
|
optionId: params.option_id,
|
|
1424
1468
|
requestId: params.request_id,
|
|
1425
|
-
supervisorId: params.supervisor_id
|
|
1469
|
+
supervisorId: params.supervisor_id,
|
|
1470
|
+
message: params.message
|
|
1426
1471
|
});
|
|
1427
1472
|
return {
|
|
1428
1473
|
content: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dougbots/avenor-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dev": "tsdown --watch"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@dougbots/avenor-core": "^0.
|
|
38
|
+
"@dougbots/avenor-core": "^0.8.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@earendil-works/pi-coding-agent": "*",
|