@wrongstack/core 0.236.0 → 0.250.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.
- package/dist/{agent-bridge-Cimv7bK7.d.ts → agent-bridge-4gc0vfW2.d.ts} +1 -1
- package/dist/{agent-subagent-runner-C658wj_c.d.ts → agent-subagent-runner-Dz-9kiE6.d.ts} +3 -3
- package/dist/{config-Koq6f3fs.d.ts → config-eSsrto5d.d.ts} +6 -0
- package/dist/coordination/index.d.ts +10 -10
- package/dist/coordination/index.js +5 -3
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +12 -12
- package/dist/defaults/index.js +8 -10
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +7 -7
- package/dist/execution/index.js +5 -3
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +3 -3
- package/dist/{goal-preamble-CnbzyVvl.d.ts → goal-preamble-BjJpnLW4.d.ts} +4 -4
- package/dist/{index-BlMqh5GO.d.ts → index-Dy8OwfBD.d.ts} +2 -2
- package/dist/{index-C2eSNPsB.d.ts → index-IehiNryU.d.ts} +2 -2
- package/dist/index.d.ts +22 -22
- package/dist/index.js +18 -16
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +3 -3
- package/dist/kernel/index.d.ts +3 -3
- package/dist/{mcp-servers-DFbirBv6.d.ts → mcp-servers-DfXxCASH.d.ts} +1 -1
- package/dist/models/index.d.ts +2 -2
- package/dist/{models-registry-CnJRjTXc.d.ts → models-registry-DpanBg8D.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-60weDZoA.d.ts → multi-agent-coordinator-CnbEqpv0.d.ts} +1 -1
- package/dist/{null-fleet-bus-1068dEnr.d.ts → null-fleet-bus-Do1OLYpj.d.ts} +4 -4
- package/dist/{package-outdated-watcher-pzJ5w7y8.d.ts → package-outdated-watcher-CA5GGB4C.d.ts} +1 -1
- package/dist/{parallel-eternal-engine-DtG1fjc9.d.ts → parallel-eternal-engine-UZg1xOzE.d.ts} +4 -4
- package/dist/{path-resolver-CA1ULU0J.d.ts → path-resolver-BaP06Owy.d.ts} +1 -1
- package/dist/{pipeline-DsmlwTXu.d.ts → pipeline-D1n-gQI-.d.ts} +1 -1
- package/dist/{plan-templates-DPABrDvy.d.ts → plan-templates-BUVRY0pU.d.ts} +1 -1
- package/dist/sdd/index.d.ts +4 -4
- package/dist/sdd/index.js +6 -8
- package/dist/sdd/index.js.map +1 -1
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js.map +1 -1
- package/dist/types/index.d.ts +10 -10
- package/dist/types/index.js +5 -3
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +11 -2
- package/dist/utils/index.js +6 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/utils/atomic-write.ts","../../src/utils/message-invariants.ts","../../src/storage/session-store.ts","../../src/storage/queue-store.ts","../../src/storage/attachment-store.ts","../../src/types/memory.ts","../../src/storage/memory-backend.ts","../../src/storage/memory-store.ts","../../src/storage/memory-graph-backend.ts","../../src/storage/memory-consolidator.ts","../../src/types/errors.ts","../../src/storage/config-store.ts","../../src/utils/deep-merge.ts","../../src/security/secret-vault.ts","../../src/types/context-window.ts","../../src/utils/safe-json.ts","../../src/types/default-config.ts","../../src/storage/config-loader.ts","../../src/storage/config-migration.ts","../../src/storage/recovery-lock.ts","../../src/utils/regex-guard.ts","../../src/storage/session-reader.ts","../../src/utils/session-scoped-path.ts","../../src/storage/annotations-store.ts","../../src/replay/hash.ts","../../src/storage/replay-log-store.ts","../../src/storage/session-recovery.ts","../../src/storage/tool-audit-log.ts","../../src/storage/session-analyzer.ts","../../src/session-registry.ts","../../src/agent-status-tracker.ts","../../src/storage/session-rewinder.ts","../../src/storage/todos-checkpoint.ts","../../src/storage/plan-store.ts","../../src/storage/plan-templates.ts","../../src/storage/task-store.ts","../../src/storage/director-state.ts","../../src/utils/term.ts","../../src/utils/color.ts","../../src/utils/wstack-paths.ts","../../src/storage/goal-store.ts","../../src/storage/prompt-store.ts","../../src/storage/cloud-sync.ts","../../src/storage/session-event-bridge.ts"],"names":["path","fs","stat","resolve","randomBytes","path2","path3","fsp2","fsp3","path4","path5","fs2","writeFile","mkdir","fs3","deepMerge","fs5","path7","fsp5","path8","randomUUID","fs6","entry","fs7","path9","fs8","path10","createHash","stableStringify","fs9","sortKeys","path11","projectSlug","fs10","path12","fsp6","fsp7","fsp8","fsp9","fsp10","lock","hostname","open","os2","fsp11","fs11","path14","path15","fs12","relative"],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { randomBytes } from 'node:crypto';\nimport type { Dirent } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\nimport type {\n ResumedSession,\n SessionData,\n SessionEvent,\n SessionMetadata,\n SessionStore,\n SessionSummary,\n SessionWriter,\n} from '../types/session.js';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\n// ─── Session ID naming ───────────────────────────────────────────────────────\n\n/** Sanitize a model name for use in filenames: alphanumeric + dash + underscore. */\nfunction sanitizeModel(model: string): string {\n return model\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n\n/**\n * Generate a session ID in the format:\n * `YYYY-MM-DD/HH-MM-SSZ[_model]_xxxx.jsonl`\n *\n * Examples:\n * `2026-06-06/12-30-45Z_claude-sonnet_a1b2.jsonl`\n * `2026-06-06/14-22-10Z_a1b2.jsonl` (no model)\n *\n * The date prefix becomes a subdirectory so sessions group naturally by day.\n * The model name (when available) lets you see at a glance which provider was\n * used, without opening the file. The 4-byte random suffix prevents collisions\n * within the same second.\n */\nfunction generateSessionId(startedAt: string, model?: string): string {\n const date = startedAt.slice(0, 10); // \"2026-06-06\"\n const time = startedAt.slice(11, 19).replace(/:/g, '-'); // \"12-30-45\"\n const suffix = randomBytes(2).toString('hex'); // \"a1b2\"\n const modelPart = model ? `_${sanitizeModel(model)}` : '';\n return `${date}/${time}Z${modelPart}_${suffix}`;\n}\n\nexport interface SessionStoreOptions {\n dir: string;\n /** Optional EventBus for emitting session diagnostics. */\n events?: EventBus | undefined;\n /**\n * Optional secret scrubber. When set, `user_input` and `llm_response` event\n * content is scrubbed before being persisted to the JSONL log and the\n * summary sidecar — so a secret a user pastes or the model echoes does not\n * sit in cleartext on disk (and does not ride along in history cloud-sync).\n * Tool output is already scrubbed upstream by the executor; this closes the\n * conversation-turn gap (finding F-06).\n */\n secretScrubber?: SecretScrubber | undefined;\n}\n\nexport class DefaultSessionStore implements SessionStore {\n private readonly dir: string;\n private readonly events?: EventBus | undefined;\n private readonly secretScrubber?: SecretScrubber | undefined;\n\n constructor(opts: SessionStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.secretScrubber = opts.secretScrubber;\n }\n\n /** Absolute path to the session index file. */\n private get indexFile(): string {\n return path.join(this.dir, '_index.jsonl');\n }\n\n /** Join session ID to its absolute path within the store directory. */\n private sessionPath(id: string, ext: '.jsonl' | '.summary.json'): string {\n return path.join(this.dir, `${id}${ext}`);\n }\n\n /**\n * Ensure the directory implied by the session ID exists. When the ID\n * contains a date prefix like `2026-06-06/...`, this creates the date\n * subdirectory so sessions group naturally by day.\n */\n private async ensureShardDir(id: string): Promise<string> {\n const dirPath = path.dirname(path.join(this.dir, id));\n await ensureDir(dirPath);\n return dirPath;\n }\n\n async create(meta: Omit<SessionMetadata, 'startedAt'>): Promise<SessionWriter> {\n const startedAt = new Date().toISOString();\n const id =\n meta.id && meta.id.length > 0\n ? meta.id\n : generateSessionId(startedAt, meta.model ?? meta.provider);\n const shardDir = await this.ensureShardDir(id);\n const file = path.join(shardDir, `${path.basename(id)}.jsonl`);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n throw new Error(\n `Failed to open session file: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n try {\n return new FileSessionWriter(id, handle, startedAt, meta, this.events, {\n dir: shardDir,\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n });\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n throw err;\n }\n }\n\n async resume(id: string): Promise<ResumedSession> {\n const file = this.sessionPath(id, '.jsonl');\n const data = await this.load(id);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n throw new Error(\n `Failed to open session \"${id}\" for append: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n try {\n const writer = new FileSessionWriter(\n id,\n handle,\n new Date().toISOString(),\n {\n id,\n model: data.metadata.model,\n provider: data.metadata.provider,\n },\n this.events,\n {\n resumed: true,\n // Shard directory (sessions/<date>/) — must match create() so the\n // .summary.json sidecar lands next to the JSONL instead of the\n // sessions root (where summaryFor() would never find it).\n dir: path.dirname(file),\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n },\n );\n return { writer, data };\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n throw err;\n }\n }\n\n async load(id: string): Promise<SessionData> {\n const file = this.sessionPath(id, '.jsonl');\n const raw = await fsp.readFile(file, 'utf8');\n const lines = raw.split('\\n').filter((l) => l.trim());\n const events: SessionEvent[] = [];\n for (const line of lines) {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\n ) {\n events.push(parsed as SessionEvent);\n }\n } catch {\n // skip malformed JSON\n }\n }\n const meta = this.metaFromEvents(id, events);\n const { messages, usage } = this.replay(events, id);\n // Extract tool_call_end events for TUI tool entry rendering on resume.\n const toolCallEnds = extractToolCallEnds(events);\n return { metadata: meta, events, messages, usage, toolCallEnds };\n }\n\n async list(limit = 20): Promise<SessionSummary[]> {\n try {\n await ensureDir(this.dir);\n // Try the index first; fall back to directory scan if the index is\n // missing, empty, or unreadable.\n const indexed = await this.readIndex();\n if (indexed.length > 0) {\n indexed.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return indexed.slice(0, limit);\n }\n // Index unavailable — fall back to full directory scan + summary parse.\n const ids = await this.collectSessionIds(this.dir);\n const sessions = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null)));\n const out = sessions.filter((s): s is SessionSummary => s !== null);\n out.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return out.slice(0, limit);\n } catch {\n return [];\n }\n }\n\n // ── Session index (_index.jsonl) ─────────────────────────────────────────\n //\n // One JSON line per closed session, appended atomically on close().\n // When a session is deleted, a tombstone {action:\"delete\",id:\"...\"} is\n // appended. On read, tombstones filter out matching session entries.\n // This keeps listing O(lines-in-index) instead of O(files-on-disk).\n //\n // The index auto-compacts every N appends to prevent unbounded growth\n // from tombstones and duplicate entries (resume cycles).\n\n private indexAppendCount = 0;\n private static readonly COMPACT_EVERY = 30;\n\n /** Append a session summary to the index. */\n private async appendToIndex(summary: SessionSummary): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify(summary) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n // Auto-compact the index periodically to remove tombstones and duplicates.\n if (this.indexAppendCount >= DefaultSessionStore.COMPACT_EVERY) {\n await this.compactIndex();\n this.indexAppendCount = 0;\n }\n } catch {\n // best-effort\n }\n }\n\n /** Append a tombstone entry for a deleted session. */\n private async writeTombstone(id: string): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify({ action: 'delete', id }) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n } catch {\n // best-effort\n }\n }\n\n /**\n * Compact the index: read all entries, drop tombstones, deduplicate\n * (keep latest per session), and rewrite. Atomic via temp+rename.\n */\n private async compactIndex(): Promise<void> {\n const entries = await this.readIndex();\n if (entries.length === 0) return;\n const tmp = `${this.indexFile}.compact.tmp`;\n const lines = entries.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n }\n\n /**\n * Read the index file and return deduplicated session summaries.\n * Entries with a matching tombstone are filtered out.\n * Returns empty array when the index doesn't exist or is corrupt.\n */\n private async readIndex(): Promise<SessionSummary[]> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.indexFile, 'utf8');\n } catch {\n return [];\n }\n const deleted = new Set<string>();\n const seen = new Map<string, SessionSummary>();\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as { action?: string | undefined; id?: string | undefined } & SessionSummary;\n if (entry.action === 'delete' && entry.id) {\n deleted.add(entry.id);\n seen.delete(entry.id);\n continue;\n }\n if (entry.id && !deleted.has(entry.id)) {\n // Keep the latest entry for each session (multiple appends on resume).\n seen.set(entry.id, entry as SessionSummary);\n }\n } catch {\n // skip corrupt lines\n }\n }\n return Array.from(seen.values());\n }\n\n /**\n * Rebuild the index from disk by scanning all sessions and writing a\n * fresh _index.jsonl. Useful after manual cleanup or index corruption.\n */\n async rebuildIndex(): Promise<number> {\n const ids = await this.collectSessionIds(this.dir);\n const summaries = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null)));\n const valid = summaries.filter((s): s is SessionSummary => s !== null);\n // Atomic rewrite: write to temp, then rename.\n const tmp = `${this.indexFile}.tmp`;\n const lines = valid.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n return valid.length;\n }\n\n /** Recursively collect session IDs from date-shard subdirectories.\n * IDs include the date-prefix path (e.g. \"2026-06-06/17-46-57Z_…\").\n * Skips `.jsonl`/`.summary.json` root files, dot-files, and\n * sub-directories that belong to fleet/subagent sessions. */\n private async collectSessionIds(\n dir: string,\n prefix = '',\n depth = 0,\n ): Promise<string[]> {\n const ids: string[] = [];\n let entries: Dirent[];\n try {\n entries = await fsp.readdir(dir, { withFileTypes: true });\n } catch {\n return ids;\n }\n for (const entry of entries) {\n // Skip dot-files and known non-session directories\n if (entry.name.startsWith('.') && entry.name !== '.wrongstack') continue;\n if (entry.name === 'shared' || entry.name === 'subagents' || entry.name === 'attachments')\n continue;\n if (entry.isDirectory()) {\n // Date-shard directories become the prefix for their contents\n const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;\n ids.push(...(await this.collectSessionIds(path.join(dir, entry.name), childPrefix, depth + 1)));\n } else if (entry.isFile() && entry.name.endsWith('.jsonl')) {\n // Skip the session index itself — it's bookkeeping, not a session log.\n // (Only skip THIS file at root, not every root-level jsonl: flat/legacy\n // sessions and the test fixtures live directly under the sessions dir.)\n if (entry.name === '_index.jsonl') continue;\n const base = entry.name.replace(/\\.jsonl$/, '');\n // Subagent session logs live under subagents/ which we skip above.\n ids.push(prefix ? `${prefix}/${base}` : base);\n }\n }\n return ids;\n }\n\n private async summaryFor(id: string): Promise<SessionSummary> {\n const manifest = this.sessionPath(id, '.summary.json');\n try {\n const raw = await fsp.readFile(manifest, 'utf8');\n return JSON.parse(raw) as SessionSummary;\n } catch {\n const full = this.sessionPath(id, '.jsonl');\n const stat = await fsp.stat(full);\n const summary = await this.summarize(id, stat.mtime.toISOString());\n await atomicWrite(manifest, JSON.stringify(summary), { mode: 0o600 }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.manifest_write_failed',\n sessionId: id,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n return summary;\n }\n }\n\n /**\n * Delete a session and all associated files: JSONL, summary, plan/todos\n * sidecars, and the session directory (fleet.json, shared/, subagents/).\n *\n * Individual file deletions are best-effort (logged as structured warnings),\n * but a tombstone is always written so readIndex() filters this session out.\n * If the session directory itself can't be removed, the error is surfaced\n * to the caller so prune() can report it.\n */\n private async deleteSession(id: string): Promise<void> {\n const jsonlPath = this.sessionPath(id, '.jsonl');\n const summaryPath = this.sessionPath(id, '.summary.json');\n const shardDir = path.dirname(path.join(this.dir, id));\n const base = path.basename(id);\n const sessDir = path.join(shardDir, base);\n\n const deletions: Array<Promise<void>> = [\n fsp.unlink(jsonlPath),\n fsp.unlink(summaryPath),\n fsp.unlink(path.join(shardDir, `${base}.plan.json`)),\n fsp.unlink(path.join(shardDir, `${base}.todos.json`)),\n ];\n\n const results = await Promise.allSettled(deletions);\n for (const r of results) {\n if (r.status === 'rejected') {\n const msg = r.reason instanceof Error ? r.reason.message : String(r.reason);\n // ENOENT is expected (file may not exist — sidecars are optional).\n if ((r.reason as NodeJS.ErrnoException)?.code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.delete_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n }\n\n // Remove the session directory (may contain fleet.json, shared/, subagents/).\n await fsp.rm(sessDir, { recursive: true, force: true }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.rmdir_failed',\n sessionId: id,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n\n // Write an index tombstone so readIndex() filters this session out.\n await this.writeTombstone(id);\n }\n\n async delete(id: string): Promise<void> {\n await this.deleteSession(id);\n }\n\n async prune(maxAgeDays = 30): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 86_400_000;\n let deleted = 0;\n\n // Read the active session lock to avoid pruning the current session.\n let activeSessionId: string | null = null;\n try {\n const raw = await fsp.readFile(path.join(this.dir, 'active.json'), 'utf8');\n const active = JSON.parse(raw) as { sessionId?: string | undefined };\n activeSessionId = active.sessionId ?? null;\n } catch {\n // no active.json — nothing to protect\n }\n\n const isPrunableJsonl = (name: string): boolean =>\n name.endsWith('.jsonl') &&\n name !== '_index.jsonl' &&\n name !== '_mailbox.jsonl' &&\n !name.endsWith('.replay.jsonl') &&\n !name.endsWith('.audit.jsonl');\n\n const pruneFile = async (dir: string, name: string, prefix: string): Promise<void> => {\n const jsonlPath = path.join(dir, name);\n try {\n const stat = await fsp.stat(jsonlPath);\n if (stat.mtimeMs >= cutoff) return;\n } catch {\n return;\n }\n const base = name.replace(/\\.jsonl$/, '');\n const id = prefix ? `${prefix}/${base}` : base;\n // Never prune the currently active session.\n if (activeSessionId && id === activeSessionId) return;\n await this.deleteSession(id);\n deleted++;\n };\n\n const entries = await fsp.readdir(this.dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (entry.isFile()) {\n // Flat legacy sessions at the sessions root — pre-shard layout.\n // A shard-only scan left these accumulating forever.\n if (isPrunableJsonl(entry.name)) await pruneFile(this.dir, entry.name, '');\n continue;\n }\n if (!entry.isDirectory()) continue;\n // entry.name is a date-shard like \"2026-06-06\"\n const dateDir = path.join(this.dir, entry.name);\n const files = await fsp.readdir(dateDir, { withFileTypes: true }).catch(() => []);\n for (const file of files) {\n if (!file.isFile() || !isPrunableJsonl(file.name)) continue;\n await pruneFile(dateDir, file.name, entry.name);\n }\n }\n if (deleted > 0) {\n // Compact the index to remove tombstones for deleted sessions.\n await this.compactIndex().catch(() => undefined);\n }\n // Clean up empty date-shard directories left behind after pruning.\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dateDir = path.join(this.dir, entry.name);\n try {\n const remaining = await fsp.readdir(dateDir);\n if (remaining.length === 0) {\n await fsp.rmdir(dateDir).catch(() => undefined);\n }\n } catch {\n // best-effort\n }\n }\n return deleted;\n }\n\n async clearHistory(id: string): Promise<void> {\n await this.ensureShardDir(id);\n const file = this.sessionPath(id, '.jsonl');\n const meta = this.sessionPath(id, '.summary.json');\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id,\n model: 'unknown',\n provider: 'unknown',\n })}\\n`;\n await fsp.writeFile(file, record, 'utf8');\n await fsp.unlink(meta).catch(() => undefined);\n }\n\n private async summarize(id: string, mtime: string): Promise<SessionSummary> {\n try {\n const data = await this.load(id);\n const firstUser = data.events.find((e) => e.type === 'user_input');\n const title =\n firstUser && firstUser.type === 'user_input'\n ? userInputTitle(firstUser.content)\n : '(empty session)';\n\n // Compute enriched stats from events.\n let iterationCount = 0;\n let toolCallCount = 0;\n let toolErrorCount = 0;\n let fileChangeCount = 0;\n const toolBreakdown: Record<string, number> = {};\n let outcome: SessionSummary['outcome'] ;\n const lastEvent = data.events[data.events.length - 1];\n\n for (const e of data.events) {\n if (e.type === 'in_flight_start') iterationCount++;\n else if (e.type === 'tool_call_start') {\n toolCallCount++;\n toolBreakdown[e.name] = (toolBreakdown[e.name] ?? 0) + 1;\n } else if (e.type === 'tool_result' && e.isError) toolErrorCount++;\n else if (e.type === 'file_snapshot') fileChangeCount += e.files.length;\n }\n\n // Determine outcome from the last event.\n if (lastEvent?.type === 'session_end') {\n outcome = 'completed';\n } else if (lastEvent?.type === 'in_flight_start') {\n outcome = 'aborted';\n } else if (data.events.some((e) => e.type === 'error')) {\n outcome = 'error';\n }\n\n return {\n id,\n title,\n startedAt: data.metadata.startedAt,\n endedAt: data.metadata.endedAt,\n model: data.metadata.model ?? 'unknown',\n provider: data.metadata.provider ?? 'unknown',\n tokenTotal: data.usage.input + data.usage.output,\n iterationCount: iterationCount > 0 ? iterationCount : undefined,\n toolCallCount: toolCallCount > 0 ? toolCallCount : undefined,\n toolErrorCount: toolErrorCount > 0 ? toolErrorCount : undefined,\n fileChangeCount: fileChangeCount > 0 ? fileChangeCount : undefined,\n toolBreakdown: Object.keys(toolBreakdown).length > 0 ? toolBreakdown : {},\n outcome,\n };\n } catch {\n return {\n id,\n title: '(damaged)',\n startedAt: mtime,\n model: 'unknown',\n provider: 'unknown',\n tokenTotal: 0,\n };\n }\n }\n\n private metaFromEvents(id: string, events: SessionEvent[]): SessionMetadata {\n const start = events.find((e) => e.type === 'session_start');\n // Use the LAST session_end: resume cycles append a new session_end on\n // every clean exit, and legacy /save commands wrote mid-stream markers.\n const end = events.findLast((e) => e.type === 'session_end');\n return {\n id,\n startedAt: start?.ts ?? new Date(0).toISOString(),\n endedAt: end?.ts,\n model: start?.model,\n provider: start?.provider,\n pendingToolUses: end?.pendingToolUses,\n };\n }\n\n private replay(\n events: SessionEvent[],\n sessionId = 'unknown',\n ): { messages: Message[]; usage: SessionData['usage'] } {\n const messages: Message[] = [];\n let usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n const openToolUses = new Set<string>();\n for (const e of events) {\n if (e.type === 'user_input') {\n openToolUses.clear();\n messages.push({ role: 'user', content: e.content, ts: e.ts });\n } else if (e.type === 'llm_response') {\n messages.push({ role: 'assistant', content: e.content, ts: e.ts });\n for (const b of e.content) {\n if (b.type === 'tool_use') openToolUses.add(b.id);\n }\n usage = {\n input: usage.input + (e.usage.input ?? 0),\n output: usage.output + (e.usage.output ?? 0),\n cacheRead: (usage.cacheRead ?? 0) + (e.usage.cacheRead ?? 0),\n cacheWrite: (usage.cacheWrite ?? 0) + (e.usage.cacheWrite ?? 0),\n };\n } else if (e.type === 'tool_result') {\n if (!openToolUses.has(e.id)) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `Orphan tool_result \"${e.id}\" has no matching tool_use`,\n });\n continue;\n }\n openToolUses.delete(e.id);\n // Provider protocol: tool_result blocks live in a USER message that\n // follows the assistant's tool_use turn — never inside the assistant\n // message itself (repairToolUseAdjacency would treat that as broken\n // adjacency and strip the tool_use blocks, silently dropping the\n // assistant turn on resume). Consecutive results from one turn are\n // grouped into a single user message.\n const resultBlock: ContentBlock = {\n type: 'tool_result',\n tool_use_id: e.id,\n content: typeof e.content === 'string' ? e.content : JSON.stringify(e.content),\n is_error: e.isError,\n };\n const last = messages[messages.length - 1];\n const lastIsToolResultUser =\n last?.role === 'user' &&\n Array.isArray(last.content) &&\n last.content.every((b) => (b as ContentBlock).type === 'tool_result');\n if (lastIsToolResultUser && Array.isArray(last.content)) {\n last.content.push(resultBlock);\n } else {\n messages.push({ role: 'user', content: [resultBlock], ts: e.ts });\n }\n }\n }\n if (openToolUses.size > 0) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `${openToolUses.size} tool_use blocks without matching results - replay repaired`,\n });\n }\n const repaired = repairToolUseAdjacency(messages);\n if (repaired.report.changed) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail:\n `Repaired replay adjacency: removed ${repaired.report.removedToolUses.length} tool_use, ` +\n `${repaired.report.removedToolResults.length} tool_result, ` +\n `${repaired.report.removedMessages} empty messages`,\n });\n }\n return { messages: repaired.messages, usage };\n }\n}\n\n/**\n * Extract tool execution records from `tool_call_end` events in the JSONL.\n * These are used by the TUI to render tool entries (name, duration, ok/error)\n * when a session is resumed. Events are returned in JSONL order (the order\n * they appear in the file, which is chronological insertion order).\n */\nfunction extractToolCallEnds(events: SessionEvent[]): SessionData['toolCallEnds'] {\n const result: SessionData['toolCallEnds'] = [];\n for (const e of events) {\n if (e.type === 'tool_call_end') {\n result.push({\n name: e.name,\n id: e.id,\n durationMs: e.durationMs,\n ok: e.ok ?? false,\n outputBytes: e.outputBytes,\n outputTokens: e.outputTokens,\n outputLines: e.outputLines,\n });\n }\n }\n return result;\n}\n\nclass FileSessionWriter implements SessionWriter {\n private closed = false;\n private closePromise: Promise<void> | null = null;\n private manifestFile: string;\n private summary: SessionSummary;\n private tokenIn = 0;\n private tokenOut = 0;\n private readonly filePath: string;\n get transcriptPath(): string | undefined {\n return this.filePath || undefined;\n }\n /**\n * Lazy session_start/session_resumed init, shared by all appenders.\n * A single promise (not a boolean) so a second append racing the first\n * can't push its event into the buffer BEFORE the first append's event —\n * every appender awaits the same init and resumes in FIFO call order.\n */\n private initPromise: Promise<void> | null = null;\n private ensureInit(): Promise<void> {\n if (!this.initPromise) this.initPromise = this.writeSessionStartLazy();\n return this.initPromise;\n }\n private readonly resumed: boolean;\n private appendFailCount = 0;\n private lastAppendWarnAt = 0;\n private readonly secretScrubber?: SecretScrubber | undefined;\n private readonly onCloseCb?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n\n // ── Write buffer — batches events to reduce per-event disk I/O ─────────\n //\n // Every append() pushes the scrubbed event into an in-memory buffer instead\n // of calling handle.appendFile() synchronously. The buffer flushes to disk\n // when it reaches FLUSH_SIZE events OR after FLUSH_INTERVAL_MS of inactivity.\n // This cuts the number of disk writes by ~95% without changing the on-disk\n // format — the JSONL is still one JSON object per line.\n private writeBuffer: SessionEvent[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly FLUSH_INTERVAL_MS = 500;\n private static readonly FLUSH_SIZE = 50;\n\n // ── Write serialization ─────────────────────────────────────────────────\n //\n // All disk writes are funneled through a FIFO promise chain. Without it,\n // a timer-driven flush racing an explicit flush()/close() issues two\n // concurrent appendFile() calls on the shared O_APPEND handle — the kernel\n // may complete them out of order (chronology breaks) or, for large\n // batches, interleave partial writes (torn JSONL lines). The chain keeps\n // exactly one write in flight; failures don't break the chain.\n private writeChain: Promise<void> = Promise.resolve();\n\n /** Enqueue a write on the FIFO chain. Resolves/rejects with that write. */\n private enqueueWrite(data: string): Promise<void> {\n const write = this.writeChain.then(() => this.handle.appendFile(data, 'utf8'));\n this.writeChain = write.then(\n () => undefined,\n () => undefined,\n );\n return write;\n }\n\n // ── Enriched summary tracking ──────────────────────────────────────────\n private iterationCount = 0;\n private toolCallCount = 0;\n private toolErrorCount = 0;\n private toolBreakdown: Record<string, number> = {};\n private fileChangeCount = 0;\n private compactionCount = 0;\n private outcome: SessionSummary['outcome'] = undefined;\n\n /**\n * Scrub secrets out of conversation-turn events before they are observed\n * for the summary, written to the JSONL log, or surfaced on resume. Only\n * `user_input` / `llm_response` carry free-form user/model text; other event\n * types either have no secret-bearing content or are already scrubbed\n * upstream (tool results). Returns the event unchanged when no scrubber is\n * configured.\n */\n private scrubEvent(event: SessionEvent): SessionEvent {\n const s = this.secretScrubber;\n if (!s) return event;\n if (event.type === 'user_input') {\n return {\n ...event,\n content:\n typeof event.content === 'string' ? s.scrub(event.content) : s.scrubObject(event.content),\n };\n }\n if (event.type === 'llm_response') {\n return { ...event, content: s.scrubObject(event.content) };\n }\n return event;\n }\n\n private pendingFileSnapshots: Array<{\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }> = [];\n /** Tracks open tool_use IDs during the current run to serialize on close for resume. */\n private openToolUses = new Set<string>();\n\n recordFileChange(input: {\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }): void {\n this.pendingFileSnapshots.push(input);\n }\n\n constructor(\n public readonly id: string,\n private handle: fsp.FileHandle,\n private readonly startedAt: string,\n private readonly meta: Omit<SessionMetadata, 'startedAt'>,\n private readonly events?: EventBus | undefined,\n opts: {\n resumed?: boolean | undefined;\n dir?: string | undefined;\n filePath?: string | undefined;\n secretScrubber?: SecretScrubber | undefined;\n /** Called on close() with the finalized summary for index/sidecar writes. */\n onClose?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n } = {},\n ) {\n this.resumed = opts.resumed ?? false;\n // id already contains a date-prefix shard (e.g. \"2026-06-06/17-46-57Z_…\").\n // opts.dir is the shard directory — join with basename so the manifest\n // lives next to the JSONL file instead of creating a double-nested path.\n this.manifestFile = opts.dir ? path.join(opts.dir, `${path.basename(id)}.summary.json`) : '';\n this.filePath = opts.filePath ?? '';\n this.secretScrubber = opts.secretScrubber;\n this.onCloseCb = opts.onClose;\n this.summary = {\n id,\n title: '(empty session)',\n startedAt,\n model: meta.model ?? 'unknown',\n provider: meta.provider ?? 'unknown',\n tokenTotal: 0,\n };\n }\n\n get pendingToolUses(): string[] {\n return Array.from(this.openToolUses);\n }\n\n private async writeSessionStartLazy(): Promise<void> {\n // Write through the SAME file handle that flushBuffer() uses — avoids\n // cross-fd issues on Windows where a separate fsp.writeFile can contend\n // with the already-open append-mode handle. The handle was opened with\n // O_APPEND so this write lands at the current end-of-file regardless of\n // whether the file is empty or already contains prior session data.\n const record = `${JSON.stringify({\n type: this.resumed ? 'session_resumed' : 'session_start',\n ts: this.startedAt,\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n try {\n await this.enqueueWrite(record);\n } catch {\n // best-effort\n }\n }\n\n async append(event: SessionEvent): Promise<void> {\n if (this.closed) return;\n await this.ensureInit();\n // Scrub before observing (the summary title is derived from user_input\n // content) and before buffering, so neither the JSONL nor the sidecar\n // ever holds a cleartext secret.\n const scrubbed = this.scrubEvent(event);\n // observeForSummary MUST run synchronously here — the summary counters\n // (toolCallCount, tokenIn/Out, outcome) drive the .summary.json sidecar\n // and the session index. Deferring observation to flush time would leave\n // the summary stale if close() fires before the next timer tick.\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n // Buffer full — flush immediately. Cancel any pending timer so we\n // don't double-flush on the next tick.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n async appendBatch(events: SessionEvent[]): Promise<void> {\n if (this.closed || events.length === 0) return;\n await this.ensureInit();\n for (const event of events) {\n const scrubbed = this.scrubEvent(event);\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n }\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n /**\n * Flush buffered events to disk immediately. Critical events\n * (user_input, llm_response) call this so they survive SIGKILL/crash\n * instead of sitting in the in-memory buffer for up to 500ms.\n *\n * Idempotent — cancels any pending timer and writes whatever has\n * accumulated in the buffer. Safe to call even when the buffer\n * is empty (no-op).\n */\n async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n }\n\n /** Schedule a deferred flush. No-op if a timer is already pending. */\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n this.flushBuffer().catch(() => {\n // flushBuffer already logs via the throttled-warning path;\n // this catch prevents an unhandled rejection in the timer callback.\n });\n }, FileSessionWriter.FLUSH_INTERVAL_MS);\n }\n\n /**\n * Flush all buffered events to disk as a single appendFile call.\n * Errors use the same throttled-warning pattern the old per-event\n * append path used — one warning every 5s with a suppressed count.\n * On failure the buffer is cleared (events are best-effort, same as\n * the old per-event path where a failed write was silently dropped).\n */\n private async flushBuffer(): Promise<void> {\n if (this.writeBuffer.length === 0) return;\n const eventCount = this.writeBuffer.length;\n const batch = this.writeBuffer.map((e) => JSON.stringify(e)).join('\\n') + '\\n';\n this.writeBuffer = [];\n try {\n await this.enqueueWrite(batch);\n } catch (err) {\n this.appendFailCount += eventCount;\n const now = Date.now();\n if (now - this.lastAppendWarnAt > 5000) {\n const suppressed = this.appendFailCount - 1;\n const tail = suppressed > 0 ? ` (+${suppressed} suppressed)` : '';\n console.warn(\n '[session] flush failed:',\n err instanceof Error ? err.message : String(err),\n tail,\n );\n this.lastAppendWarnAt = now;\n this.appendFailCount = 0;\n }\n }\n }\n\n private observeForSummary(event: SessionEvent): void {\n // Track open tool uses so we can serialize them on close for resume.\n // The authoritative source is the llm_response content (a core event,\n // always written at every audit level); the legacy 'tool_use' event is\n // kept for alternate writers that still emit it.\n if (event.type === 'llm_response') {\n for (const block of event.content) {\n if (block.type === 'tool_use') this.openToolUses.add(block.id);\n }\n }\n if (event.type === 'tool_use') {\n this.openToolUses.add(event.id);\n } else if (event.type === 'tool_call_start') {\n this.toolCallCount++;\n this.toolBreakdown[event.name] = (this.toolBreakdown[event.name] ?? 0) + 1;\n } else if (event.type === 'tool_result') {\n this.openToolUses.delete(event.id);\n if (event.isError) {\n this.toolErrorCount++;\n this.outcome = 'error';\n }\n } else if (event.type === 'file_snapshot') {\n this.fileChangeCount += event.files.length;\n } else if (event.type === 'compaction') {\n this.compactionCount++;\n }\n // Error events (provider errors, execution errors) mark the session as failed.\n if (event.type === 'error' || event.type === 'provider_error') {\n this.outcome = 'error';\n }\n if (event.type === 'user_input' && this.summary.title === '(empty session)') {\n this.summary = { ...this.summary, title: userInputTitle(event.content) };\n } else if (event.type === 'llm_response') {\n this.tokenIn += event.usage.input;\n this.tokenOut += event.usage.output;\n this.summary = { ...this.summary, tokenTotal: this.tokenIn + this.tokenOut };\n } else if (event.type === 'session_end') {\n const total = event.usage.input + event.usage.output;\n if (total > 0) this.summary = { ...this.summary, tokenTotal: total };\n } else if (event.type === 'in_flight_start') {\n this.iterationCount++;\n }\n }\n\n async close(): Promise<void> {\n // Idempotent AND awaitable: concurrent/repeat callers share the same\n // promise, so nobody proceeds (e.g. to tear down the session directory)\n // while the first close is still flushing.\n if (this.closePromise) return this.closePromise;\n this.closePromise = this.doClose();\n return this.closePromise;\n }\n\n private async doClose(): Promise<void> {\n this.closed = true;\n // Flush any buffered events before finalizing. The summary counters\n // (toolCallCount, tokenIn/Out, outcome) are already up to date because\n // observeForSummary runs synchronously on every append, but the JSONL\n // must have all events on disk before we write the .summary.json sidecar.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain any write enqueued outside flushBuffer (e.g. the lazy\n // session_start record) before the handle is closed.\n await this.writeChain;\n // Finalize the summary before writing.\n this.summary = {\n ...this.summary,\n endedAt: new Date().toISOString(),\n iterationCount: this.iterationCount,\n toolCallCount: this.toolCallCount,\n toolErrorCount: this.toolErrorCount,\n fileChangeCount: this.fileChangeCount,\n compactionCount: this.compactionCount > 0 ? this.compactionCount : undefined,\n toolBreakdown:\n { ...this.toolBreakdown },\n outcome: this.outcome ?? 'completed',\n };\n if (this.manifestFile) {\n try {\n await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 0o600 });\n } catch {\n // manifest write is best-effort\n }\n }\n // Notify the store so it can update the session index. Await so the\n // index write completes before close() resolves — otherwise the\n // fire-and-forget _index.jsonl append races callers that tear down the\n // session directory right after close() (e.g. ENOTEMPTY on Windows).\n try {\n await this.onCloseCb?.(this.summary);\n } catch {\n // best-effort\n }\n try {\n await this.handle.close();\n } catch {\n // ignore\n }\n }\n\n async writeCheckpoint(promptIndex: number, promptPreview: string): Promise<void> {\n const fileCount = this.pendingFileSnapshots.length;\n if (fileCount > 0) {\n await this.writeFileSnapshot(promptIndex, [...this.pendingFileSnapshots]);\n this.pendingFileSnapshots = [];\n }\n await this.append({\n type: 'checkpoint',\n ts: new Date().toISOString(),\n promptIndex,\n promptPreview,\n });\n this.events?.emit('checkpoint.written', {\n promptIndex,\n promptPreview,\n ts: new Date().toISOString(),\n fileCount,\n });\n }\n\n async writeFileSnapshot(\n promptIndex: number,\n files: import('../types/session.js').FileSnapshot[],\n ): Promise<void> {\n await this.append({\n type: 'file_snapshot',\n ts: new Date().toISOString(),\n promptIndex,\n files,\n });\n }\n\n async truncateToCheckpoint(targetPromptIndex: number): Promise<number> {\n if (!this.filePath) return 0;\n // Flush buffered events to disk before reading — otherwise the in-memory\n // events that haven't hit the JSONL yet would be invisible to the\n // truncation logic and would be silently dropped by the rewrite.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain the write chain so no in-flight write straddles the\n // close → rename → reopen sequence below.\n await this.writeChain;\n const raw = await fsp.readFile(this.filePath, 'utf8');\n const lines = raw.split('\\n');\n const kept: string[] = [];\n let removedCount = 0;\n\n let targetCheckpointLine = -1;\n let afterTarget = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = expectDefined(lines[i]);\n if (!line.trim()) continue;\n\n let event: { type?: string | undefined; promptIndex?: number | undefined };\n try {\n event = JSON.parse(line);\n } catch {\n kept.push(line);\n continue;\n }\n\n if (event.type === 'checkpoint') {\n if ((event as { promptIndex: number }).promptIndex === targetPromptIndex) {\n targetCheckpointLine = kept.length;\n afterTarget = true;\n } else if ((event as { promptIndex: number }).promptIndex > targetPromptIndex) {\n afterTarget = true;\n }\n }\n\n if (event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n removedCount++;\n } else if (event.promptIndex === undefined) {\n if (!afterTarget || targetCheckpointLine === -1) {\n kept.push(line);\n } else {\n removedCount++;\n }\n } else {\n kept.push(line);\n }\n }\n\n const truncated = kept.join('\\n');\n // Windows EPERM fix: close the append-mode handle, write via temp file\n // and rename, then reopen. This is needed because rename() fails on\n // Windows when the target has an open file handle.\n const tmpPath = `${this.filePath}.rewind.tmp`;\n await fsp.writeFile(tmpPath, truncated + '\\n', 'utf8');\n try {\n await this.handle.close();\n await fsp.rename(tmpPath, this.filePath);\n // Re-open in append mode for continued use of this file.\n this.handle = await fsp.open(this.filePath, 'a', 0o600);\n } catch (err) {\n await fsp.unlink(tmpPath).catch(() => undefined);\n throw err;\n }\n\n await this.append({\n type: 'rewound',\n ts: new Date().toISOString(),\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n });\n\n this.events?.emit('session.rewound', {\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n removedEvents: removedCount,\n });\n\n return removedCount;\n }\n\n async clearSession(): Promise<void> {\n if (!this.filePath) return;\n // Discard any buffered events — the caller is explicitly resetting the\n // session to a clean slate. Cancel the timer so it doesn't fire and\n // append stale events to the freshly-cleared file.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.writeBuffer = [];\n // Let any in-flight append land first — otherwise it would re-append\n // stale events AFTER the reset record below.\n await this.writeChain;\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n await fsp.writeFile(this.filePath, record, 'utf8');\n }\n\n /**\n * Idea #1 — write an in-flight marker. The agent loop should call\n * this at the start of each long-running operation; a matching\n * `clearInFlightMarker` follows on clean exit. A stale marker\n * (no end) is what `SessionRecovery.detectStale` looks for.\n */\n async writeInFlightMarker(context: string): Promise<void> {\n if (!context || context.length > 500) {\n throw new Error('In-flight context must be 1..500 chars');\n }\n await this.append({\n type: 'in_flight_start',\n ts: new Date().toISOString(),\n context,\n });\n this.events?.emit('in_flight.started', { context, ts: new Date().toISOString() });\n }\n\n /**\n * Idea #1 — close the in-flight marker. Idempotent in spirit\n * (you can call it after a successful iteration even if you\n * didn't open one this round) — but the session log records\n * every call so postmortem tooling can see \"the agent finished\n * cleanly X times, then died without finishing Y\".\n */\n async clearInFlightMarker(reason: 'clean' | 'aborted' | 'recovered'): Promise<void> {\n await this.append({\n type: 'in_flight_end',\n ts: new Date().toISOString(),\n reason,\n });\n this.events?.emit('in_flight.ended', { reason, ts: new Date().toISOString() });\n }\n}\n\nfunction userInputTitle(content: string | ContentBlock[]): string {\n const text =\n typeof content === 'string'\n ? content\n : content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join(' ');\n return (text || '(non-text input)').slice(0, 60);\n}\n","import * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ContentBlock } from '../types/blocks.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * The persisted form of a single queued user message. The TUI's\n * in-memory QueueItem has a render id; that's pure UI bookkeeping, so\n * we drop it when serializing — fresh ids are assigned on rehydrate.\n */\nexport interface PersistedQueueItem {\n displayText: string;\n blocks: ContentBlock[];\n}\n\n/**\n * Side-file storage for a session's pending input queue. Lives at\n * `<sessionDir>/queue.json` next to the attachment spool. Reads are\n * tolerant (missing/malformed file → empty array); writes are atomic\n * (tmp + rename) so a crash mid-write can never leave a partial file\n * the next launch would choke on.\n *\n * The contract is \"snapshot replacement\": every mutation hands the\n * full queue and we rewrite the file. The queue is small (rarely more\n * than a handful of messages), so this is cheaper than delta logging\n * and avoids the replay complexity.\n */\nexport class QueueStore {\n private readonly file: string;\n\n constructor(opts: { dir: string }) {\n this.file = path.join(opts.dir, 'queue.json');\n }\n\n async write(items: PersistedQueueItem[]): Promise<void> {\n if (items.length === 0) {\n // Empty queue → remove the file rather than write `[]`. Keeps\n // a clean idle state on disk and makes `read()` cheaper.\n await this.clear();\n return;\n }\n await atomicWrite(this.file, JSON.stringify(items), { mode: 0o600 });\n }\n\n async read(): Promise<PersistedQueueItem[]> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return [];\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.read_failed',\n path: this.file,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n if (!Array.isArray(parsed)) return [];\n const out: PersistedQueueItem[] = [];\n for (const v of parsed) {\n if (isPersistedQueueItem(v)) out.push(v);\n }\n return out;\n }\n\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n // Best-effort: a permission/lock error during clear is rare and\n // the queue slash command is non-critical. Warn so it's observable\n // but don't throw so the slash command doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.clear_failed',\n path: this.file,\n message: (err as Error).message,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n}\n\nfunction isPersistedQueueItem(v: unknown): v is PersistedQueueItem {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return typeof o['displayText'] === 'string' && Array.isArray(o['blocks']);\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type {\n AddAttachmentInput,\n Attachment,\n AttachmentKind,\n AttachmentRef,\n AttachmentStore,\n} from '../types/attachment.js';\nimport type { ContentBlock } from '../types/blocks.js';\n\nexport interface AttachmentStoreOptions {\n /**\n * Directory for spooling payloads larger than `spoolThresholdBytes`.\n * When omitted, all payloads stay in memory.\n */\n spoolDir?: string | undefined;\n spoolThresholdBytes?: number | undefined;\n}\n\nconst DEFAULT_SPOOL_THRESHOLD = 256 * 1024; // 256 KB\n// Two placeholder shapes:\n// - seq-keyed `[<kind> #<seq>…]` — kind is `pasted` / `image` / `file`. A\n// cosmetic suffix after the seq (e.g. `, 123 lines`) is tolerated so the\n// TUI can render `[pasted #1, 123 lines]` while still resolving by seq.\n// - path-keyed `[file:<path>]` — resolves to the most recent file ref whose\n// stored path matches, so the TUI can show a human-readable file chip.\nconst PLACEHOLDER_RE = /\\[(pasted|image|file) #(\\d+)[^\\]]*\\]|\\[file:([^\\]]+)\\]/g;\n\n/**\n * In-memory attachment store with optional disk spool. Placeholder syntax\n * is `[<kind> #<seq>]` (seq-keyed) or `[file:<path>]` (path-keyed) where kind\n * is `pasted` / `image` / `file`. Unknown placeholders are passed through\n * as-is so users can write that literal text without losing it.\n */\nexport class DefaultAttachmentStore implements AttachmentStore {\n private readonly items = new Map<string, Attachment>();\n private readonly refs: AttachmentRef[] = [];\n private nextSeq: Record<AttachmentKind, number> = { text: 0, image: 0, file: 0 };\n private readonly spoolDir: string | undefined;\n private readonly spoolThreshold: number;\n\n constructor(opts: AttachmentStoreOptions = {}) {\n this.spoolDir = opts.spoolDir;\n this.spoolThreshold = opts.spoolThresholdBytes ?? DEFAULT_SPOOL_THRESHOLD;\n }\n\n async add(input: AddAttachmentInput): Promise<AttachmentRef> {\n const seq = ++this.nextSeq[input.kind];\n const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes(3).toString('hex')}`;\n const bytes = Buffer.byteLength(input.data, input.kind === 'image' ? 'base64' : 'utf8');\n let spooledPath: string | undefined;\n let data: string | undefined = input.data;\n if (this.spoolDir && bytes >= this.spoolThreshold) {\n await fsp.mkdir(this.spoolDir, { recursive: true });\n spooledPath = path.join(this.spoolDir, `${id}.bin`);\n // atomicWrite: torn spool would silently corrupt the attachment;\n // the user would see garbled output the next time it's expanded.\n await atomicWrite(spooledPath, input.data, {\n encoding: input.kind === 'image' ? 'base64' : 'utf8',\n });\n data = undefined;\n }\n const att: Attachment = {\n id,\n kind: input.kind,\n meta: input.meta ?? {},\n data,\n path: spooledPath,\n bytes,\n createdAt: new Date().toISOString(),\n };\n this.items.set(id, att);\n const ref: AttachmentRef = { id, kind: input.kind, seq, meta: att.meta };\n this.refs.push(ref);\n return ref;\n }\n\n async get(id: string): Promise<Attachment | undefined> {\n return this.items.get(id);\n }\n\n list(): AttachmentRef[] {\n return [...this.refs];\n }\n\n async expand(text: string): Promise<ContentBlock[]> {\n const matches = [...text.matchAll(PLACEHOLDER_RE)];\n if (matches.length === 0) return text ? [{ type: 'text', text }] : [];\n const blocks: ContentBlock[] = [];\n let lastIndex = 0;\n for (const m of matches) {\n const idx = m.index ?? 0;\n const before = text.slice(lastIndex, idx);\n if (before) blocks.push({ type: 'text', text: before });\n let ref: AttachmentRef | undefined;\n if (m[3] !== undefined) {\n // Path-keyed `[file:<path>]` — most recent matching file ref wins.\n const wantPath = m[3];\n ref = findLast(this.refs, (r) => r.kind === 'file' && refPath(r) === wantPath);\n } else {\n const kind = prefixToKind(m[1] as string);\n const seq = Number(m[2]);\n ref = this.refs.find((r) => r.kind === kind && r.seq === seq);\n }\n const att = ref ? this.items.get(ref.id) : undefined;\n if (!att) {\n blocks.push({ type: 'text', text: m[0] });\n } else {\n blocks.push(await this.toBlock(att));\n }\n lastIndex = idx + m[0].length;\n }\n const tail = text.slice(lastIndex);\n if (tail) blocks.push({ type: 'text', text: tail });\n return mergeAdjacentText(blocks);\n }\n\n async clear(): Promise<void> {\n // Unlink any spooled files so we don't leak disk space.\n if (this.spoolDir) {\n const toDelete: string[] = [];\n for (const att of this.items.values()) {\n if (att.path) toDelete.push(att.path);\n }\n await Promise.all(toDelete.map((p) => fsp.unlink(p).catch(() => undefined)));\n }\n this.items.clear();\n this.refs.length = 0;\n this.nextSeq = { text: 0, image: 0, file: 0 };\n }\n\n private async toBlock(att: Attachment): Promise<ContentBlock> {\n if (att.kind === 'image') {\n const data =\n att.data ?? (att.path ? await fsp.readFile(att.path, { encoding: 'base64' }) : '');\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: att.meta.mediaType ?? 'image/png',\n data,\n },\n };\n }\n const raw = att.data ?? (att.path ? await fsp.readFile(att.path, 'utf8') : '');\n const label = att.meta.filename ? `<file path=\"${att.meta.filename}\">` : '<pasted>';\n const close = att.meta.filename ? '</file>' : '</pasted>';\n return { type: 'text', text: `${label}\\n${raw}\\n${close}` };\n }\n}\n\nfunction kindPrefix(kind: AttachmentKind): string {\n return kind === 'text' ? 'pasted' : kind;\n}\n\nfunction prefixToKind(prefix: string): AttachmentKind {\n if (prefix === 'pasted') return 'text';\n if (prefix === 'image') return 'image';\n return 'file';\n}\n\n/** Path a file ref was registered under, for `[file:<path>]` lookup. */\nfunction refPath(ref: AttachmentRef): string | undefined {\n return ref.meta.filename ?? ref.meta.label;\n}\n\n/** Last element matching the predicate (Node < 20 lacks Array.findLast). */\nfunction findLast<T>(arr: readonly T[], pred: (v: T) => boolean): T | undefined {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (pred(arr[i] as T)) return arr[i];\n }\n return undefined;\n}\n\nfunction mergeAdjacentText(blocks: ContentBlock[]): ContentBlock[] {\n const out: ContentBlock[] = [];\n for (const b of blocks) {\n const prev = out[out.length - 1];\n if (b.type === 'text' && prev && prev.type === 'text') {\n prev.text += b.text;\n } else {\n out.push(b);\n }\n }\n return out;\n}\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { MEMORY_TYPE_LABELS, type MemoryPriority, type MemoryType } from '../types/memory.js';\nimport { atomicWrite, ensureDir, withFileLock } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\n// ── Backend interface ──────────────────────────────────────────────────\n\nexport interface MemoryBackend {\n readonly kind: string;\n remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void>;\n forget(scope: MemoryScope, query: string, filePath: string): Promise<number>;\n readAll(scope: MemoryScope, filePath: string): Promise<string>;\n list(scope: MemoryScope, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n search(scope: MemoryScope, query: string, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n /** Find memories related to the given text via graph traversal. Optional — falls back to search. */\n findRelated?(scope: MemoryScope, filePath: string, text: string, limit: number): Promise<MemoryEntry[]>;\n clear(scope: MemoryScope, filePath: string): Promise<void>;\n consolidate(scope: MemoryScope, filePath: string): Promise<number>;\n}\n\n// ── Entry serialization format ─────────────────────────────────────────\n//\n// Full format:\n// - [ISO] [TYPE|PRIORITY] mem_<id> text content #tag1 #tag2\n//\n// Examples:\n// - [2026-06-07T...] mem_1234_abcd Project uses pnpm #pnpm #build\n// - [2026-06-07T...] [convention|high] mem_5678_ef01 Use conventional commits #git #commit\n//\n// Old format (backward compatible):\n// - [ISO] mem_<id> text content\n\nconst TYPE_PRIORITY_RE = /^\\[(\\w+)\\|(\\w+)\\]\\s+/;\nconst TAG_RE = /#([\\w-]+)/g;\n\nfunction formatMetadata(entry: MemoryEntry): string {\n const parts: string[] = [];\n if (entry.type && entry.priority) {\n parts.push(`[${entry.type}|${entry.priority}]`);\n } else if (entry.type) {\n parts.push(`[${entry.type}]`);\n } else if (entry.priority) {\n parts.push(`[${entry.priority}]`);\n }\n if (entry.tags && entry.tags.length > 0) {\n parts.push(entry.tags.map((t) => `#${t}`).join(' '));\n }\n return parts.length > 0 ? ` ${parts.join(' ')}` : '';\n}\n\nfunction lineToEntry(line: string, scope: MemoryScope): MemoryEntry | null {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- [')) return null;\n\n // Parse timestamp: `- [ISO] ...`\n const tsMatch = trimmed.match(/^-\\s*\\[([^\\]]+)\\]/);\n if (!tsMatch) return null;\n const ts = tsMatch[1] ?? '';\n\n let rest = trimmed.slice(tsMatch[0].length).trim();\n\n // Parse optional type|priority: `[convention|high]` or `[fact]`\n let type: MemoryType | undefined;\n let priority: MemoryPriority | undefined;\n const tpMatch = rest.match(TYPE_PRIORITY_RE);\n if (tpMatch) {\n const a = tpMatch[1] ?? '';\n const b = tpMatch[2] ?? '';\n if (isMemoryType(a)) {\n type = a;\n priority = isPriority(b) ? b : undefined;\n } else if (isPriority(a)) {\n priority = a;\n }\n rest = rest.slice(tpMatch[0].length).trim();\n }\n\n // Parse optional entry ID: `mem_<ts>_<rand>`\n const idMatch = rest.match(/^mem_\\d+_\\w+\\s+/);\n let text: string;\n if (idMatch) {\n text = rest.slice(idMatch[0].length).trim();\n } else {\n text = rest.trim();\n }\n\n // Extract #tags from text\n const tags: string[] = [];\n let tagMatch: RegExpExecArray | null;\n TAG_RE.lastIndex = 0;\n // biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop\n while ((tagMatch = TAG_RE.exec(text)) !== null) {\n tags.push(tagMatch[1] ?? '');\n }\n // Remove tags from display text\n const cleanText = text.replace(TAG_RE, '').replace(/\\s{2,}/g, ' ').trim();\n\n if (!cleanText) return null;\n\n return {\n scope,\n text: cleanText,\n ts,\n type,\n priority,\n tags: tags.length > 0 ? tags : undefined,\n };\n}\n\nfunction isMemoryType(s: string): s is MemoryType {\n return s in MEMORY_TYPE_LABELS;\n}\n\nfunction isPriority(s: string): s is MemoryPriority {\n return s === 'critical' || s === 'high' || s === 'medium' || s === 'low';\n}\n\n// ── File-based backend ─────────────────────────────────────────────────\n\nexport interface FileMemoryBackendOptions {\n paths: WstackPaths;\n}\n\nexport class FileMemoryBackend implements MemoryBackend {\n readonly kind = 'file';\n private readonly files: Record<MemoryScope, string>;\n\n constructor(opts: FileMemoryBackendOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n }\n\n private resolveFile(filePath: string, scope: MemoryScope): string {\n return filePath || this.files[scope];\n }\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await ensureDir(path.dirname(file));\n let existing = '';\n try { existing = await fs.readFile(file, 'utf8'); } catch { /* new file */ }\n\n const id = `mem_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const meta = formatMetadata(entry);\n const line = `\\n- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\\n/g, ' ')}\\n`;\n const next = existing.trim()\n ? existing.replace(/\\n+$/, '') + line\n : `# Agent Memory\\n${line}`;\n await atomicWrite(file, next);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n return withFileLock(file, async () => {\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; }\n\n const needle = query.toLowerCase();\n const idMatcher = /mem_\\d+_\\w+/;\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n if (idMatcher.test(query)) {\n const entryIdMatch = /mem_\\d+_\\w+/.exec(trimmed);\n if (entryIdMatch && entryIdMatch[0] === query) { removed++; return false; }\n }\n if (trimmed.toLowerCase().includes(needle)) { removed++; return false; }\n return true;\n });\n if (removed > 0) {\n if (lines.length === 0 || (lines.length === 1 && !lines[0]?.trim())) {\n await atomicWrite(file, '');\n } else {\n await atomicWrite(file, lines.join('\\n'));\n }\n }\n return removed;\n });\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n const file = this.resolveFile(filePath, scope);\n try { return await fs.readFile(file, 'utf8'); } catch { return ''; }\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const raw = await this.readAll(scope, filePath);\n if (!raw.trim()) return [];\n const entries = parseEntries(raw, scope);\n return limit ? entries.slice(0, limit) : entries;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const entries = await this.list(scope, filePath);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Score by word overlap + tag match\n const scored = entries.map((e) => {\n const words = e.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n // Tag matches are weighted higher\n if (e.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n return { entry: e, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await atomicWrite(file, '');\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; }\n\n const seen = new Set<string>();\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n // Normalize: strip timestamp, ID, type|priority, tags\n const norm = trimmed\n .replace(/\\[[^\\]]+\\]/g, '')\n .replace(/\\bmem_\\d+_\\w+\\s*/, '')\n .replace(/#[\\w-]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .toLowerCase();\n if (seen.has(norm)) { removed++; return false; }\n seen.add(norm);\n return true;\n });\n\n const next = lines.join('\\n');\n const backup = `${file}.bak.${Date.now()}`;\n try { await fs.copyFile(file, backup); } catch { /* best-effort */ }\n try { await atomicWrite(file, next); } catch { return 0; }\n return removed;\n }\n}\n\n// ── Entry parsing ──────────────────────────────────────────────────────\n\nexport function parseEntries(raw: string, scope: MemoryScope = 'project-memory'): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n for (const line of raw.split('\\n')) {\n const entry = lineToEntry(line, scope);\n if (entry) entries.push(entry);\n }\n return entries.reverse(); // newest first\n}\n","import type {\n MemoryClearedPayload,\n MemoryConsolidatedPayload,\n MemoryEntry,\n MemoryForgottenPayload,\n MemoryRelevanceContext,\n MemoryRememberedPayload,\n MemoryScope,\n MemoryStore,\n ScoredEntry,\n} from '../types/memory.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport { type MemoryBackend, FileMemoryBackend } from './memory-backend.js';\n\nconst MAX_BYTES_TOTAL = 32_000; // ~8K tokens\n\nexport interface MemoryStoreOptions {\n paths: WstackPaths;\n /**\n * Optional event bus — when provided, mutations emit events so plugins\n * and other subsystems can react to memory changes.\n */\n events?: EventBus | undefined;\n /**\n * Storage backend. Defaults to FileMemoryBackend when omitted.\n * Plugins can register a custom backend (graph, semantic, vector)\n * via the DI container to override storage behavior.\n */\n backend?: MemoryBackend | undefined;\n}\n\n/**\n * Three scopes:\n * project-agents → <project>/.wrongstack/AGENTS.md (committed)\n * project-memory → ~/.wrongstack/projects/<hash>/memory.md (per-project agent notes)\n * user-memory → ~/.wrongstack/memory.md (global personal memory)\n */\nexport class DefaultMemoryStore implements MemoryStore {\n private readonly files: Record<MemoryScope, string>;\n private readonly events?: EventBus | undefined;\n private readonly backend: MemoryBackend;\n\n /**\n * Per-scope serialization queue. `remember` / `forget` / `consolidate` /\n * `clear` are read-modify-write against a single file; without a lock,\n * two concurrent calls on the same scope can read the same baseline and\n * the later write silently drops the earlier entry. We chain each\n * mutation onto the prior promise for the same scope so they run in\n * issue order. Different scopes still proceed in parallel.\n *\n * The chain tracks only the last pending write. If a write fails, its\n * error is caught and swallowed so the chain stays alive for subsequent\n * calls. The error is stored in `writeErrors` so callers can learn about\n * it on the next read operation.\n */\n private readonly writeChain = new Map<MemoryScope, Promise<unknown>>();\n /** Last write error per scope — surfaced as warnings on the next readAll(). */\n private readonly writeErrors = new Map<MemoryScope, Error>();\n\n /**\n * When the global root is a temporary directory (opencode, CI sandboxes),\n * memory files are also mirrored to the project tree so they survive\n * session cleanup. The primary path stays in the temp root for isolation;\n * this backup ensures memory is never lost.\n */\n private readonly persistBackup: boolean;\n private readonly backupDir: string;\n\n constructor(opts: MemoryStoreOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n this.events = opts.events;\n this.backend = opts.backend ?? new FileMemoryBackend({ paths: opts.paths });\n\n // Detect temporary global roots: opencode, CI, test sandboxes.\n // When detected, mirror writes to the project's .wrongstack/ dir.\n const root = opts.paths.globalRoot.toLowerCase();\n this.persistBackup = /[/\\\\](tmp|temp|cache)[/\\\\]/.test(root);\n this.backupDir = this.persistBackup\n ? opts.paths.inProjectAgentsFile.replace(/AGENTS\\.md$/, 'memory-persist')\n : '';\n }\n\n /** Expose the backend for plugin introspection and advanced queries. */\n getBackend(): MemoryBackend {\n return this.backend;\n }\n\n private async runSerialized<T>(scope: MemoryScope, work: () => Promise<T>): Promise<T> {\n const prior = this.writeChain.get(scope) ?? Promise.resolve();\n // Chain: catch errors from the prior write, then run the next work item.\n const next = prior\n .catch((err) => {\n this.writeErrors.set(scope, err as Error);\n })\n .then(() => work());\n this.writeChain.set(scope, next as Promise<unknown>);\n try {\n return await next;\n } catch (err) {\n this.writeErrors.set(scope, err as Error);\n throw err;\n } finally {\n if (this.writeChain.get(scope) === next) {\n this.writeChain.delete(scope);\n }\n }\n }\n\n async readAll(): Promise<string> {\n const parts: string[] = [];\n for (const scope of ['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]) {\n const writeErr = this.writeErrors.get(scope);\n if (writeErr) {\n parts.push(`> ⚠️ Memory write error (${labelOf(scope)}): ${writeErr.message}`);\n }\n const body = await this.backend.readAll(scope, this.files[scope]);\n if (body.trim()) parts.push(`## ${labelOf(scope)}\\n\\n${body.trim()}`);\n }\n return parts.join('\\n\\n');\n }\n\n async read(scope: MemoryScope): Promise<string> {\n return this.backend.readAll(scope, this.files[scope]);\n }\n\n /**\n * List entries from a scope, newest first. Delegates to the backend\n * so graph/semantic backends can return enriched or filtered results.\n */\n async list(scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.list(scope, this.files[scope], limit);\n }\n\n /**\n * Find memories related to the given text via graph traversal.\n * Falls back to content search when no graph backend is available.\n */\n async findRelated(text: string, scope: MemoryScope = 'project-memory', limit = 5): Promise<MemoryEntry[]> {\n if (this.backend.findRelated) {\n return this.backend.findRelated(scope, this.files[scope], text, limit);\n }\n return this.search(text, scope, limit);\n }\n\n async search(query: string, scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.search(scope, query, this.files[scope], limit);\n }\n\n async remember(\n text: string,\n scope: MemoryScope = 'project-memory',\n metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>,\n ): Promise<void> {\n const ts = new Date().toISOString();\n return this.runSerialized(scope, async () => {\n const entry: MemoryEntry = { scope, text, ts, ...metadata };\n await this.backend.remember(scope, entry, this.files[scope]);\n\n // Size check — consolidate if the file exceeds the cap.\n const raw = await this.backend.readAll(scope, this.files[scope]);\n if (Buffer.byteLength(raw, 'utf8') > MAX_BYTES_TOTAL) {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n }\n }\n\n // Mirror to persistent backup when running in a temp sandbox.\n await this.mirrorBackup(scope);\n\n this.events?.emit('memory.remembered', {\n scope,\n text,\n ts,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n } satisfies MemoryRememberedPayload);\n });\n }\n\n /**\n * Score and rank memories by relevance to the current context.\n * Returns entries with score >= MIN_RELEVANCE_SCORE, sorted highest first.\n */\n async scoreRelevant(\n ctx: MemoryRelevanceContext,\n scope: MemoryScope = 'project-memory',\n limit = 8,\n ): Promise<ScoredEntry[]> {\n const all = await this.list(scope);\n if (all.length === 0) return [];\n\n const taskWords = ctx.currentTask.toLowerCase().split(/\\s+/).filter((w) => w.length > 2);\n const skillWords = (ctx.activeSkills ?? []).flatMap((s) => s.split('-'));\n const toolWords = (ctx.toolNames ?? []).flatMap((t) => t.toLowerCase().split('_'));\n const now = Date.now();\n\n const scored: ScoredEntry[] = [];\n\n for (const entry of all) {\n let score = 0;\n const reasons: string[] = [];\n const textLower = entry.text.toLowerCase();\n const tagsLower = (entry.tags ?? []).map((t) => t.toLowerCase());\n\n // Word overlap with current task (primary signal)\n let taskHits = 0;\n for (const w of taskWords) {\n if (textLower.includes(w)) { taskHits++; score += 2; }\n if (tagsLower.some((t) => t.includes(w))) { taskHits++; score += 3; }\n }\n if (taskHits > 0) reasons.push(`task match (${taskHits})`);\n\n // Skill/tool relevance\n let skillHits = 0;\n for (const w of skillWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n skillHits++;\n }\n }\n score += skillHits;\n if (skillHits > 0) reasons.push(`skill match (${skillHits})`);\n\n for (const w of toolWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n score += 1;\n reasons.push(`tool mention: ${w}`);\n }\n }\n\n // Priority boost\n switch (entry.priority) {\n case 'critical': score += 5; reasons.push('critical'); break;\n case 'high': score += 3; reasons.push('high priority'); break;\n case 'medium': score += 1; break;\n case 'low': score -= 2; reasons.push('low priority'); break;\n }\n\n // Type boost — decisions, conventions, anti-patterns are high-value\n switch (entry.type) {\n case 'decision': score += 2; reasons.push('decision'); break;\n case 'convention': score += 2; reasons.push('convention'); break;\n case 'anti_pattern': score += 3; reasons.push('anti-pattern'); break;\n case 'preference': score += 1; reasons.push('preference'); break;\n case 'reference': break;\n case 'fact': break;\n }\n\n // Recency boost — newer entries get +1, very old get 0\n const ageDays = (now - new Date(entry.ts).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays < 1) score += 1;\n else if (ageDays > 30) score -= 1;\n\n // Confidence penalty\n if (entry.confidence !== undefined && entry.confidence < 0.5) {\n score -= 2;\n reasons.push('low confidence');\n }\n\n // Repetition avoidance — recently accessed entries get slight penalty\n if (entry.lastAccessed) {\n const hoursSinceAccess = (now - new Date(entry.lastAccessed).getTime()) / (1000 * 60 * 60);\n if (hoursSinceAccess < 1) score -= 1;\n }\n\n if (score > 0) {\n scored.push({\n ...entry,\n score,\n matchReason: reasons.join(', ') || 'keyword match',\n });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n\n // Filter to entries that meet the minimum relevance threshold.\n // Critical or high-priority entries always pass.\n const threshold = 2;\n const relevant = scored.filter(\n (s) => s.score >= threshold || s.priority === 'critical' || s.priority === 'high',\n );\n\n return relevant.slice(0, Math.min(limit, 15));\n }\n\n async forget(query: string, scope: MemoryScope = 'project-memory'): Promise<number> {\n return this.runSerialized(scope, async () => {\n const removed = await this.backend.forget(scope, query, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.forgotten', {\n scope,\n query,\n removed,\n } satisfies MemoryForgottenPayload);\n await this.mirrorBackup(scope);\n }\n return removed;\n });\n }\n\n async consolidate(scope: MemoryScope): Promise<void> {\n return this.runSerialized(scope, async () => {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n await this.mirrorBackup(scope);\n }\n });\n }\n\n async clear(scope?: MemoryScope): Promise<void> {\n if (scope) {\n await this.runSerialized(scope, async () => {\n await this.backend.clear(scope, this.files[scope]);\n this.events?.emit('memory.cleared', { scope } satisfies MemoryClearedPayload);\n await this.mirrorBackup(scope);\n });\n return;\n }\n await Promise.all(\n (['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]).map((s) =>\n this.runSerialized(s, async () => {\n await this.backend.clear(s, this.files[s]);\n this.events?.emit('memory.cleared', { scope: s } satisfies MemoryClearedPayload);\n await this.mirrorBackup(s);\n }),\n ),\n );\n }\n\n /** Mirror current memory content to the persistent backup directory. */\n private async mirrorBackup(scope: MemoryScope): Promise<void> {\n if (!this.persistBackup || scope === 'project-agents') return;\n try {\n const content = await this.backend.readAll(scope, this.files[scope]);\n const { writeFile, mkdir } = await import('node:fs/promises');\n await mkdir(this.backupDir, { recursive: true });\n await writeFile(`${this.backupDir}/${scope}.md`, content, 'utf8');\n } catch {\n // best-effort\n }\n }\n}\n\nfunction labelOf(scope: MemoryScope): string {\n switch (scope) {\n case 'project-agents':\n return 'Project AGENTS.md';\n case 'project-memory':\n return 'Project memory';\n case 'user-memory':\n return 'User memory';\n }\n}\n","import * as fs from 'node:fs/promises';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { type FileMemoryBackendOptions, FileMemoryBackend } from './memory-backend.js';\nimport type { MemoryBackend } from './memory-backend.js';\n\n// ── Graph node and edge types ──────────────────────────────────────────\n\ninterface GraphNode {\n id: string;\n entry: MemoryEntry;\n firstSeen: string;\n count: number;\n /** Extracted metadata for fast lookup. */\n type?: MemoryEntry['type'] | undefined;\n tags?: string[] | undefined;\n priority?: MemoryEntry['priority'] | undefined;\n}\n\ninterface GraphEdge {\n from: string;\n to: string;\n /** Why these nodes are related. */\n relation: 'co_occurring' | 'similar' | 'same_turn' | 'explicit';\n weight: number;\n ts: string;\n}\n\n// ── Backend ────────────────────────────────────────────────────────────\n\nexport interface GraphMemoryBackendOptions extends FileMemoryBackendOptions {\n /**\n * Path to the graph metadata file (edges + node metadata).\n * Defaults to `<projectDir>/memory-graph.json`.\n */\n graphPath?: string | undefined;\n}\n\n/**\n * Graph-based memory backend that tracks relationships between entries.\n * Builds on top of FileMemoryBackend — entries are still persisted as\n * markdown bullets, but the graph layer adds:\n *\n * - Co-occurrence edges (entries from the same remember() batch)\n * - Content similarity edges (simple Jaccard on word overlap)\n * - Turn-based edges (entries created in the same LLM turn)\n * - Graph traversal queries (find related memories)\n *\n * The graph metadata persists to `<projectDir>/memory-graph.json`.\n */\nexport class GraphMemoryBackend implements MemoryBackend {\n readonly kind = 'graph';\n\n private readonly file: FileMemoryBackend;\n private readonly graphFile: string;\n\n // In-memory graph state — lazily loaded, saved on mutation.\n private nodes = new Map<string, GraphNode>();\n private edges: GraphEdge[] = [];\n private loadedScope: MemoryScope | null = null;\n private loaded = false;\n\n constructor(opts: GraphMemoryBackendOptions) {\n this.file = new FileMemoryBackend({ paths: opts.paths });\n this.graphFile = opts.graphPath ?? `${opts.paths.projectDir}/memory-graph.json`;\n }\n\n // ── Backend interface ──────────────────────────────────────────────\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n await this.file.remember(scope, entry, filePath);\n await this.loadGraph(scope);\n\n const nodeId = this.nodeId(entry);\n const existing = this.nodes.get(nodeId);\n if (existing) {\n existing.count++;\n existing.entry = entry;\n existing.type = entry.type;\n existing.tags = entry.tags;\n existing.priority = entry.priority;\n } else {\n this.nodes.set(nodeId, {\n id: nodeId,\n entry,\n firstSeen: entry.ts,\n count: 1,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n });\n\n // Create similarity edges with existing nodes\n for (const [, other] of this.nodes) {\n if (other.id === nodeId) continue;\n const sim = wordOverlap(entry.text, other.entry.text);\n // Also create edges for shared tags\n const tagSim = sharedTags(entry.tags ?? [], other.tags ?? []);\n const weight = Math.max(sim, tagSim * 0.5);\n if (weight > 0.15) {\n this.edges.push({\n from: nodeId,\n to: other.id,\n relation: sim >= tagSim ? 'similar' : 'same_turn',\n weight,\n ts: entry.ts,\n });\n }\n }\n }\n\n await this.saveGraph(scope);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const removed = await this.file.forget(scope, query, filePath);\n if (removed > 0) {\n await this.loadGraph(scope);\n // Remove nodes whose entry text matches the query\n const n = query.toLowerCase();\n const toRemove: string[] = [];\n for (const [id, node] of this.nodes) {\n if (node.entry.text.toLowerCase().includes(n)) {\n toRemove.push(id);\n }\n }\n for (const id of toRemove) this.nodes.delete(id);\n this.edges = this.edges.filter((e) => !toRemove.includes(e.from) && !toRemove.includes(e.to));\n await this.saveGraph(scope);\n }\n return removed;\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n return this.file.readAll(scope, filePath);\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n // Merge: file entries are canonical, graph adds metadata and dedup\n const fileEntries = await this.file.list(scope, filePath);\n const nodeMap = new Map(this.nodes.entries());\n\n // Enrich file entries with graph metadata\n const enriched = fileEntries.map((fe) => {\n const nodeId = this.nodeId(fe);\n const node = nodeMap.get(nodeId);\n if (node) {\n return {\n ...fe,\n type: node.type ?? fe.type,\n tags: node.tags ?? fe.tags,\n priority: node.priority ?? fe.priority,\n };\n }\n return fe;\n });\n\n // Add graph-only nodes not in file (shouldn't happen normally, but safety)\n const fileIds = new Set(fileEntries.map((e) => this.nodeId(e)));\n for (const [id, node] of this.nodes) {\n if (!fileIds.has(id)) {\n enriched.push(node.entry);\n }\n }\n\n enriched.sort((a, b) => b.ts.localeCompare(a.ts));\n return limit ? enriched.slice(0, limit) : enriched;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Get all entries (file-canonical, graph-enriched)\n const all = await this.list(scope, filePath);\n\n // Score by word overlap + tag match + graph metadata\n const scored = all.map((entry) => {\n const words = entry.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n if (entry.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n const node = this.nodes.get(this.nodeId(entry));\n if (node) {\n if (node.priority === 'critical') score += 3;\n else if (node.priority === 'high') score += 2;\n score += node.count * 0.5;\n }\n return { entry, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n await this.file.clear(scope, filePath);\n this.nodes.clear();\n this.edges = [];\n this.loadedScope = scope;\n this.loaded = true;\n // Write empty graph\n try { await fs.unlink(this.graphFile); } catch { /* ok */ }\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n return this.file.consolidate(scope, filePath);\n }\n\n // ── Graph-specific queries ─────────────────────────────────────────\n\n /**\n * Find memories related to the given entry, ordered by edge weight.\n */\n async findRelated(scope: MemoryScope, _filePath: string, entryText: string, limit = 5): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const targetId = this.nodeId({ scope, text: entryText, ts: '' });\n const related = this.edges\n .filter((e) => e.from === targetId || e.to === targetId)\n .sort((a, b) => b.weight - a.weight)\n .slice(0, limit);\n\n const result: MemoryEntry[] = [];\n for (const edge of related) {\n const otherId = edge.from === targetId ? edge.to : edge.from;\n const node = this.nodes.get(otherId);\n if (node) result.push(node.entry);\n }\n return result;\n }\n\n /**\n * Get all edges for visualization or traversal.\n */\n getGraph(): { nodes: GraphNode[]; edges: GraphEdge[] } {\n return {\n nodes: [...this.nodes.values()],\n edges: [...this.edges],\n };\n }\n\n // ── Persistence ────────────────────────────────────────────────────\n\n private nodeId(entry: MemoryEntry): string {\n // Stable ID from scope + normalized text\n const norm = entry.text.toLowerCase().trim().replace(/\\s+/g, ' ');\n return `${entry.scope ?? 'mem'}::${simpleHash(norm)}`;\n }\n\n private async loadGraph(scope: MemoryScope): Promise<void> {\n if (this.loaded && this.loadedScope === scope) return;\n try {\n const raw = await fs.readFile(this.graphFile, 'utf8');\n const data: { nodes: Array<[string, GraphNode]>; edges: GraphEdge[] } = JSON.parse(raw);\n this.nodes = new Map(data.nodes);\n this.edges = data.edges;\n } catch {\n this.nodes = new Map();\n this.edges = [];\n }\n this.loadedScope = scope;\n this.loaded = true;\n }\n\n private async saveGraph(scope: MemoryScope): Promise<void> {\n this.loadedScope = scope;\n this.loaded = true;\n try {\n const data = {\n nodes: [...this.nodes.entries()],\n edges: this.edges,\n };\n await fs.mkdir(\n this.graphFile.substring(0, this.graphFile.lastIndexOf('/')),\n { recursive: true },\n );\n // Atomic write via temp file\n const tmp = `${this.graphFile}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(data));\n await fs.rename(tmp, this.graphFile);\n } catch {\n // best-effort — graph is an enhancement, not critical\n }\n }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────\n\n/** Jaccard-style word overlap between two strings. 0.0 = no overlap, 1.0 = identical. */\nfunction wordOverlap(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n if (wordsA.size === 0 || wordsB.size === 0) return 0;\n let intersection = 0;\n for (const w of wordsA) {\n if (wordsB.has(w)) intersection++;\n }\n return intersection / Math.max(wordsA.size, wordsB.size);\n}\n\n/** Tag overlap ratio — how many tags two nodes share. */\nfunction sharedTags(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const setB = new Set(b);\n let shared = 0;\n for (const t of a) if (setB.has(t)) shared++;\n return shared / Math.max(a.length, b.length);\n}\n\n/** Fast non-crypto hash for stable node IDs. */\nfunction simpleHash(s: string): string {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h).toString(36);\n}\n","import type { RunResult } from '../core/agent-types.js';\nimport type { Context } from '../core/context.js';\nimport type { AfterRunHook, AgentExtension } from '../extension/extension-points.js';\nimport type { MemoryEntry, MemoryStore } from '../types/memory.js';\nimport type { Provider } from '../types/provider.js';\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport interface ConsolidationOp {\n action: 'add' | 'edit' | 'delete';\n /** For add: the fact to remember. For edit: the new text replacing the old. */\n text?: string | undefined;\n /** For edit/delete: the query to match existing entries. */\n query?: string | undefined;\n /** Memory type for categorization. */\n type?: string | undefined;\n /** Tags for grouping. */\n tags?: string[] | undefined;\n /** Priority level. */\n priority?: string | undefined;\n}\n\ninterface ConsolidationResponse {\n operations: ConsolidationOp[];\n summary?: string | undefined;\n}\n\nexport interface MemoryConsolidatorOptions {\n memoryStore: MemoryStore;\n /**\n * Provider used for the consolidation LLM call. Uses the session's\n * provider by default.\n */\n provider?: Provider | undefined;\n /**\n * Model override for the consolidation call. Uses the session's model\n * by default. A smaller/faster model is recommended (e.g. haiku, flash).\n */\n model?: string | undefined;\n /**\n * Minimum session iterations before consolidation fires.\n * Sessions shorter than this are skipped (default 2).\n */\n minIterations?: number | undefined;\n /**\n * Maximum memory entries to include in the prompt as context.\n */\n maxExistingEntries?: number | undefined;\n}\n\n// ── Prompt ──────────────────────────────────────────────────────────────\n\nfunction buildConsolidationPrompt(\n finalText: string,\n iterations: number,\n existingEntries: MemoryEntry[],\n): string {\n const existingBlock =\n existingEntries.length > 0\n ? `\\n\\nExisting memory entries:\\n${existingEntries\n .map((e) => `- [${e.ts.slice(0, 10)}] ${e.text}`)\n .join('\\n')}`\n : '';\n\n return `You are a memory consolidator. Review the following session summary and decide what key facts, conventions, decisions, or learnings should be persisted to long-term memory.\n\nSession summary (${iterations} iterations):\n${finalText.slice(0, 3000)}${existingBlock}\n\nReturn a JSON object with an \"operations\" array. Each operation must have an \"action\" field:\n- \"add\": create a new memory entry. Include \"text\", and optionally \"type\", \"tags\", \"priority\".\n- \"edit\": replace an existing entry. Include \"query\" (to match) and \"text\" (replacement).\n- \"delete\": remove an entry. Include \"query\" (to match).\n\nMemory types:\n- \"fact\": Objective truth about the project (e.g. \"uses pnpm workspaces\")\n- \"decision\": A choice that was made (e.g. \"decided to use biome over eslint\")\n- \"convention\": A recurring pattern or standard (e.g. \"commit messages use conventional format\")\n- \"preference\": User or team preference (e.g. \"prefers short variable names\")\n- \"reference\": Pointer to a file or location (e.g. \"auth logic in packages/core/src/auth/\")\n- \"anti_pattern\": Something to avoid (e.g. \"never use any in TypeScript\")\n\nPriority levels:\n- \"critical\": Must always be known (e.g. security constraints)\n- \"high\": Important for most tasks\n- \"medium\": Useful context\n- \"low\": Nice to know\n\nRules:\n- Only persist facts likely useful across multiple future sessions.\n- Do NOT persist task progress, temporary state, or one-off observations.\n- Prefer \"add\" over \"edit\" unless the existing entry is clearly outdated.\n- Assign a type and priority to every \"add\" operation.\n- Use 1-3 hashtag tags for each entry (e.g. #typescript #build).\n- Be concise — each memory entry should be one clear sentence.\n\nReturn ONLY valid JSON, no markdown, no explanation:\n{\n \"operations\": [\n { \n \"action\": \"add\", \n \"text\": \"Project uses pnpm workspaces with TypeScript strict mode\",\n \"type\": \"convention\",\n \"priority\": \"high\",\n \"tags\": [\"pnpm\", \"typescript\", \"build\"]\n },\n { \n \"action\": \"edit\", \n \"query\": \"pnpm\", \n \"text\": \"Project uses pnpm v9+ with ESM-only modules\",\n \"type\": \"fact\",\n \"priority\": \"medium\"\n },\n { \"action\": \"delete\", \"query\": \"outdated convention\" }\n ]\n}`;\n}\n\n// ── Consolidator ────────────────────────────────────────────────────────\n\nexport class SessionMemoryConsolidator implements AgentExtension {\n name = 'session-memory-consolidator';\n owner = 'core';\n\n private readonly memoryStore: MemoryStore;\n private readonly provider?: Provider | undefined;\n private readonly model?: string | undefined;\n private readonly minIterations: number;\n private readonly maxExistingEntries: number;\n\n constructor(opts: MemoryConsolidatorOptions) {\n this.memoryStore = opts.memoryStore;\n this.provider = opts.provider;\n this.model = opts.model;\n this.minIterations = opts.minIterations ?? 2;\n this.maxExistingEntries = opts.maxExistingEntries ?? 15;\n }\n\n afterRun: AfterRunHook = async (ctx: Context, result: RunResult) => {\n // Only consolidate successful sessions with meaningful output\n if (result.status !== 'done') return;\n if (!result.finalText || result.finalText.trim().length < 20) return;\n if (result.iterations < this.minIterations) return;\n\n const provider = this.provider ?? ctx.provider;\n if (!provider || !provider.complete) return;\n\n try {\n // Load existing memory for dedup context\n const existingEntries = await this.memoryStore.list('project-memory', this.maxExistingEntries);\n const prompt = buildConsolidationPrompt(\n result.finalText,\n result.iterations,\n existingEntries,\n );\n\n // Call the LLM with a focused, one-shot prompt\n const signal = AbortSignal.timeout(15_000);\n const response = await provider.complete(\n {\n model: this.model ?? ctx.model,\n system: [{ type: 'text', text: prompt }],\n messages: [\n { role: 'user', content: 'Review the session and return memory operations as JSON.' },\n ],\n maxTokens: 500,\n },\n { signal },\n );\n\n const text = response.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n .trim();\n if (!text) return;\n\n // Extract JSON from possible markdown wrapper\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) return;\n\n const parsed: ConsolidationResponse = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(parsed.operations) || parsed.operations.length === 0) return;\n\n // Apply operations\n let added = 0;\n let edited = 0;\n let deleted = 0;\n\n for (const op of parsed.operations) {\n switch (op.action) {\n case 'add': {\n if (op.text?.trim()) {\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n added++;\n }\n break;\n }\n case 'edit': {\n if (op.query && op.text && op.text.trim()) {\n await this.memoryStore.forget(op.query);\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n edited++;\n }\n break;\n }\n case 'delete': {\n if (op.query) {\n const n = await this.memoryStore.forget(op.query);\n deleted += n;\n }\n break;\n }\n }\n }\n\n if (added > 0 || edited > 0 || deleted > 0) {\n const parts: string[] = [];\n if (added) parts.push(`${added} added`);\n if (edited) parts.push(`${edited} edited`);\n if (deleted) parts.push(`${deleted} deleted`);\n // Log to stderr so it surfaces in the terminal\n process.stderr.write(`[memory] Session consolidation: ${parts.join(', ')}\\n`);\n }\n } catch {\n // Silent — memory consolidation is best-effort, never blocks session cleanup\n }\n };\n}\n","/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = err instanceof Error ? err.message : String(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { Config, ConfigStore } from '../types/config.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\n\n\n/**\n * Strip fields that originated from environment variables so they are never\n * persisted back to disk. This prevents an env-sourced secret (e.g.\n * WRONGSTACK_API_KEY) from being accidentally written to ~/.wrongstack/config.json.\n */\nfunction stripEphemeralFields(cfg: Partial<Config>): Partial<Config> {\n const env = (cfg as Partial<Config & { _envSource?: Set<string> | undefined}>)._envSource;\n if (!env?.size) return cfg;\n const out: Partial<Config> = { ...cfg };\n for (const field of env) {\n delete (out as Record<string, unknown>)[field];\n }\n delete (out as Record<string, unknown>)._envSource;\n return out;\n}\n\n/**\n * Reference implementation of `ConfigStore`. Stores a single frozen Config\n * and notifies watchers synchronously on every update. Updates use a deep\n * clone so callers can mutate their `partial` argument freely without\n * tainting state.\n *\n * For the CLI: instantiate once at boot, pass the store (not the Config)\n * to subsystems that care about runtime changes (provider switching,\n * extension reload).\n */\nexport class DefaultConfigStore implements ConfigStore {\n private current: Readonly<Config>;\n private watchers = new Set<(next: Readonly<Config>, prev: Readonly<Config>) => void>();\n\n constructor(initial: Config) {\n this.current = deepFreeze(structuredClone(initial));\n }\n\n get(): Readonly<Config> {\n return this.current;\n }\n\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]> {\n return this.current[key] as Readonly<Config[K]>;\n }\n\n getExtension(pluginName: string): Readonly<Record<string, unknown>> {\n const ext = this.current.extensions?.[pluginName];\n return ext ? (ext as Readonly<Record<string, unknown>>) : FROZEN_EMPTY;\n }\n\n update(partial: Partial<Config>): Readonly<Config> {\n // Strip env-sourced fields before persisting to prevent secrets leaking\n // from in-memory env-derived config values into the on-disk config file.\n const scrubbed = stripEphemeralFields(partial);\n // Shallow merge — top-level fields replace, nested objects do too unless\n // the caller passes a fully-formed sub-object. That matches the JSON\n // config user mental model (replace `tools.maxIterations` by passing\n // the whole `tools` block, or by patching `extensions.<name>`).\n const next = deepFreeze(structuredClone({ ...this.current, ...scrubbed })) as Readonly<Config>;\n\n if (next.version !== 1) {\n throw new ConfigError({\n message: `ConfigStore.update: version must remain 1, got ${String(next.version)}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: next.version },\n });\n }\n\n const prev = this.current;\n this.current = next;\n // Notify watchers AFTER mutating `current` so re-entrant watcher reads\n // see the new state. Watcher exceptions are caught individually so one\n // misbehaving subscriber can't block the others.\n for (const w of this.watchers) {\n try {\n w(next, prev);\n } catch (err) {\n // A plugin watcher that crashes on /model switch or similar would\n // otherwise leave the system in a quietly-inconsistent state. We\n // still don't propagate (one bad subscriber must not break the\n // others), but we surface the error so it's discoverable.\n console.error(JSON.stringify({\n level: 'error',\n event: 'config_store.watcher_threw',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n return next;\n }\n\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void {\n this.watchers.add(cb);\n return () => this.watchers.delete(cb);\n }\n}\n\nconst FROZEN_EMPTY: Readonly<Record<string, unknown>> = Object.freeze({});\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') return obj;\n if (Object.isFrozen(obj)) return obj;\n for (const key of Object.keys(obj as object)) {\n const v = (obj as Record<string, unknown>)[key];\n if (v !== null && typeof v === 'object' && !Object.isFrozen(v)) {\n deepFreeze(v);\n }\n }\n return Object.freeze(obj);\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { ENCRYPTED_PREFIX } from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n */\nexport class DefaultSecretVault implements SecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && value.startsWith(ENCRYPTED_PREFIX);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n return `${ENCRYPTED_PREFIX}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n const rest = value.slice(ENCRYPTED_PREFIX.length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length !== KEY_BYTES) {\n // A wrong-size key is not ENOENT — the file is corrupted or was\n // tampered with. Throwing instead of falling through to create a\n // new key protects all secrets encrypted under this key; the user\n // can remove the file manually to generate a fresh key.\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = buf;\n // Warn if the key file has wrong permissions (defense-in-depth).\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length !== KEY_BYTES) {\n // A wrong-size key is not ENOENT — the file is corrupted or was\n // tampered with. Throwing instead of falling through to create a\n // new key protects all secrets encrypted under this key; the user\n // can remove the file manually to generate a fresh key.\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = buf;\n // Warn if the key file has wrong permissions (defense-in-depth).\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n this.key = key;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","export interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n autoExtendLimit: true,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","import * as fs from 'node:fs/promises';\nimport { decryptConfigSecrets } from '../security/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport {\n DEFAULT_CONTEXT_WINDOW_MODE_ID,\n isContextWindowModeId,\n listContextWindowModes,\n} from '../types/context-window.js';\nimport type { Config, ConfigLoader, SyncConfig } from '../types/config.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { deepMerge as deepMergeCore, type DeepMergeOptions } from '../utils/deep-merge.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport {\n DEFAULT_TOOLS_CONFIG,\n DEFAULT_CONTEXT_CONFIG,\n DEFAULT_SESSION_LOGGING_CONFIG,\n} from '../types/default-config.js';\n\n/**\n * Defaults express *behavior*, not identity. Provider and model are NOT\n * hardcoded — they must be resolved at runtime from config + env + the\n * ModelsRegistry. A bare Config returned by this loader will throw when\n * the agent tries to construct a provider, with a message that points\n * users at `wstack init`.\n */\nconst BEHAVIOR_DEFAULTS: Omit<Config, 'provider' | 'model'> = {\n version: 1,\n context: {\n mode: DEFAULT_CONTEXT_WINDOW_MODE_ID,\n warnThreshold: 0.6,\n softThreshold: 0.75,\n hardThreshold: 0.9,\n autoCompact: true,\n preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,\n eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold,\n },\n tools: {\n defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,\n maxIterations: DEFAULT_TOOLS_CONFIG.maxIterations,\n iterationTimeoutMs: DEFAULT_TOOLS_CONFIG.iterationTimeoutMs,\n sessionTimeoutMs: DEFAULT_TOOLS_CONFIG.sessionTimeoutMs,\n perIterationOutputCapBytes: DEFAULT_TOOLS_CONFIG.perIterationOutputCapBytes,\n autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit,\n },\n log: { level: 'info' },\n features: {\n mcp: true,\n plugins: true,\n memory: true,\n modelsRegistry: true,\n skills: true,\n },\n indexing: {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n },\n session: { ...DEFAULT_SESSION_LOGGING_CONFIG },\n};\n\n/** Parse a boolean-ish env var: \"0\"/\"false\"/\"no\"/\"off\" → false, anything else → true. */\nfunction envBool(v: string): boolean {\n return !/^(0|false|no|off)$/i.test(v.trim());\n}\n\nfunction envBoolOptional(v: string | undefined): boolean {\n return v !== undefined && envBool(v);\n}\n\nconst LOG_LEVELS = new Set<Config['log']['level']>(['error', 'warn', 'info', 'debug', 'trace']);\n\nfunction envLogLevel(v: string): Config['log']['level'] {\n return LOG_LEVELS.has(v as Config['log']['level']) ? (v as Config['log']['level']) : 'info';\n}\n\nconst ENV_MAP: Record<string, (cfg: PartialConfig, val: string) => void> = {\n WRONGSTACK_PROVIDER: (c, v) => {\n c.provider = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('provider');\n },\n WRONGSTACK_MODEL: (c, v) => {\n c.model = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('model');\n },\n WRONGSTACK_API_KEY: (c, v) => {\n c.apiKey = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('apiKey');\n },\n WRONGSTACK_BASE_URL: (c, v) => {\n c.baseUrl = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('baseUrl');\n },\n WRONGSTACK_LOG_LEVEL: (c, v) => {\n if (!c.log) c.log = { level: 'info' };\n c.log.level = envLogLevel(v);\n },\n WRONGSTACK_INDEX_ON_START: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onSessionStart: envBool(v) };\n },\n WRONGSTACK_INDEX_ON_EDIT: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onEdit: envBool(v) };\n },\n WRONGSTACK_INDEX_WATCH: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, watchExternal: envBool(v) };\n },\n};\n\nconst defaultIndexing = {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n} as const;\n\ntype PartialConfig = Partial<Config> & {\n providers?: Record<\n string,\n { apiKey?: string | undefined; baseUrl?: string | undefined; type?: string | undefined }\n >;\n /** Fields that came from environment variables — must not be persisted. */\n _envSource?: Set<string> | undefined;\n};\n\n/**\n * Config-layer deep merge — delegates to the shared utility with\n * `arrayMode: 'concat-primitives'` and optional debug logging for\n * non-primitive array replacements.\n */\nfunction deepMerge<T>(base: T, patch: Partial<T>): T {\n const opts: DeepMergeOptions = { arrayMode: 'concat-primitives' };\n if (envBoolOptional(process.env.WRONGSTACK_DEBUG_CONFIG)) {\n opts.onNonPrimitiveArrayReplace = (key, existingLen, patchLen) => {\n console.warn(\n `[config] Non-primitive array for \"${key}\" replaced (global + local config merge). ` +\n `Global entries: ${existingLen}, local entries: ${patchLen}.`,\n );\n };\n }\n return deepMergeCore(base as Record<string, unknown>, patch as Record<string, unknown>, opts) as T;\n}\n\n/**\n * A single config source. Higher priority wins in merges.\n * Sources are applied in priority order (lowest first), so a source\n * with priority=10 overrides one with priority=1.\n */\nexport interface ConfigSource {\n /** Unique name for debugging and error messages. */\n name: string;\n /** Lower numbers merge first, higher numbers override lower. Default: 50. */\n priority?: number | undefined;\n /**\n * Read the raw config patch. Return an empty object if unavailable.\n * Errors are surfaced but do not abort loading — the source is skipped.\n */\n read(): Promise<Partial<Config>>;\n}\n\nexport interface ConfigLoaderOptions {\n paths: WstackPaths;\n strict?: boolean | undefined;\n vault?: SecretVault | undefined;\n /** Extra sources merged after the built-in layers. */\n sources?: ConfigSource[] | undefined;\n}\n\nexport class DefaultConfigLoader implements ConfigLoader {\n private readonly paths: WstackPaths;\n private readonly strict: boolean;\n private readonly vault: SecretVault | undefined;\n private readonly extraSources: ConfigSource[];\n\n constructor(opts: ConfigLoaderOptions) {\n this.paths = opts.paths;\n this.strict = opts.strict ?? false;\n this.vault = opts.vault;\n this.extraSources = opts.sources ?? [];\n }\n\n async load(\n opts: { cliFlags?: Partial<Config> | undefined; cwd?: string | undefined } = {},\n ): Promise<Config> {\n let cfg: PartialConfig = { ...BEHAVIOR_DEFAULTS } as PartialConfig;\n\n // Layer 2, 3 & 3b: global + project-local + in-project config — read in parallel.\n // inProjectConfig (<project>/.wrongstack/config.json) merges AFTER\n // projectLocalConfig so it takes priority (user-intended > auto-cached).\n const [global, local, inProject] = await Promise.all([\n this.readJson(this.paths.globalConfig),\n this.readJson(this.paths.projectLocalConfig),\n this.readJson(this.paths.inProjectConfig),\n ]);\n cfg = deepMerge(cfg, global);\n cfg = deepMerge(cfg, local);\n cfg = deepMerge(cfg, inProject);\n\n // Layer 4: env vars\n for (const [key, fn] of Object.entries(ENV_MAP)) {\n const v = process.env[key];\n if (v) fn(cfg, v);\n }\n\n // Layer 5: extra sources — sorted by priority (lowest first).\n // When priorities tie, sort by name for deterministic order.\n const sorted = [...this.extraSources].sort((a, b) => {\n const pd = (a.priority ?? 50) - (b.priority ?? 50);\n if (pd !== 0) return pd;\n return a.name.localeCompare(b.name);\n });\n for (const src of sorted) {\n try {\n const patch = await src.read();\n if (patch && Object.keys(patch).length > 0) {\n cfg = deepMerge(cfg, patch);\n }\n } catch (err) {\n // Best-effort: skip failing sources so one bad source doesn't block boot.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.source_load_failed',\n source: src.name,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n // Layer 6: CLI flags\n if (opts.cliFlags) {\n cfg = deepMerge(cfg, opts.cliFlags);\n }\n\n // Decrypt apiKey-like fields if a vault is configured.\n if (this.vault) {\n cfg = decryptConfigSecrets(cfg, this.vault);\n }\n\n // Multi-key resolution: when a provider has `apiKeys[]` configured,\n // mirror the active entry into `apiKey` so downstream construction\n // code (provider registry, wire adapters) needs no changes. Honors\n // `activeKey` (by label), else falls back to the first entry. A\n // pre-existing `apiKey` set by env/CLI flags wins so an explicit\n // override still beats the saved list.\n if (cfg.providers) {\n for (const pcfg of Object.values(cfg.providers)) {\n if (!pcfg || typeof pcfg !== 'object') continue;\n const rawKeys = (pcfg as { apiKeys?: unknown | undefined }).apiKeys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) continue;\n // Each apiKeys entry came from arbitrary JSON. Filter to entries\n // that actually have a string apiKey + label so a malformed array\n // (null entry, missing field) doesn't crash the .find / chosen.apiKey\n // path below.\n const keys = rawKeys.filter(\n (k): k is { label: string; apiKey: string } =>\n !!k &&\n typeof k === 'object' &&\n typeof (k as { label?: unknown | undefined }).label === 'string' &&\n typeof (k as { apiKey?: unknown | undefined }).apiKey === 'string',\n );\n if (keys.length === 0) continue;\n const existing = (pcfg as { apiKey?: string | undefined }).apiKey;\n if (existing && existing.length > 0) continue;\n const activeLabel = (pcfg as { activeKey?: string | undefined }).activeKey;\n const chosen = activeLabel\n ? (keys.find((k) => k.label === activeLabel) ?? keys[0])\n : keys[0];\n if (chosen?.apiKey) {\n (pcfg as { apiKey?: string | undefined }).apiKey = chosen.apiKey;\n }\n }\n }\n\n this.validateBehavior(cfg);\n if (this.strict) {\n this.validateIdentity(cfg);\n }\n // In strict mode, validateIdentity has confirmed provider/model are set;\n // it's safe to assert the full Config contract. In non-strict mode the\n // caller (e.g. early-boot wizard) accepts a Partial and constructs the\n // provider later, so we deliberately return without the cast.\n return Object.freeze(cfg) as Config;\n }\n\n /**\n * Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted\n * by the vault (if provided). The file is isolated from the main config\n * hierarchy to prevent accidental commits.\n */\n async persistSyncConfig(cfg: SyncConfig): Promise<void> {\n let toWrite = { ...cfg };\n if (this.vault && toWrite.githubToken && !toWrite.githubToken.startsWith('enc:')) {\n // Re-encrypt if plaintext (e.g. came from in-memory configStore update\n // rather than direct /sync enable call). Idempotent for already-encrypted.\n toWrite = { ...toWrite, githubToken: this.vault.encrypt(toWrite.githubToken) };\n }\n await atomicWrite(this.paths.syncConfig, JSON.stringify(toWrite, null, 2), { mode: 0o600 });\n }\n\n /**\n * Read ~/.wrongstack/sync.json (encrypted GitHub token storage) and decrypt\n * the token if a vault is available. Returns null if the file doesn't exist.\n * This is separate from main config loading because sync.json is intentionally\n * isolated — it should never be part of project-local or env-driven config.\n */\n async loadSyncConfig(): Promise<SyncConfig | null> {\n try {\n const raw = await fs.readFile(this.paths.syncConfig, 'utf8');\n const parsed = safeParse<SyncConfig>(raw);\n if (!parsed.ok || !parsed.value) return null;\n\n // Decrypt the token if vault is available (field name matches secret pattern)\n if (this.vault) {\n const decrypted = decryptConfigSecrets({ sync: parsed.value } as PartialConfig, this.vault);\n return (decrypted as { sync: SyncConfig }).sync ?? null;\n }\n return parsed.value;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.sync_load_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n }\n\n private async readJson(file: string): Promise<PartialConfig> {\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n // Missing file is the common case (per-project local config rarely\n // exists at start). Surface anything else (EACCES, EISDIR) so a\n // mis-permissioned config doesn't silently fall back to defaults.\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.read_failed',\n path: file,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return {};\n }\n const parsed = safeParse<PartialConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n // The file exists but isn't valid JSON. Don't silently reset to\n // defaults — that's hours of debug timesink for users who'd typo'd\n // their config. Warn loudly and keep the in-memory defaults.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.parse_failed',\n path: file,\n message: 'invalid JSON — falling back to defaults for this layer',\n timestamp: new Date().toISOString(),\n }));\n return {};\n }\n return parsed.value;\n }\n\n private validateBehavior(cfg: PartialConfig): void {\n if (cfg.version === undefined) throw new ConfigError({\n message: 'Config: missing version field',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version' },\n });\n if (cfg.version !== 1) throw new ConfigError({\n message: `Config: unsupported version ${cfg.version}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: cfg.version },\n });\n const c = cfg.context;\n if (!c) throw new ConfigError({\n message: 'Config: missing context section',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'context' },\n });\n // A user-edited config.json can land strings here (\"0.6\") and slip past\n // truthiness checks; the `>=` comparison then coerces silently and the\n // threshold ordering check passes for nonsense values. Validate types\n // explicitly so misconfigs surface here, not as confusing failures deep\n // in the auto-compaction logic.\n const fields: Array<keyof typeof c> = ['warnThreshold', 'softThreshold', 'hardThreshold'];\n for (const f of fields) {\n const v = c[f];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n throw new ConfigError({\n message: `Config: context.${String(f)} must be a finite number (got ${typeof v})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: `context.${String(f)}`, actualType: typeof v },\n });\n }\n }\n if (c.warnThreshold >= c.softThreshold || c.softThreshold >= c.hardThreshold) {\n throw new ConfigError({\n message: 'Config: context thresholds must satisfy warn < soft < hard',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { warn: c.warnThreshold, soft: c.softThreshold, hard: c.hardThreshold },\n });\n }\n if (c.mode !== undefined && !isContextWindowModeId(c.mode)) {\n // An unknown mode (typo or value from an older/renamed scheme) should not\n // brick the CLI — unlike the numeric thresholds above there is a safe\n // default. Warn and fall back rather than throwing.\n const known = listContextWindowModes()\n .map((m) => m.id)\n .join(', ');\n console.warn(\n `[config] Ignoring unknown context.mode \"${c.mode}\" (expected one of: ${known}); ` +\n `falling back to \"${DEFAULT_CONTEXT_WINDOW_MODE_ID}\".`,\n );\n c.mode = DEFAULT_CONTEXT_WINDOW_MODE_ID;\n }\n }\n\n private validateIdentity(cfg: PartialConfig): void {\n if (!cfg.provider) {\n throw new ConfigError({\n message: 'Config: no provider configured. Run `wstack init` or set WRONGSTACK_PROVIDER.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'provider' },\n });\n }\n if (!cfg.model) {\n throw new ConfigError({\n message: 'Config: no model configured. Run `wstack init` or set WRONGSTACK_MODEL.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'model' },\n });\n }\n }\n}\n","/**\n * L2-D: Config version migration framework. Pure functions, decoupled\n * from disk/CLI — caller passes a parsed JSON object and gets back the\n * up-to-date `Config` shape (or a structured error explaining why\n * migration failed).\n *\n * Migrations are registered as `{ from, to, migrate }` triples and run\n * sequentially. Each migration is independently testable. Adding a new\n * version means appending one migration; existing user configs are\n * upgraded in place at load time.\n */\n\nexport interface MigrationContext {\n /**\n * Original on-disk version of the input. Migrations may use this to\n * decide between in-place patches and rewrites.\n */\n fromVersion: number;\n /**\n * Set when the migration writes back to disk. Callers persist the\n * migrated config when this is true so the user doesn't see the same\n * migration banner on every boot.\n */\n shouldPersist: boolean;\n}\n\nexport interface ConfigMigration {\n /** Version of the input this migration accepts. */\n from: number;\n /** Version of the output it produces. */\n to: number;\n /** Pure transform — no I/O. */\n migrate(input: Record<string, unknown>, ctx: MigrationContext): Record<string, unknown>;\n /** Optional human-readable description for migration logs / banners. */\n describe?: string | undefined;\n}\n\nexport interface MigrationResult {\n /** Final config (still typed as `unknown`-keyed — caller validates). */\n config: Record<string, unknown>;\n /** Ordered list of `from→to` versions that ran. */\n applied: string[];\n /** True when at least one migration produced changes worth persisting. */\n shouldPersist: boolean;\n}\n\nexport class ConfigMigrationError extends Error {\n readonly fromVersion: number;\n readonly targetVersion: number;\n readonly missingStep: number | null;\n\n constructor(opts: {\n message: string;\n fromVersion: number;\n targetVersion: number;\n missingStep: number | null;\n }) {\n super(opts.message);\n this.name = 'ConfigMigrationError';\n this.fromVersion = opts.fromVersion;\n this.targetVersion = opts.targetVersion;\n this.missingStep = opts.missingStep;\n }\n}\n\n/**\n * Run registered migrations until the input reaches `targetVersion`.\n *\n * Resolution rules:\n * 1. If `input.version === targetVersion`, no migrations run; `shouldPersist`\n * is false.\n * 2. Otherwise walk the migration chain from `input.version` upward,\n * picking the migration whose `from` matches the current version.\n * 3. Stop when `current.version === targetVersion`.\n * 4. If no migration matches at some point, throw `ConfigMigrationError`\n * with the missing step recorded for diagnostics.\n *\n * Migrations may be downward (e.g. for staged rollouts), but `targetVersion`\n * must be reachable strictly via the registered chain — there's no implicit\n * \"skip\" or transitive resolution.\n */\nexport function runConfigMigrations(\n input: Record<string, unknown>,\n targetVersion: number,\n migrations: readonly ConfigMigration[],\n): MigrationResult {\n const initial = typeof input['version'] === 'number' ? (input['version'] as number) : 1;\n let current: Record<string, unknown> = { ...input };\n let currentVersion = initial;\n const applied: string[] = [];\n let shouldPersist = false;\n\n let guard = 0;\n while (currentVersion !== targetVersion) {\n if (++guard > 100) {\n throw new ConfigMigrationError({\n message: `Config migration looped past 100 steps (from v${initial} toward v${targetVersion})`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const step = migrations.find((m) => m.from === currentVersion);\n if (!step) {\n throw new ConfigMigrationError({\n message: `No migration registered from config v${currentVersion} (target v${targetVersion}). Update the framework or revert the config file.`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const ctx: MigrationContext = { fromVersion: currentVersion, shouldPersist: false };\n const next = step.migrate(current, ctx);\n // Ensure the migration set the new version. Be tolerant: if it didn't,\n // patch it in so the chain doesn't infinite-loop on author oversight.\n if (typeof next['version'] !== 'number' || next['version'] !== step.to) {\n next['version'] = step.to;\n }\n current = next;\n currentVersion = step.to;\n applied.push(`v${step.from}→v${step.to}`);\n shouldPersist = shouldPersist || ctx.shouldPersist || step.from < step.to;\n }\n return { config: current, applied, shouldPersist };\n}\n\n/**\n * Default empty migration registry. Real migrations are appended as new\n * Config versions are introduced. Example (when v2 lands):\n *\n * export const CONFIG_MIGRATIONS: readonly ConfigMigration[] = [\n * {\n * from: 1, to: 2, describe: 'rename `apiKey` → `auth.apiKey`',\n * migrate(cfg) {\n * const apiKey = cfg.apiKey;\n * delete cfg.apiKey;\n * return { ...cfg, auth: { ...(cfg.auth ?? {}), apiKey } };\n * },\n * },\n * ];\n */\nexport const DEFAULT_CONFIG_MIGRATIONS: readonly ConfigMigration[] = [];\n","import * as fsp from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SessionStore } from '../types/session.js';\nimport { ensureDir } from '../utils/atomic-write.js';\n\n/**\n * Per-project lockfile used for crash detection. The CLI writes one of\n * these alongside the session JSONLs (`<projectSessions>/active.json`)\n * when an interactive run starts, and deletes it on clean exit. If we\n * find one on the next launch whose owning PID is dead (or whose host\n * doesn't match), we know the previous run was killed mid-flight and\n * the session it was writing to is a recovery candidate.\n *\n * The lockfile is intentionally per-project (already isolated by\n * `wpaths.projectSessions`), so two TUIs in two different repos do not\n * fight each other.\n */\nexport interface RecoveryLockOptions {\n /** Directory the lockfile lives in. Usually `wpaths.projectSessions`. */\n dir: string;\n /** This process's PID. Default: `process.pid`. */\n pid?: number | undefined;\n /** Hostname recorded for the lock. Default: `os.hostname()`. */\n hostname?: string | undefined;\n /** Locks older than this are considered orphaned (disk wiped, etc.). Default 24h. */\n maxAgeMs?: number | undefined;\n /** Used to check whether the abandoned session was actually closed cleanly. */\n sessionStore?: SessionStore | undefined;\n /**\n * Override the PID-liveness probe. Default: `process.kill(pid, 0)` —\n * succeeds (or throws EPERM) when the PID is alive, throws ESRCH when\n * it is gone. Tests inject a deterministic stub.\n */\n isPidAlive?: (((pid: number) => boolean)) | undefined;\n}\n\nexport interface AbandonedSession {\n sessionId: string;\n pid: number;\n startedAt: string;\n /** Lockfile age in ms at the time of the check. */\n ageMs: number;\n /** Number of messages already on disk for this session. */\n messageCount: number;\n}\n\ninterface LockFile {\n v: 1;\n sessionId: string;\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\nconst LOCK_FILE = 'active.json';\nconst DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport class RecoveryLock {\n private readonly file: string;\n private readonly pid: number;\n private readonly hostname: string;\n private readonly maxAgeMs: number;\n private readonly sessionStore?: SessionStore | undefined;\n private readonly probe: (pid: number) => boolean;\n\n constructor(opts: RecoveryLockOptions) {\n this.file = path.join(opts.dir, LOCK_FILE);\n this.pid = opts.pid ?? process.pid;\n this.hostname = opts.hostname ?? os.hostname();\n this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n this.sessionStore = opts.sessionStore;\n this.probe = opts.isPidAlive ?? defaultIsPidAlive;\n }\n\n /**\n * Examine the lockfile and decide whether it represents an abandoned\n * session. Returns `null` if the file is missing, points to a live\n * instance, references a clean-closed session, is too old, or is\n * malformed. Otherwise returns enough detail to prompt the user.\n *\n * Important: this is a read-only check. We never delete an active\n * lock from here — if another wstack instance is alive, the caller\n * should bail or run with a fresh session instead.\n */\n async checkAbandoned(): Promise<AbandonedSession | null> {\n const lock = await this.readLock();\n if (!lock) return null;\n\n const ageMs = Date.now() - new Date(lock.startedAt).getTime();\n if (Number.isNaN(ageMs) || ageMs < 0) {\n // Clock skew or corrupted timestamp — treat as orphan.\n return null;\n }\n if (ageMs > this.maxAgeMs) return null;\n\n // PID liveness only meaningful on the same host. Different host\n // means we can't probe — assume abandoned (the other machine's\n // wstack can't be holding *our* sessions dir unless it was\n // shared via network mount, in which case the user is on their\n // own).\n if (lock.hostname === this.hostname && this.probe(lock.pid)) {\n // Another wstack on this box is actively writing here.\n return null;\n }\n\n let messageCount = 0;\n if (this.sessionStore) {\n try {\n const data = await this.sessionStore.load(lock.sessionId);\n // Closed means the LAST session_end is not followed by further\n // conversation activity. Legacy /save wrote mid-stream session_end\n // markers — `some()` would treat a session that crashed AFTER such a\n // marker as cleanly closed and silently skip recovery.\n const lastEnd = data.events.findLastIndex((e) => e.type === 'session_end');\n const closed =\n lastEnd >= 0 &&\n !data.events\n .slice(lastEnd + 1)\n .some(\n (e) =>\n e.type === 'user_input' ||\n e.type === 'llm_response' ||\n e.type === 'in_flight_start',\n );\n if (closed) return null;\n messageCount = data.messages.length;\n } catch {\n // Lock points to a session that doesn't exist on disk (deleted\n // out from under us). Nothing to recover.\n return null;\n }\n }\n\n return {\n sessionId: lock.sessionId,\n pid: lock.pid,\n startedAt: lock.startedAt,\n ageMs,\n messageCount,\n };\n }\n\n /**\n * Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)\n * to detect whether another process acquired the lock between our\n * `checkAbandoned()` call and now. If the file already exists, it means\n * another process won the race and we throw instead of silently\n * overwriting their recovery record.\n *\n * The caller MUST have already called `checkAbandoned()` and handled its\n * null return before calling this.\n */\n async write(sessionId: string): Promise<void> {\n await ensureDir(path.dirname(this.file));\n const lock: LockFile = {\n v: 1,\n sessionId,\n pid: this.pid,\n hostname: this.hostname,\n startedAt: new Date().toISOString(),\n };\n // O_EXCL: atomic create — fails with EEXIST if another process wrote\n // the file between our checkAbandoned() and this write. This prevents\n // two processes that scanned the same stale lock from both believing\n // they hold it. The atomicWrite approach (temp+rename) would silently\n // replace on POSIX, hiding the race.\n try {\n await fsp.writeFile(this.file, JSON.stringify(lock), { flag: 'wx', mode: 0o600 });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') {\n throw new Error(`Recovery lock already held by another process`);\n }\n throw err;\n }\n }\n\n /**\n * Release the lock. Idempotent — silently succeeds if the file is\n * already gone (e.g. someone else cleared it, or the directory was\n * wiped).\n */\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n throw err;\n }\n }\n\n private async readLock(): Promise<LockFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null;\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isLockFile(parsed)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n}\n\nfunction isLockFile(v: unknown): v is LockFile {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return (\n o['v'] === 1 &&\n typeof o['sessionId'] === 'string' &&\n typeof o['pid'] === 'number' &&\n typeof o['hostname'] === 'string' &&\n typeof o['startedAt'] === 'string'\n );\n}\n\n/**\n * Probe whether a process is alive without sending it a real signal.\n *\n * Unix: `process.kill(pid, 0)` succeeds for our own processes, throws\n * EPERM for others (still alive, just not ours), and throws ESRCH\n * when the PID is gone.\n * Windows (Node 22+): same call returns true if the process exists,\n * throws otherwise.\n */\nfunction defaultIsPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EPERM') return true; // alive, but owned by someone else\n return false;\n }\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport type { ContentBlock } from '../types/blocks.js';\r\nimport type {\r\n DefaultSessionReaderOptions,\r\n SessionExportOptions,\r\n SessionQuery,\r\n SessionReader,\r\n SessionSearchHit,\r\n SessionSearchQuery,\r\n SessionSummaryLite,\r\n} from '../types/session-reader.js';\r\nimport { compileUserRegex } from '../utils/regex-guard.js';\r\nimport type { SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\r\n\r\n/**\r\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\r\n * and export helpers. Implemented on top of the public `SessionStore`\r\n * surface so any concrete store can be inspected without re-implementation.\r\n *\r\n * The heavy operations re-parse the JSONL stream on every call — fine for\r\n * /resume and one-off analytics. Wrap with a memoizing decorator if needed.\r\n */\r\nexport class DefaultSessionReader implements SessionReader {\r\n private readonly store: SessionStore;\r\n\r\n constructor(opts: DefaultSessionReaderOptions) {\r\n this.store = opts.store;\r\n }\r\n\r\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\r\n const raw = await this.store.list(q.limit ? Math.max(q.limit * 4, 100) : 1000);\r\n const titleNeedle = q.titleContains?.toLowerCase();\r\n const filtered = raw.filter((s) => {\r\n if (q.since && s.startedAt < q.since) return false;\r\n if (q.until && s.startedAt > q.until) return false;\r\n if (q.provider && s.provider !== q.provider) return false;\r\n if (q.model && s.model !== q.model) return false;\r\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n const out: SessionSummaryLite[] = filtered.map((s) => ({\r\n id: s.id,\r\n title: s.title,\r\n startedAt: s.startedAt,\r\n provider: s.provider,\r\n model: s.model,\r\n tokenTotal: s.tokenTotal,\r\n }));\r\n return q.limit ? out.slice(0, q.limit) : out;\r\n }\r\n\r\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\r\n const data = await this.store.load(sessionId);\r\n for (const e of data.events) yield e;\r\n }\r\n\r\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\r\n const limit = q.limit ?? 100;\r\n const matcher = buildMatcher(q);\r\n const allowedTypes = q.types ? new Set(q.types) : null;\r\n\r\n // Filter sessions BEFORE loading events — avoids loading thousands of events\r\n // from sessions that don't match the time/provider/model criteria.\r\n let ids: string[];\r\n if (sessionId) {\r\n ids = [sessionId];\r\n } else {\r\n const sessions = await this.store.list(1000);\r\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\r\n const filtered = sessions.filter((s) => {\r\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\r\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\r\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\r\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\r\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n ids = filtered.map((s) => s.id);\r\n }\r\n\r\n const hits: SessionSearchHit[] = [];\r\n for (const id of ids) {\r\n let data;\r\n try {\r\n data = await this.store.load(id);\r\n } catch {\r\n continue;\r\n }\r\n for (let i = 0; i < data.events.length; i++) {\r\n const ev = expectDefined(data.events[i]);\r\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\r\n const text = eventText(ev);\r\n if (text === null) continue;\r\n const hit = matcher(text);\r\n if (!hit) continue;\r\n hits.push({\r\n sessionId: id,\r\n eventIndex: i,\r\n ts: ev.ts,\r\n type: ev.type,\r\n snippet: snippetOf(text, hit.start, hit.end),\r\n });\r\n if (hits.length >= limit) return hits;\r\n }\r\n }\r\n return hits;\r\n }\r\n\r\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\r\n const data = await this.store.load(sessionId);\r\n const includeTools = opts.includeTools ?? true;\r\n const includeDiagnostics = opts.includeDiagnostics ?? true;\r\n\r\n const filtered = data.events.filter((e) => {\r\n if (\r\n !includeTools &&\r\n (e.type === 'tool_use' ||\r\n e.type === 'tool_result' ||\r\n e.type === 'tool_call_start' ||\r\n e.type === 'tool_call_end')\r\n ) {\r\n return false;\r\n }\r\n if (\r\n !includeDiagnostics &&\r\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\r\n ) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n if (opts.format === 'json') {\r\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\r\n }\r\n if (opts.format === 'text') {\r\n return renderPlainText(data.metadata, filtered);\r\n }\r\n return renderMarkdown(data.metadata, filtered);\r\n }\r\n\r\n async metadata(sessionId: string): Promise<SessionMetadata> {\r\n const data = await this.store.load(sessionId);\r\n return data.metadata;\r\n }\r\n}\r\n\r\nfunction buildMatcher(\r\n q: SessionSearchQuery,\r\n): (text: string) => { start: number; end: number } | null {\r\n const ci = q.caseInsensitive ?? true;\r\n if (q.regex) {\r\n const flags = ci ? 'i' : '';\r\n const compiled = compileUserRegex(q.query, flags);\r\n if (!compiled.ok) {\r\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\r\n }\r\n const re = compiled.regex;\r\n return (text) => {\r\n const m = re.exec(text);\r\n return m ? { start: m.index, end: m.index + m[0].length } : null;\r\n };\r\n }\r\n const needle = ci ? q.query.toLowerCase() : q.query;\r\n return (text) => {\r\n const hay = ci ? text.toLowerCase() : text;\r\n const idx = hay.indexOf(needle);\r\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\r\n };\r\n}\r\n\r\nfunction eventText(e: SessionEvent): string | null {\r\n switch (e.type) {\r\n case 'user_input':\r\n return contentToString(e.content);\r\n case 'llm_response':\r\n return contentToString(e.content);\r\n case 'tool_use':\r\n return `${e.name} ${JSON.stringify(e.input)}`;\r\n case 'tool_result':\r\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\r\n case 'error':\r\n return `${e.phase}: ${e.message}`;\r\n case 'session_start':\r\n case 'session_resumed':\r\n return `${e.model}/${e.provider}`;\r\n case 'task_created':\r\n case 'task_completed':\r\n return e.title;\r\n case 'task_failed':\r\n return `${e.title}: ${e.error}`;\r\n case 'skill_activated':\r\n case 'skill_deactivated':\r\n return e.skillName;\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\nfunction contentToString(content: string | ContentBlock[]): string {\r\n if (typeof content === 'string') return content;\r\n return content\r\n .map((b) => {\r\n switch (b.type) {\r\n case 'text':\r\n return b.text;\r\n case 'tool_use':\r\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\r\n case 'tool_result':\r\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\r\n default:\r\n return '';\r\n }\r\n })\r\n .join('\\n');\r\n}\r\n\r\nconst SNIPPET_RADIUS = 60;\r\n\r\nfunction snippetOf(text: string, start: number, end: number): string {\r\n const from = Math.max(0, start - SNIPPET_RADIUS);\r\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\r\n const prefix = from > 0 ? '…' : '';\r\n const suffix = to < text.length ? '…' : '';\r\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\r\n}\r\n\r\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(`# Session ${meta.id}`);\r\n lines.push('');\r\n if (meta.model || meta.provider) {\r\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\r\n }\r\n lines.push(`- **Started:** ${meta.startedAt}`);\r\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input': {\r\n lines.push(`## User — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n }\r\n case 'llm_response': {\r\n lines.push(`## Assistant — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n if (e.stopReason && e.stopReason !== 'end_turn') {\r\n lines.push('');\r\n lines.push(`*stop: ${e.stopReason}*`);\r\n }\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_use': {\r\n lines.push(`### Tool call: \\`${e.name}\\``);\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify(e.input, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_result': {\r\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\r\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(body);\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'error': {\r\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\r\n lines.push('');\r\n break;\r\n }\r\n case 'compaction': {\r\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\r\n lines.push('');\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(\r\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\r\n );\r\n lines.push(''.padEnd(72, '-'));\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input':\r\n lines.push(`[${e.ts}] USER`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'llm_response':\r\n lines.push(`[${e.ts}] ASSISTANT`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'tool_use':\r\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\r\n break;\r\n case 'tool_result':\r\n lines.push(\r\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\r\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\r\n }`,\r\n );\r\n break;\r\n case 'error':\r\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/12-30-45Z_model_ab12\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\n/**\n * L2-B: AnnotationsStore — sidecar storage for collaboration annotations\n * (Phase 2 of idea #13 from IDEAS.md).\n *\n * Why a sidecar file, not the session JSONL?\n *\n * The session log is an event-sourced append-only journal\n * (`packages/core/src/types/session.ts` invariant: events are\n * append-only, with `truncateToCheckpoint` only as an explicit\n * rewind). Mixing in human-typed annotations would break that\n * invariant — the user's note about \"this rm looks dangerous\"\n * is not part of the agent's event history; it is meta-commentary\n * on the history.\n *\n * So we keep annotations in a sibling file: one JSON document per\n * session, at `<sessionDir>/<sessionId>.annotations.json`. The\n * shape is a simple versioned array, written atomically.\n *\n * Concurrency model:\n *\n * The store uses a per-session Promise chain to serialize writes.\n * Multiple annotators adding notes at the same time will queue,\n * not race. The atomic write itself is the second line of\n * defense (in case the chain is bypassed — e.g. two processes\n * pointing at the same dir).\n */\n\n/** Wire/storage shape for one annotation. */\nexport interface Annotation {\n /** Stable id (UUIDv4-ish). Referenced by resolve/delete. */\n id: string;\n /** Session this annotation belongs to. */\n sessionId: string;\n /** Index into the session event log the annotation refers to. */\n atEventIndex: number;\n /** Participant id of the annotator (matches WSCollabParticipantJoined.participantId). */\n authorId: string;\n /** Human-readable role label snapshot for display (e.g. \"annotator\"). */\n authorRole: 'annotator';\n /** The note itself. Trimmed, capped at `MAX_TEXT_LENGTH` on add. */\n text: string;\n /** ISO timestamp of creation. */\n createdAt: string;\n /** Resolved state. Annotations start unresolved. */\n resolved: boolean;\n /** ISO timestamp when resolved (if resolved). */\n resolvedAt?: string | undefined;\n /** Participant id of the resolver (if resolved). */\n resolvedBy?: string | undefined;\n}\n\ninterface AnnotationsFile {\n /** Bumped when the on-disk shape changes. v1 = initial release. */\n version: 1;\n annotations: Annotation[];\n}\n\n/** Bumped when the on-disk shape changes. Bump + migration on change. */\nconst FILE_VERSION = 1;\n/** Hard cap to keep a runaway annotator from writing megabytes. */\nconst MAX_TEXT_LENGTH = 2000;\n/** Hard cap on total annotations per session (oldest are evicted beyond this). */\nconst MAX_ANNOTATIONS = 1000;\n\nexport interface AnnotationsStoreOptions {\n /** Directory where `<sessionId>.annotations.json` files live. */\n dir: string;\n}\n\nexport class AnnotationsStore {\n private readonly dir: string;\n /** Per-session write queue. Created lazily on first add. */\n private readonly writeChains = new Map<string, Promise<void>>();\n\n constructor(opts: AnnotationsStoreOptions) {\n this.dir = opts.dir;\n }\n\n // ── Reads ──────────────────────────────────────────────────────────────\n\n /**\n * Return all annotations for `sessionId` in insertion order\n * (oldest first). Returns an empty array when no file exists\n * yet (the normal case for a fresh session).\n */\n async list(sessionId: string): Promise<Annotation[]> {\n const file = await this.readFile(sessionId);\n return file ? file.annotations : [];\n }\n\n /**\n * Convenience: only unresolved annotations, newest first — the\n * common UI rendering for \"what still needs attention?\".\n */\n async listOpen(sessionId: string): Promise<Annotation[]> {\n const all = await this.list(sessionId);\n return all.filter((a) => !a.resolved).reverse();\n }\n\n // ── Writes ─────────────────────────────────────────────────────────────\n\n /**\n * Add a new annotation. Returns the persisted record (with id\n * and timestamps filled in). Throws when `text` is empty or\n * exceeds `MAX_TEXT_LENGTH`.\n */\n async add(input: {\n sessionId: string;\n atEventIndex: number;\n authorId: string;\n text: string;\n }): Promise<Annotation> {\n const text = input.text.trim();\n if (text.length === 0) {\n throw new WrongStackError({\n message: 'Annotation text must be non-empty',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', sessionId: input.sessionId },\n });\n }\n if (text.length > MAX_TEXT_LENGTH) {\n throw new WrongStackError({\n message: `Annotation text exceeds ${MAX_TEXT_LENGTH} chars (got ${text.length})`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', maxLength: MAX_TEXT_LENGTH, actualLength: text.length },\n });\n }\n if (!Number.isInteger(input.atEventIndex) || input.atEventIndex < 0) {\n throw new WrongStackError({\n message: 'atEventIndex must be a non-negative integer',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'atEventIndex', value: input.atEventIndex },\n });\n }\n const annotation: Annotation = {\n id: randomUUID(),\n sessionId: input.sessionId,\n atEventIndex: input.atEventIndex,\n authorId: input.authorId,\n authorRole: 'annotator',\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n };\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const all = await this.list(input.sessionId);\n all.push(annotation);\n // Evict oldest if we crossed the cap. Resolved first, then oldest.\n if (all.length > MAX_ANNOTATIONS) {\n const sorted = all\n .map((a, i) => ({ a, i }))\n .sort((x, y) => {\n // resolved=false wins (keep unresolved); among same resolved state, oldest first.\n if (x.a.resolved !== y.a.resolved) return x.a.resolved ? 1 : -1;\n return x.a.createdAt.localeCompare(y.a.createdAt);\n });\n const evictCount = all.length - MAX_ANNOTATIONS;\n const toEvict = new Set(sorted.slice(0, evictCount).map((s) => s.a.id));\n const kept = all.filter((a) => !toEvict.has(a.id));\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: kept });\n } else {\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n }\n });\n });\n return annotation;\n }\n\n /**\n * Mark an annotation as resolved. Returns the updated record, or\n * `null` if no annotation with that id exists in this session.\n * Idempotent: resolving an already-resolved annotation refreshes\n * `resolvedAt` / `resolvedBy` to the latest call.\n */\n async resolve(input: {\n sessionId: string;\n annotationId: string;\n resolvedBy: string;\n }): Promise<Annotation | null> {\n let updated: Annotation | null = null;\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const all = await this.list(input.sessionId);\n const idx = all.findIndex((a) => a.id === input.annotationId);\n if (idx === -1) {\n updated = null;\n return;\n }\n const next: Annotation = {\n ...expectDefined(all[idx]),\n resolved: true,\n resolvedAt: new Date().toISOString(),\n resolvedBy: input.resolvedBy,\n };\n all[idx] = next;\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n updated = next;\n });\n });\n return updated;\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban here used to\n // throw for every modern session id, breaking annotations entirely.\n return sessionScopedPath(this.dir, sessionId, '.annotations.json');\n }\n\n private async readFile(sessionId: string): Promise<AnnotationsFile | null> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const parsed = JSON.parse(raw) as AnnotationsFile;\n if (parsed.version !== FILE_VERSION) {\n // Future-proof: migrations land here. For now, treat unknown\n // versions as an empty store — safer than crashing on a\n // downgrade.\n return { version: FILE_VERSION, annotations: [] };\n }\n return parsed;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Corrupt JSON or permission error: log via the silent-recovery\n // path (the store doesn't take a logger; callers observe via\n // list() returning [] for an unreadable file is acceptable for\n // Phase 2 — annotations are meta-data, losing them is not fatal).\n return { version: FILE_VERSION, annotations: [] };\n }\n }\n\n private async writeFile(sessionId: string, file: AnnotationsFile): Promise<void> {\n const fp = this.filePath(sessionId);\n await atomicWrite(fp, JSON.stringify(file, null, 2));\n }\n\n /**\n * Serialize writes per-sessionId. We chain promises instead of\n * using a Mutex class so the contract is obvious from the\n * call-site: `enqueue(sid, fn)` runs `fn` after every prior\n * enqueue for `sid` has settled.\n */\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Keep the chain intact even when `fn` throws; failures\n // shouldn't break subsequent writes.\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { createHash } from 'node:crypto';\nimport type { Request } from '../types/provider.js';\n\n/**\n * Idea #2 from IDEAS.md — Deterministic Replay.\n *\n * The hash function is the foundation of replay: given a `Request`,\n * produce a stable identifier so a recorded `Response` can be looked\n * up later when we want to \"re-run\" the same agent loop without\n * burning API credits.\n *\n * Stability rules:\n *\n * - All object keys are sorted recursively before stringification.\n * Without this, two semantically identical requests that differ\n * only in key insertion order would produce different hashes.\n * - We hash ONLY the fields that affect the response: `model`,\n * `system`, `messages`, `tools`, `maxTokens`, and the four\n * sampling knobs (`temperature`, `topP`, `stopSequences`,\n * `toolChoice`). Anything else on the `Request` (metadata,\n * future extensions) is ignored so replay stays forward-compat.\n * - We serialize to JSON. The `ContentBlock` and `Message` shapes\n * are pure data; this works as long as no `undefined` values\n * sneak in (those get dropped by `JSON.stringify`, which is\n * fine — the structural diff is what matters).\n *\n * The SHA-256 output is hex-encoded and prefixed with the algorithm\n * tag so a future migration to a different hash (e.g. blake3) is\n * trivial to detect.\n */\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function hashRequest(request: Request): string {\n // Pick only the fields that affect the response. See stability rules.\n const payload = {\n model: request.model,\n system: request.system,\n messages: request.messages,\n tools: request.tools,\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n topP: request.topP,\n stopSequences: request.stopSequences,\n toolChoice: request.toolChoice,\n };\n const json = stableStringify(payload);\n const digest = createHash('sha256').update(json, 'utf8').digest('hex');\n return `sha256:${digest}`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { hashRequest } from '../replay/hash.js';\nimport type { Request, Response } from '../types/provider.js';\nimport { safeParse } from '../utils/safe-json.js';\n\n/**\n * ReplayLogStore — sidecar store for deterministic-replay support\n * (idea #2 from IDEAS.md). One JSONL file per session, recording\n * every provider request/response pair so the same agent loop can\n * be re-run later with frozen API responses.\n *\n * Why a sidecar (not the session JSONL)?\n *\n * Same reason as `AnnotationsStore` — the session log is\n * event-sourced and append-only; a provider request payload can be\n * tens of kilobytes (especially with long conversation history),\n * and we want replay to be opt-in (recorded only when the user\n * runs with `--replay` or a future equivalent). Mixing it into\n * the event log would inflate every read for replay-irrelevant\n * paths.\n *\n * File layout: `<dir>/<sessionId>.replay.jsonl`, one entry per line.\n * Each entry: `{ hash, ts, request, response }`. The `hash` is\n * computed via `hashRequest` so lookups are O(1) by hash.\n *\n * Concurrency: per-session write queue (same pattern as\n * `AnnotationsStore`). Reads are lock-free; the write chain makes\n * the append + rehash sequence atomic.\n */\nexport interface ReplayEntry {\n hash: string;\n ts: string;\n request: Request;\n response: Response;\n}\n\nconst FILE_VERSION = 1;\n\n/** Default cap on the number of entries per session. */\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport interface ReplayLogStoreOptions {\n /** Directory where `<sessionId>.replay.jsonl` files live. */\n dir: string;\n /**\n * Cap on the number of entries per session. When a `record` would\n * push the file beyond this, the oldest entries are evicted (LRU\n * by insertion order). Set to `Infinity` to disable rotation.\n * Defaults to 1000 — a single LLM call averages ~5KB serialized\n * (messages + tools + response), so 1000 entries is ~5MB per\n * session which is a reasonable upper bound.\n */\n maxEntries?: number | undefined;\n}\n\nexport class ReplayLogStore {\n private readonly dir: string;\n private readonly writeChains = new Map<string, Promise<void>>();\n /** Per-session hash → entry index, kept in memory after the first load. */\n private readonly cache = new Map<string, Map<string, ReplayEntry>>();\n /** Per-session entry count on disk, to detect when compaction is needed. */\n private readonly diskCount = new Map<string, number>();\n private readonly maxEntries: number;\n\n constructor(opts: ReplayLogStoreOptions) {\n this.dir = opts.dir;\n this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n // ── Writes ──────────────────────────────────────────────────────────────\n\n /**\n * Record a request/response pair. Idempotent on hash: a second\n * `record` for the same hash is a no-op (the existing entry wins).\n * Returns the hash.\n */\n async record(input: {\n sessionId: string;\n request: Request;\n response: Response;\n }): Promise<string> {\n const hash = hashRequest(input.request);\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const entries = await this.readAll(input.sessionId);\n if (entries.some((entry) => entry.hash === hash)) return; // already recorded\n const entry: ReplayEntry = {\n hash,\n ts: new Date().toISOString(),\n request: input.request,\n response: input.response,\n };\n // True append — O(1) per write. Only compact (full rewrite) when\n // we exceed maxEntries and need to evict oldest entries.\n entries.push(entry);\n const keep = entries.slice(-this.maxEntries);\n const cache = new Map<string, ReplayEntry>();\n for (const e of keep) cache.set(e.hash, e);\n this.cache.set(input.sessionId, cache);\n await this.rewriteCache(input.sessionId, cache);\n });\n });\n return hash;\n }\n\n /**\n * Compact the replay log to keep only the most recent maxEntries.\n * Called when entry count exceeds the cap. Rewrites the entire file\n * but only happens O(n / maxEntries) times per session.\n */\n private async rewriteCache(sessionId: string, cache: Map<string, ReplayEntry>): Promise<void> {\n // Map.values() preserves insertion order — take the last maxEntries.\n const all = [...cache.values()];\n const keep = all.slice(-this.maxEntries);\n await this.writeAll(sessionId, keep);\n cache.clear();\n for (const e of keep) cache.set(e.hash, e);\n this.diskCount.set(sessionId, keep.length);\n }\n\n // ── Reads ───────────────────────────────────────────────────────────────\n\n /**\n * Look up an entry by hash. Returns `null` when the request has\n * not been recorded for this session. O(1) after the first call\n * per session (in-memory cache).\n */\n async lookup(sessionId: string, hash: string): Promise<ReplayEntry | null> {\n const cache = await this.ensureCache(sessionId);\n return cache.get(hash) ?? null;\n }\n\n /** All recorded entries for a session, in insertion order. */\n async load(sessionId: string): Promise<ReplayEntry[]> {\n const cache = await this.ensureCache(sessionId);\n return [...cache.values()];\n }\n\n /**\n * List every session id that has a replay log in the store dir.\n * Returns an array of `{ sessionId, entryCount, path }` sorted\n * by sessionId for stable output. Used by `wstack replay --list`.\n */\n async list(): Promise<Array<{ sessionId: string; entryCount: number; path: string }>> {\n const out: Array<{ sessionId: string; entryCount: number; path: string }> = [];\n // Replay logs sit next to their session JSONL — flat at the root for\n // legacy/`record-<ts>` ids, inside a date-shard dir for modern ids.\n // Scan both levels; a root-only scan misses every sharded session.\n const scan = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if (depth === 0 && (err as NodeJS.ErrnoException).code !== 'ENOENT') {\n // EACCES, ENOTDIR, etc. — log the real error so the operator can\n // diagnose a misconfiguration, but still return empty list so the\n // caller (slash command display) doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'replay_log_store.list_readdir_failed',\n dir,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n if (depth === 0) await scan(path.join(dir, entry.name), entry.name, depth + 1);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.replay.jsonl')) continue;\n const base = entry.name.slice(0, -'.replay.jsonl'.length);\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const all = await this.load(sessionId);\n out.push({\n sessionId,\n entryCount: all.length,\n path: path.join(dir, entry.name),\n });\n }\n };\n await scan(this.dir, '', 0);\n return out.sort((a, b) => a.sessionId.localeCompare(b.sessionId));\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // the moment a real (sharded) session id is used for --replay.\n return sessionScopedPath(this.dir, sessionId, '.replay.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: ReplayEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<\n { version?: number | undefined; entry?: ReplayEntry | undefined } & ReplayEntry\n >(line);\n if (!parsed.ok || !parsed.value) continue;\n // Forward-compat: v1 stores entries one per line, no envelope.\n // A future \"v2\" could wrap with `{version, entries:[...]}`;\n // the loader would then branch on `parsed.version`.\n if ('entry' in parsed.value && parsed.value.entry) {\n out.push(parsed.value.entry);\n } else {\n out.push(parsed.value);\n }\n } catch {\n // Skip a corrupt line — annotations-store and other sidecar\n // stores take the same approach (meta-data, not fatal).\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Corrupt or unreadable: treat as empty.\n return [];\n }\n }\n\n private async writeAll(sessionId: string, entries: ReplayEntry[]): Promise<void> {\n const fp = this.filePath(sessionId);\n const body = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n await atomicWrite(fp, body);\n // Drop the version-stamp comment at the top — v1 has no envelope,\n // but we keep a one-line marker for human readers / future tooling.\n // (The atomicWrite just wrote pure JSONL; that's correct for v1.)\n void FILE_VERSION;\n }\n\n private async ensureCache(sessionId: string): Promise<Map<string, ReplayEntry>> {\n let cache = this.cache.get(sessionId);\n if (cache) return cache;\n const all = await this.readAll(sessionId);\n cache = new Map();\n for (const e of all) cache.set(e.hash, e);\n this.cache.set(sessionId, cache);\n this.diskCount.set(sessionId, all.length);\n return cache;\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SessionEvent } from '../types/session.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * Idea #1 from IDEAS.md — Stateful Session Recovery.\n *\n * `SessionRecovery` is the read-side companion to the in-flight\n * marker mechanism. When the agent loop is running, it writes an\n * `in_flight_start` event at the current point in the log. On\n * clean shutdown, a matching `in_flight_end` follows. If the\n * process dies (crash, OOM, machine sleep, SIGKILL) the marker\n * is the last event in the file — and `detectStale` flags the\n * session as \"incomplete, can be resumed\".\n *\n * Phase 1 of this feature is **detection only**. The actual\n * re-execution of incomplete work is a follow-up: it requires\n * tracking pending tool calls, mid-stream LLM responses, and\n * uncommitted file changes — and re-running the agent loop from\n * the last `checkpoint` event. The detection layer is independent\n * and ships first because (a) it gives the user immediate\n * visibility into what died, and (b) it's the foundation for the\n * resume command and the CLI's \"Incomplete sessions\" surface.\n *\n * Concurrency: pure read; no writes. Safe to call from multiple\n * processes simultaneously.\n */\nexport interface StaleSession {\n sessionId: string;\n /** Path to the JSONL log. */\n path: string;\n /** Last event ts (the in_flight_start timestamp). */\n lastEventTs: string;\n /** Context the agent was working on when it died. */\n context: string;\n /** Total events in the log. */\n eventCount: number;\n}\n\nexport interface RecoveryPlan {\n sessionId: string;\n /** True if the session is stale (has a dangling in_flight_start). */\n stale: boolean;\n /** The last `checkpoint` event before the un-replayed work, or null. */\n lastCheckpoint: SessionEvent | null;\n /** All events after the last checkpoint (i.e. the work that needs re-execution). */\n pendingEvents: SessionEvent[];\n /** The dangling in_flight_start event, if any. */\n inFlightStart: SessionEvent | null;\n /** Free-form context the agent was working on, if any. */\n context: string | null;\n}\n\n/**\n * Result of `SessionRecovery.recover(sessionId)`. Distinct from\n * `StaleSession`: a session is \"stale\" if the last event is an\n * open marker, but a \"recovery plan\" can also be generated for\n * clean sessions whose last checkpoint is older than the\n * conversation history (e.g. a user-initiated \"rewind to last\n * good state\" flow). Phase 2 of idea #1: this returns the plan;\n * the actual kernel re-execution is a follow-up.\n */\nexport class SessionRecovery {\n /**\n * Scan a session log and return a `StaleSession` if and only\n * if the last event is an `in_flight_start` without a matching\n * `in_flight_end`. Returns `null` when:\n * - the log does not exist;\n * - the log is empty;\n * - the last event is `in_flight_end` (clean shutdown);\n * - the last event is something else (e.g. an unannotated\n * legacy log without in-flight markers).\n */\n async detectStale(sessionId: string): Promise<StaleSession | null> {\n const fp = this.filePath(sessionId);\n // Only read the last ~8KB — enough for several large events.\n // This is O(1) I/O vs O(n) of reading the entire file.\n const TAIL_SIZE = 8192;\n let stat;\n try {\n stat = await fs.stat(fp);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n return null;\n }\n if (stat.size === 0) return null;\n const position = Math.max(0, stat.size - TAIL_SIZE);\n const buf = Buffer.alloc(TAIL_SIZE);\n let fh;\n try {\n fh = await fs.open(fp, 'r');\n const { bytesRead } = await fh.read(buf, 0, TAIL_SIZE, position);\n // Count total events for StaleSession.eventCount — requires full scan.\n // For very large files this is a trade-off; count is informational.\n let eventCount = 0;\n const raw = buf.subarray(0, bytesRead).toString('utf8');\n for (const line of raw.split('\\n')) {\n if (line.trim()) eventCount++;\n }\n // Find the last complete JSON line in the tail.\n const lines = raw.split('\\n').filter((l) => l.trim());\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const ev = JSON.parse(expectDefined(lines[i])) as SessionEvent;\n if (ev.type === 'in_flight_start') {\n return {\n sessionId,\n path: fp,\n lastEventTs: ev.ts,\n context: ev.context,\n eventCount,\n };\n }\n // Found a different last event — clean shutdown or legacy\n return null;\n } catch {\n // Incomplete line (spans the read boundary) — skip\n }\n }\n return null;\n } catch {\n return null;\n } finally {\n if (fh) await fh.close();\n }\n }\n\n /**\n * Generate a recovery plan for a session. The plan describes\n * \"what would be re-executed\" if the user chose to resume —\n * everything after the last `checkpoint` event, plus the\n * dangling in-flight marker if present.\n *\n * Returns a non-null plan for ANY session that has at least\n * one event after a checkpoint (or, for legacy sessions, at\n * least one event). Pure read; no mutation.\n */\n async recover(sessionId: string): Promise<RecoveryPlan | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n return null;\n }\n const events: SessionEvent[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n if (events.length === 0) return null;\n // Find the last checkpoint.\n let lastCheckpoint: SessionEvent | null = null;\n let lastCheckpointIdx = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i]?.type === 'checkpoint') {\n lastCheckpoint = expectDefined(events[i]);\n lastCheckpointIdx = i;\n }\n }\n // Events after the last checkpoint = the work that needs re-execution.\n const pendingEvents =\n lastCheckpointIdx >= 0 ? events.slice(lastCheckpointIdx + 1) : events;\n // The dangling in_flight_start, if the last event is one.\n const lastEv = expectDefined(events[events.length - 1]);\n const inFlightStart =\n lastEv.type === 'in_flight_start' ? lastEv : null;\n const context = inFlightStart && inFlightStart.type === 'in_flight_start'\n ? inFlightStart.context\n : null;\n return {\n sessionId,\n stale: inFlightStart !== null,\n lastCheckpoint,\n pendingEvents,\n inFlightStart,\n context,\n };\n }\n\n /**\n * List every stale session in a directory. Returns an array\n * (possibly empty) sorted by `lastEventTs` descending — most\n * recent crash first.\n */\n async listResumable(): Promise<StaleSession[]> {\n const out: StaleSession[] = [];\n // Modern sessions live inside date-shard subdirectories\n // (\"2026-06-11/<base>.jsonl\"); legacy/flat sessions sit at the root.\n // Scan both — a root-only scan silently misses every modern crash.\n const collect = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (\n entry.name === 'shared' ||\n entry.name === 'subagents' ||\n entry.name === 'attachments'\n )\n continue;\n if (entry.isDirectory()) {\n if (depth === 0) {\n await collect(path.join(dir, entry.name), entry.name, depth + 1);\n }\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.jsonl')) continue;\n if (entry.name === '_index.jsonl' || entry.name === '_mailbox.jsonl') continue;\n const base = entry.name.slice(0, -'.jsonl'.length);\n if (base.includes('.replay') || base.includes('.annotations') || base.includes('.audit'))\n continue;\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const stale = await this.detectStale(sessionId);\n if (stale) out.push(stale);\n }\n };\n await collect(this.dir, '', 0);\n return out.sort((a, b) => b.lastEventTs.localeCompare(a.lastEventTs));\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. Shared with the other per-session\n // sidecar stores so the contract can't drift.\n return sessionScopedPath(this.dir, sessionId, '.jsonl');\n }\n\n constructor(private readonly dir: string) {}\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * ToolAuditLog — idea #9 from IDEAS.md.\n *\n * Tamper-evident audit trail for tool calls. Every tool_use /\n * tool_result pair is appended to a sidecar JSONL with a chained\n * SHA-256 — each entry's `prevHash` is the prior entry's `hash`,\n * so any post-hoc modification of a single line breaks the chain\n * from that point forward.\n *\n * Why a sidecar (not the session JSONL)?\n * Same reason as `AnnotationsStore` and `ReplayLogStore`: the\n * session log is an event-sourced journal. Mixing in a hash\n * chain would inflate every read and tightly couple the\n * integrity check to the event format. Sidecar keeps both\n * concerns orthogonal.\n *\n * What \"tamper-evident\" means here:\n * - The hash covers the full serialized entry: tool name, id,\n * input, output, timestamp, author. Changing any byte\n * changes the hash.\n * - The chain is sequential — a verifier walks the file in\n * order, recomputing each hash, and checks `prevHash`\n * matches the previous entry's `hash`.\n * - Any insertion, deletion, or modification of a single\n * entry surfaces as a \"chain broken at entry N\" verdict.\n *\n * What it does NOT defend against:\n * - An attacker who rewrites the whole file consistently.\n * For that you'd need an external anchor (signing key,\n * transparency log, etc.) — out of scope for Phase 1.\n * - The agent itself misbehaving; this is post-hoc audit, not\n * real-time enforcement. Use `PermissionPolicy` for that.\n *\n * File layout: `<dir>/<sessionId>.audit.jsonl`, one entry per\n * line. The chain starts with a `genesis` entry whose\n * `prevHash` is all zeros.\n */\nexport interface AuditEntry {\n /** Monotonic index (0-based). */\n index: number;\n /** UUID for cross-referencing with logs. */\n id: string;\n /** ISO timestamp. */\n ts: string;\n /** Hash of the previous entry (or all-zeros for the genesis entry). */\n prevHash: string;\n /** Hash of this entry's content (sha256 over the canonical JSON). */\n hash: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n}\n\nconst GENESIS_PREV = '0'.repeat(64);\n\nexport type VerifyResult =\n | { ok: true; entries: number }\n | { ok: false; brokenAt: number; reason: string };\n\nexport interface ToolAuditLogOptions {\n /** Directory where `<sessionId>.audit.jsonl` files live. */\n dir: string;\n /**\n * Flush the file system cache to disk every N writes per session.\n * Default 100. Lower values = better crash durability, more I/O overhead.\n * Set to `Infinity` to disable periodic fsync (fastest, but highest data-loss risk).\n */\n fsyncEvery?: number | undefined;\n}\n\n/** Default number of writes between fsync calls. */\nconst DEFAULT_FSYNC_EVERY = 100;\n\nexport class ToolAuditLog {\n private readonly dir: string;\n /** In-memory cache of the last entry's hash (per session), to compute chains efficiently. */\n private readonly tailHash = new Map<string, string>();\n /** In-memory counter for entry indices — avoids re-reading the file on every write. */\n private readonly tailIndex = new Map<string, number>();\n /** Tracks writes since last fsync, per session. */\n private readonly unSyncedWrites = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly fsyncEvery: number;\n\n constructor(opts: ToolAuditLogOptions) {\n this.dir = opts.dir;\n this.fsyncEvery = opts.fsyncEvery ?? DEFAULT_FSYNC_EVERY;\n }\n\n /**\n * Append a tool call/result pair to the chain. Returns the\n * resulting entry. Idempotency is not guaranteed — if you\n * record the same tool_use twice you get two entries. That's\n * intentional: the audit log is a record, not a cache.\n */\n async record(input: {\n sessionId: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n }): Promise<AuditEntry> {\n let entry!: AuditEntry; // assigned inside the enqueue callback\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const entries = await this.readAll(input.sessionId);\n const prev = entries.at(-1);\n const prevHash = prev?.hash ?? GENESIS_PREV;\n const index = prev ? prev.index + 1 : 0;\n const id = randomUUID();\n const ts = new Date().toISOString();\n const content = {\n id,\n ts,\n prevHash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n const hash = createHash('sha256').update(stableStringify(content), 'utf8').digest('hex');\n entry = {\n id,\n ts,\n prevHash,\n hash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n entries.push(entry);\n await this.writeAll(input.sessionId, entries);\n this.tailHash.set(input.sessionId, hash);\n this.tailIndex.set(input.sessionId, index + 1);\n });\n });\n return entry;\n }\n\n /**\n * Walk the chain and verify every entry's hash and prevHash.\n * Returns a structured verdict — never throws.\n */\n async verify(sessionId: string): Promise<VerifyResult> {\n const entries = await this.readAll(sessionId);\n if (entries.length === 0) return { ok: true, entries: 0 };\n // The first entry's prevHash must be the all-zeros genesis marker.\n if (entries[0]?.prevHash !== GENESIS_PREV) {\n return {\n ok: false,\n brokenAt: 0,\n reason: 'first entry is not the genesis (prevHash != 0…0)',\n };\n }\n let prevHash = GENESIS_PREV;\n for (let i = 0; i < entries.length; i++) {\n const e = expectDefined(entries[i]);\n if (e.prevHash !== prevHash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `prevHash mismatch at entry ${i} (expected ${prevHash.slice(0, 8)}…, got ${e.prevHash.slice(0, 8)}…)`,\n };\n }\n // Recompute the hash from the entry's content (without the\n // `hash` field itself, which is what we are verifying).\n const content = {\n id: e.id,\n ts: e.ts,\n prevHash: e.prevHash,\n toolName: e.toolName,\n toolUseId: e.toolUseId,\n input: e.input,\n output: e.output,\n isError: e.isError,\n index: e.index,\n };\n const expectedHash = createHash('sha256')\n .update(stableStringify(content), 'utf8')\n .digest('hex');\n if (expectedHash !== e.hash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `hash mismatch at entry ${i} (entry content was modified)`,\n };\n }\n prevHash = e.hash;\n }\n return { ok: true, entries: entries.length };\n }\n\n /** All entries for a session, in insertion order. */\n async load(sessionId: string): Promise<AuditEntry[]> {\n return this.readAll(sessionId);\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // for every modern session id the moment record() gets wired in.\n return sessionScopedPath(this.dir, sessionId, '.audit.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: AuditEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<AuditEntry>(line);\n if (parsed.ok && parsed.value) out.push(parsed.value);\n } catch {\n // Skip corrupt lines — audit data is meta, not fatal.\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n return [];\n }\n }\n\n private async writeAll(sessionId: string, entries: AuditEntry[]): Promise<void> {\n const fp = this.filePath(sessionId);\n const line = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n // Real append — O(1) per write. The write chain ensures serial\n // ordering per session. On crash a partial line may appear;\n // readAll skips unparseable lines so the chain stays verifiable.\n await atomicWrite(fp, line, { mode: 0o600 });\n // Periodic fsync: every fsyncEvery writes, open the file and sync it.\n // This limits data loss to at most fsyncEvery entries on crash.\n const count = (this.unSyncedWrites.get(sessionId) ?? 0) + 1;\n this.unSyncedWrites.set(sessionId, count);\n if (this.fsyncEvery !== Number.POSITIVE_INFINITY && count % this.fsyncEvery === 0) {\n await this.sync(sessionId, fp);\n }\n }\n\n /**\n * Explicitly sync the file to disk. Called automatically every\n * `fsyncEvery` writes, and available for callers who want to\n * force a sync before closing or during graceful shutdown.\n */\n async flush(sessionId: string): Promise<void> {\n await this.sync(sessionId, this.filePath(sessionId));\n }\n\n private async sync(sessionId: string, fp: string): Promise<void> {\n try {\n const fh = await fs.open(fp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync is best-effort; a failure here does not corrupt the chain.\n } finally {\n this.unSyncedWrites.set(sessionId, 0);\n }\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n","import type { SessionEvent } from '../types/session.js';\n\nexport interface QueryFilter {\n eventTypes?: string[] | undefined;\n toolNames?: string[] | undefined;\n timeRange?: { start: string; end: string } | undefined;\n}\n\nexport interface ToolInvocation {\n ts: string;\n name: string;\n input: unknown;\n output?: unknown | undefined;\n error?: string | undefined;\n durationMs: number;\n}\n\nexport interface SessionError {\n ts: string;\n phase: string;\n message: string;\n}\n\nexport interface ModeChange {\n ts: string;\n from: string;\n to: string;\n}\n\nexport interface TaskSummary {\n taskId: string;\n title: string;\n status: string;\n createdAt: string;\n completedAt?: string | undefined;\n}\n\nexport interface SessionAnalysis {\n sessionId: string;\n totalDuration: number;\n toolUsageCount: Record<string, number>;\n errorCount: number;\n modeChanges: ModeChange[];\n tasks: TaskSummary[];\n}\n\nexport class SessionAnalyzer {\n analyze(events: SessionEvent[]): SessionAnalysis {\n const toolUsageCount: Record<string, number> = {};\n const errors: SessionError[] = [];\n const modeChanges: ModeChange[] = [];\n const tasksById = new Map<string, TaskSummary>();\n let sessionId = '';\n\n for (const event of events) {\n // sessionId comes from session_start / session_resumed.\n if (event.type === 'session_start' || event.type === 'session_resumed') {\n if (!sessionId) sessionId = event.id;\n }\n if (event.type === 'tool_use') {\n toolUsageCount[event.name] = (toolUsageCount[event.name] ?? 0) + 1;\n }\n if (event.type === 'error') {\n errors.push({ ts: event.ts, phase: event.phase, message: event.message });\n }\n if (event.type === 'mode_changed') {\n modeChanges.push({ ts: event.ts, from: event.from, to: event.to });\n }\n if (event.type === 'task_created') {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'created',\n createdAt: event.ts,\n });\n }\n if (event.type === 'task_updated') {\n const t = tasksById.get(event.taskId);\n if (t) t.status = event.status;\n }\n if (event.type === 'task_completed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'completed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'completed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n if (event.type === 'task_failed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'failed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'failed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n }\n\n return {\n sessionId,\n totalDuration: this.calcDuration(events),\n toolUsageCount,\n errorCount: errors.length,\n modeChanges,\n tasks: Array.from(tasksById.values()),\n };\n }\n\n query(events: SessionEvent[], filter: QueryFilter): SessionEvent[] {\n return events.filter((e) => {\n if (filter.eventTypes?.length && !filter.eventTypes.includes(e.type)) return false;\n if (filter.toolNames?.length && e.type === 'tool_use') {\n const toolEvent = e as { type: 'tool_use'; name: string };\n if (!filter.toolNames.includes(toolEvent.name)) return false;\n }\n if (filter.timeRange) {\n const ts = new Date(e.ts).getTime();\n const start = new Date(filter.timeRange.start).getTime();\n const end = new Date(filter.timeRange.end).getTime();\n if (ts < start || ts > end) return false;\n }\n return true;\n });\n }\n\n private calcDuration(events: SessionEvent[]): number {\n if (events.length < 2) return 0;\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n if (!firstEvent || !lastEvent) return 0;\n const first = new Date(firstEvent.ts).getTime();\n const last = new Date(lastEvent.ts).getTime();\n return last - first;\n }\n}\n","/**\n * SessionRegistry — cross-process session and agent tracker.\n *\n * Each WrongStack process registers its session on start and updates its\n * status periodically. The registry is a single JSON file at\n * `~/.wrongstack/session-registry.json`. Entries are keyed by session ID.\n *\n * Because multiple processes may write concurrently, every write is an\n * atomic read-modify-write protected by a per-file advisory lock (flock on\n * Unix, exclusive open on Windows). Stale entries (process no longer alive)\n * are pruned on every read.\n *\n * @module session-registry\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\n/** Live status of a single agent within a session. */\nexport type AgentLiveStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user' // brain.ask_human, confirm prompt\n | 'error';\n\nexport interface AgentEntry {\n /** Unique agent id (ULID or UUID). */\n id: string;\n /** Human-readable label (e.g. \"leader\", \"bug-hunter #1\"). */\n name: string;\n status: AgentLiveStatus;\n /** Current tool name if running, undefined otherwise. */\n currentTool?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** UTC ISO timestamp of last activity. */\n lastActivityAt: string;\n}\n\nexport type SessionLiveStatus =\n | 'active' // process running, agents may be idle or busy\n | 'idle' // process running, no agent activity\n | 'closing' // session_end written, process shutting down\n | 'stale'; // process no longer alive (pruned on next read)\n\nexport interface SessionRegistryEntry {\n sessionId: string;\n projectSlug: string;\n projectRoot: string;\n projectName: string;\n workingDir: string;\n /** Current git branch, if the project is a git repo. Detected at registration. */\n gitBranch?: string | undefined;\n status: SessionLiveStatus;\n pid: number;\n /** UTC ISO */\n startedAt: string;\n /** UTC ISO — updated on every heartbeat */\n lastHeartbeatAt: string;\n /** Count of tracked agents */\n agentCount: number;\n agents: AgentEntry[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\nconst REGISTRY_FILE = 'session-registry.json';\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst STALE_TIMEOUT_MS = 30_000; // entry considered stale after 30s without heartbeat\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Registry class ────────────────────────────────────────────────────────\n\nexport class SessionRegistry {\n private readonly filePath: string;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private currentSessionId: string | null = null;\n\n constructor(globalRoot: string) {\n this.filePath = path.join(globalRoot, REGISTRY_FILE);\n }\n\n // ── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Register the current session. Call once on session start.\n * Starts the heartbeat timer.\n */\n async register(\n entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {\n agents?: AgentEntry[] | undefined;\n },\n ): Promise<void> {\n this.currentSessionId = entry.sessionId;\n const full: SessionRegistryEntry = {\n ...entry,\n status: 'active',\n lastHeartbeatAt: new Date().toISOString(),\n agentCount: entry.agents?.length ?? 0,\n agents: entry.agents ?? [],\n };\n await this.atomicUpdate((registry) => {\n // Prune dead entries that haven't heartbeated recently.\n // A just-created entry has no heartbeat yet — don't prune it.\n const now = Date.now();\n for (const [id, existing] of Object.entries(registry)) {\n if (existing.pid === entry.pid) continue;\n const heartbeatAge = now - new Date(existing.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(existing.pid)) {\n delete registry[id];\n }\n }\n registry[entry.sessionId] = full;\n });\n\n // Start heartbeat\n this.heartbeatTimer = setInterval(() => {\n void this.heartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n if (this.heartbeatTimer.unref) this.heartbeatTimer.unref();\n }\n\n /**\n * Update agent status for the current session. Call on every\n * significant status change (agent start, tool start, user wait, error).\n */\n async updateAgents(agents: AgentEntry[]): Promise<void> {\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.agents = agents;\n entry.agentCount = agents.length;\n // Derive session status from agent collective\n const hasRunning = agents.some((a) => a.status === 'running' || a.status === 'streaming');\n const hasWaiting = agents.some((a) => a.status === 'waiting_user');\n const hasError = agents.some((a) => a.status === 'error');\n entry.status = hasRunning ? 'active' : hasWaiting ? 'active' : hasError ? 'active' : 'idle';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Mark the session as closing. Called during shutdown.\n * Stops the heartbeat timer.\n */\n async markClosing(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.status = 'closing';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Remove the current session from the registry. Call on clean exit.\n */\n async unregister(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n const sid = this.currentSessionId;\n this.currentSessionId = null;\n await this.atomicUpdate((registry) => {\n delete registry[sid];\n });\n }\n\n /**\n * List all non-stale sessions. Prunes stale entries automatically.\n */\n async list(): Promise<SessionRegistryEntry[]> {\n const registry = await this.readAndPrune();\n return Object.values(registry);\n }\n\n /**\n * Get a single session entry by ID. Returns undefined if not found or stale.\n */\n async get(sessionId: string): Promise<SessionRegistryEntry | undefined> {\n const registry = await this.readAndPrune();\n return registry[sessionId];\n }\n\n /**\n * List all sessions for a specific project (by slug).\n */\n async listByProject(projectSlug: string): Promise<SessionRegistryEntry[]> {\n const all = await this.list();\n return all.filter((e) => e.projectSlug === projectSlug);\n }\n\n /**\n * Return the registry file path. Useful for WebUI to watch/read.\n */\n get registryPath(): string {\n return this.filePath;\n }\n\n // ── Internal ────────────────────────────────────────────────────────────\n\n private async heartbeat(): Promise<void> {\n if (!this.currentSessionId) return;\n // Only update heartbeat timestamp — avoid full read-modify-write for perf\n try {\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const entry = registry[this.currentSessionId];\n if (entry) {\n entry.lastHeartbeatAt = new Date().toISOString();\n // Status bound: if closing, don't revert\n if (entry.status !== 'closing') {\n const hasRunning = (entry.agents ?? []).some(\n (a) => a.status === 'running' || a.status === 'streaming',\n );\n entry.status = hasRunning ? 'active' : 'idle';\n }\n await this.writeAtomic(registry);\n }\n } catch {\n // Best-effort heartbeat — never throw\n }\n }\n\n private async readAndPrune(): Promise<Record<string, SessionRegistryEntry>> {\n try {\n const raw = await fs.readFile(this.filePath, 'utf8');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const now = Date.now();\n let pruned = false;\n\n for (const [id, entry] of Object.entries(registry)) {\n const heartbeatAge = now - new Date(entry.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(entry.pid)) {\n entry.status = 'stale';\n // Keep stale entries for 5 minutes so UIs can show \"recently closed\"\n const startedAge = now - new Date(entry.startedAt).getTime();\n if (startedAge > 5 * 60_000) {\n delete registry[id];\n pruned = true;\n }\n }\n }\n\n if (pruned) {\n await this.writeAtomic(registry).catch(() => undefined);\n }\n\n return registry;\n } catch {\n return {};\n }\n }\n\n private async atomicUpdate(\n fn: (registry: Record<string, SessionRegistryEntry>) => void,\n ): Promise<void> {\n const lockPath = `${this.filePath}.lock`;\n const maxRetries = 5;\n const retryDelayMs = 20;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n // Acquire exclusive lock via O_CREAT | O_EXCL\n const lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n if (!lockHandle) {\n // Lock held by another process — wait and retry\n await new Promise((r) => setTimeout(r, retryDelayMs * (attempt + 1)));\n continue;\n }\n\n try {\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n fn(registry);\n await this.writeAtomicLocked(registry);\n return; // success\n } finally {\n await lockHandle.close();\n await fs.unlink(lockPath).catch(() => undefined);\n }\n } catch {\n // Best-effort — never throw from registry writes\n return;\n }\n }\n // All retries exhausted — registry update dropped (non-critical)\n }\n\n private async writeAtomicLocked(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n\n /** Legacy write without lock — used by heartbeat for performance. */\n private async writeAtomic(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n}\n\n/** Singleton — created once per process. */\nlet _instance: SessionRegistry | null = null;\n\nexport function getSessionRegistry(globalRoot?: string): SessionRegistry {\n if (!_instance && globalRoot) {\n _instance = new SessionRegistry(globalRoot);\n }\n if (!_instance) {\n throw new Error('SessionRegistry not initialized. Call getSessionRegistry(globalRoot) first.');\n }\n return _instance;\n}\n\nexport function hasSessionRegistry(): boolean {\n return _instance !== null;\n}\n","/**\n * AgentStatusTracker — subscribes to EventBus events and keeps the\n * SessionRegistry updated with live agent status.\n *\n * Created once per process during boot. Listens for:\n * - agent.run.started / agent.run.completed → agent status changes\n * - tool.started / tool.executed → current tool tracking\n * - brain.ask_human → waiting_user status\n * - fleet events (subagent spawn/start/done) → agent entries\n *\n * @module agent-status-tracker\n */\nimport type { EventBus } from './kernel/events.js';\nimport type {\n AgentEntry,\n AgentLiveStatus,\n SessionRegistry,\n} from './session-registry.js';\n\nexport interface AgentStatusTrackerOptions {\n events: EventBus;\n registry: SessionRegistry;\n /** Leader agent name shown in the registry. Default: \"leader\". */\n leaderName?: string | undefined;\n}\n\nexport class AgentStatusTracker {\n private readonly events: EventBus;\n private readonly registry: SessionRegistry;\n private readonly leaderName: string;\n\n // Live agent map: agentId → AgentEntry\n private agents = new Map<string, AgentEntry>();\n\n // Leader tracking\n private leaderStatus: AgentLiveStatus = 'idle';\n private leaderCurrentTool: string | undefined;\n private leaderIterations = 0;\n private leaderToolCalls = 0;\n\n private unsubscribers: Array<() => void> = [];\n\n constructor(opts: AgentStatusTrackerOptions) {\n this.events = opts.events;\n this.registry = opts.registry;\n this.leaderName = opts.leaderName ?? 'leader';\n }\n\n start(): void {\n // Leader events\n this.unsubscribers.push(\n this.events.onPattern('agent.run.started', () => {\n this.leaderStatus = 'running';\n this.leaderIterations++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.completed', () => {\n this.leaderStatus = 'idle';\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.error', () => {\n this.leaderStatus = 'error';\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Tool events — track current tool\n this.unsubscribers.push(\n this.events.onPattern('tool.started', (_event, payload) => {\n const p = payload as { name?: string } | undefined;\n if (p?.name) {\n this.leaderCurrentTool = p.name;\n this.leaderToolCalls++;\n }\n this.leaderStatus = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('tool.executed', () => {\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Brain ask_human → waiting for user input\n this.unsubscribers.push(\n this.events.onPattern('brain.ask_human', () => {\n this.leaderStatus = 'waiting_user';\n this.flush();\n }),\n );\n\n // Streaming events\n this.unsubscribers.push(\n this.events.onPattern('llm.stream_started', () => {\n this.leaderStatus = 'streaming';\n this.flush();\n }),\n );\n\n // Fleet events — subagent tracking\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.spawned', (_event, payload) => {\n const p = payload as { subagentId?: string; name?: string } | undefined;\n if (p?.subagentId) {\n this.agents.set(p.subagentId, {\n id: p.subagentId,\n name: p.name ?? p.subagentId,\n status: 'idle',\n iterations: 0,\n toolCalls: 0,\n lastActivityAt: new Date().toISOString(),\n });\n this.flush();\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.task_started', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'running';\n entry.iterations++;\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.task_completed', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'idle';\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.error', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'error';\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.stopped', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n this.agents.delete(p.subagentId);\n this.flush();\n }\n }),\n );\n }\n\n stop(): void {\n for (const unsub of this.unsubscribers) {\n try { unsub(); } catch { /* ignore */ }\n }\n this.unsubscribers = [];\n }\n\n private flush(): void {\n const leaderEntry: AgentEntry = {\n id: 'leader',\n name: this.leaderName,\n status: this.leaderStatus,\n currentTool: this.leaderCurrentTool,\n iterations: this.leaderIterations,\n toolCalls: this.leaderToolCalls,\n lastActivityAt: new Date().toISOString(),\n };\n\n const allAgents = [leaderEntry, ...this.agents.values()];\n this.registry.updateAgents(allAgents).catch(() => undefined);\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { CheckpointInfo, RewindResult, RewindResultExtended, SessionRewinder } from '../types/session-rewinder.js';\r\nimport type { SessionEvent, FileSnapshot } from '../types/session.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\nimport { SessionError, ERROR_CODES } from '../types/errors.js';\r\n\r\nexport interface SessionRewinderOptions {\r\n sessionsDir: string;\r\n /** The project root directory; used to validate rewind targets stay inside it. */\r\n projectRoot: string;\r\n}\r\n\r\n/**\r\n * Rewind engine that reads session JSONL files and reverts file system\r\n * changes to any previous checkpoint.\r\n */\r\nexport class DefaultSessionRewinder implements SessionRewinder {\r\n constructor(private readonly sessionsDir: string, private readonly projectRoot: string) {}\r\n\r\n async listCheckpoints(sessionId: string): Promise<CheckpointInfo[]> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n // Build a map of promptIndex -> file snapshot count\r\n const fileCountMap = new Map<number, number>();\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n const e = event as { promptIndex: number; files: FileSnapshot[] };\r\n fileCountMap.set(e.promptIndex, (fileCountMap.get(e.promptIndex) ?? 0) + e.files.length);\r\n }\r\n }\r\n\r\n const checkpoints: CheckpointInfo[] = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n const e = event as { promptIndex: number; promptPreview: string; ts: string };\r\n checkpoints.push({\r\n promptIndex: e.promptIndex,\r\n promptPreview: e.promptPreview,\r\n ts: e.ts,\r\n fileCount: fileCountMap.get(e.promptIndex) ?? 0,\r\n });\r\n }\r\n }\r\n\r\n return checkpoints;\r\n }\r\n\r\n async rewindToCheckpoint(\r\n sessionId: string,\r\n checkpointIndex: number,\r\n ): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n let targetIdx = -1;\r\n for (let i = 0; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n const checkpointEvent = event as { promptIndex: number };\r\n if (checkpointEvent.promptIndex === checkpointIndex) {\r\n targetIdx = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (targetIdx === -1) {\r\n throw new SessionError({\r\n message: `Checkpoint ${checkpointIndex} not found`,\r\n code: ERROR_CODES.SESSION_NOT_FOUND,\r\n context: { checkpointIndex },\r\n });\r\n }\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (let i = targetIdx + 1; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n break;\r\n }\r\n if (event.type === 'file_snapshot') {\r\n const snapshotEvent = event as { promptIndex: number; files: FileSnapshot[] };\r\n if (snapshotEvent.promptIndex >= checkpointIndex) {\r\n snapshotsToRevert.push({ promptIndex: snapshotEvent.promptIndex, files: snapshotEvent.files });\r\n }\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert, this.projectRoot);\r\n const removedEvents = events.length - targetIdx - 1;\r\n return { ...result, toPromptIndex: checkpointIndex, removedEvents };\r\n }\r\n\r\n async rewindLastN(sessionId: string, n: number): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const checkpoints: Array<{ promptIndex: number; ts: string }> = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n checkpoints.push({ promptIndex: event.promptIndex, ts: event.ts });\r\n }\r\n }\r\n\r\n if (checkpoints.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n checkpoints.sort((a, b) => b.promptIndex - a.promptIndex);\r\n const targetIndex = checkpoints[n]?.promptIndex ?? 0;\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n let shouldRevert = false;\r\n\r\n for (const event of events) {\r\n if (event.type === 'checkpoint' && event.promptIndex === targetIndex) {\r\n shouldRevert = true;\r\n continue;\r\n }\r\n if (shouldRevert && event.type === 'file_snapshot') {\r\n snapshotsToRevert.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: targetIndex, removedEvents: snapshotsToRevert.length };\r\n }\r\n\r\n async rewindToStart(sessionId: string): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const allSnapshots: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n allSnapshots.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n if (allSnapshots.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n const result = await revertSnapshots(allSnapshots.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: 0, removedEvents: allSnapshots.length };\r\n }\r\n}\r\n\r\nfunction parseEvents(raw: string): SessionEvent[] {\r\n const lines = raw.split('\\n').filter((l) => l.trim());\r\n const events: SessionEvent[] = [];\r\n\r\n for (const line of lines) {\r\n try {\r\n const parsed = JSON.parse(line);\r\n if (\r\n parsed !== null &&\r\n typeof parsed === 'object' &&\r\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\r\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\r\n ) {\r\n events.push(parsed as SessionEvent);\r\n }\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n\r\n return events;\r\n}\r\n\r\nasync function revertSnapshots(\r\n snapshots: Array<{ promptIndex: number; files: FileSnapshot[] }>,\r\n projectRoot: string,\r\n): Promise<RewindResult> {\r\n const revertedFiles: string[] = [];\r\n const errors: string[] = [];\r\n\r\n for (const snapshot of snapshots) {\r\n for (const file of snapshot.files) {\r\n try {\r\n // Guard: ensure the target path resolves inside the project root.\r\n // Without this, a maliciously recorded path (e.g., via path traversal\r\n // in a tool call that wasn't caught) could cause rewind to write\r\n // to arbitrary locations.\r\n const absPath = path.resolve(file.path);\r\n const root = path.resolve(projectRoot);\r\n const rel = path.relative(root, absPath);\r\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\r\n errors.push(`${file.path}: path resolves outside project root — skipping`);\r\n continue;\r\n }\r\n\r\n if (file.action === 'deleted') {\r\n // File was deleted — restore it from before\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n } else if (file.action === 'created') {\r\n // File was created — delete it\r\n await fsp.unlink(file.path);\r\n revertedFiles.push(file.path);\r\n } else if (file.action === 'modified') {\r\n // File was modified — restore before content\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n }\r\n } catch (err) {\r\n errors.push(`${file.path}: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n }\r\n }\r\n\r\n return { revertedFiles, errors };\r\n}","import * as fsp from 'node:fs/promises';\nimport type { TodoItem } from '../core/context.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * On-disk checkpoint for `ctx.todos`. Written atomically every time the\n * todo list changes, read once on session resume. This is the missing\n * piece that lets `wstack resume <id>` rehydrate where the previous run\n * stopped instead of starting with an empty board.\n *\n * Schema is intentionally small — a single JSON object so a future\n * format bump is easy. The `version` field is the only contract; the\n * shape under `todos` mirrors `TodoItem` so reading is a straight assign.\n */\nexport interface TodosCheckpointFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n todos: TodoItem[];\n}\n\nexport type TodosCheckpointDetach = () => Promise<void>;\n\n/** Read a checkpoint from disk. Returns null when the file doesn't\n * exist or is corrupt — callers treat both cases as \"no prior state\".\n */\nexport async function loadTodosCheckpoint(filePath: string): Promise<TodoItem[] | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TodosCheckpointFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.todos)) return null;\n return parsed.todos.filter(\n (t): t is TodoItem =>\n !!t &&\n typeof t.id === 'string' &&\n typeof t.content === 'string' &&\n typeof t.status === 'string' &&\n (t.activeForm === undefined || typeof t.activeForm === 'string'),\n );\n } catch {\n return null;\n }\n}\n\n/** Write the checkpoint atomically. Best-effort: a write failure is\n * logged but does not throw — losing one checkpoint shouldn't bring\n * down the agent run.\n */\nexport async function saveTodosCheckpoint(\n filePath: string,\n sessionId: string,\n todos: readonly TodoItem[],\n): Promise<void> {\n const payload: TodosCheckpointFile = {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n todos: [...todos],\n };\n try {\n await atomicWrite(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'todos_checkpoint.save_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n}\n\n/**\n * Subscribe a `ConversationState` so every `todos_replaced` mutation\n * triggers an atomic write to disk. Returns the unsubscribe function.\n *\n * Writes are debounced by 150ms so a flurry of edits (e.g. the LLM\n * marking three items done in the same tool call) coalesces into one\n * disk hit.\n */\nexport function attachTodosCheckpoint(\n state: ConversationState,\n filePath: string,\n sessionId: string,\n): TodosCheckpointDetach {\n let timer: NodeJS.Timeout | null = null;\n let pending: readonly TodoItem[] | null = null;\n let writeChain: Promise<void> = Promise.resolve();\n\n const enqueueWrite = (todos: readonly TodoItem[]) => {\n writeChain = writeChain\n .then(() => saveTodosCheckpoint(filePath, sessionId, todos))\n .catch((err) => {\n // Log and keep the chain alive — a failed write must not\n // poison the chain and silently stop all subsequent writes.\n const msg = err instanceof Error ? err.message : String(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'todos_checkpoint.write_chain_failed',\n sessionId,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n return writeChain;\n };\n\n const flush = () => {\n timer = null;\n if (pending) {\n const todos = pending;\n pending = null;\n return enqueueWrite(todos);\n }\n return writeChain;\n };\n\n const unsubscribe = state.onChange((change) => {\n if (change.kind !== 'todos_replaced') return;\n pending = change.todos;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n void flush();\n }, 150);\n });\n return async () => {\n unsubscribe();\n if (timer) {\n clearTimeout(timer);\n // Flush any pending write before detach so callers can safely\n // unsubscribe at shutdown without losing the last update.\n await flush();\n } else {\n await writeChain;\n }\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\n\n/**\n * Plan items are the strategic counterpart to todos. Where `ctx.todos`\n * is the moment-to-moment task board the LLM mutates per-turn, a plan\n * captures the higher-level approach — the steps the user (or LLM)\n * laid out before any work began.\n *\n * Plans persist by default (per session) so a resumed session can show\n * \"you were on step 3 of 5\". Todos are derived/transient. Both can\n * coexist: think roadmap (plan) vs. sprint board (todos).\n */\nexport interface PlanItem {\n id: string;\n title: string;\n /** Optional longer-form context or rationale. */\n details?: string | undefined;\n status: 'open' | 'in_progress' | 'done';\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PlanFile {\n version: 1;\n sessionId: string;\n title?: string | undefined;\n updatedAt: string;\n items: PlanItem[];\n}\n\nexport async function loadPlan(filePath: string): Promise<PlanFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as PlanFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.items)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function savePlan(filePath: string, plan: PlanFile): Promise<void> {\n try {\n await atomicWrite(filePath, JSON.stringify(plan, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(\n '[plan-store] save failed:',\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n\n/** Create a new PlanFile when none exists on disk. */\nexport function emptyPlan(sessionId: string, title?: string): PlanFile {\n return {\n version: 1,\n sessionId,\n title,\n updatedAt: new Date().toISOString(),\n items: [],\n };\n}\n\nexport function addPlanItem(\n plan: PlanFile,\n title: string,\n details?: string | undefined,\n): { plan: PlanFile; item: PlanItem } {\n const now = new Date().toISOString();\n const item: PlanItem = {\n id: `plan_${Date.now()}_${randomUUID().slice(0, 6)}`,\n title,\n details,\n status: 'open',\n createdAt: now,\n updatedAt: now,\n };\n return {\n plan: { ...plan, items: [...plan.items, item], updatedAt: now },\n item,\n };\n}\n\nexport function removePlanItem(plan: PlanFile, idOrIndex: string): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n return {\n ...plan,\n items: plan.items.filter((_, i) => i !== idx),\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function setPlanItemStatus(\n plan: PlanFile,\n idOrIndex: string,\n status: PlanItem['status'],\n): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n const now = new Date().toISOString();\n const items = plan.items.map((it, i) =>\n i === idx ? { ...it, status, updatedAt: now } : it,\n );\n return { ...plan, items, updatedAt: now };\n}\n\nexport function clearPlan(plan: PlanFile): PlanFile {\n return { ...plan, items: [], updatedAt: new Date().toISOString() };\n}\n\n/** Render the plan as a short markdown-ish string suitable for slash output. */\nexport function formatPlan(plan: PlanFile): string {\n if (plan.items.length === 0) return 'Plan is empty.';\n const lines: string[] = [];\n if (plan.title) lines.push(`# ${plan.title}`);\n plan.items.forEach((it, i) => {\n const mark = it.status === 'done' ? '[x]' : it.status === 'in_progress' ? '[~]' : '[ ]';\n lines.push(`${i + 1}. ${mark} ${it.title}`);\n if (it.details) {\n for (const line of it.details.split('\\n')) lines.push(` ${line}`);\n }\n });\n return lines.join('\\n');\n}\n\nfunction matchIndex(plan: PlanFile, idOrIndex: string): number {\n const asNum = Number.parseInt(idOrIndex, 10);\n if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= plan.items.length) return asNum - 1;\n const byId = plan.items.findIndex((it) => it.id === idOrIndex);\n if (byId !== -1) return byId;\n const lower = idOrIndex.toLowerCase();\n return plan.items.findIndex((it) => it.title.toLowerCase().includes(lower));\n}\n\n/**\n * Promote a plan item to a set of todo items.\n * The plan item is marked 'in_progress' (if not already done) and its\n * title + details become the first todo; additional subtasks are appended.\n * Returns the derived todo list so the caller can pass it to `todoTool`\n * or `ctx.state.replaceTodos()`.\n */\nexport function deriveTodosFromPlanItem(\n plan: PlanFile,\n idOrIndex: string,\n subtasks?: string[] | undefined,\n): { plan: PlanFile; todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> } | null {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return null;\n\n const item = plan.items[idx];\n if (!item) return null;\n\n // Mark the plan item in_progress if it wasn't already done\n let updatedPlan = plan;\n if (item.status !== 'done') {\n updatedPlan = setPlanItemStatus(plan, idOrIndex, 'in_progress');\n }\n\n const todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> = [];\n\n // First todo from the plan item itself\n todos.push({\n id: `todo_${Date.now()}_plan`,\n content: item.title,\n status: 'in_progress',\n activeForm: item.title,\n promotedFromPlan: item.id,\n });\n\n // Optional subtasks\n if (subtasks && subtasks.length > 0) {\n for (const st of subtasks) {\n todos.push({\n id: `todo_${Date.now()}_${randomUUID().slice(0, 6)}`,\n content: st,\n status: 'pending',\n promotedFromPlan: item.id,\n });\n }\n }\n\n return { plan: updatedPlan, todos };\n}\n\n/**\n * Load, modify, and save the plan file under a file-level lock.\n * Prevents races from parallel tool invocations (e.g. batch_tool_use).\n */\nexport async function mutatePlan(\n filePath: string,\n sessionId: string,\n fn: (plan: PlanFile) => PlanFile | Promise<PlanFile>,\n): Promise<PlanFile> {\n return withFileLock(filePath, async () => {\n const plan = (await loadPlan(filePath)) ?? emptyPlan(sessionId);\n const updated = await fn(plan);\n await savePlan(filePath, updated);\n return updated;\n });\n}\n\n/**\n * Optional: attach a state-listener so meta operations (storing a plan\n * id on ctx.meta) trigger a save. Currently a stub — plans don't live\n * on Context, but this keeps the API surface symmetric with the todos\n * checkpoint so future refactors can flip plans into Context if needed.\n */\nexport function attachPlanCheckpoint(\n _state: ConversationState,\n _filePath: string,\n _sessionId: string,\n): () => void {\n return () => undefined;\n}\n","/**\n * Plan templates — pre-defined plan skeletons for common workflows.\n *\n * Templates are stored in-memory (no disk I/O). Users instantiate them\n * via `/plan template use <name>` or `planTool(action: 'template_use')`.\n * Each template is a function that returns an array of item titles, so\n * dynamic content (dates, project names) can be injected later.\n */\n\nexport interface PlanTemplate {\n name: string;\n description: string;\n category: 'development' | 'release' | 'maintenance' | 'infrastructure';\n items: Array<{\n title: string;\n details?: string | undefined;\n }>;\n}\n\nconst templates: Record<string, PlanTemplate> = {\n 'new-feature': {\n name: 'new-feature',\n description: 'Standard workflow for adding a new feature',\n category: 'development',\n items: [\n { title: 'Write specification / design doc', details: 'Define scope, acceptance criteria, edge cases' },\n { title: 'Set up feature branch', details: 'git checkout -b feature/...' },\n { title: 'Implement core logic', details: 'TDD preferred — write tests first' },\n { title: 'Add unit tests', details: '>= 80% coverage for new code' },\n { title: 'Add integration tests', details: 'End-to-end happy path + error paths' },\n { title: 'Update documentation', details: 'README, API docs, changelog' },\n { title: 'Code review', details: 'Self-review before requesting review' },\n { title: 'Merge and deploy', details: 'CI green, tag release' },\n ],\n },\n 'bug-fix': {\n name: 'bug-fix',\n description: 'Systematic approach to fixing bugs',\n category: 'maintenance',\n items: [\n { title: 'Reproduce the bug', details: 'Minimal reproduction case' },\n { title: 'Root cause analysis', details: 'Trace through logs, debugger' },\n { title: 'Write failing test', details: 'Test must fail before fix' },\n { title: 'Implement fix', details: 'Smallest possible change' },\n { title: 'Verify fix', details: 'Test passes, reproduction no longer fails' },\n { title: 'Regression test', details: 'Ensure no related tests broken' },\n { title: 'Document in changelog', details: 'Brief description + issue link' },\n ],\n },\n 'refactor': {\n name: 'refactor',\n description: 'Safe refactoring workflow',\n category: 'maintenance',\n items: [\n { title: 'Identify refactoring target', details: 'Code smell, performance bottleneck, or tech debt' },\n { title: 'Ensure test coverage', details: 'Existing tests must pass before and after' },\n { title: 'Write characterization tests', details: 'Capture current behavior if tests weak' },\n { title: 'Apply refactoring', details: 'Small steps, frequent commits' },\n { title: 'Run full test suite', details: 'All tests must pass' },\n { title: 'Performance check', details: 'Ensure no regression' },\n { title: 'Code review', details: 'Explain the why, not just the what' },\n ],\n },\n 'release': {\n name: 'release',\n description: 'Preparing a new release',\n category: 'release',\n items: [\n { title: 'Version bump', details: 'package.json, lockfiles, tags' },\n { title: 'Update changelog', details: 'All changes since last release' },\n { title: 'Run full test suite', details: 'Unit + integration + e2e' },\n { title: 'Build artifacts', details: 'Docker images, bundles, binaries' },\n { title: 'Staging smoke tests', details: 'Deploy to staging, verify' },\n { title: 'Production deploy', details: 'Blue-green or canary' },\n { title: 'Post-deploy verification', details: 'Health checks, error rates' },\n { title: 'Announce release', details: 'Slack, email, GitHub release notes' },\n ],\n },\n 'security-audit': {\n name: 'security-audit',\n description: 'Security review and hardening',\n category: 'infrastructure',\n items: [\n { title: 'Dependency audit', details: 'npm audit, Snyk, Dependabot alerts' },\n { title: 'Secret scan', details: 'git-secrets, truffleHog, manual review' },\n { title: 'Access control review', details: 'IAM, roles, least privilege' },\n { title: 'Input validation audit', details: 'SQL injection, XSS, path traversal' },\n { title: 'Authentication review', details: 'Session management, MFA, password policy' },\n { title: 'Logging and monitoring', details: 'PII in logs, audit trails' },\n { title: 'Incident response plan', details: 'Runbooks, contacts, escalation' },\n ],\n },\n 'onboarding': {\n name: 'onboarding',\n description: 'New developer onboarding checklist',\n category: 'infrastructure',\n items: [\n { title: 'Repository access', details: 'GitHub/GitLab permissions' },\n { title: 'Local environment setup', details: 'Docker, dependencies, env files' },\n { title: 'Run tests locally', details: 'Verify green suite' },\n { title: 'Read architecture docs', details: 'ADR, README, onboarding guide' },\n { title: 'First commit', details: 'Docs fix or small improvement' },\n { title: 'Pair programming session', details: 'Walk through codebase with buddy' },\n { title: 'Deploy to staging', details: 'Verify CI/CD access' },\n ],\n },\n};\n\nexport function listPlanTemplates(): PlanTemplate[] {\n return Object.values(templates);\n}\n\nexport function getPlanTemplate(name: string): PlanTemplate | undefined {\n return templates[name];\n}\n\nexport function formatPlanTemplates(): string {\n const cats = new Map<PlanTemplate['category'], PlanTemplate[]>();\n for (const t of Object.values(templates)) {\n const arr = cats.get(t.category) ?? [];\n arr.push(t);\n cats.set(t.category, arr);\n }\n\n const lines: string[] = ['Available plan templates:'];\n for (const [cat, items] of cats) {\n lines.push(`\\n${cat}:`);\n for (const t of items) {\n lines.push(` ${t.name.padEnd(18)} — ${t.description}`);\n }\n }\n return lines.join('\\n');\n}\n","import * as fsp from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport type { TaskItem } from '../utils/task-format.js';\n\n// ---------------------------------------------------------------------------\n// Task file persistence — one JSON file per session in\n// `<projectSessions>/<sessionId>.tasks.json`.\n//\n// Low-level load/save are exported for read-only consumers. Mutating callers\n// should use `mutateTasks` which wraps the entire read-modify-write cycle\n// under a file-level lock, preventing races from parallel tool invocations.\n// ---------------------------------------------------------------------------\n\nexport interface TaskFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n tasks: TaskItem[];\n}\n\nexport function emptyTaskFile(sessionId: string): TaskFile {\n return {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n tasks: [],\n };\n}\n\n/** Read the task file. Returns null when the file doesn't exist. */\nexport async function loadTasks(filePath: string): Promise<TaskFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TaskFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.tasks)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Write the task file atomically. Prefer `mutateTasks` for read-modify-write\n * cycles — this low-level function does NOT acquire a lock.\n */\nexport async function saveTasks(filePath: string, tasks: TaskFile): Promise<void> {\n try {\n tasks.updatedAt = new Date().toISOString();\n await atomicWrite(filePath, JSON.stringify(tasks, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(\n '[task-store] save failed:',\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n\n/**\n * Load, modify, and save the task file under a file-level lock.\n * `fn` receives the current TaskFile (or a fresh empty one) and must\n * return the mutated TaskFile (mutating in-place is fine — the returned\n * reference is what gets saved).\n *\n * This is the primary API for any code path that reads *and then writes*\n * the task file — it prevents races from parallel `batch_tool_use` calls.\n */\nexport async function mutateTasks(\n filePath: string,\n sessionId: string,\n fn: (file: TaskFile) => TaskFile | Promise<TaskFile>,\n): Promise<TaskFile> {\n return withFileLock(filePath, async () => {\n const file = (await loadTasks(filePath)) ?? emptyTaskFile(sessionId);\n const updated = await fn(file);\n await saveTasks(filePath, updated);\n return updated;\n });\n}\n","import * as fsp from 'node:fs/promises';\nimport { hostname } from 'node:os';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * Director state checkpoint — written incrementally throughout a fleet\n * run so a crashed director can be inspected (and eventually resumed)\n * instead of leaving only a final `fleet.json` manifest after `shutdown()`.\n *\n * Schema is JSON-friendly and deliberately denormalized. Each mutation\n * triggers an atomic-write of the whole file — small payloads (typically\n * < 10 KB even with dozens of subagents) make this cheap.\n */\nexport interface DirectorSubagentState {\n id: string;\n name?: string | undefined;\n role?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n spawnedAt: string;\n}\n\nexport interface DirectorTaskState {\n taskId: string;\n subagentId?: string | undefined;\n description?: string | undefined;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout';\n assignedAt?: string | undefined;\n completedAt?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n durationMs?: number | undefined;\n error?: string | undefined;\n}\n\nexport interface DirectorStateSnapshot {\n version: 1;\n directorRunId: string;\n updatedAt: string;\n spawnCount: number;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n subagents: DirectorSubagentState[];\n tasks: DirectorTaskState[];\n /** Aggregated usage snapshot. Optional — populated by the Director on save when available. */\n usage?: unknown | undefined;\n}\n\nexport async function loadDirectorState(filePath: string): Promise<DirectorStateSnapshot | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as DirectorStateSnapshot;\n if (parsed?.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Lock file entry written when a director starts. Prevents two directors\n * from resuming the same run — the second one sees the lock and refuses\n * rather than corrupting the checkpoint by writing concurrently.\n */\nexport interface DirectorStateLock {\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\n/**\n * Write a lock file to claim this checkpoint. Returns false if the lock\n * is already held by a live process; returns true if the lock was acquired\n * (either the file didn't exist, or the previous holder is dead).\n */\nexport async function acquireDirectorStateLock(\n lockPath: string,\n processId = process.pid,\n): Promise<boolean> {\n let existing: string | undefined;\n try {\n existing = await fsp.readFile(lockPath, 'utf8');\n } catch {\n // No lock file — we're safe to claim\n }\n\n if (existing) {\n try {\n const lock = JSON.parse(existing) as DirectorStateLock;\n // Check if the process is still alive\n try {\n process.kill(lock.pid, 0);\n // Signal success means the process is alive — another director\n // owns this checkpoint. Refuse.\n return false;\n } catch {\n // ESRCH means the process is dead — stale lock. We'll overwrite.\n }\n } catch {\n // Malformed lock — treat as stale.\n }\n }\n\n const lock: DirectorStateLock = {\n pid: processId,\n hostname: hostname(),\n startedAt: new Date().toISOString(),\n };\n await atomicWrite(lockPath, JSON.stringify(lock), { mode: 0o600 });\n return true;\n}\n\n/**\n * Remove the lock file. Call this on graceful Director.shutdown() so the\n * next director run can claim the checkpoint without stale-lock checks.\n */\nexport async function releaseDirectorStateLock(lockPath: string): Promise<void> {\n try {\n await fsp.unlink(lockPath);\n } catch {\n // ignore\n }\n}\n\n/**\n * In-memory accumulator with atomic-write checkpoint. The Director keeps\n * an instance, mutates it on every spawn/assign/complete/fail event, and\n * the instance debounces writes so a burst of activity collapses into a\n * single disk hit.\n *\n * Supports crash recovery: use `loadDirectorState()` to read an existing\n * checkpoint, then call `DirectorStateCheckpoint.resume(snapshot)` to\n * re-attach to a fleet mid-flight. The lock mechanism ensures no two\n * directors can claim the same checkpoint.\n */\nexport class DirectorStateCheckpoint {\n private snapshot: DirectorStateSnapshot;\n private readonly filePath: string;\n private readonly lockPath: string;\n private timer: NodeJS.Timeout | null = null;\n private readonly debounceMs: number;\n private writing = false;\n private rewriteRequested = false;\n\n constructor(\n filePath: string,\n init: {\n directorRunId: string;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n },\n debounceMs = 250,\n ) {\n this.filePath = filePath;\n // Lock file lives alongside the checkpoint — `<path>.lock`\n this.lockPath = `${filePath}.lock`;\n this.debounceMs = debounceMs;\n this.snapshot = {\n version: 1,\n directorRunId: init.directorRunId,\n updatedAt: new Date().toISOString(),\n spawnCount: 0,\n maxSpawns: init.maxSpawns,\n spawnDepth: init.spawnDepth,\n maxSpawnDepth: init.maxSpawnDepth,\n directorBudget: init.directorBudget,\n subagents: [],\n tasks: [],\n };\n }\n\n /**\n * Attempt to acquire the lock for this checkpoint. Call this before\n * resuming a crashed director run. If it returns false, another\n * director process is still running this fleet — do not resume.\n */\n async acquireLock(): Promise<boolean> {\n return acquireDirectorStateLock(this.lockPath);\n }\n\n /**\n * Release the lock on graceful shutdown. Call `flush()` first to ensure\n * the final checkpoint state is on disk before removing the lock.\n * Without this, the next resume will see a stale-lock and refuse.\n */\n async releaseLock(): Promise<void> {\n return releaseDirectorStateLock(this.lockPath);\n }\n\n /**\n * Resume from a snapshot previously loaded via `loadDirectorState()`.\n * Use this when `--resume <runId>` is triggered — the snapshot has\n * the full fleet state (subagents, tasks) from before the crash; the\n * checkpoint continues from there.\n */\n resume(snapshot: DirectorStateSnapshot): void {\n this.snapshot = snapshot;\n }\n\n current(): DirectorStateSnapshot {\n return this.snapshot;\n }\n\n recordSpawn(sub: DirectorSubagentState, spawnCount: number): void {\n this.snapshot = {\n ...this.snapshot,\n spawnCount,\n subagents: [...this.snapshot.subagents.filter((s) => s.id !== sub.id), sub],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskAssigned(task: DirectorTaskState): void {\n const exists = this.snapshot.tasks.some((t) => t.taskId === task.taskId);\n this.snapshot = {\n ...this.snapshot,\n tasks: exists\n ? this.snapshot.tasks.map((t) => (t.taskId === task.taskId ? { ...t, ...task } : t))\n : [...this.snapshot.tasks, task],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskStatus(\n taskId: string,\n patch: Partial<DirectorTaskState> & { status: DirectorTaskState['status'] },\n ): void {\n this.snapshot = {\n ...this.snapshot,\n tasks: this.snapshot.tasks.map((t) =>\n t.taskId === taskId ? { ...t, ...patch } : t,\n ),\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n setUsage(usage: unknown): void {\n this.snapshot = { ...this.snapshot, usage };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n /** Force a synchronous flush — used by Director.shutdown(). */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n await this.persist();\n // If a rewrite was requested while we waited, persist() scheduled\n // a follow-up write. Loop until no more rewrites are requested so\n // shutdown doesn't return before the most recent state lands on disk.\n while (this.rewriteRequested) {\n this.rewriteRequested = false;\n await this.persist();\n }\n }\n\n private bumpUpdatedAt(): void {\n this.snapshot = { ...this.snapshot, updatedAt: new Date().toISOString() };\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.persist();\n }, this.debounceMs);\n }\n\n private async persist(): Promise<void> {\n if (this.writing) {\n // A write is already in flight — defer to a follow-up flush so the\n // most recent state still lands. Without this guard, simultaneous\n // burst mutations can drop the latest snapshot if rename races.\n this.rewriteRequested = true;\n return;\n }\n this.writing = true;\n try {\n await atomicWrite(this.filePath, JSON.stringify(this.snapshot, null, 2), {\n mode: 0o600,\n });\n } catch (err) {\n console.warn(\n '[director-state] checkpoint write failed:',\n err instanceof Error ? err.message : String(err),\n );\n } finally {\n this.writing = false;\n if (this.rewriteRequested) {\n this.rewriteRequested = false;\n this.schedule();\n }\n }\n }\n}\n","/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack — global root. */\n globalRoot: string;\n /**\n * ~/.wrongstack — directory for user-global stateful config files\n * (mode.json, theme.json, …). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key — 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md — user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills — user-global skills. */\n globalSkills: string;\n /** ~/.wrongstack/prompts — user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/cache — fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json — cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir — NOT inside the repo — so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history — REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json — optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json — per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md — committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills — committed project skills. */\n inProjectSkills: string;\n /** <project>/.wrongstack/worktrees — git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json — goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/specs — SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs — SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json — SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json — plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase — AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/sync.json — CloudSync configuration */\n syncConfig: string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state — config, secrets, logs, projects/, mailboxes — away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { color } from '../utils/color.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport { FsError, ERROR_CODES } from '../types/errors.js';\n\n/**\n * Long-running autonomous mission. A goal survives across sessions and\n * drives the EternalAutonomyEngine — every iteration of the engine\n * consults the goal to choose what to do next.\n *\n * Storage: `~/.wrongstack/projects/<hash>/goal.json`. Persistent and\n * project-scoped on purpose: the goal belongs to the codebase, not the\n * REPL session.\n */\n\nexport interface JournalEntry {\n /** ISO timestamp of the iteration. */\n at: string;\n /** Sequential iteration counter (1-based, monotonically increasing). */\n iteration: number;\n /** Source that produced the action ('todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel'). */\n source: 'todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel';\n /** Short one-line description of what the iteration set out to do. */\n task: string;\n /** Outcome status. */\n status: 'success' | 'failure' | 'aborted' | 'skipped';\n /** Optional free-form note (error message, summary, etc.). */\n note?: string | undefined;\n /** Optional token usage delta for this iteration. */\n tokens?: { input: number; output: number } | undefined;\n /** Optional USD cost delta for this iteration (provider-estimated). */\n costUsd?: number | undefined;\n}\n\nexport interface GoalFile {\n version: 1;\n /** The raw mission statement as entered by the user. */\n goal: string;\n /**\n * LLM-refined version of the goal — unambiguous, with concrete\n * deliverables and acceptance criteria.\n */\n refinedGoal?: string | undefined;\n /**\n * Concrete, verifiable deliverables extracted from the refined goal.\n */\n deliverables?: string[] | undefined;\n /**\n * Estimated completion 0-100. Updated by the engine after each\n * iteration. Null means \"not yet assessed\".\n */\n progress?: number | undefined;\n /** Human-readable note explaining the current progress estimate. */\n progressNote?: string | undefined;\n /**\n * Time-series of progress measurements for trend analysis.\n * Last 200 entries retained. Use `recordProgress()` to append.\n */\n progressHistory?: ProgressSnapshot[] | undefined;\n /**\n * Computed trend from recent progress measurements.\n * 'accelerating' | 'steady' | 'stalling' | undefined.\n */\n progressTrend?: 'accelerating' | 'steady' | 'stalling' | undefined;\n /** When the goal was first set or last replaced. */\n setAt: string;\n /** Updated on every iteration completion. */\n lastActivityAt: string;\n /** Total iterations the engine has run against this goal (cumulative). */\n iterations: number;\n /** Engine lifecycle state — 'running' means another process owns this goal. */\n engineState: 'idle' | 'running' | 'stopped';\n /**\n * Mission-level lifecycle.\n */\n goalState?: 'active' | 'paused' | 'completed' | 'abandoned' | undefined;\n /**\n * Per-todo attempt counter.\n */\n todoAttempts?: Record<string, number>;\n /** Bounded ring buffer of recent iterations (newest last). */\n journal: JournalEntry[];\n}\n\n/** Cap on persisted journal entries — older entries are evicted FIFO. */\nexport const MAX_JOURNAL_ENTRIES = 500;\n\n/**\n * Resolve the goal file path for a given project root.\n *\n * SINGLE canonical location: the per-project directory that\n * `resolveWstackPaths()` uses for everything else (sessions, memory, specs) —\n * `~/.wrongstack/projects/<slug>/goal.json`. This is the same path the `/goal`\n * slash command writes via `opts.paths.projectGoal`, so every reader/writer\n * (the eternal/parallel autonomy engines, the CLI autonomy commands, the TUI\n * F9 panel, and `/goal` itself) now agree on one file.\n *\n * Previously this returned a SEPARATE hash-based dir (`projects/<hash>/`), which\n * disagreed with `/goal` and littered the home dir with thousands of stray\n * `<hash>/goal.json` directories that held nothing else.\n */\nexport function goalFilePath(projectRoot: string): string {\n return resolveWstackPaths({ projectRoot }).projectGoal;\n}\n\nexport async function loadGoal(filePath: string): Promise<GoalFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null; // file doesn't exist — not an error\n throw err; // permission errors etc. should surface\n }\n try {\n const parsed = JSON.parse(raw) as GoalFile;\n if (parsed?.version !== 1 || typeof parsed.goal !== 'string' || !Array.isArray(parsed.journal)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.invalid_schema',\n path: filePath,\n message: 'invalid schema — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n return parsed;\n } catch {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.parse_failed',\n path: filePath,\n message: 'JSON parse failed — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n}\n\nexport async function saveGoal(filePath: string, goal: GoalFile): Promise<void> {\n try {\n await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 0o600 });\n } catch (err) {\n throw new FsError({\n message: err instanceof Error ? err.message : String(err),\n code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,\n path: filePath,\n cause: err,\n });\n }\n}\n\n/**\n * Atomically load, modify, and save a goal file under a file lock.\n * Prevents lost-update races when the autonomy engine and CLI /goal commands\n * write concurrently (both eternal and parallel engines may run simultaneously).\n *\n * `fn` receives the current GoalFile (or `null` if no goal exists yet)\n * and must return the updated GoalFile (or `null` to delete).\n */\nexport async function updateGoal(\n filePath: string,\n fn: (current: GoalFile | null) => GoalFile | null,\n): Promise<void> {\n await withFileLock(filePath, async () => {\n const current = await loadGoal(filePath);\n const next = fn(current);\n if (next) {\n await saveGoal(filePath, next);\n } else {\n try {\n await fsp.unlink(filePath);\n } catch {\n // best-effort — file may not exist\n }\n }\n });\n}\n\nexport function emptyGoal(goal: string): GoalFile {\n const now = new Date().toISOString();\n return {\n version: 1,\n goal,\n setAt: now,\n lastActivityAt: now,\n iterations: 0,\n engineState: 'idle',\n goalState: 'active',\n todoAttempts: {},\n journal: [],\n };\n}\n\n/**\n * Set progress estimate on a goal. Returns a new GoalFile.\n * Clamps progress to 0-100.\n */\nexport function setProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? clamped + '% complete',\n };\n}\n\n/**\n * Append a journal entry, bumping iteration counters and trimming the\n * ring buffer. Returns a new GoalFile — does not mutate the argument.\n */\nexport function appendJournal(goal: GoalFile, entry: Omit<JournalEntry, 'iteration' | 'at'>): GoalFile {\n const iteration = goal.iterations + 1;\n const at = new Date().toISOString();\n const full: JournalEntry = { ...entry, iteration, at };\n const journal = [...goal.journal, full];\n const trimmed = journal.length > MAX_JOURNAL_ENTRIES\n ? journal.slice(journal.length - MAX_JOURNAL_ENTRIES)\n : journal;\n return {\n ...goal,\n iterations: iteration,\n lastActivityAt: at,\n journal: trimmed,\n };\n}\n\n/**\n * Aggregate cumulative cost + tokens across all journal entries.\n */\nexport function summarizeUsage(goal: GoalFile): {\n totalCostUsd: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n iterationsWithUsage: number;\n} {\n let totalCostUsd = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let iterationsWithUsage = 0;\n for (const e of goal.journal) {\n if (typeof e.costUsd === 'number') totalCostUsd += e.costUsd;\n if (e.tokens) {\n totalInputTokens += e.tokens.input;\n totalOutputTokens += e.tokens.output;\n }\n if (typeof e.costUsd === 'number' || e.tokens) iterationsWithUsage++;\n }\n return { totalCostUsd, totalInputTokens, totalOutputTokens, iterationsWithUsage };\n}\n\nconst DOLLAR = '\\u0024';\n\n/** Format the goal + recent journal as a human-readable status block. */\nexport function formatGoal(goal: GoalFile, journalLimit = 10): string {\n const lines: string[] = [];\n\n // Header — show refined goal, with original as annotation if different\n const displayGoal = goal.refinedGoal || goal.goal;\n lines.push(color.bold('Goal') + ': ' + displayGoal);\n if (goal.refinedGoal && goal.refinedGoal !== goal.goal) {\n const snippet = goal.goal.length > 60 ? goal.goal.slice(0, 60) + '…' : goal.goal;\n lines.push(color.dim(' (original: \"' + snippet + '\")'));\n }\n\n // Progress bar (20-segment)\n if (typeof goal.progress === 'number') {\n const pct = Math.min(100, Math.max(0, Math.round(goal.progress)));\n const filled = Math.round(pct / 5);\n const empty = 20 - filled;\n const bar = color.green('█'.repeat(filled)) + color.dim('░'.repeat(empty));\n lines.push('Progress: ' + bar + ' ' + color.bold(pct + '%'));\n if (goal.progressNote) {\n lines.push(' ' + color.dim(goal.progressNote));\n }\n // Trend indicator\n if (goal.progressTrend) {\n const trendIcon = goal.progressTrend === 'accelerating' ? '🚀'\n : goal.progressTrend === 'stalling' ? '⚠️'\n : '➡️';\n lines.push(' Trend: ' + trendIcon + ' ' + goal.progressTrend);\n }\n }\n\n // Deliverables checklist\n if (goal.deliverables && goal.deliverables.length > 0) {\n lines.push('');\n lines.push(color.bold('Deliverables:'));\n for (const d of goal.deliverables) {\n const done = /^\\[[x✓]\\]|✅|\\(done\\)/i.test(d);\n const marker = done ? color.green('✓') : color.dim('○');\n lines.push(' ' + marker + ' ' + d);\n }\n }\n\n lines.push('');\n lines.push('Set: ' + goal.setAt);\n lines.push('Last activity: ' + goal.lastActivityAt);\n lines.push('Iterations: ' + goal.iterations);\n const stateLabel = goal.goalState ?? 'active';\n lines.push('State: ' + stateLabel + (goal.iterations > 0 ? ' (iteration #' + goal.iterations + ')' : ''));\n lines.push('Engine: ' + goal.engineState);\n const usage = summarizeUsage(goal);\n if (usage.iterationsWithUsage > 0) {\n const spent = 'Spent: ' + DOLLAR + usage.totalCostUsd.toFixed(4)\n + ' (in ' + usage.totalInputTokens + ' / out ' + usage.totalOutputTokens\n + ' tokens across ' + usage.iterationsWithUsage + ' iterations)';\n lines.push(spent);\n }\n if (goal.journal.length > 0) {\n lines.push('');\n lines.push('Recent journal (last ' + Math.min(journalLimit, goal.journal.length) + '):');\n const tail = goal.journal.slice(-journalLimit);\n for (const e of tail) {\n const mark = e.status === 'success' ? '✓' : e.status === 'failure' ? '✗' : e.status === 'aborted' ? '⊘' : '·';\n const note = e.note ? ' — ' + e.note : '';\n const cost = typeof e.costUsd === 'number' ? ' (' + DOLLAR + e.costUsd.toFixed(4) + ')' : '';\n lines.push(' #' + e.iteration + ' ' + mark + ' [' + e.source + '] ' + e.task + cost + note);\n }\n }\n return lines.join('\\n');\n}\n\n/** A single progress measurement at a point in time. */\nexport interface ProgressSnapshot {\n at: string;\n progress: number;\n note?: string | undefined;\n}\n\n/**\n * Parse [PROGRESS: N%] from agent final text.\n * Supports formats:\n * [PROGRESS: 45%]\n * [PROGRESS: 45%] — 3/5 deliverables done\n * [progress: 100%]\n * Returns null if no match.\n */\nexport function parseProgressFromText(text: string): { progress: number; note?: string } | null {\n const re = /\\[progress:\\s*(\\d{1,3})%\\]\\s*(?:[—-]\\s*(.+))?/i;\n const m = text.match(re);\n if (!m) return null;\n // Regex match guarantees capture group 1 exists, but use ?? fallback to\n // satisfy noUncheckedIndexedAccess without a non-null assertion.\n const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? '0', 10)));\n const note = m[2]?.trim() || undefined;\n return note === undefined ? { progress } : { progress, note };\n}\n\n/**\n * Record a progress measurement. Returns a new GoalFile with:\n * - progress + progressNote updated\n * - progressHistory appended (last 200 entries kept)\n * - progress trend computed (accelerating/steady/stalling)\n */\nexport function recordProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n const history = [...(goal.progressHistory ?? []), { at: new Date().toISOString(), progress: clamped, note }];\n // Keep last 200 snapshots\n const trimmed = history.length > 200 ? history.slice(-200) : history;\n\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? `${clamped}% complete`,\n progressHistory: trimmed,\n progressTrend: computeTrend(trimmed),\n };\n}\n\n/** Max progress history entries to retain. */\nexport const MAX_PROGRESS_HISTORY = 200;\n\nfunction computeTrend(history: ProgressSnapshot[]): 'accelerating' | 'steady' | 'stalling' | undefined {\n if (history.length < 3) return undefined;\n const recent = history.slice(-5);\n const deltas: number[] = [];\n for (let i = 1; i < recent.length; i++) {\n deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));\n }\n if (deltas.length < 2) return undefined;\n const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n if (avgDelta > 2) return 'accelerating';\n if (avgDelta < -1) return 'stalling';\n return 'steady';\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\nexport interface PromptEntry {\n id: string;\n title: string;\n content: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PromptStore {\n list(): Promise<PromptEntry[]>;\n get(id: string): Promise<PromptEntry | null>;\n save(entry: PromptEntry): Promise<void>;\n delete(id: string): Promise<boolean>;\n find(query: string): Promise<PromptEntry[]>;\n}\n\ninterface RawPromptFile {\n version: 1;\n entry: PromptEntry;\n}\n\nexport class DefaultPromptStore implements PromptStore {\n private readonly dir: string;\n\n constructor(paths: WstackPaths) {\n this.dir = paths.globalPrompts;\n }\n\n async list(): Promise<PromptEntry[]> {\n await ensureDir(this.dir);\n const entries: PromptEntry[] = [];\n try {\n const files = await fs.readdir(this.dir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const raw: RawPromptFile = JSON.parse(\n await fs.readFile(path.join(this.dir, file), 'utf8'),\n );\n entries.push(raw.entry);\n } catch {\n // skip corrupt files\n }\n }\n } catch {\n // dir doesn't exist yet\n }\n return entries.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n async get(id: string): Promise<PromptEntry | null> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n const raw: RawPromptFile = JSON.parse(await fs.readFile(file, 'utf8'));\n return raw.entry;\n } catch {\n return null;\n }\n }\n\n async save(entry: PromptEntry): Promise<void> {\n await ensureDir(this.dir);\n const file = path.join(this.dir, `${entry.id}.json`);\n const raw: RawPromptFile = { version: 1, entry };\n await atomicWrite(file, JSON.stringify(raw, null, 2));\n }\n\n async delete(id: string): Promise<boolean> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n await fs.unlink(file);\n return true;\n } catch {\n return false;\n }\n }\n\n async find(query: string): Promise<PromptEntry[]> {\n const all = await this.list();\n const lower = query.toLowerCase();\n return all.filter(\n (e) =>\n e.title.toLowerCase().includes(lower) ||\n e.content.toLowerCase().includes(lower) ||\n e.tags.some((t) => t.toLowerCase().includes(lower)),\n );\n }\n\n /** Create a new entry and return it. Does NOT persist — call save() afterwards. */\n createNew(title: string, content: string, tags: string[] = []): PromptEntry {\n const now = new Date().toISOString();\n return {\n id: randomUUID().slice(0, 8),\n title,\n content,\n tags,\n createdAt: now,\n updatedAt: now,\n };\n }\n}","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport type { SyncCategory, SyncConfig } from '../types/config.js';\nimport { FsError, WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport const ALL_SYNC_CATEGORIES: SyncCategory[] = ['settings', 'skills', 'prompts', 'memory', 'history'];\n\nexport interface SyncResult {\n ok: boolean;\n action: 'push' | 'pull';\n categories: SyncCategory[];\n committedAt?: string | undefined;\n message: string;\n}\n\ninterface SyncStateFile {\n version: 1;\n sha: string;\n lastSyncedAt: string;\n localRev: string;\n}\n\n/**\n * CloudSync — push/pull user-selected ~/.wrongstack categories to a\n * private GitHub repo. No git CLI needed; uses GitHub REST API via fetch.\n * The token is stored encrypted via SecretVault (field named `githubToken`\n * so the vault walker picks it up automatically).\n */\nexport class CloudSync {\n private readonly statePath: string;\n private state: SyncStateFile | null = null;\n\n constructor(\n private readonly paths: WstackPaths,\n private readonly getConfig: () => SyncConfig | null,\n private readonly setConfig: (c: SyncConfig) => Promise<void>,\n ) {\n this.statePath = path.join(paths.globalRoot, 'sync-state.json');\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n async status(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) {\n return 'CloudSync: disabled. Run `/sync enable` to activate.';\n }\n const last = this.state?.lastSyncedAt;\n const since = last ? timeAgo(last) : 'never';\n return [\n `CloudSync: enabled`,\n ` repo: ${cfg.repo}`,\n ` categories: ${cfg.categories.join(', ')}`,\n ` last sync: ${since}`,\n ].join('\\n');\n }\n\n async enable(_repo: string, _categories: SyncCategory[]): Promise<string> {\n // Persisted by the slash command via configStore.update.\n return 'Enable via /sync enable.';\n }\n\n async disable(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg) return 'CloudSync is not configured.';\n const next = { ...cfg, enabled: false };\n await this.setConfig(next);\n return 'CloudSync disabled. Local data kept.';\n }\n\n async push(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'push', categories: [], message: 'Not enabled.' };\n\n const parts = cfg.repo.split('/');\n const owner = expectDefined(parts[0]);\n const repoName = expectDefined(parts[1]);\n const branch = 'main';\n const baseTreeSha = this.state?.sha;\n\n const { treeEntries, rev } = await this.buildLocalTree(cfg.categories);\n const newTreeSha = await this.createGitTree(token, owner, repoName, treeEntries, baseTreeSha);\n\n const commitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n baseTreeSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n\n try {\n await this.updateRef(token, owner, repoName, branch, commitSha);\n } catch (err) {\n // 422 = not a fast forward — remote branch moved. Fetch latest SHA and retry.\n if (err instanceof Error && err.message.includes('422')) {\n const remote = await this.getRef(token, owner, repoName, branch);\n const currentSha = remote.object.sha;\n const rebasedCommitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n currentSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n await this.updateRef(token, owner, repoName, branch, rebasedCommitSha);\n } else {\n throw err;\n }\n }\n\n const syncState: SyncStateFile = {\n version: 1,\n sha: commitSha,\n lastSyncedAt: new Date().toISOString(),\n localRev: rev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'push',\n categories: cfg.categories,\n committedAt: commitSha,\n message: `Pushed ${cfg.categories.join(', ')} to ${cfg.repo}. Commit: ${commitSha.slice(0, 7)}`,\n };\n }\n\n async pull(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'pull', categories: [], message: 'Not enabled.' };\n\n const pullParts = cfg.repo.split('/');\n const owner = expectDefined(pullParts[0]);\n const repoName = expectDefined(pullParts[1]);\n\n const branchData = await this.getRef(token, owner, repoName, 'main');\n const currentSha = branchData.object.sha;\n\n const commitData = await this.getCommit(token, owner, repoName, currentSha);\n const treeSha = commitData.tree.sha;\n\n const treeEntries = await this.getTreeEntries(token, owner, repoName, treeSha);\n\n for (const entry of treeEntries) {\n if (entry.type !== 'blob') continue;\n\n // Paths look like \"data/{category}/...\" — extract the category\n const segments = entry.path.split('/');\n if (segments[0] !== 'data' || !segments[1]) continue;\n const cat = segments[1] as SyncCategory;\n if (!['settings', 'skills', 'prompts', 'memory', 'history'].includes(cat)) continue;\n\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n\n // Reconstruct relative path under the category dir. Remote trees are\n // untrusted input: a compromised sync repo could contain paths like\n // data/skills/../../config.json. Keep every write inside the selected\n // category root, and only allow subpaths for directory-backed categories.\n const rel = segments.slice(2).join('/');\n const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);\n\n const blobData = await this.getBlob(token, owner, repoName, entry.sha);\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.writeFile(destPath, Buffer.from(blobData, 'base64'));\n }\n\n const localRev = await this.hashLocalCategories(cfg.categories);\n const syncState: SyncStateFile = {\n version: 1,\n sha: currentSha,\n lastSyncedAt: new Date().toISOString(),\n localRev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'pull',\n categories: cfg.categories,\n committedAt: currentSha,\n message: `Pulled ${cfg.categories.join(', ')} from ${cfg.repo}. Commit: ${currentSha.slice(0, 7)}`,\n };\n }\n\n async hasLocalChanges(): Promise<boolean> {\n if (!this.state) return true;\n const cfg = this.getConfig();\n if (!cfg) return true;\n const current = await this.hashLocalCategories(cfg.categories);\n return current !== this.state.localRev;\n }\n\n async loadState(): Promise<void> {\n try {\n const raw = await fs.readFile(this.statePath, 'utf8');\n this.state = JSON.parse(raw) as SyncStateFile;\n } catch {\n this.state = null;\n }\n }\n\n // ── GitHub API helpers ──────────────────────────────────────────────\n\n private async githubFetch(\n token: string,\n owner: string,\n repo: string,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH',\n pathSegment: string,\n body?: unknown | undefined,\n ): Promise<unknown> {\n const url = `https://api.github.com/repos/${owner}/${repo}${pathSegment}`;\n const init: RequestInit = {\n signal: AbortSignal.timeout(15_000),\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Content-Type': 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new WrongStackError({\n message: `GitHub API ${method} ${pathSegment} failed (${res.status}): ${errText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { method, pathSegment, status: res.status, repo: `${owner}/${repo}` },\n });\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : {};\n }\n\n private async getRef(token: string, owner: string, repo: string, ref: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/refs/heads/${ref}`)) as {\n object: { sha: string };\n };\n }\n\n private async updateRef(token: string, owner: string, repo: string, ref: string, sha: string) {\n await this.githubFetch(token, owner, repo, 'PATCH', `/git/refs/heads/${ref}`, {\n sha,\n force: false,\n });\n }\n\n private async getCommit(token: string, owner: string, repo: string, sha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/commits/${sha}`)) as {\n tree: { sha: string };\n message: string;\n };\n }\n\n private async getTreeEntries(token: string, owner: string, repo: string, treeSha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/trees/${treeSha}?recursive=1`)) as Array<{\n path: string;\n sha: string;\n type: 'blob' | 'tree';\n }>;\n }\n\n private async createCommit(\n token: string, owner: string, repo: string,\n treeSha: string, parentSha?: string | undefined, message = 'sync',\n ) {\n const body: Record<string, unknown> = { message, tree: treeSha };\n if (parentSha) body.parents = [parentSha];\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/commits', body)) as { sha: string };\n return result.sha;\n }\n\n private async createGitTree(\n token: string, owner: string, repo: string,\n entries: Array<{ path: string; content: string; mode: string }>,\n baseTreeSha?: string | undefined,\n ): Promise<string> {\n const tree = entries.map((e) => ({\n path: e.path,\n mode: e.mode,\n type: 'blob',\n content: e.content,\n }));\n const body: Record<string, unknown> = { tree };\n if (baseTreeSha) body.base_tree = baseTreeSha;\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/trees', body)) as { sha: string };\n return result.sha;\n }\n\n private async getBlob(token: string, owner: string, repo: string, sha: string): Promise<string> {\n const result = (await this.githubFetch(token, owner, repo, 'GET', `/git/blobs/${sha}`)) as { content: string };\n return result.content;\n }\n\n // ── Local file helpers ──────────────────────────────────────────────\n\n private async buildLocalTree(categories: SyncCategory[]): Promise<{\n treeEntries: Array<{ path: string; content: string; mode: string }>;\n rev: string;\n }> {\n const entries: Array<{ path: string; content: string; mode: string }> = [];\n const hashes: string[] = [];\n\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file, 'utf8');\n const rel = path.relative(localPath, file).replace(/\\\\/g, '/');\n entries.push({ path: `data/${cat}/${rel}`, content, mode: '100644' });\n hashes.push(content);\n }\n } else {\n const content = await fs.readFile(localPath, 'utf8');\n entries.push({ path: `data/${cat}`, content, mode: '100644' });\n hashes.push(content);\n }\n } catch {\n // skip missing files/dirs\n }\n }\n\n const rev = createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n return { treeEntries: entries, rev };\n }\n\n private async hashLocalCategories(categories: SyncCategory[]): Promise<string> {\n const hashes: string[] = [];\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file);\n hashes.push(content.toString('base64') + file);\n }\n } else {\n const content = await fs.readFile(localPath);\n hashes.push(content.toString('base64') + localPath);\n }\n } catch {\n // skip\n }\n }\n return createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n }\n\n private categoryToPath(cat: SyncCategory): string | null {\n switch (cat) {\n case 'settings': return this.paths.globalConfig;\n case 'skills': return this.paths.globalSkills;\n case 'prompts': return this.paths.globalPrompts;\n case 'memory': return this.paths.globalMemory;\n case 'history': return this.paths.historyFile;\n default: return null;\n }\n }\n\n private async walkDir(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await this.walkDir(full, base)));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n\nfunction resolvePulledCategoryPath(\n cat: SyncCategory,\n localPath: string,\n rel: string,\n remotePath: string,\n): string {\n const directoryBacked = cat === 'skills' || cat === 'prompts';\n if (!directoryBacked) {\n if (rel) throw new FsError({\n message: `Refusing nested CloudSync path for file category: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'nested_file_category', category: cat },\n });\n return localPath;\n }\n\n if (!rel) return localPath;\n const normalizedRel = path.normalize(rel);\n const traversesUp = normalizedRel === '..' || normalizedRel.startsWith(`..${path.sep}`);\n if (path.isAbsolute(normalizedRel) || traversesUp) {\n throw new FsError({\n message: `Refusing CloudSync path traversal: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'path_traversal', normalizedRel },\n });\n }\n\n const dest = path.resolve(localPath, normalizedRel);\n const root = path.resolve(localPath);\n const relative = path.relative(root, dest);\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new FsError({\n message: `Refusing CloudSync path outside category root: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'outside_category_root', category: cat },\n });\n }\n return dest;\n}\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n","import type { SessionEvent, SessionWriter } from '../types/session.js';\n\nexport type AuditLevel = 'minimal' | 'standard' | 'full';\n\n/**\n * Configuration for sampling high-volume events inside the bridge.\n * This allows callers (CLI, TUI, WebUI, plugins) to tune how aggressively\n * noisy events like tool progress are persisted.\n */\nexport interface ToolProgressSamplingOptions {\n /**\n * How often to persist 'log' and 'partial_output' progress events.\n * - 1 = every message (no sampling)\n * - 8 = keep the first message + every 8th after that (default)\n */\n sampleRate?: number | undefined;\n}\n\nexport interface SessionSamplingOptions {\n /** Controls sampling behavior for `tool_progress` events (only relevant at auditLevel 'full'). */\n toolProgress?: ToolProgressSamplingOptions | undefined;\n}\n\nexport interface SessionEventBridgeOptions {\n /** Sampling rules for high-volume audit events. */\n sampling?: SessionSamplingOptions | undefined;\n}\n\n/**\n * Small, safe helper that wraps a SessionWriter and enforces the\n * configured auditLevel.\n *\n * All appends are best-effort. Failures are swallowed (with optional\n * diagnostics) so they never crash the agent loop.\n */\nexport interface SessionEventBridge {\n /** Append an event if allowed by the current audit level. */\n append(event: SessionEvent): Promise<void>;\n /** Batch-append events allowed by the current audit level. */\n appendBatch(events: SessionEvent[]): Promise<void>;\n\n /** Current audit level this bridge was created with. */\n readonly level: AuditLevel;\n\n /** Returns true if an event of this type should be written at the current level. */\n allows(type: SessionEvent['type']): boolean;\n}\n\n/** Core events that are always written regardless of auditLevel. */\nconst CORE_RECONSTRUCT_EVENTS = new Set<SessionEvent['type']>([\n 'session_start',\n 'session_resumed',\n 'user_input',\n 'llm_response',\n 'tool_result',\n 'checkpoint',\n 'file_snapshot',\n 'rewound',\n 'in_flight_start',\n 'in_flight_end',\n 'session_end',\n]);\n\n/**\n * Events that are considered \"standard\" audit detail.\n * These are lightweight and high-value for forensics.\n */\nconst STANDARD_AUDIT_EVENTS = new Set<SessionEvent['type']>([\n 'llm_request',\n 'tool_use',\n 'tool_call_start',\n 'tool_call_end',\n 'compaction',\n 'error',\n 'message_truncated',\n 'provider_retry',\n 'provider_error',\n]);\n\n/**\n * Events that are only allowed at 'full' audit level because they can be\n * very high volume (e.g. streaming tool output).\n */\nconst FULL_ONLY_EVENTS = new Set<SessionEvent['type']>([\n 'tool_progress',\n]);\n\n/**\n * \"full\" level allows everything (including potentially heavy events\n * that plugins or future code may emit).\n */\nfunction isAllowed(type: SessionEvent['type'], level: AuditLevel): boolean {\n if (CORE_RECONSTRUCT_EVENTS.has(type)) return true;\n if (level === 'minimal') return false;\n\n if (STANDARD_AUDIT_EVENTS.has(type)) return true;\n if (level === 'standard') return false;\n\n // 'full' level events (high volume)\n if (FULL_ONLY_EVENTS.has(type)) {\n return level === 'full';\n }\n\n // 'full' — allow everything else\n return true;\n}\n\n/**\n * Create a safe, audit-level-aware bridge around a SessionWriter.\n *\n * The bridge can also apply sampling for high-volume events (e.g. `tool_progress`)\n * when `auditLevel` is set to `'full'`.\n *\n * @example\n * const bridge = createSessionEventBridge(sessionWriter, 'full', {\n * sampling: {\n * toolProgress: { sampleRate: 5 } // more aggressive sampling\n * }\n * });\n */\nexport function createSessionEventBridge(\n writer:\n | SessionWriter\n | (() => SessionWriter | undefined | null)\n | undefined\n | null,\n level: AuditLevel = 'standard',\n options: SessionEventBridgeOptions = {},\n): SessionEventBridge {\n const normalizedLevel: AuditLevel = level ?? 'standard';\n\n // Accept either a writer instance or a getter. A getter lets long-lived\n // hosts (CLI/TUI/WebUI) resolve the CURRENT writer on every append — when\n // the user resumes another session mid-run, audit events follow the swap\n // instead of being silently dropped into the old, closed writer.\n const resolveWriter: () => SessionWriter | undefined | null =\n typeof writer === 'function' ? writer : () => writer;\n\n // Internal sampling state for high-volume events (e.g. tool_progress).\n // Keyed by tool call id (or name as fallback) to keep sampling per-call.\n const progressCounters = new Map<string, number>();\n\n const toolProgressConfig = options.sampling?.toolProgress ?? {};\n const TOOL_PROGRESS_SAMPLE_RATE = toolProgressConfig.sampleRate ?? 8;\n\n /**\n * Decide whether a high-volume event should be sampled in.\n * Currently only implements sampling for 'tool_progress'.\n */\n function shouldSample(event: SessionEvent): boolean {\n if (event.type !== 'tool_progress') return true;\n\n const progEvent = event as Extract<SessionEvent, { type: 'tool_progress' }>;\n const innerType = progEvent.event?.type;\n\n // Always let through high-signal structured events\n if (innerType === 'warning' || innerType === 'metric' || innerType === 'file_changed') {\n return true;\n }\n\n // Sample noisy text streams (log / partial_output)\n if (innerType === 'log' || innerType === 'partial_output') {\n const key = progEvent.id || progEvent.name;\n const count = (progressCounters.get(key) || 0) + 1;\n progressCounters.set(key, count);\n\n // Always keep the first message + every Nth after that\n return count === 1 || (count % TOOL_PROGRESS_SAMPLE_RATE === 0);\n }\n\n return true;\n }\n\n return {\n level: normalizedLevel,\n\n allows(type) {\n return isAllowed(type, normalizedLevel);\n },\n\n async append(event) {\n const target = resolveWriter();\n if (!target) return;\n if (!isAllowed(event.type, normalizedLevel)) return;\n\n // Apply sampling for high-volume events (only at 'full' level)\n if (!shouldSample(event)) return;\n\n try {\n await target.append(event);\n } catch (err) {\n // Best-effort: never let session logging break the agent.\n // The existing FileSessionWriter already does throttled warnings,\n // but we keep this wrapper silent by default to avoid log spam.\n // Callers that care can listen to EventBus 'session.damaged' etc.\n }\n },\n\n async appendBatch(events) {\n const target = resolveWriter();\n if (!target || events.length === 0) return;\n const allowed = events.filter(\n (e) => isAllowed(e.type, normalizedLevel) && shouldSample(e),\n );\n if (allowed.length === 0) return;\n try {\n await target.appendBatch(allowed);\n } catch {\n // best-effort — same contract as append()\n }\n },\n };\n}\n\n/** Convenience re-export of the allowed core set for tests/docs. */\nexport { CORE_RECONSTRUCT_EVENTS, STANDARD_AUDIT_EVENTS };\n\n/**\n * Safely extract the auditLevel from a (possibly partial) Config object.\n * Falls back to 'standard' if not present or invalid.\n */\nexport function resolveAuditLevel(\n cfg?: { session?: { auditLevel?: AuditLevel | undefined } | undefined } | null,\n): AuditLevel {\n const raw = cfg?.session?.auditLevel;\n if (raw === 'minimal' || raw === 'standard' || raw === 'full') {\n return raw;\n }\n return 'standard';\n}\n\n/**\n * Fully resolves the session logging configuration with sensible defaults.\n * This is the recommended way for the CLI / TUI / WebUI to read session config.\n */\nexport function resolveSessionLoggingConfig(\n cfg?: {\n session?: {\n auditLevel?: AuditLevel | undefined;\n sampling?: {\n toolProgress?: { sampleRate?: number | undefined };\n };\n };\n } | null,\n): {\n auditLevel: AuditLevel;\n sampling: {\n toolProgress: { sampleRate: number };\n };\n} {\n const session = cfg?.session ?? {};\n\n const auditLevel = resolveAuditLevel(cfg);\n\n const toolProgressSampleRate =\n session.sampling?.toolProgress?.sampleRate ?? 8;\n\n return {\n auditLevel,\n sampling: {\n toolProgress: {\n sampleRate: Math.max(1, Math.floor(toolProgressSampleRate)),\n },\n },\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/utils/atomic-write.ts","../../src/utils/message-invariants.ts","../../src/storage/session-store.ts","../../src/storage/queue-store.ts","../../src/storage/attachment-store.ts","../../src/types/memory.ts","../../src/storage/memory-backend.ts","../../src/storage/memory-store.ts","../../src/storage/memory-graph-backend.ts","../../src/storage/memory-consolidator.ts","../../src/types/errors.ts","../../src/storage/config-store.ts","../../src/utils/deep-merge.ts","../../src/security/secret-vault.ts","../../src/types/context-window.ts","../../src/utils/safe-json.ts","../../src/types/default-config.ts","../../src/storage/config-loader.ts","../../src/storage/config-migration.ts","../../src/storage/recovery-lock.ts","../../src/utils/regex-guard.ts","../../src/storage/session-reader.ts","../../src/utils/session-scoped-path.ts","../../src/storage/annotations-store.ts","../../src/replay/hash.ts","../../src/storage/replay-log-store.ts","../../src/storage/session-recovery.ts","../../src/storage/tool-audit-log.ts","../../src/storage/session-analyzer.ts","../../src/session-registry.ts","../../src/agent-status-tracker.ts","../../src/storage/session-rewinder.ts","../../src/storage/todos-checkpoint.ts","../../src/storage/plan-store.ts","../../src/storage/plan-templates.ts","../../src/storage/task-store.ts","../../src/storage/director-state.ts","../../src/utils/term.ts","../../src/utils/color.ts","../../src/utils/wstack-paths.ts","../../src/storage/goal-store.ts","../../src/storage/prompt-store.ts","../../src/storage/cloud-sync.ts","../../src/storage/session-event-bridge.ts"],"names":["path","fs","stat","resolve","randomBytes","path2","path3","fsp2","fsp3","path4","path5","fs2","writeFile","mkdir","fs3","deepMerge","fs5","path7","fsp5","path8","randomUUID","fs6","entry","fs7","path9","fs8","path10","createHash","stableStringify","fs9","sortKeys","path11","projectSlug","fs10","path12","fsp6","fsp7","fsp8","fsp9","fsp10","lock","hostname","open","os2","fsp11","fs11","path14","path15","fs12","relative"],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { randomBytes } from 'node:crypto';\nimport type { Dirent } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\nimport type {\n ResumedSession,\n SessionData,\n SessionEvent,\n SessionMetadata,\n SessionStore,\n SessionSummary,\n SessionWriter,\n} from '../types/session.js';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\n// ─── Session ID naming ───────────────────────────────────────────────────────\n\n/** Sanitize a model name for use in filenames: alphanumeric + dash + underscore. */\nfunction sanitizeModel(model: string): string {\n return model\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n\n/**\n * Generate a session ID in the format:\n * `YYYY-MM-DD/HH-MM-SSZ[_model]_xxxx.jsonl`\n *\n * Examples:\n * `2026-06-06/12-30-45Z_claude-sonnet_a1b2.jsonl`\n * `2026-06-06/14-22-10Z_a1b2.jsonl` (no model)\n *\n * The date prefix becomes a subdirectory so sessions group naturally by day.\n * The model name (when available) lets you see at a glance which provider was\n * used, without opening the file. The 4-byte random suffix prevents collisions\n * within the same second.\n */\nfunction generateSessionId(startedAt: string, model?: string): string {\n const date = startedAt.slice(0, 10); // \"2026-06-06\"\n const time = startedAt.slice(11, 19).replace(/:/g, '-'); // \"12-30-45\"\n const suffix = randomBytes(2).toString('hex'); // \"a1b2\"\n const modelPart = model ? `_${sanitizeModel(model)}` : '';\n return `${date}/${time}Z${modelPart}_${suffix}`;\n}\n\nexport interface SessionStoreOptions {\n dir: string;\n /** Optional EventBus for emitting session diagnostics. */\n events?: EventBus | undefined;\n /**\n * Optional secret scrubber. When set, `user_input` and `llm_response` event\n * content is scrubbed before being persisted to the JSONL log and the\n * summary sidecar — so a secret a user pastes or the model echoes does not\n * sit in cleartext on disk (and does not ride along in history cloud-sync).\n * Tool output is already scrubbed upstream by the executor; this closes the\n * conversation-turn gap (finding F-06).\n */\n secretScrubber?: SecretScrubber | undefined;\n}\n\nexport class DefaultSessionStore implements SessionStore {\n private readonly dir: string;\n private readonly events?: EventBus | undefined;\n private readonly secretScrubber?: SecretScrubber | undefined;\n\n constructor(opts: SessionStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.secretScrubber = opts.secretScrubber;\n }\n\n /** Absolute path to the session index file. */\n private get indexFile(): string {\n return path.join(this.dir, '_index.jsonl');\n }\n\n /** Join session ID to its absolute path within the store directory. */\n private sessionPath(id: string, ext: '.jsonl' | '.summary.json'): string {\n return path.join(this.dir, `${id}${ext}`);\n }\n\n /**\n * Ensure the directory implied by the session ID exists. When the ID\n * contains a date prefix like `2026-06-06/...`, this creates the date\n * subdirectory so sessions group naturally by day.\n */\n private async ensureShardDir(id: string): Promise<string> {\n const dirPath = path.dirname(path.join(this.dir, id));\n await ensureDir(dirPath);\n return dirPath;\n }\n\n async create(meta: Omit<SessionMetadata, 'startedAt'>): Promise<SessionWriter> {\n const startedAt = new Date().toISOString();\n const id =\n meta.id && meta.id.length > 0\n ? meta.id\n : generateSessionId(startedAt, meta.model ?? meta.provider);\n const shardDir = await this.ensureShardDir(id);\n const file = path.join(shardDir, `${path.basename(id)}.jsonl`);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n throw new Error(\n `Failed to open session file: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n try {\n return new FileSessionWriter(id, handle, startedAt, meta, this.events, {\n dir: shardDir,\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n });\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n throw err;\n }\n }\n\n async resume(id: string): Promise<ResumedSession> {\n const file = this.sessionPath(id, '.jsonl');\n const data = await this.load(id);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n throw new Error(\n `Failed to open session \"${id}\" for append: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n try {\n const writer = new FileSessionWriter(\n id,\n handle,\n new Date().toISOString(),\n {\n id,\n model: data.metadata.model,\n provider: data.metadata.provider,\n },\n this.events,\n {\n resumed: true,\n // Shard directory (sessions/<date>/) — must match create() so the\n // .summary.json sidecar lands next to the JSONL instead of the\n // sessions root (where summaryFor() would never find it).\n dir: path.dirname(file),\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n },\n );\n return { writer, data };\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n throw err;\n }\n }\n\n async load(id: string): Promise<SessionData> {\n const file = this.sessionPath(id, '.jsonl');\n const raw = await fsp.readFile(file, 'utf8');\n const lines = raw.split('\\n').filter((l) => l.trim());\n const events: SessionEvent[] = [];\n for (const line of lines) {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\n ) {\n events.push(parsed as SessionEvent);\n }\n } catch {\n // skip malformed JSON\n }\n }\n const meta = this.metaFromEvents(id, events);\n const { messages, usage } = this.replay(events, id);\n // Extract tool_call_end events for TUI tool entry rendering on resume.\n const toolCallEnds = extractToolCallEnds(events);\n return { metadata: meta, events, messages, usage, toolCallEnds };\n }\n\n async list(limit = 20): Promise<SessionSummary[]> {\n try {\n await ensureDir(this.dir);\n // Try the index first; fall back to directory scan if the index is\n // missing, empty, or unreadable.\n const indexed = await this.readIndex();\n if (indexed.length > 0) {\n indexed.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return indexed.slice(0, limit);\n }\n // Index unavailable — fall back to full directory scan + summary parse.\n const ids = await this.collectSessionIds(this.dir);\n const sessions = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const out = sessions.filter((s): s is SessionSummary => s !== null);\n out.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return out.slice(0, limit);\n } catch {\n return [];\n }\n }\n\n // ── Session index (_index.jsonl) ─────────────────────────────────────────\n //\n // One JSON line per closed session, appended atomically on close().\n // When a session is deleted, a tombstone {action:\"delete\",id:\"...\"} is\n // appended. On read, tombstones filter out matching session entries.\n // This keeps listing O(lines-in-index) instead of O(files-on-disk).\n //\n // The index auto-compacts every N appends to prevent unbounded growth\n // from tombstones and duplicate entries (resume cycles).\n\n private indexAppendCount = 0;\n private static readonly COMPACT_EVERY = 30;\n\n /** Append a session summary to the index. */\n private async appendToIndex(summary: SessionSummary): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify(summary) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n // Auto-compact the index periodically to remove tombstones and duplicates.\n if (this.indexAppendCount >= DefaultSessionStore.COMPACT_EVERY) {\n await this.compactIndex();\n this.indexAppendCount = 0;\n }\n } catch {\n // best-effort\n }\n }\n\n /** Append a tombstone entry for a deleted session. */\n private async writeTombstone(id: string): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify({ action: 'delete', id }) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n } catch {\n // best-effort\n }\n }\n\n /**\n * Compact the index: read all entries, drop tombstones, deduplicate\n * (keep latest per session), and rewrite. Atomic via temp+rename.\n */\n private async compactIndex(): Promise<void> {\n const entries = await this.readIndex();\n if (entries.length === 0) return;\n const tmp = `${this.indexFile}.compact.tmp`;\n const lines = entries.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n }\n\n /**\n * Read the index file and return deduplicated session summaries.\n * Entries with a matching tombstone are filtered out.\n * Returns empty array when the index doesn't exist or is corrupt.\n */\n private async readIndex(): Promise<SessionSummary[]> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.indexFile, 'utf8');\n } catch {\n return [];\n }\n const deleted = new Set<string>();\n const seen = new Map<string, SessionSummary>();\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as { action?: string | undefined; id?: string | undefined } & SessionSummary;\n if (entry.action === 'delete' && entry.id) {\n deleted.add(entry.id);\n seen.delete(entry.id);\n continue;\n }\n if (entry.id && !deleted.has(entry.id)) {\n // Keep the latest entry for each session (multiple appends on resume).\n seen.set(entry.id, entry as SessionSummary);\n }\n } catch {\n // skip corrupt lines\n }\n }\n return Array.from(seen.values());\n }\n\n /**\n * Rebuild the index from disk by scanning all sessions and writing a\n * fresh _index.jsonl. Useful after manual cleanup or index corruption.\n */\n async rebuildIndex(): Promise<number> {\n const ids = await this.collectSessionIds(this.dir);\n const summaries = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const valid = summaries.filter((s): s is SessionSummary => s !== null);\n // Atomic rewrite: write to temp, then rename.\n const tmp = `${this.indexFile}.tmp`;\n const lines = valid.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n return valid.length;\n }\n\n /** Recursively collect session IDs from date-shard subdirectories.\n * IDs include the date-prefix path (e.g. \"2026-06-06/17-46-57Z_…\").\n * Skips `.jsonl`/`.summary.json` root files, dot-files, and\n * sub-directories that belong to fleet/subagent sessions. */\n private async collectSessionIds(\n dir: string,\n prefix = '',\n depth = 0,\n ): Promise<string[]> {\n const ids: string[] = [];\n let entries: Dirent[];\n try {\n entries = await fsp.readdir(dir, { withFileTypes: true });\n } catch {\n return ids;\n }\n for (const entry of entries) {\n // Skip dot-files and known non-session directories\n if (entry.name.startsWith('.') && entry.name !== '.wrongstack') continue;\n if (entry.name === 'shared' || entry.name === 'subagents' || entry.name === 'attachments')\n continue;\n if (entry.isDirectory()) {\n // Date-shard directories become the prefix for their contents\n const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;\n ids.push(...(await this.collectSessionIds(path.join(dir, entry.name), childPrefix, depth + 1)));\n } else if (entry.isFile() && entry.name.endsWith('.jsonl')) {\n // Skip the session index itself — it's bookkeeping, not a session log.\n // (Only skip THIS file at root, not every root-level jsonl: flat/legacy\n // sessions and the test fixtures live directly under the sessions dir.)\n if (entry.name === '_index.jsonl') continue;\n const base = entry.name.replace(/\\.jsonl$/, '');\n // Subagent session logs live under subagents/ which we skip above.\n ids.push(prefix ? `${prefix}/${base}` : base);\n }\n }\n return ids;\n }\n\n private async summaryFor(id: string): Promise<SessionSummary> {\n const manifest = this.sessionPath(id, '.summary.json');\n try {\n const raw = await fsp.readFile(manifest, 'utf8');\n return JSON.parse(raw) as SessionSummary;\n } catch {\n const full = this.sessionPath(id, '.jsonl');\n const stat = await fsp.stat(full);\n const summary = await this.summarize(id, stat.mtime.toISOString());\n await atomicWrite(manifest, JSON.stringify(summary), { mode: 0o600 }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.manifest_write_failed',\n sessionId: id,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n return summary;\n }\n }\n\n /**\n * Delete a session and all associated files: JSONL, summary, plan/todos\n * sidecars, and the session directory (fleet.json, shared/, subagents/).\n *\n * Individual file deletions are best-effort (logged as structured warnings),\n * but a tombstone is always written so readIndex() filters this session out.\n * If the session directory itself can't be removed, the error is surfaced\n * to the caller so prune() can report it.\n */\n private async deleteSession(id: string): Promise<void> {\n const jsonlPath = this.sessionPath(id, '.jsonl');\n const summaryPath = this.sessionPath(id, '.summary.json');\n const shardDir = path.dirname(path.join(this.dir, id));\n const base = path.basename(id);\n const sessDir = path.join(shardDir, base);\n\n const deletions: Array<Promise<void>> = [\n fsp.unlink(jsonlPath),\n fsp.unlink(summaryPath),\n fsp.unlink(path.join(shardDir, `${base}.plan.json`)),\n fsp.unlink(path.join(shardDir, `${base}.todos.json`)),\n ];\n\n const results = await Promise.allSettled(deletions);\n for (const r of results) {\n if (r.status === 'rejected') {\n const msg = r.reason instanceof Error ? r.reason.message : String(r.reason);\n // ENOENT is expected (file may not exist — sidecars are optional).\n if ((r.reason as NodeJS.ErrnoException)?.code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.delete_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n }\n\n // Remove the session directory (may contain fleet.json, shared/, subagents/).\n await fsp.rm(sessDir, { recursive: true, force: true }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.rmdir_failed',\n sessionId: id,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n\n // Write an index tombstone so readIndex() filters this session out.\n await this.writeTombstone(id);\n }\n\n async delete(id: string): Promise<void> {\n await this.deleteSession(id);\n }\n\n async prune(maxAgeDays = 30): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 86_400_000;\n let deleted = 0;\n\n // Read the active session lock to avoid pruning the current session.\n let activeSessionId: string | null = null;\n try {\n const raw = await fsp.readFile(path.join(this.dir, 'active.json'), 'utf8');\n const active = JSON.parse(raw) as { sessionId?: string | undefined };\n activeSessionId = active.sessionId ?? null;\n } catch {\n // no active.json — nothing to protect\n }\n\n const isPrunableJsonl = (name: string): boolean =>\n name.endsWith('.jsonl') &&\n name !== '_index.jsonl' &&\n name !== '_mailbox.jsonl' &&\n !name.endsWith('.replay.jsonl') &&\n !name.endsWith('.audit.jsonl');\n\n const pruneFile = async (dir: string, name: string, prefix: string): Promise<void> => {\n const jsonlPath = path.join(dir, name);\n try {\n const stat = await fsp.stat(jsonlPath);\n if (stat.mtimeMs >= cutoff) return;\n } catch {\n return;\n }\n const base = name.replace(/\\.jsonl$/, '');\n const id = prefix ? `${prefix}/${base}` : base;\n // Never prune the currently active session.\n if (activeSessionId && id === activeSessionId) return;\n await this.deleteSession(id);\n deleted++;\n };\n\n const entries = await fsp.readdir(this.dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (entry.isFile()) {\n // Flat legacy sessions at the sessions root — pre-shard layout.\n // A shard-only scan left these accumulating forever.\n if (isPrunableJsonl(entry.name)) await pruneFile(this.dir, entry.name, '');\n continue;\n }\n if (!entry.isDirectory()) continue;\n // entry.name is a date-shard like \"2026-06-06\"\n const dateDir = path.join(this.dir, entry.name);\n const files = await fsp.readdir(dateDir, { withFileTypes: true }).catch(() => []);\n for (const file of files) {\n if (!file.isFile() || !isPrunableJsonl(file.name)) continue;\n await pruneFile(dateDir, file.name, entry.name);\n }\n }\n if (deleted > 0) {\n // Compact the index to remove tombstones for deleted sessions.\n await this.compactIndex().catch(() => undefined); /* best-effort */\n }\n // Clean up empty date-shard directories left behind after pruning.\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dateDir = path.join(this.dir, entry.name);\n try {\n const remaining = await fsp.readdir(dateDir);\n if (remaining.length === 0) {\n await fsp.rmdir(dateDir).catch(() => undefined);\n }\n } catch {\n // best-effort\n }\n }\n return deleted;\n }\n\n async clearHistory(id: string): Promise<void> {\n await this.ensureShardDir(id);\n const file = this.sessionPath(id, '.jsonl');\n const meta = this.sessionPath(id, '.summary.json');\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id,\n model: 'unknown',\n provider: 'unknown',\n })}\\n`;\n await fsp.writeFile(file, record, 'utf8');\n await fsp.unlink(meta).catch(() => undefined);\n }\n\n private async summarize(id: string, mtime: string): Promise<SessionSummary> {\n try {\n const data = await this.load(id);\n const firstUser = data.events.find((e) => e.type === 'user_input');\n const title =\n firstUser && firstUser.type === 'user_input'\n ? userInputTitle(firstUser.content)\n : '(empty session)';\n\n // Compute enriched stats from events.\n let iterationCount = 0;\n let toolCallCount = 0;\n let toolErrorCount = 0;\n let fileChangeCount = 0;\n const toolBreakdown: Record<string, number> = {};\n let outcome: SessionSummary['outcome'] ;\n const lastEvent = data.events[data.events.length - 1];\n\n for (const e of data.events) {\n if (e.type === 'in_flight_start') iterationCount++;\n else if (e.type === 'tool_call_start') {\n toolCallCount++;\n toolBreakdown[e.name] = (toolBreakdown[e.name] ?? 0) + 1;\n } else if (e.type === 'tool_result' && e.isError) toolErrorCount++;\n else if (e.type === 'file_snapshot') fileChangeCount += e.files.length;\n }\n\n // Determine outcome from the last event.\n if (lastEvent?.type === 'session_end') {\n outcome = 'completed';\n } else if (lastEvent?.type === 'in_flight_start') {\n outcome = 'aborted';\n } else if (data.events.some((e) => e.type === 'error')) {\n outcome = 'error';\n }\n\n return {\n id,\n title,\n startedAt: data.metadata.startedAt,\n endedAt: data.metadata.endedAt,\n model: data.metadata.model ?? 'unknown',\n provider: data.metadata.provider ?? 'unknown',\n tokenTotal: data.usage.input + data.usage.output,\n iterationCount: iterationCount > 0 ? iterationCount : undefined,\n toolCallCount: toolCallCount > 0 ? toolCallCount : undefined,\n toolErrorCount: toolErrorCount > 0 ? toolErrorCount : undefined,\n fileChangeCount: fileChangeCount > 0 ? fileChangeCount : undefined,\n toolBreakdown: Object.keys(toolBreakdown).length > 0 ? toolBreakdown : {},\n outcome,\n };\n } catch {\n return {\n id,\n title: '(damaged)',\n startedAt: mtime,\n model: 'unknown',\n provider: 'unknown',\n tokenTotal: 0,\n };\n }\n }\n\n private metaFromEvents(id: string, events: SessionEvent[]): SessionMetadata {\n const start = events.find((e) => e.type === 'session_start');\n // Use the LAST session_end: resume cycles append a new session_end on\n // every clean exit, and legacy /save commands wrote mid-stream markers.\n const end = events.findLast((e) => e.type === 'session_end');\n return {\n id,\n startedAt: start?.ts ?? new Date(0).toISOString(),\n endedAt: end?.ts,\n model: start?.model,\n provider: start?.provider,\n pendingToolUses: end?.pendingToolUses,\n };\n }\n\n private replay(\n events: SessionEvent[],\n sessionId = 'unknown',\n ): { messages: Message[]; usage: SessionData['usage'] } {\n const messages: Message[] = [];\n let usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n const openToolUses = new Set<string>();\n for (const e of events) {\n if (e.type === 'user_input') {\n openToolUses.clear();\n messages.push({ role: 'user', content: e.content, ts: e.ts });\n } else if (e.type === 'llm_response') {\n messages.push({ role: 'assistant', content: e.content, ts: e.ts });\n for (const b of e.content) {\n if (b.type === 'tool_use') openToolUses.add(b.id);\n }\n usage = {\n input: usage.input + (e.usage.input ?? 0),\n output: usage.output + (e.usage.output ?? 0),\n cacheRead: (usage.cacheRead ?? 0) + (e.usage.cacheRead ?? 0),\n cacheWrite: (usage.cacheWrite ?? 0) + (e.usage.cacheWrite ?? 0),\n };\n } else if (e.type === 'tool_result') {\n if (!openToolUses.has(e.id)) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `Orphan tool_result \"${e.id}\" has no matching tool_use`,\n });\n continue;\n }\n openToolUses.delete(e.id);\n // Provider protocol: tool_result blocks live in a USER message that\n // follows the assistant's tool_use turn — never inside the assistant\n // message itself (repairToolUseAdjacency would treat that as broken\n // adjacency and strip the tool_use blocks, silently dropping the\n // assistant turn on resume). Consecutive results from one turn are\n // grouped into a single user message.\n const resultBlock: ContentBlock = {\n type: 'tool_result',\n tool_use_id: e.id,\n content: typeof e.content === 'string' ? e.content : JSON.stringify(e.content),\n is_error: e.isError,\n };\n const last = messages[messages.length - 1];\n const lastIsToolResultUser =\n last?.role === 'user' &&\n Array.isArray(last.content) &&\n last.content.every((b) => (b as ContentBlock).type === 'tool_result');\n if (lastIsToolResultUser && Array.isArray(last.content)) {\n last.content.push(resultBlock);\n } else {\n messages.push({ role: 'user', content: [resultBlock], ts: e.ts });\n }\n }\n }\n if (openToolUses.size > 0) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `${openToolUses.size} tool_use blocks without matching results - replay repaired`,\n });\n }\n const repaired = repairToolUseAdjacency(messages);\n if (repaired.report.changed) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail:\n `Repaired replay adjacency: removed ${repaired.report.removedToolUses.length} tool_use, ` +\n `${repaired.report.removedToolResults.length} tool_result, ` +\n `${repaired.report.removedMessages} empty messages`,\n });\n }\n return { messages: repaired.messages, usage };\n }\n}\n\n/**\n * Extract tool execution records from `tool_call_end` events in the JSONL.\n * These are used by the TUI to render tool entries (name, duration, ok/error)\n * when a session is resumed. Events are returned in JSONL order (the order\n * they appear in the file, which is chronological insertion order).\n */\nfunction extractToolCallEnds(events: SessionEvent[]): SessionData['toolCallEnds'] {\n const result: SessionData['toolCallEnds'] = [];\n for (const e of events) {\n if (e.type === 'tool_call_end') {\n result.push({\n name: e.name,\n id: e.id,\n durationMs: e.durationMs,\n ok: e.ok ?? false,\n outputBytes: e.outputBytes,\n outputTokens: e.outputTokens,\n outputLines: e.outputLines,\n });\n }\n }\n return result;\n}\n\nclass FileSessionWriter implements SessionWriter {\n private closed = false;\n private closePromise: Promise<void> | null = null;\n private manifestFile: string;\n private summary: SessionSummary;\n private tokenIn = 0;\n private tokenOut = 0;\n private readonly filePath: string;\n get transcriptPath(): string | undefined {\n return this.filePath || undefined;\n }\n /**\n * Lazy session_start/session_resumed init, shared by all appenders.\n * A single promise (not a boolean) so a second append racing the first\n * can't push its event into the buffer BEFORE the first append's event —\n * every appender awaits the same init and resumes in FIFO call order.\n */\n private initPromise: Promise<void> | null = null;\n private ensureInit(): Promise<void> {\n if (!this.initPromise) this.initPromise = this.writeSessionStartLazy();\n return this.initPromise;\n }\n private readonly resumed: boolean;\n private appendFailCount = 0;\n private lastAppendWarnAt = 0;\n private readonly secretScrubber?: SecretScrubber | undefined;\n private readonly onCloseCb?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n\n // ── Write buffer — batches events to reduce per-event disk I/O ─────────\n //\n // Every append() pushes the scrubbed event into an in-memory buffer instead\n // of calling handle.appendFile() synchronously. The buffer flushes to disk\n // when it reaches FLUSH_SIZE events OR after FLUSH_INTERVAL_MS of inactivity.\n // This cuts the number of disk writes by ~95% without changing the on-disk\n // format — the JSONL is still one JSON object per line.\n private writeBuffer: SessionEvent[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly FLUSH_INTERVAL_MS = 500;\n private static readonly FLUSH_SIZE = 50;\n\n // ── Write serialization ─────────────────────────────────────────────────\n //\n // All disk writes are funneled through a FIFO promise chain. Without it,\n // a timer-driven flush racing an explicit flush()/close() issues two\n // concurrent appendFile() calls on the shared O_APPEND handle — the kernel\n // may complete them out of order (chronology breaks) or, for large\n // batches, interleave partial writes (torn JSONL lines). The chain keeps\n // exactly one write in flight; failures don't break the chain.\n private writeChain: Promise<void> = Promise.resolve();\n\n /** Enqueue a write on the FIFO chain. Resolves/rejects with that write. */\n private enqueueWrite(data: string): Promise<void> {\n const write = this.writeChain.then(() => this.handle.appendFile(data, 'utf8'));\n this.writeChain = write.then(\n () => undefined,\n () => undefined,\n );\n return write;\n }\n\n // ── Enriched summary tracking ──────────────────────────────────────────\n private iterationCount = 0;\n private toolCallCount = 0;\n private toolErrorCount = 0;\n private toolBreakdown: Record<string, number> = {};\n private fileChangeCount = 0;\n private compactionCount = 0;\n private outcome: SessionSummary['outcome'] = undefined;\n\n /**\n * Scrub secrets out of conversation-turn events before they are observed\n * for the summary, written to the JSONL log, or surfaced on resume. Only\n * `user_input` / `llm_response` carry free-form user/model text; other event\n * types either have no secret-bearing content or are already scrubbed\n * upstream (tool results). Returns the event unchanged when no scrubber is\n * configured.\n */\n private scrubEvent(event: SessionEvent): SessionEvent {\n const s = this.secretScrubber;\n if (!s) return event;\n if (event.type === 'user_input') {\n return {\n ...event,\n content:\n typeof event.content === 'string' ? s.scrub(event.content) : s.scrubObject(event.content),\n };\n }\n if (event.type === 'llm_response') {\n return { ...event, content: s.scrubObject(event.content) };\n }\n return event;\n }\n\n private pendingFileSnapshots: Array<{\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }> = [];\n /** Tracks open tool_use IDs during the current run to serialize on close for resume. */\n private openToolUses = new Set<string>();\n\n recordFileChange(input: {\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }): void {\n this.pendingFileSnapshots.push(input);\n }\n\n constructor(\n public readonly id: string,\n private handle: fsp.FileHandle,\n private readonly startedAt: string,\n private readonly meta: Omit<SessionMetadata, 'startedAt'>,\n private readonly events?: EventBus | undefined,\n opts: {\n resumed?: boolean | undefined;\n dir?: string | undefined;\n filePath?: string | undefined;\n secretScrubber?: SecretScrubber | undefined;\n /** Called on close() with the finalized summary for index/sidecar writes. */\n onClose?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n } = {},\n ) {\n this.resumed = opts.resumed ?? false;\n // id already contains a date-prefix shard (e.g. \"2026-06-06/17-46-57Z_…\").\n // opts.dir is the shard directory — join with basename so the manifest\n // lives next to the JSONL file instead of creating a double-nested path.\n this.manifestFile = opts.dir ? path.join(opts.dir, `${path.basename(id)}.summary.json`) : '';\n this.filePath = opts.filePath ?? '';\n this.secretScrubber = opts.secretScrubber;\n this.onCloseCb = opts.onClose;\n this.summary = {\n id,\n title: '(empty session)',\n startedAt,\n model: meta.model ?? 'unknown',\n provider: meta.provider ?? 'unknown',\n tokenTotal: 0,\n };\n }\n\n get pendingToolUses(): string[] {\n return Array.from(this.openToolUses);\n }\n\n private async writeSessionStartLazy(): Promise<void> {\n // Write through the SAME file handle that flushBuffer() uses — avoids\n // cross-fd issues on Windows where a separate fsp.writeFile can contend\n // with the already-open append-mode handle. The handle was opened with\n // O_APPEND so this write lands at the current end-of-file regardless of\n // whether the file is empty or already contains prior session data.\n const record = `${JSON.stringify({\n type: this.resumed ? 'session_resumed' : 'session_start',\n ts: this.startedAt,\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n try {\n await this.enqueueWrite(record);\n } catch {\n // best-effort\n }\n }\n\n async append(event: SessionEvent): Promise<void> {\n if (this.closed) return;\n await this.ensureInit();\n // Scrub before observing (the summary title is derived from user_input\n // content) and before buffering, so neither the JSONL nor the sidecar\n // ever holds a cleartext secret.\n const scrubbed = this.scrubEvent(event);\n // observeForSummary MUST run synchronously here — the summary counters\n // (toolCallCount, tokenIn/Out, outcome) drive the .summary.json sidecar\n // and the session index. Deferring observation to flush time would leave\n // the summary stale if close() fires before the next timer tick.\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n // Buffer full — flush immediately. Cancel any pending timer so we\n // don't double-flush on the next tick.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n async appendBatch(events: SessionEvent[]): Promise<void> {\n if (this.closed || events.length === 0) return;\n await this.ensureInit();\n for (const event of events) {\n const scrubbed = this.scrubEvent(event);\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n }\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n /**\n * Flush buffered events to disk immediately. Critical events\n * (user_input, llm_response) call this so they survive SIGKILL/crash\n * instead of sitting in the in-memory buffer for up to 500ms.\n *\n * Idempotent — cancels any pending timer and writes whatever has\n * accumulated in the buffer. Safe to call even when the buffer\n * is empty (no-op).\n */\n async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n }\n\n /** Schedule a deferred flush. No-op if a timer is already pending. */\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n this.flushBuffer().catch(() => {\n // flushBuffer already logs via the throttled-warning path;\n // this catch prevents an unhandled rejection in the timer callback.\n });\n }, FileSessionWriter.FLUSH_INTERVAL_MS);\n }\n\n /**\n * Flush all buffered events to disk as a single appendFile call.\n * Errors use the same throttled-warning pattern the old per-event\n * append path used — one warning every 5s with a suppressed count.\n * On failure the buffer is cleared (events are best-effort, same as\n * the old per-event path where a failed write was silently dropped).\n */\n private async flushBuffer(): Promise<void> {\n if (this.writeBuffer.length === 0) return;\n const eventCount = this.writeBuffer.length;\n const batch = this.writeBuffer.map((e) => JSON.stringify(e)).join('\\n') + '\\n';\n this.writeBuffer = [];\n try {\n await this.enqueueWrite(batch);\n } catch (err) {\n this.appendFailCount += eventCount;\n const now = Date.now();\n if (now - this.lastAppendWarnAt > 5000) {\n const suppressed = this.appendFailCount - 1;\n const tail = suppressed > 0 ? ` (+${suppressed} suppressed)` : '';\n console.warn(\n '[session] flush failed:',\n err instanceof Error ? err.message : String(err),\n tail,\n );\n this.lastAppendWarnAt = now;\n this.appendFailCount = 0;\n }\n }\n }\n\n private observeForSummary(event: SessionEvent): void {\n // Track open tool uses so we can serialize them on close for resume.\n // The authoritative source is the llm_response content (a core event,\n // always written at every audit level); the legacy 'tool_use' event is\n // kept for alternate writers that still emit it.\n if (event.type === 'llm_response') {\n for (const block of event.content) {\n if (block.type === 'tool_use') this.openToolUses.add(block.id);\n }\n }\n if (event.type === 'tool_use') {\n this.openToolUses.add(event.id);\n } else if (event.type === 'tool_call_start') {\n this.toolCallCount++;\n this.toolBreakdown[event.name] = (this.toolBreakdown[event.name] ?? 0) + 1;\n } else if (event.type === 'tool_result') {\n this.openToolUses.delete(event.id);\n if (event.isError) {\n this.toolErrorCount++;\n this.outcome = 'error';\n }\n } else if (event.type === 'file_snapshot') {\n this.fileChangeCount += event.files.length;\n } else if (event.type === 'compaction') {\n this.compactionCount++;\n }\n // Error events (provider errors, execution errors) mark the session as failed.\n if (event.type === 'error' || event.type === 'provider_error') {\n this.outcome = 'error';\n }\n if (event.type === 'user_input' && this.summary.title === '(empty session)') {\n this.summary = { ...this.summary, title: userInputTitle(event.content) };\n } else if (event.type === 'llm_response') {\n this.tokenIn += event.usage.input;\n this.tokenOut += event.usage.output;\n this.summary = { ...this.summary, tokenTotal: this.tokenIn + this.tokenOut };\n } else if (event.type === 'session_end') {\n const total = event.usage.input + event.usage.output;\n if (total > 0) this.summary = { ...this.summary, tokenTotal: total };\n } else if (event.type === 'in_flight_start') {\n this.iterationCount++;\n }\n }\n\n async close(): Promise<void> {\n // Idempotent AND awaitable: concurrent/repeat callers share the same\n // promise, so nobody proceeds (e.g. to tear down the session directory)\n // while the first close is still flushing.\n if (this.closePromise) return this.closePromise;\n this.closePromise = this.doClose();\n return this.closePromise;\n }\n\n private async doClose(): Promise<void> {\n this.closed = true;\n // Flush any buffered events before finalizing. The summary counters\n // (toolCallCount, tokenIn/Out, outcome) are already up to date because\n // observeForSummary runs synchronously on every append, but the JSONL\n // must have all events on disk before we write the .summary.json sidecar.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain any write enqueued outside flushBuffer (e.g. the lazy\n // session_start record) before the handle is closed.\n await this.writeChain;\n // Finalize the summary before writing.\n this.summary = {\n ...this.summary,\n endedAt: new Date().toISOString(),\n iterationCount: this.iterationCount,\n toolCallCount: this.toolCallCount,\n toolErrorCount: this.toolErrorCount,\n fileChangeCount: this.fileChangeCount,\n compactionCount: this.compactionCount > 0 ? this.compactionCount : undefined,\n toolBreakdown:\n { ...this.toolBreakdown },\n outcome: this.outcome ?? 'completed',\n };\n if (this.manifestFile) {\n try {\n await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 0o600 });\n } catch {\n // manifest write is best-effort\n }\n }\n // Notify the store so it can update the session index. Await so the\n // index write completes before close() resolves — otherwise the\n // fire-and-forget _index.jsonl append races callers that tear down the\n // session directory right after close() (e.g. ENOTEMPTY on Windows).\n try {\n await this.onCloseCb?.(this.summary);\n } catch {\n // best-effort\n }\n try {\n await this.handle.close();\n } catch {\n // ignore\n }\n }\n\n async writeCheckpoint(promptIndex: number, promptPreview: string): Promise<void> {\n const fileCount = this.pendingFileSnapshots.length;\n if (fileCount > 0) {\n await this.writeFileSnapshot(promptIndex, [...this.pendingFileSnapshots]);\n this.pendingFileSnapshots = [];\n }\n await this.append({\n type: 'checkpoint',\n ts: new Date().toISOString(),\n promptIndex,\n promptPreview,\n });\n this.events?.emit('checkpoint.written', {\n promptIndex,\n promptPreview,\n ts: new Date().toISOString(),\n fileCount,\n });\n }\n\n async writeFileSnapshot(\n promptIndex: number,\n files: import('../types/session.js').FileSnapshot[],\n ): Promise<void> {\n await this.append({\n type: 'file_snapshot',\n ts: new Date().toISOString(),\n promptIndex,\n files,\n });\n }\n\n async truncateToCheckpoint(targetPromptIndex: number): Promise<number> {\n if (!this.filePath) return 0;\n // Flush buffered events to disk before reading — otherwise the in-memory\n // events that haven't hit the JSONL yet would be invisible to the\n // truncation logic and would be silently dropped by the rewrite.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain the write chain so no in-flight write straddles the\n // close → rename → reopen sequence below.\n await this.writeChain;\n const raw = await fsp.readFile(this.filePath, 'utf8');\n const lines = raw.split('\\n');\n const kept: string[] = [];\n let removedCount = 0;\n\n let targetCheckpointLine = -1;\n let afterTarget = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = expectDefined(lines[i]);\n if (!line.trim()) continue;\n\n let event: { type?: string | undefined; promptIndex?: number | undefined };\n try {\n event = JSON.parse(line);\n } catch {\n kept.push(line);\n continue;\n }\n\n if (event.type === 'checkpoint') {\n if ((event as { promptIndex: number }).promptIndex === targetPromptIndex) {\n targetCheckpointLine = kept.length;\n afterTarget = true;\n } else if ((event as { promptIndex: number }).promptIndex > targetPromptIndex) {\n afterTarget = true;\n }\n }\n\n if (event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n removedCount++;\n } else if (event.promptIndex === undefined) {\n if (!afterTarget || targetCheckpointLine === -1) {\n kept.push(line);\n } else {\n removedCount++;\n }\n } else {\n kept.push(line);\n }\n }\n\n const truncated = kept.join('\\n');\n // Windows EPERM fix: close the append-mode handle, write via temp file\n // and rename, then reopen. This is needed because rename() fails on\n // Windows when the target has an open file handle.\n const tmpPath = `${this.filePath}.rewind.tmp`;\n await fsp.writeFile(tmpPath, truncated + '\\n', 'utf8');\n try {\n await this.handle.close();\n await fsp.rename(tmpPath, this.filePath);\n // Re-open in append mode for continued use of this file.\n this.handle = await fsp.open(this.filePath, 'a', 0o600);\n } catch (err) {\n await fsp.unlink(tmpPath).catch(() => undefined);\n throw err;\n }\n\n await this.append({\n type: 'rewound',\n ts: new Date().toISOString(),\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n });\n\n this.events?.emit('session.rewound', {\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n removedEvents: removedCount,\n });\n\n return removedCount;\n }\n\n async clearSession(): Promise<void> {\n if (!this.filePath) return;\n // Discard any buffered events — the caller is explicitly resetting the\n // session to a clean slate. Cancel the timer so it doesn't fire and\n // append stale events to the freshly-cleared file.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.writeBuffer = [];\n // Let any in-flight append land first — otherwise it would re-append\n // stale events AFTER the reset record below.\n await this.writeChain;\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n await fsp.writeFile(this.filePath, record, 'utf8');\n }\n\n /**\n * Idea #1 — write an in-flight marker. The agent loop should call\n * this at the start of each long-running operation; a matching\n * `clearInFlightMarker` follows on clean exit. A stale marker\n * (no end) is what `SessionRecovery.detectStale` looks for.\n */\n async writeInFlightMarker(context: string): Promise<void> {\n if (!context || context.length > 500) {\n throw new Error('In-flight context must be 1..500 chars');\n }\n await this.append({\n type: 'in_flight_start',\n ts: new Date().toISOString(),\n context,\n });\n this.events?.emit('in_flight.started', { context, ts: new Date().toISOString() });\n }\n\n /**\n * Idea #1 — close the in-flight marker. Idempotent in spirit\n * (you can call it after a successful iteration even if you\n * didn't open one this round) — but the session log records\n * every call so postmortem tooling can see \"the agent finished\n * cleanly X times, then died without finishing Y\".\n */\n async clearInFlightMarker(reason: 'clean' | 'aborted' | 'recovered'): Promise<void> {\n await this.append({\n type: 'in_flight_end',\n ts: new Date().toISOString(),\n reason,\n });\n this.events?.emit('in_flight.ended', { reason, ts: new Date().toISOString() });\n }\n}\n\nfunction userInputTitle(content: string | ContentBlock[]): string {\n const text =\n typeof content === 'string'\n ? content\n : content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join(' ');\n return (text || '(non-text input)').slice(0, 60);\n}\n","import * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ContentBlock } from '../types/blocks.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * The persisted form of a single queued user message. The TUI's\n * in-memory QueueItem has a render id; that's pure UI bookkeeping, so\n * we drop it when serializing — fresh ids are assigned on rehydrate.\n */\nexport interface PersistedQueueItem {\n displayText: string;\n blocks: ContentBlock[];\n}\n\n/**\n * Side-file storage for a session's pending input queue. Lives at\n * `<sessionDir>/queue.json` next to the attachment spool. Reads are\n * tolerant (missing/malformed file → empty array); writes are atomic\n * (tmp + rename) so a crash mid-write can never leave a partial file\n * the next launch would choke on.\n *\n * The contract is \"snapshot replacement\": every mutation hands the\n * full queue and we rewrite the file. The queue is small (rarely more\n * than a handful of messages), so this is cheaper than delta logging\n * and avoids the replay complexity.\n */\nexport class QueueStore {\n private readonly file: string;\n\n constructor(opts: { dir: string }) {\n this.file = path.join(opts.dir, 'queue.json');\n }\n\n async write(items: PersistedQueueItem[]): Promise<void> {\n if (items.length === 0) {\n // Empty queue → remove the file rather than write `[]`. Keeps\n // a clean idle state on disk and makes `read()` cheaper.\n await this.clear();\n return;\n }\n await atomicWrite(this.file, JSON.stringify(items), { mode: 0o600 });\n }\n\n async read(): Promise<PersistedQueueItem[]> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return [];\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.read_failed',\n path: this.file,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n if (!Array.isArray(parsed)) return [];\n const out: PersistedQueueItem[] = [];\n for (const v of parsed) {\n if (isPersistedQueueItem(v)) out.push(v);\n }\n return out;\n }\n\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n // Best-effort: a permission/lock error during clear is rare and\n // the queue slash command is non-critical. Warn so it's observable\n // but don't throw so the slash command doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.clear_failed',\n path: this.file,\n message: (err as Error).message,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n}\n\nfunction isPersistedQueueItem(v: unknown): v is PersistedQueueItem {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return typeof o['displayText'] === 'string' && Array.isArray(o['blocks']);\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type {\n AddAttachmentInput,\n Attachment,\n AttachmentKind,\n AttachmentRef,\n AttachmentStore,\n} from '../types/attachment.js';\nimport type { ContentBlock } from '../types/blocks.js';\n\nexport interface AttachmentStoreOptions {\n /**\n * Directory for spooling payloads larger than `spoolThresholdBytes`.\n * When omitted, all payloads stay in memory.\n */\n spoolDir?: string | undefined;\n spoolThresholdBytes?: number | undefined;\n}\n\nconst DEFAULT_SPOOL_THRESHOLD = 256 * 1024; // 256 KB\n// Two placeholder shapes:\n// - seq-keyed `[<kind> #<seq>…]` — kind is `pasted` / `image` / `file`. A\n// cosmetic suffix after the seq (e.g. `, 123 lines`) is tolerated so the\n// TUI can render `[pasted #1, 123 lines]` while still resolving by seq.\n// - path-keyed `[file:<path>]` — resolves to the most recent file ref whose\n// stored path matches, so the TUI can show a human-readable file chip.\nconst PLACEHOLDER_RE = /\\[(pasted|image|file) #(\\d+)[^\\]]*\\]|\\[file:([^\\]]+)\\]/g;\n\n/**\n * In-memory attachment store with optional disk spool. Placeholder syntax\n * is `[<kind> #<seq>]` (seq-keyed) or `[file:<path>]` (path-keyed) where kind\n * is `pasted` / `image` / `file`. Unknown placeholders are passed through\n * as-is so users can write that literal text without losing it.\n */\nexport class DefaultAttachmentStore implements AttachmentStore {\n private readonly items = new Map<string, Attachment>();\n private readonly refs: AttachmentRef[] = [];\n private nextSeq: Record<AttachmentKind, number> = { text: 0, image: 0, file: 0 };\n private readonly spoolDir: string | undefined;\n private readonly spoolThreshold: number;\n\n constructor(opts: AttachmentStoreOptions = {}) {\n this.spoolDir = opts.spoolDir;\n this.spoolThreshold = opts.spoolThresholdBytes ?? DEFAULT_SPOOL_THRESHOLD;\n }\n\n async add(input: AddAttachmentInput): Promise<AttachmentRef> {\n const seq = ++this.nextSeq[input.kind];\n const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes(3).toString('hex')}`;\n const bytes = Buffer.byteLength(input.data, input.kind === 'image' ? 'base64' : 'utf8');\n let spooledPath: string | undefined;\n let data: string | undefined = input.data;\n if (this.spoolDir && bytes >= this.spoolThreshold) {\n await fsp.mkdir(this.spoolDir, { recursive: true });\n spooledPath = path.join(this.spoolDir, `${id}.bin`);\n // atomicWrite: torn spool would silently corrupt the attachment;\n // the user would see garbled output the next time it's expanded.\n await atomicWrite(spooledPath, input.data, {\n encoding: input.kind === 'image' ? 'base64' : 'utf8',\n });\n data = undefined;\n }\n const att: Attachment = {\n id,\n kind: input.kind,\n meta: input.meta ?? {},\n data,\n path: spooledPath,\n bytes,\n createdAt: new Date().toISOString(),\n };\n this.items.set(id, att);\n const ref: AttachmentRef = { id, kind: input.kind, seq, meta: att.meta };\n this.refs.push(ref);\n return ref;\n }\n\n async get(id: string): Promise<Attachment | undefined> {\n return this.items.get(id);\n }\n\n list(): AttachmentRef[] {\n return [...this.refs];\n }\n\n async expand(text: string): Promise<ContentBlock[]> {\n const matches = [...text.matchAll(PLACEHOLDER_RE)];\n if (matches.length === 0) return text ? [{ type: 'text', text }] : [];\n const blocks: ContentBlock[] = [];\n let lastIndex = 0;\n for (const m of matches) {\n const idx = m.index ?? 0;\n const before = text.slice(lastIndex, idx);\n if (before) blocks.push({ type: 'text', text: before });\n let ref: AttachmentRef | undefined;\n if (m[3] !== undefined) {\n // Path-keyed `[file:<path>]` — most recent matching file ref wins.\n const wantPath = m[3];\n ref = findLast(this.refs, (r) => r.kind === 'file' && refPath(r) === wantPath);\n } else {\n const kind = prefixToKind(m[1] as string);\n const seq = Number(m[2]);\n ref = this.refs.find((r) => r.kind === kind && r.seq === seq);\n }\n const att = ref ? this.items.get(ref.id) : undefined;\n if (!att) {\n blocks.push({ type: 'text', text: m[0] });\n } else {\n blocks.push(await this.toBlock(att));\n }\n lastIndex = idx + m[0].length;\n }\n const tail = text.slice(lastIndex);\n if (tail) blocks.push({ type: 'text', text: tail });\n return mergeAdjacentText(blocks);\n }\n\n async clear(): Promise<void> {\n // Unlink any spooled files so we don't leak disk space.\n if (this.spoolDir) {\n const toDelete: string[] = [];\n for (const att of this.items.values()) {\n if (att.path) toDelete.push(att.path);\n }\n await Promise.all(toDelete.map((p) => fsp.unlink(p).catch(() => undefined)));\n }\n this.items.clear();\n this.refs.length = 0;\n this.nextSeq = { text: 0, image: 0, file: 0 };\n }\n\n private async toBlock(att: Attachment): Promise<ContentBlock> {\n if (att.kind === 'image') {\n const data =\n att.data ?? (att.path ? await fsp.readFile(att.path, { encoding: 'base64' }) : '');\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: att.meta.mediaType ?? 'image/png',\n data,\n },\n };\n }\n const raw = att.data ?? (att.path ? await fsp.readFile(att.path, 'utf8') : '');\n const label = att.meta.filename ? `<file path=\"${att.meta.filename}\">` : '<pasted>';\n const close = att.meta.filename ? '</file>' : '</pasted>';\n return { type: 'text', text: `${label}\\n${raw}\\n${close}` };\n }\n}\n\nfunction kindPrefix(kind: AttachmentKind): string {\n return kind === 'text' ? 'pasted' : kind;\n}\n\nfunction prefixToKind(prefix: string): AttachmentKind {\n if (prefix === 'pasted') return 'text';\n if (prefix === 'image') return 'image';\n return 'file';\n}\n\n/** Path a file ref was registered under, for `[file:<path>]` lookup. */\nfunction refPath(ref: AttachmentRef): string | undefined {\n return ref.meta.filename ?? ref.meta.label;\n}\n\n/** Last element matching the predicate (Node < 20 lacks Array.findLast). */\nfunction findLast<T>(arr: readonly T[], pred: (v: T) => boolean): T | undefined {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (pred(arr[i] as T)) return arr[i];\n }\n return undefined;\n}\n\nfunction mergeAdjacentText(blocks: ContentBlock[]): ContentBlock[] {\n const out: ContentBlock[] = [];\n for (const b of blocks) {\n const prev = out[out.length - 1];\n if (b.type === 'text' && prev && prev.type === 'text') {\n prev.text += b.text;\n } else {\n out.push(b);\n }\n }\n return out;\n}\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { MEMORY_TYPE_LABELS, type MemoryPriority, type MemoryType } from '../types/memory.js';\nimport { atomicWrite, ensureDir, withFileLock } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\n// ── Backend interface ──────────────────────────────────────────────────\n\nexport interface MemoryBackend {\n readonly kind: string;\n remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void>;\n forget(scope: MemoryScope, query: string, filePath: string): Promise<number>;\n readAll(scope: MemoryScope, filePath: string): Promise<string>;\n list(scope: MemoryScope, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n search(scope: MemoryScope, query: string, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n /** Find memories related to the given text via graph traversal. Optional — falls back to search. */\n findRelated?(scope: MemoryScope, filePath: string, text: string, limit: number): Promise<MemoryEntry[]>;\n clear(scope: MemoryScope, filePath: string): Promise<void>;\n consolidate(scope: MemoryScope, filePath: string): Promise<number>;\n}\n\n// ── Entry serialization format ─────────────────────────────────────────\n//\n// Full format:\n// - [ISO] [TYPE|PRIORITY] mem_<id> text content #tag1 #tag2\n//\n// Examples:\n// - [2026-06-07T...] mem_1234_abcd Project uses pnpm #pnpm #build\n// - [2026-06-07T...] [convention|high] mem_5678_ef01 Use conventional commits #git #commit\n//\n// Old format (backward compatible):\n// - [ISO] mem_<id> text content\n\nconst TYPE_PRIORITY_RE = /^\\[(\\w+)\\|(\\w+)\\]\\s+/;\nconst TAG_RE = /#([\\w-]+)/g;\n\nfunction formatMetadata(entry: MemoryEntry): string {\n const parts: string[] = [];\n if (entry.type && entry.priority) {\n parts.push(`[${entry.type}|${entry.priority}]`);\n } else if (entry.type) {\n parts.push(`[${entry.type}]`);\n } else if (entry.priority) {\n parts.push(`[${entry.priority}]`);\n }\n if (entry.tags && entry.tags.length > 0) {\n parts.push(entry.tags.map((t) => `#${t}`).join(' '));\n }\n return parts.length > 0 ? ` ${parts.join(' ')}` : '';\n}\n\nfunction lineToEntry(line: string, scope: MemoryScope): MemoryEntry | null {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- [')) return null;\n\n // Parse timestamp: `- [ISO] ...`\n const tsMatch = trimmed.match(/^-\\s*\\[([^\\]]+)\\]/);\n if (!tsMatch) return null;\n const ts = tsMatch[1] ?? '';\n\n let rest = trimmed.slice(tsMatch[0].length).trim();\n\n // Parse optional type|priority: `[convention|high]` or `[fact]`\n let type: MemoryType | undefined;\n let priority: MemoryPriority | undefined;\n const tpMatch = rest.match(TYPE_PRIORITY_RE);\n if (tpMatch) {\n const a = tpMatch[1] ?? '';\n const b = tpMatch[2] ?? '';\n if (isMemoryType(a)) {\n type = a;\n priority = isPriority(b) ? b : undefined;\n } else if (isPriority(a)) {\n priority = a;\n }\n rest = rest.slice(tpMatch[0].length).trim();\n }\n\n // Parse optional entry ID: `mem_<ts>_<rand>`\n const idMatch = rest.match(/^mem_\\d+_\\w+\\s+/);\n let text: string;\n if (idMatch) {\n text = rest.slice(idMatch[0].length).trim();\n } else {\n text = rest.trim();\n }\n\n // Extract #tags from text\n const tags: string[] = [];\n let tagMatch: RegExpExecArray | null;\n TAG_RE.lastIndex = 0;\n // biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop\n while ((tagMatch = TAG_RE.exec(text)) !== null) {\n tags.push(tagMatch[1] ?? '');\n }\n // Remove tags from display text\n const cleanText = text.replace(TAG_RE, '').replace(/\\s{2,}/g, ' ').trim();\n\n if (!cleanText) return null;\n\n return {\n scope,\n text: cleanText,\n ts,\n type,\n priority,\n tags: tags.length > 0 ? tags : undefined,\n };\n}\n\nfunction isMemoryType(s: string): s is MemoryType {\n return s in MEMORY_TYPE_LABELS;\n}\n\nfunction isPriority(s: string): s is MemoryPriority {\n return s === 'critical' || s === 'high' || s === 'medium' || s === 'low';\n}\n\n// ── File-based backend ─────────────────────────────────────────────────\n\nexport interface FileMemoryBackendOptions {\n paths: WstackPaths;\n}\n\nexport class FileMemoryBackend implements MemoryBackend {\n readonly kind = 'file';\n private readonly files: Record<MemoryScope, string>;\n\n constructor(opts: FileMemoryBackendOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n }\n\n private resolveFile(filePath: string, scope: MemoryScope): string {\n return filePath || this.files[scope];\n }\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await ensureDir(path.dirname(file));\n let existing = '';\n try { existing = await fs.readFile(file, 'utf8'); } catch { /* new file */ }\n\n const id = `mem_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const meta = formatMetadata(entry);\n const line = `\\n- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\\n/g, ' ')}\\n`;\n const next = existing.trim()\n ? existing.replace(/\\n+$/, '') + line\n : `# Agent Memory\\n${line}`;\n await atomicWrite(file, next);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n return withFileLock(file, async () => {\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const needle = query.toLowerCase();\n const idMatcher = /mem_\\d+_\\w+/;\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n if (idMatcher.test(query)) {\n const entryIdMatch = /mem_\\d+_\\w+/.exec(trimmed);\n if (entryIdMatch && entryIdMatch[0] === query) { removed++; return false; }\n }\n if (trimmed.toLowerCase().includes(needle)) { removed++; return false; }\n return true;\n });\n if (removed > 0) {\n if (lines.length === 0 || (lines.length === 1 && !lines[0]?.trim())) {\n await atomicWrite(file, '');\n } else {\n await atomicWrite(file, lines.join('\\n'));\n }\n }\n return removed;\n });\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n const file = this.resolveFile(filePath, scope);\n try { return await fs.readFile(file, 'utf8'); } catch { return ''; /* best-effort */ }\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const raw = await this.readAll(scope, filePath);\n if (!raw.trim()) return [];\n const entries = parseEntries(raw, scope);\n return limit ? entries.slice(0, limit) : entries;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const entries = await this.list(scope, filePath);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Score by word overlap + tag match\n const scored = entries.map((e) => {\n const words = e.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n // Tag matches are weighted higher\n if (e.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n return { entry: e, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await atomicWrite(file, '');\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const seen = new Set<string>();\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n // Normalize: strip timestamp, ID, type|priority, tags\n const norm = trimmed\n .replace(/\\[[^\\]]+\\]/g, '')\n .replace(/\\bmem_\\d+_\\w+\\s*/, '')\n .replace(/#[\\w-]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .toLowerCase();\n if (seen.has(norm)) { removed++; return false; }\n seen.add(norm);\n return true;\n });\n\n const next = lines.join('\\n');\n const backup = `${file}.bak.${Date.now()}`;\n try { await fs.copyFile(file, backup); } catch { /* best-effort */ }\n try { await atomicWrite(file, next); } catch { return 0; /* best-effort */ }\n return removed;\n }\n}\n\n// ── Entry parsing ──────────────────────────────────────────────────────\n\nexport function parseEntries(raw: string, scope: MemoryScope = 'project-memory'): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n for (const line of raw.split('\\n')) {\n const entry = lineToEntry(line, scope);\n if (entry) entries.push(entry);\n }\n return entries.reverse(); // newest first\n}\n","import type {\n MemoryClearedPayload,\n MemoryConsolidatedPayload,\n MemoryEntry,\n MemoryForgottenPayload,\n MemoryRelevanceContext,\n MemoryRememberedPayload,\n MemoryScope,\n MemoryStore,\n ScoredEntry,\n} from '../types/memory.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport { type MemoryBackend, FileMemoryBackend } from './memory-backend.js';\n\nconst MAX_BYTES_TOTAL = 32_000; // ~8K tokens\n\nexport interface MemoryStoreOptions {\n paths: WstackPaths;\n /**\n * Optional event bus — when provided, mutations emit events so plugins\n * and other subsystems can react to memory changes.\n */\n events?: EventBus | undefined;\n /**\n * Storage backend. Defaults to FileMemoryBackend when omitted.\n * Plugins can register a custom backend (graph, semantic, vector)\n * via the DI container to override storage behavior.\n */\n backend?: MemoryBackend | undefined;\n}\n\n/**\n * Three scopes:\n * project-agents → <project>/.wrongstack/AGENTS.md (committed)\n * project-memory → ~/.wrongstack/projects/<hash>/memory.md (per-project agent notes)\n * user-memory → ~/.wrongstack/memory.md (global personal memory)\n */\nexport class DefaultMemoryStore implements MemoryStore {\n private readonly files: Record<MemoryScope, string>;\n private readonly events?: EventBus | undefined;\n private readonly backend: MemoryBackend;\n\n /**\n * Per-scope serialization queue. `remember` / `forget` / `consolidate` /\n * `clear` are read-modify-write against a single file; without a lock,\n * two concurrent calls on the same scope can read the same baseline and\n * the later write silently drops the earlier entry. We chain each\n * mutation onto the prior promise for the same scope so they run in\n * issue order. Different scopes still proceed in parallel.\n *\n * The chain tracks only the last pending write. If a write fails, its\n * error is caught and swallowed so the chain stays alive for subsequent\n * calls. The error is stored in `writeErrors` so callers can learn about\n * it on the next read operation.\n */\n private readonly writeChain = new Map<MemoryScope, Promise<unknown>>();\n /** Last write error per scope — surfaced as warnings on the next readAll(). */\n private readonly writeErrors = new Map<MemoryScope, Error>();\n\n /**\n * When the global root is a temporary directory (opencode, CI sandboxes),\n * memory files are also mirrored to the project tree so they survive\n * session cleanup. The primary path stays in the temp root for isolation;\n * this backup ensures memory is never lost.\n */\n private readonly persistBackup: boolean;\n private readonly backupDir: string;\n\n constructor(opts: MemoryStoreOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n this.events = opts.events;\n this.backend = opts.backend ?? new FileMemoryBackend({ paths: opts.paths });\n\n // Detect temporary global roots: opencode, CI, test sandboxes.\n // When detected, mirror writes to the project's .wrongstack/ dir.\n const root = opts.paths.globalRoot.toLowerCase();\n this.persistBackup = /[/\\\\](tmp|temp|cache)[/\\\\]/.test(root);\n this.backupDir = this.persistBackup\n ? opts.paths.inProjectAgentsFile.replace(/AGENTS\\.md$/, 'memory-persist')\n : '';\n }\n\n /** Expose the backend for plugin introspection and advanced queries. */\n getBackend(): MemoryBackend {\n return this.backend;\n }\n\n private async runSerialized<T>(scope: MemoryScope, work: () => Promise<T>): Promise<T> {\n const prior = this.writeChain.get(scope) ?? Promise.resolve();\n // Chain: catch errors from the prior write, then run the next work item.\n const next = prior\n .catch((err) => {\n this.writeErrors.set(scope, err as Error);\n })\n .then(() => work());\n this.writeChain.set(scope, next as Promise<unknown>);\n try {\n return await next;\n } catch (err) {\n this.writeErrors.set(scope, err as Error);\n throw err;\n } finally {\n if (this.writeChain.get(scope) === next) {\n this.writeChain.delete(scope);\n }\n }\n }\n\n async readAll(): Promise<string> {\n const parts: string[] = [];\n for (const scope of ['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]) {\n const writeErr = this.writeErrors.get(scope);\n if (writeErr) {\n parts.push(`> ⚠️ Memory write error (${labelOf(scope)}): ${writeErr.message}`);\n }\n const body = await this.backend.readAll(scope, this.files[scope]);\n if (body.trim()) parts.push(`## ${labelOf(scope)}\\n\\n${body.trim()}`);\n }\n return parts.join('\\n\\n');\n }\n\n async read(scope: MemoryScope): Promise<string> {\n return this.backend.readAll(scope, this.files[scope]);\n }\n\n /**\n * List entries from a scope, newest first. Delegates to the backend\n * so graph/semantic backends can return enriched or filtered results.\n */\n async list(scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.list(scope, this.files[scope], limit);\n }\n\n /**\n * Find memories related to the given text via graph traversal.\n * Falls back to content search when no graph backend is available.\n */\n async findRelated(text: string, scope: MemoryScope = 'project-memory', limit = 5): Promise<MemoryEntry[]> {\n if (this.backend.findRelated) {\n return this.backend.findRelated(scope, this.files[scope], text, limit);\n }\n return this.search(text, scope, limit);\n }\n\n async search(query: string, scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.search(scope, query, this.files[scope], limit);\n }\n\n async remember(\n text: string,\n scope: MemoryScope = 'project-memory',\n metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>,\n ): Promise<void> {\n const ts = new Date().toISOString();\n return this.runSerialized(scope, async () => {\n const entry: MemoryEntry = { scope, text, ts, ...metadata };\n await this.backend.remember(scope, entry, this.files[scope]);\n\n // Size check — consolidate if the file exceeds the cap.\n const raw = await this.backend.readAll(scope, this.files[scope]);\n if (Buffer.byteLength(raw, 'utf8') > MAX_BYTES_TOTAL) {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n }\n }\n\n // Mirror to persistent backup when running in a temp sandbox.\n await this.mirrorBackup(scope);\n\n this.events?.emit('memory.remembered', {\n scope,\n text,\n ts,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n } satisfies MemoryRememberedPayload);\n });\n }\n\n /**\n * Score and rank memories by relevance to the current context.\n * Returns entries with score >= MIN_RELEVANCE_SCORE, sorted highest first.\n */\n async scoreRelevant(\n ctx: MemoryRelevanceContext,\n scope: MemoryScope = 'project-memory',\n limit = 8,\n ): Promise<ScoredEntry[]> {\n const all = await this.list(scope);\n if (all.length === 0) return [];\n\n const taskWords = ctx.currentTask.toLowerCase().split(/\\s+/).filter((w) => w.length > 2);\n const skillWords = (ctx.activeSkills ?? []).flatMap((s) => s.split('-'));\n const toolWords = (ctx.toolNames ?? []).flatMap((t) => t.toLowerCase().split('_'));\n const now = Date.now();\n\n const scored: ScoredEntry[] = [];\n\n for (const entry of all) {\n let score = 0;\n const reasons: string[] = [];\n const textLower = entry.text.toLowerCase();\n const tagsLower = (entry.tags ?? []).map((t) => t.toLowerCase());\n\n // Word overlap with current task (primary signal)\n let taskHits = 0;\n for (const w of taskWords) {\n if (textLower.includes(w)) { taskHits++; score += 2; }\n if (tagsLower.some((t) => t.includes(w))) { taskHits++; score += 3; }\n }\n if (taskHits > 0) reasons.push(`task match (${taskHits})`);\n\n // Skill/tool relevance\n let skillHits = 0;\n for (const w of skillWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n skillHits++;\n }\n }\n score += skillHits;\n if (skillHits > 0) reasons.push(`skill match (${skillHits})`);\n\n for (const w of toolWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n score += 1;\n reasons.push(`tool mention: ${w}`);\n }\n }\n\n // Priority boost\n switch (entry.priority) {\n case 'critical': score += 5; reasons.push('critical'); break;\n case 'high': score += 3; reasons.push('high priority'); break;\n case 'medium': score += 1; break;\n case 'low': score -= 2; reasons.push('low priority'); break;\n }\n\n // Type boost — decisions, conventions, anti-patterns are high-value\n switch (entry.type) {\n case 'decision': score += 2; reasons.push('decision'); break;\n case 'convention': score += 2; reasons.push('convention'); break;\n case 'anti_pattern': score += 3; reasons.push('anti-pattern'); break;\n case 'preference': score += 1; reasons.push('preference'); break;\n case 'reference': break;\n case 'fact': break;\n }\n\n // Recency boost — newer entries get +1, very old get 0\n const ageDays = (now - new Date(entry.ts).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays < 1) score += 1;\n else if (ageDays > 30) score -= 1;\n\n // Confidence penalty\n if (entry.confidence !== undefined && entry.confidence < 0.5) {\n score -= 2;\n reasons.push('low confidence');\n }\n\n // Repetition avoidance — recently accessed entries get slight penalty\n if (entry.lastAccessed) {\n const hoursSinceAccess = (now - new Date(entry.lastAccessed).getTime()) / (1000 * 60 * 60);\n if (hoursSinceAccess < 1) score -= 1;\n }\n\n if (score > 0) {\n scored.push({\n ...entry,\n score,\n matchReason: reasons.join(', ') || 'keyword match',\n });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n\n // Filter to entries that meet the minimum relevance threshold.\n // Critical or high-priority entries always pass.\n const threshold = 2;\n const relevant = scored.filter(\n (s) => s.score >= threshold || s.priority === 'critical' || s.priority === 'high',\n );\n\n return relevant.slice(0, Math.min(limit, 15));\n }\n\n async forget(query: string, scope: MemoryScope = 'project-memory'): Promise<number> {\n return this.runSerialized(scope, async () => {\n const removed = await this.backend.forget(scope, query, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.forgotten', {\n scope,\n query,\n removed,\n } satisfies MemoryForgottenPayload);\n await this.mirrorBackup(scope);\n }\n return removed;\n });\n }\n\n async consolidate(scope: MemoryScope): Promise<void> {\n return this.runSerialized(scope, async () => {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n await this.mirrorBackup(scope);\n }\n });\n }\n\n async clear(scope?: MemoryScope): Promise<void> {\n if (scope) {\n await this.runSerialized(scope, async () => {\n await this.backend.clear(scope, this.files[scope]);\n this.events?.emit('memory.cleared', { scope } satisfies MemoryClearedPayload);\n await this.mirrorBackup(scope);\n });\n return;\n }\n await Promise.all(\n (['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]).map((s) =>\n this.runSerialized(s, async () => {\n await this.backend.clear(s, this.files[s]);\n this.events?.emit('memory.cleared', { scope: s } satisfies MemoryClearedPayload);\n await this.mirrorBackup(s);\n }),\n ),\n );\n }\n\n /** Mirror current memory content to the persistent backup directory. */\n private async mirrorBackup(scope: MemoryScope): Promise<void> {\n if (!this.persistBackup || scope === 'project-agents') return;\n try {\n const content = await this.backend.readAll(scope, this.files[scope]);\n const { writeFile, mkdir } = await import('node:fs/promises');\n await mkdir(this.backupDir, { recursive: true });\n await writeFile(`${this.backupDir}/${scope}.md`, content, 'utf8');\n } catch {\n // best-effort\n }\n }\n}\n\nfunction labelOf(scope: MemoryScope): string {\n switch (scope) {\n case 'project-agents':\n return 'Project AGENTS.md';\n case 'project-memory':\n return 'Project memory';\n case 'user-memory':\n return 'User memory';\n }\n}\n","import * as fs from 'node:fs/promises';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { type FileMemoryBackendOptions, FileMemoryBackend } from './memory-backend.js';\nimport type { MemoryBackend } from './memory-backend.js';\n\n// ── Graph node and edge types ──────────────────────────────────────────\n\ninterface GraphNode {\n id: string;\n entry: MemoryEntry;\n firstSeen: string;\n count: number;\n /** Extracted metadata for fast lookup. */\n type?: MemoryEntry['type'] | undefined;\n tags?: string[] | undefined;\n priority?: MemoryEntry['priority'] | undefined;\n}\n\ninterface GraphEdge {\n from: string;\n to: string;\n /** Why these nodes are related. */\n relation: 'co_occurring' | 'similar' | 'same_turn' | 'explicit';\n weight: number;\n ts: string;\n}\n\n// ── Backend ────────────────────────────────────────────────────────────\n\nexport interface GraphMemoryBackendOptions extends FileMemoryBackendOptions {\n /**\n * Path to the graph metadata file (edges + node metadata).\n * Defaults to `<projectDir>/memory-graph.json`.\n */\n graphPath?: string | undefined;\n}\n\n/**\n * Graph-based memory backend that tracks relationships between entries.\n * Builds on top of FileMemoryBackend — entries are still persisted as\n * markdown bullets, but the graph layer adds:\n *\n * - Co-occurrence edges (entries from the same remember() batch)\n * - Content similarity edges (simple Jaccard on word overlap)\n * - Turn-based edges (entries created in the same LLM turn)\n * - Graph traversal queries (find related memories)\n *\n * The graph metadata persists to `<projectDir>/memory-graph.json`.\n */\nexport class GraphMemoryBackend implements MemoryBackend {\n readonly kind = 'graph';\n\n private readonly file: FileMemoryBackend;\n private readonly graphFile: string;\n\n // In-memory graph state — lazily loaded, saved on mutation.\n private nodes = new Map<string, GraphNode>();\n private edges: GraphEdge[] = [];\n private loadedScope: MemoryScope | null = null;\n private loaded = false;\n\n constructor(opts: GraphMemoryBackendOptions) {\n this.file = new FileMemoryBackend({ paths: opts.paths });\n this.graphFile = opts.graphPath ?? `${opts.paths.projectDir}/memory-graph.json`;\n }\n\n // ── Backend interface ──────────────────────────────────────────────\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n await this.file.remember(scope, entry, filePath);\n await this.loadGraph(scope);\n\n const nodeId = this.nodeId(entry);\n const existing = this.nodes.get(nodeId);\n if (existing) {\n existing.count++;\n existing.entry = entry;\n existing.type = entry.type;\n existing.tags = entry.tags;\n existing.priority = entry.priority;\n } else {\n this.nodes.set(nodeId, {\n id: nodeId,\n entry,\n firstSeen: entry.ts,\n count: 1,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n });\n\n // Create similarity edges with existing nodes\n for (const [, other] of this.nodes) {\n if (other.id === nodeId) continue;\n const sim = wordOverlap(entry.text, other.entry.text);\n // Also create edges for shared tags\n const tagSim = sharedTags(entry.tags ?? [], other.tags ?? []);\n const weight = Math.max(sim, tagSim * 0.5);\n if (weight > 0.15) {\n this.edges.push({\n from: nodeId,\n to: other.id,\n relation: sim >= tagSim ? 'similar' : 'same_turn',\n weight,\n ts: entry.ts,\n });\n }\n }\n }\n\n await this.saveGraph(scope);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const removed = await this.file.forget(scope, query, filePath);\n if (removed > 0) {\n await this.loadGraph(scope);\n // Remove nodes whose entry text matches the query\n const n = query.toLowerCase();\n const toRemove: string[] = [];\n for (const [id, node] of this.nodes) {\n if (node.entry.text.toLowerCase().includes(n)) {\n toRemove.push(id);\n }\n }\n for (const id of toRemove) this.nodes.delete(id);\n this.edges = this.edges.filter((e) => !toRemove.includes(e.from) && !toRemove.includes(e.to));\n await this.saveGraph(scope);\n }\n return removed;\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n return this.file.readAll(scope, filePath);\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n // Merge: file entries are canonical, graph adds metadata and dedup\n const fileEntries = await this.file.list(scope, filePath);\n const nodeMap = new Map(this.nodes.entries());\n\n // Enrich file entries with graph metadata\n const enriched = fileEntries.map((fe) => {\n const nodeId = this.nodeId(fe);\n const node = nodeMap.get(nodeId);\n if (node) {\n return {\n ...fe,\n type: node.type ?? fe.type,\n tags: node.tags ?? fe.tags,\n priority: node.priority ?? fe.priority,\n };\n }\n return fe;\n });\n\n // Add graph-only nodes not in file (shouldn't happen normally, but safety)\n const fileIds = new Set(fileEntries.map((e) => this.nodeId(e)));\n for (const [id, node] of this.nodes) {\n if (!fileIds.has(id)) {\n enriched.push(node.entry);\n }\n }\n\n enriched.sort((a, b) => b.ts.localeCompare(a.ts));\n return limit ? enriched.slice(0, limit) : enriched;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Get all entries (file-canonical, graph-enriched)\n const all = await this.list(scope, filePath);\n\n // Score by word overlap + tag match + graph metadata\n const scored = all.map((entry) => {\n const words = entry.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n if (entry.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n const node = this.nodes.get(this.nodeId(entry));\n if (node) {\n if (node.priority === 'critical') score += 3;\n else if (node.priority === 'high') score += 2;\n score += node.count * 0.5;\n }\n return { entry, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n await this.file.clear(scope, filePath);\n this.nodes.clear();\n this.edges = [];\n this.loadedScope = scope;\n this.loaded = true;\n // Write empty graph\n try { await fs.unlink(this.graphFile); } catch { /* ok */ }\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n return this.file.consolidate(scope, filePath);\n }\n\n // ── Graph-specific queries ─────────────────────────────────────────\n\n /**\n * Find memories related to the given entry, ordered by edge weight.\n */\n async findRelated(scope: MemoryScope, _filePath: string, entryText: string, limit = 5): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const targetId = this.nodeId({ scope, text: entryText, ts: '' });\n const related = this.edges\n .filter((e) => e.from === targetId || e.to === targetId)\n .sort((a, b) => b.weight - a.weight)\n .slice(0, limit);\n\n const result: MemoryEntry[] = [];\n for (const edge of related) {\n const otherId = edge.from === targetId ? edge.to : edge.from;\n const node = this.nodes.get(otherId);\n if (node) result.push(node.entry);\n }\n return result;\n }\n\n /**\n * Get all edges for visualization or traversal.\n */\n getGraph(): { nodes: GraphNode[]; edges: GraphEdge[] } {\n return {\n nodes: [...this.nodes.values()],\n edges: [...this.edges],\n };\n }\n\n // ── Persistence ────────────────────────────────────────────────────\n\n private nodeId(entry: MemoryEntry): string {\n // Stable ID from scope + normalized text\n const norm = entry.text.toLowerCase().trim().replace(/\\s+/g, ' ');\n return `${entry.scope ?? 'mem'}::${simpleHash(norm)}`;\n }\n\n private async loadGraph(scope: MemoryScope): Promise<void> {\n if (this.loaded && this.loadedScope === scope) return;\n try {\n const raw = await fs.readFile(this.graphFile, 'utf8');\n const data: { nodes: Array<[string, GraphNode]>; edges: GraphEdge[] } = JSON.parse(raw);\n this.nodes = new Map(data.nodes);\n this.edges = data.edges;\n } catch {\n this.nodes = new Map();\n this.edges = [];\n }\n this.loadedScope = scope;\n this.loaded = true;\n }\n\n private async saveGraph(scope: MemoryScope): Promise<void> {\n this.loadedScope = scope;\n this.loaded = true;\n try {\n const data = {\n nodes: [...this.nodes.entries()],\n edges: this.edges,\n };\n await fs.mkdir(\n this.graphFile.substring(0, this.graphFile.lastIndexOf('/')),\n { recursive: true },\n );\n // Atomic write via temp file\n const tmp = `${this.graphFile}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(data));\n await fs.rename(tmp, this.graphFile);\n } catch {\n // best-effort — graph is an enhancement, not critical\n }\n }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────\n\n/** Jaccard-style word overlap between two strings. 0.0 = no overlap, 1.0 = identical. */\nfunction wordOverlap(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n if (wordsA.size === 0 || wordsB.size === 0) return 0;\n let intersection = 0;\n for (const w of wordsA) {\n if (wordsB.has(w)) intersection++;\n }\n return intersection / Math.max(wordsA.size, wordsB.size);\n}\n\n/** Tag overlap ratio — how many tags two nodes share. */\nfunction sharedTags(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const setB = new Set(b);\n let shared = 0;\n for (const t of a) if (setB.has(t)) shared++;\n return shared / Math.max(a.length, b.length);\n}\n\n/** Fast non-crypto hash for stable node IDs. */\nfunction simpleHash(s: string): string {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h).toString(36);\n}\n","import type { RunResult } from '../core/agent-types.js';\nimport type { Context } from '../core/context.js';\nimport type { AfterRunHook, AgentExtension } from '../extension/extension-points.js';\nimport type { MemoryEntry, MemoryStore } from '../types/memory.js';\nimport type { Provider } from '../types/provider.js';\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport interface ConsolidationOp {\n action: 'add' | 'edit' | 'delete';\n /** For add: the fact to remember. For edit: the new text replacing the old. */\n text?: string | undefined;\n /** For edit/delete: the query to match existing entries. */\n query?: string | undefined;\n /** Memory type for categorization. */\n type?: string | undefined;\n /** Tags for grouping. */\n tags?: string[] | undefined;\n /** Priority level. */\n priority?: string | undefined;\n}\n\ninterface ConsolidationResponse {\n operations: ConsolidationOp[];\n summary?: string | undefined;\n}\n\nexport interface MemoryConsolidatorOptions {\n memoryStore: MemoryStore;\n /**\n * Provider used for the consolidation LLM call. Uses the session's\n * provider by default.\n */\n provider?: Provider | undefined;\n /**\n * Model override for the consolidation call. Uses the session's model\n * by default. A smaller/faster model is recommended (e.g. haiku, flash).\n */\n model?: string | undefined;\n /**\n * Minimum session iterations before consolidation fires.\n * Sessions shorter than this are skipped (default 2).\n */\n minIterations?: number | undefined;\n /**\n * Maximum memory entries to include in the prompt as context.\n */\n maxExistingEntries?: number | undefined;\n}\n\n// ── Prompt ──────────────────────────────────────────────────────────────\n\nfunction buildConsolidationPrompt(\n finalText: string,\n iterations: number,\n existingEntries: MemoryEntry[],\n): string {\n const existingBlock =\n existingEntries.length > 0\n ? `\\n\\nExisting memory entries:\\n${existingEntries\n .map((e) => `- [${e.ts.slice(0, 10)}] ${e.text}`)\n .join('\\n')}`\n : '';\n\n return `You are a memory consolidator. Review the following session summary and decide what key facts, conventions, decisions, or learnings should be persisted to long-term memory.\n\nSession summary (${iterations} iterations):\n${finalText.slice(0, 3000)}${existingBlock}\n\nReturn a JSON object with an \"operations\" array. Each operation must have an \"action\" field:\n- \"add\": create a new memory entry. Include \"text\", and optionally \"type\", \"tags\", \"priority\".\n- \"edit\": replace an existing entry. Include \"query\" (to match) and \"text\" (replacement).\n- \"delete\": remove an entry. Include \"query\" (to match).\n\nMemory types:\n- \"fact\": Objective truth about the project (e.g. \"uses pnpm workspaces\")\n- \"decision\": A choice that was made (e.g. \"decided to use biome over eslint\")\n- \"convention\": A recurring pattern or standard (e.g. \"commit messages use conventional format\")\n- \"preference\": User or team preference (e.g. \"prefers short variable names\")\n- \"reference\": Pointer to a file or location (e.g. \"auth logic in packages/core/src/auth/\")\n- \"anti_pattern\": Something to avoid (e.g. \"never use any in TypeScript\")\n\nPriority levels:\n- \"critical\": Must always be known (e.g. security constraints)\n- \"high\": Important for most tasks\n- \"medium\": Useful context\n- \"low\": Nice to know\n\nRules:\n- Only persist facts likely useful across multiple future sessions.\n- Do NOT persist task progress, temporary state, or one-off observations.\n- Prefer \"add\" over \"edit\" unless the existing entry is clearly outdated.\n- Assign a type and priority to every \"add\" operation.\n- Use 1-3 hashtag tags for each entry (e.g. #typescript #build).\n- Be concise — each memory entry should be one clear sentence.\n\nReturn ONLY valid JSON, no markdown, no explanation:\n{\n \"operations\": [\n { \n \"action\": \"add\", \n \"text\": \"Project uses pnpm workspaces with TypeScript strict mode\",\n \"type\": \"convention\",\n \"priority\": \"high\",\n \"tags\": [\"pnpm\", \"typescript\", \"build\"]\n },\n { \n \"action\": \"edit\", \n \"query\": \"pnpm\", \n \"text\": \"Project uses pnpm v9+ with ESM-only modules\",\n \"type\": \"fact\",\n \"priority\": \"medium\"\n },\n { \"action\": \"delete\", \"query\": \"outdated convention\" }\n ]\n}`;\n}\n\n// ── Consolidator ────────────────────────────────────────────────────────\n\nexport class SessionMemoryConsolidator implements AgentExtension {\n name = 'session-memory-consolidator';\n owner = 'core';\n\n private readonly memoryStore: MemoryStore;\n private readonly provider?: Provider | undefined;\n private readonly model?: string | undefined;\n private readonly minIterations: number;\n private readonly maxExistingEntries: number;\n\n constructor(opts: MemoryConsolidatorOptions) {\n this.memoryStore = opts.memoryStore;\n this.provider = opts.provider;\n this.model = opts.model;\n this.minIterations = opts.minIterations ?? 2;\n this.maxExistingEntries = opts.maxExistingEntries ?? 15;\n }\n\n afterRun: AfterRunHook = async (ctx: Context, result: RunResult) => {\n // Only consolidate successful sessions with meaningful output\n if (result.status !== 'done') return;\n if (!result.finalText || result.finalText.trim().length < 20) return;\n if (result.iterations < this.minIterations) return;\n\n const provider = this.provider ?? ctx.provider;\n if (!provider || !provider.complete) return;\n\n try {\n // Load existing memory for dedup context\n const existingEntries = await this.memoryStore.list('project-memory', this.maxExistingEntries);\n const prompt = buildConsolidationPrompt(\n result.finalText,\n result.iterations,\n existingEntries,\n );\n\n // Call the LLM with a focused, one-shot prompt\n const signal = AbortSignal.timeout(15_000);\n const response = await provider.complete(\n {\n model: this.model ?? ctx.model,\n system: [{ type: 'text', text: prompt }],\n messages: [\n { role: 'user', content: 'Review the session and return memory operations as JSON.' },\n ],\n maxTokens: 500,\n },\n { signal },\n );\n\n const text = response.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n .trim();\n if (!text) return;\n\n // Extract JSON from possible markdown wrapper\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) return;\n\n const parsed: ConsolidationResponse = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(parsed.operations) || parsed.operations.length === 0) return;\n\n // Apply operations\n let added = 0;\n let edited = 0;\n let deleted = 0;\n\n for (const op of parsed.operations) {\n switch (op.action) {\n case 'add': {\n if (op.text?.trim()) {\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n added++;\n }\n break;\n }\n case 'edit': {\n if (op.query && op.text && op.text.trim()) {\n await this.memoryStore.forget(op.query);\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n edited++;\n }\n break;\n }\n case 'delete': {\n if (op.query) {\n const n = await this.memoryStore.forget(op.query);\n deleted += n;\n }\n break;\n }\n }\n }\n\n if (added > 0 || edited > 0 || deleted > 0) {\n const parts: string[] = [];\n if (added) parts.push(`${added} added`);\n if (edited) parts.push(`${edited} edited`);\n if (deleted) parts.push(`${deleted} deleted`);\n // Log to stderr so it surfaces in the terminal\n process.stderr.write(`[memory] Session consolidation: ${parts.join(', ')}\\n`);\n }\n } catch {\n // Silent — memory consolidation is best-effort, never blocks session cleanup\n }\n };\n}\n","/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = err instanceof Error ? err.message : String(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { Config, ConfigStore } from '../types/config.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\n\n\n/**\n * Strip fields that originated from environment variables so they are never\n * persisted back to disk. This prevents an env-sourced secret (e.g.\n * WRONGSTACK_API_KEY) from being accidentally written to ~/.wrongstack/config.json.\n */\nfunction stripEphemeralFields(cfg: Partial<Config>): Partial<Config> {\n const env = (cfg as Partial<Config & { _envSource?: Set<string> | undefined}>)._envSource;\n if (!env?.size) return cfg;\n const out: Partial<Config> = { ...cfg };\n for (const field of env) {\n delete (out as Record<string, unknown>)[field];\n }\n delete (out as Record<string, unknown>)._envSource;\n return out;\n}\n\n/**\n * Reference implementation of `ConfigStore`. Stores a single frozen Config\n * and notifies watchers synchronously on every update. Updates use a deep\n * clone so callers can mutate their `partial` argument freely without\n * tainting state.\n *\n * For the CLI: instantiate once at boot, pass the store (not the Config)\n * to subsystems that care about runtime changes (provider switching,\n * extension reload).\n */\nexport class DefaultConfigStore implements ConfigStore {\n private current: Readonly<Config>;\n private watchers = new Set<(next: Readonly<Config>, prev: Readonly<Config>) => void>();\n\n constructor(initial: Config) {\n this.current = deepFreeze(structuredClone(initial));\n }\n\n get(): Readonly<Config> {\n return this.current;\n }\n\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]> {\n return this.current[key] as Readonly<Config[K]>;\n }\n\n getExtension(pluginName: string): Readonly<Record<string, unknown>> {\n const ext = this.current.extensions?.[pluginName];\n return ext ? (ext as Readonly<Record<string, unknown>>) : FROZEN_EMPTY;\n }\n\n update(partial: Partial<Config>): Readonly<Config> {\n // Strip env-sourced fields before persisting to prevent secrets leaking\n // from in-memory env-derived config values into the on-disk config file.\n const scrubbed = stripEphemeralFields(partial);\n // Shallow merge — top-level fields replace, nested objects do too unless\n // the caller passes a fully-formed sub-object. That matches the JSON\n // config user mental model (replace `tools.maxIterations` by passing\n // the whole `tools` block, or by patching `extensions.<name>`).\n const next = deepFreeze(structuredClone({ ...this.current, ...scrubbed })) as Readonly<Config>;\n\n if (next.version !== 1) {\n throw new ConfigError({\n message: `ConfigStore.update: version must remain 1, got ${String(next.version)}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: next.version },\n });\n }\n\n const prev = this.current;\n this.current = next;\n // Notify watchers AFTER mutating `current` so re-entrant watcher reads\n // see the new state. Watcher exceptions are caught individually so one\n // misbehaving subscriber can't block the others.\n for (const w of this.watchers) {\n try {\n w(next, prev);\n } catch (err) {\n // A plugin watcher that crashes on /model switch or similar would\n // otherwise leave the system in a quietly-inconsistent state. We\n // still don't propagate (one bad subscriber must not break the\n // others), but we surface the error so it's discoverable.\n console.error(JSON.stringify({\n level: 'error',\n event: 'config_store.watcher_threw',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n return next;\n }\n\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void {\n this.watchers.add(cb);\n return () => this.watchers.delete(cb);\n }\n}\n\nconst FROZEN_EMPTY: Readonly<Record<string, unknown>> = Object.freeze({});\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') return obj;\n if (Object.isFrozen(obj)) return obj;\n for (const key of Object.keys(obj as object)) {\n const v = (obj as Record<string, unknown>)[key];\n if (v !== null && typeof v === 'object' && !Object.isFrozen(v)) {\n deepFreeze(v);\n }\n }\n return Object.freeze(obj);\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { ENCRYPTED_PREFIX } from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n */\nexport class DefaultSecretVault implements SecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && value.startsWith(ENCRYPTED_PREFIX);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n return `${ENCRYPTED_PREFIX}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n const rest = value.slice(ENCRYPTED_PREFIX.length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length !== KEY_BYTES) {\n // A wrong-size key is not ENOENT — the file is corrupted or was\n // tampered with. Throwing instead of falling through to create a\n // new key protects all secrets encrypted under this key; the user\n // can remove the file manually to generate a fresh key.\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = buf;\n // Warn if the key file has wrong permissions (defense-in-depth).\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length !== KEY_BYTES) {\n // A wrong-size key is not ENOENT — the file is corrupted or was\n // tampered with. Throwing instead of falling through to create a\n // new key protects all secrets encrypted under this key; the user\n // can remove the file manually to generate a fresh key.\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES}). Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = buf;\n // Warn if the key file has wrong permissions (defense-in-depth).\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n this.key = key;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","export interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n autoExtendLimit: true,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","import * as fs from 'node:fs/promises';\nimport { decryptConfigSecrets } from '../security/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport {\n DEFAULT_CONTEXT_WINDOW_MODE_ID,\n isContextWindowModeId,\n listContextWindowModes,\n} from '../types/context-window.js';\nimport type { Config, ConfigLoader, SyncConfig } from '../types/config.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { deepMerge as deepMergeCore, type DeepMergeOptions } from '../utils/deep-merge.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport {\n DEFAULT_TOOLS_CONFIG,\n DEFAULT_CONTEXT_CONFIG,\n DEFAULT_SESSION_LOGGING_CONFIG,\n} from '../types/default-config.js';\n\n/**\n * Defaults express *behavior*, not identity. Provider and model are NOT\n * hardcoded — they must be resolved at runtime from config + env + the\n * ModelsRegistry. A bare Config returned by this loader will throw when\n * the agent tries to construct a provider, with a message that points\n * users at `wstack init`.\n */\nconst BEHAVIOR_DEFAULTS: Omit<Config, 'provider' | 'model'> = {\n version: 1,\n context: {\n mode: DEFAULT_CONTEXT_WINDOW_MODE_ID,\n warnThreshold: 0.6,\n softThreshold: 0.75,\n hardThreshold: 0.9,\n autoCompact: true,\n preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,\n eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold,\n },\n tools: {\n defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,\n maxIterations: DEFAULT_TOOLS_CONFIG.maxIterations,\n iterationTimeoutMs: DEFAULT_TOOLS_CONFIG.iterationTimeoutMs,\n sessionTimeoutMs: DEFAULT_TOOLS_CONFIG.sessionTimeoutMs,\n perIterationOutputCapBytes: DEFAULT_TOOLS_CONFIG.perIterationOutputCapBytes,\n autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit,\n },\n log: { level: 'info' },\n features: {\n mcp: true,\n plugins: true,\n memory: true,\n modelsRegistry: true,\n skills: true,\n },\n indexing: {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n },\n session: { ...DEFAULT_SESSION_LOGGING_CONFIG },\n};\n\n/** Parse a boolean-ish env var: \"0\"/\"false\"/\"no\"/\"off\" → false, anything else → true. */\nfunction envBool(v: string): boolean {\n return !/^(0|false|no|off)$/i.test(v.trim());\n}\n\nfunction envBoolOptional(v: string | undefined): boolean {\n return v !== undefined && envBool(v);\n}\n\nconst LOG_LEVELS = new Set<Config['log']['level']>(['error', 'warn', 'info', 'debug', 'trace']);\n\nfunction envLogLevel(v: string): Config['log']['level'] {\n return LOG_LEVELS.has(v as Config['log']['level']) ? (v as Config['log']['level']) : 'info';\n}\n\nconst ENV_MAP: Record<string, (cfg: PartialConfig, val: string) => void> = {\n WRONGSTACK_PROVIDER: (c, v) => {\n c.provider = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('provider');\n },\n WRONGSTACK_MODEL: (c, v) => {\n c.model = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('model');\n },\n WRONGSTACK_API_KEY: (c, v) => {\n c.apiKey = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('apiKey');\n },\n WRONGSTACK_BASE_URL: (c, v) => {\n c.baseUrl = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('baseUrl');\n },\n WRONGSTACK_LOG_LEVEL: (c, v) => {\n if (!c.log) c.log = { level: 'info' };\n c.log.level = envLogLevel(v);\n },\n WRONGSTACK_INDEX_ON_START: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onSessionStart: envBool(v) };\n },\n WRONGSTACK_INDEX_ON_EDIT: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onEdit: envBool(v) };\n },\n WRONGSTACK_INDEX_WATCH: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, watchExternal: envBool(v) };\n },\n};\n\nconst defaultIndexing = {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n} as const;\n\ntype PartialConfig = Partial<Config> & {\n providers?: Record<\n string,\n { apiKey?: string | undefined; baseUrl?: string | undefined; type?: string | undefined }\n >;\n /** Fields that came from environment variables — must not be persisted. */\n _envSource?: Set<string> | undefined;\n};\n\n/**\n * Config-layer deep merge — delegates to the shared utility with\n * `arrayMode: 'concat-primitives'` and optional debug logging for\n * non-primitive array replacements.\n */\nfunction deepMerge<T>(base: T, patch: Partial<T>): T {\n const opts: DeepMergeOptions = { arrayMode: 'concat-primitives' };\n if (envBoolOptional(process.env.WRONGSTACK_DEBUG_CONFIG)) {\n opts.onNonPrimitiveArrayReplace = (key, existingLen, patchLen) => {\n console.warn(\n `[config] Non-primitive array for \"${key}\" replaced (global + local config merge). ` +\n `Global entries: ${existingLen}, local entries: ${patchLen}.`,\n );\n };\n }\n return deepMergeCore(base as Record<string, unknown>, patch as Record<string, unknown>, opts) as T;\n}\n\n/**\n * A single config source. Higher priority wins in merges.\n * Sources are applied in priority order (lowest first), so a source\n * with priority=10 overrides one with priority=1.\n */\nexport interface ConfigSource {\n /** Unique name for debugging and error messages. */\n name: string;\n /** Lower numbers merge first, higher numbers override lower. Default: 50. */\n priority?: number | undefined;\n /**\n * Read the raw config patch. Return an empty object if unavailable.\n * Errors are surfaced but do not abort loading — the source is skipped.\n */\n read(): Promise<Partial<Config>>;\n}\n\nexport interface ConfigLoaderOptions {\n paths: WstackPaths;\n strict?: boolean | undefined;\n vault?: SecretVault | undefined;\n /** Extra sources merged after the built-in layers. */\n sources?: ConfigSource[] | undefined;\n}\n\nexport class DefaultConfigLoader implements ConfigLoader {\n private readonly paths: WstackPaths;\n private readonly strict: boolean;\n private readonly vault: SecretVault | undefined;\n private readonly extraSources: ConfigSource[];\n\n constructor(opts: ConfigLoaderOptions) {\n this.paths = opts.paths;\n this.strict = opts.strict ?? false;\n this.vault = opts.vault;\n this.extraSources = opts.sources ?? [];\n }\n\n async load(\n opts: { cliFlags?: Partial<Config> | undefined; cwd?: string | undefined } = {},\n ): Promise<Config> {\n let cfg: PartialConfig = { ...BEHAVIOR_DEFAULTS } as PartialConfig;\n\n // Layer 2, 3 & 3b: global + project-local + in-project config — read in parallel.\n // inProjectConfig (<project>/.wrongstack/config.json) merges AFTER\n // projectLocalConfig so it takes priority (user-intended > auto-cached).\n const [global, local, inProject] = await Promise.all([\n this.readJson(this.paths.globalConfig),\n this.readJson(this.paths.projectLocalConfig),\n this.readJson(this.paths.inProjectConfig),\n ]);\n cfg = deepMerge(cfg, global);\n cfg = deepMerge(cfg, local);\n cfg = deepMerge(cfg, inProject);\n\n // Layer 4: env vars\n for (const [key, fn] of Object.entries(ENV_MAP)) {\n const v = process.env[key];\n if (v) fn(cfg, v);\n }\n\n // Layer 5: extra sources — sorted by priority (lowest first).\n // When priorities tie, sort by name for deterministic order.\n const sorted = [...this.extraSources].sort((a, b) => {\n const pd = (a.priority ?? 50) - (b.priority ?? 50);\n if (pd !== 0) return pd;\n return a.name.localeCompare(b.name);\n });\n for (const src of sorted) {\n try {\n const patch = await src.read();\n if (patch && Object.keys(patch).length > 0) {\n cfg = deepMerge(cfg, patch);\n }\n } catch (err) {\n // Best-effort: skip failing sources so one bad source doesn't block boot.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.source_load_failed',\n source: src.name,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n // Layer 6: CLI flags\n if (opts.cliFlags) {\n cfg = deepMerge(cfg, opts.cliFlags);\n }\n\n // Decrypt apiKey-like fields if a vault is configured.\n if (this.vault) {\n cfg = decryptConfigSecrets(cfg, this.vault);\n }\n\n // Multi-key resolution: when a provider has `apiKeys[]` configured,\n // mirror the active entry into `apiKey` so downstream construction\n // code (provider registry, wire adapters) needs no changes. Honors\n // `activeKey` (by label), else falls back to the first entry. A\n // pre-existing `apiKey` set by env/CLI flags wins so an explicit\n // override still beats the saved list.\n if (cfg.providers) {\n for (const pcfg of Object.values(cfg.providers)) {\n if (!pcfg || typeof pcfg !== 'object') continue;\n const rawKeys = (pcfg as { apiKeys?: unknown | undefined }).apiKeys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) continue;\n // Each apiKeys entry came from arbitrary JSON. Filter to entries\n // that actually have a string apiKey + label so a malformed array\n // (null entry, missing field) doesn't crash the .find / chosen.apiKey\n // path below.\n const keys = rawKeys.filter(\n (k): k is { label: string; apiKey: string } =>\n !!k &&\n typeof k === 'object' &&\n typeof (k as { label?: unknown | undefined }).label === 'string' &&\n typeof (k as { apiKey?: unknown | undefined }).apiKey === 'string',\n );\n if (keys.length === 0) continue;\n const existing = (pcfg as { apiKey?: string | undefined }).apiKey;\n if (existing && existing.length > 0) continue;\n const activeLabel = (pcfg as { activeKey?: string | undefined }).activeKey;\n const chosen = activeLabel\n ? (keys.find((k) => k.label === activeLabel) ?? keys[0])\n : keys[0];\n if (chosen?.apiKey) {\n (pcfg as { apiKey?: string | undefined }).apiKey = chosen.apiKey;\n }\n }\n }\n\n this.validateBehavior(cfg);\n if (this.strict) {\n this.validateIdentity(cfg);\n }\n // In strict mode, validateIdentity has confirmed provider/model are set;\n // it's safe to assert the full Config contract. In non-strict mode the\n // caller (e.g. early-boot wizard) accepts a Partial and constructs the\n // provider later, so we deliberately return without the cast.\n return Object.freeze(cfg) as Config;\n }\n\n /**\n * Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted\n * by the vault (if provided). The file is isolated from the main config\n * hierarchy to prevent accidental commits.\n */\n async persistSyncConfig(cfg: SyncConfig): Promise<void> {\n let toWrite = { ...cfg };\n if (this.vault && toWrite.githubToken && !toWrite.githubToken.startsWith('enc:')) {\n // Re-encrypt if plaintext (e.g. came from in-memory configStore update\n // rather than direct /sync enable call). Idempotent for already-encrypted.\n toWrite = { ...toWrite, githubToken: this.vault.encrypt(toWrite.githubToken) };\n }\n await atomicWrite(this.paths.syncConfig, JSON.stringify(toWrite, null, 2), { mode: 0o600 });\n }\n\n /**\n * Read ~/.wrongstack/sync.json (encrypted GitHub token storage) and decrypt\n * the token if a vault is available. Returns null if the file doesn't exist.\n * This is separate from main config loading because sync.json is intentionally\n * isolated — it should never be part of project-local or env-driven config.\n */\n async loadSyncConfig(): Promise<SyncConfig | null> {\n try {\n const raw = await fs.readFile(this.paths.syncConfig, 'utf8');\n const parsed = safeParse<SyncConfig>(raw);\n if (!parsed.ok || !parsed.value) return null;\n\n // Decrypt the token if vault is available (field name matches secret pattern)\n if (this.vault) {\n const decrypted = decryptConfigSecrets({ sync: parsed.value } as PartialConfig, this.vault);\n return (decrypted as { sync: SyncConfig }).sync ?? null;\n }\n return parsed.value;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.sync_load_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n }\n\n private async readJson(file: string): Promise<PartialConfig> {\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n // Missing file is the common case (per-project local config rarely\n // exists at start). Surface anything else (EACCES, EISDIR) so a\n // mis-permissioned config doesn't silently fall back to defaults.\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.read_failed',\n path: file,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return {};\n }\n const parsed = safeParse<PartialConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n // The file exists but isn't valid JSON. Don't silently reset to\n // defaults — that's hours of debug timesink for users who'd typo'd\n // their config. Warn loudly and keep the in-memory defaults.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.parse_failed',\n path: file,\n message: 'invalid JSON — falling back to defaults for this layer',\n timestamp: new Date().toISOString(),\n }));\n return {};\n }\n return parsed.value;\n }\n\n private validateBehavior(cfg: PartialConfig): void {\n if (cfg.version === undefined) throw new ConfigError({\n message: 'Config: missing version field',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version' },\n });\n if (cfg.version !== 1) throw new ConfigError({\n message: `Config: unsupported version ${cfg.version}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: cfg.version },\n });\n const c = cfg.context;\n if (!c) throw new ConfigError({\n message: 'Config: missing context section',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'context' },\n });\n // A user-edited config.json can land strings here (\"0.6\") and slip past\n // truthiness checks; the `>=` comparison then coerces silently and the\n // threshold ordering check passes for nonsense values. Validate types\n // explicitly so misconfigs surface here, not as confusing failures deep\n // in the auto-compaction logic.\n const fields: Array<keyof typeof c> = ['warnThreshold', 'softThreshold', 'hardThreshold'];\n for (const f of fields) {\n const v = c[f];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n throw new ConfigError({\n message: `Config: context.${String(f)} must be a finite number (got ${typeof v})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: `context.${String(f)}`, actualType: typeof v },\n });\n }\n }\n if (c.warnThreshold >= c.softThreshold || c.softThreshold >= c.hardThreshold) {\n throw new ConfigError({\n message: 'Config: context thresholds must satisfy warn < soft < hard',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { warn: c.warnThreshold, soft: c.softThreshold, hard: c.hardThreshold },\n });\n }\n if (c.mode !== undefined && !isContextWindowModeId(c.mode)) {\n // An unknown mode (typo or value from an older/renamed scheme) should not\n // brick the CLI — unlike the numeric thresholds above there is a safe\n // default. Warn and fall back rather than throwing.\n const known = listContextWindowModes()\n .map((m) => m.id)\n .join(', ');\n console.warn(\n `[config] Ignoring unknown context.mode \"${c.mode}\" (expected one of: ${known}); ` +\n `falling back to \"${DEFAULT_CONTEXT_WINDOW_MODE_ID}\".`,\n );\n c.mode = DEFAULT_CONTEXT_WINDOW_MODE_ID;\n }\n }\n\n private validateIdentity(cfg: PartialConfig): void {\n if (!cfg.provider) {\n throw new ConfigError({\n message: 'Config: no provider configured. Run `wstack init` or set WRONGSTACK_PROVIDER.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'provider' },\n });\n }\n if (!cfg.model) {\n throw new ConfigError({\n message: 'Config: no model configured. Run `wstack init` or set WRONGSTACK_MODEL.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'model' },\n });\n }\n }\n}\n","/**\n * L2-D: Config version migration framework. Pure functions, decoupled\n * from disk/CLI — caller passes a parsed JSON object and gets back the\n * up-to-date `Config` shape (or a structured error explaining why\n * migration failed).\n *\n * Migrations are registered as `{ from, to, migrate }` triples and run\n * sequentially. Each migration is independently testable. Adding a new\n * version means appending one migration; existing user configs are\n * upgraded in place at load time.\n */\n\nexport interface MigrationContext {\n /**\n * Original on-disk version of the input. Migrations may use this to\n * decide between in-place patches and rewrites.\n */\n fromVersion: number;\n /**\n * Set when the migration writes back to disk. Callers persist the\n * migrated config when this is true so the user doesn't see the same\n * migration banner on every boot.\n */\n shouldPersist: boolean;\n}\n\nexport interface ConfigMigration {\n /** Version of the input this migration accepts. */\n from: number;\n /** Version of the output it produces. */\n to: number;\n /** Pure transform — no I/O. */\n migrate(input: Record<string, unknown>, ctx: MigrationContext): Record<string, unknown>;\n /** Optional human-readable description for migration logs / banners. */\n describe?: string | undefined;\n}\n\nexport interface MigrationResult {\n /** Final config (still typed as `unknown`-keyed — caller validates). */\n config: Record<string, unknown>;\n /** Ordered list of `from→to` versions that ran. */\n applied: string[];\n /** True when at least one migration produced changes worth persisting. */\n shouldPersist: boolean;\n}\n\nexport class ConfigMigrationError extends Error {\n readonly fromVersion: number;\n readonly targetVersion: number;\n readonly missingStep: number | null;\n\n constructor(opts: {\n message: string;\n fromVersion: number;\n targetVersion: number;\n missingStep: number | null;\n }) {\n super(opts.message);\n this.name = 'ConfigMigrationError';\n this.fromVersion = opts.fromVersion;\n this.targetVersion = opts.targetVersion;\n this.missingStep = opts.missingStep;\n }\n}\n\n/**\n * Run registered migrations until the input reaches `targetVersion`.\n *\n * Resolution rules:\n * 1. If `input.version === targetVersion`, no migrations run; `shouldPersist`\n * is false.\n * 2. Otherwise walk the migration chain from `input.version` upward,\n * picking the migration whose `from` matches the current version.\n * 3. Stop when `current.version === targetVersion`.\n * 4. If no migration matches at some point, throw `ConfigMigrationError`\n * with the missing step recorded for diagnostics.\n *\n * Migrations may be downward (e.g. for staged rollouts), but `targetVersion`\n * must be reachable strictly via the registered chain — there's no implicit\n * \"skip\" or transitive resolution.\n */\nexport function runConfigMigrations(\n input: Record<string, unknown>,\n targetVersion: number,\n migrations: readonly ConfigMigration[],\n): MigrationResult {\n const initial = typeof input['version'] === 'number' ? (input['version'] as number) : 1;\n let current: Record<string, unknown> = { ...input };\n let currentVersion = initial;\n const applied: string[] = [];\n let shouldPersist = false;\n\n let guard = 0;\n while (currentVersion !== targetVersion) {\n if (++guard > 100) {\n throw new ConfigMigrationError({\n message: `Config migration looped past 100 steps (from v${initial} toward v${targetVersion})`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const step = migrations.find((m) => m.from === currentVersion);\n if (!step) {\n throw new ConfigMigrationError({\n message: `No migration registered from config v${currentVersion} (target v${targetVersion}). Update the framework or revert the config file.`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const ctx: MigrationContext = { fromVersion: currentVersion, shouldPersist: false };\n const next = step.migrate(current, ctx);\n // Ensure the migration set the new version. Be tolerant: if it didn't,\n // patch it in so the chain doesn't infinite-loop on author oversight.\n if (typeof next['version'] !== 'number' || next['version'] !== step.to) {\n next['version'] = step.to;\n }\n current = next;\n currentVersion = step.to;\n applied.push(`v${step.from}→v${step.to}`);\n shouldPersist = shouldPersist || ctx.shouldPersist || step.from < step.to;\n }\n return { config: current, applied, shouldPersist };\n}\n\n/**\n * Default empty migration registry. Real migrations are appended as new\n * Config versions are introduced. Example (when v2 lands):\n *\n * export const CONFIG_MIGRATIONS: readonly ConfigMigration[] = [\n * {\n * from: 1, to: 2, describe: 'rename `apiKey` → `auth.apiKey`',\n * migrate(cfg) {\n * const apiKey = cfg.apiKey;\n * delete cfg.apiKey;\n * return { ...cfg, auth: { ...(cfg.auth ?? {}), apiKey } };\n * },\n * },\n * ];\n */\nexport const DEFAULT_CONFIG_MIGRATIONS: readonly ConfigMigration[] = [];\n","import * as fsp from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SessionStore } from '../types/session.js';\nimport { ensureDir } from '../utils/atomic-write.js';\n\n/**\n * Per-project lockfile used for crash detection. The CLI writes one of\n * these alongside the session JSONLs (`<projectSessions>/active.json`)\n * when an interactive run starts, and deletes it on clean exit. If we\n * find one on the next launch whose owning PID is dead (or whose host\n * doesn't match), we know the previous run was killed mid-flight and\n * the session it was writing to is a recovery candidate.\n *\n * The lockfile is intentionally per-project (already isolated by\n * `wpaths.projectSessions`), so two TUIs in two different repos do not\n * fight each other.\n */\nexport interface RecoveryLockOptions {\n /** Directory the lockfile lives in. Usually `wpaths.projectSessions`. */\n dir: string;\n /** This process's PID. Default: `process.pid`. */\n pid?: number | undefined;\n /** Hostname recorded for the lock. Default: `os.hostname()`. */\n hostname?: string | undefined;\n /** Locks older than this are considered orphaned (disk wiped, etc.). Default 24h. */\n maxAgeMs?: number | undefined;\n /** Used to check whether the abandoned session was actually closed cleanly. */\n sessionStore?: SessionStore | undefined;\n /**\n * Override the PID-liveness probe. Default: `process.kill(pid, 0)` —\n * succeeds (or throws EPERM) when the PID is alive, throws ESRCH when\n * it is gone. Tests inject a deterministic stub.\n */\n isPidAlive?: (((pid: number) => boolean)) | undefined;\n}\n\nexport interface AbandonedSession {\n sessionId: string;\n pid: number;\n startedAt: string;\n /** Lockfile age in ms at the time of the check. */\n ageMs: number;\n /** Number of messages already on disk for this session. */\n messageCount: number;\n}\n\ninterface LockFile {\n v: 1;\n sessionId: string;\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\nconst LOCK_FILE = 'active.json';\nconst DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport class RecoveryLock {\n private readonly file: string;\n private readonly pid: number;\n private readonly hostname: string;\n private readonly maxAgeMs: number;\n private readonly sessionStore?: SessionStore | undefined;\n private readonly probe: (pid: number) => boolean;\n\n constructor(opts: RecoveryLockOptions) {\n this.file = path.join(opts.dir, LOCK_FILE);\n this.pid = opts.pid ?? process.pid;\n this.hostname = opts.hostname ?? os.hostname();\n this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n this.sessionStore = opts.sessionStore;\n this.probe = opts.isPidAlive ?? defaultIsPidAlive;\n }\n\n /**\n * Examine the lockfile and decide whether it represents an abandoned\n * session. Returns `null` if the file is missing, points to a live\n * instance, references a clean-closed session, is too old, or is\n * malformed. Otherwise returns enough detail to prompt the user.\n *\n * Important: this is a read-only check. We never delete an active\n * lock from here — if another wstack instance is alive, the caller\n * should bail or run with a fresh session instead.\n */\n async checkAbandoned(): Promise<AbandonedSession | null> {\n const lock = await this.readLock();\n if (!lock) return null;\n\n const ageMs = Date.now() - new Date(lock.startedAt).getTime();\n if (Number.isNaN(ageMs) || ageMs < 0) {\n // Clock skew or corrupted timestamp — treat as orphan.\n return null;\n }\n if (ageMs > this.maxAgeMs) return null;\n\n // PID liveness only meaningful on the same host. Different host\n // means we can't probe — assume abandoned (the other machine's\n // wstack can't be holding *our* sessions dir unless it was\n // shared via network mount, in which case the user is on their\n // own).\n if (lock.hostname === this.hostname && this.probe(lock.pid)) {\n // Another wstack on this box is actively writing here.\n return null;\n }\n\n let messageCount = 0;\n if (this.sessionStore) {\n try {\n const data = await this.sessionStore.load(lock.sessionId);\n // Closed means the LAST session_end is not followed by further\n // conversation activity. Legacy /save wrote mid-stream session_end\n // markers — `some()` would treat a session that crashed AFTER such a\n // marker as cleanly closed and silently skip recovery.\n const lastEnd = data.events.findLastIndex((e) => e.type === 'session_end');\n const closed =\n lastEnd >= 0 &&\n !data.events\n .slice(lastEnd + 1)\n .some(\n (e) =>\n e.type === 'user_input' ||\n e.type === 'llm_response' ||\n e.type === 'in_flight_start',\n );\n if (closed) return null;\n messageCount = data.messages.length;\n } catch {\n // Lock points to a session that doesn't exist on disk (deleted\n // out from under us). Nothing to recover.\n return null;\n }\n }\n\n return {\n sessionId: lock.sessionId,\n pid: lock.pid,\n startedAt: lock.startedAt,\n ageMs,\n messageCount,\n };\n }\n\n /**\n * Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)\n * to detect whether another process acquired the lock between our\n * `checkAbandoned()` call and now. If the file already exists, it means\n * another process won the race and we throw instead of silently\n * overwriting their recovery record.\n *\n * The caller MUST have already called `checkAbandoned()` and handled its\n * null return before calling this.\n */\n async write(sessionId: string): Promise<void> {\n await ensureDir(path.dirname(this.file));\n const lock: LockFile = {\n v: 1,\n sessionId,\n pid: this.pid,\n hostname: this.hostname,\n startedAt: new Date().toISOString(),\n };\n // O_EXCL: atomic create — fails with EEXIST if another process wrote\n // the file between our checkAbandoned() and this write. This prevents\n // two processes that scanned the same stale lock from both believing\n // they hold it. The atomicWrite approach (temp+rename) would silently\n // replace on POSIX, hiding the race.\n try {\n await fsp.writeFile(this.file, JSON.stringify(lock), { flag: 'wx', mode: 0o600 });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') {\n throw new Error(`Recovery lock already held by another process`);\n }\n throw err;\n }\n }\n\n /**\n * Release the lock. Idempotent — silently succeeds if the file is\n * already gone (e.g. someone else cleared it, or the directory was\n * wiped).\n */\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n throw err;\n }\n }\n\n private async readLock(): Promise<LockFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null;\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isLockFile(parsed)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n}\n\nfunction isLockFile(v: unknown): v is LockFile {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return (\n o['v'] === 1 &&\n typeof o['sessionId'] === 'string' &&\n typeof o['pid'] === 'number' &&\n typeof o['hostname'] === 'string' &&\n typeof o['startedAt'] === 'string'\n );\n}\n\n/**\n * Probe whether a process is alive without sending it a real signal.\n *\n * Unix: `process.kill(pid, 0)` succeeds for our own processes, throws\n * EPERM for others (still alive, just not ours), and throws ESRCH\n * when the PID is gone.\n * Windows (Node 22+): same call returns true if the process exists,\n * throws otherwise.\n */\nfunction defaultIsPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EPERM') return true; // alive, but owned by someone else\n return false;\n }\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport type { ContentBlock } from '../types/blocks.js';\r\nimport type {\r\n DefaultSessionReaderOptions,\r\n SessionExportOptions,\r\n SessionQuery,\r\n SessionReader,\r\n SessionSearchHit,\r\n SessionSearchQuery,\r\n SessionSummaryLite,\r\n} from '../types/session-reader.js';\r\nimport { compileUserRegex } from '../utils/regex-guard.js';\r\nimport type { SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\r\n\r\n/**\r\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\r\n * and export helpers. Implemented on top of the public `SessionStore`\r\n * surface so any concrete store can be inspected without re-implementation.\r\n *\r\n * The heavy operations re-parse the JSONL stream on every call — fine for\r\n * /resume and one-off analytics. Wrap with a memoizing decorator if needed.\r\n */\r\nexport class DefaultSessionReader implements SessionReader {\r\n private readonly store: SessionStore;\r\n\r\n constructor(opts: DefaultSessionReaderOptions) {\r\n this.store = opts.store;\r\n }\r\n\r\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\r\n const raw = await this.store.list(q.limit ? Math.max(q.limit * 4, 100) : 1000);\r\n const titleNeedle = q.titleContains?.toLowerCase();\r\n const filtered = raw.filter((s) => {\r\n if (q.since && s.startedAt < q.since) return false;\r\n if (q.until && s.startedAt > q.until) return false;\r\n if (q.provider && s.provider !== q.provider) return false;\r\n if (q.model && s.model !== q.model) return false;\r\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n const out: SessionSummaryLite[] = filtered.map((s) => ({\r\n id: s.id,\r\n title: s.title,\r\n startedAt: s.startedAt,\r\n provider: s.provider,\r\n model: s.model,\r\n tokenTotal: s.tokenTotal,\r\n }));\r\n return q.limit ? out.slice(0, q.limit) : out;\r\n }\r\n\r\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\r\n const data = await this.store.load(sessionId);\r\n for (const e of data.events) yield e;\r\n }\r\n\r\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\r\n const limit = q.limit ?? 100;\r\n const matcher = buildMatcher(q);\r\n const allowedTypes = q.types ? new Set(q.types) : null;\r\n\r\n // Filter sessions BEFORE loading events — avoids loading thousands of events\r\n // from sessions that don't match the time/provider/model criteria.\r\n let ids: string[];\r\n if (sessionId) {\r\n ids = [sessionId];\r\n } else {\r\n const sessions = await this.store.list(1000);\r\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\r\n const filtered = sessions.filter((s) => {\r\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\r\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\r\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\r\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\r\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n ids = filtered.map((s) => s.id);\r\n }\r\n\r\n const hits: SessionSearchHit[] = [];\r\n for (const id of ids) {\r\n let data;\r\n try {\r\n data = await this.store.load(id);\r\n } catch {\r\n continue;\r\n }\r\n for (let i = 0; i < data.events.length; i++) {\r\n const ev = expectDefined(data.events[i]);\r\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\r\n const text = eventText(ev);\r\n if (text === null) continue;\r\n const hit = matcher(text);\r\n if (!hit) continue;\r\n hits.push({\r\n sessionId: id,\r\n eventIndex: i,\r\n ts: ev.ts,\r\n type: ev.type,\r\n snippet: snippetOf(text, hit.start, hit.end),\r\n });\r\n if (hits.length >= limit) return hits;\r\n }\r\n }\r\n return hits;\r\n }\r\n\r\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\r\n const data = await this.store.load(sessionId);\r\n const includeTools = opts.includeTools ?? true;\r\n const includeDiagnostics = opts.includeDiagnostics ?? true;\r\n\r\n const filtered = data.events.filter((e) => {\r\n if (\r\n !includeTools &&\r\n (e.type === 'tool_use' ||\r\n e.type === 'tool_result' ||\r\n e.type === 'tool_call_start' ||\r\n e.type === 'tool_call_end')\r\n ) {\r\n return false;\r\n }\r\n if (\r\n !includeDiagnostics &&\r\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\r\n ) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n if (opts.format === 'json') {\r\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\r\n }\r\n if (opts.format === 'text') {\r\n return renderPlainText(data.metadata, filtered);\r\n }\r\n return renderMarkdown(data.metadata, filtered);\r\n }\r\n\r\n async metadata(sessionId: string): Promise<SessionMetadata> {\r\n const data = await this.store.load(sessionId);\r\n return data.metadata;\r\n }\r\n}\r\n\r\nfunction buildMatcher(\r\n q: SessionSearchQuery,\r\n): (text: string) => { start: number; end: number } | null {\r\n const ci = q.caseInsensitive ?? true;\r\n if (q.regex) {\r\n const flags = ci ? 'i' : '';\r\n const compiled = compileUserRegex(q.query, flags);\r\n if (!compiled.ok) {\r\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\r\n }\r\n const re = compiled.regex;\r\n return (text) => {\r\n const m = re.exec(text);\r\n return m ? { start: m.index, end: m.index + m[0].length } : null;\r\n };\r\n }\r\n const needle = ci ? q.query.toLowerCase() : q.query;\r\n return (text) => {\r\n const hay = ci ? text.toLowerCase() : text;\r\n const idx = hay.indexOf(needle);\r\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\r\n };\r\n}\r\n\r\nfunction eventText(e: SessionEvent): string | null {\r\n switch (e.type) {\r\n case 'user_input':\r\n return contentToString(e.content);\r\n case 'llm_response':\r\n return contentToString(e.content);\r\n case 'tool_use':\r\n return `${e.name} ${JSON.stringify(e.input)}`;\r\n case 'tool_result':\r\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\r\n case 'error':\r\n return `${e.phase}: ${e.message}`;\r\n case 'session_start':\r\n case 'session_resumed':\r\n return `${e.model}/${e.provider}`;\r\n case 'task_created':\r\n case 'task_completed':\r\n return e.title;\r\n case 'task_failed':\r\n return `${e.title}: ${e.error}`;\r\n case 'skill_activated':\r\n case 'skill_deactivated':\r\n return e.skillName;\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\nfunction contentToString(content: string | ContentBlock[]): string {\r\n if (typeof content === 'string') return content;\r\n return content\r\n .map((b) => {\r\n switch (b.type) {\r\n case 'text':\r\n return b.text;\r\n case 'tool_use':\r\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\r\n case 'tool_result':\r\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\r\n default:\r\n return '';\r\n }\r\n })\r\n .join('\\n');\r\n}\r\n\r\nconst SNIPPET_RADIUS = 60;\r\n\r\nfunction snippetOf(text: string, start: number, end: number): string {\r\n const from = Math.max(0, start - SNIPPET_RADIUS);\r\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\r\n const prefix = from > 0 ? '…' : '';\r\n const suffix = to < text.length ? '…' : '';\r\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\r\n}\r\n\r\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(`# Session ${meta.id}`);\r\n lines.push('');\r\n if (meta.model || meta.provider) {\r\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\r\n }\r\n lines.push(`- **Started:** ${meta.startedAt}`);\r\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input': {\r\n lines.push(`## User — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n }\r\n case 'llm_response': {\r\n lines.push(`## Assistant — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n if (e.stopReason && e.stopReason !== 'end_turn') {\r\n lines.push('');\r\n lines.push(`*stop: ${e.stopReason}*`);\r\n }\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_use': {\r\n lines.push(`### Tool call: \\`${e.name}\\``);\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify(e.input, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_result': {\r\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\r\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(body);\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'error': {\r\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\r\n lines.push('');\r\n break;\r\n }\r\n case 'compaction': {\r\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\r\n lines.push('');\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(\r\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\r\n );\r\n lines.push(''.padEnd(72, '-'));\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input':\r\n lines.push(`[${e.ts}] USER`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'llm_response':\r\n lines.push(`[${e.ts}] ASSISTANT`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'tool_use':\r\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\r\n break;\r\n case 'tool_result':\r\n lines.push(\r\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\r\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\r\n }`,\r\n );\r\n break;\r\n case 'error':\r\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/12-30-45Z_model_ab12\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\n/**\n * L2-B: AnnotationsStore — sidecar storage for collaboration annotations\n * (Phase 2 of idea #13 from IDEAS.md).\n *\n * Why a sidecar file, not the session JSONL?\n *\n * The session log is an event-sourced append-only journal\n * (`packages/core/src/types/session.ts` invariant: events are\n * append-only, with `truncateToCheckpoint` only as an explicit\n * rewind). Mixing in human-typed annotations would break that\n * invariant — the user's note about \"this rm looks dangerous\"\n * is not part of the agent's event history; it is meta-commentary\n * on the history.\n *\n * So we keep annotations in a sibling file: one JSON document per\n * session, at `<sessionDir>/<sessionId>.annotations.json`. The\n * shape is a simple versioned array, written atomically.\n *\n * Concurrency model:\n *\n * The store uses a per-session Promise chain to serialize writes.\n * Multiple annotators adding notes at the same time will queue,\n * not race. The atomic write itself is the second line of\n * defense (in case the chain is bypassed — e.g. two processes\n * pointing at the same dir).\n */\n\n/** Wire/storage shape for one annotation. */\nexport interface Annotation {\n /** Stable id (UUIDv4-ish). Referenced by resolve/delete. */\n id: string;\n /** Session this annotation belongs to. */\n sessionId: string;\n /** Index into the session event log the annotation refers to. */\n atEventIndex: number;\n /** Participant id of the annotator (matches WSCollabParticipantJoined.participantId). */\n authorId: string;\n /** Human-readable role label snapshot for display (e.g. \"annotator\"). */\n authorRole: 'annotator';\n /** The note itself. Trimmed, capped at `MAX_TEXT_LENGTH` on add. */\n text: string;\n /** ISO timestamp of creation. */\n createdAt: string;\n /** Resolved state. Annotations start unresolved. */\n resolved: boolean;\n /** ISO timestamp when resolved (if resolved). */\n resolvedAt?: string | undefined;\n /** Participant id of the resolver (if resolved). */\n resolvedBy?: string | undefined;\n}\n\ninterface AnnotationsFile {\n /** Bumped when the on-disk shape changes. v1 = initial release. */\n version: 1;\n annotations: Annotation[];\n}\n\n/** Bumped when the on-disk shape changes. Bump + migration on change. */\nconst FILE_VERSION = 1;\n/** Hard cap to keep a runaway annotator from writing megabytes. */\nconst MAX_TEXT_LENGTH = 2000;\n/** Hard cap on total annotations per session (oldest are evicted beyond this). */\nconst MAX_ANNOTATIONS = 1000;\n\nexport interface AnnotationsStoreOptions {\n /** Directory where `<sessionId>.annotations.json` files live. */\n dir: string;\n}\n\nexport class AnnotationsStore {\n private readonly dir: string;\n /** Per-session write queue. Created lazily on first add. */\n private readonly writeChains = new Map<string, Promise<void>>();\n\n constructor(opts: AnnotationsStoreOptions) {\n this.dir = opts.dir;\n }\n\n // ── Reads ──────────────────────────────────────────────────────────────\n\n /**\n * Return all annotations for `sessionId` in insertion order\n * (oldest first). Returns an empty array when no file exists\n * yet (the normal case for a fresh session).\n */\n async list(sessionId: string): Promise<Annotation[]> {\n const file = await this.readFile(sessionId);\n return file ? file.annotations : [];\n }\n\n /**\n * Convenience: only unresolved annotations, newest first — the\n * common UI rendering for \"what still needs attention?\".\n */\n async listOpen(sessionId: string): Promise<Annotation[]> {\n const all = await this.list(sessionId);\n return all.filter((a) => !a.resolved).reverse();\n }\n\n // ── Writes ─────────────────────────────────────────────────────────────\n\n /**\n * Add a new annotation. Returns the persisted record (with id\n * and timestamps filled in). Throws when `text` is empty or\n * exceeds `MAX_TEXT_LENGTH`.\n */\n async add(input: {\n sessionId: string;\n atEventIndex: number;\n authorId: string;\n text: string;\n }): Promise<Annotation> {\n const text = input.text.trim();\n if (text.length === 0) {\n throw new WrongStackError({\n message: 'Annotation text must be non-empty',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', sessionId: input.sessionId },\n });\n }\n if (text.length > MAX_TEXT_LENGTH) {\n throw new WrongStackError({\n message: `Annotation text exceeds ${MAX_TEXT_LENGTH} chars (got ${text.length})`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', maxLength: MAX_TEXT_LENGTH, actualLength: text.length },\n });\n }\n if (!Number.isInteger(input.atEventIndex) || input.atEventIndex < 0) {\n throw new WrongStackError({\n message: 'atEventIndex must be a non-negative integer',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'atEventIndex', value: input.atEventIndex },\n });\n }\n const annotation: Annotation = {\n id: randomUUID(),\n sessionId: input.sessionId,\n atEventIndex: input.atEventIndex,\n authorId: input.authorId,\n authorRole: 'annotator',\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n };\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const all = await this.list(input.sessionId);\n all.push(annotation);\n // Evict oldest if we crossed the cap. Resolved first, then oldest.\n if (all.length > MAX_ANNOTATIONS) {\n const sorted = all\n .map((a, i) => ({ a, i }))\n .sort((x, y) => {\n // resolved=false wins (keep unresolved); among same resolved state, oldest first.\n if (x.a.resolved !== y.a.resolved) return x.a.resolved ? 1 : -1;\n return x.a.createdAt.localeCompare(y.a.createdAt);\n });\n const evictCount = all.length - MAX_ANNOTATIONS;\n const toEvict = new Set(sorted.slice(0, evictCount).map((s) => s.a.id));\n const kept = all.filter((a) => !toEvict.has(a.id));\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: kept });\n } else {\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n }\n });\n });\n return annotation;\n }\n\n /**\n * Mark an annotation as resolved. Returns the updated record, or\n * `null` if no annotation with that id exists in this session.\n * Idempotent: resolving an already-resolved annotation refreshes\n * `resolvedAt` / `resolvedBy` to the latest call.\n */\n async resolve(input: {\n sessionId: string;\n annotationId: string;\n resolvedBy: string;\n }): Promise<Annotation | null> {\n let updated: Annotation | null = null;\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const all = await this.list(input.sessionId);\n const idx = all.findIndex((a) => a.id === input.annotationId);\n if (idx === -1) {\n updated = null;\n return;\n }\n const next: Annotation = {\n ...expectDefined(all[idx]),\n resolved: true,\n resolvedAt: new Date().toISOString(),\n resolvedBy: input.resolvedBy,\n };\n all[idx] = next;\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n updated = next;\n });\n });\n return updated;\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban here used to\n // throw for every modern session id, breaking annotations entirely.\n return sessionScopedPath(this.dir, sessionId, '.annotations.json');\n }\n\n private async readFile(sessionId: string): Promise<AnnotationsFile | null> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const parsed = JSON.parse(raw) as AnnotationsFile;\n if (parsed.version !== FILE_VERSION) {\n // Future-proof: migrations land here. For now, treat unknown\n // versions as an empty store — safer than crashing on a\n // downgrade.\n return { version: FILE_VERSION, annotations: [] };\n }\n return parsed;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Corrupt JSON or permission error: log via the silent-recovery\n // path (the store doesn't take a logger; callers observe via\n // list() returning [] for an unreadable file is acceptable for\n // Phase 2 — annotations are meta-data, losing them is not fatal).\n return { version: FILE_VERSION, annotations: [] };\n }\n }\n\n private async writeFile(sessionId: string, file: AnnotationsFile): Promise<void> {\n const fp = this.filePath(sessionId);\n await atomicWrite(fp, JSON.stringify(file, null, 2));\n }\n\n /**\n * Serialize writes per-sessionId. We chain promises instead of\n * using a Mutex class so the contract is obvious from the\n * call-site: `enqueue(sid, fn)` runs `fn` after every prior\n * enqueue for `sid` has settled.\n */\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Keep the chain intact even when `fn` throws; failures\n // shouldn't break subsequent writes.\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { createHash } from 'node:crypto';\nimport type { Request } from '../types/provider.js';\n\n/**\n * Idea #2 from IDEAS.md — Deterministic Replay.\n *\n * The hash function is the foundation of replay: given a `Request`,\n * produce a stable identifier so a recorded `Response` can be looked\n * up later when we want to \"re-run\" the same agent loop without\n * burning API credits.\n *\n * Stability rules:\n *\n * - All object keys are sorted recursively before stringification.\n * Without this, two semantically identical requests that differ\n * only in key insertion order would produce different hashes.\n * - We hash ONLY the fields that affect the response: `model`,\n * `system`, `messages`, `tools`, `maxTokens`, and the four\n * sampling knobs (`temperature`, `topP`, `stopSequences`,\n * `toolChoice`). Anything else on the `Request` (metadata,\n * future extensions) is ignored so replay stays forward-compat.\n * - We serialize to JSON. The `ContentBlock` and `Message` shapes\n * are pure data; this works as long as no `undefined` values\n * sneak in (those get dropped by `JSON.stringify`, which is\n * fine — the structural diff is what matters).\n *\n * The SHA-256 output is hex-encoded and prefixed with the algorithm\n * tag so a future migration to a different hash (e.g. blake3) is\n * trivial to detect.\n */\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function hashRequest(request: Request): string {\n // Pick only the fields that affect the response. See stability rules.\n const payload = {\n model: request.model,\n system: request.system,\n messages: request.messages,\n tools: request.tools,\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n topP: request.topP,\n stopSequences: request.stopSequences,\n toolChoice: request.toolChoice,\n };\n const json = stableStringify(payload);\n const digest = createHash('sha256').update(json, 'utf8').digest('hex');\n return `sha256:${digest}`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { hashRequest } from '../replay/hash.js';\nimport type { Request, Response } from '../types/provider.js';\nimport { safeParse } from '../utils/safe-json.js';\n\n/**\n * ReplayLogStore — sidecar store for deterministic-replay support\n * (idea #2 from IDEAS.md). One JSONL file per session, recording\n * every provider request/response pair so the same agent loop can\n * be re-run later with frozen API responses.\n *\n * Why a sidecar (not the session JSONL)?\n *\n * Same reason as `AnnotationsStore` — the session log is\n * event-sourced and append-only; a provider request payload can be\n * tens of kilobytes (especially with long conversation history),\n * and we want replay to be opt-in (recorded only when the user\n * runs with `--replay` or a future equivalent). Mixing it into\n * the event log would inflate every read for replay-irrelevant\n * paths.\n *\n * File layout: `<dir>/<sessionId>.replay.jsonl`, one entry per line.\n * Each entry: `{ hash, ts, request, response }`. The `hash` is\n * computed via `hashRequest` so lookups are O(1) by hash.\n *\n * Concurrency: per-session write queue (same pattern as\n * `AnnotationsStore`). Reads are lock-free; the write chain makes\n * the append + rehash sequence atomic.\n */\nexport interface ReplayEntry {\n hash: string;\n ts: string;\n request: Request;\n response: Response;\n}\n\nconst FILE_VERSION = 1;\n\n/** Default cap on the number of entries per session. */\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport interface ReplayLogStoreOptions {\n /** Directory where `<sessionId>.replay.jsonl` files live. */\n dir: string;\n /**\n * Cap on the number of entries per session. When a `record` would\n * push the file beyond this, the oldest entries are evicted (LRU\n * by insertion order). Set to `Infinity` to disable rotation.\n * Defaults to 1000 — a single LLM call averages ~5KB serialized\n * (messages + tools + response), so 1000 entries is ~5MB per\n * session which is a reasonable upper bound.\n */\n maxEntries?: number | undefined;\n}\n\nexport class ReplayLogStore {\n private readonly dir: string;\n private readonly writeChains = new Map<string, Promise<void>>();\n /** Per-session hash → entry index, kept in memory after the first load. */\n private readonly cache = new Map<string, Map<string, ReplayEntry>>();\n /** Per-session entry count on disk, to detect when compaction is needed. */\n private readonly diskCount = new Map<string, number>();\n private readonly maxEntries: number;\n\n constructor(opts: ReplayLogStoreOptions) {\n this.dir = opts.dir;\n this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n // ── Writes ──────────────────────────────────────────────────────────────\n\n /**\n * Record a request/response pair. Idempotent on hash: a second\n * `record` for the same hash is a no-op (the existing entry wins).\n * Returns the hash.\n */\n async record(input: {\n sessionId: string;\n request: Request;\n response: Response;\n }): Promise<string> {\n const hash = hashRequest(input.request);\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const entries = await this.readAll(input.sessionId);\n if (entries.some((entry) => entry.hash === hash)) return; // already recorded\n const entry: ReplayEntry = {\n hash,\n ts: new Date().toISOString(),\n request: input.request,\n response: input.response,\n };\n // True append — O(1) per write. Only compact (full rewrite) when\n // we exceed maxEntries and need to evict oldest entries.\n entries.push(entry);\n const keep = entries.slice(-this.maxEntries);\n const cache = new Map<string, ReplayEntry>();\n for (const e of keep) cache.set(e.hash, e);\n this.cache.set(input.sessionId, cache);\n await this.rewriteCache(input.sessionId, cache);\n });\n });\n return hash;\n }\n\n /**\n * Compact the replay log to keep only the most recent maxEntries.\n * Called when entry count exceeds the cap. Rewrites the entire file\n * but only happens O(n / maxEntries) times per session.\n */\n private async rewriteCache(sessionId: string, cache: Map<string, ReplayEntry>): Promise<void> {\n // Map.values() preserves insertion order — take the last maxEntries.\n const all = [...cache.values()];\n const keep = all.slice(-this.maxEntries);\n await this.writeAll(sessionId, keep);\n cache.clear();\n for (const e of keep) cache.set(e.hash, e);\n this.diskCount.set(sessionId, keep.length);\n }\n\n // ── Reads ───────────────────────────────────────────────────────────────\n\n /**\n * Look up an entry by hash. Returns `null` when the request has\n * not been recorded for this session. O(1) after the first call\n * per session (in-memory cache).\n */\n async lookup(sessionId: string, hash: string): Promise<ReplayEntry | null> {\n const cache = await this.ensureCache(sessionId);\n return cache.get(hash) ?? null;\n }\n\n /** All recorded entries for a session, in insertion order. */\n async load(sessionId: string): Promise<ReplayEntry[]> {\n const cache = await this.ensureCache(sessionId);\n return [...cache.values()];\n }\n\n /**\n * List every session id that has a replay log in the store dir.\n * Returns an array of `{ sessionId, entryCount, path }` sorted\n * by sessionId for stable output. Used by `wstack replay --list`.\n */\n async list(): Promise<Array<{ sessionId: string; entryCount: number; path: string }>> {\n const out: Array<{ sessionId: string; entryCount: number; path: string }> = [];\n // Replay logs sit next to their session JSONL — flat at the root for\n // legacy/`record-<ts>` ids, inside a date-shard dir for modern ids.\n // Scan both levels; a root-only scan misses every sharded session.\n const scan = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if (depth === 0 && (err as NodeJS.ErrnoException).code !== 'ENOENT') {\n // EACCES, ENOTDIR, etc. — log the real error so the operator can\n // diagnose a misconfiguration, but still return empty list so the\n // caller (slash command display) doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'replay_log_store.list_readdir_failed',\n dir,\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n if (depth === 0) await scan(path.join(dir, entry.name), entry.name, depth + 1);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.replay.jsonl')) continue;\n const base = entry.name.slice(0, -'.replay.jsonl'.length);\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const all = await this.load(sessionId);\n out.push({\n sessionId,\n entryCount: all.length,\n path: path.join(dir, entry.name),\n });\n }\n };\n await scan(this.dir, '', 0);\n return out.sort((a, b) => a.sessionId.localeCompare(b.sessionId));\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // the moment a real (sharded) session id is used for --replay.\n return sessionScopedPath(this.dir, sessionId, '.replay.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: ReplayEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<\n { version?: number | undefined; entry?: ReplayEntry | undefined } & ReplayEntry\n >(line);\n if (!parsed.ok || !parsed.value) continue;\n // Forward-compat: v1 stores entries one per line, no envelope.\n // A future \"v2\" could wrap with `{version, entries:[...]}`;\n // the loader would then branch on `parsed.version`.\n if ('entry' in parsed.value && parsed.value.entry) {\n out.push(parsed.value.entry);\n } else {\n out.push(parsed.value);\n }\n } catch {\n // Skip a corrupt line — annotations-store and other sidecar\n // stores take the same approach (meta-data, not fatal).\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Corrupt or unreadable: treat as empty.\n return [];\n }\n }\n\n private async writeAll(sessionId: string, entries: ReplayEntry[]): Promise<void> {\n const fp = this.filePath(sessionId);\n const body = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n await atomicWrite(fp, body);\n // Drop the version-stamp comment at the top — v1 has no envelope,\n // but we keep a one-line marker for human readers / future tooling.\n // (The atomicWrite just wrote pure JSONL; that's correct for v1.)\n void FILE_VERSION;\n }\n\n private async ensureCache(sessionId: string): Promise<Map<string, ReplayEntry>> {\n let cache = this.cache.get(sessionId);\n if (cache) return cache;\n const all = await this.readAll(sessionId);\n cache = new Map();\n for (const e of all) cache.set(e.hash, e);\n this.cache.set(sessionId, cache);\n this.diskCount.set(sessionId, all.length);\n return cache;\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SessionEvent } from '../types/session.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * Idea #1 from IDEAS.md — Stateful Session Recovery.\n *\n * `SessionRecovery` is the read-side companion to the in-flight\n * marker mechanism. When the agent loop is running, it writes an\n * `in_flight_start` event at the current point in the log. On\n * clean shutdown, a matching `in_flight_end` follows. If the\n * process dies (crash, OOM, machine sleep, SIGKILL) the marker\n * is the last event in the file — and `detectStale` flags the\n * session as \"incomplete, can be resumed\".\n *\n * Phase 1 of this feature is **detection only**. The actual\n * re-execution of incomplete work is a follow-up: it requires\n * tracking pending tool calls, mid-stream LLM responses, and\n * uncommitted file changes — and re-running the agent loop from\n * the last `checkpoint` event. The detection layer is independent\n * and ships first because (a) it gives the user immediate\n * visibility into what died, and (b) it's the foundation for the\n * resume command and the CLI's \"Incomplete sessions\" surface.\n *\n * Concurrency: pure read; no writes. Safe to call from multiple\n * processes simultaneously.\n */\nexport interface StaleSession {\n sessionId: string;\n /** Path to the JSONL log. */\n path: string;\n /** Last event ts (the in_flight_start timestamp). */\n lastEventTs: string;\n /** Context the agent was working on when it died. */\n context: string;\n /** Total events in the log. */\n eventCount: number;\n}\n\nexport interface RecoveryPlan {\n sessionId: string;\n /** True if the session is stale (has a dangling in_flight_start). */\n stale: boolean;\n /** The last `checkpoint` event before the un-replayed work, or null. */\n lastCheckpoint: SessionEvent | null;\n /** All events after the last checkpoint (i.e. the work that needs re-execution). */\n pendingEvents: SessionEvent[];\n /** The dangling in_flight_start event, if any. */\n inFlightStart: SessionEvent | null;\n /** Free-form context the agent was working on, if any. */\n context: string | null;\n}\n\n/**\n * Result of `SessionRecovery.recover(sessionId)`. Distinct from\n * `StaleSession`: a session is \"stale\" if the last event is an\n * open marker, but a \"recovery plan\" can also be generated for\n * clean sessions whose last checkpoint is older than the\n * conversation history (e.g. a user-initiated \"rewind to last\n * good state\" flow). Phase 2 of idea #1: this returns the plan;\n * the actual kernel re-execution is a follow-up.\n */\nexport class SessionRecovery {\n /**\n * Scan a session log and return a `StaleSession` if and only\n * if the last event is an `in_flight_start` without a matching\n * `in_flight_end`. Returns `null` when:\n * - the log does not exist;\n * - the log is empty;\n * - the last event is `in_flight_end` (clean shutdown);\n * - the last event is something else (e.g. an unannotated\n * legacy log without in-flight markers).\n */\n async detectStale(sessionId: string): Promise<StaleSession | null> {\n const fp = this.filePath(sessionId);\n // Only read the last ~8KB — enough for several large events.\n // This is O(1) I/O vs O(n) of reading the entire file.\n const TAIL_SIZE = 8192;\n let stat;\n try {\n stat = await fs.stat(fp);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n return null;\n }\n if (stat.size === 0) return null;\n const position = Math.max(0, stat.size - TAIL_SIZE);\n const buf = Buffer.alloc(TAIL_SIZE);\n let fh;\n try {\n fh = await fs.open(fp, 'r');\n const { bytesRead } = await fh.read(buf, 0, TAIL_SIZE, position);\n // Count total events for StaleSession.eventCount — requires full scan.\n // For very large files this is a trade-off; count is informational.\n let eventCount = 0;\n const raw = buf.subarray(0, bytesRead).toString('utf8');\n for (const line of raw.split('\\n')) {\n if (line.trim()) eventCount++;\n }\n // Find the last complete JSON line in the tail.\n const lines = raw.split('\\n').filter((l) => l.trim());\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const ev = JSON.parse(expectDefined(lines[i])) as SessionEvent;\n if (ev.type === 'in_flight_start') {\n return {\n sessionId,\n path: fp,\n lastEventTs: ev.ts,\n context: ev.context,\n eventCount,\n };\n }\n // Found a different last event — clean shutdown or legacy\n return null;\n } catch {\n // Incomplete line (spans the read boundary) — skip\n }\n }\n return null;\n } catch {\n return null;\n } finally {\n if (fh) await fh.close();\n }\n }\n\n /**\n * Generate a recovery plan for a session. The plan describes\n * \"what would be re-executed\" if the user chose to resume —\n * everything after the last `checkpoint` event, plus the\n * dangling in-flight marker if present.\n *\n * Returns a non-null plan for ANY session that has at least\n * one event after a checkpoint (or, for legacy sessions, at\n * least one event). Pure read; no mutation.\n */\n async recover(sessionId: string): Promise<RecoveryPlan | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n return null;\n }\n const events: SessionEvent[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n if (events.length === 0) return null;\n // Find the last checkpoint.\n let lastCheckpoint: SessionEvent | null = null;\n let lastCheckpointIdx = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i]?.type === 'checkpoint') {\n lastCheckpoint = expectDefined(events[i]);\n lastCheckpointIdx = i;\n }\n }\n // Events after the last checkpoint = the work that needs re-execution.\n const pendingEvents =\n lastCheckpointIdx >= 0 ? events.slice(lastCheckpointIdx + 1) : events;\n // The dangling in_flight_start, if the last event is one.\n const lastEv = expectDefined(events[events.length - 1]);\n const inFlightStart =\n lastEv.type === 'in_flight_start' ? lastEv : null;\n const context = inFlightStart && inFlightStart.type === 'in_flight_start'\n ? inFlightStart.context\n : null;\n return {\n sessionId,\n stale: inFlightStart !== null,\n lastCheckpoint,\n pendingEvents,\n inFlightStart,\n context,\n };\n }\n\n /**\n * List every stale session in a directory. Returns an array\n * (possibly empty) sorted by `lastEventTs` descending — most\n * recent crash first.\n */\n async listResumable(): Promise<StaleSession[]> {\n const out: StaleSession[] = [];\n // Modern sessions live inside date-shard subdirectories\n // (\"2026-06-11/<base>.jsonl\"); legacy/flat sessions sit at the root.\n // Scan both — a root-only scan silently misses every modern crash.\n const collect = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (\n entry.name === 'shared' ||\n entry.name === 'subagents' ||\n entry.name === 'attachments'\n )\n continue;\n if (entry.isDirectory()) {\n if (depth === 0) {\n await collect(path.join(dir, entry.name), entry.name, depth + 1);\n }\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.jsonl')) continue;\n if (entry.name === '_index.jsonl' || entry.name === '_mailbox.jsonl') continue;\n const base = entry.name.slice(0, -'.jsonl'.length);\n if (base.includes('.replay') || base.includes('.annotations') || base.includes('.audit'))\n continue;\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const stale = await this.detectStale(sessionId);\n if (stale) out.push(stale);\n }\n };\n await collect(this.dir, '', 0);\n return out.sort((a, b) => b.lastEventTs.localeCompare(a.lastEventTs));\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. Shared with the other per-session\n // sidecar stores so the contract can't drift.\n return sessionScopedPath(this.dir, sessionId, '.jsonl');\n }\n\n constructor(private readonly dir: string) {}\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * ToolAuditLog — idea #9 from IDEAS.md.\n *\n * Tamper-evident audit trail for tool calls. Every tool_use /\n * tool_result pair is appended to a sidecar JSONL with a chained\n * SHA-256 — each entry's `prevHash` is the prior entry's `hash`,\n * so any post-hoc modification of a single line breaks the chain\n * from that point forward.\n *\n * Why a sidecar (not the session JSONL)?\n * Same reason as `AnnotationsStore` and `ReplayLogStore`: the\n * session log is an event-sourced journal. Mixing in a hash\n * chain would inflate every read and tightly couple the\n * integrity check to the event format. Sidecar keeps both\n * concerns orthogonal.\n *\n * What \"tamper-evident\" means here:\n * - The hash covers the full serialized entry: tool name, id,\n * input, output, timestamp, author. Changing any byte\n * changes the hash.\n * - The chain is sequential — a verifier walks the file in\n * order, recomputing each hash, and checks `prevHash`\n * matches the previous entry's `hash`.\n * - Any insertion, deletion, or modification of a single\n * entry surfaces as a \"chain broken at entry N\" verdict.\n *\n * What it does NOT defend against:\n * - An attacker who rewrites the whole file consistently.\n * For that you'd need an external anchor (signing key,\n * transparency log, etc.) — out of scope for Phase 1.\n * - The agent itself misbehaving; this is post-hoc audit, not\n * real-time enforcement. Use `PermissionPolicy` for that.\n *\n * File layout: `<dir>/<sessionId>.audit.jsonl`, one entry per\n * line. The chain starts with a `genesis` entry whose\n * `prevHash` is all zeros.\n */\nexport interface AuditEntry {\n /** Monotonic index (0-based). */\n index: number;\n /** UUID for cross-referencing with logs. */\n id: string;\n /** ISO timestamp. */\n ts: string;\n /** Hash of the previous entry (or all-zeros for the genesis entry). */\n prevHash: string;\n /** Hash of this entry's content (sha256 over the canonical JSON). */\n hash: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n}\n\nconst GENESIS_PREV = '0'.repeat(64);\n\nexport type VerifyResult =\n | { ok: true; entries: number }\n | { ok: false; brokenAt: number; reason: string };\n\nexport interface ToolAuditLogOptions {\n /** Directory where `<sessionId>.audit.jsonl` files live. */\n dir: string;\n /**\n * Flush the file system cache to disk every N writes per session.\n * Default 100. Lower values = better crash durability, more I/O overhead.\n * Set to `Infinity` to disable periodic fsync (fastest, but highest data-loss risk).\n */\n fsyncEvery?: number | undefined;\n}\n\n/** Default number of writes between fsync calls. */\nconst DEFAULT_FSYNC_EVERY = 100;\n\nexport class ToolAuditLog {\n private readonly dir: string;\n /** In-memory cache of the last entry's hash (per session), to compute chains efficiently. */\n private readonly tailHash = new Map<string, string>();\n /** In-memory counter for entry indices — avoids re-reading the file on every write. */\n private readonly tailIndex = new Map<string, number>();\n /** Tracks writes since last fsync, per session. */\n private readonly unSyncedWrites = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly fsyncEvery: number;\n\n constructor(opts: ToolAuditLogOptions) {\n this.dir = opts.dir;\n this.fsyncEvery = opts.fsyncEvery ?? DEFAULT_FSYNC_EVERY;\n }\n\n /**\n * Append a tool call/result pair to the chain. Returns the\n * resulting entry. Idempotency is not guaranteed — if you\n * record the same tool_use twice you get two entries. That's\n * intentional: the audit log is a record, not a cache.\n */\n async record(input: {\n sessionId: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n }): Promise<AuditEntry> {\n let entry!: AuditEntry; // assigned inside the enqueue callback\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(this.filePath(input.sessionId), async () => {\n const entries = await this.readAll(input.sessionId);\n const prev = entries.at(-1);\n const prevHash = prev?.hash ?? GENESIS_PREV;\n const index = prev ? prev.index + 1 : 0;\n const id = randomUUID();\n const ts = new Date().toISOString();\n const content = {\n id,\n ts,\n prevHash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n const hash = createHash('sha256').update(stableStringify(content), 'utf8').digest('hex');\n entry = {\n id,\n ts,\n prevHash,\n hash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n entries.push(entry);\n await this.writeAll(input.sessionId, entries);\n this.tailHash.set(input.sessionId, hash);\n this.tailIndex.set(input.sessionId, index + 1);\n });\n });\n return entry;\n }\n\n /**\n * Walk the chain and verify every entry's hash and prevHash.\n * Returns a structured verdict — never throws.\n */\n async verify(sessionId: string): Promise<VerifyResult> {\n const entries = await this.readAll(sessionId);\n if (entries.length === 0) return { ok: true, entries: 0 };\n // The first entry's prevHash must be the all-zeros genesis marker.\n if (entries[0]?.prevHash !== GENESIS_PREV) {\n return {\n ok: false,\n brokenAt: 0,\n reason: 'first entry is not the genesis (prevHash != 0…0)',\n };\n }\n let prevHash = GENESIS_PREV;\n for (let i = 0; i < entries.length; i++) {\n const e = expectDefined(entries[i]);\n if (e.prevHash !== prevHash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `prevHash mismatch at entry ${i} (expected ${prevHash.slice(0, 8)}…, got ${e.prevHash.slice(0, 8)}…)`,\n };\n }\n // Recompute the hash from the entry's content (without the\n // `hash` field itself, which is what we are verifying).\n const content = {\n id: e.id,\n ts: e.ts,\n prevHash: e.prevHash,\n toolName: e.toolName,\n toolUseId: e.toolUseId,\n input: e.input,\n output: e.output,\n isError: e.isError,\n index: e.index,\n };\n const expectedHash = createHash('sha256')\n .update(stableStringify(content), 'utf8')\n .digest('hex');\n if (expectedHash !== e.hash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `hash mismatch at entry ${i} (entry content was modified)`,\n };\n }\n prevHash = e.hash;\n }\n return { ok: true, entries: entries.length };\n }\n\n /** All entries for a session, in insertion order. */\n async load(sessionId: string): Promise<AuditEntry[]> {\n return this.readAll(sessionId);\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // for every modern session id the moment record() gets wired in.\n return sessionScopedPath(this.dir, sessionId, '.audit.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: AuditEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<AuditEntry>(line);\n if (parsed.ok && parsed.value) out.push(parsed.value);\n } catch {\n // Skip corrupt lines — audit data is meta, not fatal.\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n return [];\n }\n }\n\n private async writeAll(sessionId: string, entries: AuditEntry[]): Promise<void> {\n const fp = this.filePath(sessionId);\n const line = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n // Real append — O(1) per write. The write chain ensures serial\n // ordering per session. On crash a partial line may appear;\n // readAll skips unparseable lines so the chain stays verifiable.\n await atomicWrite(fp, line, { mode: 0o600 });\n // Periodic fsync: every fsyncEvery writes, open the file and sync it.\n // This limits data loss to at most fsyncEvery entries on crash.\n const count = (this.unSyncedWrites.get(sessionId) ?? 0) + 1;\n this.unSyncedWrites.set(sessionId, count);\n if (this.fsyncEvery !== Number.POSITIVE_INFINITY && count % this.fsyncEvery === 0) {\n await this.sync(sessionId, fp);\n }\n }\n\n /**\n * Explicitly sync the file to disk. Called automatically every\n * `fsyncEvery` writes, and available for callers who want to\n * force a sync before closing or during graceful shutdown.\n */\n async flush(sessionId: string): Promise<void> {\n await this.sync(sessionId, this.filePath(sessionId));\n }\n\n private async sync(sessionId: string, fp: string): Promise<void> {\n try {\n const fh = await fs.open(fp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync is best-effort; a failure here does not corrupt the chain.\n } finally {\n this.unSyncedWrites.set(sessionId, 0);\n }\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n","import type { SessionEvent } from '../types/session.js';\n\nexport interface QueryFilter {\n eventTypes?: string[] | undefined;\n toolNames?: string[] | undefined;\n timeRange?: { start: string; end: string } | undefined;\n}\n\nexport interface ToolInvocation {\n ts: string;\n name: string;\n input: unknown;\n output?: unknown | undefined;\n error?: string | undefined;\n durationMs: number;\n}\n\nexport interface SessionError {\n ts: string;\n phase: string;\n message: string;\n}\n\nexport interface ModeChange {\n ts: string;\n from: string;\n to: string;\n}\n\nexport interface TaskSummary {\n taskId: string;\n title: string;\n status: string;\n createdAt: string;\n completedAt?: string | undefined;\n}\n\nexport interface SessionAnalysis {\n sessionId: string;\n totalDuration: number;\n toolUsageCount: Record<string, number>;\n errorCount: number;\n modeChanges: ModeChange[];\n tasks: TaskSummary[];\n}\n\nexport class SessionAnalyzer {\n analyze(events: SessionEvent[]): SessionAnalysis {\n const toolUsageCount: Record<string, number> = {};\n const errors: SessionError[] = [];\n const modeChanges: ModeChange[] = [];\n const tasksById = new Map<string, TaskSummary>();\n let sessionId = '';\n\n for (const event of events) {\n // sessionId comes from session_start / session_resumed.\n if (event.type === 'session_start' || event.type === 'session_resumed') {\n if (!sessionId) sessionId = event.id;\n }\n if (event.type === 'tool_use') {\n toolUsageCount[event.name] = (toolUsageCount[event.name] ?? 0) + 1;\n }\n if (event.type === 'error') {\n errors.push({ ts: event.ts, phase: event.phase, message: event.message });\n }\n if (event.type === 'mode_changed') {\n modeChanges.push({ ts: event.ts, from: event.from, to: event.to });\n }\n if (event.type === 'task_created') {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'created',\n createdAt: event.ts,\n });\n }\n if (event.type === 'task_updated') {\n const t = tasksById.get(event.taskId);\n if (t) t.status = event.status;\n }\n if (event.type === 'task_completed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'completed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'completed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n if (event.type === 'task_failed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'failed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'failed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n }\n\n return {\n sessionId,\n totalDuration: this.calcDuration(events),\n toolUsageCount,\n errorCount: errors.length,\n modeChanges,\n tasks: Array.from(tasksById.values()),\n };\n }\n\n query(events: SessionEvent[], filter: QueryFilter): SessionEvent[] {\n return events.filter((e) => {\n if (filter.eventTypes?.length && !filter.eventTypes.includes(e.type)) return false;\n if (filter.toolNames?.length && e.type === 'tool_use') {\n const toolEvent = e as { type: 'tool_use'; name: string };\n if (!filter.toolNames.includes(toolEvent.name)) return false;\n }\n if (filter.timeRange) {\n const ts = new Date(e.ts).getTime();\n const start = new Date(filter.timeRange.start).getTime();\n const end = new Date(filter.timeRange.end).getTime();\n if (ts < start || ts > end) return false;\n }\n return true;\n });\n }\n\n private calcDuration(events: SessionEvent[]): number {\n if (events.length < 2) return 0;\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n if (!firstEvent || !lastEvent) return 0;\n const first = new Date(firstEvent.ts).getTime();\n const last = new Date(lastEvent.ts).getTime();\n return last - first;\n }\n}\n","/**\n * SessionRegistry — cross-process session and agent tracker.\n *\n * Each WrongStack process registers its session on start and updates its\n * status periodically. The registry is a single JSON file at\n * `~/.wrongstack/session-registry.json`. Entries are keyed by session ID.\n *\n * Because multiple processes may write concurrently, every write is an\n * atomic read-modify-write protected by a per-file advisory lock (flock on\n * Unix, exclusive open on Windows). Stale entries (process no longer alive)\n * are pruned on every read.\n *\n * @module session-registry\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\n/** Live status of a single agent within a session. */\nexport type AgentLiveStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user' // brain.ask_human, confirm prompt\n | 'error';\n\nexport interface AgentEntry {\n /** Unique agent id (ULID or UUID). */\n id: string;\n /** Human-readable label (e.g. \"leader\", \"bug-hunter #1\"). */\n name: string;\n status: AgentLiveStatus;\n /** Current tool name if running, undefined otherwise. */\n currentTool?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** UTC ISO timestamp of last activity. */\n lastActivityAt: string;\n}\n\nexport type SessionLiveStatus =\n | 'active' // process running, agents may be idle or busy\n | 'idle' // process running, no agent activity\n | 'closing' // session_end written, process shutting down\n | 'stale'; // process no longer alive (pruned on next read)\n\nexport interface SessionRegistryEntry {\n sessionId: string;\n projectSlug: string;\n projectRoot: string;\n projectName: string;\n workingDir: string;\n /** Current git branch, if the project is a git repo. Detected at registration. */\n gitBranch?: string | undefined;\n status: SessionLiveStatus;\n pid: number;\n /** UTC ISO */\n startedAt: string;\n /** UTC ISO — updated on every heartbeat */\n lastHeartbeatAt: string;\n /** Count of tracked agents */\n agentCount: number;\n agents: AgentEntry[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\nconst REGISTRY_FILE = 'session-registry.json';\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst STALE_TIMEOUT_MS = 30_000; // entry considered stale after 30s without heartbeat\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Registry class ────────────────────────────────────────────────────────\n\nexport class SessionRegistry {\n private readonly filePath: string;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private currentSessionId: string | null = null;\n\n constructor(globalRoot: string) {\n this.filePath = path.join(globalRoot, REGISTRY_FILE);\n }\n\n // ── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Register the current session. Call once on session start.\n * Starts the heartbeat timer.\n */\n async register(\n entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {\n agents?: AgentEntry[] | undefined;\n },\n ): Promise<void> {\n this.currentSessionId = entry.sessionId;\n const full: SessionRegistryEntry = {\n ...entry,\n status: 'active',\n lastHeartbeatAt: new Date().toISOString(),\n agentCount: entry.agents?.length ?? 0,\n agents: entry.agents ?? [],\n };\n await this.atomicUpdate((registry) => {\n // Prune dead entries that haven't heartbeated recently.\n // A just-created entry has no heartbeat yet — don't prune it.\n const now = Date.now();\n for (const [id, existing] of Object.entries(registry)) {\n if (existing.pid === entry.pid) continue;\n const heartbeatAge = now - new Date(existing.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(existing.pid)) {\n delete registry[id];\n }\n }\n registry[entry.sessionId] = full;\n });\n\n // Start heartbeat\n this.heartbeatTimer = setInterval(() => {\n void this.heartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n if (this.heartbeatTimer.unref) this.heartbeatTimer.unref();\n }\n\n /**\n * Update agent status for the current session. Call on every\n * significant status change (agent start, tool start, user wait, error).\n */\n async updateAgents(agents: AgentEntry[]): Promise<void> {\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.agents = agents;\n entry.agentCount = agents.length;\n // Derive session status from agent collective\n const hasRunning = agents.some((a) => a.status === 'running' || a.status === 'streaming');\n const hasWaiting = agents.some((a) => a.status === 'waiting_user');\n const hasError = agents.some((a) => a.status === 'error');\n entry.status = hasRunning ? 'active' : hasWaiting ? 'active' : hasError ? 'active' : 'idle';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Mark the session as closing. Called during shutdown.\n * Stops the heartbeat timer.\n */\n async markClosing(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.status = 'closing';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Remove the current session from the registry. Call on clean exit.\n */\n async unregister(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n const sid = this.currentSessionId;\n this.currentSessionId = null;\n await this.atomicUpdate((registry) => {\n delete registry[sid];\n });\n }\n\n /**\n * List all non-stale sessions. Prunes stale entries automatically.\n */\n async list(): Promise<SessionRegistryEntry[]> {\n const registry = await this.readAndPrune();\n return Object.values(registry);\n }\n\n /**\n * Get a single session entry by ID. Returns undefined if not found or stale.\n */\n async get(sessionId: string): Promise<SessionRegistryEntry | undefined> {\n const registry = await this.readAndPrune();\n return registry[sessionId];\n }\n\n /**\n * List all sessions for a specific project (by slug).\n */\n async listByProject(projectSlug: string): Promise<SessionRegistryEntry[]> {\n const all = await this.list();\n return all.filter((e) => e.projectSlug === projectSlug);\n }\n\n /**\n * Return the registry file path. Useful for WebUI to watch/read.\n */\n get registryPath(): string {\n return this.filePath;\n }\n\n // ── Internal ────────────────────────────────────────────────────────────\n\n private async heartbeat(): Promise<void> {\n if (!this.currentSessionId) return;\n // Only update heartbeat timestamp — avoid full read-modify-write for perf\n try {\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const entry = registry[this.currentSessionId];\n if (entry) {\n entry.lastHeartbeatAt = new Date().toISOString();\n // Status bound: if closing, don't revert\n if (entry.status !== 'closing') {\n const hasRunning = (entry.agents ?? []).some(\n (a) => a.status === 'running' || a.status === 'streaming',\n );\n entry.status = hasRunning ? 'active' : 'idle';\n }\n await this.writeAtomic(registry);\n }\n } catch {\n // Best-effort heartbeat — never throw\n }\n }\n\n private async readAndPrune(): Promise<Record<string, SessionRegistryEntry>> {\n try {\n const raw = await fs.readFile(this.filePath, 'utf8');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const now = Date.now();\n let pruned = false;\n\n for (const [id, entry] of Object.entries(registry)) {\n const heartbeatAge = now - new Date(entry.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(entry.pid)) {\n entry.status = 'stale';\n // Keep stale entries for 5 minutes so UIs can show \"recently closed\"\n const startedAge = now - new Date(entry.startedAt).getTime();\n if (startedAge > 5 * 60_000) {\n delete registry[id];\n pruned = true;\n }\n }\n }\n\n if (pruned) {\n await this.writeAtomic(registry).catch(() => undefined);\n }\n\n return registry;\n } catch {\n return {};\n }\n }\n\n private async atomicUpdate(\n fn: (registry: Record<string, SessionRegistryEntry>) => void,\n ): Promise<void> {\n const lockPath = `${this.filePath}.lock`;\n const maxRetries = 5;\n const retryDelayMs = 20;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n // Acquire exclusive lock via O_CREAT | O_EXCL\n const lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n if (!lockHandle) {\n // Lock held by another process — wait and retry\n await new Promise((r) => setTimeout(r, retryDelayMs * (attempt + 1)));\n continue;\n }\n\n try {\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n fn(registry);\n await this.writeAtomicLocked(registry);\n return; // success\n } finally {\n await lockHandle.close();\n await fs.unlink(lockPath).catch(() => undefined);\n }\n } catch {\n // Best-effort — never throw from registry writes\n return;\n }\n }\n // All retries exhausted — registry update dropped (non-critical)\n }\n\n private async writeAtomicLocked(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n\n /** Legacy write without lock — used by heartbeat for performance. */\n private async writeAtomic(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n}\n\n/** Singleton — created once per process. */\nlet _instance: SessionRegistry | null = null;\n\nexport function getSessionRegistry(globalRoot?: string): SessionRegistry {\n if (!_instance && globalRoot) {\n _instance = new SessionRegistry(globalRoot);\n }\n if (!_instance) {\n throw new Error('SessionRegistry not initialized. Call getSessionRegistry(globalRoot) first.');\n }\n return _instance;\n}\n\nexport function hasSessionRegistry(): boolean {\n return _instance !== null;\n}\n","/**\n * AgentStatusTracker — subscribes to EventBus events and keeps the\n * SessionRegistry updated with live agent status.\n *\n * Created once per process during boot. Listens for:\n * - agent.run.started / agent.run.completed → agent status changes\n * - tool.started / tool.executed → current tool tracking\n * - brain.ask_human → waiting_user status\n * - fleet events (subagent spawn/start/done) → agent entries\n *\n * @module agent-status-tracker\n */\nimport type { EventBus } from './kernel/events.js';\nimport type {\n AgentEntry,\n AgentLiveStatus,\n SessionRegistry,\n} from './session-registry.js';\n\nexport interface AgentStatusTrackerOptions {\n events: EventBus;\n registry: SessionRegistry;\n /** Leader agent name shown in the registry. Default: \"leader\". */\n leaderName?: string | undefined;\n}\n\nexport class AgentStatusTracker {\n private readonly events: EventBus;\n private readonly registry: SessionRegistry;\n private readonly leaderName: string;\n\n // Live agent map: agentId → AgentEntry\n private agents = new Map<string, AgentEntry>();\n\n // Leader tracking\n private leaderStatus: AgentLiveStatus = 'idle';\n private leaderCurrentTool: string | undefined;\n private leaderIterations = 0;\n private leaderToolCalls = 0;\n\n private unsubscribers: Array<() => void> = [];\n\n constructor(opts: AgentStatusTrackerOptions) {\n this.events = opts.events;\n this.registry = opts.registry;\n this.leaderName = opts.leaderName ?? 'leader';\n }\n\n start(): void {\n // Leader events\n this.unsubscribers.push(\n this.events.onPattern('agent.run.started', () => {\n this.leaderStatus = 'running';\n this.leaderIterations++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.completed', () => {\n this.leaderStatus = 'idle';\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.error', () => {\n this.leaderStatus = 'error';\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Tool events — track current tool\n this.unsubscribers.push(\n this.events.onPattern('tool.started', (_event, payload) => {\n const p = payload as { name?: string } | undefined;\n if (p?.name) {\n this.leaderCurrentTool = p.name;\n this.leaderToolCalls++;\n }\n this.leaderStatus = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('tool.executed', () => {\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Brain ask_human → waiting for user input\n this.unsubscribers.push(\n this.events.onPattern('brain.ask_human', () => {\n this.leaderStatus = 'waiting_user';\n this.flush();\n }),\n );\n\n // Streaming events\n this.unsubscribers.push(\n this.events.onPattern('llm.stream_started', () => {\n this.leaderStatus = 'streaming';\n this.flush();\n }),\n );\n\n // Fleet events — subagent tracking\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.spawned', (_event, payload) => {\n const p = payload as { subagentId?: string; name?: string } | undefined;\n if (p?.subagentId) {\n this.agents.set(p.subagentId, {\n id: p.subagentId,\n name: p.name ?? p.subagentId,\n status: 'idle',\n iterations: 0,\n toolCalls: 0,\n lastActivityAt: new Date().toISOString(),\n });\n this.flush();\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.task_started', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'running';\n entry.iterations++;\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.task_completed', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'idle';\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.error', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n const entry = this.agents.get(p.subagentId);\n if (entry) {\n entry.status = 'error';\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }\n }\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('fleet.subagent.stopped', (_event, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (p?.subagentId) {\n this.agents.delete(p.subagentId);\n this.flush();\n }\n }),\n );\n }\n\n stop(): void {\n for (const unsub of this.unsubscribers) {\n try { unsub(); } catch { /* ignore */ }\n }\n this.unsubscribers = [];\n }\n\n private flush(): void {\n const leaderEntry: AgentEntry = {\n id: 'leader',\n name: this.leaderName,\n status: this.leaderStatus,\n currentTool: this.leaderCurrentTool,\n iterations: this.leaderIterations,\n toolCalls: this.leaderToolCalls,\n lastActivityAt: new Date().toISOString(),\n };\n\n const allAgents = [leaderEntry, ...this.agents.values()];\n this.registry.updateAgents(allAgents).catch(() => undefined);\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { CheckpointInfo, RewindResult, RewindResultExtended, SessionRewinder } from '../types/session-rewinder.js';\r\nimport type { SessionEvent, FileSnapshot } from '../types/session.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\nimport { SessionError, ERROR_CODES } from '../types/errors.js';\r\n\r\nexport interface SessionRewinderOptions {\r\n sessionsDir: string;\r\n /** The project root directory; used to validate rewind targets stay inside it. */\r\n projectRoot: string;\r\n}\r\n\r\n/**\r\n * Rewind engine that reads session JSONL files and reverts file system\r\n * changes to any previous checkpoint.\r\n */\r\nexport class DefaultSessionRewinder implements SessionRewinder {\r\n constructor(private readonly sessionsDir: string, private readonly projectRoot: string) {}\r\n\r\n async listCheckpoints(sessionId: string): Promise<CheckpointInfo[]> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n // Build a map of promptIndex -> file snapshot count\r\n const fileCountMap = new Map<number, number>();\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n const e = event as { promptIndex: number; files: FileSnapshot[] };\r\n fileCountMap.set(e.promptIndex, (fileCountMap.get(e.promptIndex) ?? 0) + e.files.length);\r\n }\r\n }\r\n\r\n const checkpoints: CheckpointInfo[] = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n const e = event as { promptIndex: number; promptPreview: string; ts: string };\r\n checkpoints.push({\r\n promptIndex: e.promptIndex,\r\n promptPreview: e.promptPreview,\r\n ts: e.ts,\r\n fileCount: fileCountMap.get(e.promptIndex) ?? 0,\r\n });\r\n }\r\n }\r\n\r\n return checkpoints;\r\n }\r\n\r\n async rewindToCheckpoint(\r\n sessionId: string,\r\n checkpointIndex: number,\r\n ): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n let targetIdx = -1;\r\n for (let i = 0; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n const checkpointEvent = event as { promptIndex: number };\r\n if (checkpointEvent.promptIndex === checkpointIndex) {\r\n targetIdx = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (targetIdx === -1) {\r\n throw new SessionError({\r\n message: `Checkpoint ${checkpointIndex} not found`,\r\n code: ERROR_CODES.SESSION_NOT_FOUND,\r\n context: { checkpointIndex },\r\n });\r\n }\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (let i = targetIdx + 1; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n break;\r\n }\r\n if (event.type === 'file_snapshot') {\r\n const snapshotEvent = event as { promptIndex: number; files: FileSnapshot[] };\r\n if (snapshotEvent.promptIndex >= checkpointIndex) {\r\n snapshotsToRevert.push({ promptIndex: snapshotEvent.promptIndex, files: snapshotEvent.files });\r\n }\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert, this.projectRoot);\r\n const removedEvents = events.length - targetIdx - 1;\r\n return { ...result, toPromptIndex: checkpointIndex, removedEvents };\r\n }\r\n\r\n async rewindLastN(sessionId: string, n: number): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const checkpoints: Array<{ promptIndex: number; ts: string }> = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n checkpoints.push({ promptIndex: event.promptIndex, ts: event.ts });\r\n }\r\n }\r\n\r\n if (checkpoints.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n checkpoints.sort((a, b) => b.promptIndex - a.promptIndex);\r\n const targetIndex = checkpoints[n]?.promptIndex ?? 0;\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n let shouldRevert = false;\r\n\r\n for (const event of events) {\r\n if (event.type === 'checkpoint' && event.promptIndex === targetIndex) {\r\n shouldRevert = true;\r\n continue;\r\n }\r\n if (shouldRevert && event.type === 'file_snapshot') {\r\n snapshotsToRevert.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: targetIndex, removedEvents: snapshotsToRevert.length };\r\n }\r\n\r\n async rewindToStart(sessionId: string): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const allSnapshots: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n allSnapshots.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n if (allSnapshots.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n const result = await revertSnapshots(allSnapshots.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: 0, removedEvents: allSnapshots.length };\r\n }\r\n}\r\n\r\nfunction parseEvents(raw: string): SessionEvent[] {\r\n const lines = raw.split('\\n').filter((l) => l.trim());\r\n const events: SessionEvent[] = [];\r\n\r\n for (const line of lines) {\r\n try {\r\n const parsed = JSON.parse(line);\r\n if (\r\n parsed !== null &&\r\n typeof parsed === 'object' &&\r\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\r\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\r\n ) {\r\n events.push(parsed as SessionEvent);\r\n }\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n\r\n return events;\r\n}\r\n\r\nasync function revertSnapshots(\r\n snapshots: Array<{ promptIndex: number; files: FileSnapshot[] }>,\r\n projectRoot: string,\r\n): Promise<RewindResult> {\r\n const revertedFiles: string[] = [];\r\n const errors: string[] = [];\r\n\r\n for (const snapshot of snapshots) {\r\n for (const file of snapshot.files) {\r\n try {\r\n // Guard: ensure the target path resolves inside the project root.\r\n // Without this, a maliciously recorded path (e.g., via path traversal\r\n // in a tool call that wasn't caught) could cause rewind to write\r\n // to arbitrary locations.\r\n const absPath = path.resolve(file.path);\r\n const root = path.resolve(projectRoot);\r\n const rel = path.relative(root, absPath);\r\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\r\n errors.push(`${file.path}: path resolves outside project root — skipping`);\r\n continue;\r\n }\r\n\r\n if (file.action === 'deleted') {\r\n // File was deleted — restore it from before\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n } else if (file.action === 'created') {\r\n // File was created — delete it\r\n await fsp.unlink(file.path);\r\n revertedFiles.push(file.path);\r\n } else if (file.action === 'modified') {\r\n // File was modified — restore before content\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n }\r\n } catch (err) {\r\n errors.push(`${file.path}: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n }\r\n }\r\n\r\n return { revertedFiles, errors };\r\n}","import * as fsp from 'node:fs/promises';\nimport type { TodoItem } from '../core/context.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * On-disk checkpoint for `ctx.todos`. Written atomically every time the\n * todo list changes, read once on session resume. This is the missing\n * piece that lets `wstack resume <id>` rehydrate where the previous run\n * stopped instead of starting with an empty board.\n *\n * Schema is intentionally small — a single JSON object so a future\n * format bump is easy. The `version` field is the only contract; the\n * shape under `todos` mirrors `TodoItem` so reading is a straight assign.\n */\nexport interface TodosCheckpointFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n todos: TodoItem[];\n}\n\nexport type TodosCheckpointDetach = () => Promise<void>;\n\n/** Read a checkpoint from disk. Returns null when the file doesn't\n * exist or is corrupt — callers treat both cases as \"no prior state\".\n */\nexport async function loadTodosCheckpoint(filePath: string): Promise<TodoItem[] | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TodosCheckpointFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.todos)) return null;\n return parsed.todos.filter(\n (t): t is TodoItem =>\n !!t &&\n typeof t.id === 'string' &&\n typeof t.content === 'string' &&\n typeof t.status === 'string' &&\n (t.activeForm === undefined || typeof t.activeForm === 'string'),\n );\n } catch {\n return null;\n }\n}\n\n/** Write the checkpoint atomically. Best-effort: a write failure is\n * logged but does not throw — losing one checkpoint shouldn't bring\n * down the agent run.\n */\nexport async function saveTodosCheckpoint(\n filePath: string,\n sessionId: string,\n todos: readonly TodoItem[],\n): Promise<void> {\n const payload: TodosCheckpointFile = {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n todos: [...todos],\n };\n try {\n await atomicWrite(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'todos_checkpoint.save_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n }\n}\n\n/**\n * Subscribe a `ConversationState` so every `todos_replaced` mutation\n * triggers an atomic write to disk. Returns the unsubscribe function.\n *\n * Writes are debounced by 150ms so a flurry of edits (e.g. the LLM\n * marking three items done in the same tool call) coalesces into one\n * disk hit.\n */\nexport function attachTodosCheckpoint(\n state: ConversationState,\n filePath: string,\n sessionId: string,\n): TodosCheckpointDetach {\n let timer: NodeJS.Timeout | null = null;\n let pending: readonly TodoItem[] | null = null;\n let writeChain: Promise<void> = Promise.resolve();\n\n const enqueueWrite = (todos: readonly TodoItem[]) => {\n writeChain = writeChain\n .then(() => saveTodosCheckpoint(filePath, sessionId, todos))\n .catch((err) => {\n // Log and keep the chain alive — a failed write must not\n // poison the chain and silently stop all subsequent writes.\n const msg = err instanceof Error ? err.message : String(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'todos_checkpoint.write_chain_failed',\n sessionId,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n return writeChain;\n };\n\n const flush = () => {\n timer = null;\n if (pending) {\n const todos = pending;\n pending = null;\n return enqueueWrite(todos);\n }\n return writeChain;\n };\n\n const unsubscribe = state.onChange((change) => {\n if (change.kind !== 'todos_replaced') return;\n pending = change.todos;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n void flush();\n }, 150);\n });\n return async () => {\n unsubscribe();\n if (timer) {\n clearTimeout(timer);\n // Flush any pending write before detach so callers can safely\n // unsubscribe at shutdown without losing the last update.\n await flush();\n } else {\n await writeChain;\n }\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\n\n/**\n * Plan items are the strategic counterpart to todos. Where `ctx.todos`\n * is the moment-to-moment task board the LLM mutates per-turn, a plan\n * captures the higher-level approach — the steps the user (or LLM)\n * laid out before any work began.\n *\n * Plans persist by default (per session) so a resumed session can show\n * \"you were on step 3 of 5\". Todos are derived/transient. Both can\n * coexist: think roadmap (plan) vs. sprint board (todos).\n */\nexport interface PlanItem {\n id: string;\n title: string;\n /** Optional longer-form context or rationale. */\n details?: string | undefined;\n status: 'open' | 'in_progress' | 'done';\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PlanFile {\n version: 1;\n sessionId: string;\n title?: string | undefined;\n updatedAt: string;\n items: PlanItem[];\n}\n\nexport async function loadPlan(filePath: string): Promise<PlanFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as PlanFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.items)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function savePlan(filePath: string, plan: PlanFile): Promise<void> {\n try {\n await atomicWrite(filePath, JSON.stringify(plan, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(\n '[plan-store] save failed:',\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n\n/** Create a new PlanFile when none exists on disk. */\nexport function emptyPlan(sessionId: string, title?: string): PlanFile {\n return {\n version: 1,\n sessionId,\n title,\n updatedAt: new Date().toISOString(),\n items: [],\n };\n}\n\nexport function addPlanItem(\n plan: PlanFile,\n title: string,\n details?: string | undefined,\n): { plan: PlanFile; item: PlanItem } {\n const now = new Date().toISOString();\n const item: PlanItem = {\n id: `plan_${Date.now()}_${randomUUID().slice(0, 6)}`,\n title,\n details,\n status: 'open',\n createdAt: now,\n updatedAt: now,\n };\n return {\n plan: { ...plan, items: [...plan.items, item], updatedAt: now },\n item,\n };\n}\n\nexport function removePlanItem(plan: PlanFile, idOrIndex: string): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n return {\n ...plan,\n items: plan.items.filter((_, i) => i !== idx),\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function setPlanItemStatus(\n plan: PlanFile,\n idOrIndex: string,\n status: PlanItem['status'],\n): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n const now = new Date().toISOString();\n const items = plan.items.map((it, i) =>\n i === idx ? { ...it, status, updatedAt: now } : it,\n );\n return { ...plan, items, updatedAt: now };\n}\n\nexport function clearPlan(plan: PlanFile): PlanFile {\n return { ...plan, items: [], updatedAt: new Date().toISOString() };\n}\n\n/** Render the plan as a short markdown-ish string suitable for slash output. */\nexport function formatPlan(plan: PlanFile): string {\n if (plan.items.length === 0) return 'Plan is empty.';\n const lines: string[] = [];\n if (plan.title) lines.push(`# ${plan.title}`);\n plan.items.forEach((it, i) => {\n const mark = it.status === 'done' ? '[x]' : it.status === 'in_progress' ? '[~]' : '[ ]';\n lines.push(`${i + 1}. ${mark} ${it.title}`);\n if (it.details) {\n for (const line of it.details.split('\\n')) lines.push(` ${line}`);\n }\n });\n return lines.join('\\n');\n}\n\nfunction matchIndex(plan: PlanFile, idOrIndex: string): number {\n const asNum = Number.parseInt(idOrIndex, 10);\n if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= plan.items.length) return asNum - 1;\n const byId = plan.items.findIndex((it) => it.id === idOrIndex);\n if (byId !== -1) return byId;\n const lower = idOrIndex.toLowerCase();\n return plan.items.findIndex((it) => it.title.toLowerCase().includes(lower));\n}\n\n/**\n * Promote a plan item to a set of todo items.\n * The plan item is marked 'in_progress' (if not already done) and its\n * title + details become the first todo; additional subtasks are appended.\n * Returns the derived todo list so the caller can pass it to `todoTool`\n * or `ctx.state.replaceTodos()`.\n */\nexport function deriveTodosFromPlanItem(\n plan: PlanFile,\n idOrIndex: string,\n subtasks?: string[] | undefined,\n): { plan: PlanFile; todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> } | null {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return null;\n\n const item = plan.items[idx];\n if (!item) return null;\n\n // Mark the plan item in_progress if it wasn't already done\n let updatedPlan = plan;\n if (item.status !== 'done') {\n updatedPlan = setPlanItemStatus(plan, idOrIndex, 'in_progress');\n }\n\n const todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> = [];\n\n // First todo from the plan item itself\n todos.push({\n id: `todo_${Date.now()}_plan`,\n content: item.title,\n status: 'in_progress',\n activeForm: item.title,\n promotedFromPlan: item.id,\n });\n\n // Optional subtasks\n if (subtasks && subtasks.length > 0) {\n for (const st of subtasks) {\n todos.push({\n id: `todo_${Date.now()}_${randomUUID().slice(0, 6)}`,\n content: st,\n status: 'pending',\n promotedFromPlan: item.id,\n });\n }\n }\n\n return { plan: updatedPlan, todos };\n}\n\n/**\n * Load, modify, and save the plan file under a file-level lock.\n * Prevents races from parallel tool invocations (e.g. batch_tool_use).\n */\nexport async function mutatePlan(\n filePath: string,\n sessionId: string,\n fn: (plan: PlanFile) => PlanFile | Promise<PlanFile>,\n): Promise<PlanFile> {\n return withFileLock(filePath, async () => {\n const plan = (await loadPlan(filePath)) ?? emptyPlan(sessionId);\n const updated = await fn(plan);\n await savePlan(filePath, updated);\n return updated;\n });\n}\n\n/**\n * Optional: attach a state-listener so meta operations (storing a plan\n * id on ctx.meta) trigger a save. Currently a stub — plans don't live\n * on Context, but this keeps the API surface symmetric with the todos\n * checkpoint so future refactors can flip plans into Context if needed.\n */\nexport function attachPlanCheckpoint(\n _state: ConversationState,\n _filePath: string,\n _sessionId: string,\n): () => void {\n return () => undefined;\n}\n","/**\n * Plan templates — pre-defined plan skeletons for common workflows.\n *\n * Templates are stored in-memory (no disk I/O). Users instantiate them\n * via `/plan template use <name>` or `planTool(action: 'template_use')`.\n * Each template is a function that returns an array of item titles, so\n * dynamic content (dates, project names) can be injected later.\n */\n\nexport interface PlanTemplate {\n name: string;\n description: string;\n category: 'development' | 'release' | 'maintenance' | 'infrastructure';\n items: Array<{\n title: string;\n details?: string | undefined;\n }>;\n}\n\nconst templates: Record<string, PlanTemplate> = {\n 'new-feature': {\n name: 'new-feature',\n description: 'Standard workflow for adding a new feature',\n category: 'development',\n items: [\n { title: 'Write specification / design doc', details: 'Define scope, acceptance criteria, edge cases' },\n { title: 'Set up feature branch', details: 'git checkout -b feature/...' },\n { title: 'Implement core logic', details: 'TDD preferred — write tests first' },\n { title: 'Add unit tests', details: '>= 80% coverage for new code' },\n { title: 'Add integration tests', details: 'End-to-end happy path + error paths' },\n { title: 'Update documentation', details: 'README, API docs, changelog' },\n { title: 'Code review', details: 'Self-review before requesting review' },\n { title: 'Merge and deploy', details: 'CI green, tag release' },\n ],\n },\n 'bug-fix': {\n name: 'bug-fix',\n description: 'Systematic approach to fixing bugs',\n category: 'maintenance',\n items: [\n { title: 'Reproduce the bug', details: 'Minimal reproduction case' },\n { title: 'Root cause analysis', details: 'Trace through logs, debugger' },\n { title: 'Write failing test', details: 'Test must fail before fix' },\n { title: 'Implement fix', details: 'Smallest possible change' },\n { title: 'Verify fix', details: 'Test passes, reproduction no longer fails' },\n { title: 'Regression test', details: 'Ensure no related tests broken' },\n { title: 'Document in changelog', details: 'Brief description + issue link' },\n ],\n },\n 'refactor': {\n name: 'refactor',\n description: 'Safe refactoring workflow',\n category: 'maintenance',\n items: [\n { title: 'Identify refactoring target', details: 'Code smell, performance bottleneck, or tech debt' },\n { title: 'Ensure test coverage', details: 'Existing tests must pass before and after' },\n { title: 'Write characterization tests', details: 'Capture current behavior if tests weak' },\n { title: 'Apply refactoring', details: 'Small steps, frequent commits' },\n { title: 'Run full test suite', details: 'All tests must pass' },\n { title: 'Performance check', details: 'Ensure no regression' },\n { title: 'Code review', details: 'Explain the why, not just the what' },\n ],\n },\n 'release': {\n name: 'release',\n description: 'Preparing a new release',\n category: 'release',\n items: [\n { title: 'Version bump', details: 'package.json, lockfiles, tags' },\n { title: 'Update changelog', details: 'All changes since last release' },\n { title: 'Run full test suite', details: 'Unit + integration + e2e' },\n { title: 'Build artifacts', details: 'Docker images, bundles, binaries' },\n { title: 'Staging smoke tests', details: 'Deploy to staging, verify' },\n { title: 'Production deploy', details: 'Blue-green or canary' },\n { title: 'Post-deploy verification', details: 'Health checks, error rates' },\n { title: 'Announce release', details: 'Slack, email, GitHub release notes' },\n ],\n },\n 'security-audit': {\n name: 'security-audit',\n description: 'Security review and hardening',\n category: 'infrastructure',\n items: [\n { title: 'Dependency audit', details: 'npm audit, Snyk, Dependabot alerts' },\n { title: 'Secret scan', details: 'git-secrets, truffleHog, manual review' },\n { title: 'Access control review', details: 'IAM, roles, least privilege' },\n { title: 'Input validation audit', details: 'SQL injection, XSS, path traversal' },\n { title: 'Authentication review', details: 'Session management, MFA, password policy' },\n { title: 'Logging and monitoring', details: 'PII in logs, audit trails' },\n { title: 'Incident response plan', details: 'Runbooks, contacts, escalation' },\n ],\n },\n 'onboarding': {\n name: 'onboarding',\n description: 'New developer onboarding checklist',\n category: 'infrastructure',\n items: [\n { title: 'Repository access', details: 'GitHub/GitLab permissions' },\n { title: 'Local environment setup', details: 'Docker, dependencies, env files' },\n { title: 'Run tests locally', details: 'Verify green suite' },\n { title: 'Read architecture docs', details: 'ADR, README, onboarding guide' },\n { title: 'First commit', details: 'Docs fix or small improvement' },\n { title: 'Pair programming session', details: 'Walk through codebase with buddy' },\n { title: 'Deploy to staging', details: 'Verify CI/CD access' },\n ],\n },\n};\n\nexport function listPlanTemplates(): PlanTemplate[] {\n return Object.values(templates);\n}\n\nexport function getPlanTemplate(name: string): PlanTemplate | undefined {\n return templates[name];\n}\n\nexport function formatPlanTemplates(): string {\n const cats = new Map<PlanTemplate['category'], PlanTemplate[]>();\n for (const t of Object.values(templates)) {\n const arr = cats.get(t.category) ?? [];\n arr.push(t);\n cats.set(t.category, arr);\n }\n\n const lines: string[] = ['Available plan templates:'];\n for (const [cat, items] of cats) {\n lines.push(`\\n${cat}:`);\n for (const t of items) {\n lines.push(` ${t.name.padEnd(18)} — ${t.description}`);\n }\n }\n return lines.join('\\n');\n}\n","import * as fsp from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport type { TaskItem } from '../utils/task-format.js';\n\n// ---------------------------------------------------------------------------\n// Task file persistence — one JSON file per session in\n// `<projectSessions>/<sessionId>.tasks.json`.\n//\n// Low-level load/save are exported for read-only consumers. Mutating callers\n// should use `mutateTasks` which wraps the entire read-modify-write cycle\n// under a file-level lock, preventing races from parallel tool invocations.\n// ---------------------------------------------------------------------------\n\nexport interface TaskFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n tasks: TaskItem[];\n}\n\nexport function emptyTaskFile(sessionId: string): TaskFile {\n return {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n tasks: [],\n };\n}\n\n/** Read the task file. Returns null when the file doesn't exist. */\nexport async function loadTasks(filePath: string): Promise<TaskFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TaskFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.tasks)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Write the task file atomically. Prefer `mutateTasks` for read-modify-write\n * cycles — this low-level function does NOT acquire a lock.\n */\nexport async function saveTasks(filePath: string, tasks: TaskFile): Promise<void> {\n try {\n tasks.updatedAt = new Date().toISOString();\n await atomicWrite(filePath, JSON.stringify(tasks, null, 2), { mode: 0o600 });\n } catch (err) {\n console.warn(\n '[task-store] save failed:',\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n\n/**\n * Load, modify, and save the task file under a file-level lock.\n * `fn` receives the current TaskFile (or a fresh empty one) and must\n * return the mutated TaskFile (mutating in-place is fine — the returned\n * reference is what gets saved).\n *\n * This is the primary API for any code path that reads *and then writes*\n * the task file — it prevents races from parallel `batch_tool_use` calls.\n */\nexport async function mutateTasks(\n filePath: string,\n sessionId: string,\n fn: (file: TaskFile) => TaskFile | Promise<TaskFile>,\n): Promise<TaskFile> {\n return withFileLock(filePath, async () => {\n const file = (await loadTasks(filePath)) ?? emptyTaskFile(sessionId);\n const updated = await fn(file);\n await saveTasks(filePath, updated);\n return updated;\n });\n}\n","import * as fsp from 'node:fs/promises';\nimport { hostname } from 'node:os';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\n/**\n * Director state checkpoint — written incrementally throughout a fleet\n * run so a crashed director can be inspected (and eventually resumed)\n * instead of leaving only a final `fleet.json` manifest after `shutdown()`.\n *\n * Schema is JSON-friendly and deliberately denormalized. Each mutation\n * triggers an atomic-write of the whole file — small payloads (typically\n * < 10 KB even with dozens of subagents) make this cheap.\n */\nexport interface DirectorSubagentState {\n id: string;\n name?: string | undefined;\n role?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n spawnedAt: string;\n}\n\nexport interface DirectorTaskState {\n taskId: string;\n subagentId?: string | undefined;\n description?: string | undefined;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout';\n assignedAt?: string | undefined;\n completedAt?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n durationMs?: number | undefined;\n error?: string | undefined;\n}\n\nexport interface DirectorStateSnapshot {\n version: 1;\n directorRunId: string;\n updatedAt: string;\n spawnCount: number;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n subagents: DirectorSubagentState[];\n tasks: DirectorTaskState[];\n /** Aggregated usage snapshot. Optional — populated by the Director on save when available. */\n usage?: unknown | undefined;\n}\n\nexport async function loadDirectorState(filePath: string): Promise<DirectorStateSnapshot | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as DirectorStateSnapshot;\n if (parsed?.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Lock file entry written when a director starts. Prevents two directors\n * from resuming the same run — the second one sees the lock and refuses\n * rather than corrupting the checkpoint by writing concurrently.\n */\nexport interface DirectorStateLock {\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\n/**\n * Write a lock file to claim this checkpoint. Returns false if the lock\n * is already held by a live process; returns true if the lock was acquired\n * (either the file didn't exist, or the previous holder is dead).\n */\nexport async function acquireDirectorStateLock(\n lockPath: string,\n processId = process.pid,\n): Promise<boolean> {\n let existing: string | undefined;\n try {\n existing = await fsp.readFile(lockPath, 'utf8');\n } catch {\n // No lock file — we're safe to claim\n }\n\n if (existing) {\n try {\n const lock = JSON.parse(existing) as DirectorStateLock;\n // Check if the process is still alive\n try {\n process.kill(lock.pid, 0);\n // Signal success means the process is alive — another director\n // owns this checkpoint. Refuse.\n return false;\n } catch {\n // ESRCH means the process is dead — stale lock. We'll overwrite.\n }\n } catch {\n // Malformed lock — treat as stale.\n }\n }\n\n const lock: DirectorStateLock = {\n pid: processId,\n hostname: hostname(),\n startedAt: new Date().toISOString(),\n };\n await atomicWrite(lockPath, JSON.stringify(lock), { mode: 0o600 });\n return true;\n}\n\n/**\n * Remove the lock file. Call this on graceful Director.shutdown() so the\n * next director run can claim the checkpoint without stale-lock checks.\n */\nexport async function releaseDirectorStateLock(lockPath: string): Promise<void> {\n try {\n await fsp.unlink(lockPath);\n } catch {\n // ignore\n }\n}\n\n/**\n * In-memory accumulator with atomic-write checkpoint. The Director keeps\n * an instance, mutates it on every spawn/assign/complete/fail event, and\n * the instance debounces writes so a burst of activity collapses into a\n * single disk hit.\n *\n * Supports crash recovery: use `loadDirectorState()` to read an existing\n * checkpoint, then call `DirectorStateCheckpoint.resume(snapshot)` to\n * re-attach to a fleet mid-flight. The lock mechanism ensures no two\n * directors can claim the same checkpoint.\n */\nexport class DirectorStateCheckpoint {\n private snapshot: DirectorStateSnapshot;\n private readonly filePath: string;\n private readonly lockPath: string;\n private timer: NodeJS.Timeout | null = null;\n private readonly debounceMs: number;\n private writing = false;\n private rewriteRequested = false;\n\n constructor(\n filePath: string,\n init: {\n directorRunId: string;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n },\n debounceMs = 250,\n ) {\n this.filePath = filePath;\n // Lock file lives alongside the checkpoint — `<path>.lock`\n this.lockPath = `${filePath}.lock`;\n this.debounceMs = debounceMs;\n this.snapshot = {\n version: 1,\n directorRunId: init.directorRunId,\n updatedAt: new Date().toISOString(),\n spawnCount: 0,\n maxSpawns: init.maxSpawns,\n spawnDepth: init.spawnDepth,\n maxSpawnDepth: init.maxSpawnDepth,\n directorBudget: init.directorBudget,\n subagents: [],\n tasks: [],\n };\n }\n\n /**\n * Attempt to acquire the lock for this checkpoint. Call this before\n * resuming a crashed director run. If it returns false, another\n * director process is still running this fleet — do not resume.\n */\n async acquireLock(): Promise<boolean> {\n return acquireDirectorStateLock(this.lockPath);\n }\n\n /**\n * Release the lock on graceful shutdown. Call `flush()` first to ensure\n * the final checkpoint state is on disk before removing the lock.\n * Without this, the next resume will see a stale-lock and refuse.\n */\n async releaseLock(): Promise<void> {\n return releaseDirectorStateLock(this.lockPath);\n }\n\n /**\n * Resume from a snapshot previously loaded via `loadDirectorState()`.\n * Use this when `--resume <runId>` is triggered — the snapshot has\n * the full fleet state (subagents, tasks) from before the crash; the\n * checkpoint continues from there.\n */\n resume(snapshot: DirectorStateSnapshot): void {\n this.snapshot = snapshot;\n }\n\n current(): DirectorStateSnapshot {\n return this.snapshot;\n }\n\n recordSpawn(sub: DirectorSubagentState, spawnCount: number): void {\n this.snapshot = {\n ...this.snapshot,\n spawnCount,\n subagents: [...this.snapshot.subagents.filter((s) => s.id !== sub.id), sub],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskAssigned(task: DirectorTaskState): void {\n const exists = this.snapshot.tasks.some((t) => t.taskId === task.taskId);\n this.snapshot = {\n ...this.snapshot,\n tasks: exists\n ? this.snapshot.tasks.map((t) => (t.taskId === task.taskId ? { ...t, ...task } : t))\n : [...this.snapshot.tasks, task],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskStatus(\n taskId: string,\n patch: Partial<DirectorTaskState> & { status: DirectorTaskState['status'] },\n ): void {\n this.snapshot = {\n ...this.snapshot,\n tasks: this.snapshot.tasks.map((t) =>\n t.taskId === taskId ? { ...t, ...patch } : t,\n ),\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n setUsage(usage: unknown): void {\n this.snapshot = { ...this.snapshot, usage };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n /** Force a synchronous flush — used by Director.shutdown(). */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n await this.persist();\n // If a rewrite was requested while we waited, persist() scheduled\n // a follow-up write. Loop until no more rewrites are requested so\n // shutdown doesn't return before the most recent state lands on disk.\n while (this.rewriteRequested) {\n this.rewriteRequested = false;\n await this.persist();\n }\n }\n\n private bumpUpdatedAt(): void {\n this.snapshot = { ...this.snapshot, updatedAt: new Date().toISOString() };\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.persist();\n }, this.debounceMs);\n }\n\n private async persist(): Promise<void> {\n if (this.writing) {\n // A write is already in flight — defer to a follow-up flush so the\n // most recent state still lands. Without this guard, simultaneous\n // burst mutations can drop the latest snapshot if rename races.\n this.rewriteRequested = true;\n return;\n }\n this.writing = true;\n try {\n await atomicWrite(this.filePath, JSON.stringify(this.snapshot, null, 2), {\n mode: 0o600,\n });\n } catch (err) {\n console.warn(\n '[director-state] checkpoint write failed:',\n err instanceof Error ? err.message : String(err),\n );\n } finally {\n this.writing = false;\n if (this.rewriteRequested) {\n this.rewriteRequested = false;\n this.schedule();\n }\n }\n }\n}\n","/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack — global root. */\n globalRoot: string;\n /**\n * ~/.wrongstack — directory for user-global stateful config files\n * (mode.json, theme.json, …). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key — 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md — user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills — user-global skills. */\n globalSkills: string;\n /** ~/.wrongstack/prompts — user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/cache — fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json — cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir — NOT inside the repo — so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history — REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json — optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json — per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md — committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills — committed project skills. */\n inProjectSkills: string;\n /** <project>/.wrongstack/worktrees — git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json — goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/specs — SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs — SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json — SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json — plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase — AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/sync.json — CloudSync configuration */\n syncConfig: string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state — config, secrets, logs, projects/, mailboxes — away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { color } from '../utils/color.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport { FsError, ERROR_CODES } from '../types/errors.js';\n\n/**\n * Long-running autonomous mission. A goal survives across sessions and\n * drives the EternalAutonomyEngine — every iteration of the engine\n * consults the goal to choose what to do next.\n *\n * Storage: `~/.wrongstack/projects/<hash>/goal.json`. Persistent and\n * project-scoped on purpose: the goal belongs to the codebase, not the\n * REPL session.\n */\n\nexport interface JournalEntry {\n /** ISO timestamp of the iteration. */\n at: string;\n /** Sequential iteration counter (1-based, monotonically increasing). */\n iteration: number;\n /** Source that produced the action ('todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel'). */\n source: 'todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel';\n /** Short one-line description of what the iteration set out to do. */\n task: string;\n /** Outcome status. */\n status: 'success' | 'failure' | 'aborted' | 'skipped';\n /** Optional free-form note (error message, summary, etc.). */\n note?: string | undefined;\n /** Optional token usage delta for this iteration. */\n tokens?: { input: number; output: number } | undefined;\n /** Optional USD cost delta for this iteration (provider-estimated). */\n costUsd?: number | undefined;\n}\n\nexport interface GoalFile {\n version: 1;\n /** The raw mission statement as entered by the user. */\n goal: string;\n /**\n * LLM-refined version of the goal — unambiguous, with concrete\n * deliverables and acceptance criteria.\n */\n refinedGoal?: string | undefined;\n /**\n * Concrete, verifiable deliverables extracted from the refined goal.\n */\n deliverables?: string[] | undefined;\n /**\n * Estimated completion 0-100. Updated by the engine after each\n * iteration. Null means \"not yet assessed\".\n */\n progress?: number | undefined;\n /** Human-readable note explaining the current progress estimate. */\n progressNote?: string | undefined;\n /**\n * Time-series of progress measurements for trend analysis.\n * Last 200 entries retained. Use `recordProgress()` to append.\n */\n progressHistory?: ProgressSnapshot[] | undefined;\n /**\n * Computed trend from recent progress measurements.\n * 'accelerating' | 'steady' | 'stalling' | undefined.\n */\n progressTrend?: 'accelerating' | 'steady' | 'stalling' | undefined;\n /** When the goal was first set or last replaced. */\n setAt: string;\n /** Updated on every iteration completion. */\n lastActivityAt: string;\n /** Total iterations the engine has run against this goal (cumulative). */\n iterations: number;\n /** Engine lifecycle state — 'running' means another process owns this goal. */\n engineState: 'idle' | 'running' | 'stopped';\n /**\n * Mission-level lifecycle.\n */\n goalState?: 'active' | 'paused' | 'completed' | 'abandoned' | undefined;\n /**\n * Per-todo attempt counter.\n */\n todoAttempts?: Record<string, number>;\n /** Bounded ring buffer of recent iterations (newest last). */\n journal: JournalEntry[];\n}\n\n/** Cap on persisted journal entries — older entries are evicted FIFO. */\nexport const MAX_JOURNAL_ENTRIES = 500;\n\n/**\n * Resolve the goal file path for a given project root.\n *\n * SINGLE canonical location: the per-project directory that\n * `resolveWstackPaths()` uses for everything else (sessions, memory, specs) —\n * `~/.wrongstack/projects/<slug>/goal.json`. This is the same path the `/goal`\n * slash command writes via `opts.paths.projectGoal`, so every reader/writer\n * (the eternal/parallel autonomy engines, the CLI autonomy commands, the TUI\n * F9 panel, and `/goal` itself) now agree on one file.\n *\n * Previously this returned a SEPARATE hash-based dir (`projects/<hash>/`), which\n * disagreed with `/goal` and littered the home dir with thousands of stray\n * `<hash>/goal.json` directories that held nothing else.\n */\nexport function goalFilePath(projectRoot: string): string {\n return resolveWstackPaths({ projectRoot }).projectGoal;\n}\n\nexport async function loadGoal(filePath: string): Promise<GoalFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null; // file doesn't exist — not an error\n throw err; // permission errors etc. should surface\n }\n try {\n const parsed = JSON.parse(raw) as GoalFile;\n if (parsed?.version !== 1 || typeof parsed.goal !== 'string' || !Array.isArray(parsed.journal)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.invalid_schema',\n path: filePath,\n message: 'invalid schema — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n return parsed;\n } catch {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.parse_failed',\n path: filePath,\n message: 'JSON parse failed — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n}\n\nexport async function saveGoal(filePath: string, goal: GoalFile): Promise<void> {\n try {\n await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 0o600 });\n } catch (err) {\n throw new FsError({\n message: err instanceof Error ? err.message : String(err),\n code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,\n path: filePath,\n cause: err,\n });\n }\n}\n\n/**\n * Atomically load, modify, and save a goal file under a file lock.\n * Prevents lost-update races when the autonomy engine and CLI /goal commands\n * write concurrently (both eternal and parallel engines may run simultaneously).\n *\n * `fn` receives the current GoalFile (or `null` if no goal exists yet)\n * and must return the updated GoalFile (or `null` to delete).\n */\nexport async function updateGoal(\n filePath: string,\n fn: (current: GoalFile | null) => GoalFile | null,\n): Promise<void> {\n await withFileLock(filePath, async () => {\n const current = await loadGoal(filePath);\n const next = fn(current);\n if (next) {\n await saveGoal(filePath, next);\n } else {\n try {\n await fsp.unlink(filePath);\n } catch {\n // best-effort — file may not exist\n }\n }\n });\n}\n\nexport function emptyGoal(goal: string): GoalFile {\n const now = new Date().toISOString();\n return {\n version: 1,\n goal,\n setAt: now,\n lastActivityAt: now,\n iterations: 0,\n engineState: 'idle',\n goalState: 'active',\n todoAttempts: {},\n journal: [],\n };\n}\n\n/**\n * Set progress estimate on a goal. Returns a new GoalFile.\n * Clamps progress to 0-100.\n */\nexport function setProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? clamped + '% complete',\n };\n}\n\n/**\n * Append a journal entry, bumping iteration counters and trimming the\n * ring buffer. Returns a new GoalFile — does not mutate the argument.\n */\nexport function appendJournal(goal: GoalFile, entry: Omit<JournalEntry, 'iteration' | 'at'>): GoalFile {\n const iteration = goal.iterations + 1;\n const at = new Date().toISOString();\n const full: JournalEntry = { ...entry, iteration, at };\n const journal = [...goal.journal, full];\n const trimmed = journal.length > MAX_JOURNAL_ENTRIES\n ? journal.slice(journal.length - MAX_JOURNAL_ENTRIES)\n : journal;\n return {\n ...goal,\n iterations: iteration,\n lastActivityAt: at,\n journal: trimmed,\n };\n}\n\n/**\n * Aggregate cumulative cost + tokens across all journal entries.\n */\nexport function summarizeUsage(goal: GoalFile): {\n totalCostUsd: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n iterationsWithUsage: number;\n} {\n let totalCostUsd = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let iterationsWithUsage = 0;\n for (const e of goal.journal) {\n if (typeof e.costUsd === 'number') totalCostUsd += e.costUsd;\n if (e.tokens) {\n totalInputTokens += e.tokens.input;\n totalOutputTokens += e.tokens.output;\n }\n if (typeof e.costUsd === 'number' || e.tokens) iterationsWithUsage++;\n }\n return { totalCostUsd, totalInputTokens, totalOutputTokens, iterationsWithUsage };\n}\n\nconst DOLLAR = '\\u0024';\n\n/** Format the goal + recent journal as a human-readable status block. */\nexport function formatGoal(goal: GoalFile, journalLimit = 10): string {\n const lines: string[] = [];\n\n // Header — show refined goal, with original as annotation if different\n const displayGoal = goal.refinedGoal || goal.goal;\n lines.push(color.bold('Goal') + ': ' + displayGoal);\n if (goal.refinedGoal && goal.refinedGoal !== goal.goal) {\n const snippet = goal.goal.length > 60 ? goal.goal.slice(0, 60) + '…' : goal.goal;\n lines.push(color.dim(' (original: \"' + snippet + '\")'));\n }\n\n // Progress bar (20-segment)\n if (typeof goal.progress === 'number') {\n const pct = Math.min(100, Math.max(0, Math.round(goal.progress)));\n const filled = Math.round(pct / 5);\n const empty = 20 - filled;\n const bar = color.green('█'.repeat(filled)) + color.dim('░'.repeat(empty));\n lines.push('Progress: ' + bar + ' ' + color.bold(pct + '%'));\n if (goal.progressNote) {\n lines.push(' ' + color.dim(goal.progressNote));\n }\n // Trend indicator\n if (goal.progressTrend) {\n const trendIcon = goal.progressTrend === 'accelerating' ? '🚀'\n : goal.progressTrend === 'stalling' ? '⚠️'\n : '➡️';\n lines.push(' Trend: ' + trendIcon + ' ' + goal.progressTrend);\n }\n }\n\n // Deliverables checklist\n if (goal.deliverables && goal.deliverables.length > 0) {\n lines.push('');\n lines.push(color.bold('Deliverables:'));\n for (const d of goal.deliverables) {\n const done = /^\\[[x✓]\\]|✅|\\(done\\)/i.test(d);\n const marker = done ? color.green('✓') : color.dim('○');\n lines.push(' ' + marker + ' ' + d);\n }\n }\n\n lines.push('');\n lines.push('Set: ' + goal.setAt);\n lines.push('Last activity: ' + goal.lastActivityAt);\n lines.push('Iterations: ' + goal.iterations);\n const stateLabel = goal.goalState ?? 'active';\n lines.push('State: ' + stateLabel + (goal.iterations > 0 ? ' (iteration #' + goal.iterations + ')' : ''));\n lines.push('Engine: ' + goal.engineState);\n const usage = summarizeUsage(goal);\n if (usage.iterationsWithUsage > 0) {\n const spent = 'Spent: ' + DOLLAR + usage.totalCostUsd.toFixed(4)\n + ' (in ' + usage.totalInputTokens + ' / out ' + usage.totalOutputTokens\n + ' tokens across ' + usage.iterationsWithUsage + ' iterations)';\n lines.push(spent);\n }\n if (goal.journal.length > 0) {\n lines.push('');\n lines.push('Recent journal (last ' + Math.min(journalLimit, goal.journal.length) + '):');\n const tail = goal.journal.slice(-journalLimit);\n for (const e of tail) {\n const mark = e.status === 'success' ? '✓' : e.status === 'failure' ? '✗' : e.status === 'aborted' ? '⊘' : '·';\n const note = e.note ? ' — ' + e.note : '';\n const cost = typeof e.costUsd === 'number' ? ' (' + DOLLAR + e.costUsd.toFixed(4) + ')' : '';\n lines.push(' #' + e.iteration + ' ' + mark + ' [' + e.source + '] ' + e.task + cost + note);\n }\n }\n return lines.join('\\n');\n}\n\n/** A single progress measurement at a point in time. */\nexport interface ProgressSnapshot {\n at: string;\n progress: number;\n note?: string | undefined;\n}\n\n/**\n * Parse [PROGRESS: N%] from agent final text.\n * Supports formats:\n * [PROGRESS: 45%]\n * [PROGRESS: 45%] — 3/5 deliverables done\n * [progress: 100%]\n * Returns null if no match.\n */\nexport function parseProgressFromText(text: string): { progress: number; note?: string } | null {\n const re = /\\[progress:\\s*(\\d{1,3})%\\]\\s*(?:[—-]\\s*(.+))?/i;\n const m = text.match(re);\n if (!m) return null;\n // Regex match guarantees capture group 1 exists, but use ?? fallback to\n // satisfy noUncheckedIndexedAccess without a non-null assertion.\n const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? '0', 10)));\n const note = m[2]?.trim() || undefined;\n return note === undefined ? { progress } : { progress, note };\n}\n\n/**\n * Record a progress measurement. Returns a new GoalFile with:\n * - progress + progressNote updated\n * - progressHistory appended (last 200 entries kept)\n * - progress trend computed (accelerating/steady/stalling)\n */\nexport function recordProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n const history = [...(goal.progressHistory ?? []), { at: new Date().toISOString(), progress: clamped, note }];\n // Keep last 200 snapshots\n const trimmed = history.length > 200 ? history.slice(-200) : history;\n\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? `${clamped}% complete`,\n progressHistory: trimmed,\n progressTrend: computeTrend(trimmed),\n };\n}\n\n/** Max progress history entries to retain. */\nexport const MAX_PROGRESS_HISTORY = 200;\n\nfunction computeTrend(history: ProgressSnapshot[]): 'accelerating' | 'steady' | 'stalling' | undefined {\n if (history.length < 3) return undefined;\n const recent = history.slice(-5);\n const deltas: number[] = [];\n for (let i = 1; i < recent.length; i++) {\n deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));\n }\n if (deltas.length < 2) return undefined;\n const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n if (avgDelta > 2) return 'accelerating';\n if (avgDelta < -1) return 'stalling';\n return 'steady';\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\nexport interface PromptEntry {\n id: string;\n title: string;\n content: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PromptStore {\n list(): Promise<PromptEntry[]>;\n get(id: string): Promise<PromptEntry | null>;\n save(entry: PromptEntry): Promise<void>;\n delete(id: string): Promise<boolean>;\n find(query: string): Promise<PromptEntry[]>;\n}\n\ninterface RawPromptFile {\n version: 1;\n entry: PromptEntry;\n}\n\nexport class DefaultPromptStore implements PromptStore {\n private readonly dir: string;\n\n constructor(paths: WstackPaths) {\n this.dir = paths.globalPrompts;\n }\n\n async list(): Promise<PromptEntry[]> {\n await ensureDir(this.dir);\n const entries: PromptEntry[] = [];\n try {\n const files = await fs.readdir(this.dir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const raw: RawPromptFile = JSON.parse(\n await fs.readFile(path.join(this.dir, file), 'utf8'),\n );\n entries.push(raw.entry);\n } catch {\n // skip corrupt files\n }\n }\n } catch {\n // dir doesn't exist yet\n }\n return entries.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n async get(id: string): Promise<PromptEntry | null> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n const raw: RawPromptFile = JSON.parse(await fs.readFile(file, 'utf8'));\n return raw.entry;\n } catch {\n return null;\n }\n }\n\n async save(entry: PromptEntry): Promise<void> {\n await ensureDir(this.dir);\n const file = path.join(this.dir, `${entry.id}.json`);\n const raw: RawPromptFile = { version: 1, entry };\n await atomicWrite(file, JSON.stringify(raw, null, 2));\n }\n\n async delete(id: string): Promise<boolean> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n await fs.unlink(file);\n return true;\n } catch {\n return false;\n }\n }\n\n async find(query: string): Promise<PromptEntry[]> {\n const all = await this.list();\n const lower = query.toLowerCase();\n return all.filter(\n (e) =>\n e.title.toLowerCase().includes(lower) ||\n e.content.toLowerCase().includes(lower) ||\n e.tags.some((t) => t.toLowerCase().includes(lower)),\n );\n }\n\n /** Create a new entry and return it. Does NOT persist — call save() afterwards. */\n createNew(title: string, content: string, tags: string[] = []): PromptEntry {\n const now = new Date().toISOString();\n return {\n id: randomUUID().slice(0, 8),\n title,\n content,\n tags,\n createdAt: now,\n updatedAt: now,\n };\n }\n}","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport type { SyncCategory, SyncConfig } from '../types/config.js';\nimport { FsError, WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport const ALL_SYNC_CATEGORIES: SyncCategory[] = ['settings', 'skills', 'prompts', 'memory', 'history'];\n\nexport interface SyncResult {\n ok: boolean;\n action: 'push' | 'pull';\n categories: SyncCategory[];\n committedAt?: string | undefined;\n message: string;\n}\n\ninterface SyncStateFile {\n version: 1;\n sha: string;\n lastSyncedAt: string;\n localRev: string;\n}\n\n/**\n * CloudSync — push/pull user-selected ~/.wrongstack categories to a\n * private GitHub repo. No git CLI needed; uses GitHub REST API via fetch.\n * The token is stored encrypted via SecretVault (field named `githubToken`\n * so the vault walker picks it up automatically).\n */\nexport class CloudSync {\n private readonly statePath: string;\n private state: SyncStateFile | null = null;\n\n constructor(\n private readonly paths: WstackPaths,\n private readonly getConfig: () => SyncConfig | null,\n private readonly setConfig: (c: SyncConfig) => Promise<void>,\n ) {\n this.statePath = path.join(paths.globalRoot, 'sync-state.json');\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n async status(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) {\n return 'CloudSync: disabled. Run `/sync enable` to activate.';\n }\n const last = this.state?.lastSyncedAt;\n const since = last ? timeAgo(last) : 'never';\n return [\n `CloudSync: enabled`,\n ` repo: ${cfg.repo}`,\n ` categories: ${cfg.categories.join(', ')}`,\n ` last sync: ${since}`,\n ].join('\\n');\n }\n\n async enable(_repo: string, _categories: SyncCategory[]): Promise<string> {\n // Persisted by the slash command via configStore.update.\n return 'Enable via /sync enable.';\n }\n\n async disable(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg) return 'CloudSync is not configured.';\n const next = { ...cfg, enabled: false };\n await this.setConfig(next);\n return 'CloudSync disabled. Local data kept.';\n }\n\n async push(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'push', categories: [], message: 'Not enabled.' };\n\n const parts = cfg.repo.split('/');\n const owner = expectDefined(parts[0]);\n const repoName = expectDefined(parts[1]);\n const branch = 'main';\n const baseTreeSha = this.state?.sha;\n\n const { treeEntries, rev } = await this.buildLocalTree(cfg.categories);\n const newTreeSha = await this.createGitTree(token, owner, repoName, treeEntries, baseTreeSha);\n\n const commitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n baseTreeSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n\n try {\n await this.updateRef(token, owner, repoName, branch, commitSha);\n } catch (err) {\n // 422 = not a fast forward — remote branch moved. Fetch latest SHA and retry.\n if (err instanceof Error && err.message.includes('422')) {\n const remote = await this.getRef(token, owner, repoName, branch);\n const currentSha = remote.object.sha;\n const rebasedCommitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n currentSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n await this.updateRef(token, owner, repoName, branch, rebasedCommitSha);\n } else {\n throw err;\n }\n }\n\n const syncState: SyncStateFile = {\n version: 1,\n sha: commitSha,\n lastSyncedAt: new Date().toISOString(),\n localRev: rev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'push',\n categories: cfg.categories,\n committedAt: commitSha,\n message: `Pushed ${cfg.categories.join(', ')} to ${cfg.repo}. Commit: ${commitSha.slice(0, 7)}`,\n };\n }\n\n async pull(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'pull', categories: [], message: 'Not enabled.' };\n\n const pullParts = cfg.repo.split('/');\n const owner = expectDefined(pullParts[0]);\n const repoName = expectDefined(pullParts[1]);\n\n const branchData = await this.getRef(token, owner, repoName, 'main');\n const currentSha = branchData.object.sha;\n\n const commitData = await this.getCommit(token, owner, repoName, currentSha);\n const treeSha = commitData.tree.sha;\n\n const treeEntries = await this.getTreeEntries(token, owner, repoName, treeSha);\n\n for (const entry of treeEntries) {\n if (entry.type !== 'blob') continue;\n\n // Paths look like \"data/{category}/...\" — extract the category\n const segments = entry.path.split('/');\n if (segments[0] !== 'data' || !segments[1]) continue;\n const cat = segments[1] as SyncCategory;\n if (!['settings', 'skills', 'prompts', 'memory', 'history'].includes(cat)) continue;\n\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n\n // Reconstruct relative path under the category dir. Remote trees are\n // untrusted input: a compromised sync repo could contain paths like\n // data/skills/../../config.json. Keep every write inside the selected\n // category root, and only allow subpaths for directory-backed categories.\n const rel = segments.slice(2).join('/');\n const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);\n\n const blobData = await this.getBlob(token, owner, repoName, entry.sha);\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.writeFile(destPath, Buffer.from(blobData, 'base64'));\n }\n\n const localRev = await this.hashLocalCategories(cfg.categories);\n const syncState: SyncStateFile = {\n version: 1,\n sha: currentSha,\n lastSyncedAt: new Date().toISOString(),\n localRev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'pull',\n categories: cfg.categories,\n committedAt: currentSha,\n message: `Pulled ${cfg.categories.join(', ')} from ${cfg.repo}. Commit: ${currentSha.slice(0, 7)}`,\n };\n }\n\n async hasLocalChanges(): Promise<boolean> {\n if (!this.state) return true;\n const cfg = this.getConfig();\n if (!cfg) return true;\n const current = await this.hashLocalCategories(cfg.categories);\n return current !== this.state.localRev;\n }\n\n async loadState(): Promise<void> {\n try {\n const raw = await fs.readFile(this.statePath, 'utf8');\n this.state = JSON.parse(raw) as SyncStateFile;\n } catch {\n this.state = null;\n }\n }\n\n // ── GitHub API helpers ──────────────────────────────────────────────\n\n private async githubFetch(\n token: string,\n owner: string,\n repo: string,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH',\n pathSegment: string,\n body?: unknown | undefined,\n ): Promise<unknown> {\n const url = `https://api.github.com/repos/${owner}/${repo}${pathSegment}`;\n const init: RequestInit = {\n signal: AbortSignal.timeout(15_000),\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Content-Type': 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new WrongStackError({\n message: `GitHub API ${method} ${pathSegment} failed (${res.status}): ${errText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { method, pathSegment, status: res.status, repo: `${owner}/${repo}` },\n });\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : {};\n }\n\n private async getRef(token: string, owner: string, repo: string, ref: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/refs/heads/${ref}`)) as {\n object: { sha: string };\n };\n }\n\n private async updateRef(token: string, owner: string, repo: string, ref: string, sha: string) {\n await this.githubFetch(token, owner, repo, 'PATCH', `/git/refs/heads/${ref}`, {\n sha,\n force: false,\n });\n }\n\n private async getCommit(token: string, owner: string, repo: string, sha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/commits/${sha}`)) as {\n tree: { sha: string };\n message: string;\n };\n }\n\n private async getTreeEntries(token: string, owner: string, repo: string, treeSha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/trees/${treeSha}?recursive=1`)) as Array<{\n path: string;\n sha: string;\n type: 'blob' | 'tree';\n }>;\n }\n\n private async createCommit(\n token: string, owner: string, repo: string,\n treeSha: string, parentSha?: string | undefined, message = 'sync',\n ) {\n const body: Record<string, unknown> = { message, tree: treeSha };\n if (parentSha) body.parents = [parentSha];\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/commits', body)) as { sha: string };\n return result.sha;\n }\n\n private async createGitTree(\n token: string, owner: string, repo: string,\n entries: Array<{ path: string; content: string; mode: string }>,\n baseTreeSha?: string | undefined,\n ): Promise<string> {\n const tree = entries.map((e) => ({\n path: e.path,\n mode: e.mode,\n type: 'blob',\n content: e.content,\n }));\n const body: Record<string, unknown> = { tree };\n if (baseTreeSha) body.base_tree = baseTreeSha;\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/trees', body)) as { sha: string };\n return result.sha;\n }\n\n private async getBlob(token: string, owner: string, repo: string, sha: string): Promise<string> {\n const result = (await this.githubFetch(token, owner, repo, 'GET', `/git/blobs/${sha}`)) as { content: string };\n return result.content;\n }\n\n // ── Local file helpers ──────────────────────────────────────────────\n\n private async buildLocalTree(categories: SyncCategory[]): Promise<{\n treeEntries: Array<{ path: string; content: string; mode: string }>;\n rev: string;\n }> {\n const entries: Array<{ path: string; content: string; mode: string }> = [];\n const hashes: string[] = [];\n\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file, 'utf8');\n const rel = path.relative(localPath, file).replace(/\\\\/g, '/');\n entries.push({ path: `data/${cat}/${rel}`, content, mode: '100644' });\n hashes.push(content);\n }\n } else {\n const content = await fs.readFile(localPath, 'utf8');\n entries.push({ path: `data/${cat}`, content, mode: '100644' });\n hashes.push(content);\n }\n } catch {\n // skip missing files/dirs\n }\n }\n\n const rev = createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n return { treeEntries: entries, rev };\n }\n\n private async hashLocalCategories(categories: SyncCategory[]): Promise<string> {\n const hashes: string[] = [];\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file);\n hashes.push(content.toString('base64') + file);\n }\n } else {\n const content = await fs.readFile(localPath);\n hashes.push(content.toString('base64') + localPath);\n }\n } catch {\n // skip\n }\n }\n return createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n }\n\n private categoryToPath(cat: SyncCategory): string | null {\n switch (cat) {\n case 'settings': return this.paths.globalConfig;\n case 'skills': return this.paths.globalSkills;\n case 'prompts': return this.paths.globalPrompts;\n case 'memory': return this.paths.globalMemory;\n case 'history': return this.paths.historyFile;\n default: return null;\n }\n }\n\n private async walkDir(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await this.walkDir(full, base)));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n\nfunction resolvePulledCategoryPath(\n cat: SyncCategory,\n localPath: string,\n rel: string,\n remotePath: string,\n): string {\n const directoryBacked = cat === 'skills' || cat === 'prompts';\n if (!directoryBacked) {\n if (rel) throw new FsError({\n message: `Refusing nested CloudSync path for file category: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'nested_file_category', category: cat },\n });\n return localPath;\n }\n\n if (!rel) return localPath;\n const normalizedRel = path.normalize(rel);\n const traversesUp = normalizedRel === '..' || normalizedRel.startsWith(`..${path.sep}`);\n if (path.isAbsolute(normalizedRel) || traversesUp) {\n throw new FsError({\n message: `Refusing CloudSync path traversal: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'path_traversal', normalizedRel },\n });\n }\n\n const dest = path.resolve(localPath, normalizedRel);\n const root = path.resolve(localPath);\n const relative = path.relative(root, dest);\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new FsError({\n message: `Refusing CloudSync path outside category root: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'outside_category_root', category: cat },\n });\n }\n return dest;\n}\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n","import type { SessionEvent, SessionWriter } from '../types/session.js';\n\nexport type AuditLevel = 'minimal' | 'standard' | 'full';\n\n/**\n * Configuration for sampling high-volume events inside the bridge.\n * This allows callers (CLI, TUI, WebUI, plugins) to tune how aggressively\n * noisy events like tool progress are persisted.\n */\nexport interface ToolProgressSamplingOptions {\n /**\n * How often to persist 'log' and 'partial_output' progress events.\n * - 1 = every message (no sampling)\n * - 8 = keep the first message + every 8th after that (default)\n */\n sampleRate?: number | undefined;\n}\n\nexport interface SessionSamplingOptions {\n /** Controls sampling behavior for `tool_progress` events (only relevant at auditLevel 'full'). */\n toolProgress?: ToolProgressSamplingOptions | undefined;\n}\n\nexport interface SessionEventBridgeOptions {\n /** Sampling rules for high-volume audit events. */\n sampling?: SessionSamplingOptions | undefined;\n}\n\n/**\n * Small, safe helper that wraps a SessionWriter and enforces the\n * configured auditLevel.\n *\n * All appends are best-effort. Failures are swallowed (with optional\n * diagnostics) so they never crash the agent loop.\n */\nexport interface SessionEventBridge {\n /** Append an event if allowed by the current audit level. */\n append(event: SessionEvent): Promise<void>;\n /** Batch-append events allowed by the current audit level. */\n appendBatch(events: SessionEvent[]): Promise<void>;\n\n /** Current audit level this bridge was created with. */\n readonly level: AuditLevel;\n\n /** Returns true if an event of this type should be written at the current level. */\n allows(type: SessionEvent['type']): boolean;\n}\n\n/** Core events that are always written regardless of auditLevel. */\nconst CORE_RECONSTRUCT_EVENTS = new Set<SessionEvent['type']>([\n 'session_start',\n 'session_resumed',\n 'user_input',\n 'llm_response',\n 'tool_result',\n 'checkpoint',\n 'file_snapshot',\n 'rewound',\n 'in_flight_start',\n 'in_flight_end',\n 'session_end',\n]);\n\n/**\n * Events that are considered \"standard\" audit detail.\n * These are lightweight and high-value for forensics.\n */\nconst STANDARD_AUDIT_EVENTS = new Set<SessionEvent['type']>([\n 'llm_request',\n 'tool_use',\n 'tool_call_start',\n 'tool_call_end',\n 'compaction',\n 'error',\n 'message_truncated',\n 'provider_retry',\n 'provider_error',\n]);\n\n/**\n * Events that are only allowed at 'full' audit level because they can be\n * very high volume (e.g. streaming tool output).\n */\nconst FULL_ONLY_EVENTS = new Set<SessionEvent['type']>([\n 'tool_progress',\n]);\n\n/**\n * \"full\" level allows everything (including potentially heavy events\n * that plugins or future code may emit).\n */\nfunction isAllowed(type: SessionEvent['type'], level: AuditLevel): boolean {\n if (CORE_RECONSTRUCT_EVENTS.has(type)) return true;\n if (level === 'minimal') return false;\n\n if (STANDARD_AUDIT_EVENTS.has(type)) return true;\n if (level === 'standard') return false;\n\n // 'full' level events (high volume)\n if (FULL_ONLY_EVENTS.has(type)) {\n return level === 'full';\n }\n\n // 'full' — allow everything else\n return true;\n}\n\n/**\n * Create a safe, audit-level-aware bridge around a SessionWriter.\n *\n * The bridge can also apply sampling for high-volume events (e.g. `tool_progress`)\n * when `auditLevel` is set to `'full'`.\n *\n * @example\n * const bridge = createSessionEventBridge(sessionWriter, 'full', {\n * sampling: {\n * toolProgress: { sampleRate: 5 } // more aggressive sampling\n * }\n * });\n */\nexport function createSessionEventBridge(\n writer:\n | SessionWriter\n | (() => SessionWriter | undefined | null)\n | undefined\n | null,\n level: AuditLevel = 'standard',\n options: SessionEventBridgeOptions = {},\n): SessionEventBridge {\n const normalizedLevel: AuditLevel = level ?? 'standard';\n\n // Accept either a writer instance or a getter. A getter lets long-lived\n // hosts (CLI/TUI/WebUI) resolve the CURRENT writer on every append — when\n // the user resumes another session mid-run, audit events follow the swap\n // instead of being silently dropped into the old, closed writer.\n const resolveWriter: () => SessionWriter | undefined | null =\n typeof writer === 'function' ? writer : () => writer;\n\n // Internal sampling state for high-volume events (e.g. tool_progress).\n // Keyed by tool call id (or name as fallback) to keep sampling per-call.\n const progressCounters = new Map<string, number>();\n\n const toolProgressConfig = options.sampling?.toolProgress ?? {};\n const TOOL_PROGRESS_SAMPLE_RATE = toolProgressConfig.sampleRate ?? 8;\n\n /**\n * Decide whether a high-volume event should be sampled in.\n * Currently only implements sampling for 'tool_progress'.\n */\n function shouldSample(event: SessionEvent): boolean {\n if (event.type !== 'tool_progress') return true;\n\n const progEvent = event as Extract<SessionEvent, { type: 'tool_progress' }>;\n const innerType = progEvent.event?.type;\n\n // Always let through high-signal structured events\n if (innerType === 'warning' || innerType === 'metric' || innerType === 'file_changed') {\n return true;\n }\n\n // Sample noisy text streams (log / partial_output)\n if (innerType === 'log' || innerType === 'partial_output') {\n const key = progEvent.id || progEvent.name;\n const count = (progressCounters.get(key) || 0) + 1;\n progressCounters.set(key, count);\n\n // Always keep the first message + every Nth after that\n return count === 1 || (count % TOOL_PROGRESS_SAMPLE_RATE === 0);\n }\n\n return true;\n }\n\n return {\n level: normalizedLevel,\n\n allows(type) {\n return isAllowed(type, normalizedLevel);\n },\n\n async append(event) {\n const target = resolveWriter();\n if (!target) return;\n if (!isAllowed(event.type, normalizedLevel)) return;\n\n // Apply sampling for high-volume events (only at 'full' level)\n if (!shouldSample(event)) return;\n\n try {\n await target.append(event);\n } catch (err) {\n // Best-effort: never let session logging break the agent.\n // The existing FileSessionWriter already does throttled warnings,\n // but we keep this wrapper silent by default to avoid log spam.\n // Callers that care can listen to EventBus 'session.damaged' etc.\n }\n },\n\n async appendBatch(events) {\n const target = resolveWriter();\n if (!target || events.length === 0) return;\n const allowed = events.filter(\n (e) => isAllowed(e.type, normalizedLevel) && shouldSample(e),\n );\n if (allowed.length === 0) return;\n try {\n await target.appendBatch(allowed);\n } catch {\n // best-effort — same contract as append()\n }\n },\n };\n}\n\n/** Convenience re-export of the allowed core set for tests/docs. */\nexport { CORE_RECONSTRUCT_EVENTS, STANDARD_AUDIT_EVENTS };\n\n/**\n * Safely extract the auditLevel from a (possibly partial) Config object.\n * Falls back to 'standard' if not present or invalid.\n */\nexport function resolveAuditLevel(\n cfg?: { session?: { auditLevel?: AuditLevel | undefined } | undefined } | null,\n): AuditLevel {\n const raw = cfg?.session?.auditLevel;\n if (raw === 'minimal' || raw === 'standard' || raw === 'full') {\n return raw;\n }\n return 'standard';\n}\n\n/**\n * Fully resolves the session logging configuration with sensible defaults.\n * This is the recommended way for the CLI / TUI / WebUI to read session config.\n */\nexport function resolveSessionLoggingConfig(\n cfg?: {\n session?: {\n auditLevel?: AuditLevel | undefined;\n sampling?: {\n toolProgress?: { sampleRate?: number | undefined };\n };\n };\n } | null,\n): {\n auditLevel: AuditLevel;\n sampling: {\n toolProgress: { sampleRate: number };\n };\n} {\n const session = cfg?.session ?? {};\n\n const auditLevel = resolveAuditLevel(cfg);\n\n const toolProgressSampleRate =\n session.sampling?.toolProgress?.sampleRate ?? 8;\n\n return {\n auditLevel,\n sampling: {\n toolProgress: {\n sampleRate: Math.max(1, Math.floor(toolProgressSampleRate)),\n },\n },\n };\n}"]}
|