trajectories 0.1.2 → 0.1.4

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/dist/convert.d.ts CHANGED
@@ -21,6 +21,14 @@ export declare function readSnapshot(input: {
21
21
  pythonExecutable?: string;
22
22
  }): Promise<Snapshot>;
23
23
  export declare function assertSnapshot(snapshot: Snapshot): void;
24
+ /** Append a post-hoc annotation (judge verdict, review error, first-pointed step)
25
+ * to a finished snapshot. The channel is outside `raw` and every content hash:
26
+ * the snapshot id, source sha256 and record ids are unchanged, so annotations
27
+ * attach without re-normalizing. The result stays valid for assertSnapshot. */
28
+ export declare function annotateSnapshot(snapshot: Snapshot, annotation: {
29
+ kind: string;
30
+ content: string;
31
+ }): Snapshot;
24
32
  /** Complete portable context, stricter than an archive's integrity-only validation. */
25
33
  export declare function assertPortableSnapshot(snapshot: Snapshot): void;
26
34
  export declare function convert(snapshot: Snapshot, target: Harness, options: WriteOptions): NativeExport;
package/dist/convert.js CHANGED
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
2
2
  import { readFile, mkdir, writeFile, realpath } from 'node:fs/promises';
3
3
  import { resolve, dirname, relative, isAbsolute, sep, join, basename } from 'node:path';
4
4
  import { normalizeToCanonical, validateTranscript } from '@letta-ai/trajectory';
5
- import { HARNESSES } from './types.js';
5
+ import { HARNESSES, isNativeHarness } from './types.js';
6
6
  import { createSeededNativeEntropy } from './writers/entropy.js';
7
7
  import { writePi } from './writers/pi.js';
8
8
  import { writeOmp } from './writers/omp.js';
@@ -16,6 +16,7 @@ import { writeGitHubCopilot } from './writers/github-copilot.js';
16
16
  import { writeCline } from './writers/cline.js';
17
17
  import { writeFx } from './writers/fx.js';
18
18
  import { normalizeGrokBuild } from './readers/grok-build.js';
19
+ import { enrichAtifCanonical } from './readers/atif.js';
19
20
  import { readCursor, readCursorNative } from './readers/cursor.js';
20
21
  import { readDeepAgents, readDeepAgentsSeed } from './readers/deepagents.js';
21
22
  import { readCline } from './readers/cline.js';
@@ -212,7 +213,8 @@ function finalizeSnapshot(input, archived, clineCompaction = false) {
212
213
  const invalid = archived.diagnostics.filter(d => d.code === 'invalid_json_line' || d.code === 'non_object_json_line');
213
214
  if (invalid.length)
214
215
  throw new Error(`Invalid native transcript: ${invalid.map(d => d.message).join('; ')}`);
215
- const canonical = input.harness === 'pi' ? projectPiProviderContext(raw, archived) : archived;
216
+ const canonical = input.harness === 'pi' ? projectPiProviderContext(raw, archived)
217
+ : input.harness === 'atif' ? enrichAtifCanonical(raw, archived) : archived;
216
218
  const metadata = provenance(input.harness, canonical);
217
219
  if (input.nativeSessionId && metadata.nativeSessionId !== input.nativeSessionId)
218
220
  throw new Error('Selected native session does not match source provenance.');
@@ -352,12 +354,31 @@ export function assertSnapshot(snapshot) {
352
354
  if (sha256(attachment.content) !== attachment.sha256)
353
355
  throw new Error('Snapshot attachment integrity check failed.');
354
356
  }
357
+ for (const annotation of snapshot.annotations ?? []) {
358
+ if (typeof annotation.kind !== 'string' || !annotation.kind || typeof annotation.content !== 'string'
359
+ || sha256(annotation.content) !== annotation.sha256)
360
+ throw new Error('Snapshot annotation integrity check failed.');
361
+ }
355
362
  for (const record of canonical.records) {
356
363
  if (sha256(record.record_json) !== record.record_hash)
357
364
  throw new Error('Snapshot canonical record integrity check failed.');
358
365
  }
359
366
  validateTranscript(canonical.records.map(r => JSON.parse(r.record_json)));
360
367
  }
