@llblab/pi-actors 0.40.1 → 0.41.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/AGENTS.md +3 -3
- package/CHANGELOG.md +32 -0
- package/README.md +2 -1
- package/dist/index.js +80 -58
- package/dist/lib/inspector-overlay.d.ts +95 -0
- package/dist/lib/inspector-overlay.js +873 -0
- package/dist/lib/inspector.d.ts +17 -33
- package/dist/lib/inspector.js +101 -151
- package/dist/lib/limits.d.ts +3 -0
- package/dist/lib/limits.js +3 -0
- package/dist/lib/observability.d.ts +38 -3
- package/dist/lib/observability.js +151 -33
- package/dist/lib/recipes-context.d.ts +5 -0
- package/dist/lib/recipes-context.js +15 -0
- package/dist/lib/session-evidence.d.ts +45 -0
- package/dist/lib/session-evidence.js +204 -0
- package/dist/lib/tools-response.d.ts +3 -0
- package/dist/lib/tools-response.js +29 -0
- package/dist/scripts/async-runner.mjs +40 -5
- package/dist/scripts/coordinator.mjs +55 -9
- package/dist/skills/actors/SKILL.md +5 -11
- package/dist/skills/swarm/SKILL.md +1 -1
- package/docs/README.md +1 -0
- package/docs/actor-inspector.md +77 -0
- package/docs/async-runs.md +1 -1
- package/index.ts +80 -70
- package/lib/inspector-overlay.ts +1071 -0
- package/lib/inspector.ts +135 -204
- package/lib/limits.ts +3 -0
- package/lib/observability.ts +205 -39
- package/lib/recipes-context.ts +25 -0
- package/lib/session-evidence.ts +302 -0
- package/lib/tools-response.ts +32 -0
- package/package.json +1 -1
- package/scripts/async-runner.mjs +40 -5
- package/scripts/coordinator.mjs +55 -9
- package/skills/actors/SKILL.md +5 -11
- package/skills/swarm/SKILL.md +1 -1
package/dist/lib/inspector.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Zones: terminal run inspection, room/direct message previews, no-dependency UI formatting
|
|
4
4
|
* Owns read-only previews and TUI-ready summaries; actor routing stays outside.
|
|
5
5
|
*/
|
|
6
|
+
import * as SessionEvidence from "./session-evidence.ts";
|
|
6
7
|
export interface ActorInspectorPreview {
|
|
7
8
|
body_preview?: string;
|
|
8
9
|
branch?: string;
|
|
@@ -45,47 +46,30 @@ export interface ActorInspectorPreviewReadOptions {
|
|
|
45
46
|
ownerId?: string;
|
|
46
47
|
branch?: string;
|
|
47
48
|
currentRunOnly?: boolean;
|
|
49
|
+
run?: string;
|
|
48
50
|
channels?: ActorInspectorPreview["channel"][];
|
|
49
51
|
mention?: string;
|
|
50
52
|
readKeys?: Iterable<string>;
|
|
51
53
|
roomLimitPerRun?: number;
|
|
52
54
|
unreadOnly?: boolean;
|
|
53
55
|
}
|
|
54
|
-
export interface
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
readKeys: Set<string>;
|
|
59
|
-
roomLimitPerRun: number;
|
|
60
|
-
rows: number;
|
|
61
|
-
selectedSequence?: number;
|
|
62
|
-
unreadOnly: boolean;
|
|
63
|
-
visible: boolean;
|
|
56
|
+
export interface ActorInspectorRunItem {
|
|
57
|
+
run: string;
|
|
58
|
+
status: string;
|
|
59
|
+
updatedAt?: string;
|
|
64
60
|
}
|
|
65
|
-
export
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
export declare function readActorInspectorRuns(stateRoot: string, ownerId: string): ActorInspectorRunItem[];
|
|
62
|
+
export interface ActorInspectorTurnItem extends SessionEvidence.SessionEvidenceTurn {
|
|
63
|
+
commandId: string;
|
|
64
|
+
diagnostics: string[];
|
|
65
|
+
promptBytes?: number;
|
|
66
|
+
promptFile?: string;
|
|
67
|
+
recipeContext?: unknown;
|
|
68
|
+
sessionFile: string;
|
|
69
|
+
sessionTruncated: boolean;
|
|
70
|
+
stage?: string;
|
|
69
71
|
}
|
|
70
|
-
export declare
|
|
71
|
-
export declare const ACTOR_INSPECTOR_COMMAND_DESCRIPTIONS: {
|
|
72
|
-
filter: string;
|
|
73
|
-
inspect: string;
|
|
74
|
-
toggle: string;
|
|
75
|
-
};
|
|
76
|
-
export declare function createActorInspectorControllerState(): ActorInspectorControllerState;
|
|
77
|
-
export declare function getActorInspectorPreviewOptions(state: ActorInspectorControllerState, ownerId: string): ActorInspectorPreviewReadOptions;
|
|
78
|
-
export declare function handleActorInspectorToggle(state: ActorInspectorControllerState, args: unknown): ActorInspectorCommandResult;
|
|
79
|
-
export declare function handleActorInspectorFilter(state: ActorInspectorControllerState, args: unknown): ActorInspectorCommandResult;
|
|
80
|
-
export declare function handleActorInspectorInspect(state: ActorInspectorControllerState, args: unknown, previews: ActorInspectorPreview[]): ActorInspectorCommandResult;
|
|
81
|
-
export declare function selectActorInspectorSequence(state: ActorInspectorControllerState, sequence: number, previews: ActorInspectorPreview[]): ActorInspectorCommandResult;
|
|
82
|
-
export declare function renderActorInspectorPanel(input: {
|
|
83
|
-
stateRoot: string;
|
|
84
|
-
state: ActorInspectorControllerState;
|
|
85
|
-
ownerId: string;
|
|
86
|
-
width: number;
|
|
87
|
-
style: ActorInspectorWidgetStyle;
|
|
88
|
-
}): string[];
|
|
72
|
+
export declare function readActorInspectorTurns(stateDir: string): ActorInspectorTurnItem[];
|
|
89
73
|
export declare function inspectorPreviewReadKey(preview: ActorInspectorPreview): string;
|
|
90
74
|
export declare function readActorInspectorPreviews(stateRoot?: string, limit?: number, options?: ActorInspectorPreviewReadOptions): ActorInspectorPreview[];
|
|
91
75
|
export declare function readActorInspectorRoster(stateRoot: string | undefined, run: string, room?: string): ActorInspectorRosterMember[];
|
package/dist/lib/inspector.js
CHANGED
|
@@ -8,164 +8,111 @@ import * as path from "node:path";
|
|
|
8
8
|
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
9
9
|
import * as Limits from "./limits.js";
|
|
10
10
|
import * as Paths from "./paths.js";
|
|
11
|
+
import * as SessionEvidence from "./session-evidence.js";
|
|
11
12
|
import { readJsonFileResilient, readJsonlFileResilient, } from "./state-readers.js";
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export function handleActorInspectorToggle(state, args) {
|
|
40
|
-
const raw = Array.isArray(args) ? args[0] : String(args ?? "");
|
|
41
|
-
if (String(raw).trim()) {
|
|
42
|
-
const rows = Number.parseInt(String(raw), 10);
|
|
43
|
-
if (!Number.isFinite(rows) || rows <= 0) {
|
|
44
|
-
return {
|
|
45
|
-
notify: "Usage: /actors-inspector-toggle [rows] where rows > 0",
|
|
46
|
-
type: "warning",
|
|
47
|
-
update: false,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
state.rows = rows;
|
|
51
|
-
state.roomLimitPerRun = rows;
|
|
52
|
-
state.selectedSequence = undefined;
|
|
53
|
-
state.visible = true;
|
|
54
|
-
return {
|
|
55
|
-
notify: `Actor inspector rows ${rows}`,
|
|
56
|
-
type: "info",
|
|
57
|
-
update: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if (state.selectedSequence !== undefined) {
|
|
61
|
-
state.selectedSequence = undefined;
|
|
62
|
-
state.visible = true;
|
|
63
|
-
return { notify: "Actor inspector table", type: "info", update: true };
|
|
13
|
+
export function readActorInspectorRuns(stateRoot, ownerId) {
|
|
14
|
+
try {
|
|
15
|
+
return fs
|
|
16
|
+
.readdirSync(stateRoot, { withFileTypes: true })
|
|
17
|
+
.filter((entry) => entry.isDirectory())
|
|
18
|
+
.flatMap((entry) => {
|
|
19
|
+
const stateDir = path.join(stateRoot, entry.name);
|
|
20
|
+
if (!matchesOwner(stateDir, ownerId))
|
|
21
|
+
return [];
|
|
22
|
+
const progress = readJsonFileResilient(path.join(stateDir, "progress.json"), {}).value;
|
|
23
|
+
const result = readJsonFileResilient(path.join(stateDir, "result.json"), {}).value;
|
|
24
|
+
return [{
|
|
25
|
+
run: entry.name,
|
|
26
|
+
status: String(progress.phase ?? (Object.keys(result).length ? "terminal" : "unknown")),
|
|
27
|
+
...(typeof progress.updatedAt === "string"
|
|
28
|
+
? { updatedAt: progress.updatedAt }
|
|
29
|
+
: typeof result.completedAt === "string"
|
|
30
|
+
? { updatedAt: result.completedAt }
|
|
31
|
+
: {}),
|
|
32
|
+
}];
|
|
33
|
+
})
|
|
34
|
+
.sort((left, right) => {
|
|
35
|
+
const recency = String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? ""));
|
|
36
|
+
return recency || right.run.localeCompare(left.run);
|
|
37
|
+
});
|
|
64
38
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
state.roomLimitPerRun = DEFAULT_ACTOR_INSPECTOR_ROWS;
|
|
70
|
-
state.visible = true;
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code === "ENOENT")
|
|
41
|
+
return [];
|
|
42
|
+
return [];
|
|
71
43
|
}
|
|
72
|
-
return {
|
|
73
|
-
notify: `Actor inspector ${state.visible ? "shown" : "hidden"}`,
|
|
74
|
-
type: "info",
|
|
75
|
-
update: true,
|
|
76
|
-
};
|
|
77
44
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
if (!
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
state.mention = undefined;
|
|
92
|
-
}
|
|
93
|
-
else if (mode === "unread") {
|
|
94
|
-
state.unreadOnly = true;
|
|
95
|
-
}
|
|
96
|
-
else if (mode === "branch" || mode === "current-branch") {
|
|
97
|
-
const branch = parts.slice(1).join(" ").trim();
|
|
98
|
-
if (!branch) {
|
|
99
|
-
return {
|
|
100
|
-
notify: `Usage: /actors-inspector-filter ${mode} <branch-name>`,
|
|
101
|
-
type: "warning",
|
|
102
|
-
update: false,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
state.branch = branch;
|
|
106
|
-
}
|
|
107
|
-
else if (mode === "mention") {
|
|
108
|
-
const mention = parts.slice(1).join(" ").trim();
|
|
109
|
-
if (!mention) {
|
|
110
|
-
return {
|
|
111
|
-
notify: "Usage: /actors-inspector-filter mention <text>",
|
|
112
|
-
type: "warning",
|
|
113
|
-
update: false,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
state.channels = undefined;
|
|
117
|
-
state.mention = mention;
|
|
45
|
+
function ownedSessionPath(stateDir, sessionFile) {
|
|
46
|
+
if (path.isAbsolute(sessionFile))
|
|
47
|
+
return undefined;
|
|
48
|
+
const sessionsRoot = path.resolve(stateDir, "sessions");
|
|
49
|
+
const resolved = path.resolve(stateDir, sessionFile);
|
|
50
|
+
if (!resolved.startsWith(`${sessionsRoot}${path.sep}`))
|
|
51
|
+
return undefined;
|
|
52
|
+
try {
|
|
53
|
+
const canonicalRoot = fs.realpathSync(sessionsRoot);
|
|
54
|
+
const canonicalFile = fs.realpathSync(resolved);
|
|
55
|
+
return canonicalFile.startsWith(`${canonicalRoot}${path.sep}`)
|
|
56
|
+
? canonicalFile
|
|
57
|
+
: undefined;
|
|
118
58
|
}
|
|
119
|
-
|
|
120
|
-
return
|
|
121
|
-
notify: "Usage: /actors-inspector-filter all|room|direct|broadcast|unread|branch <name>|mention <text>",
|
|
122
|
-
type: "warning",
|
|
123
|
-
update: false,
|
|
124
|
-
};
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
125
61
|
}
|
|
126
|
-
state.selectedSequence = undefined;
|
|
127
|
-
state.visible = true;
|
|
128
|
-
return {
|
|
129
|
-
notify: `Actor inspector filter ${mode || "all"}`,
|
|
130
|
-
type: "info",
|
|
131
|
-
update: true,
|
|
132
|
-
};
|
|
133
62
|
}
|
|
134
|
-
export function
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
63
|
+
export function readActorInspectorTurns(stateDir) {
|
|
64
|
+
const evidence = readJsonFileResilient(path.join(stateDir, "review-evidence.json"), {}).value;
|
|
65
|
+
const commands = Array.isArray(evidence.commands)
|
|
66
|
+
? evidence.commands
|
|
67
|
+
: [];
|
|
68
|
+
const recordedFiles = new Set(commands.flatMap((command) => (Array.isArray(command.session_files) ? command.session_files : []).filter((file) => typeof file === "string")));
|
|
69
|
+
let discoveredCommands = [];
|
|
70
|
+
try {
|
|
71
|
+
const sessionsDir = path.join(stateDir, "sessions");
|
|
72
|
+
discoveredCommands = fs
|
|
73
|
+
.readdirSync(sessionsDir, { withFileTypes: true })
|
|
74
|
+
.filter((entry) => entry.isDirectory())
|
|
75
|
+
.flatMap((entry) => {
|
|
76
|
+
const files = fs
|
|
77
|
+
.readdirSync(path.join(sessionsDir, entry.name), {
|
|
78
|
+
withFileTypes: true,
|
|
79
|
+
})
|
|
80
|
+
.filter((file) => file.isFile() && file.name.endsWith(".jsonl"))
|
|
81
|
+
.map((file) => path.join("sessions", entry.name, file.name))
|
|
82
|
+
.filter((file) => !recordedFiles.has(file));
|
|
83
|
+
return files.length > 0
|
|
84
|
+
? [{ id: entry.name, session_files: files, stage: "subagent" }]
|
|
85
|
+
: [];
|
|
86
|
+
});
|
|
145
87
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
88
|
+
catch {
|
|
89
|
+
discoveredCommands = [];
|
|
90
|
+
}
|
|
91
|
+
return [...commands, ...discoveredCommands].flatMap((command) => (Array.isArray(command.session_files) ? command.session_files : [])
|
|
92
|
+
.filter((file) => typeof file === "string")
|
|
93
|
+
.flatMap((file) => {
|
|
94
|
+
const sessionPath = ownedSessionPath(stateDir, file);
|
|
95
|
+
if (!sessionPath)
|
|
96
|
+
return [];
|
|
97
|
+
const session = SessionEvidence.readSessionEvidence(sessionPath);
|
|
98
|
+
return session.turns.map((turn) => ({
|
|
99
|
+
...turn,
|
|
100
|
+
commandId: String(command.id ?? "unknown"),
|
|
101
|
+
diagnostics: session.diagnostics.map((item) => `${item.line === undefined ? "" : `line ${item.line}: `}${item.message}`),
|
|
102
|
+
...(typeof command.prompt_bytes === "number"
|
|
103
|
+
? { promptBytes: command.prompt_bytes }
|
|
104
|
+
: {}),
|
|
105
|
+
...(typeof command.prompt_file === "string"
|
|
106
|
+
? { promptFile: command.prompt_file }
|
|
107
|
+
: {}),
|
|
108
|
+
...(command.recipe_context !== undefined
|
|
109
|
+
? { recipeContext: command.recipe_context }
|
|
110
|
+
: {}),
|
|
111
|
+
sessionFile: file,
|
|
112
|
+
sessionTruncated: session.truncated,
|
|
113
|
+
...(typeof command.stage === "string" ? { stage: command.stage } : {}),
|
|
114
|
+
}));
|
|
115
|
+
})).map((turn, index) => ({ ...turn, index: index + 1 }));
|
|
169
116
|
}
|
|
170
117
|
function asRecord(value) {
|
|
171
118
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
@@ -178,7 +125,8 @@ function readJsonLines(file) {
|
|
|
178
125
|
function previewValue(value, maxLength = Limits.INSPECTOR_BODY_PREVIEW_CHARS) {
|
|
179
126
|
if (value === undefined)
|
|
180
127
|
return undefined;
|
|
181
|
-
const
|
|
128
|
+
const redacted = SessionEvidence.redactSessionEvidenceValue(value);
|
|
129
|
+
const text = typeof redacted === "string" ? redacted : JSON.stringify(redacted);
|
|
182
130
|
const compact = text.replaceAll(/\s+/g, " ").trim();
|
|
183
131
|
if (!compact)
|
|
184
132
|
return undefined;
|
|
@@ -393,6 +341,8 @@ export function readActorInspectorPreviews(stateRoot = Paths.getRunStateRoot(),
|
|
|
393
341
|
const stateDir = path.join(stateRoot, entry.name);
|
|
394
342
|
if (!matchesOwner(stateDir, options.ownerId))
|
|
395
343
|
return [];
|
|
344
|
+
if (options.run && entry.name !== options.run)
|
|
345
|
+
return [];
|
|
396
346
|
return [
|
|
397
347
|
...readRoomPreviews(entry.name, stateDir),
|
|
398
348
|
...readInboxPreviews(entry.name, stateDir),
|
package/dist/lib/limits.d.ts
CHANGED
|
@@ -9,3 +9,6 @@ export declare const COMPACT_PREVIEW_CHARS = 160;
|
|
|
9
9
|
export declare const INSPECTOR_BODY_PREVIEW_CHARS = 320;
|
|
10
10
|
export declare const ROOM_MESSAGE_PREVIEW_CHARS = 320;
|
|
11
11
|
export declare const DOCTOR_ACTION_PREVIEW_CHARS = 72;
|
|
12
|
+
export declare const SESSION_EVIDENCE_MAX_TURNS = 100;
|
|
13
|
+
export declare const SESSION_EVIDENCE_TEXT_CHARS = 4000;
|
|
14
|
+
export declare const SESSION_EVIDENCE_MAX_TOOL_CALLS = 100;
|
package/dist/lib/limits.js
CHANGED
|
@@ -9,3 +9,6 @@ export const COMPACT_PREVIEW_CHARS = 160;
|
|
|
9
9
|
export const INSPECTOR_BODY_PREVIEW_CHARS = 320;
|
|
10
10
|
export const ROOM_MESSAGE_PREVIEW_CHARS = 320;
|
|
11
11
|
export const DOCTOR_ACTION_PREVIEW_CHARS = 72;
|
|
12
|
+
export const SESSION_EVIDENCE_MAX_TURNS = 100;
|
|
13
|
+
export const SESSION_EVIDENCE_TEXT_CHARS = 4_000;
|
|
14
|
+
export const SESSION_EVIDENCE_MAX_TOOL_CALLS = 100;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Zones: async runtime, ambient UI, diagnostics
|
|
4
4
|
* Owns ambient summaries, terminal events, and run outbox delivery for detached command-template runs
|
|
5
5
|
*/
|
|
6
|
+
import { type FSWatcher } from "node:fs";
|
|
6
7
|
import * as AsyncRuns from "./async-runs.ts";
|
|
7
8
|
export type RunObservedStatus = "running" | "done" | "failed" | "exited" | "cancelled" | "killed";
|
|
8
9
|
export type RunOutboxDelivery = "log" | "notify" | "followup";
|
|
@@ -58,9 +59,19 @@ export interface RunUiNotificationSink {
|
|
|
58
59
|
}): void;
|
|
59
60
|
}
|
|
60
61
|
export declare function createRunUiObservationState(): RunUiObservationState;
|
|
61
|
-
export declare function readRunUiSnapshot(state: RunUiObservationState, ownerId: string
|
|
62
|
+
export declare function readRunUiSnapshot(state: RunUiObservationState, ownerId: string, options?: {
|
|
63
|
+
includeOutbox?: boolean;
|
|
64
|
+
stateRoot?: string;
|
|
65
|
+
}): RunUiSnapshot;
|
|
62
66
|
export declare function pruneRunUiObservationState(state: RunUiObservationState, snapshot: Pick<RunUiSnapshot, "summary" | "transitions">): void;
|
|
63
|
-
export declare function deliverRunTransitionNotifications(transitions: RunTransition[], sink: RunUiNotificationSink): void;
|
|
67
|
+
export declare function deliverRunTransitionNotifications(transitions: RunTransition[], sink: RunUiNotificationSink, inFlight?: Set<string>): void;
|
|
68
|
+
export declare function reconcileRunTerminalNotifications(input: {
|
|
69
|
+
inFlight?: Set<string>;
|
|
70
|
+
ownerId: string;
|
|
71
|
+
sink: RunUiNotificationSink;
|
|
72
|
+
state: RunUiObservationState;
|
|
73
|
+
stateRoot?: string;
|
|
74
|
+
}): RunUiSnapshot;
|
|
64
75
|
export declare function deliverRunOutboxNotifications(events: RunOutboxEvent[], sink: RunUiNotificationSink): void;
|
|
65
76
|
export interface RunRetirementCandidate {
|
|
66
77
|
activeSubagents: number;
|
|
@@ -76,14 +87,38 @@ export interface RunRetirementExecution {
|
|
|
76
87
|
run: string;
|
|
77
88
|
stateDir: string;
|
|
78
89
|
}
|
|
90
|
+
export type RunStateWatcherDiagnosticCode = "attach_failed" | "error" | "removed" | "rearmed";
|
|
91
|
+
export interface RunStateWatcherDiagnostic {
|
|
92
|
+
code: RunStateWatcherDiagnosticCode;
|
|
93
|
+
id: number;
|
|
94
|
+
message: string;
|
|
95
|
+
path: string;
|
|
96
|
+
scope: "root" | "run";
|
|
97
|
+
ts: string;
|
|
98
|
+
}
|
|
79
99
|
export interface RunStateWatcher {
|
|
80
100
|
close(): void;
|
|
101
|
+
getDiagnostics(): RunStateWatcherDiagnostic[];
|
|
81
102
|
refresh(): void;
|
|
82
103
|
}
|
|
83
104
|
export declare function createRunStateWatcher(input: {
|
|
84
|
-
|
|
105
|
+
exists?: (path: string) => boolean;
|
|
106
|
+
listDirectories?: (path: string) => string[];
|
|
85
107
|
onChange: () => void;
|
|
108
|
+
stateRoot?: string;
|
|
109
|
+
watchPath?: (path: string, onChange: () => void) => FSWatcher;
|
|
86
110
|
}): RunStateWatcher;
|
|
111
|
+
export interface RunTerminalReconciliationLoop {
|
|
112
|
+
close(): void;
|
|
113
|
+
reconcileNow(): void;
|
|
114
|
+
start(): void;
|
|
115
|
+
}
|
|
116
|
+
export declare function createRunTerminalReconciliationLoop(input: {
|
|
117
|
+
intervalMs?: number;
|
|
118
|
+
onError?: (error: unknown) => void;
|
|
119
|
+
reconcile: () => void;
|
|
120
|
+
refreshWatcher: () => void;
|
|
121
|
+
}): RunTerminalReconciliationLoop;
|
|
87
122
|
export interface RunRetirementExecutorOptions {
|
|
88
123
|
attempted?: Set<string>;
|
|
89
124
|
cancelRun: (candidate: RunRetirementCandidate) => Record<string, unknown>;
|