@rynfar/meridian 1.62.6 → 1.63.0

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 (53) hide show
  1. package/bin/meridian-launchd.sh +128 -0
  2. package/dist/{cli-xmweegb1.js → cli-8yp89fan.js} +52 -0
  3. package/dist/{cli-wxk8xvd3.js → cli-hdyptm7z.js} +4934 -769
  4. package/dist/{cli-d45dq9gf.js → cli-xfbhn15a.js} +31 -10
  5. package/dist/cli.js +4 -4
  6. package/dist/{pluginPage-03q5j753.js → pluginPage-n3gdtbmj.js} +1 -1
  7. package/dist/{profileCli-7f6yhakj.js → profileCli-39vshwdn.js} +1 -1
  8. package/dist/{profilePage-gtazq15d.js → profilePage-vfj2dbhn.js} +1 -1
  9. package/dist/proxy/adapter.d.ts +13 -0
  10. package/dist/proxy/adapter.d.ts.map +1 -1
  11. package/dist/proxy/adapters/opencode.d.ts +7 -0
  12. package/dist/proxy/adapters/opencode.d.ts.map +1 -1
  13. package/dist/proxy/buildInfo.d.ts +94 -0
  14. package/dist/proxy/buildInfo.d.ts.map +1 -0
  15. package/dist/proxy/cwd.d.ts.map +1 -1
  16. package/dist/proxy/errors.d.ts.map +1 -1
  17. package/dist/proxy/models.d.ts +20 -9
  18. package/dist/proxy/models.d.ts.map +1 -1
  19. package/dist/proxy/passthroughDenial.d.ts +17 -0
  20. package/dist/proxy/passthroughDenial.d.ts.map +1 -0
  21. package/dist/proxy/passthroughEarlyStop.d.ts +64 -10
  22. package/dist/proxy/passthroughEarlyStop.d.ts.map +1 -1
  23. package/dist/proxy/query.d.ts +16 -0
  24. package/dist/proxy/query.d.ts.map +1 -1
  25. package/dist/proxy/server.d.ts.map +1 -1
  26. package/dist/proxy/session/cache.d.ts +11 -2
  27. package/dist/proxy/session/cache.d.ts.map +1 -1
  28. package/dist/proxy/session/crossProcessTurnCoordinator.d.ts +40 -0
  29. package/dist/proxy/session/crossProcessTurnCoordinator.d.ts.map +1 -0
  30. package/dist/proxy/session/durableFileSystem.d.ts +21 -0
  31. package/dist/proxy/session/durableFileSystem.d.ts.map +1 -0
  32. package/dist/proxy/session/lineage.d.ts +20 -0
  33. package/dist/proxy/session/lineage.d.ts.map +1 -1
  34. package/dist/proxy/session/processIncarnation.d.ts +46 -0
  35. package/dist/proxy/session/processIncarnation.d.ts.map +1 -0
  36. package/dist/proxy/session/recoveryClaim.d.ts +19 -0
  37. package/dist/proxy/session/recoveryClaim.d.ts.map +1 -0
  38. package/dist/proxy/session/sdkProcessGate.d.ts +19 -0
  39. package/dist/proxy/session/sdkProcessGate.d.ts.map +1 -0
  40. package/dist/proxy/sessionLifecycle.d.ts +105 -0
  41. package/dist/proxy/sessionLifecycle.d.ts.map +1 -0
  42. package/dist/proxy/sessionStore.d.ts +53 -7
  43. package/dist/proxy/sessionStore.d.ts.map +1 -1
  44. package/dist/proxy/types.d.ts +4 -0
  45. package/dist/proxy/types.d.ts.map +1 -1
  46. package/dist/proxy/updateCheck.d.ts +31 -0
  47. package/dist/proxy/updateCheck.d.ts.map +1 -0
  48. package/dist/server.js +3 -3
  49. package/dist/telemetry/profileBar.d.ts +3 -3
  50. package/dist/telemetry/profileBar.d.ts.map +1 -1
  51. package/dist/telemetry/settingsPage.d.ts +1 -1
  52. package/dist/telemetry/settingsPage.d.ts.map +1 -1
  53. package/package.json +3 -2
@@ -0,0 +1,40 @@
1
+ export interface CrossProcessTurnCoordinatorOptions {
2
+ /** Maximum time an acquire may wait. Acquires always have a finite bound. */
3
+ acquireTimeoutMs?: number;
4
+ /** A lock with no fresh heartbeat for this long may be recovered. */
5
+ staleAfterMs?: number;
6
+ /** Defaults to one third of `staleAfterMs`. Must be shorter than it. */
7
+ heartbeatIntervalMs?: number;
8
+ /** Delay between attempts while another process owns the turn. */
9
+ retryDelayMs?: number;
10
+ }
11
+ export interface CrossProcessTurnLease {
12
+ readonly waitedMs: number;
13
+ /** Stop the heartbeat and release the lock if this lease still owns it. */
14
+ release(): Promise<void>;
15
+ }
16
+ export declare class CrossProcessTurnAcquireTimeoutError extends Error {
17
+ constructor(timeoutMs: number);
18
+ }
19
+ export declare class CrossProcessTurnOwnershipError extends Error {
20
+ constructor(message?: string);
21
+ }
22
+ /**
23
+ * Serializes one logical turn key across processes using atomic filesystem
24
+ * directory operations. Lock errors never cause an unlocked turn to proceed.
25
+ */
26
+ export declare class CrossProcessTurnCoordinator {
27
+ private readonly root;
28
+ private readonly acquireTimeoutMs;
29
+ private readonly staleAfterMs;
30
+ private readonly heartbeatIntervalMs;
31
+ private readonly retryDelayMs;
32
+ constructor(root: string, options?: CrossProcessTurnCoordinatorOptions);
33
+ acquire(key: string, signal?: AbortSignal): Promise<CrossProcessTurnLease>;
34
+ private tryAcquire;
35
+ private createLease;
36
+ private recover;
37
+ private releaseOwned;
38
+ private wait;
39
+ }
40
+ //# sourceMappingURL=crossProcessTurnCoordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crossProcessTurnCoordinator.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/crossProcessTurnCoordinator.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,kCAAkC;IACjD,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,2EAA2E;IAC3E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAkBD,qBAAa,mCAAoC,SAAQ,KAAK;gBAChD,SAAS,EAAE,MAAM;CAI9B;AAED,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,OAAO,SAAqD;CAIzE;AAmRD;;;GAGG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,kCAAuC;IAwBpE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC;YA2ClE,UAAU;IA2CxB,OAAO,CAAC,WAAW;YA0CL,OAAO;YA2CP,YAAY;IAgC1B,OAAO,CAAC,IAAI;CAsBb"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Persist directory metadata where the runtime exposes a directory handle.
3
+ *
4
+ * Node on Windows does not support opening directories for fsync. Windows has
5
+ * no equivalent API here, so preserve the fsynced-file + atomic-rename order
6
+ * and skip only this unsupported metadata flush. On supported platforms every
7
+ * open, sync, and close error remains fail-closed.
8
+ */
9
+ export declare function syncDirectoryDurably(path: string): Promise<void>;
10
+ /** Synchronous form for the session store's synchronous lock protocol. */
11
+ export declare function syncDirectoryDurablySync(path: string): void;
12
+ /**
13
+ * Classify an atomic directory publication collision without masking a real
14
+ * Windows permission or filesystem error. Windows reports EPERM/EACCES rather
15
+ * than EEXIST when the destination directory is already present, so accept
16
+ * those codes only after proving that the destination currently exists.
17
+ */
18
+ export declare function directoryRenameWasBlocked(error: unknown, destination: string): Promise<boolean>;
19
+ /** Synchronous form for the session store's recovery-claim protocol. */
20
+ export declare function directoryRenameWasBlockedSync(error: unknown, destination: string): boolean;
21
+ //# sourceMappingURL=durableFileSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durableFileSystem.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/durableFileSystem.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtE;AAED,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQ3D;AAWD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wEAAwE;AACxE,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAa1F"}
@@ -50,6 +50,17 @@ export interface SessionState {
50
50
  passthroughToolCallIds?: string[];
51
51
  /** Last observed token usage for this session (from SDK message_start / message_delta events) */
52
52
  contextUsage?: TokenUsage;
53
+ /** Exact SDK transcript roots for cross-process lifecycle retention. */
54
+ currentTranscript?: {
55
+ sessionId: string;
56
+ configDir: string;
57
+ projectDir?: string;
58
+ };
59
+ previousTranscript?: {
60
+ sessionId: string;
61
+ configDir: string;
62
+ projectDir?: string;
63
+ };
53
64
  }
