@ours.network/fleet 1.2.0-nightly.73 → 1.2.0-nightly.74

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.
@@ -65,6 +65,14 @@ function identity(path, followLink = false) {
65
65
  }
66
66
  }
67
67
  function within(path, root) { return path === root || path.startsWith(root + sep); }
68
+ /** Lock directories and the claim/reclaim entries derived from their names
69
+ * (`<lock>.claim.<pid>.<uuid>`, `<lock>.reclaim`) are never resources. */
70
+ const lockClaim = /\.claim\.\d+\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$|\.reclaim$/;
71
+ function lockName(name) { return name === '.locks' || name.endsWith('.lock'); }
72
+ function lockArtifact(name) { return lockName(name) || (lockClaim.test(name) && lockName(name.replace(lockClaim, ''))); }
73
+ /** Full discovery is synchronous and lstats every covered directory. Wakes are
74
+ * still delivered promptly, but discovery runs at most once per window. */
75
+ const DISCOVERY_WINDOW_MS = 100;
68
76
  /** Native notifications cover supported local mounts. No idle content scan or
69
77
  * silent claim of coverage after watch failure. Parents survive atomic rename.
70
78
  * Discovery reads directory metadata only, never opens a controller or transcript. */
@@ -87,9 +95,11 @@ export function observeFleetResources(scope, onCommitted, signal) {
87
95
  trustedPaths.add(parent);
88
96
  }
89
97
  const resourceIdentity = (path) => identity(path, trustedPaths.has(path));
98
+ const locks = resolve(stateRoot(), 'locks');
99
+ const ignored = (path) => within(path, locks) || path.split(sep).some(name => lockArtifact(name) || name.endsWith('.tmp'));
90
100
  let state = { protocolVersion: 1, producerGeneration: randomUUID(), position: 0, health: 'healthy' };
91
- let disposed = signal.aborted, queued = false;
92
- let recovery;
101
+ let disposed = signal.aborted, queued = false, discoveredAt = -Infinity;
102
+ let recovery, discovery;
93
103
  let installing = false, installFailure;
94
104
  const cursors = new Set();
95
105
  const watchers = new Map();