368
+ /** Append a post-hoc annotation (judge verdict, review error, first-pointed step)
369
+ * to a finished snapshot. The channel is outside `raw` and every content hash:
370
+ * the snapshot id, source sha256 and record ids are unchanged, so annotations
371
+ * attach without re-normalizing. The result stays valid for assertSnapshot. */
372
+ export function annotateSnapshot(snapshot, annotation) {
373
+ assertSnapshot(snapshot);
374
+ if (typeof annotation?.kind !== 'string' || !annotation.kind.trim())
375
+ throw new Error('Snapshot annotation requires a kind.');
376
+ if (typeof annotation.content !== 'string')
377
+ throw new Error('Snapshot annotation content must be a string.');
378
+ const entry = { kind: annotation.kind, content: annotation.content,
379
+ sha256: sha256(annotation.content), createdAt: new Date().toISOString() };
380
+ return { ...snapshot, annotations: [...(snapshot.annotations ?? []), entry] };
381
+ }
361
382
  /** Complete portable context, stricter than an archive's integrity-only validation. */
362
383
  export function assertPortableSnapshot(snapshot) {
363
384
  assertSnapshot(snapshot);
@@ -385,8 +406,9 @@ export function convertManaged(snapshot, target, options, entropySeed, records)
385
406
  }
386
407
  function convertWithEntropy(snapshot, target, options, entropy, retainedRecords) {
387
408
  assertPortableSnapshot(snapshot);
388
- if (!HARNESSES.includes(target))
389
- throw new Error(`Unsupported target: ${target}`);
409
+ if (!isNativeHarness(target)) {
410
+ throw new Error(HARNESSES.includes(target) ? `Unsupported target: ${target} is a read-only interchange format.` : `Unsupported target: ${target}`);
411
+ }
390
412
  if (!isAbsolute(options.cwd) || !isAbsolute(options.directory))
391
413
  throw new Error('cwd and directory must be absolute paths.');
392
414
  const records = retainedRecords ?? snapshot.canonical.records.map(r => JSON.parse(r.record_json));
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- export { HARNESSES } from './types.js';
2
- export type { Harness, Snapshot, ConversionDiagnostic, WriteOptions, NativeExport, NativeWriter, NativeEntropy } from './types.js';
1
+ export { HARNESSES, NATIVE_HARNESSSES } from './types.js';
2
+ export type { Harness, NativeHarness, Snapshot, SnapshotAnnotation, SnapshotCanonical, ExtendedCanonicalRecord, CanonicalRecordMetadata, ConversionDiagnostic, WriteOptions, NativeExport, NativeWriter, NativeEntropy } from './types.js';
3
3
  export * from './log-types.js';
4
- export { readSnapshot, assertSnapshot, assertPortableSnapshot, convert, writeNativeExport, writeSnapshot } from './convert.js';
4
+ export { readSnapshot, assertSnapshot, assertPortableSnapshot, annotateSnapshot, convert, writeNativeExport, writeSnapshot } from './convert.js';
5
5
  export { createSession, getSession, listSessions, stageCapture, appendCapture, switchSession, readSession, getNativeBinding, getHeadMetadata } from './log.js';
6
6
  export { assertSnapshotContinuation } from './store.js';
7
7
  export { migrateLegacyStore, type MigrationManifest, type MigratedSession } from './migrate.js';
8
+ export { createSharedClient, createSharedHandler, sharedObservationId } from './shared.js';
9
+ export type { ObservedRecord, ObservedSession, ObservedState, ObservedSummary, SharedTransfer, ObservedSyncReceipt, ManagedSyncReceipt } from './shared.js';