54
65
  /**
55
66
  * Associate SDK assistant events from the current upstream run with the single
@@ -58,6 +69,15 @@ export interface SessionState {
58
69
  * assistant UUID as the undo checkpoint for the consolidated client turn.
59
70
  */
60
71
  export declare function withClientAssistantUuid(existing: Array<string | null>, clientMessageCount: number, uuid: unknown): Array<string | null>;
72
+ /**
73
+ * Reconcile rollback UUIDs with the session the SDK actually returned.
74
+ *
75
+ * A fork remaps every copied transcript UUID, so UUIDs inherited from the
76
+ * resumed session are invalid in the returned session. The one UUID observed
77
+ * for this request's new client-visible assistant remains valid and occupies
78
+ * its future client message slot.
79
+ */
80
+ export declare function reconcileReturnedSessionUuids(existing: Array<string | null>, clientMessageCount: number, currentAssistantUuid: string | null, resumeSessionId: string | undefined, returnedSessionId: string | undefined): Array<string | null>;
61
81
  /**
62
82
  * Result of lineage verification — classifies the mutation and provides
63
83
  * the information needed to take the correct SDK action.
@@ -1 +1 @@
1
- {"version":3,"file":"lineage.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/lineage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lineage.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/lineage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ export declare const PROCESS_INCARNATION_VERSION = 1;
2
+ export type ProcessStartIdKind = "linux-proc-start-ticks" | "darwin-ps-lstart" | "windows-start-ticks";
3
+ /**
4
+ * OS-backed identity for one process incarnation.
5
+ *
6
+ * `hostId` identifies the machine (and Linux PID namespace), `bootId`
7
+ * identifies one boot of that machine, and `startId` distinguishes PID reuse
8
+ * within the boot. Raw machine IDs are hashed before they are persisted.
9
+ */
10
+ export interface ProcessIncarnation {
11
+ version: typeof PROCESS_INCARNATION_VERSION;
12
+ pid: number;
13
+ hostId: string;
14
+ bootId: string;
15
+ startId: string;
16
+ startIdKind: ProcessStartIdKind;
17
+ }
18
+ export type ProcessIncarnationProbe = "alive" | "dead" | "indeterminate";
19
+ export interface LocalBootIdentity {
20
+ hostId: string;
21
+ bootId: string;
22
+ }
23
+ export type ProcessStartObservation = {
24
+ status: "found";
25
+ startId: string;
26
+ startIdKind: ProcessStartIdKind;
27
+ } | {
28
+ status: "missing";
29
+ } | {
30
+ status: "indeterminate";
31
+ };
32
+ export declare function parseProcessIncarnation(value: unknown): ProcessIncarnation | undefined;
33
+ export declare function parseProcessIncarnationJson(raw: string): ProcessIncarnation | undefined;
34
+ /**
35
+ * Pure recovery decision. Only `dead` is permission to retire an owner's lock.
36
+ * Unknown hosts and every unavailable or malformed observation fail closed.
37
+ */
38
+ export declare function evaluateProcessIncarnation(owner: ProcessIncarnation, localBoot: LocalBootIdentity | undefined, observedStart: ProcessStartObservation | undefined): ProcessIncarnationProbe;
39
+ /** Parse field 22 (`starttime`) without assuming that comm contains no `)`. */
40
+ export declare function parseLinuxProcStatStartId(raw: string, expectedPid: number): string | undefined;
41
+ /** Capture metadata for a lock created by `pid` (normally the current process). */
42
+ export declare function captureProcessIncarnation(pid?: number): ProcessIncarnation | undefined;
43
+ /** Probe one stored owner. Recovery callers must act only on `dead`. */
44
+ export declare function probeProcessIncarnation(owner: ProcessIncarnation): ProcessIncarnationProbe;
45
+ export declare function processIncarnationIsDead(owner: ProcessIncarnation): boolean;
46
+ //# sourceMappingURL=processIncarnation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processIncarnation.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/processIncarnation.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,CAAA;AAEzB;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,2BAA2B,CAAA;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,MAAM,GAAG,eAAe,CAAA;AAExE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAA;AAkC/B,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAqBtF;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAMvF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,iBAAiB,GAAG,SAAS,EACxC,aAAa,EAAE,uBAAuB,GAAG,SAAS,GACjD,uBAAuB,CAsBzB;AA6HD,+EAA+E;AAC/E,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ9F;AAsDD,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,GAAG,SAAc,GAAG,kBAAkB,GAAG,SAAS,CAkB3F;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,uBAAuB,CAS1F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAE3E"}
@@ -0,0 +1,19 @@
1
+ import { type ProcessIncarnation } from "./processIncarnation";
2
+ export declare const RECOVERY_CLAIM_VERSION = 2;
3
+ export interface RecoveryClaimOwner {
4
+ version: typeof RECOVERY_CLAIM_VERSION;
5
+ generation: string;
6
+ token: string;
7
+ pid: number;
8
+ hostname: string;
9
+ createdAt: number;
10
+ incarnation: ProcessIncarnation;
11
+ }
12
+ export declare function createRecoveryClaimOwner(generation: string): RecoveryClaimOwner;
13
+ export declare function parseRecoveryClaimOwner(value: unknown): RecoveryClaimOwner | undefined;
14
+ export declare function parseRecoveryClaimOwnerJson(raw: string): RecoveryClaimOwner | undefined;
15
+ /** Only an authoritative OS incarnation mismatch proves that an owner is dead. */
16
+ export declare function recoveryClaimOwnerIsDead(owner: RecoveryClaimOwner, probe?: (incarnation: ProcessIncarnation) => boolean): boolean;
17
+ export declare function getRecoveryClaimPath(lockPath: string, generation: string): string;
18
+ export declare function getRecoveryClaimTombstonePath(claimPath: string, claimToken: string): string;
19
+ //# sourceMappingURL=recoveryClaim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryClaim.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/recoveryClaim.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,sBAAsB,CAAA;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,kBAAkB,CAAA;CAChC;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAa/E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CA4BtF;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAMvF;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,kBAAkB,EACzB,KAAK,GAAE,CAAC,WAAW,EAAE,kBAAkB,KAAK,OAAkC,GAC7E,OAAO,CAET;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F"}
@@ -0,0 +1,19 @@
1
+ import type { SpawnedProcess, SpawnOptions } from "@anthropic-ai/claude-agent-sdk";
2
+ import { type ProcessIncarnation } from "./processIncarnation";
3
+ export interface SdkProcessGate {
4
+ readonly executor: ProcessIncarnation;
5
+ /** False means a crashed proxy's lease must remain fail-closed forever. */
6
+ readonly recoverableAfterCrash: boolean;
7
+ readonly spawnClaudeCodeProcess: (options: SpawnOptions) => SpawnedProcess;
8
+ /** True only after the exact wrapper/CLI process has exited safely. */
9
+ closeAndJoin(timeoutMs?: number): Promise<boolean>;
10
+ }
11
+ /**
12
+ * Start a harmless gated wrapper and capture its exact incarnation before the
13
+ * SDK can execute Claude Code. POSIX wrappers `exec` the CLI in the same PID.
14
+ * Windows keeps a PowerShell parent for the complete CLI lifetime; crash
15
+ * recovery of that lease is deliberately disabled because Windows has no
16
+ * built-in, authoritative descendant-group incarnation.
17
+ */
18
+ export declare function createSdkProcessGate(root: string, attachExecutor: (executor: ProcessIncarnation, recoverableAfterCrash: boolean) => Promise<void>, onStderr?: (data: string) => void): Promise<SdkProcessGate>;
19
+ //# sourceMappingURL=sdkProcessGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdkProcessGate.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/sdkProcessGate.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACb,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAA;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAA;IACvC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,cAAc,CAAA;IAC1E,uEAAuE;IACvE,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnD;AAuJD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/F,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,cAAc,CAAC,CAmGzB"}
@@ -0,0 +1,105 @@
1
+ import { type ProcessIncarnation } from "./session/processIncarnation";
2
+ export interface TranscriptLocator {
3
+ sessionId: string;
4
+ /** The absolute CLAUDE_CONFIG_DIR which owns this transcript. */
5
+ configDir: string;
6
+ /** SDK project directory, passed as deleteSession(..., { dir }). */
7
+ projectDir?: string;
8
+ /** Opaque physical-ownership fence. Omitted only on legacy store locators. */
9
+ lifecycleGeneration?: string;
10
+ }
11
+ export type TranscriptResourceState = "prepared" | "live" | "retired" | "deleting" | "deleted";
12
+ export type SessionDeleter = (locator: TranscriptLocator) => Promise<void>;
13
+ export interface SessionLifecycleOptions {
14
+ /** Test seam. Production callers should use getSessionStoreDir(). */
15
+ storeDir?: string;
16
+ deleter?: SessionDeleter;
17
+ now?: () => number;
18
+ /** Maximum non-live ownership backlog (prepared/retired/deleting). */
19
+ maxPending?: number;
20
+ /** Hard ceiling across every non-deleted owned transcript. */
21
+ maxOwned?: number;
22
+ maxTombstones?: number;
23
+ maxDeletesPerRun?: number;
24
+ lockWaitMs?: number;
25
+ lockRetryMs?: number;
26
+ lockStaleMs?: number;
27
+ preparedGraceMs?: number;
28
+ deletingLeaseMs?: number;
29
+ /** Quarantine after retirement so old readers and rolling upgrades can drain. */
30
+ retiredGraceMs?: number;
31
+ retryBaseMs?: number;
32
+ retryMaxMs?: number;
33
+ deletionTimeoutMs?: number;
34
+ /** Refresh durable mapping pins before each destructive claim. */
35
+ pinProvider?: () => readonly TranscriptLocator[];
36
+ /** Bound one complete sweep, including all child deletions. */
37
+ runTimeoutMs?: number;
38
+ }
39
+ export interface ActiveTranscriptLease {
40
+ token: string;
41
+ resourceKeys: string[];
42
+ }
43
+ export interface ReconcileResult {
44
+ preparedRetired: number;
45
+ liveRetired: number;
46
+ resourcesPinned: number;
47
+ deletingRecovered: number;
48
+ }
49
+ export interface GcResult {
50
+ deleted: number;
51
+ notFound: number;
52
+ failed: number;
53
+ deferred: number;
54
+ }
55
+ export declare class SessionLifecycleError extends Error {
56
+ }
57
+ export declare class SessionLifecycleLockError extends SessionLifecycleError {
58
+ }
59
+ export declare class SessionLifecycleCorruptError extends SessionLifecycleError {
60
+ }
61
+ export declare class SessionLifecycleBacklogError extends SessionLifecycleError {
62
+ }
63
+ /** Stable ownership key. The separator prevents ambiguous concatenation. */
64
+ export declare function getTranscriptResourceKey(locator: TranscriptLocator): string;
65
+ /** Persist a cross-process writer lease before an SDK child can touch transcripts. */
66
+ export declare function acquireActiveTranscriptLease(locators: readonly TranscriptLocator[], options?: SessionLifecycleOptions): Promise<ActiveTranscriptLease>;
67
+ /** Arm a writer lease with the exact gated shell/CLI process incarnation. */
68
+ export declare function attachActiveTranscriptExecutor(lease: ActiveTranscriptLease, executor: ProcessIncarnation, options?: SessionLifecycleOptions, executorRecoverable?: boolean): Promise<void>;
69
+ /** Release only this exact writer lease after its child has been joined. */
70
+ export declare function releaseActiveTranscriptLease(lease: ActiveTranscriptLease, options?: SessionLifecycleOptions): Promise<void>;
71
+ /** Persist ownership before the SDK process which can create the transcript starts. */
72
+ export declare function prepareFork(locator: TranscriptLocator, options?: SessionLifecycleOptions): Promise<TranscriptLocator>;
73
+ /** Ensure a legacy/direct-resume locator is journaled without promoting a prepared target. */
74
+ export declare function ensureTranscriptJournaled(locator: TranscriptLocator, options?: SessionLifecycleOptions): Promise<TranscriptLocator>;
75
+ /** Register an existing SDK transcript as Meridian-owned without a fork intent. */
76
+ export declare function registerLiveTranscript(locator: TranscriptLocator, options?: SessionLifecycleOptions): Promise<TranscriptLocator>;
77
+ /** Mark a successfully spawned, Meridian-owned fork as live. */
78
+ export declare function commitFork(locator: TranscriptLocator, options?: SessionLifecycleOptions): Promise<void>;
79
+ /**
80
+ * Fence durable mapping publication against GC's final claim transaction.
81
+ * The callback must be synchronous and must perform the session-store CAS.
82
+ * A normal publisher must refer to an already journaled resource. This makes
83
+ * tombstone pruning safe: a delayed old publisher cannot recreate a locator
84
+ * that GC already deleted.
85
+ */
86
+ export declare function publishPinnedTranscript<T extends boolean | string>(locator: TranscriptLocator, publish: () => T, options?: SessionLifecycleOptions): Promise<T>;
87
+ /**
88
+ * Atomically attach a legacy mapping whose source predates lifecycle metadata.
89
+ * Missing-resource creation is allowed only inside the same lifecycle critical
90
+ * section as the exact session-store CAS, so there is no stale publish gap.
91
+ */
92
+ export declare function attachPinnedTranscript<T extends boolean | string>(locator: TranscriptLocator, publish: () => T, options?: SessionLifecycleOptions): Promise<T>;
93
+ /** Retire an intent when spawn fails. It remains tracked until SDK deletion succeeds. */
94
+ export declare function abandonFork(locator: TranscriptLocator, options?: SessionLifecycleOptions): Promise<void>;
95
+ /**
96
+ * Reconcile durable ownership with caller-provided current and previous pins.
97
+ * Pins are the retention authority. Callers should pass both generations.
98
+ */
99
+ export declare function reconcile(pins: readonly TranscriptLocator[], options?: SessionLifecycleOptions): Promise<ReconcileResult>;
100
+ /** Delete a bounded batch of unpinned retired transcripts through the supported SDK API. */
101
+ export declare function runGc(pins: readonly TranscriptLocator[], options?: SessionLifecycleOptions): Promise<GcResult>;
102
+ export declare function canonicalizeTranscriptLocator(locator: TranscriptLocator): TranscriptLocator;
103
+ /** Resolve a real Node runtime even when Meridian itself is bundled under Bun. */
104
+ export declare function getSessionGcNodeExecutable(): string;
105
+ //# sourceMappingURL=sessionLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionLifecycle.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionLifecycle.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,19 @@
10
10
  * Keys are either OpenCode session IDs or conversation fingerprints.
