@gajae-code/coding-agent 0.12.19 → 0.12.21
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/CHANGELOG.md +27 -9
- package/dist/types/commands/gc.d.ts +4 -0
- package/dist/types/commands/sdk.d.ts +66 -0
- package/dist/types/config/settings-schema.d.ts +34 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +97 -1
- package/dist/types/modes/acp/acp-agent.d.ts +33 -1
- package/dist/types/modes/components/bash-execution.d.ts +7 -0
- package/dist/types/modes/components/eval-execution.d.ts +7 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +10 -1
- package/dist/types/sdk/acp/adapter.d.ts +9 -17
- package/dist/types/sdk/acp/index.d.ts +1 -1
- package/dist/types/sdk/broker/broker.d.ts +93 -1
- package/dist/types/sdk/broker/ensure.d.ts +17 -0
- package/dist/types/sdk/broker/index.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +10 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +81 -2
- package/dist/types/sdk/broker/startup-budget.d.ts +44 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +7 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +11 -1
- package/dist/types/sdk/bus/discord-daemon.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +20 -9
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -6
- package/dist/types/sdk/bus/slack-daemon.d.ts +2 -2
- package/dist/types/sdk/host/query/revision-store.d.ts +5 -0
- package/dist/types/sdk/host/session-runtime.d.ts +4 -0
- package/dist/types/sdk/lifecycle-session.d.ts +13 -2
- package/dist/types/sdk/prompt-failure.d.ts +13 -0
- package/dist/types/sdk/prompt-watchdog.d.ts +82 -0
- package/dist/types/sdk/session-reconnect.d.ts +20 -0
- package/dist/types/sdk/startup-capability.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +14 -4
- package/dist/types/session/blob-store.d.ts +32 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +40 -2
- package/dist/types/session/internal/session-memory-sidecar.d.ts +881 -0
- package/dist/types/session/session-manager.d.ts +302 -27
- package/dist/types/session/session-storage.d.ts +170 -0
- package/dist/types/task/executor.d.ts +2 -1
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/todo-contract.d.ts +10 -1
- package/dist/types/tui/output-block.d.ts +6 -0
- package/package.json +8 -8
- package/src/cli/args.ts +75 -34
- package/src/commands/acp.ts +7 -1
- package/src/commands/gc.ts +31 -2
- package/src/commands/sdk.ts +141 -7
- package/src/config/settings-schema.ts +43 -0
- package/src/coordinator-mcp/server.ts +6 -1
- package/src/export/html/index.ts +83 -39
- package/src/gjc-runtime/gc-runtime.ts +1283 -4
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/internal-urls/local-protocol.ts +14 -0
- package/src/main.ts +40 -9
- package/src/modes/acp/acp-agent.ts +564 -37
- package/src/modes/acp/terminal-auth.ts +2 -2
- package/src/modes/components/bash-execution.ts +14 -0
- package/src/modes/components/eval-execution.ts +14 -0
- package/src/modes/controllers/command-controller.ts +63 -8
- package/src/modes/utils/ui-helpers.ts +81 -11
- package/src/sdk/acp/adapter.ts +46 -45
- package/src/sdk/acp/index.ts +1 -1
- package/src/sdk/broker/broker.ts +392 -11
- package/src/sdk/broker/ensure.ts +131 -61
- package/src/sdk/broker/index.ts +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +59 -5
- package/src/sdk/broker/lifecycle.ts +278 -63
- package/src/sdk/broker/startup-budget.ts +103 -0
- package/src/sdk/bus/chat-daemon-control.ts +9 -3
- package/src/sdk/bus/chat-daemon-runtime.ts +565 -29
- package/src/sdk/bus/conversation-store.ts +1 -1
- package/src/sdk/bus/discord-daemon.ts +2 -1
- package/src/sdk/bus/discord-live-provider.ts +34 -6
- package/src/sdk/bus/index.ts +118 -20
- package/src/sdk/bus/kind-aware-reconciliation.ts +2 -1
- package/src/sdk/bus/prompt-reconciliation.ts +4 -9
- package/src/sdk/bus/slack-daemon.ts +91 -18
- package/src/sdk/cli/session-cli.ts +8 -1
- package/src/sdk/host/query/handlers.ts +1 -1
- package/src/sdk/host/query/revision-store.ts +48 -12
- package/src/sdk/host/session-runtime.test.ts +50 -0
- package/src/sdk/host/session-runtime.ts +12 -2
- package/src/sdk/lifecycle-session.ts +26 -3
- package/src/sdk/mcp/server.ts +6 -1
- package/src/sdk/prompt-failure.ts +42 -0
- package/src/sdk/prompt-watchdog.ts +162 -0
- package/src/sdk/session-reconnect.ts +43 -0
- package/src/sdk/startup-capability.ts +13 -4
- package/src/session/agent-session.ts +541 -226
- package/src/session/blob-store.ts +89 -0
- package/src/session/internal/managed-session-scope.ts +36 -26
- package/src/session/internal/managed-session-storage.ts +303 -32
- package/src/session/internal/session-memory-sidecar.ts +2160 -0
- package/src/session/session-manager.ts +7057 -399
- package/src/session/session-storage.ts +1134 -11
- package/src/task/executor.ts +17 -4
- package/src/tools/bash.ts +109 -7
- package/src/tools/descriptors.test.ts +51 -0
- package/src/tools/find.ts +55 -26
- package/src/tools/todo-contract.ts +82 -13
- package/src/tools/todo-write.ts +2 -5
- package/src/tui/output-block.ts +11 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import { type AgentMessage } from "@gajae-code/agent-core";
|
|
2
3
|
import type { ConfiguredModelChainEntry as SharedConfiguredModelChainEntry } from "@gajae-code/agent-core/compaction";
|
|
3
4
|
import type { ImageContent, Message, MessageAttribution, ServiceTier, TextContent } from "@gajae-code/ai/core";
|
|
@@ -7,7 +8,8 @@ import type { ManagedLegacyLocalMigrationSource } from "../internal-urls/local-p
|
|
|
7
8
|
import { ArtifactManager } from "./artifacts";
|
|
8
9
|
import { type BlobPutResult, BlobStore } from "./blob-store";
|
|
9
10
|
import { type ManagedMigrationPolicy } from "./internal/managed-session-scope";
|
|
10
|
-
import { type ManagedDirectoryRoot, ManagedSessionDescendantStore } from "./internal/managed-session-storage";
|
|
11
|
+
import { type ManagedBoundedAppendExpectation, type ManagedDirectoryRoot, ManagedSessionDescendantStore } from "./internal/managed-session-storage";
|
|
12
|
+
import { type BaseAnchor, BoundedLabelsPinsStore, type CommittedTail, type DescriptorSnapshot, type DictionaryPartitionCommit, FixedCacheAccount, type MetadataDeltaValue, type ParentBucketCommit, type ReducerState, type ReopenClassification, SessionMemoryAccountant } from "./internal/session-memory-sidecar";
|
|
11
13
|
import { type MemoryGuardCreateCheckpointInput, type MemoryGuardParticipantIngressLease, type MemoryGuardRestoreInput, type MemoryGuardRestoreResult, type MemoryGuardSessionManagerCheckpointV1 } from "./memory-guard-checkpoint-participant";
|
|
12
14
|
import { type BashExecutionMessage, type CustomMessage, type FileMentionMessage, type HookMessage, type PythonExecutionMessage } from "./messages";
|
|
13
15
|
import { type SessionManagerReadAccess, sessionManagerReadCapability } from "./session-manager-internal";
|
|
@@ -84,6 +86,48 @@ export interface SessionManagerObservabilityStats {
|
|
|
84
86
|
materializedCacheDemotedCount: number;
|
|
85
87
|
pathOnlyContextBuildCount: number;
|
|
86
88
|
}
|
|
89
|
+
export interface SessionMemoryStats {
|
|
90
|
+
sidecarEnabled: boolean;
|
|
91
|
+
coldRetirementActive: boolean;
|
|
92
|
+
sidecarIneligible: boolean;
|
|
93
|
+
hotRegionBytes: number;
|
|
94
|
+
metaDescriptorBytes: number;
|
|
95
|
+
totalAccountedBytes: number;
|
|
96
|
+
lastReopenTransition: ReopenClassification | undefined;
|
|
97
|
+
currentCommitTransition: ReopenClassification | undefined;
|
|
98
|
+
lazyReopenAttempted: boolean;
|
|
99
|
+
lazyReopenSucceeded: boolean;
|
|
100
|
+
lazyReopenFallbackReason: string | undefined;
|
|
101
|
+
retirementFallbackReason: string | undefined;
|
|
102
|
+
autoDisabledReason: string | undefined;
|
|
103
|
+
consecutiveBuildFailures: number;
|
|
104
|
+
/** Persistent bounded parent→children artifact is adopted and usable. */
|
|
105
|
+
parentArtifactEnabled: boolean;
|
|
106
|
+
/** Persistent bounded dictionary artifact is adopted and usable. */
|
|
107
|
+
dictionaryArtifactEnabled: boolean;
|
|
108
|
+
/** Reducer-bucket bytes retained by metadata-delta descriptors (fixed accounting). */
|
|
109
|
+
metadataDeltaDescriptorBytes: number;
|
|
110
|
+
/** Live cold index bytes (descriptor size when proven, else 0). */
|
|
111
|
+
coldIndexBytes: number;
|
|
112
|
+
/** Live cold block-cache allocated bytes. */
|
|
113
|
+
coldIndexBlockCacheBytes: number;
|
|
114
|
+
/** Live cold entry-cache allocated bytes. */
|
|
115
|
+
coldEntryCacheBytes: number;
|
|
116
|
+
/** Live observability counters (P7 contract). */
|
|
117
|
+
coldEntriesRetired: number;
|
|
118
|
+
coldEntriesReloaded: number;
|
|
119
|
+
rangeReadCount: number;
|
|
120
|
+
rangeReadGenerationMismatchCount: number;
|
|
121
|
+
sidecarRebuildCount: number;
|
|
122
|
+
coldMutationPromotions: number;
|
|
123
|
+
hotOverflowTransitions: number;
|
|
124
|
+
labelDiskFallbackCount: number;
|
|
125
|
+
/** Shadow-mode eager-vs-sidecar parity mismatches observed at build time (AC10 telemetry). */
|
|
126
|
+
shadowParityMismatchCount: number;
|
|
127
|
+
/** Shadow-mode parity comparisons performed at build time (AC10 telemetry). */
|
|
128
|
+
shadowParityCheckCount: number;
|
|
129
|
+
transcriptGeneration: number;
|
|
130
|
+
}
|
|
87
131
|
export interface SessionMessageEntry extends SessionEntryBase {
|
|
88
132
|
type: "message";
|
|
89
133
|
message: AgentMessage;
|
|
@@ -256,14 +300,179 @@ export interface EntryPatchRecord {
|
|
|
256
300
|
export type SessionPatchRecord = HeaderPatchRecord | EntryPatchRecord;
|
|
257
301
|
/** Resolved file entries; patch records are applied by parseSessionEntries(). */
|
|
258
302
|
export type FileEntry = SessionHeader | SessionEntry;
|
|
303
|
+
/**
|
|
304
|
+
* Cold-region placeholder envelope for a retired entry. The heavy payload was moved
|
|
305
|
+
* out of RAM into the disposable `.spill.idx`/`.spill.tail` cold region; the exact
|
|
306
|
+
* transcript byte range is recorded so the entry can be lazily resolved by
|
|
307
|
+
* `ordinal`/`id`. Never persisted; used only while a cold sidecar region is active.
|
|
308
|
+
*/
|
|
309
|
+
export interface SessionColdRefEntry extends SessionEntryBase {
|
|
310
|
+
type: "session_cold_ref";
|
|
311
|
+
ordinal: number;
|
|
312
|
+
seq: number;
|
|
313
|
+
byteOffset: number;
|
|
314
|
+
byteLength: number;
|
|
315
|
+
}
|
|
316
|
+
/** One cold entry's transcript location, keyed by entry id. */
|
|
317
|
+
export interface ColdEntryIndex {
|
|
318
|
+
ordinal: number;
|
|
319
|
+
seq: number;
|
|
320
|
+
byteOffset: number;
|
|
321
|
+
byteLength: number;
|
|
322
|
+
recordDigest: string;
|
|
323
|
+
parentId?: string | null;
|
|
324
|
+
entryType?: string;
|
|
325
|
+
}
|
|
326
|
+
export interface SessionMemorySidecarRuntime {
|
|
327
|
+
/** Transcript v5 remains authoritative; sidecars are disposable/rebuildable. */
|
|
328
|
+
enabled: boolean;
|
|
329
|
+
/** Set when duplicate record IDs were detected; session stays eager. */
|
|
330
|
+
sidecarIneligible: boolean;
|
|
331
|
+
base: BaseAnchor;
|
|
332
|
+
tail: CommittedTail;
|
|
333
|
+
/** Bounded hot index cache; authoritative lookup falls back to the disk index. */
|
|
334
|
+
coldEntries: Map<string, ColdEntryIndex>;
|
|
335
|
+
indexPath: string;
|
|
336
|
+
tailPath: string;
|
|
337
|
+
commitPath: string;
|
|
338
|
+
/** Directory prefix of the persistent `.spill.parent-<bucket>` bucket files. */
|
|
339
|
+
parentPathPrefix: string;
|
|
340
|
+
/** Directory prefix of the persistent `.spill.dict-part-<partition>` partition files. */
|
|
341
|
+
dictionaryPathPrefix: string;
|
|
342
|
+
/** Path of the persistent `.spill.dict-meta` finalization file. */
|
|
343
|
+
dictionaryMetaPath: string;
|
|
344
|
+
/** Path of the persistent `.spill.metadata-delta` section. */
|
|
345
|
+
metadataDeltaPath: string;
|
|
346
|
+
retirementFirstKeptEntryId: string | undefined;
|
|
347
|
+
/** Hot-suffix byte total (accountant-bounded to ≤ 16 MiB). */
|
|
348
|
+
hotSuffixBytes: number;
|
|
349
|
+
accountant: SessionMemoryAccountant;
|
|
350
|
+
reducer: ReducerState;
|
|
351
|
+
/** Resident inline provider-affecting entries (merged order minus demoted slots). */
|
|
352
|
+
providerStateEntries: SessionEntry[];
|
|
353
|
+
/** Merged provider-list order as keys (inline + demoted); reopened/appended slots stay exact. */
|
|
354
|
+
providerStateOrder: string[];
|
|
355
|
+
blockCache: FixedCacheAccount;
|
|
356
|
+
parentChildrenCache: Map<string, {
|
|
357
|
+
ids: readonly string[];
|
|
358
|
+
bytes: number;
|
|
359
|
+
descriptor: SessionStorageStat;
|
|
360
|
+
bucketDescriptor?: SessionStorageStat;
|
|
361
|
+
bucketIndex?: number;
|
|
362
|
+
}>;
|
|
363
|
+
entryCache: FixedCacheAccount;
|
|
364
|
+
tailCache: FixedCacheAccount;
|
|
365
|
+
labelsPins: BoundedLabelsPinsStore;
|
|
366
|
+
terminalTransition: ReopenClassification | undefined;
|
|
367
|
+
reopenTransition: ReopenClassification | undefined;
|
|
368
|
+
/** SHA-256 over the exact `.spill.idx` bytes this runtime has written/adopted ("" until proven). */
|
|
369
|
+
indexDigest: string;
|
|
370
|
+
/** Descriptor of the exact index bytes whose digest was validated for cache use. */
|
|
371
|
+
validatedIndexDescriptor?: SessionStorageStat;
|
|
372
|
+
/** Live running hash of the index bytes; updated on every index append. */
|
|
373
|
+
indexHash: crypto.Hash;
|
|
374
|
+
/** Persistent bounded parent→children artifact state; absent = parent lookups fail closed. */
|
|
375
|
+
parentArtifact?: ParentArtifactRuntimeState;
|
|
376
|
+
/** Persistent bounded dictionary artifact state; absent = dictionary lookups fail closed to the cold scan. */
|
|
377
|
+
dictionary?: DictionaryArtifactRuntimeState;
|
|
378
|
+
/** Persistent metadata-delta section state; absent = no demoted provider values. */
|
|
379
|
+
metadataDelta?: MetadataDeltaArtifactRuntimeState;
|
|
380
|
+
/** Lazily built 24-bit fingerprints for O(1) fail-closed ID generation when no persistent dictionary exists. */
|
|
381
|
+
coldIdHashes?: BoundedColdIdHashSet;
|
|
382
|
+
coldIdHashesDescriptor?: SessionStorageStat;
|
|
383
|
+
/** Live observability counters (P7 live-only contract). */
|
|
384
|
+
coldEntriesRetired: number;
|
|
385
|
+
coldEntriesReloaded: number;
|
|
386
|
+
rangeReadCount: number;
|
|
387
|
+
rangeReadGenerationMismatchCount: number;
|
|
388
|
+
sidecarRebuildCount: number;
|
|
389
|
+
coldMutationPromotions: number;
|
|
390
|
+
hotOverflowTransitions: number;
|
|
391
|
+
labelDiskFallbackCount: number;
|
|
392
|
+
/** Shadow-mode eager-vs-sidecar parity mismatches observed at build time (AC10 telemetry). */
|
|
393
|
+
shadowParityMismatchCount: number;
|
|
394
|
+
/** Shadow-mode parity comparisons performed at build time (AC10 telemetry). */
|
|
395
|
+
shadowParityCheckCount: number;
|
|
396
|
+
transcriptGeneration: number;
|
|
397
|
+
}
|
|
398
|
+
/** Retained runtime state of the disposable parent→children artifact (block-cache charged). */
|
|
399
|
+
interface ParentArtifactRuntimeState {
|
|
400
|
+
/** Exact `.spill.idx` digest the artifact covers; artifact lookups require `indexDigest === runtime.indexDigest`. */
|
|
401
|
+
indexDigest: string;
|
|
402
|
+
/** Committed per-bucket exact-byte size + sha256, updated incrementally on append. */
|
|
403
|
+
buckets: ParentBucketCommit[];
|
|
404
|
+
/** Total artifact bytes (sum of bucket sizes). */
|
|
405
|
+
totalBytes: number;
|
|
406
|
+
/** Block-cache bytes charged for this retained state; released on invalidation/wholesale release. */
|
|
407
|
+
chargedBytes: number;
|
|
408
|
+
/** On-disk byte cap enforced on append; fixed at `PARENT_CHILDREN_BUDGET_BYTES` unless a test shrinks it. */
|
|
409
|
+
budgetBytes: number;
|
|
410
|
+
}
|
|
411
|
+
/** Retained runtime state of the disposable dictionary artifact (block-cache charged). */
|
|
412
|
+
interface DictionaryArtifactRuntimeState {
|
|
413
|
+
/** Exact `.spill.idx` digest the artifact covers; lookups require `indexDigest === runtime.indexDigest`. */
|
|
414
|
+
indexDigest: string;
|
|
415
|
+
/** Committed per-partition exact-byte size + sha256, updated incrementally on append. */
|
|
416
|
+
partitions: DictionaryPartitionCommit[];
|
|
417
|
+
/** Exact `.spill.dict-meta` bytes (size + digest). */
|
|
418
|
+
metaSize: number;
|
|
419
|
+
metaDigest: string;
|
|
420
|
+
recordCount: number;
|
|
421
|
+
uniqueTerms: number;
|
|
422
|
+
totalBytes: number;
|
|
423
|
+
/** Bounded duplicate-id diagnostics; non-empty ⇒ the artifact is never adopted. */
|
|
424
|
+
duplicateIds: readonly string[];
|
|
425
|
+
sidecarIneligible: boolean;
|
|
426
|
+
/** Block-cache bytes charged for this retained state; released on invalidation. */
|
|
427
|
+
chargedBytes: number;
|
|
428
|
+
/** On-disk byte cap for a single partition append; fixed unless a test shrinks it. */
|
|
429
|
+
budgetBytes: number;
|
|
430
|
+
/** Running per-partition hashes/sizes/records for append-time rebinding. */
|
|
431
|
+
partitionHashes: crypto.Hash[];
|
|
432
|
+
partitionSizes: number[];
|
|
433
|
+
partitionRecords: number[];
|
|
434
|
+
/** Descriptor of the exact meta bytes whose digest was validated for artifact use. */
|
|
435
|
+
validatedDescriptor?: SessionStorageStat;
|
|
436
|
+
}
|
|
437
|
+
/** Retained runtime state of the disposable metadata-delta section (reducer-bucket accounting). */
|
|
438
|
+
interface MetadataDeltaArtifactRuntimeState {
|
|
439
|
+
/** Exact `.spill.idx` digest the sidecar set was built with. */
|
|
440
|
+
indexDigest: string;
|
|
441
|
+
/** Exact bytes of the `.spill.metadata-delta` file. */
|
|
442
|
+
size: number;
|
|
443
|
+
sha256: string;
|
|
444
|
+
/** Live running hash of the delta bytes; updated on every value append. */
|
|
445
|
+
hash: crypto.Hash;
|
|
446
|
+
/** Demoted value descriptors keyed by provider key (positions derived at marker time). */
|
|
447
|
+
byKey: Map<string, Omit<MetadataDeltaValue, "key" | "position">>;
|
|
448
|
+
/** Reducer-bucket bytes retained by the descriptors (fixed accounting, reported in stats). */
|
|
449
|
+
descriptorBytes: number;
|
|
450
|
+
/** Fixed on-disk byte cap for the section. */
|
|
451
|
+
budgetBytes: number;
|
|
452
|
+
/** Descriptor of the exact delta bytes whose digest was validated. */
|
|
453
|
+
validatedDescriptor?: SessionStorageStat;
|
|
454
|
+
}
|
|
455
|
+
declare class BoundedColdIdHashSet {
|
|
456
|
+
#private;
|
|
457
|
+
has(value: string): boolean;
|
|
458
|
+
add(value: string): boolean;
|
|
459
|
+
addUnique(value: string): boolean;
|
|
460
|
+
}
|
|
259
461
|
export type DefaultModelSelectionStage = {
|
|
260
462
|
readonly entryRevision: number;
|
|
463
|
+
readonly leafRevision: number;
|
|
261
464
|
readonly headerExportRevision: number;
|
|
262
465
|
readonly sessionId: string;
|
|
263
466
|
readonly sessionFile: string | undefined;
|
|
264
467
|
readonly entries: readonly FileEntry[];
|
|
265
468
|
readonly tempPath: string | undefined;
|
|
266
469
|
readonly persistsToExistingFile: boolean;
|
|
470
|
+
readonly boundedCold: boolean;
|
|
471
|
+
readonly appendEntries: readonly SessionEntry[];
|
|
472
|
+
readonly sourceDescriptor: DescriptorSnapshot | undefined;
|
|
473
|
+
readonly sourceStat: SessionStorageStat | undefined;
|
|
474
|
+
readonly sourceSha256: string | undefined;
|
|
475
|
+
readonly managedAppendExpectation: ManagedBoundedAppendExpectation | undefined;
|
|
267
476
|
};
|
|
268
477
|
export interface SessionManagerRevisionSnapshot {
|
|
269
478
|
entry: number;
|
|
@@ -346,18 +555,12 @@ export interface ResumeTailTerminal {
|
|
|
346
555
|
}
|
|
347
556
|
export interface ResumeTailError {
|
|
348
557
|
kind: "error";
|
|
349
|
-
reason: "missing" | "malformed" | "unstable" | "read-failed" | "legacy_migration_disabled" | "oversized";
|
|
558
|
+
reason: "missing" | "malformed" | "unstable" | "read-failed" | "legacy_migration_disabled" | "oversized" | "context_too_large";
|
|
350
559
|
size?: number;
|
|
351
560
|
}
|
|
352
561
|
export type SessionDirectoryMigrationPolicy = ManagedMigrationPolicy;
|
|
353
562
|
export type SessionAppendPersistenceFailurePhase = "current_append" | "prior_failure";
|
|
354
|
-
/**
|
|
355
|
-
* Safety bound for resuming a single transcript file. Matches the managed-storage
|
|
356
|
-
* per-file artifact limit (`MANAGED_ARTIFACT_MAX_FILE_BYTES`): transcripts at or above
|
|
357
|
-
* this size are not loaded into memory wholesale because the decode + per-line JSON
|
|
358
|
-
* parse + identity hash would OOM or stall the process (#3851). The bound is a
|
|
359
|
-
* load-time guard only; it does not raise the on-disk managed-storage limit.
|
|
360
|
-
*/
|
|
563
|
+
/** Safety bound for eager resume compatibility and managed per-file artifacts. */
|
|
361
564
|
export declare const RESUME_TRANSCRIPT_MAX_BYTES: number;
|
|
362
565
|
export declare const SESSION_OVERSIZED_RECOVERY_MESSAGE = "The selected session transcript is too large to resume safely. Use `gjc export <session-file>` to export its content into a new session, or remove/archive it after confirming its content is no longer needed.";
|
|
363
566
|
export declare class SessionAppendPersistenceError extends Error {
|
|
@@ -383,6 +586,21 @@ export declare class SessionTranscriptOversizedError extends Error {
|
|
|
383
586
|
readonly size: number;
|
|
384
587
|
constructor(size: number);
|
|
385
588
|
}
|
|
589
|
+
/** Operation-peak budget for one synchronous session-context materialization. */
|
|
590
|
+
export declare const SESSION_CONTEXT_MATERIALIZATION_BUDGET_BYTES: number;
|
|
591
|
+
/**
|
|
592
|
+
* Thrown by the synchronous session-context builders when the materialized graph
|
|
593
|
+
* exceeds the operation budget. `instanceof`-stable across module boundaries:
|
|
594
|
+
* consumers map with `error instanceof SessionContextTooLargeError`, never by name
|
|
595
|
+
* string. The over-budget graph is never retained — the builder releases scratch
|
|
596
|
+
* before throwing and public synchronous signatures are unchanged.
|
|
597
|
+
*/
|
|
598
|
+
export declare class SessionContextTooLargeError extends Error {
|
|
599
|
+
readonly code: "context_too_large";
|
|
600
|
+
readonly measuredBytes: number;
|
|
601
|
+
readonly budgetBytes: number;
|
|
602
|
+
constructor(measuredBytes: number, budgetBytes?: number, options?: ErrorOptions);
|
|
603
|
+
}
|
|
386
604
|
export type ResumeTailInspection = ResumeTailResumable | ResumeTailTerminal | ResumeTailError;
|
|
387
605
|
export interface StrictSessionOpenSuccess {
|
|
388
606
|
kind: "opened";
|
|
@@ -394,16 +612,42 @@ export interface StrictSessionOpenFailure {
|
|
|
394
612
|
message?: string;
|
|
395
613
|
size?: number;
|
|
396
614
|
}
|
|
397
|
-
/**
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
615
|
+
/**
|
|
616
|
+
* Descriptor-bound strict-capture handle. Bounded recorded-length range reads
|
|
617
|
+
* revalidate the live source against the captured identity on every pass; no
|
|
618
|
+
* whole-transcript buffer is ever materialized by capture or fork.
|
|
619
|
+
*/
|
|
620
|
+
export interface TranscriptSnapshotHandle {
|
|
621
|
+
readonly sourcePath: string;
|
|
622
|
+
readonly identity: ResumeSessionIdentity;
|
|
623
|
+
readonly storage: SessionStorage;
|
|
624
|
+
/**
|
|
625
|
+
* Iterate every transcript line in bounded recorded-length reads. Each line
|
|
626
|
+
* is delivered without its trailing newline; returning `false` aborts the
|
|
627
|
+
* pass. A completed pass re-validates the running content hash against the
|
|
628
|
+
* captured identity and throws `identity-mismatch` on divergence.
|
|
629
|
+
*/
|
|
630
|
+
forEachLine(callback: (line: Uint8Array) => boolean | undefined): boolean;
|
|
631
|
+
/** Descriptor captured after the most recent complete line pass, when supported. */
|
|
632
|
+
getLastReadStat(): SessionStorageStat | undefined;
|
|
633
|
+
/** Revalidate the live source against the captured identity (bounded). */
|
|
634
|
+
revalidate(): {
|
|
635
|
+
kind: "valid";
|
|
636
|
+
} | StrictSessionOpenFailure;
|
|
637
|
+
/** Idempotent close; subsequent reads throw. */
|
|
638
|
+
close(): void;
|
|
639
|
+
/**
|
|
640
|
+
* Rehydrate the full transcript bytes for bounded-full-return consumers.
|
|
641
|
+
* This is an explicit compatibility escape hatch, never used by fork/capture
|
|
642
|
+
* publication itself.
|
|
643
|
+
*/
|
|
644
|
+
materialize(): Uint8Array;
|
|
403
645
|
}
|
|
646
|
+
/** @deprecated Use {@link TranscriptSnapshotHandle}; retained for call-site compatibility. */
|
|
647
|
+
export type CapturedSessionTranscriptSnapshot = TranscriptSnapshotHandle;
|
|
404
648
|
export type StrictSessionCaptureResult = {
|
|
405
649
|
kind: "captured";
|
|
406
|
-
snapshot:
|
|
650
|
+
snapshot: TranscriptSnapshotHandle;
|
|
407
651
|
} | ResumeTailError;
|
|
408
652
|
export type StrictSessionForkResult = {
|
|
409
653
|
kind: "forked";
|
|
@@ -521,11 +765,6 @@ export declare function migrateSessionEntries(entries: FileEntry[]): void;
|
|
|
521
765
|
/** Exported for compaction.test.ts */
|
|
522
766
|
export declare function parseSessionEntries(content: string): FileEntry[];
|
|
523
767
|
export declare function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null;
|
|
524
|
-
/**
|
|
525
|
-
* Build the session context from entries using tree traversal.
|
|
526
|
-
* If leafId is provided, walks from that entry to root.
|
|
527
|
-
* Handles compaction and branch summaries along the path.
|
|
528
|
-
*/
|
|
529
768
|
export declare function buildSessionContext(entries: SessionEntry[], leafId?: string | null, byId?: Map<string, SessionEntry>, sessionIdentityNamespace?: string): SessionContext;
|
|
530
769
|
/** A session directory's authority is distinct from its string path. */
|
|
531
770
|
export type SessionDestination = {
|
|
@@ -550,6 +789,7 @@ type ForkArtifactPublication = {
|
|
|
550
789
|
};
|
|
551
790
|
/** Exported for testing */
|
|
552
791
|
export declare function loadEntriesFromFile(filePath: string, storage?: SessionStorage): Promise<FileEntry[]>;
|
|
792
|
+
export declare const TRANSCRIPT_CAPTURE_CHUNK_BYTES: number;
|
|
553
793
|
declare class RecentSessionInfo {
|
|
554
794
|
#private;
|
|
555
795
|
readonly path: string;
|
|
@@ -640,8 +880,29 @@ export declare const SessionManagerTestHooks: {
|
|
|
640
880
|
materializedCacheMaxBytesOverride?: number;
|
|
641
881
|
beforeResidentTransitionIndexBuild?: () => void;
|
|
642
882
|
afterForkSnapshot?: () => void | Promise<void>;
|
|
883
|
+
afterForkTranscriptPublished?: () => void | Promise<void>;
|
|
643
884
|
beforeEphemeralArtifactManagerInstall?: (dir: string) => void | Promise<void>;
|
|
885
|
+
beforePersistPatchFence?: (attempt: number) => void;
|
|
644
886
|
};
|
|
887
|
+
/**
|
|
888
|
+
* Freshness snapshot captured with every async whole-session persistence
|
|
889
|
+
* preparation. Immediately before the synchronous persistence transaction, the
|
|
890
|
+
* live values are compared: a `sessionFile`/`lifecycleId` change aborts (lifecycle
|
|
891
|
+
* switch); a revision change discards the prepared bytes and re-prepares (bounded),
|
|
892
|
+
* so a stale snapshot is never published.
|
|
893
|
+
*/
|
|
894
|
+
export interface PersistenceInputToken {
|
|
895
|
+
/** Canonical session file path the prepared bytes target. */
|
|
896
|
+
sessionFile: string;
|
|
897
|
+
/** Per-manager lifecycle identity (`sessionId@sessionFile`); changes on switch/open/reset. */
|
|
898
|
+
lifecycleId: string;
|
|
899
|
+
/** Revision of #fileEntries affecting persisted bytes. */
|
|
900
|
+
entryRevision: number;
|
|
901
|
+
/** Header/version revision affecting persisted bytes. */
|
|
902
|
+
headerRevision: number;
|
|
903
|
+
/** Resident/blob store revision affecting persisted bytes. */
|
|
904
|
+
residentBlobRevision: number;
|
|
905
|
+
}
|
|
645
906
|
export declare class SessionManager {
|
|
646
907
|
#private;
|
|
647
908
|
private cwd;
|
|
@@ -753,6 +1014,8 @@ export declare class SessionManager {
|
|
|
753
1014
|
listForResumePickerReadOnly(): Promise<SessionInfo[]>;
|
|
754
1015
|
getSessionId(): string;
|
|
755
1016
|
getSessionFile(): string | undefined;
|
|
1017
|
+
getSessionMemoryStats(): SessionMemoryStats;
|
|
1018
|
+
setSessionMemoryMode(mode: "off" | "shadow" | "enabled"): void;
|
|
756
1019
|
acquireMemoryGuardParticipantIngressLease(): MemoryGuardParticipantIngressLease;
|
|
757
1020
|
createMemoryGuardCheckpoint(input: MemoryGuardCreateCheckpointInput): Promise<MemoryGuardSessionManagerCheckpointV1>;
|
|
758
1021
|
/**
|
|
@@ -938,10 +1201,21 @@ export declare class SessionManager {
|
|
|
938
1201
|
/**
|
|
939
1202
|
* Get the most recent model role from the current session path.
|
|
940
1203
|
* Returns undefined if no model change has been recorded.
|
|
1204
|
+
*
|
|
1205
|
+
* R1: keyed ONLY on the nearest `model_change` on the leaf→root path — never on
|
|
1206
|
+
* `hasExplicitDefaultModel`, which gates only legacy assistant inference into
|
|
1207
|
+
* `models.default` inside `buildSessionContext`. Six parity cases (D1): reviewer-
|
|
1208
|
+
* only → "reviewer"; temporary-only → "temporary"; interleaved → nearest;
|
|
1209
|
+
* no model_change → undefined; legacy-only inference → undefined; explicit
|
|
1210
|
+
* default then legacy inference → "default".
|
|
941
1211
|
*/
|
|
942
1212
|
getLastModelChangeRole(): string | undefined;
|
|
943
1213
|
evictCompactedContent(firstKeptEntryId: string, compactionEntryId: string): EvictCompactedContentResult;
|
|
944
1214
|
getObservabilityStatsForTests(): SessionManagerObservabilityStats;
|
|
1215
|
+
setSidecarHotSuffixBudgetForTests(bytes: number): void;
|
|
1216
|
+
parentChildrenCacheKeysForTests(): string[];
|
|
1217
|
+
parentArtifactEnabledForTests(): boolean;
|
|
1218
|
+
setParentArtifactBudgetForTests(bytes: number): void;
|
|
945
1219
|
hotRetainedMessageCharsForTests(): number;
|
|
946
1220
|
getCanonicalEntryForTests(id: string): SessionEntry | undefined;
|
|
947
1221
|
getEntryForFidelity(id: string): SessionEntry | undefined;
|
|
@@ -952,6 +1226,7 @@ export declare class SessionManager {
|
|
|
952
1226
|
* sync; callers must not mutate returned entries.
|
|
953
1227
|
*/
|
|
954
1228
|
getActivePathEntriesCanonical(fromId?: string): SessionEntry[];
|
|
1229
|
+
visitEntriesForExport(visitor: (entry: SessionEntry) => void): void;
|
|
955
1230
|
getEntriesForExport(): SessionEntry[];
|
|
956
1231
|
getEntry(id: string): SessionEntry | undefined;
|
|
957
1232
|
/**
|
|
@@ -1046,14 +1321,14 @@ export declare class SessionManager {
|
|
|
1046
1321
|
* Fork a session into the current project directory.
|
|
1047
1322
|
* Copies history from another session file while creating a new session file in the current sessionDir.
|
|
1048
1323
|
*/
|
|
1049
|
-
static forkFrom(sourcePath: string, cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1324
|
+
static forkFrom(sourcePath: string, cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1050
1325
|
/**
|
|
1051
1326
|
* Open a specific session file.
|
|
1052
1327
|
* @param path Path to session file
|
|
1053
1328
|
* @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.
|
|
1054
1329
|
*/
|
|
1055
|
-
static open(filePath: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1056
|
-
static openNestedManaged(filePath: string, destination: SessionDestination, store: ManagedSessionDescendantStore, storage?: SessionStorage, cwdOverride?: string): Promise<SessionManager>;
|
|
1330
|
+
static open(filePath: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1331
|
+
static openNestedManaged(filePath: string, destination: SessionDestination, store: ManagedSessionDescendantStore, storage?: SessionStorage, cwdOverride?: string, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1057
1332
|
/**
|
|
1058
1333
|
* List default-managed sessions for the resume picker without recovery or other
|
|
1059
1334
|
* maintenance writes. This is the only picker inventory that includes legacy
|
|
@@ -1075,7 +1350,7 @@ export declare class SessionManager {
|
|
|
1075
1350
|
* revalidate captured authority before destination initialization and transcript
|
|
1076
1351
|
* persistence; destination history always comes from the captured bytes.
|
|
1077
1352
|
*/
|
|
1078
|
-
static forkFromCaptured(snapshot: CapturedSessionTranscriptSnapshot, cwd: string, destinationInput?: SessionDestinationInput, _migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<StrictSessionForkResult>;
|
|
1353
|
+
static forkFromCaptured(snapshot: CapturedSessionTranscriptSnapshot, cwd: string, destinationInput?: SessionDestinationInput, _migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<StrictSessionForkResult>;
|
|
1079
1354
|
static restoreMemoryGuardCheckpoint(input: MemoryGuardRestoreInput): Promise<MemoryGuardRestoreResult>;
|
|
1080
1355
|
/** Inspect a selected session without acquiring write-capable ownership. */
|
|
1081
1356
|
static inspectSessionTailReadOnly(filePath: string, storage?: SessionStorage): Promise<ResumeTailInspection>;
|
|
@@ -1096,13 +1371,13 @@ export declare class SessionManager {
|
|
|
1096
1371
|
* the returned discriminant; an error result never creates, rewrites, or adopts
|
|
1097
1372
|
* the selected path. Breadcrumb ownership begins only after `kind: "opened"`.
|
|
1098
1373
|
*/
|
|
1099
|
-
static openExistingStrict(identity: ResumeSessionIdentity, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<StrictSessionOpenResult>;
|
|
1374
|
+
static openExistingStrict(identity: ResumeSessionIdentity, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<StrictSessionOpenResult>;
|
|
1100
1375
|
/**
|
|
1101
1376
|
* Continue the most recent session, or create new if none.
|
|
1102
1377
|
* @param cwd Working directory
|
|
1103
1378
|
* @param sessionDir Optional session directory. If omitted, uses default (~/.gjc/agent/sessions/<encoded-cwd>/).
|
|
1104
1379
|
*/
|
|
1105
|
-
static continueRecent(cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1380
|
+
static continueRecent(cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1106
1381
|
/** Create an in-memory session (no file persistence) */
|
|
1107
1382
|
static inMemory(cwd?: string, storage?: SessionStorage): SessionManager;
|
|
1108
1383
|
/**
|