/** * Session × binding-store × outer-session bridge layer. * * v2.18.0: extracted from `session-manager.ts` to keep that file under * the Karpathy 800 LOC cap while the binding-store D2 sub-slice work * adds ~65 LOC over the next slice. The 4 blocks that moved here are * the natural "bridge" concern: the lower-level session-manager * primitives (read / write the project-level session binding, get / * rotate, etc.) are wired up here into the user-facing `ensureSession` * and the outer-session-aware `ensureSessionWithRotation`. * * `session-manager.ts` re-exports the two functions and the two result * types so the 5 external callers (`request-artifact-service.ts`, * `upgrade-commands.ts`, `init-command.ts`, plus 2 test files) do NOT * need to change their import path. The re-export shim is the only * added code in `session-manager.ts`. * * Body of every function moved verbatim per Karpathy #3 (Surgical * Changes). No behavior change. The bridge adds nothing of its own. */ /** * Test-only seam: reset the module-scoped `lastResolvedOuter` so * individual tests start with a clean slate. NOT exported as part * of the public API; marked TODO(g2) for the v2.14.0 grace window. */ export declare function _resetLastResolvedOuterForTest(): void; export type EnsureSessionOptions = { /** * When `true`, suppress the outer-session-mismatch auto-rotation. * The caller wants today's "stamp the field, do not rotate" behaviour * even when the outer session id has changed. Used by * `peaks workspace init --no-rotate-on-outer-mismatch`. */ skipRotateOnOuterMismatch?: boolean; }; /** * Result of `ensureSessionWithRotation`. When the bound session was * rotated because the outer session id had changed, `previousSessionId` * is the id of the unbound session and `rotationReason` is the structured * reason code the CLI surfaces in its JSON envelope. */ export type EnsureSessionResult = { sessionId: string; previousSessionId: string | null; rotationReason: 'outer-session-mismatch' | null; }; export declare function ensureSession(projectRoot: string): Promise; /** * Outer-session-aware wrapper around `ensureSession`. * * session id (sourced from `PEAKS_OUTER_SESSION_ID` with * `CLAUDE_CODE_SESSION_ID` as the Claude-Code fallback) differs from * the outer session id recorded on the *bound* peaks session's * `.peaks/_runtime//session.json`, the project-level session * binding is rotated before `ensureSession` is called. The old * session dir is preserved on disk (data is never wiped) — only the * binding changes — and the rotation is surfaced in the return value * so the CLI can include it in the JSON envelope. * * Rotation is suppressed in four cases (all false-positive guards): * * 1. The current outer session id is undefined (no env var set) — * there is no signal to compare against, defaulting to "do not * rotate" avoids orphaning the session. * 2. The bound session has no recorded `outerSessionId` (legacy * session predating the outer-session contract) — there is no * signal on the other side either. * 3. The bound session's recorded outer session id matches the * current one (reconnect within the same Claude session) — this * is the common case, not a swap. * `lastResolvedOuter.value` was already set to `currentOuterSessionId` * in this process and `boundOuter` equals that same value. Long- * running presence-lease writers that re-resolve within a single * process must not rotate on every CLI heartbeat. The module-scoped * state is per-process; each fresh CLI invocation starts with * `lastResolvedOuter === null`, so this guard cannot leak across * processes. The 4th guard ONLY fires when `lastResolvedOuter.value` * is a defined string (an undefined last-resolved value still * falls through to the legacy comparison path). * * When `options.skipRotateOnOuterMismatch === true`, the rotation * check is short-circuited and the binding is preserved (opt-out for * `peaks workspace init --no-rotate-on-outer-mismatch`). The wrapper * still delegates to `ensureSession` so the caller gets the existing * binding on a reconnect and a fresh id on a first run. * * Existing public surface is preserved: `ensureSession` is unchanged. * This wrapper is the new entry point the CLI uses. */ export declare function ensureSessionWithRotation(projectRoot: string, options?: EnsureSessionOptions): Promise;