@volter/supercode-teams 0.3.193 → 0.3.194

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-teams",
3
- "version": "0.3.193",
3
+ "version": "0.3.194",
4
4
  "type": "module",
5
5
  "description": "A machine daemon serving this machine's doors, and a local or remote Teams server for shared session discovery, OpenTelemetry ingestion and access to enrolled machines.",
6
6
  "license": "MIT",
@@ -84,7 +84,7 @@
84
84
  "@volter/supercode-frontend": "^0.2.2",
85
85
  "@volter/supercode-harness-sdk": "^0.3.58",
86
86
  "@volter/supercode-health": "^0.1.0",
87
- "@volter/supercode-interchange": "0.1.9",
87
+ "@volter/supercode-interchange": "0.1.10",
88
88
  "@volter/supercode-terminal": "^0.2.54",
89
89
  "@volter/supercode-trace": "^0.1.0",
90
90
  "@volter/teams": "0.2.46",
@@ -3,7 +3,7 @@ import * as zlib from 'node:zlib';
3
3
  import { basename, dirname, join, relative, resolve, sep } from 'node:path';
4
4
  import {
5
5
  HARNESSES, resolveHarnessHomes, selectedHarnesses, FILE_HARNESSES, fileRoot,
6
- normalizedSourcePath, pathUnder, sourceStat, sourceEntries, sameFingerprint,
6
+ normalizedSourcePath, pathUnder, sourceStat, sourceEntries, sameFingerprint, fileFingerprint,
7
7
  listSessionParts, sessionPartFor, readFileMetadata, verifySources,
8
8
  selectStoreFiles, storeRegistryDirectories, storeFingerprints,
9
9
  readForeignStore, readHermesStore, readOrchestratorStore, readGeminiProjects,
@@ -29,7 +29,7 @@ export class SessionIndexOwner extends EventEmitter {
29
29
  constructor({ database, env = process.env, log = () => {} }) {
30
30
  super(); requireSessionIndexRuntime(); this.database = database; this.store = new SessionIndexStore(database);
31
31
  this.env = env; this.log = log; this.sources = new Map(); this.pending = new Map();
32
- this.fileCaches = new Map(); this.projections = new Map();
32
+ this.fileCaches = new Map(); this.projections = new Map(); this.notSessions = new Set();
33
33
  this.metrics = {}; this.closed = false; this.running = null;
34
34
  this.watches = new SessionIndexWatches({
35
35
  changed: (id, event) => this.#event(id, event),
@@ -425,8 +425,9 @@ export class SessionIndexOwner extends EventEmitter {
425
425
 
426
426
  async #file(source, path) {
427
427
  const old = source.parts.get(path);
428
+ let info = null;
428
429
  try {
429
- const info = await sourceStat(path);
430
+ info = await sourceStat(path);
430
431
  if (this.closed) return;
431
432
  // Saved Supercode can retain a metadata row after both content files
432
433
  // disappear. Other formats require their native transcript file.
@@ -459,7 +460,24 @@ export class SessionIndexOwner extends EventEmitter {
459
460
  source.parts.set(path, { path, kind: 'file', state, stamps });
460
461
  this.metrics.changed_rows = (this.metrics.changed_rows ?? 0) + changed;
461
462
  } catch (error) {
462
- if (!this.closed) this.store.fail(source.id, path, 'file', error);
463
+ if (this.closed) return;
464
+ if (error?.code === 'not_a_session' && info) return this.#notSession(source, path, old, info, error);
465
+ this.store.fail(source.id, path, 'file', error);
466
+ }
467
+ }
468
+
469
+ /** A file in a harness's folder that is not one of its sessions (no session header) holds no rows and is no
470
+ * failure: it never makes the index, or the machine, unread. Its fingerprint, taken before the read, keeps it from
471
+ * being read again until it changes; the daemon log names it once. */
472
+ #notSession(source, path, old, info, error) {
473
+ const stamps = [{ path, fingerprint: fileFingerprint(info) }];
474
+ const state = { not_session: true, ...(source.harness === 'gemini' ? { projectsStamp: source.projectsStamp } : {}) };
475
+ this.store.commitPart(source.id, path, { kind: 'file', state, stamps, rows: [], invalidate: !sameStamps(stamps, old?.stamps) });
476
+ this.#apply(source, path, []);
477
+ source.parts.set(path, { path, kind: 'file', state, stamps });
478
+ if (!this.notSessions.has(path)) {
479
+ this.notSessions.add(path); this.metrics.not_sessions = this.notSessions.size;
480
+ this.log(`session index: left out ${path}: ${error.message} (${this.notSessions.size} file${this.notSessions.size === 1 ? '' : 's'} left out)`);
463
481
  }
464
482
  }
465
483