@sapiom/harness 0.8.9 → 0.9.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 +63 -0
- package/README.md +11 -1
- package/dist/core/agent-project-discovery.d.ts +235 -1
- package/dist/core/agent-project-discovery.d.ts.map +1 -1
- package/dist/core/agent-project-discovery.js +303 -1
- package/dist/core/agent-project-discovery.js.map +1 -1
- package/dist/core/canvas-interconnections.d.ts +31 -0
- package/dist/core/canvas-interconnections.d.ts.map +1 -1
- package/dist/core/canvas-interconnections.js +294 -21
- package/dist/core/canvas-interconnections.js.map +1 -1
- package/dist/core/canvas-render.d.ts +32 -0
- package/dist/core/canvas-render.d.ts.map +1 -1
- package/dist/core/canvas-render.js +50 -41
- package/dist/core/canvas-render.js.map +1 -1
- package/dist/core/definition-name.d.ts +12 -0
- package/dist/core/definition-name.d.ts.map +1 -1
- package/dist/core/definition-name.js +14 -5
- package/dist/core/definition-name.js.map +1 -1
- package/dist/core/system-graph-inventory.d.ts +68 -0
- package/dist/core/system-graph-inventory.d.ts.map +1 -0
- package/dist/core/system-graph-inventory.js +312 -0
- package/dist/core/system-graph-inventory.js.map +1 -0
- package/dist/core/system-graph-relationships.d.ts +41 -0
- package/dist/core/system-graph-relationships.d.ts.map +1 -0
- package/dist/core/system-graph-relationships.js +98 -0
- package/dist/core/system-graph-relationships.js.map +1 -0
- package/dist/core/system-graph-store.d.ts +45 -0
- package/dist/core/system-graph-store.d.ts.map +1 -0
- package/dist/core/system-graph-store.js +222 -0
- package/dist/core/system-graph-store.js.map +1 -0
- package/dist/core/system-graph-watcher.d.ts +51 -0
- package/dist/core/system-graph-watcher.d.ts.map +1 -0
- package/dist/core/system-graph-watcher.js +448 -0
- package/dist/core/system-graph-watcher.js.map +1 -0
- package/dist/core/system-graph.d.ts +43 -0
- package/dist/core/system-graph.d.ts.map +1 -0
- package/dist/core/system-graph.js +321 -0
- package/dist/core/system-graph.js.map +1 -0
- package/dist/core/workflow-registry.d.ts +84 -6
- package/dist/core/workflow-registry.d.ts.map +1 -1
- package/dist/core/workflow-registry.js +191 -91
- package/dist/core/workflow-registry.js.map +1 -1
- package/dist/core/workspace-watcher.d.ts +21 -13
- package/dist/core/workspace-watcher.d.ts.map +1 -1
- package/dist/core/workspace-watcher.js +79 -81
- package/dist/core/workspace-watcher.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/agent-move.d.ts +134 -0
- package/dist/server/agent-move.d.ts.map +1 -0
- package/dist/server/agent-move.js +343 -0
- package/dist/server/agent-move.js.map +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +275 -22
- package/dist/server/index.js.map +1 -1
- package/dist/server/rest.d.ts +3 -0
- package/dist/server/rest.d.ts.map +1 -1
- package/dist/server/rest.js +3 -0
- package/dist/server/rest.js.map +1 -1
- package/dist/server/studio-rail.d.ts +76 -0
- package/dist/server/studio-rail.d.ts.map +1 -0
- package/dist/server/studio-rail.js +234 -0
- package/dist/server/studio-rail.js.map +1 -0
- package/dist/server/system-graph.d.ts +14 -0
- package/dist/server/system-graph.d.ts.map +1 -0
- package/dist/server/system-graph.js +40 -0
- package/dist/server/system-graph.js.map +1 -0
- package/dist/server/workflow-graph.d.ts +43 -0
- package/dist/server/workflow-graph.d.ts.map +1 -0
- package/dist/server/workflow-graph.js +200 -0
- package/dist/server/workflow-graph.js.map +1 -0
- package/dist/shared/system-graph.d.ts +59 -0
- package/dist/shared/system-graph.d.ts.map +1 -0
- package/dist/shared/system-graph.js +76 -0
- package/dist/shared/system-graph.js.map +1 -0
- package/dist/shared/types.d.ts +45 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/web/assets/index-2Fab6dzf.js +508 -0
- package/dist/web/assets/index-D0doaFvT.css +32 -0
- package/dist/web/index.html +2 -2
- package/package.json +5 -5
- package/dist/web/assets/index-B18B2y5o.js +0 -494
- package/dist/web/assets/index-jGBbXx9R.css +0 -32
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as fsp from "node:fs/promises";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { isAgentProjectScanIgnoredDir } from "./agent-project-discovery.js";
|
|
5
|
+
import { normalizeWatchPath } from "./canvas-watcher.js";
|
|
6
|
+
import { snapshotWorkspaceWorkflowsAsync } from "./workspace-watcher.js";
|
|
7
|
+
const SOURCE_DEBOUNCE_MS = 150;
|
|
8
|
+
const INVENTORY_DEBOUNCE_MS = 250;
|
|
9
|
+
const INVENTORY_RETRY_BASE_MS = 500;
|
|
10
|
+
const MAX_INVENTORY_RETRIES = 3;
|
|
11
|
+
const POLL_INTERVAL_MS = 2000;
|
|
12
|
+
const SOURCE_EXTENSIONS = new Set([".ts", ".tsx"]);
|
|
13
|
+
const UNREADABLE_SOURCE_FINGERPRINT = "<unreadable>";
|
|
14
|
+
function ignoredRelativePath(relativePath) {
|
|
15
|
+
return relativePath
|
|
16
|
+
.split("/")
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.some((segment) => isAgentProjectScanIgnoredDir(segment));
|
|
19
|
+
}
|
|
20
|
+
function sourceRelativePath(relativePath) {
|
|
21
|
+
return (!ignoredRelativePath(relativePath) &&
|
|
22
|
+
SOURCE_EXTENSIONS.has(path.extname(relativePath)));
|
|
23
|
+
}
|
|
24
|
+
function confinedSourcePath(root, relativePath) {
|
|
25
|
+
const absolute = path.resolve(root, relativePath);
|
|
26
|
+
const relative = path.relative(root, absolute);
|
|
27
|
+
if (relative === ".." ||
|
|
28
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
29
|
+
path.isAbsolute(relative)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return absolute;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Async source fingerprint for the registered agent roots in one workspace.
|
|
36
|
+
*
|
|
37
|
+
* The graph watcher deliberately does not reuse Canvas's synchronous,
|
|
38
|
+
* 400-file project snapshot here: a workspace can contain many agent projects,
|
|
39
|
+
* and polling it on the server event loop would both stutter Studio and miss
|
|
40
|
+
* edits after that project-sized ceiling. Async directory reads yield between
|
|
41
|
+
* entries, while scoping the walk to registry roots keeps the unbounded file
|
|
42
|
+
* count honest without traversing unrelated workspace trees.
|
|
43
|
+
*/
|
|
44
|
+
export async function snapshotWorkflowSourceRootsAsync(sourceRoots) {
|
|
45
|
+
const roots = [
|
|
46
|
+
...new Set(sourceRoots.map((root) => path.resolve(root))),
|
|
47
|
+
].sort();
|
|
48
|
+
const snapshots = new Map();
|
|
49
|
+
const walk = async (dir, parts) => {
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
parts.push(`${dir}\0${UNREADABLE_SOURCE_FINGERPRINT}`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
const full = path.join(dir, entry.name);
|
|
60
|
+
if (entry.isDirectory()) {
|
|
61
|
+
if (isAgentProjectScanIgnoredDir(entry.name))
|
|
62
|
+
continue;
|
|
63
|
+
await walk(full, parts);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!entry.isFile() || !SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const stat = await fsp.stat(full);
|
|
71
|
+
parts.push(`${full}:${stat.mtimeMs}:${stat.size}`);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
parts.push(`${full}:gone`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
for (const root of roots) {
|
|
79
|
+
const parts = [`root\0${root}`];
|
|
80
|
+
await walk(root, parts);
|
|
81
|
+
snapshots.set(root, parts.sort().join("|"));
|
|
82
|
+
}
|
|
83
|
+
return snapshots;
|
|
84
|
+
}
|
|
85
|
+
function isNestedSourceRoot(parent, candidate) {
|
|
86
|
+
const relative = path.relative(parent, candidate);
|
|
87
|
+
return (relative !== "" &&
|
|
88
|
+
relative !== ".." &&
|
|
89
|
+
!relative.startsWith(`..${path.sep}`) &&
|
|
90
|
+
!path.isAbsolute(relative));
|
|
91
|
+
}
|
|
92
|
+
function changedSourceRoots(previous, current) {
|
|
93
|
+
const changed = [...new Set([...previous.keys(), ...current.keys()])].filter((root) => previous.get(root) !== current.get(root));
|
|
94
|
+
// Nested registered projects appear in their parent's recursive snapshot.
|
|
95
|
+
// Attribute the edit only to the deepest changed caller(s).
|
|
96
|
+
return changed
|
|
97
|
+
.filter((root) => !changed.some((candidate) => candidate !== root && isNestedSourceRoot(root, candidate)))
|
|
98
|
+
.sort();
|
|
99
|
+
}
|
|
100
|
+
class WorkspaceSystemGraphWatcher {
|
|
101
|
+
constructor(scope, callbacks, options, initialInventorySnapshot) {
|
|
102
|
+
this.scope = scope;
|
|
103
|
+
this.callbacks = callbacks;
|
|
104
|
+
this.options = options;
|
|
105
|
+
this.watcher = null;
|
|
106
|
+
this.pollTimer = null;
|
|
107
|
+
this.sourceTimer = null;
|
|
108
|
+
this.inventoryTimer = null;
|
|
109
|
+
this.inventoryRetryTimer = null;
|
|
110
|
+
this.closed = false;
|
|
111
|
+
this.sourcePaths = new Set();
|
|
112
|
+
this.ambiguousSourceChange = false;
|
|
113
|
+
this.lastSourceSnapshots = null;
|
|
114
|
+
this.failedInventorySnapshot = null;
|
|
115
|
+
this.inventoryGeneration = 0;
|
|
116
|
+
this.inventoryCheckInFlight = false;
|
|
117
|
+
this.inventoryCheckPending = false;
|
|
118
|
+
this.pollInFlight = false;
|
|
119
|
+
this.callbackQueue = Promise.resolve();
|
|
120
|
+
this.lastInventorySnapshot = initialInventorySnapshot;
|
|
121
|
+
this.arm();
|
|
122
|
+
}
|
|
123
|
+
static async create(scope, callbacks, options) {
|
|
124
|
+
// Establish the native/polling watcher from an async baseline. The graph
|
|
125
|
+
// route awaits this factory, so no synchronous workspace walk runs on the
|
|
126
|
+
// server loop before the watcher starts.
|
|
127
|
+
const initialInventorySnapshot = await snapshotWorkspaceWorkflowsAsync(scope.root);
|
|
128
|
+
return new WorkspaceSystemGraphWatcher(scope, callbacks, options, initialInventorySnapshot);
|
|
129
|
+
}
|
|
130
|
+
enqueue(callback, onFailure) {
|
|
131
|
+
this.callbackQueue = this.callbackQueue.then(async () => {
|
|
132
|
+
if (this.closed)
|
|
133
|
+
return;
|
|
134
|
+
try {
|
|
135
|
+
await callback();
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Watch callbacks are refresh hints. A failed scan/build must not tear
|
|
139
|
+
// down the watcher or affect the rest of Studio.
|
|
140
|
+
try {
|
|
141
|
+
onFailure?.();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Failure recovery is best-effort too.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
scheduleSourceChange(sourcePath) {
|
|
150
|
+
if (this.closed)
|
|
151
|
+
return;
|
|
152
|
+
if (sourcePath === null)
|
|
153
|
+
this.ambiguousSourceChange = true;
|
|
154
|
+
else
|
|
155
|
+
this.sourcePaths.add(sourcePath);
|
|
156
|
+
if (this.sourceTimer)
|
|
157
|
+
clearTimeout(this.sourceTimer);
|
|
158
|
+
this.sourceTimer = setTimeout(() => {
|
|
159
|
+
this.sourceTimer = null;
|
|
160
|
+
const paths = this.ambiguousSourceChange
|
|
161
|
+
? null
|
|
162
|
+
: [...this.sourcePaths].sort();
|
|
163
|
+
this.sourcePaths.clear();
|
|
164
|
+
this.ambiguousSourceChange = false;
|
|
165
|
+
this.enqueue(() => this.callbacks.onSourceChange(this.scope, paths));
|
|
166
|
+
}, this.options.sourceDebounceMs ?? SOURCE_DEBOUNCE_MS);
|
|
167
|
+
}
|
|
168
|
+
dispatchInventoryChange(snapshot, retryNumber = 0, retryGeneration) {
|
|
169
|
+
const generation = retryGeneration ?? this.inventoryGeneration + 1;
|
|
170
|
+
if (retryGeneration !== undefined &&
|
|
171
|
+
retryGeneration !== this.inventoryGeneration) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (retryGeneration === undefined) {
|
|
175
|
+
this.inventoryGeneration = generation;
|
|
176
|
+
if (this.inventoryRetryTimer)
|
|
177
|
+
clearTimeout(this.inventoryRetryTimer);
|
|
178
|
+
this.inventoryRetryTimer = null;
|
|
179
|
+
}
|
|
180
|
+
this.lastInventorySnapshot = snapshot;
|
|
181
|
+
this.failedInventorySnapshot = null;
|
|
182
|
+
this.enqueue(() => {
|
|
183
|
+
if (generation !== this.inventoryGeneration)
|
|
184
|
+
return;
|
|
185
|
+
return this.callbacks.onInventoryChange(this.scope);
|
|
186
|
+
}, () => {
|
|
187
|
+
if (this.closed ||
|
|
188
|
+
generation !== this.inventoryGeneration ||
|
|
189
|
+
this.lastInventorySnapshot !== snapshot) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (retryNumber >=
|
|
193
|
+
(this.options.maxInventoryRetries ?? MAX_INVENTORY_RETRIES)) {
|
|
194
|
+
// Consume the observed fingerprint after bounded recovery. This
|
|
195
|
+
// leaves the server snapshot stale without turning polling into a
|
|
196
|
+
// permanent registry-scan/event-bus loop. A later real source or
|
|
197
|
+
// inventory change clears this sentinel and starts a fresh series.
|
|
198
|
+
this.failedInventorySnapshot = snapshot;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
this.scheduleInventoryRetry(snapshot, retryNumber + 1, generation);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
scheduleInventoryRetry(snapshot, retryNumber, generation) {
|
|
205
|
+
if (this.closed || generation !== this.inventoryGeneration)
|
|
206
|
+
return;
|
|
207
|
+
if (this.inventoryRetryTimer)
|
|
208
|
+
clearTimeout(this.inventoryRetryTimer);
|
|
209
|
+
const delay = (this.options.inventoryRetryBaseMs ?? INVENTORY_RETRY_BASE_MS) *
|
|
210
|
+
2 ** (retryNumber - 1);
|
|
211
|
+
this.inventoryRetryTimer = setTimeout(() => {
|
|
212
|
+
this.inventoryRetryTimer = null;
|
|
213
|
+
if (this.closed || generation !== this.inventoryGeneration)
|
|
214
|
+
return;
|
|
215
|
+
void snapshotWorkspaceWorkflowsAsync(this.scope.root)
|
|
216
|
+
.then((currentSnapshot) => {
|
|
217
|
+
if (this.closed || generation !== this.inventoryGeneration)
|
|
218
|
+
return;
|
|
219
|
+
if (currentSnapshot !== snapshot) {
|
|
220
|
+
this.dispatchInventoryChange(currentSnapshot);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.dispatchInventoryChange(snapshot, retryNumber, generation);
|
|
224
|
+
})
|
|
225
|
+
.catch(() => {
|
|
226
|
+
if (this.closed || generation !== this.inventoryGeneration)
|
|
227
|
+
return;
|
|
228
|
+
this.dispatchInventoryChange(snapshot, retryNumber, generation);
|
|
229
|
+
});
|
|
230
|
+
}, delay);
|
|
231
|
+
}
|
|
232
|
+
scheduleInventoryCheck(delay = this.options.inventoryDebounceMs ?? INVENTORY_DEBOUNCE_MS) {
|
|
233
|
+
if (this.closed)
|
|
234
|
+
return;
|
|
235
|
+
if (this.inventoryTimer)
|
|
236
|
+
clearTimeout(this.inventoryTimer);
|
|
237
|
+
this.inventoryTimer = setTimeout(() => {
|
|
238
|
+
this.inventoryTimer = null;
|
|
239
|
+
this.checkInventoryAsync();
|
|
240
|
+
}, delay);
|
|
241
|
+
}
|
|
242
|
+
checkInventoryAsync() {
|
|
243
|
+
if (this.closed)
|
|
244
|
+
return;
|
|
245
|
+
if (this.inventoryCheckInFlight) {
|
|
246
|
+
// One more async pass after the current walk is enough to cover any
|
|
247
|
+
// number of native events that arrive while it yields between dirs.
|
|
248
|
+
this.inventoryCheckPending = true;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.inventoryCheckInFlight = true;
|
|
252
|
+
this.inventoryCheckPending = false;
|
|
253
|
+
void snapshotWorkspaceWorkflowsAsync(this.scope.root)
|
|
254
|
+
.then((snapshot) => {
|
|
255
|
+
if (this.closed)
|
|
256
|
+
return;
|
|
257
|
+
if (snapshot === this.lastInventorySnapshot &&
|
|
258
|
+
snapshot !== this.failedInventorySnapshot) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.dispatchInventoryChange(snapshot);
|
|
262
|
+
})
|
|
263
|
+
.catch(() => {
|
|
264
|
+
// A later native event retries an unreadable workspace. Watch hints
|
|
265
|
+
// must never surface as an unhandled rejection or tear down Studio.
|
|
266
|
+
})
|
|
267
|
+
.finally(() => {
|
|
268
|
+
this.inventoryCheckInFlight = false;
|
|
269
|
+
if (this.closed || !this.inventoryCheckPending)
|
|
270
|
+
return;
|
|
271
|
+
this.inventoryCheckPending = false;
|
|
272
|
+
this.checkInventoryAsync();
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
arm() {
|
|
276
|
+
if (this.closed)
|
|
277
|
+
return;
|
|
278
|
+
if (this.options.forcePolling) {
|
|
279
|
+
this.fallBackToPolling();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
const listener = (_event, rawFilename) => {
|
|
284
|
+
if (rawFilename === null) {
|
|
285
|
+
this.scheduleSourceChange(null);
|
|
286
|
+
this.scheduleInventoryCheck();
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const relativePath = normalizeWatchPath(rawFilename);
|
|
290
|
+
if (ignoredRelativePath(relativePath))
|
|
291
|
+
return;
|
|
292
|
+
if (sourceRelativePath(relativePath)) {
|
|
293
|
+
this.scheduleSourceChange(confinedSourcePath(this.scope.root, relativePath));
|
|
294
|
+
}
|
|
295
|
+
// Event kind is unreliable across editors/platforms. The marker
|
|
296
|
+
// fingerprint decides whether inventory really changed.
|
|
297
|
+
this.scheduleInventoryCheck();
|
|
298
|
+
};
|
|
299
|
+
this.watcher = this.options.watchFactory
|
|
300
|
+
? this.options.watchFactory(this.scope.root, listener)
|
|
301
|
+
: fs.watch(this.scope.root, { recursive: true }, (_event, rawFilename) => {
|
|
302
|
+
listener(_event, rawFilename);
|
|
303
|
+
});
|
|
304
|
+
this.watcher.on("error", () => this.fallBackToPolling());
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
this.fallBackToPolling();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
fallBackToPolling() {
|
|
311
|
+
if (this.closed || this.pollTimer)
|
|
312
|
+
return;
|
|
313
|
+
let refreshAfterInitialSnapshot = this.watcher !== null;
|
|
314
|
+
this.watcher?.close();
|
|
315
|
+
this.watcher = null;
|
|
316
|
+
const poll = () => {
|
|
317
|
+
if (this.closed || this.pollInFlight)
|
|
318
|
+
return;
|
|
319
|
+
this.pollInFlight = true;
|
|
320
|
+
let sourceRoots = [];
|
|
321
|
+
try {
|
|
322
|
+
sourceRoots = this.callbacks.listSourceRoots(this.scope);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
// Registry reads are hints too. Inventory polling still proceeds.
|
|
326
|
+
}
|
|
327
|
+
void Promise.all([
|
|
328
|
+
snapshotWorkflowSourceRootsAsync(sourceRoots),
|
|
329
|
+
snapshotWorkspaceWorkflowsAsync(this.scope.root),
|
|
330
|
+
])
|
|
331
|
+
.then(([sourceSnapshots, inventorySnapshot]) => {
|
|
332
|
+
if (this.closed)
|
|
333
|
+
return;
|
|
334
|
+
const changedRoots = this.lastSourceSnapshots
|
|
335
|
+
? changedSourceRoots(this.lastSourceSnapshots, sourceSnapshots)
|
|
336
|
+
: [];
|
|
337
|
+
const ambiguousInitialChange = this.lastSourceSnapshots === null && refreshAfterInitialSnapshot;
|
|
338
|
+
const sourceChanged = ambiguousInitialChange || changedRoots.length > 0;
|
|
339
|
+
this.lastSourceSnapshots = sourceSnapshots;
|
|
340
|
+
refreshAfterInitialSnapshot = false;
|
|
341
|
+
if (ambiguousInitialChange)
|
|
342
|
+
this.scheduleSourceChange(null);
|
|
343
|
+
else {
|
|
344
|
+
for (const sourceRoot of changedRoots) {
|
|
345
|
+
this.scheduleSourceChange(sourceRoot);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (inventorySnapshot !== this.lastInventorySnapshot) {
|
|
349
|
+
this.dispatchInventoryChange(inventorySnapshot);
|
|
350
|
+
}
|
|
351
|
+
else if (sourceChanged &&
|
|
352
|
+
inventorySnapshot === this.failedInventorySnapshot) {
|
|
353
|
+
// Polling has no raw filesystem event. A source-fingerprint change
|
|
354
|
+
// is its proof that a real edit occurred after bounded give-up.
|
|
355
|
+
this.dispatchInventoryChange(inventorySnapshot);
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
.catch(() => {
|
|
359
|
+
// The next poll retries an unreadable workspace.
|
|
360
|
+
})
|
|
361
|
+
.finally(() => {
|
|
362
|
+
this.pollInFlight = false;
|
|
363
|
+
});
|
|
364
|
+
};
|
|
365
|
+
poll();
|
|
366
|
+
this.pollTimer = setInterval(poll, this.options.pollIntervalMs ?? POLL_INTERVAL_MS);
|
|
367
|
+
}
|
|
368
|
+
close() {
|
|
369
|
+
this.closed = true;
|
|
370
|
+
if (this.sourceTimer)
|
|
371
|
+
clearTimeout(this.sourceTimer);
|
|
372
|
+
if (this.inventoryTimer)
|
|
373
|
+
clearTimeout(this.inventoryTimer);
|
|
374
|
+
if (this.inventoryRetryTimer)
|
|
375
|
+
clearTimeout(this.inventoryRetryTimer);
|
|
376
|
+
if (this.pollTimer)
|
|
377
|
+
clearInterval(this.pollTimer);
|
|
378
|
+
this.watcher?.close();
|
|
379
|
+
this.watcher = null;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/** One watcher per requested workspace, independent of harness sessions. */
|
|
383
|
+
export class SystemGraphWatcherManager {
|
|
384
|
+
constructor(callbacks, options = {}) {
|
|
385
|
+
this.callbacks = callbacks;
|
|
386
|
+
this.options = options;
|
|
387
|
+
this.watchers = new Map();
|
|
388
|
+
this.pendingStarts = new Map();
|
|
389
|
+
}
|
|
390
|
+
start(scope) {
|
|
391
|
+
const existing = this.watchers.get(scope.workspaceKey);
|
|
392
|
+
if (existing?.scope.root === scope.root)
|
|
393
|
+
return Promise.resolve();
|
|
394
|
+
const pending = this.pendingStarts.get(scope.workspaceKey);
|
|
395
|
+
if (pending?.root === scope.root)
|
|
396
|
+
return pending.promise;
|
|
397
|
+
this.stop(scope.workspaceKey);
|
|
398
|
+
const token = {};
|
|
399
|
+
const promise = WorkspaceSystemGraphWatcher.create(scope, this.callbacks, this.options)
|
|
400
|
+
.then((watcher) => {
|
|
401
|
+
const current = this.pendingStarts.get(scope.workspaceKey);
|
|
402
|
+
if (current?.token !== token) {
|
|
403
|
+
watcher.close();
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
this.watchers.set(scope.workspaceKey, watcher);
|
|
407
|
+
})
|
|
408
|
+
.finally(() => {
|
|
409
|
+
if (this.pendingStarts.get(scope.workspaceKey)?.token === token) {
|
|
410
|
+
this.pendingStarts.delete(scope.workspaceKey);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
this.pendingStarts.set(scope.workspaceKey, {
|
|
414
|
+
root: scope.root,
|
|
415
|
+
token,
|
|
416
|
+
promise,
|
|
417
|
+
});
|
|
418
|
+
return promise;
|
|
419
|
+
}
|
|
420
|
+
retain(workspaceKeys) {
|
|
421
|
+
const tracked = new Set([
|
|
422
|
+
...this.watchers.keys(),
|
|
423
|
+
...this.pendingStarts.keys(),
|
|
424
|
+
]);
|
|
425
|
+
for (const workspaceKey of tracked) {
|
|
426
|
+
if (!workspaceKeys.has(workspaceKey))
|
|
427
|
+
this.stop(workspaceKey);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
stop(workspaceKey) {
|
|
431
|
+
this.pendingStarts.delete(workspaceKey);
|
|
432
|
+
this.watchers.get(workspaceKey)?.close();
|
|
433
|
+
this.watchers.delete(workspaceKey);
|
|
434
|
+
}
|
|
435
|
+
stopAll() {
|
|
436
|
+
const tracked = new Set([
|
|
437
|
+
...this.watchers.keys(),
|
|
438
|
+
...this.pendingStarts.keys(),
|
|
439
|
+
]);
|
|
440
|
+
for (const workspaceKey of tracked) {
|
|
441
|
+
this.stop(workspaceKey);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
get size() {
|
|
445
|
+
return this.watchers.size;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=system-graph-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-graph-watcher.js","sourceRoot":"","sources":["../../src/core/system-graph-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SystemGraph, WorkspaceKey, WorkspaceScopeSummary } from "../shared/system-graph.js";
|
|
2
|
+
import { type AgentInventoryProvider, type WorkspaceScope } from "./system-graph-inventory.js";
|
|
3
|
+
import { type AgentRelationshipProvider } from "./system-graph-relationships.js";
|
|
4
|
+
export { HarnessRegistryInventoryProvider } from "./system-graph-inventory.js";
|
|
5
|
+
export type { AgentInventoryItem, AgentInventoryProvider, AgentInventoryResult, AgentInventoryWarning, WorkspaceScope, } from "./system-graph-inventory.js";
|
|
6
|
+
export { CachedAgentRelationshipProvider, SourceAgentRelationshipProvider, } from "./system-graph-relationships.js";
|
|
7
|
+
export type { AgentRelationshipCandidate, AgentRelationshipProvider, AgentRelationshipProviderResult, AgentRelationshipWarning, } from "./system-graph-relationships.js";
|
|
8
|
+
export interface WorkspaceScopeResolver {
|
|
9
|
+
resolve(workspaceKey: WorkspaceKey): Promise<WorkspaceScope | null>;
|
|
10
|
+
}
|
|
11
|
+
export interface WorkspaceScopeCatalog extends WorkspaceScopeResolver {
|
|
12
|
+
list(): Promise<WorkspaceScopeSummary[]>;
|
|
13
|
+
}
|
|
14
|
+
export interface SystemGraphBuilder {
|
|
15
|
+
build(scope: WorkspaceScope): Promise<SystemGraphBuildResult>;
|
|
16
|
+
/** Optional lifecycle hook for builders with workspace-scoped caches. */
|
|
17
|
+
retainWorkspaces?(workspaceKeys: ReadonlySet<WorkspaceKey>): void;
|
|
18
|
+
}
|
|
19
|
+
export interface SystemGraphBuildResult {
|
|
20
|
+
/** Internal cache policy; only graph crosses the HTTP boundary. */
|
|
21
|
+
cacheable: boolean;
|
|
22
|
+
graph: SystemGraph;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolves only roots the running Studio already knows about. A caller cannot
|
|
26
|
+
* manufacture a key and turn the graph endpoint into an arbitrary path scan.
|
|
27
|
+
*/
|
|
28
|
+
export declare class LocalWorkspaceScopeCatalog implements WorkspaceScopeCatalog {
|
|
29
|
+
private readonly listRoots;
|
|
30
|
+
constructor(listRoots: () => readonly string[] | Promise<readonly string[]>);
|
|
31
|
+
list(): Promise<WorkspaceScopeSummary[]>;
|
|
32
|
+
resolve(workspaceKey: WorkspaceKey): Promise<WorkspaceScope | null>;
|
|
33
|
+
}
|
|
34
|
+
export declare class StaticSystemGraphBuilder implements SystemGraphBuilder {
|
|
35
|
+
private readonly inventory;
|
|
36
|
+
private readonly relationships;
|
|
37
|
+
private readonly callersByWorkspace;
|
|
38
|
+
constructor(inventory: AgentInventoryProvider, relationships?: AgentRelationshipProvider);
|
|
39
|
+
build(scope: WorkspaceScope): Promise<SystemGraphBuildResult>;
|
|
40
|
+
retainWorkspaces(workspaceKeys: ReadonlySet<WorkspaceKey>): void;
|
|
41
|
+
private retainRelationshipCallers;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=system-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-graph.d.ts","sourceRoot":"","sources":["../../src/core/system-graph.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,WAAW,EAEX,YAAY,EACZ,qBAAqB,EACtB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAGL,KAAK,yBAAyB,EAE/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC/E,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,+BAA+B,EAC/B,wBAAwB,GACzB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACnE,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9D,yEAAyE;IACzE,gBAAgB,CAAC,CAAC,aAAa,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;CACpB;AAMD;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,qBAAqB;IAEpE,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MACxB,SAAS,MAAM,EAAE,GACjB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAG1B,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAcxC,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAS1E;AA6JD,qBAAa,wBAAyB,YAAW,kBAAkB;IAO/D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAPhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAG/B;gBAGe,SAAS,EAAE,sBAAsB,EACjC,aAAa,GAAE,yBAE/B;IAGG,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAsJnE,gBAAgB,CAAC,aAAa,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,IAAI;IAShE,OAAO,CAAC,yBAAyB;CASlC"}
|