pi-daddy 0.48.3 → 0.49.0
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 +7 -0
- package/README.md +53 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/kernel/selected-definitions.d.ts.map +1 -1
- package/dist/kernel/selected-definitions.js +6 -3
- package/dist/kernel/selected-definitions.js.map +1 -1
- package/dist/products/dashboard-cli.d.ts.map +1 -1
- package/dist/products/dashboard-cli.js +46 -1
- package/dist/products/dashboard-cli.js.map +1 -1
- package/dist/products/dashboard-display-controls.d.ts +1 -1
- package/dist/products/dashboard-display-controls.d.ts.map +1 -1
- package/dist/products/dashboard-display-controls.js +11 -3
- package/dist/products/dashboard-display-controls.js.map +1 -1
- package/dist/products/dashboard-screen.d.ts +3 -1
- package/dist/products/dashboard-screen.d.ts.map +1 -1
- package/dist/products/dashboard-screen.js +21 -8
- package/dist/products/dashboard-screen.js.map +1 -1
- package/dist/products/dashboard-session-client.d.ts +9 -0
- package/dist/products/dashboard-session-client.d.ts.map +1 -1
- package/dist/products/dashboard-session-client.js.map +1 -1
- package/dist/products/dashboard-settings.d.ts +28 -0
- package/dist/products/dashboard-settings.d.ts.map +1 -0
- package/dist/products/dashboard-settings.js +42 -0
- package/dist/products/dashboard-settings.js.map +1 -0
- package/dist/products/diagnostic-export.d.ts +23 -0
- package/dist/products/diagnostic-export.d.ts.map +1 -0
- package/dist/products/diagnostic-export.js +264 -0
- package/dist/products/diagnostic-export.js.map +1 -0
- package/dist/products/diagnostic-filter.d.ts +7 -0
- package/dist/products/diagnostic-filter.d.ts.map +1 -0
- package/dist/products/diagnostic-filter.js +135 -0
- package/dist/products/diagnostic-filter.js.map +1 -0
- package/extensions/dashboard-session-server.ts +17 -2
- package/extensions/dashboard-settings.ts +149 -0
- package/extensions/delegation-operations.ts +81 -2
- package/extensions/execute-child.ts +9 -11
- package/extensions/execution-controls.ts +7 -2
- package/extensions/grants-command.ts +3 -1
- package/extensions/grants.ts +3 -0
- package/extensions/reload-environment.ts +3 -0
- package/extensions/run-delegation.ts +3 -1
- package/extensions/runtime-snapshot.ts +9 -1
- package/package.json +1 -1
- package/src/cli.ts +24 -1
- package/src/index.ts +2 -0
- package/src/kernel/selected-definitions.ts +5 -3
- package/src/products/dashboard-cli.ts +38 -1
- package/src/products/dashboard-display-controls.ts +10 -4
- package/src/products/dashboard-screen.ts +21 -10
- package/src/products/dashboard-session-client.ts +7 -1
- package/src/products/dashboard-settings.ts +72 -0
- package/src/products/diagnostic-export.ts +288 -0
- package/src/products/diagnostic-filter.ts +140 -0
|
@@ -5,6 +5,7 @@ import { openRuntimeSettlement, settlementHash } from "../src/governance/runtime
|
|
|
5
5
|
import { reconcileDelegationCapacity } from "./session-capacity.ts";
|
|
6
6
|
import { agentDir } from "../src/kernel/project-paths.ts";
|
|
7
7
|
import type { GrantsSession } from "./session.ts";
|
|
8
|
+
import { bindOperationFinals, operationFinal } from "./delegation-operations.ts";
|
|
8
9
|
export const OPERATION_STATUS_EVENT = "pi-daddy:operation-status:v1";
|
|
9
10
|
export const RUNTIME_SNAPSHOT_EVENT = "pi-daddy:runtime-snapshot:v1";
|
|
10
11
|
export function registerRuntimeSnapshot(
|
|
@@ -99,6 +100,7 @@ export function registerRuntimeSnapshot(
|
|
|
99
100
|
sessionId?: string;
|
|
100
101
|
cwd?: string;
|
|
101
102
|
operationId?: string;
|
|
103
|
+
includeFinal?: boolean;
|
|
102
104
|
reply?: (value: unknown) => void;
|
|
103
105
|
};
|
|
104
106
|
if (
|
|
@@ -139,7 +141,12 @@ export function registerRuntimeSnapshot(
|
|
|
139
141
|
lifecycle.runtimeSnapshotGeneration !== generation
|
|
140
142
|
)
|
|
141
143
|
throw Error("operation owner changed during read");
|
|
142
|
-
request.reply!({
|
|
144
|
+
request.reply!({
|
|
145
|
+
...envelope,
|
|
146
|
+
qualified: true,
|
|
147
|
+
operation,
|
|
148
|
+
...(request.includeFinal === true && operation ? { final: operationFinal(session, operation) } : {}),
|
|
149
|
+
});
|
|
143
150
|
} catch (error) {
|
|
144
151
|
request.reply!({ ...envelope, qualified: false, operation: null, reason: String(error) });
|
|
145
152
|
}
|
|
@@ -172,6 +179,7 @@ export function registerRuntimeSnapshot(
|
|
|
172
179
|
}
|
|
173
180
|
if (sequence !== bindSequence || session.reloadLifecycle !== lifecycle) return;
|
|
174
181
|
lifecycle.runtimeSettlement = runtime;
|
|
182
|
+
bindOperationFinals(session, sessionId, cwd);
|
|
175
183
|
bound = { sessionId, cwd, lifecycle: session.reloadLifecycle };
|
|
176
184
|
} catch (error) {
|
|
177
185
|
if (sequence === bindSequence && session.reloadLifecycle === lifecycle) problem = String(error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-daddy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "Capability governance for pi sub-agents: spawn Agent Skills (SKILL.md) definitions whose allowed-tools becomes a grant that can only narrow going down a delegation tree, enforced by pi's own --tools allowlist, with an append-only ledger.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
package/src/cli.ts
CHANGED
|
@@ -50,6 +50,7 @@ Usage:
|
|
|
50
50
|
pi-daddy report [--since <date>] [--definition <name>] [--model <id>]
|
|
51
51
|
[--group-by definition|model|thinking] [--json]
|
|
52
52
|
pi-daddy outcomes append changed episode outcomes from Git and CI
|
|
53
|
+
pi-daddy diagnostics export <selection.json> <new-directory> private filtered local evidence
|
|
53
54
|
pi-daddy --help | --version
|
|
54
55
|
|
|
55
56
|
init references skills already enabled in Pi at their installed or local paths. Legacy unregistered npm
|
|
@@ -61,8 +62,11 @@ stays unspawnable. Capabilities that can change your machine
|
|
|
61
62
|
It never rewrites ${SETTINGS_REL} — delete that file if you want it regenerated.`;
|
|
62
63
|
|
|
63
64
|
export interface ParsedArgs {
|
|
64
|
-
command:
|
|
65
|
+
command:
|
|
66
|
+
"init" | "ledger-repair" | "ledger-import" | "report" | "outcomes" | "diagnostics-export" | "help" | "version";
|
|
65
67
|
importTarget?: string;
|
|
68
|
+
selectionPath?: string;
|
|
69
|
+
exportDirectory?: string;
|
|
66
70
|
/** `ledger repair <path>`: the ledger file; `yes` applies, otherwise preview only. */
|
|
67
71
|
ledgerPath?: string;
|
|
68
72
|
yes?: boolean;
|
|
@@ -91,6 +95,19 @@ export function parseArgs(argv: string[]): ParsedArgs {
|
|
|
91
95
|
if (args.includes("--version") || args.includes("-v")) return { command: "version", force: false, errors: [] };
|
|
92
96
|
|
|
93
97
|
const [command, ...tail] = args;
|
|
98
|
+
if (command === "diagnostics") {
|
|
99
|
+
const [verb, selectionPath, exportDirectory, ...extra] = tail;
|
|
100
|
+
if (
|
|
101
|
+
verb !== "export" ||
|
|
102
|
+
!selectionPath ||
|
|
103
|
+
!exportDirectory ||
|
|
104
|
+
selectionPath.startsWith("-") ||
|
|
105
|
+
exportDirectory.startsWith("-") ||
|
|
106
|
+
extra.length
|
|
107
|
+
)
|
|
108
|
+
return { command: "help", force: false, errors: ["diagnostics needs: export <selection.json> <new-directory>"] };
|
|
109
|
+
return { command: "diagnostics-export", force: false, errors: [], selectionPath, exportDirectory };
|
|
110
|
+
}
|
|
94
111
|
if (command === "ledger") {
|
|
95
112
|
// ADR-0076 PR 3d: `ledger repair <path> [--yes]` previews, --yes truncates; `ledger import <source> <target>`.
|
|
96
113
|
const [verb, target, ...flags] = tail;
|
|
@@ -388,6 +405,12 @@ export async function main(
|
|
|
388
405
|
console.log(USAGE);
|
|
389
406
|
return 0;
|
|
390
407
|
}
|
|
408
|
+
if (parsed.command === "diagnostics-export") {
|
|
409
|
+
const { exportDiagnostics } = await import("./products/diagnostic-export.ts");
|
|
410
|
+
const result = await exportDiagnostics(parsed.selectionPath!, parsed.exportDirectory!);
|
|
411
|
+
console.log(JSON.stringify(result));
|
|
412
|
+
return result.missing ? 1 : 0;
|
|
413
|
+
}
|
|
391
414
|
if (parsed.command === "outcomes") {
|
|
392
415
|
const cwd = process.cwd();
|
|
393
416
|
const result = await updateEpisodeOutcomes({
|
package/src/index.ts
CHANGED
|
@@ -12,7 +12,8 @@ export interface SelectedCommand {
|
|
|
12
12
|
name: string;
|
|
13
13
|
sourceInfo?: { path?: string };
|
|
14
14
|
}
|
|
15
|
-
const
|
|
15
|
+
const requiredPhases = ["plan", "build", "review", "debug", "investigate"];
|
|
16
|
+
const phases = [...requiredPhases, "test-review"];
|
|
16
17
|
const hash = (value: string) => createHash("sha256").update(value, "utf8").digest("hex");
|
|
17
18
|
const object = (x: unknown): x is Record<string, unknown> => !!x && typeof x === "object" && !Array.isArray(x);
|
|
18
19
|
const exact = (x: Record<string, unknown>, keys: string[]) =>
|
|
@@ -57,10 +58,10 @@ async function principalBinding(
|
|
|
57
58
|
manifest.version !== 1 ||
|
|
58
59
|
manifest.package !== "principal-pi-skills" ||
|
|
59
60
|
!object(manifest.bindings) ||
|
|
60
|
-
!exact(manifest.bindings, phases)
|
|
61
|
+
!exact(manifest.bindings, Object.hasOwn(manifest.bindings, "test-review") ? phases : requiredPhases)
|
|
61
62
|
)
|
|
62
63
|
throw Error("invalid Principal binding manifest");
|
|
63
|
-
for (const name of
|
|
64
|
+
for (const name of Object.keys(manifest.bindings)) {
|
|
64
65
|
const row = manifest.bindings[name];
|
|
65
66
|
if (
|
|
66
67
|
!object(row) ||
|
|
@@ -74,6 +75,7 @@ async function principalBinding(
|
|
|
74
75
|
)
|
|
75
76
|
throw Error("invalid Principal binding row");
|
|
76
77
|
}
|
|
78
|
+
if (!Object.hasOwn(manifest.bindings, phase)) throw Error("selected Principal phase has no binding row");
|
|
77
79
|
const row = manifest.bindings[phase] as Record<string, string>;
|
|
78
80
|
const agentPath = join(root, row.agent);
|
|
79
81
|
if (
|
|
@@ -376,6 +376,17 @@ export async function runDashboard(argv = process.argv.slice(2), env: NodeJS.Pro
|
|
|
376
376
|
notice = (await connection.change({ action: "set", edits: trimmed.slice(2).trim() }))
|
|
377
377
|
? "Session models updated"
|
|
378
378
|
: connection.state.error || "Session controls unavailable";
|
|
379
|
+
} else if (trimmed.startsWith("limit ")) {
|
|
380
|
+
const edit = /^limit (wall|idle) ([0-9]+)$/.exec(trimmed);
|
|
381
|
+
if (!edit) notice = "Use limit wall <seconds> or limit idle <seconds>; 0 restores default";
|
|
382
|
+
else
|
|
383
|
+
notice = (await connection.change({
|
|
384
|
+
action: "set-limit",
|
|
385
|
+
key: edit[1] as "wall" | "idle",
|
|
386
|
+
seconds: Number(edit[2]),
|
|
387
|
+
}))
|
|
388
|
+
? "Session limit updated for future children; running children unchanged"
|
|
389
|
+
: connection.state.error || "Settings unavailable";
|
|
379
390
|
} else notice = display.input(line) ? "" : `Unknown command: ${trimmed}. Press ? for help.`;
|
|
380
391
|
redraw();
|
|
381
392
|
};
|
|
@@ -397,7 +408,7 @@ export async function runDashboard(argv = process.argv.slice(2), env: NodeJS.Pro
|
|
|
397
408
|
redraw();
|
|
398
409
|
return;
|
|
399
410
|
}
|
|
400
|
-
|
|
411
|
+
let action = display.key(
|
|
401
412
|
key.name === "return"
|
|
402
413
|
? "return"
|
|
403
414
|
: ["up", "down", "escape", "tab"].includes(key.name || "")
|
|
@@ -409,6 +420,32 @@ export async function runDashboard(argv = process.argv.slice(2), env: NodeJS.Pro
|
|
|
409
420
|
return;
|
|
410
421
|
}
|
|
411
422
|
if (action === "command") command = "";
|
|
423
|
+
if (action === "setting") {
|
|
424
|
+
const selected = display.screen.settingKey ?? "auto";
|
|
425
|
+
const settings = connection.state.snapshot?.settings;
|
|
426
|
+
if (!settings?.editable) notice = "Settings can only be changed in the connected owning parent";
|
|
427
|
+
else if (selected === "auto") action = "auto";
|
|
428
|
+
else if (selected === "wall" || selected === "idle") command = `limit ${selected} `;
|
|
429
|
+
else if (selected === "descendants") notice = "Startup only: set PI_DADDY_FANOUT before restarting Pi";
|
|
430
|
+
else if (selected === "depth") notice = "Startup only: set PI_DADDY_MAX_DEPTH before restarting Pi";
|
|
431
|
+
else if (selected === "perCall") notice = "Children per call is a fixed safety bound";
|
|
432
|
+
else if (!settings.jev.available)
|
|
433
|
+
notice = "JEV controls unavailable; load skill-harness in the parent Pi session";
|
|
434
|
+
else {
|
|
435
|
+
void connection
|
|
436
|
+
.change({ action: "set-jev", enabled: !(settings.jev.enabled || settings.jev.pending) })
|
|
437
|
+
.then((changed) => {
|
|
438
|
+
const jev = connection.state.snapshot?.settings?.jev;
|
|
439
|
+
notice = !changed
|
|
440
|
+
? connection.state.error || "JEV change already pending"
|
|
441
|
+
: jev?.pending
|
|
442
|
+
? "Complete JEV paid-call and LoRA-storage choices in the parent Pi session"
|
|
443
|
+
: jev?.error ||
|
|
444
|
+
`JEV ${jev?.enabled ? "enabled" : "disabled"}; ${jev?.availability ?? "status unknown"}`;
|
|
445
|
+
redraw();
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
412
449
|
if (action === "auto") {
|
|
413
450
|
const snapshot = connection.state.snapshot;
|
|
414
451
|
if (!snapshot) notice = "Daddy permission controls unavailable";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DASHBOARD_SETTING_KEYS } from "./dashboard-settings.ts";
|
|
1
2
|
/** Local display controls; these never dispatch actions to an owner or change ledger state. */
|
|
2
3
|
import { dashboardScreenState } from "./dashboard-screen.ts";
|
|
3
4
|
import { ActivityTimelineAliases } from "./activity-timeline.ts";
|
|
@@ -16,16 +17,17 @@ export function createDashboardDisplayControls(details: boolean, ledger: boolean
|
|
|
16
17
|
return {
|
|
17
18
|
state,
|
|
18
19
|
screen,
|
|
19
|
-
key(key: string): "auto" | "quit" | "command" | undefined {
|
|
20
|
+
key(key: string): "auto" | "quit" | "command" | "setting" | undefined {
|
|
20
21
|
if (key === "a") return "auto";
|
|
21
22
|
if (key === "q" || key === "ctrl-c") return "quit";
|
|
22
23
|
if (key === ":") return "command";
|
|
24
|
+
if (screen.view === "settings" && (key === "return" || key === "d")) return "setting";
|
|
23
25
|
if (key === "escape") {
|
|
24
26
|
screen.view = screen.view === "version-details" ? "versions" : "main";
|
|
25
27
|
state.activityDetail = undefined;
|
|
26
28
|
screen.offset = 0;
|
|
27
|
-
} else if (key === "?" || key === "m" || key === "v") {
|
|
28
|
-
screen.view = key === "?" ? "help" : key === "v" ? "versions" : "models";
|
|
29
|
+
} else if (key === "?" || key === "m" || key === "v" || key === "s") {
|
|
30
|
+
screen.view = key === "?" ? "help" : key === "v" ? "versions" : key === "s" ? "settings" : "models";
|
|
29
31
|
state.activityDetail = undefined;
|
|
30
32
|
screen.offset = 0;
|
|
31
33
|
} else if (key === "return" || key === "d") {
|
|
@@ -33,7 +35,11 @@ export function createDashboardDisplayControls(details: boolean, ledger: boolean
|
|
|
33
35
|
screen.offset = 0;
|
|
34
36
|
} else if (["up", "down", "j", "k"].includes(key)) {
|
|
35
37
|
const delta = key === "up" || key === "k" ? -1 : 1;
|
|
36
|
-
if (screen.view === "
|
|
38
|
+
if (screen.view === "settings") {
|
|
39
|
+
const index = DASHBOARD_SETTING_KEYS.indexOf(screen.settingKey ?? "auto");
|
|
40
|
+
screen.settingKey =
|
|
41
|
+
DASHBOARD_SETTING_KEYS[Math.max(0, Math.min(DASHBOARD_SETTING_KEYS.length - 1, index + delta))];
|
|
42
|
+
} else if (screen.view === "versions") {
|
|
37
43
|
const rows = screen.versionRows ?? [],
|
|
38
44
|
index = rows.findIndex((row) => row.id === screen.versionId);
|
|
39
45
|
screen.versionId = rows[Math.max(0, Math.min(rows.length - 1, index + delta))]?.id;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dashboardSettingsLines, type DashboardSettingKey } from "./dashboard-settings.ts";
|
|
1
2
|
/** Height-bounded, task-first view. Permission state is always supplied by the owner. */
|
|
2
3
|
import type { EcosystemVersionRow } from "./ecosystem-versions.ts";
|
|
3
4
|
import type { DashboardProjection } from "./dashboard-projection.ts";
|
|
@@ -19,7 +20,8 @@ export interface DashboardItem {
|
|
|
19
20
|
agent?: boolean;
|
|
20
21
|
}
|
|
21
22
|
export interface DashboardScreenState {
|
|
22
|
-
view: "main" | "details" | "models" | "help" | "versions" | "version-details";
|
|
23
|
+
view: "main" | "details" | "models" | "help" | "versions" | "version-details" | "settings";
|
|
24
|
+
settingKey?: DashboardSettingKey;
|
|
23
25
|
versionId?: EcosystemVersionRow["id"];
|
|
24
26
|
versionRows?: EcosystemVersionRow[];
|
|
25
27
|
selectedKey?: string;
|
|
@@ -204,12 +206,14 @@ export function renderDashboardScreen(options: DashboardScreenOptions): string {
|
|
|
204
206
|
const footer =
|
|
205
207
|
options.command !== undefined
|
|
206
208
|
? [`: ${clean(options.command)}`]
|
|
207
|
-
: screen.view === "
|
|
208
|
-
? ["↑↓ select · Enter
|
|
209
|
-
:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
: screen.view === "settings"
|
|
210
|
+
? ["↑↓ select · Enter toggle/edit · Esc back", "0 restores a default limit · s settings"]
|
|
211
|
+
: screen.view === "main" || screen.view === "versions"
|
|
212
|
+
? ["↑↓ select · Enter details · a Auto", "m models · v versions · s settings · ?"]
|
|
213
|
+
: [
|
|
214
|
+
"↑↓ scroll · Esc back · a Auto",
|
|
215
|
+
screen.view === "details" ? "p prompt · f final · : command · ? help" : ": command · ? help",
|
|
216
|
+
];
|
|
213
217
|
const fixed = [
|
|
214
218
|
header,
|
|
215
219
|
session
|
|
@@ -223,7 +227,7 @@ export function renderDashboardScreen(options: DashboardScreenOptions): string {
|
|
|
223
227
|
"DASHBOARD KEYS",
|
|
224
228
|
"↑/↓ or j/k: select; Enter/d: details",
|
|
225
229
|
"a: toggle Daddy permission Auto",
|
|
226
|
-
"m: session models; v: ecosystem versions",
|
|
230
|
+
"m: session models; v: ecosystem versions; s: settings",
|
|
227
231
|
"h: show/hide finished history",
|
|
228
232
|
"Tab: Everything / Agents / Skills / Needs-you",
|
|
229
233
|
"p/f: selected retained prompt/final",
|
|
@@ -234,7 +238,9 @@ export function renderDashboardScreen(options: DashboardScreenOptions): string {
|
|
|
234
238
|
"Auto does not enable JEV or change LoRA consent.",
|
|
235
239
|
"Finished means observed completion, not acceptance.",
|
|
236
240
|
);
|
|
237
|
-
else if (screen.view === "
|
|
241
|
+
else if (screen.view === "settings") {
|
|
242
|
+
body.push(...dashboardSettingsLines(session?.settings, session?.auto.enabled, screen.settingKey ?? "auto"));
|
|
243
|
+
} else if (screen.view === "versions" || screen.view === "version-details") {
|
|
238
244
|
body.push("VERSIONS");
|
|
239
245
|
if (!session?.versions) body.push("Owner has not reported versions.");
|
|
240
246
|
else if (screen.view === "versions") {
|
|
@@ -323,6 +329,11 @@ export function renderDashboardScreen(options: DashboardScreenOptions): string {
|
|
|
323
329
|
if (row < screen.offset) screen.offset = row;
|
|
324
330
|
else if (row + 1 >= screen.offset + room) screen.offset = Math.max(0, row + 2 - room);
|
|
325
331
|
}
|
|
332
|
+
if (screen.view === "settings" && room > 0) {
|
|
333
|
+
const row = detailBody.findIndex((line) => line.startsWith(">"));
|
|
334
|
+
if (row < screen.offset) screen.offset = Math.max(0, row);
|
|
335
|
+
else if (row >= screen.offset + room) screen.offset = Math.max(0, row - room + 1);
|
|
336
|
+
}
|
|
326
337
|
const offset =
|
|
327
338
|
screen.view === "main" ? 0 : Math.max(0, Math.min(screen.offset, Math.max(0, detailBody.length - room)));
|
|
328
339
|
screen.offset = offset;
|
|
@@ -337,7 +348,7 @@ export function renderDashboardScreen(options: DashboardScreenOptions): string {
|
|
|
337
348
|
const safe = truncate(dashboardText(line), width);
|
|
338
349
|
if (!options.color) return safe;
|
|
339
350
|
const section =
|
|
340
|
-
/^(CURRENT REQUEST|LATEST REQUEST|CURRENT WORK|NEEDS YOU|NEEDS ATTENTION|WORK IN PROGRESS|HISTORY|VERSIONS|SESSION MODELS|DASHBOARD KEYS|MANAGE)/.test(
|
|
351
|
+
/^(CURRENT REQUEST|LATEST REQUEST|CURRENT WORK|NEEDS YOU|NEEDS ATTENTION|WORK IN PROGRESS|HISTORY|VERSIONS|SETTINGS|STARTUP LIMITS|SESSION MODELS|DASHBOARD KEYS|MANAGE)/.test(
|
|
341
352
|
safe,
|
|
342
353
|
);
|
|
343
354
|
const code =
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DashboardSettingsSnapshot } from "./dashboard-settings.ts";
|
|
1
2
|
import type { EcosystemVersions } from "./ecosystem-versions.ts";
|
|
2
3
|
import { createConnection } from "node:net";
|
|
3
4
|
|
|
@@ -6,12 +7,17 @@ export interface DashboardSessionSnapshot {
|
|
|
6
7
|
cost: number | null;
|
|
7
8
|
activity?: { rootId: string; path: string; taskId: string };
|
|
8
9
|
versions?: EcosystemVersions;
|
|
10
|
+
settings?: DashboardSettingsSnapshot;
|
|
9
11
|
auto: { enabled: boolean; source: "default" | "environment" | "session" };
|
|
10
12
|
pendingApprovals: Array<{ id: string; subject: string; capability: string }>;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export type DashboardSessionAction =
|
|
14
|
-
|
|
16
|
+
| { action: "get" }
|
|
17
|
+
| { action: "set"; edits: string }
|
|
18
|
+
| { action: "set-auto"; enabled: boolean }
|
|
19
|
+
| { action: "set-jev"; enabled: boolean }
|
|
20
|
+
| { action: "set-limit"; key: "wall" | "idle"; seconds: number };
|
|
15
21
|
|
|
16
22
|
export async function dashboardSessionRequest(
|
|
17
23
|
socketPath: string,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Settings are owner observations; rendering never grants consent or changes execution. */
|
|
2
|
+
export type DashboardSettingKey = "auto" | "jev" | "wall" | "idle" | "descendants" | "depth" | "perCall";
|
|
3
|
+
export const DASHBOARD_SETTING_KEYS: DashboardSettingKey[] = [
|
|
4
|
+
"auto",
|
|
5
|
+
"jev",
|
|
6
|
+
"wall",
|
|
7
|
+
"idle",
|
|
8
|
+
"descendants",
|
|
9
|
+
"depth",
|
|
10
|
+
"perCall",
|
|
11
|
+
];
|
|
12
|
+
export interface DashboardJevState {
|
|
13
|
+
available: boolean;
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
pending: boolean;
|
|
16
|
+
mode?: string;
|
|
17
|
+
storage?: string | null;
|
|
18
|
+
remaining?: number;
|
|
19
|
+
availability?: string;
|
|
20
|
+
providerReadiness?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DashboardSettingsSnapshot {
|
|
24
|
+
editable: boolean;
|
|
25
|
+
wallSeconds: number;
|
|
26
|
+
idleSeconds: number;
|
|
27
|
+
wallSource: "session" | "startup";
|
|
28
|
+
idleSource: "session" | "startup";
|
|
29
|
+
descendants: number;
|
|
30
|
+
reserved: number;
|
|
31
|
+
maxDepth: number;
|
|
32
|
+
perCall: number;
|
|
33
|
+
jev: DashboardJevState;
|
|
34
|
+
}
|
|
35
|
+
export function dashboardSettingsLines(
|
|
36
|
+
settings: DashboardSettingsSnapshot | undefined,
|
|
37
|
+
auto: boolean | undefined,
|
|
38
|
+
selected: DashboardSettingKey,
|
|
39
|
+
): string[] {
|
|
40
|
+
if (!settings) return ["SETTINGS", "Owner settings unavailable. Reconnect from /grants dashboard."];
|
|
41
|
+
const row = (key: DashboardSettingKey, label: string) => `${key === selected ? ">" : " "} ${label}`;
|
|
42
|
+
const jev = settings.jev;
|
|
43
|
+
return [
|
|
44
|
+
"SETTINGS · current session",
|
|
45
|
+
row("auto", `Permission Auto: ${auto ? "ON" : "OFF"}`),
|
|
46
|
+
row(
|
|
47
|
+
"jev",
|
|
48
|
+
`JEV: ${jev.pending ? "waiting for consent" : !jev.available ? "unavailable" : jev.enabled ? "ON" : "OFF"}`,
|
|
49
|
+
),
|
|
50
|
+
...(jev.available
|
|
51
|
+
? [
|
|
52
|
+
` ${jev.availability ?? "unknown"} · ${jev.remaining ?? 0} paid calls left`,
|
|
53
|
+
` Key: ${jev.providerReadiness ?? "unknown"}; storage: ${jev.storage ?? "not granted"}`,
|
|
54
|
+
]
|
|
55
|
+
: [" Load skill-harness to connect JEV controls."]),
|
|
56
|
+
...(jev.error ? [` ${jev.error}`] : []),
|
|
57
|
+
row("wall", `Child wall: ${settings.wallSeconds}s (${settings.wallSource})`),
|
|
58
|
+
row("idle", `Child idle: ${settings.idleSeconds}s (${settings.idleSource})`),
|
|
59
|
+
settings.editable
|
|
60
|
+
? "Edits apply to future children from this parent."
|
|
61
|
+
: "Read-only: change settings in the owning parent.",
|
|
62
|
+
"Running children keep their captured limits.",
|
|
63
|
+
"JEV ON asks paid-call and LoRA-storage consent in Pi.",
|
|
64
|
+
"Auto never supplies that consent. No model token budget.",
|
|
65
|
+
"",
|
|
66
|
+
"STARTUP LIMITS · restart to change",
|
|
67
|
+
row("descendants", `Active descendants: ${settings.descendants} (${settings.reserved} reserved) · PI_DADDY_FANOUT`),
|
|
68
|
+
row("depth", `Maximum depth: ${settings.maxDepth} · PI_DADDY_MAX_DEPTH`),
|
|
69
|
+
row("perCall", `Children per call: ${settings.perCall} (fixed safety bound)`),
|
|
70
|
+
"s settings · m models · v versions",
|
|
71
|
+
];
|
|
72
|
+
}
|