agentcache 0.4.2 → 0.5.0-beta.2

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.
Files changed (38) hide show
  1. package/README.md +282 -151
  2. package/dist/{chunk-T4COG3XD.js → chunk-R5I6WWSD.js} +31 -14
  3. package/dist/chunk-RXGW4Q3G.js +109 -0
  4. package/dist/chunk-XRJ6QW6N.js +92 -0
  5. package/dist/chunk-YKG6CDGT.js +1818 -0
  6. package/dist/chunk-YY7QXBG5.js +6610 -0
  7. package/dist/cli.js +2535 -292
  8. package/dist/device-id-RV7RO5RB.js +7 -0
  9. package/dist/ide-detector-ETGAVVXO.js +8 -0
  10. package/dist/mcp.d.ts +734 -2
  11. package/dist/mcp.js +1126 -446
  12. package/dist/{paths-5LZRKNYY.js → paths-NTZ2357O.js} +3 -2
  13. package/dist/postinstall.js +1 -65
  14. package/dist/setup-7JJPW3VG.js +48 -0
  15. package/docs/compatibility.md +152 -0
  16. package/docs/demo-script.md +121 -0
  17. package/docs/launch-copy.md +125 -0
  18. package/docs/privacy.md +173 -0
  19. package/docs/troubleshooting.md +209 -0
  20. package/package.json +32 -14
  21. package/dist/3-canonicalizer-HIN2F7SZ.js +0 -11
  22. package/dist/chunk-5UO7NJPQ.js +0 -71
  23. package/dist/chunk-CUBZRYS5.js +0 -580
  24. package/dist/chunk-GGAATZKM.js +0 -120
  25. package/dist/chunk-JUDLOBOC.js +0 -77
  26. package/dist/chunk-KFQGP6VL.js +0 -33
  27. package/dist/chunk-PSASDZQE.js +0 -490
  28. package/dist/chunk-SLRKWMSE.js +0 -202
  29. package/dist/chunk-T7BJPANN.js +0 -45
  30. package/dist/chunk-WTXSZBQE.js +0 -388
  31. package/dist/compile-all-PTWTZVP5.js +0 -495
  32. package/dist/ide-detector-5TRCR4F5.js +0 -7
  33. package/dist/pre-tool-use-A4AJHZOJ.js +0 -30
  34. package/dist/session-start-DGMGEAJU.js +0 -78
  35. package/dist/setup-CVG35TUZ.js +0 -51
  36. package/dist/sqlite-NM2BVHUY.js +0 -7
  37. package/dist/stop-WGGRX6TQ.js +0 -38
  38. package/dist/transcript-JWSGSDSF.js +0 -24
package/dist/mcp.d.ts CHANGED
@@ -1,3 +1,735 @@
1
- declare function startMcpServer(): Promise<void>;
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
2
3
 