@@ -110,6 +120,7 @@ export function observeFleetResources(scope, onCommitted, signal) {
110
120
  const install = () => {
111
121
  installing = true;
112
122
  installFailure = undefined;
123
+ let added = 0;
113
124
  try {
114
125
  const wanted = new Set();
115
126
  const cover = (dir) => {
@@ -131,7 +142,7 @@ export function observeFleetResources(scope, onCommitted, signal) {
131
142
  return;
132
143
  // Ignore sibling noise from ancestor coverage, lock churn and delivery acknowledgements.
133
144
  const changed = filename === null ? dir : resolve(dir, String(filename));
134
- if (changed.split(sep).some(name => name === '.locks' || name.endsWith('.lock') || name.endsWith('.tmp')))
145
+ if (ignored(changed))
135
146
  return;
136
147
  if (paths.some(path => within(changed, path) || within(path, changed)) || (configEnabled && changed === config) || filename === null)
137
148
  wake(filename === null ? undefined : changed);
@@ -145,6 +156,7 @@ export function observeFleetResources(scope, onCommitted, signal) {
145
156
  throw error;
146
157
  }
147
158
  watchers.set(dir, { identity: id, handle });
159
+ added++;
148
160
  handle.on('error', (error) => { if (watchers.get(dir)?.handle === handle)
149
161
  fail(error); });
150
162
  handle.on('close', () => { if (watchers.get(dir)?.handle === handle)
@@ -153,6 +165,8 @@ export function observeFleetResources(scope, onCommitted, signal) {
153
165
  throw installFailure;
154
166
  };
155
167
  const visit = (dir, depth) => {
168
+ if (within(dir, locks))
169
+ return;
156
170
  const id = resourceIdentity(dir);
157
171
  if (!id)
158
172
  return;
@@ -171,7 +185,7 @@ export function observeFleetResources(scope, onCommitted, signal) {
171
185
  throw error;
172
186
  }
173
187
  for (const entry of entries) {
174
- if (!entry.isDirectory() || entry.isSymbolicLink() || entry.name === '.locks' || entry.name.endsWith('.lock'))
188
+ if (!entry.isDirectory() || entry.isSymbolicLink() || lockArtifact(entry.name))
175
189
  continue;
176
190
  visit(join(dir, entry.name), depth - 1);
177
191
  }
@@ -195,6 +209,7 @@ export function observeFleetResources(scope, onCommitted, signal) {
195
209
  }
196
210
  if (installFailure)
197
211
  throw installFailure;
212
+ return added;
198
213
  }
199
214
  finally {
200
215
  installing = false;
@@ -236,21 +251,48 @@ export function observeFleetResources(scope, onCommitted, signal) {
236
251
  queued = false;
237
252
  if (disposed || state.health !== 'healthy')
238
253
  return;
239
- try {
240
- install();
241
- }
242
- catch (error) {
243
- fail(error);
244
- return;
254
+ if (!discovery) {
255
+ const wait = discoveredAt + DISCOVERY_WINDOW_MS - performance.now();
256
+ if (wait <= 0) {
257
+ discover(false);
258
+ return;
259
+ }
260
+ discovery = setTimeout(() => { discovery = undefined; discover(true); }, wait);
261
+ discovery.unref();
245
262
  }
263
+ // Covered directories were watched before this wake; directories created
264
+ // since the last pass are covered by the pending one.
246
265
  onCommitted({ ...state });
247
266
  });
248
267
  };
268
+ const discover = (deferred) => {
269
+ if (disposed || state.health !== 'healthy')
270
+ return;
271
+ discoveredAt = performance.now();
272
+ let added;
273
+ try {
274
+ added = install();
275
+ }
276
+ catch (error) {
277
+ fail(error);
278
+ return;
279
+ }
280
+ // Every wake before a deferred pass was already delivered. Writes into
281
+ // directories it newly covers have no event of their own: treat as unknown.
282
+ if (deferred) {
283
+ if (!added)
284
+ return;
285
+ state = { ...state, position: state.position + 1 };
286
+ for (const cursor of cursors)
287
+ cursor.position = state.position;
288
+ }
289
+ onCommitted({ ...state });
290
+ };
249
291
  const direct = (path) => { if (paths.some(root => within(path, root)) || (configEnabled && path === config))
250
292
  wake(path); };
251
293
  let detach;
252
294
  const dispose = () => { if (disposed)
253
- return; disposed = true; clearTimeout(recovery); recovery = undefined; detach?.(); for (const cursor of [...cursors])
295
+ return; disposed = true; clearTimeout(recovery); recovery = undefined; clearTimeout(discovery); discovery = undefined; detach?.(); for (const cursor of [...cursors])
254
296
  cursor.dispose(); commits.delete(direct); signal.removeEventListener('abort', dispose); release(); };
255
297
  if (!disposed) {
256
298
  commits.add(direct);
@@ -1,9 +1,9 @@
1
1
  {
2
- "version": "1.2.0-nightly.73",
3
- "buildId": "b6b76cb3faf6",
4
- "commit": "45058aae764ba12d712ea74da7bbdb840c497171",
2
+ "version": "1.2.0-nightly.74",
3
+ "buildId": "a3cb6f23464e",
4
+ "commit": "0ada452c41fd1d4d9237f0f86caa11b2dcba6b69",
5
5
  "dirty": true,
6
- "builtAt": "2026-10-18T13:27:24.108Z",
6
+ "builtAt": "2026-10-18T16:29:31.599Z",
7
7
  "capabilities": [
8
8
  "service.refresh-v1",
9
9
  "managed-cli.codex-reasoning-effort-v1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/fleet",
3
- "version": "1.2.0-nightly.73",
3
+ "version": "1.2.0-nightly.74",
4
4
  "description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, managed native/ACP sessions, supervision, and ours.network messaging.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",