@volter/supercode-interchange 0.1.13 → 0.1.15

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/discovery.mjs CHANGED
@@ -3,7 +3,9 @@ import { readLatestCandidates, readFileTopics } from './previews.mjs';
3
3
  import { nativeTrim } from './text.mjs';
4
4
 
5
5
  /** Preview refusal preserves the native metadata row. The owner can retain
6
- * the exact failed source in diagnostics; it never invents message content. */
6
+ * the exact failed source in diagnostics; it never invents message content.
7
+ * A query that shows no message (`include_latest_candidates: false`, with no
8
+ * topics asked) opens no file: its row is the index's own. */
7
9
  export async function enrichDescriptor(query, descriptor, { codexTopics, metrics, previewFailure } = {}) {
8
10
  const row = { ...descriptor };
9
11
  const take = async (read) => {
@@ -17,7 +19,7 @@ export async function enrichDescriptor(query, descriptor, { codexTopics, metrics
17
19
  if (topics.length) row.preview_candidates = topics;
18
20
  else delete row.preview_candidates;
19
21
  }
20
- const latest = await take(() => readLatestCandidates(row.locator, metrics));
22
+ const latest = query.include_latest_candidates === false ? [] : await take(() => readLatestCandidates(row.locator, metrics));
21
23
  if (latest.length) row.latest_message_candidates = latest;
22
24
  else delete row.latest_message_candidates;
23
25
  return row;
@@ -25,6 +27,8 @@ export async function enrichDescriptor(query, descriptor, { codexTopics, metrics
25
27
 
26
28
  /** Bounded enrichment belongs to returned/current-window rows. Metadata
27
29
  * maintenance never invokes this function, including unchanged warm queries. */
30
+ export const readsPreviews = (query) => query.include_latest_candidates !== false || Boolean(query.include_topic_candidates);
31
+
28
32
  export async function enrichIndexPage(query, rows, options) {
29
33
  const result = [];
30
34
  for (const row of rows) result.push(await enrichDescriptor(query, row, options));
package/index.d.ts CHANGED
@@ -29,7 +29,7 @@ export interface DiscoveryQuery {
29
29
  workspace?: string | null; workspace_subtree?: boolean; workspace_family?: string | null;
30
30
  updated_after_ms?: number | null; updated_before_ms?: number | null;
31
31
  query?: string | null; search_previews?: boolean; cursor?: string | null; limit?: number | null;
32
- include_topic_candidates?: boolean; include_child_sessions?: boolean;
32
+ include_topic_candidates?: boolean; include_latest_candidates?: boolean; include_child_sessions?: boolean;
33
33
  root_session_id?: string | null; profile?: string | null;
34
34
  }
35
35
  export interface DiscoveryReceipt {
@@ -83,6 +83,8 @@ export function fileRoot(harness: HarnessId, homes: HarnessHomes): string | null
83
83
  export function sessionPartFor(harness: HarnessId, root: string, path: string): Promise<string | null>;
84
84
  export function listSessionParts(harness: HarnessId, root: string, options?: { folder?: string; beforeDirectory?: (path: string) => Promise<void>; metrics?: IndexMetrics }): Promise<{ parts: Set<string>; directories: Set<string> }>;
85
85
  export function readFileMetadata(harness: HarnessId, root: string, path: string, options?: { previous?: FileReadCache; projects?: Map<string, string>; nativeTopic?: (path: string, id: string) => string | null; metrics?: IndexMetrics }): Promise<{ descriptor: SessionDescriptor | null; cache: FileReadCache | null }>;
86
+ /** The version of a harness's metadata reader; a part read by another version is read again. */
87
+ export function metadataReaderVersion(harness: HarnessId): number;
86
88
  export function sourceStat(path: string): Promise<import('node:fs').BigIntStats | null>;
87
89
  export function sourceEntries(path: string): Promise<string[]>;
88
90
  export function selectStoreFiles(harness: HarnessId, homes: HarnessHomes): Promise<Array<{ path: string; profile: string | null }>>;
@@ -108,6 +110,7 @@ export interface DiscoveryEnrichmentOptions extends MetadataProjectionOptions {
108
110
  lateClaudeName?: (name: string) => Promise<string | null>;
109
111
  }
110
112
  export function enrichDescriptor(query: DiscoveryQuery, descriptor: SessionDescriptor, options?: DiscoveryEnrichmentOptions): Promise<SessionDescriptor>;
113
+ export function readsPreviews(query: DiscoveryQuery): boolean;
111
114
  export function enrichIndexPage(query: DiscoveryQuery, descriptors: SessionDescriptor[], options?: DiscoveryEnrichmentOptions): Promise<SessionDescriptor[]>;
112
115
  export function discoverFromIndex(query: DiscoveryQuery, descriptors: Iterable<SessionDescriptor>, options?: DiscoveryEnrichmentOptions): Promise<DiscoveryPage>;
113
116
  export function nativeTrim(value: string): string;
@@ -115,6 +118,8 @@ export interface IndexMetadataRecord {
115
118
  source: string; part: string; row_key: string; descriptor: SessionDescriptor;
116
119
  mirror?: { harness: string | null; messages: number | null; continued: boolean; count: number } | null;
117
120
  }
121
+ /** Whether a row stands for the session its key names: false for one that names that same key as its parent. */
122
+ export function filedUnderOwnKey(descriptor: SessionDescriptor): boolean;
118
123
  export class RetainedMetadataProjection {
119
124
  constructor(query: DiscoveryQuery, sources: string[], records: Iterable<IndexMetadataRecord>, metrics?: IndexMetrics);
120
125
  updatePart(source: string, part: string, records: Iterable<IndexMetadataRecord>): void;
package/index.mjs CHANGED
@@ -5,7 +5,7 @@ export {
5
5
  encodeDiscoveryCursor, decodeDiscoveryCursor, paginateDescriptors,
6
6
  discoveryReceipt, projectMetadataPage,
7
7
  } from './query.mjs';
8
- export { FILE_HARNESSES, STORE_HARNESSES, normalizedSourcePath, pathUnder, fileRoot, sessionPartFor, listSessionParts, readFileMetadata } from './source-layout.mjs';
8
+ export { FILE_HARNESSES, STORE_HARNESSES, normalizedSourcePath, pathUnder, fileRoot, sessionPartFor, listSessionParts, readFileMetadata, metadataReaderVersion } from './source-layout.mjs';
9
9
  export { sourceStat, sourceEntries, selectStoreFiles, storeRegistryDirectories } from './store-registry.mjs';
10
10
  export { fileFingerprint, sameFingerprint } from './file-io.mjs';
11
11
  export { verifySources, readGeminiProjects, readSourceJson } from './source-files.mjs';
@@ -14,7 +14,7 @@ export { readForeignStore } from './foreign-store.mjs';
14
14
  export { readHermesStore } from './hermes-store.mjs';
15
15
  export { readOrchestratorStore } from './orchestrator-store.mjs';
16
16
  export { codexNamesPath, readCodexNames, readCodexHistory, readClaudeTitles } from './native-ledgers.mjs';
17
- export { enrichDescriptor, enrichIndexPage, discoverFromIndex } from './discovery.mjs';
17
+ export { enrichDescriptor, enrichIndexPage, readsPreviews, discoverFromIndex } from './discovery.mjs';
18
18
  export { nativeInteger } from './native-json.mjs';
19
19
  export { nativeTrim } from './text.mjs';
20
- export { RetainedMetadataProjection } from './retained-projection.mjs';
20
+ export { RetainedMetadataProjection, filedUnderOwnKey } from './retained-projection.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-interchange",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "type": "module",
5
5
  "description": "Read-only harness metadata, transcript codecs and session projections for Supercode",
6
6
  "license": "MIT OR Apache-2.0",
@@ -4,6 +4,10 @@ const order = (a, b) => a.rank - b.rank || Buffer.compare(Buffer.from(a.part), B
4
4
  || Buffer.compare(Buffer.from(a.row_key), Buffer.from(b.row_key));
5
5
  const originKey = (row) => JSON.stringify([row.source, row.part, row.row_key]);
6
6
  const partKey = (source, part) => JSON.stringify([source, part]);
7
+ /** A row naming its own key as its parent is another transcript filed under that key (a child's file that carries
8
+ * its parent's id). It never stands for the session, whatever reader wrote it and whichever part sorts last. */
9
+ export const filedUnderOwnKey = (descriptor) => descriptor.parent_session_id == null
10
+ || descriptor.parent_session_id !== descriptor.locator.session_id;
7
11
 
8
12
  /** A retained query owns one ordered metadata projection, shared by windows
9
13
  * with the same filters. An ordinary part update replaces only its connected
@@ -33,7 +37,8 @@ export class RetainedMetadataProjection {
33
37
  }
34
38
 
35
39
  #winner(key) {
36
- const candidates = [...(this.candidates.get(key) ?? [])].map((origin) => this.origins.get(origin)).sort(order);
40
+ const candidates = [...(this.candidates.get(key) ?? [])].map((origin) => this.origins.get(origin))
41
+ .filter((row) => filedUnderOwnKey(row.descriptor)).sort(order);
37
42
  if (!candidates.length) { this.raw.delete(key); return; }
38
43
  // snapshot's deduplication keeps the last value, but the first occurrence
39
44
  // determines map iteration order (including native cross-harness families).
package/source-layout.mjs CHANGED
@@ -82,6 +82,13 @@ export async function listSessionParts(harness, root, { folder = root, beforeDir
82
82
  return { parts, directories };
83
83
  }
84
84
 
85
+ /** Each harness's metadata reader version, 1 where none is named. A change that makes a reader name a session
86
+ * differently from the same bytes (its key, its parent, the facts of its header) raises that harness's number: the
87
+ * daemon keeps the version each part was read with and reads again every part an older reader wrote
88
+ * (session-index-owner.mjs), since a file whose stamps hold is otherwise never read twice. */
89
+ const METADATA_READERS = { 'claude-code': 2 };
90
+ export const metadataReaderVersion = (harness) => METADATA_READERS[harness] ?? 1;
91
+
85
92
  /** All readers return one cache/descriptor unit. Cache identities and offsets
86
93
  * are committed beside the descriptor by the daemon, never by this library. */
87
94
  export async function readFileMetadata(harness, root, path, { previous, projects, nativeTopic, metrics = {} } = {}) {