3
- export { startMcpServer };
4
+ declare const SESSION_SCHEMA_VERSION: 1;
5
+ type JsonPrimitive = string | number | boolean | null;
6
+ type JsonValue = JsonPrimitive | JsonValue[] | {
7
+ [key: string]: JsonValue;
8
+ };
9
+ type JsonObject = {
10
+ [key: string]: JsonValue;
11
+ };
12
+ /**
13
+ * Known adapters remain autocomplete-friendly while third-party adapters can
14
+ * participate without requiring a domain-model release.
15
+ */
16
+ type AdapterId = "claude-code" | "cursor" | "roo-code" | "windsurf" | "continue" | "codex" | "goose" | (string & {});
17
+ type SessionState = "active" | "checkpointed" | "closed" | "archived";
18
+ type ClientLegState = "attached" | "completed" | "orphaned";
19
+ type SessionEventKind = "message.user" | "message.assistant" | "tool.call" | "tool.result" | "checkpoint" | "correction" | "tombstone";
20
+ type SessionEventRole = "user" | "assistant" | "tool";
21
+ type RedactionState = "none" | "redacted" | "omitted";
22
+ type HandoffMode = "continue" | "fork";
23
+ type SourceCursorStatus = "active" | "out-of-sync" | "malformed" | "unsupported";
24
+ /** Source facts emitted by adapters before persistence concerns are applied. */
25
+ interface NormalizedEventInput {
26
+ sourceEventId: string;
27
+ sourceSequence?: number;
28
+ kind: SessionEventKind;
29
+ role?: SessionEventRole;
30
+ occurredAt: number;
31
+ textContent?: string;
32
+ payload?: Record<string, unknown>;
33
+ }
34
+ interface PortableSession {
35
+ sessionId: string;
36
+ workspaceId: string | null;
37
+ title: string;
38
+ status: SessionState;
39
+ createdAt: number;
40
+ updatedAt: number;
41
+ headEventId: string | null;
42
+ headSequence: number;
43
+ headCheckpointId: string | null;
44
+ metadata: JsonObject;
45
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
46
+ }
47
+ interface ClientLeg {
48
+ legId: string;
49
+ sessionId: string;
50
+ deviceId: string;
51
+ adapterId: AdapterId;
52
+ nativeSessionId: string | null;
53
+ clientVersion: string | null;
54
+ model: string | null;
55
+ workspaceLocationId: string | null;
56
+ resumedFromCheckpointId: string | null;
57
+ state: ClientLegState;
58
+ startedAt: number;
59
+ endedAt: number | null;
60
+ metadata: JsonObject;
61
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
62
+ }
63
+ interface SessionEvent {
64
+ eventId: string;
65
+ sessionId: string;
66
+ legId: string;
67
+ timelineSequence: number;
68
+ sourceEventId: string;
69
+ sourceSequence: number | null;
70
+ parentEventId: string | null;
71
+ kind: SessionEventKind;
72
+ role: SessionEventRole | null;
73
+ occurredAt: number;
74
+ ingestedAt: number;
75
+ textContent: string | null;
76
+ payload: JsonObject;
77
+ contentHash: string;
78
+ redactionState: RedactionState;
79
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
80
+ }
81
+ interface CheckpointState {
82
+ objective: string;
83
+ completedWork: string[];
84
+ openWork: string[];
85
+ blockers: string[];
86
+ explicitConstraints: string[];
87
+ decisions: string[];
88
+ rejectedApproaches: string[];
89
+ nextStep: string | null;
90
+ }
91
+ interface CheckpointWorkspaceState {
92
+ gitBranch: string | null;
93
+ gitCommit: string | null;
94
+ repositoryRelativePaths: string[];
95
+ }
96
+ interface SessionCheckpoint {
97
+ checkpointId: string;
98
+ sessionId: string;
99
+ createdByLegId: string;
100
+ throughEventId: string;
101
+ throughSequence: number;
102
+ summaryText: string;
103
+ state: CheckpointState;
104
+ workspaceState: CheckpointWorkspaceState;
105
+ generator: string;
106
+ createdAt: number;
107
+ contentHash: string;
108
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
109
+ }
110
+ interface SessionFork {
111
+ forkSessionId: string;
112
+ parentSessionId: string;
113
+ forkedFromEventId: string;
114
+ createdByLegId: string | null;
115
+ reason: string | null;
116
+ createdAt: number;
117
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
118
+ }
119
+ interface SourceCursor {
120
+ sourceId: string;
121
+ legId: string;
122
+ deviceId: string;
123
+ adapterId: AdapterId;
124
+ locator: string;
125
+ sourceFingerprint: string;
126
+ cursorKind: string;
127
+ cursorValue: string;
128
+ lastSourceEventId: string | null;
129
+ parserVersion: string;
130
+ lastSeenAt: number;
131
+ status: SourceCursorStatus;
132
+ lastError: string | null;
133
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
134
+ }
135
+ interface Handoff {
136
+ handoffId: string;
137
+ sessionId: string;
138
+ checkpointId: string;
139
+ workspaceId: string;
140
+ targetAdapterId: AdapterId;
141
+ mode: HandoffMode;
142
+ tokenHash: string;
143
+ createdAt: number;
144
+ expiresAt: number;
145
+ consumedAt: number | null;
146
+ createdHeadSequence: number;
147
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
148
+ allowsLeaseTakeover: boolean;
149
+ expectedSourceLeaseGeneration: number | null;
150
+ expectedSourceLeaseTokenHash: string | null;
151
+ forkTitle: string | null;
152
+ forkReason: string | null;
153
+ /** Exact immutable capsule previewed before this handoff token is disclosed. */
154
+ capsule: ResumeCapsule | null;
155
+ /** SHA-256 of the exact persisted capsule JSON; null only for migrated beta rows. */
156
+ capsuleHash: string | null;
157
+ }
158
+ interface SessionLease {
159
+ sessionId: string;
160
+ legId: string;
161
+ tokenHash: string;
162
+ generation: number;
163
+ acquiredAt: number;
164
+ expiresAt: number;
165
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
166
+ }
167
+ interface CapsuleEvent {
168
+ eventId: string;
169
+ sequence: number;
170
+ adapterId: AdapterId;
171
+ kind: SessionEventKind;
172
+ role: SessionEventRole | null;
173
+ occurredAt: number;
174
+ text: string | null;
175
+ toolOutcome?: string;
176
+ }
177
+ interface ResumeCapsule {
178
+ schemaVersion: typeof SESSION_SCHEMA_VERSION;
179
+ trust: "untrusted_prior_session_context";
180
+ checkpointId: string;
181
+ sessionId: string;
182
+ workspaceId: string;
183
+ sourceAdapterId: AdapterId;
184
+ sourceLegId: string;
185
+ destinationAdapterId: AdapterId;
186
+ goal: string;
187
+ explicitConstraints: string[];
188
+ completedWork: string[];
189
+ openWork: string[];
190
+ blockers: string[];
191
+ decisions: string[];
192
+ rejectedApproaches: string[];
193
+ nextStep: string | null;
194
+ workspaceState: CheckpointWorkspaceState;
195
+ recentEvents: CapsuleEvent[];
196
+ partial: boolean;
197
+ olderEventsCursor: string | null;
198
+ createdAt: number;
199
+ }
200
+
201
+ declare const ADAPTER_CONTRACT_VERSION: 1;
202
+ type AdapterCapabilityMode = "mcp-cooperative" | "hook-assisted" | "local-snapshot" | "native-api" | "cli-launch" | "none";
203
+ /** Evidence for one independently testable adapter behavior. */
204
+ interface AdapterCapabilityEvidence {
205
+ mode: AdapterCapabilityMode;
206
+ /** ISO-8601 timestamp of the integration check supporting this claim. */
207
+ verifiedAt?: string;
208
+ evidence?: string;
209
+ }
210
+ type AdapterCapability = (AdapterCapabilityEvidence & {
211
+ level: "stable";
212
+ reason?: string;
213
+ evidence: string;
214
+ verifiedAt: string;
215
+ }) | (AdapterCapabilityEvidence & {
216
+ level: "experimental" | "unsupported";
217
+ /** Why this behavior cannot be advertised as stable. */
218
+ reason: string;
219
+ });
220
+ interface AdapterCapabilities {
221
+ registration: AdapterCapability;
222
+ history: AdapterCapability;
223
+ nativeResume: AdapterCapability;
224
+ append: AdapterCapability;
225
+ checkpoint: AdapterCapability;
226
+ fork: AdapterCapability;
227
+ launch: AdapterCapability;
228
+ }
229
+ interface ReadBudget {
230
+ maxBytes: number;
231
+ maxEvents: number;
232
+ maxDurationMs: number;
233
+ }
234
+ interface TranscriptRoot {
235
+ path: string;
236
+ readOnly: true;
237
+ }
238
+ interface AdapterDescriptor {
239
+ contractVersion: typeof ADAPTER_CONTRACT_VERSION;
240
+ id: AdapterId;
241
+ displayName: string;
242
+ capabilities: AdapterCapabilities;
243
+ transcriptRoots: readonly TranscriptRoot[];
244
+ defaultReadBudget: ReadBudget;
245
+ }
246
+ interface AdapterProbeResult {
247
+ adapterId: AdapterId;
248
+ available: boolean;
249
+ checkedAt: string;
250
+ clientVersion?: string;
251
+ sourceFormatVersion?: string;
252
+ diagnostics: readonly string[];
253
+ capabilities: AdapterCapabilities;
254
+ }
255
+ interface NativeSessionReference {
256
+ adapterId: AdapterId;
257
+ nativeSessionId: string;
258
+ locator: string;
259
+ /** Present only when the native source itself proves the workspace root. */
260
+ workspaceRoot?: string;
261
+ }
262
+ type VerifiedWorkspaceEvidenceSource = "claude.cwd" | "codex.session_meta.cwd" | "continue.workspaceDirectory";
263
+ type WorkspaceHintSource = "claude.path-key" | "cursor.path-key";
264
+ /**
265
+ * Native-source evidence for workspace ownership.
266
+ *
267
+ * Encoded directory names are intentionally hints: they are lossy and must
268
+ * never be promoted to a workspace binding. Only an explicit native metadata
269
+ * field can produce `verified` evidence and a `reference.workspaceRoot`.
270
+ */
271
+ type WorkspaceEvidence = {
272
+ status: "verified";
273
+ root: string;
274
+ source: VerifiedWorkspaceEvidenceSource;
275
+ } | {
276
+ status: "hint";
277
+ source: WorkspaceHintSource;
278
+ } | {
279
+ status: "unknown";
280
+ source: "none";
281
+ };
282
+ interface DiscoveredNativeSession {
283
+ reference: NativeSessionReference;
284
+ workspaceEvidence: WorkspaceEvidence;
285
+ title?: string;
286
+ startedAt?: number;
287
+ updatedAt: number;
288
+ clientVersion?: string;
289
+ model?: string;
290
+ gitBranch?: string;
291
+ gitCommit?: string;
292
+ metadata?: Record<string, unknown>;
293
+ }
294
+ interface TranscriptCursor {
295
+ kind: "byte" | "line" | "sequence" | "snapshot" | (string & {});
296
+ value: string;
297
+ lastSourceEventId?: string;
298
+ }
299
+ interface TranscriptDiagnostic {
300
+ level: "warning" | "error";
301
+ code: string;
302
+ message: string;
303
+ sourceSequence?: number;
304
+ }
305
+ interface TranscriptSnapshot {
306
+ reference: NativeSessionReference;
307
+ /** Workspace evidence derived from the same immutable source read as events. */
308
+ workspaceEvidence: WorkspaceEvidence;
309
+ events: readonly NormalizedEventInput[];
310
+ sourceFingerprint: string;
311
+ parserVersion: string;
312
+ nextCursor: TranscriptCursor;
313
+ truncated: boolean;
314
+ diagnostics: readonly TranscriptDiagnostic[];
315
+ }
316
+ interface AdapterDiscoveryRequest {
317
+ workspaceRoot?: string;
318
+ budget: ReadBudget;
319
+ }
320
+ interface TranscriptSnapshotRequest {
321
+ reference: NativeSessionReference;
322
+ budget: ReadBudget;
323
+ cursor?: TranscriptCursor;
324
+ }
325
+ interface NativeReferenceRequest {
326
+ nativeSessionId?: string;
327
+ locator?: string;
328
+ workspaceRoot?: string;
329
+ }
330
+ interface NativeLaunchRequest {
331
+ workspaceRoot: string;
332
+ handoffToken: string;
333
+ }
334
+ interface NativeLaunchResult {
335
+ launched: boolean;
336
+ nativeSessionId?: string;
337
+ message?: string;
338
+ }
339
+ interface AdapterRegistrationResult {
340
+ changed: boolean;
341
+ registered: boolean;
342
+ reason?: string;
343
+ }
344
+ /**
345
+ * Boundary implemented by each client integration.
346
+ *
347
+ * There are deliberately no transcript-write methods. Native transcript stores
348
+ * are inputs owned by their clients and remain read-only to AgentCache.
349
+ */
350
+ interface AgentClientAdapter {
351
+ readonly id: AdapterId;
352
+ descriptor(): AdapterDescriptor;
353
+ probe(): Promise<AdapterProbeResult>;
354
+ register(): Promise<AdapterRegistrationResult>;
355
+ unregister(): Promise<AdapterRegistrationResult>;
356
+ discover?(request: AdapterDiscoveryRequest): Promise<readonly DiscoveredNativeSession[]>;
357
+ readSnapshot?(request: TranscriptSnapshotRequest): Promise<TranscriptSnapshot>;
358
+ resolveNativeReference?(request: NativeReferenceRequest): Promise<NativeSessionReference | undefined>;
359
+ launchNative?(request: NativeLaunchRequest): Promise<NativeLaunchResult>;
360
+ }
361
+
362
+ interface Device {
363
+ deviceId: string;
364
+ displayName: string | null;
365
+ createdAt: number;
366
+ lastSeenAt: number;
367
+ }
368
+ type WorkspaceKind = "git" | "directory" | "none";
369
+ interface Workspace {
370
+ workspaceId: string;
371
+ displayName: string;
372
+ kind: WorkspaceKind;
373
+ createdAt: number;
374
+ updatedAt: number;
375
+ archivedAt: number | null;
376
+ metadata: JsonObject;
377
+ }
378
+ interface WorkspaceLocation {
379
+ locationId: string;
380
+ workspaceId: string;
381
+ deviceId: string;
382
+ rootPath: string;
383
+ canonicalGitRemote: string | null;
384
+ gitCommonDir: string | null;
385
+ firstSeenAt: number;
386
+ lastSeenAt: number;
387
+ }
388
+ type WorkspaceResolutionSource = "existing-location" | "created";
389
+ interface ResolveWorkspaceLocationInput {
390
+ deviceId: string;
391
+ rootPath: string;
392
+ canonicalGitRemote: string | null;
393
+ gitCommonDir: string | null;
394
+ proposedWorkspace: Workspace;
395
+ proposedLocationId: string;
396
+ seenAt: number;
397
+ }
398
+ type ResolveWorkspaceLocationResult = {
399
+ status: "bound";
400
+ source: WorkspaceResolutionSource;
401
+ location: WorkspaceLocation;
402
+ /** True when a previously known Git identity no longer matches this exact path. */
403
+ gitIdentityMismatch: boolean;
404
+ } | {
405
+ status: "unassigned";
406
+ reason: "ambiguous-git-remote";
407
+ candidateWorkspaceIds: string[];
408
+ };
409
+ interface SessionListFilter {
410
+ workspaceId?: string | null;
411
+ status?: SessionState;
412
+ adapterId?: AdapterId;
413
+ limit?: number;
414
+ }
415
+ interface AppendEventInput extends NormalizedEventInput {
416
+ eventId?: string;
417
+ parentEventId?: string | null;
418
+ contentHash?: string;
419
+ redactionState?: SessionEvent["redactionState"];
420
+ }
421
+ interface AppendEventsInput {
422
+ sessionId: string;
423
+ legId: string;
424
+ events: readonly AppendEventInput[];
425
+ expectedHeadSequence?: number;
426
+ ingestedAt?: number;
427
+ cursor?: SourceCursor;
428
+ }
429
+ interface AppendEventsResult {
430
+ inserted: number;
431
+ events: SessionEvent[];
432
+ headEventId: string | null;
433
+ headSequence: number;
434
+ }
435
+ interface AppendEventsWithLeaseInput extends AppendEventsInput {
436
+ leaseToken: string;
437
+ expectedAdapterId: AdapterId;
438
+ expectedDeviceId: string;
439
+ now?: number;
440
+ renewLeaseExpiresAt: number;
441
+ /**
442
+ * Portable API timestamps are assigned by the receiving service. On an
443
+ * idempotent retry, reuse the durable timestamp before comparing content so
444
+ * two processes racing the same key return the original event.
445
+ */
446
+ reusePersistedOccurredAtOnRetry?: boolean;
447
+ }
448
+ interface AppendEventsWithLeaseResult extends AppendEventsResult {
449
+ lease: SessionLease;
450
+ }
451
+ interface AppendEventsAsTransientWriterInput {
452
+ leg: ClientLeg;
453
+ leaseToken: string;
454
+ now: number;
455
+ leaseExpiresAt: number;
456
+ append: AppendEventsInput;
457
+ reusePersistedOccurredAtOnRetry?: boolean;
458
+ }
459
+ interface AppendEventsAsTransientWriterResult extends AppendEventsResult {
460
+ leg: ClientLeg;
461
+ }
462
+ interface CreateCheckpointWithLeaseInput {
463
+ checkpoint: SessionCheckpoint;
464
+ expectedHeadSequence: number;
465
+ legId: string;
466
+ leaseToken: string;
467
+ expectedAdapterId: AdapterId;
468
+ expectedDeviceId: string;
469
+ now?: number;
470
+ renewLeaseExpiresAt: number;
471
+ }
472
+ interface CreateCheckpointWithLeaseResult {
473
+ checkpoint: SessionCheckpoint;
474
+ lease: SessionLease;
475
+ }
476
+ interface CreateCheckpointAsTransientWriterInput {
477
+ leg: ClientLeg;
478
+ leaseToken: string;
479
+ now: number;
480
+ leaseExpiresAt: number;
481
+ checkpoint: SessionCheckpoint;
482
+ expectedHeadSequence: number;
483
+ }
484
+ interface CreateCheckpointAsTransientWriterResult {
485
+ checkpoint: SessionCheckpoint;
486
+ leg: ClientLeg;
487
+ }
488
+ type IngestionTitleSource = "native" | "user" | "fallback";
489
+ /**
490
+ * One adapter page plus the identity and metadata required to commit it.
491
+ * `proposedSession` is used only when import mode wins the native-leg claim.
492
+ */
493
+ interface IngestTranscriptPageInput {
494
+ mode: "import" | "attach";
495
+ proposedSession: PortableSession | null;
496
+ proposedLeg: ClientLeg;
497
+ targetSessionId: string | null;
498
+ rootScopeId: string;
499
+ events: readonly AppendEventInput[];
500
+ expectedHeadSequence?: number;
501
+ expectedCursor: SourceCursor | null;
502
+ nextCursor: SourceCursor;
503
+ titleCandidate: {
504
+ title: string;
505
+ source: IngestionTitleSource;
506
+ };
507
+ sessionMetadata: JsonObject;
508
+ legMetadata: JsonObject;
509
+ updatedAt: number;
510
+ }
511
+ interface IngestTranscriptPageResult extends AppendEventsResult {
512
+ session: PortableSession;
513
+ leg: ClientLeg;
514
+ cursor: SourceCursor;
515
+ createdSession: boolean;
516
+ createdLeg: boolean;
517
+ }
518
+ interface MarkIngestionSourceStatusInput {
519
+ expectedCursor: SourceCursor;
520
+ rootScopeId: string;
521
+ status: SourceCursor["status"];
522
+ lastError: string;
523
+ lastSeenAt: number;
524
+ }
525
+ interface CreateForkInput {
526
+ session: PortableSession;
527
+ parentSessionId: string;
528
+ expectedParentHeadSequence: number;
529
+ forkedFromCheckpointId: string;
530
+ forkedFromEventId: string;
531
+ createdByLegId: string | null;
532
+ reason: string | null;
533
+ createdAt: number;
534
+ }
535
+ interface CreateForkAndAcquireLeaseInput {
536
+ fork: CreateForkInput;
537
+ destinationLeg: ClientLeg;
538
+ leaseToken: string;
539
+ now?: number;
540
+ leaseExpiresAt: number;
541
+ }
542
+ interface CreateForkAndAcquireLeaseResult {
543
+ session: PortableSession;
544
+ fork: CheckpointAnchoredFork;
545
+ leg: ClientLeg;
546
+ lease: SessionLease;
547
+ }
548
+ interface CheckpointAnchoredFork extends SessionFork {
549
+ forkedFromCheckpointId: string;
550
+ }
551
+ interface CreateHandoffInput {
552
+ handoffId: string;
553
+ sessionId: string;
554
+ checkpointId: string;
555
+ workspaceId: string;
556
+ targetAdapterId: AdapterId;
557
+ mode: HandoffMode;
558
+ token: string;
559
+ createdAt: number;
560
+ expiresAt: number;
561
+ createdHeadSequence: number;
562
+ allowsLeaseTakeover?: boolean;
563
+ expectedSourceLeaseGeneration?: number | null;
564
+ /** Hash of the exact source lease being authorized for replacement. */
565
+ expectedSourceLeaseTokenHash?: string | null;
566
+ forkTitle?: string | null;
567
+ forkReason?: string | null;
568
+ capsule: ResumeCapsule;
569
+ }
570
+ interface ConsumeHandoffInput {
571
+ handoffId: string;
572
+ token: string;
573
+ targetAdapterId: AdapterId;
574
+ workspaceId: string;
575
+ now?: number;
576
+ }
577
+ interface ConsumeHandoffAndAcquireLeaseInput extends ConsumeHandoffInput {
578
+ destinationLeg: ClientLeg;
579
+ leaseToken: string;
580
+ leaseExpiresAt: number;
581
+ fork?: CreateForkInput;
582
+ }
583
+ interface ConsumeHandoffAndAcquireLeaseResult {
584
+ handoff: Handoff;
585
+ session: PortableSession;
586
+ leg: ClientLeg;
587
+ lease: SessionLease;
588
+ fork: CheckpointAnchoredFork | null;
589
+ }
590
+ interface AcquireLeaseInput {
591
+ sessionId: string;
592
+ legId: string;
593
+ token: string;
594
+ now?: number;
595
+ expiresAt: number;
596
+ }
597
+ interface OpenSessionAndAcquireLeaseInput {
598
+ session: PortableSession;
599
+ leg: ClientLeg;
600
+ leaseToken: string;
601
+ now?: number;
602
+ leaseExpiresAt: number;
603
+ }
604
+ interface OpenSessionAndAcquireLeaseResult {
605
+ session: PortableSession;
606
+ leg: ClientLeg;
607
+ lease: SessionLease;
608
+ }
609
+ /**
610
+ * Persistence boundary for the portable v2 session model.
611
+ *
612
+ * Bearer tokens cross this interface only in plaintext and are hashed by the
613
+ * implementation before they reach durable storage.
614
+ */
615
+ interface SessionRepository {
616
+ close(): void;
617
+ upsertDevice(device: Device): Device;
618
+ getDevice(deviceId: string): Device | null;
619
+ createWorkspace(workspace: Workspace): Workspace;
620
+ updateWorkspace(workspace: Workspace): Workspace;
621
+ getWorkspace(workspaceId: string): Workspace | null;
622
+ listWorkspaces(): Workspace[];
623
+ saveWorkspaceLocation(location: WorkspaceLocation): WorkspaceLocation;
624
+ getWorkspaceLocation(locationId: string): WorkspaceLocation | null;
625
+ getWorkspaceLocationForPath(deviceId: string, rootPath: string): WorkspaceLocation | null;
626
+ listWorkspaceLocations(workspaceId: string): WorkspaceLocation[];
627
+ findWorkspaceLocationsByGitRemote(canonicalGitRemote: string): WorkspaceLocation[];
628
+ resolveWorkspaceLocation(input: ResolveWorkspaceLocationInput): ResolveWorkspaceLocationResult;
629
+ createSession(session: PortableSession): PortableSession;
630
+ openSessionAndAcquireLease(input: OpenSessionAndAcquireLeaseInput): OpenSessionAndAcquireLeaseResult;
631
+ updateSession(session: PortableSession): PortableSession;
632
+ getSession(sessionId: string): PortableSession | null;
633
+ listSessions(filter?: SessionListFilter): PortableSession[];
634
+ createLeg(leg: ClientLeg): ClientLeg;
635
+ updateLeg(leg: ClientLeg): ClientLeg;
636
+ getLeg(legId: string): ClientLeg | null;
637
+ findLeg(deviceId: string, adapterId: AdapterId, nativeSessionId: string): ClientLeg | null;
638
+ listLegs(sessionId: string, limit?: number): ClientLeg[];
639
+ appendEvents(input: AppendEventsInput): AppendEventsResult;
640
+ appendEventsWithLease(input: AppendEventsWithLeaseInput): AppendEventsWithLeaseResult;
641
+ appendEventsAsTransientWriter(input: AppendEventsAsTransientWriterInput): AppendEventsAsTransientWriterResult;
642
+ ingestTranscriptPage(input: IngestTranscriptPageInput): IngestTranscriptPageResult;
643
+ markIngestionSourceStatus(input: MarkIngestionSourceStatusInput): SourceCursor;
644
+ getEvent(eventId: string): SessionEvent | null;
645
+ listEvents(sessionId: string, options?: {
646
+ beforeSequence?: number;
647
+ limit?: number;
648
+ }): SessionEvent[];
649
+ saveSourceCursor(cursor: SourceCursor): SourceCursor;
650
+ getSourceCursor(sourceId: string): SourceCursor | null;
651
+ findSourceCursor(deviceId: string, adapterId: AdapterId, locator: string): SourceCursor | null;
652
+ createCheckpoint(checkpoint: SessionCheckpoint, expectedHeadSequence?: number): SessionCheckpoint;
653
+ createCheckpointWithLease(input: CreateCheckpointWithLeaseInput): CreateCheckpointWithLeaseResult;
654
+ createCheckpointAsTransientWriter(input: CreateCheckpointAsTransientWriterInput): CreateCheckpointAsTransientWriterResult;
655
+ getCheckpoint(checkpointId: string): SessionCheckpoint | null;
656
+ listCheckpoints(sessionId: string, limit?: number): SessionCheckpoint[];
657
+ createFork(input: CreateForkInput): CheckpointAnchoredFork;
658
+ createForkAndAcquireLease(input: CreateForkAndAcquireLeaseInput): CreateForkAndAcquireLeaseResult;
659
+ getFork(forkSessionId: string): CheckpointAnchoredFork | null;
660
+ listForks(parentSessionId: string, limit?: number): CheckpointAnchoredFork[];
661
+ createHandoff(input: CreateHandoffInput): Handoff;
662
+ getHandoff(handoffId: string): Handoff | null;
663
+ listHandoffs(sessionId?: string, includeConsumed?: boolean, limit?: number): Handoff[];
664
+ listPendingHandoffs(workspaceId: string, now: number, limit?: number): Handoff[];
665
+ consumeHandoff(input: ConsumeHandoffInput): Handoff;
666
+ consumeHandoffAndAcquireLease(input: ConsumeHandoffAndAcquireLeaseInput): ConsumeHandoffAndAcquireLeaseResult;
667
+ cancelHandoff(handoffId: string): boolean;
668
+ acquireLease(input: AcquireLeaseInput): SessionLease;
669
+ getLease(sessionId: string): SessionLease | null;
670
+ validateLease(sessionId: string, legId: string, token: string, now?: number): SessionLease;
671
+ releaseLease(sessionId: string, legId: string, token: string): boolean;
672
+ }
673
+
674
+ type RootBindingSource = WorkspaceResolutionSource | "unassigned";
675
+ interface RootBindingBase {
676
+ /** Ephemeral, server-issued authority handle; never derived from a path. */
677
+ rootId: string;
678
+ /** Optional bounded client-facing label; never used as workspace authority. */
679
+ displayName?: string;
680
+ /** Warning only; the exact canonical device path remains the authority boundary. */
681
+ gitIdentityMismatch?: true;
682
+ rootPath: string;
683
+ canonicalGitRemote: string | null;
684
+ gitCommonDir: string | null;
685
+ }
686
+ interface AssignedRootBinding extends RootBindingBase {
687
+ status: "bound";
688
+ workspaceId: string;
689
+ locationId: string;
690
+ source: Exclude<RootBindingSource, "unassigned">;
691
+ }
692
+ interface UnassignedRootBinding extends RootBindingBase {
693
+ status: "unassigned";
694
+ workspaceId: null;
695
+ locationId: null;
696
+ source: "unassigned";
697
+ reason: "ambiguous-git-remote";
698
+ candidateWorkspaceIds: string[];
699
+ }
700
+ type RootBinding = AssignedRootBinding | UnassignedRootBinding;
701
+
702
+ interface McpClientRoot {
703
+ uri: string;
704
+ name?: string;
705
+ }
706
+ interface CanonicalizedClientRoot {
707
+ rootPath: string;
708
+ displayName: string;
709
+ }
710
+ interface StartMcpServerOptions {
711
+ /** Trusted process identity supplied by the integration, never by a tool call. */
712
+ adapterId: AdapterId;
713
+ /** Stable machine identity supplied by shared runtime configuration. */
714
+ deviceId: string;
715
+ /** Test/integration seams; normal callers use the v2 local repository and registry. */
716
+ repository?: SessionRepository;
717
+ adapters?: readonly AgentClientAdapter[];
718
+ resolveRoot?: (canonicalRoot: string, deviceId: string, repository: SessionRepository) => RootBinding;
719
+ server?: Server;
720
+ transport?: Transport;
721
+ }
722
+ /**
723
+ * Decodes and canonicalizes roots with URL semantics. There is deliberately no
724
+ * process.cwd() fallback: absent roots mean absent workspace authority.
725
+ */
726
+ declare function canonicalizeClientRootUris(roots: readonly McpClientRoot[]): string[];
727
+ /** Preserve only a safe human label alongside each canonical authority root. */
728
+ declare function canonicalizeClientRoots(roots: readonly McpClientRoot[]): CanonicalizedClientRoot[];
729
+ /**
730
+ * Starts the beta session-continuity server. Legacy knowledge, compilation,
731
+ * policy, migration, update, and background jobs are intentionally absent.
732
+ */
733
+ declare function startMcpServer(options?: StartMcpServerOptions): Promise<void>;
734
+
735
+ export { type CanonicalizedClientRoot, type McpClientRoot, type StartMcpServerOptions, canonicalizeClientRootUris, canonicalizeClientRoots, startMcpServer };