11
11
  */
12
12
  import type { TokenUsage } from "./session/lineage";
13
+ export interface TranscriptLocator {
14
+ sessionId: string;
15
+ configDir: string;
16
+ projectDir?: string;
17
+ /** Opaque lifecycle ownership fence; absent only on legacy mappings. */
18
+ lifecycleGeneration?: string;
19
+ }
13
20
  export interface StoredSession {
14
21
  claudeSessionId: string;
22
+ /** Monotonic per-entry revision retained for diagnostics and upgrades. */
23
+ revision?: number;
24
+ /** Unique publication token. Replaced on every durable mapping mutation. */
25
+ generationId?: string;
15
26
  createdAt: number;
16
27
  lastUsedAt: number;
17
28
  messageCount: number;
@@ -34,19 +45,54 @@ export interface StoredSession {
34
45
  * Enables recovery when a lineage bug (e.g. false compaction) causes the
35
46
  * original session to be abandoned and a new one started. */
36
47
  previousClaudeSessionId?: string;
48
+ /** Exact transcript location for the current Claude session. */
49
+ currentTranscript?: TranscriptLocator;
50
+ /** Transcript location retained when the session mapping is replaced. */
51
+ previousTranscript?: TranscriptLocator;
37
52
  }
53
+ export type StoredSessionGeneration = string;
54
+ /** Exact, key-bound durable generation used for compare-and-swap fencing. */
55
+ export declare function getStoredSessionGeneration(session: StoredSession, key: string): StoredSessionGeneration;
56
+ export declare function getMaxStoredSessionsLimit(): number;
38
57
  /** Set an explicit session store directory. Takes priority over env var.
39
- * Pass null to clear. For testing only.
40
- * @param opts.skipLocking — skip file locking (default true for test isolation) */
41
- export declare function setSessionStoreDir(dir: string | null, opts?: {
58
+ * Pass null to clear. For testing only. The legacy options parameter remains
59
+ * accepted for compatibility, but transactions are always locked. */
60
+ export declare function setSessionStoreDir(dir: string | null, _opts?: {
42
61
  skipLocking?: boolean;
43
62
  }): void;
63
+ /** Return the directory containing the cross-process session store. */
64
+ export declare function getSessionStoreDir(): string;
65
+ /** Read a strict, coherent snapshot for maintenance tasks such as session GC.
66
+ * Unlike lookup helpers, malformed JSON and I/O errors are propagated. */
67
+ export declare function readSessionStoreSnapshot(): Record<string, StoredSession>;
68
+ /** Capture exact durable generations for one adapter session across profile keys. */
69
+ export declare function readSessionStoreGenerationSnapshot(adapterSessionId: string, profileIds?: readonly string[]): Record<string, StoredSessionGeneration>;
70
+ export type SharedSessionLookupResult = {
71
+ status: "found";
72
+ session: StoredSession;
73
+ generation?: StoredSessionGeneration;
74
+ } | {
75
+ status: "missing";
76
+ existing?: StoredSession;
77
+ generation?: StoredSessionGeneration;
78
+ } | {
79
+ status: "error";
80
+ error: Error;
81
+ };
82
+ /** Distinguish an authoritative absence from a transient/corrupt read. */
83
+ export declare function lookupSharedSessionResult(key: string): SharedSessionLookupResult;
44
84
  export declare function lookupSharedSession(key: string): StoredSession | undefined;
85
+ export declare function lookupSharedSessionByClaudeIdResult(claudeSessionId: string): SharedSessionLookupResult;
45
86
  export declare function lookupSharedSessionByClaudeId(claudeSessionId: string): StoredSession | undefined;
46
- export declare function storeSharedSession(key: string, claudeSessionId: string, messageCount?: number, lineageHash?: string, messageHashes?: string[], sdkMessageUuids?: Array<string | null>, contextUsage?: TokenUsage, messageBlockHashes?: string[][], passthroughToolCallAssistantUuid?: string | null, passthroughToolCallIds?: string[] | null): void;
47
- /** Remove a single session from the shared file store.
48
- * Used when a session is detected as stale (e.g. expired upstream). */
49
- export declare function evictSharedSession(key: string): void;
87
+ export declare function storeSharedSession(key: string, claudeSessionId: string, messageCount?: number, lineageHash?: string, messageHashes?: string[], sdkMessageUuids?: Array<string | null>, contextUsage?: TokenUsage, messageBlockHashes?: string[][], passthroughToolCallAssistantUuid?: string | null, passthroughToolCallIds?: string[] | null, currentTranscript?: TranscriptLocator, sourceTranscript?: TranscriptLocator, expectedGeneration?: StoredSessionGeneration | null): StoredSessionGeneration | false;
88
+ /** Attach an exact transcript locator without changing lineage or SDK identity.
89
+ * The durable revision advances so concurrent readers cannot miss the mutation. */
90
+ export declare function attachSharedTranscriptLocator(key: string, expectedClaudeSessionId: string, locator: TranscriptLocator, expectedGeneration?: StoredSessionGeneration): StoredSessionGeneration | false;
91
+ /** Ensure a single session is absent from the shared file store.
92
+ * Used when a session is detected as stale (e.g. expired upstream).
93
+ * Absence is an idempotent success; false is reserved for a present mapping
94
+ * whose exact expected generation no longer matches. */
95
+ export declare function evictSharedSession(key: string, expectedGeneration?: StoredSessionGeneration): boolean;
50
96
  /** Look up recovery information for a session key.
51
97
  * Returns the current and previous Claude session IDs, plus derived
52
98
  * file paths and CLI commands for conversation recovery. */
@@ -1 +1 @@
1
- {"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAA;IAC/B,iFAAiF;IACjF,eAAe,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACtC;oFACgF;IAChF,gCAAgC,CAAC,EAAE,MAAM,CAAA;IACzC,qEAAqE;IACrE,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC,wDAAwD;IACxD,YAAY,CAAC,EAAE,UAAU,CAAA;IACzB;;kEAE8D;IAC9D,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC;AA0DD;;oFAEoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAG7F;AA2ED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAO1E;AAED,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAYhG;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,MAAM,EAAE,EACxB,eAAe,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,EACtC,YAAY,CAAC,EAAE,UAAU,EACzB,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,EAC/B,gCAAgC,CAAC,EAAE,MAAM,GAAG,IAAI,EAChD,sBAAsB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,GACvC,IAAI,CAqDN;AAED;wEACwE;AACxE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAkBpD;AAED;;6DAE6D;AAC7D,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG;IAClD,eAAe,EAAE,MAAM,CAAA;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,SAAS,CAWZ;AAED;uEACuE;AACvE,wBAAgB,kBAAkB,IAAI,KAAK,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,eAAe,EAAE,MAAM,CAAA;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAC,CAUD;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C"}
1
+ {"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionStore.ts"],"names":[],"mappings":"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"}
@@ -57,8 +57,12 @@ export interface ProxyServer {
57
57
  * to drain in-flight requests before the HTTP server actually shuts down.
58
58
  */
59
59
  beginDrain?(): void;
60
+ /** Revoke durable writes and abort work that outlived the shutdown grace. */
61
+ forceAbortInFlight?(): void;
60
62
  /** Count of requests admitted past the draining gate that haven't finished yet. */
61
63
  getInFlightCount?(): number;
64
+ /** Run one fail-closed transcript maintenance sweep. */
65
+ sweepSessionGc?(): Promise<void>;
62
66
  }
63
67
  export declare const DEFAULT_PROXY_CONFIG: ProxyConfig;
64
68
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,kBAAkB,EAAE,MAAM,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,oDAAoD;IACpD,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;IAC1B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAA;IACnB,mEAAmE;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,GAAG,EAAE;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IAClF,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAA;IACnB,qEAAqE;IACrE,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B;;;;OAIG;IACH,UAAU,CAAC,IAAI,IAAI,CAAA;IACnB,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,MAAM,CAAA;CAC5B;AAED,eAAO,MAAM,oBAAoB,EAAE,WAWlC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,kBAAkB,EAAE,MAAM,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,oDAAoD;IACpD,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;IAC1B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAA;IACnB,mEAAmE;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,GAAG,EAAE;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IAClF,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAA;IACnB,qEAAqE;IACrE,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B;;;;OAIG;IACH,UAAU,CAAC,IAAI,IAAI,CAAA;IACnB,6EAA6E;IAC7E,kBAAkB,CAAC,IAAI,IAAI,CAAA;IAC3B,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,MAAM,CAAA;IAC3B,wDAAwD;IACxD,cAAc,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,oBAAoB,EAAE,WAWlC,CAAA"}
@@ -0,0 +1,31 @@
1
+ export interface UpdateCheckOptions {
2
+ /** Cache location. Overridable so tests never touch the real cache. */
3
+ cachePath?: string;
4
+ ttlMs?: number;
5
+ now?: () => number;
6
+ /** Injected in tests; the default hits the npm registry. */
7
+ fetchLatest?: () => Promise<string | undefined>;
8
+ /** Called when a check resolves a version we did not already have. */
9
+ onResolved?: (latest: string) => void;
10
+ }
11
+ /**
12
+ * Resolve the newest published version, preferring a fresh disk cache.
13
+ *
14
+ * Returns a stale cached value when the registry is unreachable — see the
15
+ * module header for why that beats returning nothing.
16
+ */
17
+ export declare function checkForUpdate(options?: UpdateCheckOptions): Promise<string | undefined>;
18
+ /** The last resolved published version, or undefined if not yet known. */
19
+ export declare function getLatestVersion(): string | undefined;
20
+ /**
21
+ * Begin checking for updates in the background.
22
+ *
23
+ * Callers do not await this — startup never waits on the registry. The
24
+ * returned promise settles after the first check purely so tests can act on a
25
+ * resolved value instead of polling. The interval is unref'd so it cannot keep
26
+ * a short-lived embedder's process alive.
27
+ */
28
+ export declare function startUpdateCheck(options?: UpdateCheckOptions): Promise<void>;
29
+ /** Stop the background refresh (shutdown, and between tests). */
30
+ export declare function stopUpdateCheck(): void;
31
+ //# sourceMappingURL=updateCheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateCheck.d.ts","sourceRoot":"","sources":["../../src/proxy/updateCheck.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC/C,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAyCD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqBlG;AAOD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAErD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehF;AAED,iEAAiE;AACjE,wBAAgB,eAAe,IAAI,IAAI,CAItC"}
package/dist/server.js CHANGED
@@ -11,11 +11,11 @@ import {
11
11
  runObserveHook,
12
12
  runTransformHook,
13
13
  startProxyServer
14
- } from "./cli-wxk8xvd3.js";
14
+ } from "./cli-hdyptm7z.js";
15
15
  import"./cli-m0p2bc8v.js";
16
16
  import"./cli-sry5aqdj.js";
17
- import"./cli-xmweegb1.js";
18
- import"./cli-d45dq9gf.js";
17
+ import"./cli-8yp89fan.js";
18
+ import"./cli-xfbhn15a.js";
19
19
  import"./cli-vj9cv18n.js";
20
20
  import"./cli-pc0mtjjv.js";
21
21
  import"./cli-khhjyk04.js";
@@ -27,7 +27,7 @@ export declare const themeCss = "\n :root {\n /* Cool-gray neutral palette.
27
27
  * pole. Scales cleanly from favicon to hero size.
28
28
  */
29
29
  export declare const meridianLogoSvg = "<svg class=\"mh-logo\" width=\"24\" height=\"24\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <defs>\n <linearGradient id=\"mhGrad\" x1=\"32\" y1=\"4\" x2=\"32\" y2=\"60\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#58a6ff\"/>\n <stop offset=\"1\" stop-color=\"#bc8cff\"/>\n </linearGradient>\n </defs>\n <circle cx=\"32\" cy=\"32\" r=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"3.5\"/>\n <ellipse cx=\"32\" cy=\"32\" rx=\"10.5\" ry=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"2.5\" opacity=\"0.8\"/>\n <path d=\"M7 32h50\" stroke=\"url(#mhGrad)\" stroke-width=\"2\" opacity=\"0.4\"/>\n <circle cx=\"32\" cy=\"7\" r=\"4.5\" fill=\"#58a6ff\"/>\n <circle cx=\"32\" cy=\"57\" r=\"4.5\" fill=\"#bc8cff\"/>\n</svg>";
30
- export declare const profileBarCss = "\n .meridian-header {\n position: sticky; top: 0; z-index: 100;\n display: flex; align-items: center; gap: 20px;\n padding: 10px 24px;\n background: rgba(13, 17, 23, 0.92);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--border, #30363d);\n }\n .meridian-header .mh-brand {\n display: flex; align-items: center; gap: 10px;\n text-decoration: none; color: var(--text, #e6edf3);\n }\n .meridian-header .mh-logo { display: block; }\n .meridian-header .mh-name {\n font-size: 15px; font-weight: 700; letter-spacing: 2px;\n text-transform: uppercase;\n }\n .meridian-header .mh-nav { display: flex; align-items: center; gap: 2px; }\n .meridian-header .mh-nav a {\n color: var(--muted, #8b949e); text-decoration: none; font-size: 12px;\n font-weight: 500; padding: 5px 10px; border-radius: 6px;\n transition: color 0.15s, background 0.15s;\n }\n .meridian-header .mh-nav a:hover { color: var(--text, #e6edf3); background: var(--surface, #161b22); }\n .meridian-header .mh-nav a.active { color: var(--accent, #58a6ff); background: var(--surface, #161b22); }\n .meridian-header .mh-right {\n margin-left: auto; display: flex; align-items: center; gap: 10px;\n }\n .meridian-header .mh-profile {\n display: none; align-items: center; gap: 6px;\n font-size: 11px; font-weight: 500; color: var(--text, #e6edf3);\n padding: 3px 10px; border-radius: 20px;\n background: var(--surface, #161b22); border: 1px solid var(--border, #30363d);\n text-decoration: none; transition: border-color 0.15s;\n }\n .meridian-header .mh-profile:hover { border-color: var(--accent, #58a6ff); }\n .meridian-header .mh-profile.visible { display: inline-flex; }\n .meridian-header .mh-profile .mh-profile-type {\n color: var(--muted, #8b949e); font-size: 10px;\n }\n .meridian-header .mh-status {\n display: inline-flex; align-items: center; gap: 6px;\n font-size: 11px; color: var(--muted, #8b949e); white-space: nowrap;\n }\n .meridian-header .mh-dot {\n width: 8px; height: 8px; border-radius: 50%;\n background: var(--muted, #8b949e); flex-shrink: 0;\n }\n .meridian-header .mh-dot.healthy { background: var(--green, #3fb950); box-shadow: 0 0 6px rgba(63,185,80,0.5); }\n .meridian-header .mh-dot.degraded { background: var(--yellow, #d29922); }\n .meridian-header .mh-dot.unhealthy { background: var(--red, #f85149); }\n @media (max-width: 720px) {\n .meridian-header { gap: 10px; padding: 10px 16px; flex-wrap: wrap; }\n .meridian-header .mh-name { display: none; }\n .meridian-header .mh-status .mh-status-text { display: none; }\n }\n";
31
- export declare const profileBarHtml = "\n<header class=\"meridian-header\" id=\"meridianHeader\">\n <a class=\"mh-brand\" href=\"/\">\n <svg class=\"mh-logo\" width=\"24\" height=\"24\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <defs>\n <linearGradient id=\"mhGrad\" x1=\"32\" y1=\"4\" x2=\"32\" y2=\"60\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#58a6ff\"/>\n <stop offset=\"1\" stop-color=\"#bc8cff\"/>\n </linearGradient>\n </defs>\n <circle cx=\"32\" cy=\"32\" r=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"3.5\"/>\n <ellipse cx=\"32\" cy=\"32\" rx=\"10.5\" ry=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"2.5\" opacity=\"0.8\"/>\n <path d=\"M7 32h50\" stroke=\"url(#mhGrad)\" stroke-width=\"2\" opacity=\"0.4\"/>\n <circle cx=\"32\" cy=\"7\" r=\"4.5\" fill=\"#58a6ff\"/>\n <circle cx=\"32\" cy=\"57\" r=\"4.5\" fill=\"#bc8cff\"/>\n</svg>\n <span class=\"mh-name\">Meridian</span>\n </a>\n <nav class=\"mh-nav\">\n <a href=\"/\" id=\"nav-home\">Home</a>\n <a href=\"/telemetry\" id=\"nav-telemetry\">Telemetry</a>\n <a href=\"/profiles\" id=\"nav-profiles\">Profiles</a>\n <a href=\"/settings\" id=\"nav-settings\">Settings</a>\n <a href=\"/plugins\" id=\"nav-plugins\">Plugins</a>\n </nav>\n <div class=\"mh-right\">\n <a class=\"mh-profile\" id=\"mhProfile\" href=\"/\" title=\"Active profile \u2014 switch from the home page\"></a>\n <span class=\"mh-status\" id=\"mhStatus\"><span class=\"mh-dot\" id=\"mhDot\"></span><span class=\"mh-status-text\" id=\"mhStatusText\"></span></span>\n </div>\n</header>\n";
32
- export declare const profileBarJs = "\n(function() {\n var profileChip = document.getElementById('mhProfile');\n var statusDot = document.getElementById('mhDot');\n var statusText = document.getElementById('mhStatusText');\n\n // Highlight active nav link\n var path = location.pathname;\n var navLinks = document.querySelectorAll('.mh-nav a');\n navLinks.forEach(function(a) {\n if (a.getAttribute('href') === path || (path === '/telemetry' && a.id === 'nav-telemetry') || (path === '/' && a.id === 'nav-home')) {\n a.classList.add('active');\n }\n });\n\n function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }\n\n function loadHeader() {\n fetch('/health').then(function(r) { return r.json(); }).then(function(h) {\n var st = h.status === 'healthy' ? 'healthy' : h.status === 'degraded' ? 'degraded' : 'unhealthy';\n statusDot.className = 'mh-dot ' + st;\n statusText.textContent = st === 'healthy' ? 'Operational' : st === 'degraded' ? 'Degraded' : 'Offline';\n }).catch(function() {\n statusDot.className = 'mh-dot unhealthy';\n statusText.textContent = 'Offline';\n });\n\n fetch('/profiles/list').then(function(r) { return r.json(); }).then(function(data) {\n var current = (data.profiles || []).find(function(p) { return p.isActive; });\n if (!current) { profileChip.classList.remove('visible'); return; }\n profileChip.innerHTML = esc(current.id) + ' <span class=\"mh-profile-type\">' + esc(current.type || '') + '</span>';\n profileChip.classList.add('visible');\n }).catch(function() {});\n }\n\n loadHeader();\n setInterval(loadHeader, 10000);\n // Pages call this after mutating state (e.g. switching the active profile)\n // so the header chip updates immediately instead of on the next poll.\n window.meridianHeaderRefresh = loadHeader;\n})();\n";
30
+ export declare const profileBarCss = "\n .meridian-header {\n position: sticky; top: 0; z-index: 100;\n display: flex; align-items: center; gap: 20px;\n padding: 10px 24px;\n background: rgba(13, 17, 23, 0.92);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--border, #30363d);\n }\n .meridian-header .mh-brand {\n display: flex; align-items: center; gap: 10px;\n text-decoration: none; color: var(--text, #e6edf3);\n }\n .meridian-header .mh-logo { display: block; }\n .meridian-header .mh-name {\n font-size: 15px; font-weight: 700; letter-spacing: 2px;\n text-transform: uppercase;\n }\n .meridian-header .mh-nav { display: flex; align-items: center; gap: 2px; }\n .meridian-header .mh-nav a {\n color: var(--muted, #8b949e); text-decoration: none; font-size: 12px;\n font-weight: 500; padding: 5px 10px; border-radius: 6px;\n transition: color 0.15s, background 0.15s;\n }\n .meridian-header .mh-nav a:hover { color: var(--text, #e6edf3); background: var(--surface, #161b22); }\n .meridian-header .mh-nav a.active { color: var(--accent, #58a6ff); background: var(--surface, #161b22); }\n .meridian-header .mh-right {\n margin-left: auto; display: flex; align-items: center; gap: 10px;\n }\n .meridian-header .mh-profile {\n display: none; align-items: center; gap: 6px;\n font-size: 11px; font-weight: 500; color: var(--text, #e6edf3);\n padding: 3px 10px; border-radius: 20px;\n background: var(--surface, #161b22); border: 1px solid var(--border, #30363d);\n text-decoration: none; transition: border-color 0.15s;\n }\n .meridian-header .mh-profile:hover { border-color: var(--accent, #58a6ff); }\n .meridian-header .mh-profile.visible { display: inline-flex; }\n .meridian-header .mh-profile .mh-profile-type {\n color: var(--muted, #8b949e); font-size: 10px;\n }\n /* Build chip \u2014 two mutually exclusive states, and the colour is not a\n style choice: \"update available\" is a link to the releases page, so it\n is blue (interactive); \"local/dev build\" is a meta annotation with no\n href, so it is violet. Swapping them would break the DESIGN.md rule. */\n .meridian-header .mh-build {\n display: none; align-items: center; gap: 6px;\n font-size: 11px; font-weight: 500; white-space: nowrap;\n padding: 3px 10px; border-radius: 20px; text-decoration: none;\n transition: background 0.15s;\n }\n .meridian-header .mh-build.visible { display: inline-flex; }\n .meridian-header .mh-build.update {\n color: var(--accent, #58a6ff);\n background: rgba(88,166,255,0.12);\n border: 1px solid rgba(88,166,255,0.35);\n }\n .meridian-header .mh-build.update:hover { background: rgba(88,166,255,0.18); }\n .meridian-header .mh-build.provenance {\n color: var(--accent2, #bc8cff);\n background: rgba(188,140,255,0.12);\n border: 1px solid rgba(188,140,255,0.35);\n cursor: default;\n }\n .meridian-header .mh-status {\n display: inline-flex; align-items: center; gap: 6px;\n font-size: 11px; color: var(--muted, #8b949e); white-space: nowrap;\n }\n .meridian-header .mh-dot {\n width: 8px; height: 8px; border-radius: 50%;\n background: var(--muted, #8b949e); flex-shrink: 0;\n }\n .meridian-header .mh-dot.healthy { background: var(--green, #3fb950); box-shadow: 0 0 6px rgba(63,185,80,0.5); }\n .meridian-header .mh-dot.degraded { background: var(--yellow, #d29922); }\n .meridian-header .mh-dot.unhealthy { background: var(--red, #f85149); }\n @media (max-width: 720px) {\n .meridian-header { gap: 10px; padding: 10px 16px; flex-wrap: wrap; }\n .meridian-header .mh-name { display: none; }\n .meridian-header .mh-status .mh-status-text { display: none; }\n }\n";
31
+ export declare const profileBarHtml = "\n<header class=\"meridian-header\" id=\"meridianHeader\">\n <a class=\"mh-brand\" href=\"/\">\n <svg class=\"mh-logo\" width=\"24\" height=\"24\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <defs>\n <linearGradient id=\"mhGrad\" x1=\"32\" y1=\"4\" x2=\"32\" y2=\"60\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#58a6ff\"/>\n <stop offset=\"1\" stop-color=\"#bc8cff\"/>\n </linearGradient>\n </defs>\n <circle cx=\"32\" cy=\"32\" r=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"3.5\"/>\n <ellipse cx=\"32\" cy=\"32\" rx=\"10.5\" ry=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"2.5\" opacity=\"0.8\"/>\n <path d=\"M7 32h50\" stroke=\"url(#mhGrad)\" stroke-width=\"2\" opacity=\"0.4\"/>\n <circle cx=\"32\" cy=\"7\" r=\"4.5\" fill=\"#58a6ff\"/>\n <circle cx=\"32\" cy=\"57\" r=\"4.5\" fill=\"#bc8cff\"/>\n</svg>\n <span class=\"mh-name\">Meridian</span>\n </a>\n <nav class=\"mh-nav\">\n <a href=\"/\" id=\"nav-home\">Home</a>\n <a href=\"/telemetry\" id=\"nav-telemetry\">Telemetry</a>\n <a href=\"/profiles\" id=\"nav-profiles\">Profiles</a>\n <a href=\"/settings\" id=\"nav-settings\">Settings</a>\n <a href=\"/plugins\" id=\"nav-plugins\">Plugins</a>\n </nav>\n <div class=\"mh-right\">\n <a class=\"mh-build\" id=\"mhBuild\" target=\"_blank\" rel=\"noopener\"></a>\n <a class=\"mh-profile\" id=\"mhProfile\" href=\"/\" title=\"Active profile \u2014 switch from the home page\"></a>\n <span class=\"mh-status\" id=\"mhStatus\"><span class=\"mh-dot\" id=\"mhDot\"></span><span class=\"mh-status-text\" id=\"mhStatusText\"></span></span>\n </div>\n</header>\n";
32
+ export declare const profileBarJs = "\n(function() {\n var profileChip = document.getElementById('mhProfile');\n var buildChip = document.getElementById('mhBuild');\n var statusDot = document.getElementById('mhDot');\n var statusText = document.getElementById('mhStatusText');\n\n // Highlight active nav link\n var path = location.pathname;\n var navLinks = document.querySelectorAll('.mh-nav a');\n navLinks.forEach(function(a) {\n if (a.getAttribute('href') === path || (path === '/telemetry' && a.id === 'nav-telemetry') || (path === '/' && a.id === 'nav-home')) {\n a.classList.add('active');\n }\n });\n\n function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }\n\n // Build provenance chip. Hidden entirely for a current npm install, which\n // is the case that needs no comment.\n function renderBuild(build) {\n if (!buildChip) return;\n if (!build) { buildChip.className = 'mh-build'; return; }\n if (build.source !== 'npm') {\n buildChip.textContent = (build.source === 'dev' ? 'dev build' : 'local build') + (build.dirty ? ' *' : '');\n buildChip.removeAttribute('href');\n buildChip.title = 'Not an npm release \u2014 the reported version ' + build.version +\n ' is the tree\\'s last release, not proof of what is running' +\n (build.branch ? '\\nbranch: ' + build.branch : '') +\n (build.sha ? '\\ncommit: ' + build.sha.slice(0, 8) : '') +\n (build.dirty ? '\\nuncommitted changes present' : '');\n buildChip.className = 'mh-build provenance visible';\n return;\n }\n if (build.updateAvailable) {\n buildChip.textContent = build.latest + ' available';\n buildChip.href = 'https://github.com/rynfar/meridian/releases';\n buildChip.title = 'Running ' + build.version + ' \u2014 update with:\\nnpm install -g @rynfar/meridian@latest';\n buildChip.className = 'mh-build update visible';\n return;\n }\n buildChip.className = 'mh-build';\n }\n\n function loadHeader() {\n fetch('/health').then(function(r) { return r.json(); }).then(function(h) {\n var st = h.status === 'healthy' ? 'healthy' : h.status === 'degraded' ? 'degraded' : 'unhealthy';\n statusDot.className = 'mh-dot ' + st;\n statusText.textContent = st === 'healthy' ? 'Operational' : st === 'degraded' ? 'Degraded' : 'Offline';\n renderBuild(h.build);\n }).catch(function() {\n statusDot.className = 'mh-dot unhealthy';\n statusText.textContent = 'Offline';\n });\n\n fetch('/profiles/list').then(function(r) { return r.json(); }).then(function(data) {\n var current = (data.profiles || []).find(function(p) { return p.isActive; });\n if (!current) { profileChip.classList.remove('visible'); return; }\n profileChip.innerHTML = esc(current.id) + ' <span class=\"mh-profile-type\">' + esc(current.type || '') + '</span>';\n profileChip.classList.add('visible');\n }).catch(function() {});\n }\n\n loadHeader();\n setInterval(loadHeader, 10000);\n // Pages call this after mutating state (e.g. switching the active profile)\n // so the header chip updates immediately instead of on the next poll.\n window.meridianHeaderRefresh = loadHeader;\n})();\n";
33
33
  //# sourceMappingURL=profileBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"profileBar.d.ts","sourceRoot":"","sources":["../../src/telemetry/profileBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,6gDAwCpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,syBAYrB,CAAA;AAEP,eAAO,MAAM,aAAa,glFAyDzB,CAAA;AAED,eAAO,MAAM,cAAc,ukDAkB1B,CAAA;AAED,eAAO,MAAM,YAAY,k0DAyCxB,CAAA"}
1
+ {"version":3,"file":"profileBar.d.ts","sourceRoot":"","sources":["../../src/telemetry/profileBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,6gDAwCpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,syBAYrB,CAAA;AAEP,eAAO,MAAM,aAAa,ioHAgFzB,CAAA;AAED,eAAO,MAAM,cAAc,ypDAmB1B,CAAA;AAED,eAAO,MAAM,YAAY,4pGAqExB,CAAA"}