codesesh 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +4 -4
  2. package/dist/{chunk-MBZ4VV4C.js → chunk-FCYCBGEL.js} +3 -3
  3. package/dist/{chunk-W4PZHL2C.js → chunk-NBJJGH5P.js} +57 -39
  4. package/dist/chunk-NBJJGH5P.js.map +1 -0
  5. package/dist/chunk-PAP2Q3WV.js +1271 -0
  6. package/dist/chunk-PAP2Q3WV.js.map +1 -0
  7. package/dist/{chunk-BYB77UAJ.js → chunk-TS3IWH5U.js} +115 -72
  8. package/dist/chunk-TS3IWH5U.js.map +1 -0
  9. package/dist/{chunk-YCUN52HA.js → chunk-WUYSZAYR.js} +75 -114
  10. package/dist/chunk-WUYSZAYR.js.map +1 -0
  11. package/dist/{chunk-3SXCTDD6.js → chunk-XKZSX5BM.js} +4 -3
  12. package/dist/chunk-YQFEGFWD.js +89 -0
  13. package/dist/chunk-YQFEGFWD.js.map +1 -0
  14. package/dist/{discovery-K3GLISI6.js → discovery-D23RV7FY.js} +11 -5
  15. package/dist/index.js +1415 -948
  16. package/dist/index.js.map +1 -1
  17. package/dist/project-identity-worker.js +4 -4
  18. package/dist/scan-refresh-worker.js +17 -7
  19. package/dist/scan-refresh-worker.js.map +1 -1
  20. package/dist/search-index-worker.js +16 -8
  21. package/dist/search-index-worker.js.map +1 -1
  22. package/dist/session-detail-worker.js +79 -0
  23. package/dist/session-detail-worker.js.map +1 -0
  24. package/dist/smart-tag-worker.js +3 -3
  25. package/dist/web/assets/CustomTimeWindowDialog-C9XTZRm0.js +1 -0
  26. package/dist/web/assets/{InteractiveReceipt-Dk50TBsH.js → InteractiveReceipt-Sca1smpv.js} +1 -1
  27. package/dist/web/assets/OverviewScreen-Vq6BQR9_.js +1 -0
  28. package/dist/web/assets/{PrismHighlighter-B1a2dPJO.js → PrismHighlighter-LWITDffT.js} +1 -1
  29. package/dist/web/assets/Projects-CwicV3Dk.js +1 -0
  30. package/dist/web/assets/{SearchResultsPanel-DfheEwpz.js → SearchResultsPanel-DCO0Ak0c.js} +1 -1
  31. package/dist/web/assets/SessionDetail-mdmTQgo1.js +53 -0
  32. package/dist/web/assets/api-CXVT9XcZ.js +1 -0
  33. package/dist/web/assets/contract-BS78VBCV.js +2 -0
  34. package/dist/web/assets/{index-Bd-YkWkZ.css → index-C5cyw58A.css} +1 -1
  35. package/dist/web/assets/index-H2cT-6c6.js +1423 -0
  36. package/dist/web/assets/{session-indexes-BsgjUoc1.js → session-indexes-yyyWpKLf.js} +2 -2
  37. package/dist/web/index.html +6 -6
  38. package/package.json +1 -1
  39. package/dist/chunk-BYB77UAJ.js.map +0 -1
  40. package/dist/chunk-G4HRD3AR.js +0 -246
  41. package/dist/chunk-G4HRD3AR.js.map +0 -1
  42. package/dist/chunk-W4PZHL2C.js.map +0 -1
  43. package/dist/chunk-YCUN52HA.js.map +0 -1
  44. package/dist/web/assets/OverviewScreen-5hvQVp4H.js +0 -1
  45. package/dist/web/assets/Projects-Cy_v2yep.js +0 -1
  46. package/dist/web/assets/SessionDetail-DRI8R3st.js +0 -53
  47. package/dist/web/assets/api-GP9UCedC.js +0 -1
  48. package/dist/web/assets/contract-xJyW5u7a.js +0 -2
  49. package/dist/web/assets/index-DEjvzumm.js +0 -1410
  50. package/dist/web/assets/panel-ND0J63d3.js +0 -1
  51. /package/dist/{chunk-MBZ4VV4C.js.map → chunk-FCYCBGEL.js.map} +0 -0
  52. /package/dist/{chunk-3SXCTDD6.js.map → chunk-XKZSX5BM.js.map} +0 -0
  53. /package/dist/{discovery-K3GLISI6.js.map → discovery-D23RV7FY.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logging.ts","../src/log-file-writer.ts","../src/log-record.ts","../src/diagnostics-bridge.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { getEnvironmentData, setEnvironmentData } from \"node:worker_threads\";\nimport {\n isWorkerLogMessage,\n WORKER_LOG_MESSAGE_TYPE,\n type WorkerLogContext,\n type WorkerLogLevel,\n type WorkerLogMessage,\n} from \"@codesesh/core/runtime/diagnostics\";\nimport type { SearchIndexSyncResult } from \"@codesesh/core/runtime/discovery\";\nimport { AsyncLogFileWriter, type DroppedLogCounts } from \"./log-file-writer.js\";\nimport { LogRecordEncoder, type EncodedLogLine } from \"./log-record.js\";\n\nexport type LogContext = WorkerLogContext;\ntype LogLevel = WorkerLogLevel;\n\ninterface WorkerLogPort {\n postMessage(message: WorkerLogMessage): void;\n}\n\nconst DEFAULT_MAX_FILE_BYTES = 5_000_000;\nconst DEFAULT_MAX_FILES = 10;\nconst DEFAULT_MAX_DIRECTORY_BYTES = 50_000_000;\nconst DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1_000;\nconst DEFAULT_MAX_QUEUE_BYTES = 1_000_000;\nconst DEFAULT_MAX_RECORD_BYTES = 64 * 1_024;\nconst FINGERPRINT_KEY_ENVIRONMENT_DATA = \"codesesh.logging.fingerprint-key.v1\";\nconst LOG_CONTEXT_KEYS = new Set<keyof LogContext>([\n \"request_id\",\n \"operation_id\",\n \"publication_id\",\n]);\n\nconst LEVEL_WEIGHT: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nexport interface LoggerOptions {\n logDir?: string;\n level?: LogLevel;\n maxBytes?: number;\n maxFiles?: number;\n maxDirectoryBytes?: number;\n maxAgeMs?: number;\n maxQueueBytes?: number;\n maxRecordBytes?: number;\n}\n\nfunction parseLevel(value: string | undefined): LogLevel {\n if (value === \"debug\" || value === \"info\" || value === \"warn\" || value === \"error\") {\n return value;\n }\n return \"info\";\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number): number {\n const parsed = Math.floor(value ?? Number.NaN);\n return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nfunction parsePositiveInteger(value: string | undefined, fallback: number): number {\n return positiveInteger(value == null ? undefined : Number(value), fallback);\n}\n\nfunction parseMaxAge(value: string | undefined): number {\n const days = parsePositiveInteger(value, DEFAULT_MAX_AGE_MS / (24 * 60 * 60 * 1_000));\n const milliseconds = days * 24 * 60 * 60 * 1_000;\n return Number.isSafeInteger(milliseconds) ? milliseconds : DEFAULT_MAX_AGE_MS;\n}\n\nfunction getDefaultLogDir(): string {\n const base = process.env.XDG_CACHE_HOME ?? join(homedir(), \".cache\");\n return join(base, \"codesesh\", \"logs\");\n}\n\nfunction sharedFingerprintKey(): string {\n const existing = getEnvironmentData(FINGERPRINT_KEY_ENVIRONMENT_DATA) as unknown;\n if (typeof existing === \"string\" && /^[a-f0-9]{64}$/.test(existing)) return existing;\n\n const generated = randomBytes(32).toString(\"hex\");\n setEnvironmentData(FINGERPRINT_KEY_ENVIRONMENT_DATA, generated);\n return generated;\n}\n\nconst LOG_FINGERPRINT_KEY = sharedFingerprintKey();\n\nfunction normalizedContext(context: LogContext): LogContext {\n return Object.fromEntries(\n Object.entries(context).flatMap(([key, value]) =>\n LOG_CONTEXT_KEYS.has(key as keyof LogContext) && typeof value === \"string\" && value.length > 0\n ? [[key, value.slice(0, 160)]]\n : [],\n ),\n );\n}\n\nexport class AppLogger {\n private readonly level: LogLevel;\n private readonly runId: string;\n private readonly context = new AsyncLocalStorage<LogContext>();\n private readonly encoder: LogRecordEncoder;\n private readonly writer: AsyncLogFileWriter;\n private workerTarget: { port: WorkerLogPort; threadId: number } | null = null;\n private sequence = 0;\n private transportFailureReported = false;\n\n constructor(options: LoggerOptions = {}) {\n const logDir = options.logDir ?? process.env.CODESESH_LOG_DIR ?? getDefaultLogDir();\n this.level = options.level ?? parseLevel(process.env.CODESESH_LOG_LEVEL);\n this.runId = randomUUID();\n const maxRecordBytes = positiveInteger(\n options.maxRecordBytes,\n parsePositiveInteger(process.env.CODESESH_LOG_MAX_RECORD_BYTES, DEFAULT_MAX_RECORD_BYTES),\n );\n this.encoder = new LogRecordEncoder({\n fingerprintKey: LOG_FINGERPRINT_KEY,\n maxRecordBytes,\n });\n this.writer = new AsyncLogFileWriter({\n logDir,\n runId: this.runId,\n maxFileBytes: positiveInteger(\n options.maxBytes,\n parsePositiveInteger(process.env.CODESESH_LOG_MAX_BYTES, DEFAULT_MAX_FILE_BYTES),\n ),\n maxFiles: positiveInteger(\n options.maxFiles,\n parsePositiveInteger(process.env.CODESESH_LOG_MAX_FILES, DEFAULT_MAX_FILES),\n ),\n maxDirectoryBytes: positiveInteger(\n options.maxDirectoryBytes,\n parsePositiveInteger(process.env.CODESESH_LOG_MAX_TOTAL_BYTES, DEFAULT_MAX_DIRECTORY_BYTES),\n ),\n maxAgeMs: positiveInteger(\n options.maxAgeMs,\n parseMaxAge(process.env.CODESESH_LOG_MAX_AGE_DAYS),\n ),\n maxQueueBytes: positiveInteger(\n options.maxQueueBytes,\n parsePositiveInteger(process.env.CODESESH_LOG_MAX_QUEUE_BYTES, DEFAULT_MAX_QUEUE_BYTES),\n ),\n createDropSummary: (counts) => this.encodeDropSummary(counts),\n });\n }\n\n getLogPath(): string {\n return this.writer.path;\n }\n\n runWithContext<Result>(context: LogContext, operation: () => Result): Result {\n return this.context.run({ ...this.captureContext(), ...normalizedContext(context) }, operation);\n }\n\n restoreContext<Result>(context: LogContext, operation: () => Result): Result {\n return this.context.run(normalizedContext(context), operation);\n }\n\n captureContext(): LogContext {\n return { ...this.context.getStore() };\n }\n\n forwardToParent(port: WorkerLogPort, threadId: number): void {\n this.workerTarget = { port, threadId };\n }\n\n consumeWorkerMessage(message: unknown): boolean {\n if (!isWorkerLogMessage(message)) return false;\n if (LEVEL_WEIGHT[message.level] < LEVEL_WEIGHT[this.level]) return true;\n try {\n this.writer.enqueue(\n this.encode({\n timestamp: message.ts,\n level: message.level,\n event: message.event,\n pid: message.pid,\n threadId: message.threadId,\n context: message.context,\n data: message.data,\n }),\n );\n this.transportFailureReported = false;\n } catch (error) {\n this.reportTransportFailure(error);\n }\n return true;\n }\n\n debug(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"debug\", event, data);\n }\n\n info(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"info\", event, data);\n }\n\n warn(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"warn\", event, data);\n }\n\n error(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"error\", event, data);\n }\n\n flush(): Promise<void> {\n return this.writer.flush();\n }\n\n close(): Promise<void> {\n return this.writer.close();\n }\n\n flushSync(): void {\n this.writer.flushSync();\n }\n\n private write(level: LogLevel, event: string, data: Record<string, unknown>): void {\n if (LEVEL_WEIGHT[level] < LEVEL_WEIGHT[this.level]) return;\n try {\n const timestamp = new Date().toISOString();\n const context = this.captureContext();\n if (this.workerTarget) {\n this.workerTarget.port.postMessage({\n type: WORKER_LOG_MESSAGE_TYPE,\n ts: timestamp,\n level,\n event,\n pid: process.pid,\n threadId: this.workerTarget.threadId,\n context,\n data: this.encoder.sanitizeForTransport(data, event),\n });\n this.transportFailureReported = false;\n return;\n }\n\n this.writer.enqueue(\n this.encode({\n timestamp,\n level,\n event,\n pid: process.pid,\n context,\n data,\n }),\n );\n } catch (error) {\n this.reportTransportFailure(error);\n }\n }\n\n private encode(\n input: Omit<Parameters<LogRecordEncoder[\"encode\"]>[0], \"runId\" | \"sequence\">,\n ): EncodedLogLine {\n this.sequence += 1;\n return this.encoder.encode({\n ...input,\n runId: this.runId,\n sequence: this.sequence,\n });\n }\n\n private encodeDropSummary(counts: DroppedLogCounts): EncodedLogLine {\n return this.encode({\n timestamp: new Date().toISOString(),\n level: \"warn\",\n event: \"logger.records_dropped\",\n pid: process.pid,\n data: { ...counts },\n });\n }\n\n private reportTransportFailure(error: unknown): void {\n if (this.transportFailureReported) return;\n this.transportFailureReported = true;\n const message = error instanceof Error ? error.message : String(error);\n try {\n process.stderr.write(`[codesesh] Failed to prepare log entry: ${message}\\n`);\n } catch {}\n }\n}\n\nexport const appLogger = new AppLogger();\n\nexport function logSearchIndexSync(\n context: string,\n result: SearchIndexSyncResult | null,\n data: Record<string, unknown> = {},\n): void {\n if (result?.failures?.length) {\n appLogger.warn(\"search_index.sessions_skipped\", {\n context,\n agent: result.agentName,\n failures: result.failures,\n });\n }\n if (!result) return;\n\n const detail = {\n context,\n agent: result.agentName,\n mode: result.mode,\n sessions: result.sessions,\n changed: result.changed,\n deleted: result.deleted,\n indexed: result.indexed,\n skipped: result.skipped,\n duration_ms: Math.round(result.durationMs),\n planning_ms: Math.round(result.planningDurationMs),\n get_session_data_calls: result.getSessionDataCalls,\n reused_materializations: result.reusedMaterializations,\n get_session_data_ms: Math.round(result.getSessionDataDurationMs),\n materialization_ms: Math.round(result.materializationDurationMs),\n rebuild_duration_ms:\n result.rebuildDurationMs != null ? Math.round(result.rebuildDurationMs) : undefined,\n ...data,\n };\n if (result.mode === \"bulk\") appLogger.info(\"search_index.sync\", detail);\n else appLogger.debug(\"search_index.sync\", detail);\n}\n","import { appendFileSync, chmodSync, mkdirSync } from \"node:fs\";\nimport {\n chmod,\n lstat,\n mkdir,\n open,\n readdir,\n rename,\n unlink,\n type FileHandle,\n} from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n PRIVATE_DIR_MODE,\n PRIVATE_FILE_MODE,\n type WorkerLogLevel,\n} from \"@codesesh/core/runtime/diagnostics\";\nimport type { EncodedLogLine } from \"./log-record.js\";\n\nconst MAX_BATCH_BYTES = 64 * 1024;\nconst UUID_PATTERN = \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\";\nconst CURRENT_LOG_PATTERN = new RegExp(`^codesesh-(\\\\d+)-${UUID_PATTERN}-active\\\\.log$`);\nconst EMERGENCY_LOG_PATTERN = new RegExp(`^codesesh-(\\\\d+)-${UUID_PATTERN}-emergency\\\\.log$`);\nconst RUN_LOG_PATTERN = new RegExp(`^codesesh-\\\\d+-${UUID_PATTERN}-\\\\d+\\\\.log$`);\nconst LEGACY_ACTIVE_LOG_PATTERN = /^codesesh-(\\d+)\\.log$/;\nconst LEGACY_ROTATED_LOG_PATTERN =\n /^codesesh-\\d+-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z-\\d+\\.log$/;\nconst ORIGINAL_ROTATED_LOG_PATTERN =\n /^codesesh-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z-\\d+-\\d+\\.log$/;\nconst ORIGINAL_ACTIVE_LOG_PATTERN = /^codesesh\\.log$/;\nconst LOG_LEVEL_PRIORITY: Record<WorkerLogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nexport interface DroppedLogCounts {\n debug: number;\n info: number;\n warn: number;\n error: number;\n}\n\ninterface LogFileWriterOptions {\n logDir: string;\n runId: string;\n maxFileBytes: number;\n maxFiles: number;\n maxDirectoryBytes: number;\n maxAgeMs: number;\n maxQueueBytes: number;\n createDropSummary(counts: DroppedLogCounts): EncodedLogLine;\n}\n\ninterface PendingLine extends EncodedLogLine {\n internal?: boolean;\n}\n\ninterface ManagedLogFile {\n name: string;\n path: string;\n bytes: number;\n mtimeMs: number;\n isProtected: boolean;\n}\n\nfunction emptyDropCounts(): DroppedLogCounts {\n return { debug: 0, info: 0, warn: 0, error: 0 };\n}\n\nfunction droppedCount(counts: DroppedLogCounts): number {\n return counts.debug + counts.info + counts.warn + counts.error;\n}\n\nfunction errorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? String(error.code)\n : undefined;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n if (pid === process.pid) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return errorCode(error) !== \"ESRCH\";\n }\n}\n\nfunction activeLogPid(name: string): number | null {\n const match =\n CURRENT_LOG_PATTERN.exec(name) ??\n EMERGENCY_LOG_PATTERN.exec(name) ??\n LEGACY_ACTIVE_LOG_PATTERN.exec(name);\n if (!match) return null;\n const pid = Number(match[1]);\n return Number.isSafeInteger(pid) && pid > 0 ? pid : null;\n}\n\nfunction isManagedLog(name: string): boolean {\n return (\n CURRENT_LOG_PATTERN.test(name) ||\n EMERGENCY_LOG_PATTERN.test(name) ||\n RUN_LOG_PATTERN.test(name) ||\n LEGACY_ACTIVE_LOG_PATTERN.test(name) ||\n LEGACY_ROTATED_LOG_PATTERN.test(name) ||\n ORIGINAL_ROTATED_LOG_PATTERN.test(name) ||\n ORIGINAL_ACTIVE_LOG_PATTERN.test(name)\n );\n}\n\nexport class AsyncLogFileWriter {\n private readonly logDir: string;\n private readonly prefix: string;\n private readonly currentPath: string;\n private readonly emergencyPath: string;\n private readonly maxFileBytes: number;\n private readonly maxFiles: number;\n private readonly maxDirectoryBytes: number;\n private readonly maxAgeMs: number;\n private readonly maxQueueBytes: number;\n private readonly createDropSummary: (counts: DroppedLogCounts) => EncodedLogLine;\n private queue: PendingLine[] = [];\n private inFlight: PendingLine[] = [];\n private dropped = emptyDropCounts();\n private queuedBytes = 0;\n private currentBytes = 0;\n private rotationIndex = 0;\n private handle: FileHandle | null = null;\n private drainPromise: Promise<void> | null = null;\n private closePromise: Promise<void> | null = null;\n private storagePrepared = false;\n private currentFileCreated = false;\n private needsRecoverySeparator = false;\n private writeFailureReported = false;\n private overflowReported = false;\n private closedWriteReported = false;\n\n constructor(options: LogFileWriterOptions) {\n this.logDir = options.logDir;\n this.prefix = `codesesh-${process.pid}-${options.runId}`;\n this.currentPath = join(this.logDir, `${this.prefix}-active.log`);\n this.emergencyPath = join(this.logDir, `${this.prefix}-emergency.log`);\n this.maxFileBytes = options.maxFileBytes;\n this.maxFiles = options.maxFiles;\n this.maxDirectoryBytes = options.maxDirectoryBytes;\n this.maxAgeMs = options.maxAgeMs;\n this.maxQueueBytes = options.maxQueueBytes;\n this.createDropSummary = options.createDropSummary;\n }\n\n get path(): string {\n return this.currentPath;\n }\n\n enqueue(entry: EncodedLogLine): void {\n if (this.closePromise) {\n if (!this.closedWriteReported) {\n this.closedWriteReported = true;\n this.writeStderr(\"Log entry dropped after logger close\");\n }\n return;\n }\n if (!this.makeRoom(entry)) {\n this.recordDrop(entry.level);\n this.scheduleDrain();\n return;\n }\n this.queue.push(entry);\n this.queuedBytes += entry.bytes;\n this.scheduleDrain();\n }\n\n async flush(): Promise<void> {\n while (this.queue.length > 0 || droppedCount(this.dropped) > 0 || this.drainPromise) {\n this.scheduleDrain();\n const drain = this.drainPromise;\n if (!drain) break;\n await drain;\n }\n }\n\n close(): Promise<void> {\n if (this.closePromise) return this.closePromise;\n this.closePromise = this.finishClose();\n return this.closePromise;\n }\n\n flushSync(): void {\n const pending = this.queue.splice(0);\n const pendingBytes = pending.reduce((total, entry) => total + entry.bytes, 0);\n this.queuedBytes = Math.max(0, this.queuedBytes - pendingBytes);\n const dropped = droppedCount(this.dropped);\n const emergency = [...this.inFlight, ...pending];\n if (dropped > 0) {\n emergency.push(this.createDropSummary({ ...this.dropped }));\n this.dropped = emptyDropCounts();\n }\n if (emergency.length === 0) return;\n try {\n mkdirSync(this.logDir, { recursive: true, mode: PRIVATE_DIR_MODE });\n if (process.platform !== \"win32\") chmodSync(this.logDir, PRIVATE_DIR_MODE);\n appendFileSync(this.emergencyPath, emergency.map((entry) => entry.line).join(\"\"), {\n encoding: \"utf8\",\n mode: PRIVATE_FILE_MODE,\n });\n if (process.platform !== \"win32\") chmodSync(this.emergencyPath, PRIVATE_FILE_MODE);\n } catch (error) {\n this.reportWriteFailure(error);\n }\n }\n\n private makeRoom(entry: EncodedLogLine): boolean {\n if (entry.bytes > this.maxQueueBytes) return false;\n if (entry.bytes <= this.maxQueueBytes - this.queuedBytes) return true;\n if (entry.level === \"debug\" || entry.level === \"info\") return false;\n\n const requiredBytes = entry.bytes - (this.maxQueueBytes - this.queuedBytes);\n const candidates = this.queue\n .map((candidate, index) => ({ candidate, index }))\n .filter(\n ({ candidate }) =>\n !candidate.internal &&\n LOG_LEVEL_PRIORITY[candidate.level] < LOG_LEVEL_PRIORITY[entry.level],\n )\n .toSorted((left, right) => {\n return (\n LOG_LEVEL_PRIORITY[left.candidate.level] - LOG_LEVEL_PRIORITY[right.candidate.level] ||\n left.index - right.index\n );\n });\n const removedIndexes = new Set<number>();\n let removedBytes = 0;\n for (const { candidate, index } of candidates) {\n removedIndexes.add(index);\n removedBytes += candidate.bytes;\n if (removedBytes >= requiredBytes) break;\n }\n if (removedBytes < requiredBytes) return false;\n\n this.queue = this.queue.filter((candidate, index) => {\n if (!removedIndexes.has(index)) return true;\n this.queuedBytes -= candidate.bytes;\n this.recordDrop(candidate.level);\n return false;\n });\n return true;\n }\n\n private recordDrop(level: WorkerLogLevel): void {\n this.dropped[level] += 1;\n if (this.overflowReported) return;\n this.overflowReported = true;\n this.writeStderr(\"Log queue full; entries were dropped\");\n }\n\n private scheduleDrain(): void {\n if (this.drainPromise) return;\n const drain = Promise.resolve()\n .then(() => this.drain())\n .catch((error) => {\n this.discardPending();\n this.reportWriteFailure(error);\n });\n this.drainPromise = drain;\n void drain.then(() => {\n if (this.drainPromise === drain) this.drainPromise = null;\n if (this.queue.length > 0 || droppedCount(this.dropped) > 0) this.scheduleDrain();\n });\n }\n\n private async drain(): Promise<void> {\n while (this.queue.length > 0 || droppedCount(this.dropped) > 0) {\n try {\n await this.openCurrentFile();\n } catch (error) {\n this.discardPending();\n this.reportWriteFailure(error);\n return;\n }\n this.enqueueDropSummaryIfPossible();\n if (this.queue.length === 0) return;\n if (this.shouldRotate(this.queue[0]!.bytes)) await this.rotate();\n const batch = this.takeBatch();\n await this.appendBatch(batch);\n }\n }\n\n private enqueueDropSummaryIfPossible(): void {\n if (droppedCount(this.dropped) === 0) return;\n const summary = this.createDropSummary({ ...this.dropped });\n if (summary.bytes > this.maxQueueBytes - this.queuedBytes) {\n if (this.queue.length === 0) this.dropped = emptyDropCounts();\n return;\n }\n this.dropped = emptyDropCounts();\n this.queue.push({ ...summary, internal: true });\n this.queuedBytes += summary.bytes;\n }\n\n private takeBatch(): PendingLine[] {\n const first = this.queue[0]!;\n const remainingFileBytes = Math.max(0, this.maxFileBytes - this.currentBytes);\n const batchLimit =\n this.currentBytes === 0 && first.bytes > this.maxFileBytes\n ? first.bytes\n : Math.min(MAX_BATCH_BYTES, remainingFileBytes);\n let count = 0;\n let bytes = 0;\n for (const next of this.queue) {\n if (count > 0 && next.bytes > batchLimit - bytes) break;\n count += 1;\n if (count === 1 && next.bytes > batchLimit) {\n break;\n }\n bytes += next.bytes;\n }\n return this.queue.splice(0, count);\n }\n\n private async appendBatch(batch: PendingLine[]): Promise<void> {\n const bytes = batch.reduce((total, entry) => total + entry.bytes, 0);\n this.inFlight = batch;\n try {\n if (!this.handle) throw new Error(\"Log file is not open\");\n if (this.needsRecoverySeparator && this.currentBytes > 0) {\n await this.handle.writeFile(\"\\n\", \"utf8\");\n this.currentBytes += 1;\n }\n this.needsRecoverySeparator = false;\n await this.handle.writeFile(batch.map((entry) => entry.line).join(\"\"), \"utf8\");\n this.currentBytes += bytes;\n this.writeFailureReported = false;\n this.overflowReported = false;\n } catch (error) {\n this.needsRecoverySeparator = true;\n for (const entry of batch) {\n if (!entry.internal) this.recordDrop(entry.level);\n }\n await this.closeHandle();\n this.reportWriteFailure(error);\n } finally {\n if (this.inFlight === batch) this.inFlight = [];\n this.queuedBytes = Math.max(0, this.queuedBytes - bytes);\n }\n }\n\n private shouldRotate(nextBytes: number): boolean {\n return this.currentBytes > 0 && nextBytes > this.maxFileBytes - this.currentBytes;\n }\n\n private async rotate(): Promise<void> {\n await this.closeHandle();\n this.rotationIndex += 1;\n const rotatedPath = join(this.logDir, `${this.prefix}-${this.rotationIndex}.log`);\n await rename(this.currentPath, rotatedPath);\n this.currentFileCreated = false;\n this.currentBytes = 0;\n await this.openCurrentFile();\n }\n\n private async openCurrentFile(): Promise<void> {\n if (this.handle) return;\n await this.prepareStorage();\n const handle = await open(\n this.currentPath,\n this.currentFileCreated ? \"a\" : \"ax\",\n PRIVATE_FILE_MODE,\n );\n this.currentFileCreated = true;\n try {\n const stats = await handle.stat();\n this.currentBytes = stats.size;\n if (process.platform !== \"win32\") await chmod(this.currentPath, PRIVATE_FILE_MODE);\n } catch (error) {\n await handle.close().catch(() => undefined);\n throw error;\n }\n this.handle = handle;\n await this.pruneLogs();\n }\n\n private async prepareStorage(): Promise<void> {\n if (this.storagePrepared) return;\n await mkdir(this.logDir, { recursive: true, mode: PRIVATE_DIR_MODE });\n if (process.platform !== \"win32\") await chmod(this.logDir, PRIVATE_DIR_MODE);\n await this.restrictExistingLogs();\n this.storagePrepared = true;\n }\n\n private async restrictExistingLogs(): Promise<void> {\n if (process.platform === \"win32\") return;\n const entries = await readdir(this.logDir, { withFileTypes: true });\n await Promise.all(\n entries\n .filter((entry) => entry.isFile() && isManagedLog(entry.name))\n .map((entry) =>\n chmod(join(this.logDir, entry.name), PRIVATE_FILE_MODE).catch((error) => {\n this.reportWriteFailure(error);\n }),\n ),\n );\n }\n\n private async pruneLogs(): Promise<void> {\n let files: ManagedLogFile[];\n try {\n files = await this.managedLogs();\n } catch (error) {\n this.reportWriteFailure(error);\n return;\n }\n\n const now = Date.now();\n for (const file of files) {\n if (!file.isProtected && now - file.mtimeMs > this.maxAgeMs) {\n if (await this.removeLog(file)) files = files.filter((item) => item.path !== file.path);\n }\n }\n\n let totalBytes = files.reduce((total, file) => total + file.bytes, 0);\n let totalFiles = files.length;\n const candidates = files\n .filter((file) => !file.isProtected)\n .toSorted(\n (left, right) => left.mtimeMs - right.mtimeMs || left.name.localeCompare(right.name),\n );\n for (const file of candidates) {\n if (totalFiles <= this.maxFiles && totalBytes <= this.maxDirectoryBytes) break;\n if (!(await this.removeLog(file))) continue;\n totalFiles -= 1;\n totalBytes = Math.max(0, totalBytes - file.bytes);\n }\n }\n\n private async managedLogs(): Promise<ManagedLogFile[]> {\n const entries = await readdir(this.logDir, { withFileTypes: true });\n const files: ManagedLogFile[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !isManagedLog(entry.name)) continue;\n const path = join(this.logDir, entry.name);\n try {\n const stats = await lstat(path);\n if (!stats.isFile()) continue;\n const pid = activeLogPid(entry.name);\n files.push({\n name: entry.name,\n path,\n bytes: stats.size,\n mtimeMs: stats.mtimeMs,\n isProtected:\n path === this.currentPath ||\n ORIGINAL_ACTIVE_LOG_PATTERN.test(entry.name) ||\n (pid != null && isProcessAlive(pid)),\n });\n } catch (error) {\n if (errorCode(error) !== \"ENOENT\") this.reportWriteFailure(error);\n }\n }\n return files;\n }\n\n private async removeLog(file: ManagedLogFile): Promise<boolean> {\n try {\n await unlink(file.path);\n return true;\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return true;\n this.reportWriteFailure(error);\n return false;\n }\n }\n\n private async finishClose(): Promise<void> {\n await this.flush();\n await this.closeHandle();\n if (this.storagePrepared) await this.pruneLogs();\n }\n\n private async closeHandle(): Promise<void> {\n const handle = this.handle;\n this.handle = null;\n if (!handle) return;\n try {\n await handle.close();\n } catch (error) {\n this.reportWriteFailure(error);\n }\n }\n\n private reportWriteFailure(error: unknown): void {\n if (this.writeFailureReported) return;\n this.writeFailureReported = true;\n const message = error instanceof Error ? error.message : String(error);\n this.writeStderr(`Failed to write log ${this.currentPath}: ${message}`);\n }\n\n private discardPending(): void {\n this.queue.splice(0);\n this.queuedBytes = 0;\n this.dropped = emptyDropCounts();\n }\n\n private writeStderr(message: string): void {\n try {\n process.stderr.write(`[codesesh] ${message}\\n`);\n } catch {}\n }\n}\n","import { createHmac, type BinaryLike } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { types } from \"node:util\";\nimport { AGENT_CATALOG } from \"@codesesh/core/contract\";\nimport type { WorkerLogContext, WorkerLogLevel } from \"@codesesh/core/runtime/diagnostics\";\n\nexport const LOG_SCHEMA_VERSION = 1;\nexport const MIN_LOG_RECORD_BYTES = 512;\n\nconst MAX_ARRAY_ITEMS = 50;\nconst MAX_OBJECT_FIELDS = 100;\nconst MAX_DEPTH = 5;\nconst MAX_STRING_LENGTH = 4_000;\nconst MAX_SANITIZED_VALUES = 1_000;\nconst REDACTED_VALUE = \"[redacted]\";\nconst OMITTED_VALUE = \"[omitted]\";\nconst TRUNCATED_VALUE = \"[truncated]\";\nconst UNSERIALIZABLE_VALUE = \"[unserializable]\";\nconst ACCESSOR_VALUE = \"[accessor]\";\nconst CIRCULAR_VALUE = \"[circular]\";\nconst SAFE_SENTINELS = new Set([\n ACCESSOR_VALUE,\n CIRCULAR_VALUE,\n OMITTED_VALUE,\n REDACTED_VALUE,\n TRUNCATED_VALUE,\n UNSERIALIZABLE_VALUE,\n]);\nconst LOG_CONTEXT_KEYS = new Set<keyof WorkerLogContext>([\n \"request_id\",\n \"operation_id\",\n \"publication_id\",\n]);\nconst CORRELATION_ID_KEYS = new Set([...LOG_CONTEXT_KEYS, \"connection_id\"]);\n\nconst SENSITIVE_KEYS = new Set([\n \"access_token\",\n \"api_key\",\n \"apikey\",\n \"authorization\",\n \"client_secret\",\n \"cookie\",\n \"credential\",\n \"credentials\",\n \"id_token\",\n \"passphrase\",\n \"passwd\",\n \"password\",\n \"private_key\",\n \"refresh_token\",\n \"secret\",\n \"set_cookie\",\n \"token\",\n]);\n\nconst OMITTED_KEYS = new Set([\n \"argv\",\n \"body\",\n \"command_args\",\n \"content\",\n \"env\",\n \"environment\",\n \"headers\",\n \"http_body\",\n \"message\",\n \"messages\",\n \"prompt\",\n \"prompts\",\n \"request_body\",\n \"response_body\",\n \"stderr\",\n \"stdout\",\n \"tool_output\",\n \"tool_outputs\",\n \"transcript\",\n \"transcripts\",\n]);\n\nconst IDENTIFIER_KEYS = new Set([\n \"cursor\",\n \"message_cursor\",\n \"request_key\",\n \"session\",\n \"session_id\",\n]);\nconst ERROR_TEXT_KEYS = new Set([\"cause\", \"error\"]);\nconst KNOWN_AGENT_NAMES = new Set<string>(AGENT_CATALOG.map(({ name }) => name));\nconst HTTP_METHODS = new Set([\"DELETE\", \"GET\", \"HEAD\", \"OPTIONS\", \"PATCH\", \"POST\", \"PUT\"]);\nconst AUDITED_STRING_VALUES = new Map<string, ReadonlySet<string>>([\n [\n \"mode\",\n new Set([\n \"agent\",\n \"bulk\",\n \"incremental\",\n \"invalidRoute\",\n \"missingAgent\",\n \"project\",\n \"projects\",\n \"root\",\n \"session\",\n ]),\n ],\n [\"phase\", new Set([\"measure\", \"mount\", \"nested-update\", \"update\"])],\n [\n \"profiler_id\",\n new Set([\n \"App\",\n \"InteractiveReceipt\",\n \"MainContent\",\n \"MessageList\",\n \"OverviewScreen\",\n \"SearchControls\",\n \"SearchResultsPanel\",\n \"SessionDetail\",\n \"SessionTreeSidebar\",\n ]),\n ],\n [\"source\", new Set([\"commit-latency\", \"custom-timing\", \"react-profiler\"])],\n [\"trigger\", new Set([\"route\"])],\n [\"reason\", new Set([\"query-cancelled\"])],\n [\"exception_origin\", new Set([\"uncaughtException\", \"unhandledRejection\"])],\n]);\nconst INTERNAL_PLAINTEXT_KEYS = new Set([\n \"authentication\",\n \"bind_category\",\n \"cache\",\n \"close_reason\",\n \"context\",\n \"encoding\",\n \"endpoint\",\n \"event\",\n \"exception_origin\",\n \"failure_stage\",\n \"field\",\n \"indexes\",\n \"label\",\n \"loopback_authority\",\n \"message_update\",\n \"operation\",\n \"outcome\",\n \"parameter\",\n \"persistent_index_worker_job\",\n \"publication_completeness\",\n \"query_keys\",\n \"request_type\",\n \"result\",\n \"route\",\n \"signal\",\n \"stage\",\n \"state\",\n \"status\",\n \"transport\",\n \"update\",\n \"validation_outcome\",\n \"version\",\n \"worker_level\",\n]);\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst FINGERPRINT_TOKEN_PATTERN =\n /^(?:error_message|field|identifier|path|string|url):[a-f0-9]{16}$/;\n\nconst PATH_KEY_PATTERN = /(?:^|_)(?:cwd|directory|file|path|root)$/;\nconst URL_KEY_PATTERN = /(?:^|_)(?:origin|url)$/;\nconst SENSITIVE_KEY_SUFFIX_PATTERN =\n /(?:^|_)(?:api_key|authorization|cookie|credential|credentials|passphrase|passwd|password|private_key|secret|token)$/;\nconst BEARER_PATTERN = /\\bBearer\\s+[^\\s,;]+/gi;\nconst JWT_PATTERN = /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g;\nconst SECRET_QUERY_PATTERN =\n /([?&](?:access_token|api_key|apikey|password|secret|token)=)[^&#\\s]*/gi;\nconst PRIVATE_KEY_PATTERN =\n /-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z ]*PRIVATE KEY-----/g;\nconst INCOMPLETE_PRIVATE_KEY_PATTERN = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*$/g;\nconst INCOMPLETE_JWT_PATTERN = /\\beyJ[A-Za-z0-9_-]*(?:\\.[A-Za-z0-9_-]*){0,2}$/g;\nconst LINE_BREAK_PATTERN = /\\r\\n|[\\n\\r]/;\n\ninterface SanitizationBudget {\n remainingValues: number;\n remainingCharacters: number;\n}\n\ninterface PersonalPrefixReplacement {\n prefix: string;\n replacement: string;\n pattern?: RegExp;\n}\n\nexport interface EncodedLogLine {\n line: string;\n bytes: number;\n level: WorkerLogLevel;\n}\n\nexport interface LogRecordInput {\n timestamp: string;\n level: WorkerLogLevel;\n event: string;\n runId: string;\n sequence: number;\n pid: number;\n threadId?: number;\n context?: WorkerLogContext;\n data: Record<string, unknown>;\n}\n\ninterface LogRecordEncoderOptions {\n fingerprintKey: BinaryLike;\n maxRecordBytes: number;\n currentWorkingDirectory?: string;\n homeDirectory?: string;\n}\n\nfunction normalizedKey(key: string): string {\n return key\n .trim()\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .toLowerCase();\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEYS.has(key) || SENSITIVE_KEY_SUFFIX_PATTERN.test(key);\n}\n\nfunction isIdentifierKey(key: string): boolean {\n return (\n !CORRELATION_ID_KEYS.has(key) &&\n (IDENTIFIER_KEYS.has(key) || /(?:^|_)(?:cursor|id|request_key|session_id)$/.test(key))\n );\n}\n\nfunction isAuditedString(key: string, value: string): boolean {\n if (\n (key === \"agent\" || key === \"agent_name\" || key === \"agents\" || key === \"failed_agents\") &&\n KNOWN_AGENT_NAMES.has(value)\n ) {\n return true;\n }\n if (key === \"method\" && HTTP_METHODS.has(value)) return true;\n return AUDITED_STRING_VALUES.get(key)?.has(value) === true;\n}\n\nfunction windowsPathPattern(value: string): RegExp | undefined {\n if (!/^(?:[a-z]:[\\\\/]|\\\\\\\\)/i.test(value)) return undefined;\n const pattern = value\n .split(/[\\\\/]+/)\n .map((segment) => segment.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"))\n .join(\"[\\\\\\\\/]+\");\n return new RegExp(pattern, \"gi\");\n}\n\nexport class LogRecordEncoder {\n private readonly fingerprintKey: BinaryLike;\n private readonly maxRecordBytes: number;\n private readonly personalPrefixes: PersonalPrefixReplacement[];\n\n constructor(options: LogRecordEncoderOptions) {\n this.fingerprintKey = options.fingerprintKey;\n this.maxRecordBytes = Math.max(\n MIN_LOG_RECORD_BYTES,\n Number.isFinite(options.maxRecordBytes) ? Math.floor(options.maxRecordBytes) : 0,\n );\n const personalPrefixes: Array<[string, string]> = [\n [options.currentWorkingDirectory ?? process.cwd(), \"<cwd>\"],\n [options.homeDirectory ?? homedir(), \"~\"],\n ];\n this.personalPrefixes = personalPrefixes\n .toSorted(([left], [right]) => right.length - left.length)\n .map(([prefix, replacement]) => ({\n prefix,\n replacement,\n pattern: windowsPathPattern(prefix),\n }));\n }\n\n encode(input: LogRecordInput): EncodedLogLine {\n const budget = this.createSanitizationBudget();\n const trustedCorrelationIds = !input.event.startsWith(\"client.\");\n const fixed = {\n schema_version: LOG_SCHEMA_VERSION,\n ts: input.timestamp,\n level: input.level,\n event: this.sanitizeEvent(input.event, budget),\n run_id: input.runId,\n seq: input.sequence,\n pid: input.pid,\n ...(input.threadId == null ? {} : { thread_id: input.threadId }),\n };\n const context = this.sanitizeContext(input.context, trustedCorrelationIds, budget);\n const data = this.sanitizeFields(input.data, trustedCorrelationIds, budget);\n const line = `${JSON.stringify({ ...data, ...context, ...fixed })}\\n`;\n const bytes = Buffer.byteLength(line);\n if (bytes <= this.maxRecordBytes) return { line, bytes, level: input.level };\n\n const truncatedLine = `${JSON.stringify({\n ...context,\n ...fixed,\n record_truncated: true,\n original_bytes: bytes,\n })}\\n`;\n const truncatedBytes = Buffer.byteLength(truncatedLine);\n if (truncatedBytes <= this.maxRecordBytes) {\n return { line: truncatedLine, bytes: truncatedBytes, level: input.level };\n }\n\n const minimalLine = `${JSON.stringify({\n schema_version: LOG_SCHEMA_VERSION,\n ts: input.timestamp.slice(0, 40).replace(/[^0-9TZ:.-]/g, \"_\"),\n level: input.level,\n event: fixed.event.slice(0, 64),\n record_truncated: true,\n original_bytes: bytes,\n })}\\n`;\n return {\n line: minimalLine,\n bytes: Buffer.byteLength(minimalLine),\n level: input.level,\n };\n }\n\n sanitizeForTransport(data: Record<string, unknown>, event = \"\"): Record<string, unknown> {\n const sanitized = this.sanitizeFields(\n data,\n !event.startsWith(\"client.\"),\n this.createSanitizationBudget(),\n );\n const bytes = Buffer.byteLength(JSON.stringify(sanitized));\n return bytes <= this.maxRecordBytes\n ? sanitized\n : { transport_truncated: true, original_bytes: bytes };\n }\n\n private sanitizeFields(\n data: Record<string, unknown>,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): Record<string, unknown> {\n const normalized = this.sanitizeValue(\n data,\n \"\",\n 0,\n new WeakSet(),\n trustedCorrelationIds,\n budget,\n );\n return normalized && typeof normalized === \"object\" && !Array.isArray(normalized)\n ? (normalized as Record<string, unknown>)\n : { diagnostic_data: normalized };\n }\n\n private sanitizeValue(\n value: unknown,\n key: string,\n depth: number,\n ancestors: WeakSet<object>,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): unknown {\n if (budget.remainingValues <= 0 || budget.remainingCharacters <= 0) return TRUNCATED_VALUE;\n budget.remainingValues -= 1;\n\n const normalized = normalizedKey(this.takeKeyInput(key, budget));\n if (isSensitiveKey(normalized)) return REDACTED_VALUE;\n if (ERROR_TEXT_KEYS.has(normalized) && typeof value === \"string\") {\n return this.fingerprint(\"error_message\", value, budget);\n }\n if (\n OMITTED_KEYS.has(normalized) &&\n value != null &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n return OMITTED_VALUE;\n }\n const valueType = typeof value;\n if (\n (valueType === \"function\" || (valueType === \"object\" && value !== null)) &&\n types.isProxy(value)\n ) {\n return UNSERIALIZABLE_VALUE;\n }\n if (value == null || typeof value === \"boolean\") return value;\n if (typeof value === \"number\") {\n if (Number.isFinite(value)) return value;\n return value === Number.POSITIVE_INFINITY\n ? \"Infinity\"\n : value === Number.NEGATIVE_INFINITY\n ? \"-Infinity\"\n : \"NaN\";\n }\n if (typeof value === \"bigint\") {\n return this.sanitizeString(value.toString(), normalized, budget, trustedCorrelationIds);\n }\n if (typeof value === \"string\") {\n if (normalized === \"stack\") return this.sanitizeStack(value, budget);\n return this.sanitizeString(value, normalized, budget, trustedCorrelationIds);\n }\n if (typeof value !== \"object\") return OMITTED_VALUE;\n if (depth >= MAX_DEPTH) return TRUNCATED_VALUE;\n if (ArrayBuffer.isView(value) || types.isAnyArrayBuffer(value)) {\n return OMITTED_VALUE;\n }\n if (ancestors.has(value)) return CIRCULAR_VALUE;\n\n ancestors.add(value);\n try {\n if (types.isDate(value)) {\n const timestamp = Date.prototype.getTime.call(value);\n return Number.isNaN(timestamp)\n ? this.takeLiteral(\"Invalid Date\", budget)\n : this.takeLiteral(Date.prototype.toISOString.call(value), budget);\n }\n const url = this.urlString(value);\n if (url != null) {\n return this.sanitizeString(url, \"url\", budget, trustedCorrelationIds);\n }\n if (types.isNativeError(value)) {\n return this.sanitizeError(value, depth, ancestors, trustedCorrelationIds, budget);\n }\n if (Array.isArray(value)) {\n return this.sanitizeArray(value, key, depth, ancestors, trustedCorrelationIds, budget);\n }\n if (types.isMap(value)) {\n const result: unknown[] = [];\n for (const [mapKey, item] of Map.prototype.entries.call(value)) {\n result.push([\n this.sanitizeValue(mapKey, \"key\", depth + 1, ancestors, trustedCorrelationIds, budget),\n this.sanitizeValue(item, key, depth + 1, ancestors, trustedCorrelationIds, budget),\n ]);\n if (\n result.length >= MAX_ARRAY_ITEMS ||\n budget.remainingValues <= 0 ||\n budget.remainingCharacters <= 0\n ) {\n break;\n }\n }\n return result;\n }\n if (types.isSet(value)) {\n const result: unknown[] = [];\n for (const item of Set.prototype.values.call(value)) {\n result.push(\n this.sanitizeValue(item, key, depth + 1, ancestors, trustedCorrelationIds, budget),\n );\n if (\n result.length >= MAX_ARRAY_ITEMS ||\n budget.remainingValues <= 0 ||\n budget.remainingCharacters <= 0\n ) {\n break;\n }\n }\n return result;\n }\n return this.sanitizeObject(value, depth, ancestors, trustedCorrelationIds, budget);\n } catch {\n return UNSERIALIZABLE_VALUE;\n } finally {\n ancestors.delete(value);\n }\n }\n\n private sanitizeObject(\n value: object,\n depth: number,\n ancestors: WeakSet<object>,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): Record<string, unknown> | string {\n let keys: string[];\n try {\n keys = Object.getOwnPropertyNames(value).slice(0, MAX_OBJECT_FIELDS);\n } catch {\n return UNSERIALIZABLE_VALUE;\n }\n\n const result: Record<string, unknown> = {};\n for (const key of keys) {\n let descriptor: PropertyDescriptor | undefined;\n try {\n descriptor = Object.getOwnPropertyDescriptor(value, key);\n } catch {\n result[this.boundedFieldName(key, budget)] = UNSERIALIZABLE_VALUE;\n if (budget.remainingCharacters <= 0) break;\n continue;\n }\n if (!descriptor) continue;\n\n result[this.boundedFieldName(key, budget)] =\n \"value\" in descriptor\n ? this.sanitizeValue(\n descriptor.value,\n key,\n depth + 1,\n ancestors,\n trustedCorrelationIds,\n budget,\n )\n : ACCESSOR_VALUE;\n if (budget.remainingValues <= 0 || budget.remainingCharacters <= 0) break;\n }\n return result;\n }\n\n private sanitizeArray(\n value: unknown[],\n key: string,\n depth: number,\n ancestors: WeakSet<object>,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): unknown[] {\n const lengthDescriptor = Object.getOwnPropertyDescriptor(value, \"length\");\n const length =\n lengthDescriptor && \"value\" in lengthDescriptor && typeof lengthDescriptor.value === \"number\"\n ? Math.min(lengthDescriptor.value, MAX_ARRAY_ITEMS)\n : 0;\n const result: unknown[] = [];\n for (let index = 0; index < length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index));\n result.push(\n !descriptor\n ? null\n : \"value\" in descriptor\n ? this.sanitizeValue(\n descriptor.value,\n key,\n depth + 1,\n ancestors,\n trustedCorrelationIds,\n budget,\n )\n : ACCESSOR_VALUE,\n );\n if (budget.remainingValues <= 0 || budget.remainingCharacters <= 0) break;\n }\n return result;\n }\n\n private sanitizeError(\n error: Error,\n depth: number,\n ancestors: WeakSet<object>,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): Record<string, unknown> {\n const code = this.errorProperty(error, \"code\");\n const cause = this.errorProperty(error, \"cause\");\n const message = this.errorStringProperty(error, \"message\", \"\");\n const stack = this.errorStringProperty(error, \"stack\", \"\");\n return {\n name: this.sanitizeString(\n this.errorStringProperty(error, \"name\", \"Error\"),\n \"name\",\n budget,\n trustedCorrelationIds,\n ),\n message_fingerprint: this.fingerprint(\"error_message\", message, budget),\n stack: this.sanitizeStack(stack, budget),\n ...(code == null\n ? {}\n : {\n code: this.sanitizeValue(\n code,\n \"code\",\n depth + 1,\n ancestors,\n trustedCorrelationIds,\n budget,\n ),\n }),\n ...(cause == null\n ? {}\n : {\n cause: this.sanitizeValue(\n cause,\n \"cause\",\n depth + 1,\n ancestors,\n trustedCorrelationIds,\n budget,\n ),\n }),\n };\n }\n\n private errorProperty(error: Error, key: string): unknown {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(error, key);\n if (!descriptor) return undefined;\n return \"value\" in descriptor ? descriptor.value : ACCESSOR_VALUE;\n } catch {\n return UNSERIALIZABLE_VALUE;\n }\n }\n\n private errorStringProperty(error: Error, key: string, fallback: string): string {\n const value = this.errorProperty(error, key);\n return value == null ? fallback : typeof value === \"string\" ? value : UNSERIALIZABLE_VALUE;\n }\n\n private urlString(value: object): string | undefined {\n try {\n return URL.prototype.toString.call(value);\n } catch {\n return undefined;\n }\n }\n\n private createSanitizationBudget(): SanitizationBudget {\n return {\n remainingValues: MAX_SANITIZED_VALUES,\n remainingCharacters: Math.max(0, Math.floor(this.maxRecordBytes)),\n };\n }\n\n private sanitizeContext(\n context: WorkerLogContext | undefined,\n trustedCorrelationIds: boolean,\n budget: SanitizationBudget,\n ): WorkerLogContext {\n if (!context) return {};\n return Object.fromEntries(\n Object.entries(context).flatMap(([key, value]) =>\n LOG_CONTEXT_KEYS.has(key as keyof WorkerLogContext) &&\n typeof value === \"string\" &&\n value.length > 0\n ? [\n [\n key,\n this.sanitizeString(value, normalizedKey(key), budget, trustedCorrelationIds).slice(\n 0,\n 160,\n ),\n ],\n ]\n : [],\n ),\n );\n }\n\n private sanitizeEvent(event: string, budget: SanitizationBudget): string {\n return this.takePrefix(event, budget)\n .trim()\n .replace(/[^a-zA-Z0-9_.:-]/g, \"_\")\n .slice(0, 160);\n }\n\n private sanitizeString(\n value: string,\n key: string,\n budget: SanitizationBudget,\n trustedCorrelationIds = false,\n ): string {\n if (FINGERPRINT_TOKEN_PATTERN.test(value) || SAFE_SENTINELS.has(value)) {\n return this.takeLiteral(value, budget);\n }\n if (CORRELATION_ID_KEYS.has(key)) {\n return trustedCorrelationIds || UUID_PATTERN.test(value)\n ? this.takeLiteral(value, budget)\n : this.fingerprint(\"identifier\", value, budget);\n }\n if (isAuditedString(key, value)) return this.takeLiteral(value, budget);\n if (isIdentifierKey(key)) return this.fingerprint(\"identifier\", value, budget);\n if (trustedCorrelationIds && INTERNAL_PLAINTEXT_KEYS.has(key)) {\n const bounded = this.takePrefix(value, budget);\n return this.sanitizeBoundedString(bounded, key, bounded.length < value.length);\n }\n if (PATH_KEY_PATTERN.test(key)) return this.fingerprint(\"path\", value, budget);\n if (\n URL_KEY_PATTERN.test(key) &&\n value.length > Math.min(MAX_STRING_LENGTH, budget.remainingCharacters)\n ) {\n return this.fingerprint(\"url\", value, budget);\n }\n if (URL_KEY_PATTERN.test(key)) {\n const bounded = this.takePrefix(value, budget);\n return this.sanitizeBoundedString(bounded, key, bounded.length < value.length);\n }\n return this.fingerprint(\"string\", value, budget);\n }\n\n private takeLiteral(value: string, budget: SanitizationBudget): string {\n if (value.length > budget.remainingCharacters) return TRUNCATED_VALUE;\n budget.remainingCharacters -= value.length;\n return value;\n }\n\n private sanitizeStack(value: string, budget: SanitizationBudget): string {\n const bounded = this.takePrefix(value, budget);\n const inputTruncated = bounded.length < value.length;\n const startsWithFrame = /^\\s*at(?:\\s|$)/.test(bounded);\n const lineBreak = LINE_BREAK_PATTERN.exec(bounded);\n if (!startsWithFrame && !lineBreak) return inputTruncated ? TRUNCATED_VALUE : \"\";\n\n const stackBody = startsWithFrame\n ? bounded\n : bounded.slice(lineBreak!.index + lineBreak![0].length);\n const sanitized = this.sanitizeBoundedString(stackBody, \"stack\", inputTruncated);\n return inputTruncated && !sanitized.endsWith(TRUNCATED_VALUE)\n ? `${sanitized}[truncated]`\n : sanitized;\n }\n\n private sanitizeBoundedString(value: string, key: string, inputTruncated: boolean): string {\n let sanitized = value\n .replace(PRIVATE_KEY_PATTERN, REDACTED_VALUE)\n .replace(BEARER_PATTERN, `Bearer ${REDACTED_VALUE}`)\n .replace(JWT_PATTERN, REDACTED_VALUE)\n .replace(SECRET_QUERY_PATTERN, `$1${REDACTED_VALUE}`);\n if (inputTruncated) {\n sanitized = sanitized\n .replace(INCOMPLETE_PRIVATE_KEY_PATTERN, REDACTED_VALUE)\n .replace(INCOMPLETE_JWT_PATTERN, REDACTED_VALUE);\n }\n if (URL_KEY_PATTERN.test(key)) sanitized = this.sanitizeUrl(sanitized);\n sanitized = this.replacePersonalPrefixes(sanitized);\n return !inputTruncated && sanitized.length <= MAX_STRING_LENGTH\n ? sanitized\n : `${sanitized.slice(0, MAX_STRING_LENGTH)}[truncated]`;\n }\n\n private takePrefix(value: string, budget: SanitizationBudget): string {\n const length = Math.min(value.length, MAX_STRING_LENGTH, budget.remainingCharacters);\n budget.remainingCharacters -= length;\n return value.slice(0, length);\n }\n\n private takeKeyInput(key: string, budget: SanitizationBudget): string {\n const length = Math.min(key.length, MAX_STRING_LENGTH, budget.remainingCharacters);\n budget.remainingCharacters -= length;\n if (length >= key.length) return key;\n if (length === 0) return \"\";\n if (length < 3) return key.slice(-length);\n\n const contentLength = length - 1;\n const prefixLength = Math.ceil(contentLength / 2);\n return `${key.slice(0, prefixLength)}_${key.slice(-(contentLength - prefixLength))}`;\n }\n\n private boundedFieldName(key: string, budget: SanitizationBudget): string {\n if (key.length <= MAX_STRING_LENGTH && key.length <= budget.remainingCharacters) {\n budget.remainingCharacters -= key.length;\n return key;\n }\n return this.fingerprint(\"field\", key, budget);\n }\n\n private sanitizeUrl(value: string): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return OMITTED_VALUE;\n }\n return url.origin === \"null\" ? OMITTED_VALUE : `${url.origin}/`;\n }\n\n private replacePersonalPrefixes(value: string): string {\n return this.personalPrefixes.reduce(\n (text, { prefix, replacement, pattern }) =>\n pattern ? text.replace(pattern, replacement) : text.split(prefix).join(replacement),\n value,\n );\n }\n\n private fingerprint(kind: string, value: string, budget: SanitizationBudget): string {\n if (FINGERPRINT_TOKEN_PATTERN.test(value)) return this.takeLiteral(value, budget);\n const suffix = `\\0${value.length}`;\n const contentLength = MAX_STRING_LENGTH - suffix.length;\n const prefixLength = Math.ceil(contentLength / 2);\n const bounded =\n value.length <= MAX_STRING_LENGTH\n ? value\n : `${value.slice(0, prefixLength)}${value.slice(-(contentLength - prefixLength))}${suffix}`;\n if (bounded.length > budget.remainingCharacters) return TRUNCATED_VALUE;\n budget.remainingCharacters -= bounded.length;\n const digest = createHmac(\"sha256\", this.fingerprintKey)\n .update(bounded)\n .digest(\"hex\")\n .slice(0, 16);\n return `${kind}:${digest}`;\n }\n}\n","import { setCoreDiagnostics } from \"@codesesh/core/runtime/diagnostics\";\nimport { parentPort, threadId } from \"node:worker_threads\";\nimport { appLogger } from \"./logging.js\";\n\n/**\n * Bridges core's diagnostics sink to appLogger. Import this once, for its\n * side effect, from every entry point that gets its own module graph — the\n * main CLI thread and each worker_threads script (scan-refresh-worker,\n * search-index-worker, smart-tag-worker) — since core's module-level\n * diagnostics singleton is per-thread, not shared across workers.\n */\nif (parentPort) appLogger.forwardToParent(parentPort, threadId);\n\nsetCoreDiagnostics({\n info(event, detail) {\n appLogger.info(event, detail);\n },\n warn(event, detail) {\n appLogger.warn(event, detail);\n },\n});\n"],"mappings":"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","names":["homedir","join","UUID_PATTERN","LOG_CONTEXT_KEYS","join","homedir","threadId"]}
@@ -4,16 +4,17 @@ import {
4
4
  computeIdentity,
5
5
  computeIdentityProjection,
6
6
  filterSessionsByProjectScope,
7
+ matchesProjectScope,
7
8
  normalizeProjectDirectory,
8
9
  normalizeProjectScopePath,
9
10
  realFs
10
- } from "./chunk-3SXCTDD6.js";
11
+ } from "./chunk-XKZSX5BM.js";
11
12
  import {
12
13
  SessionScanError,
13
14
  createAgentScanFailure,
14
15
  createRegisteredAgents,
15
16
  reportAgentScanFailure
16
- } from "./chunk-YCUN52HA.js";
17
+ } from "./chunk-WUYSZAYR.js";
17
18
  import {
18
19
  SMART_TAG_CLASSIFIER_REVISION,
19
20
  assertIdentifiedSessionHead,
@@ -40,12 +41,12 @@ import {
40
41
  setUserVersion,
41
42
  sortSessionsByActivity,
42
43
  tableExists
43
- } from "./chunk-W4PZHL2C.js";
44
+ } from "./chunk-NBJJGH5P.js";
44
45
 
45
46
  // ../core/dist/chunk-XGIUX4DD.mjs
46
47
  var CACHE_SCHEMA_VERSION = 32;
47
48
 
48
- // ../core/dist/chunk-A6L44WG2.mjs
49
+ // ../core/dist/chunk-5XQWZQGH.mjs
49
50
  import { existsSync } from "fs";
50
51
  import { join } from "path";
51
52
  import { homedir } from "os";
@@ -60,6 +61,11 @@ function getCacheConnection(path) {
60
61
  if (cached) return cached;
61
62
  const db = openDb(path);
62
63
  if (!db) return null;
64
+ db.function(
65
+ "codesesh_project_scope_path",
66
+ { deterministic: true },
67
+ (directory) => normalizeProjectScopePath(String(directory ?? ""))
68
+ );
63
69
  const connection = { db, ftsReady: false, publicationStagingCleaned: false };
64
70
  cacheConnections.set(path, connection);
65
71
  return connection;
@@ -1220,8 +1226,12 @@ function runSearchIndexWrite(db, rebuild, write, transaction = "immediate") {
1220
1226
  let rebuildDurationMs;
1221
1227
  if (rebuild) {
1222
1228
  const rebuildStartedAt = performance.now();
1229
+ getCoreDiagnostics()?.info?.("search_index.fts_rebuild.started");
1223
1230
  rebuildSearchIndex(db);
1224
1231
  rebuildDurationMs = performance.now() - rebuildStartedAt;
1232
+ getCoreDiagnostics()?.info?.("search_index.fts_rebuild.completed", {
1233
+ duration_ms: Math.round(rebuildDurationMs)
1234
+ });
1225
1235
  createSearchTriggers(db);
1226
1236
  }
1227
1237
  return { value, rebuildDurationMs };
@@ -2697,12 +2707,13 @@ var SEARCH_INDEX_COMMIT_CHUNK_SIZE = 64;
2697
2707
  function createSearchIndexLoadTiming() {
2698
2708
  return { calls: 0, reused: 0, getSessionDataMs: 0, materializationMs: 0 };
2699
2709
  }
2700
- function shouldBulkSyncSearchIndex(options, changedCount) {
2710
+ function shouldBulkSyncSearchIndex(db, options, changedCount) {
2701
2711
  if (options.isBulk != null) {
2702
2712
  return options.isBulk;
2703
2713
  }
2704
2714
  const threshold = options.bulkThreshold ?? SEARCH_INDEX_BULK_SYNC_THRESHOLD;
2705
- return threshold > 0 && changedCount >= threshold;
2715
+ if (!(threshold > 0 && changedCount >= threshold)) return false;
2716
+ return options.bulkThreshold != null || db.prepare("SELECT 1 FROM session_documents LIMIT 1").get() === void 0;
2706
2717
  }
2707
2718
  function loadSearchIndexEntry(agentName, change, loadSessionData, detailVersion, failures, timing) {
2708
2719
  const sessionId = change.session.reference.sessionId;
@@ -2966,7 +2977,8 @@ function readSearchIndexPlanInput(db, agentName, request, options) {
2966
2977
  startedAt
2967
2978
  };
2968
2979
  }
2969
- function createSearchIndexPlan(input) {
2980
+ function planSearchIndexWrite(db, agentName, request, options) {
2981
+ const input = readSearchIndexPlanInput(db, agentName, request, options);
2970
2982
  const changes = input.candidates.filter(
2971
2983
  ({ session }) => searchIndexEntryNeedsUpdate(input.state, session, input.options)
2972
2984
  );
@@ -2987,7 +2999,7 @@ function createSearchIndexPlan(input) {
2987
2999
  })
2988
3000
  );
2989
3001
  const changedCount = input.removedSessionIds.length + changes.length;
2990
- const isBulk = shouldBulkSyncSearchIndex(input.options, changedCount);
3002
+ const isBulk = shouldBulkSyncSearchIndex(db, input.options, changedCount);
2991
3003
  return {
2992
3004
  agentName: input.agentName,
2993
3005
  mode: isBulk ? "bulk" : "incremental",
@@ -3000,9 +3012,6 @@ function createSearchIndexPlan(input) {
3000
3012
  startedAt: input.startedAt
3001
3013
  };
3002
3014
  }
3003
- function planSearchIndexWrite(db, agentName, request, options) {
3004
- return createSearchIndexPlan(readSearchIndexPlanInput(db, agentName, request, options));
3005
- }
3006
3015
  function detailVersionForPlan(plan, sessionId) {
3007
3016
  return plan.detailVersionBySessionId.get(sessionId) ?? sessionDetailVersion(null);
3008
3017
  }
@@ -3238,6 +3247,24 @@ function syncSessionSearchIndexChanges(agentName, changes, removedSessionIds, lo
3238
3247
  )
3239
3248
  );
3240
3249
  }
3250
+ function buildSessionQueryScopeFilters(scope) {
3251
+ const clauses = [];
3252
+ const params = [];
3253
+ if (scope?.agents?.length) {
3254
+ clauses.push(`s.agent_name IN (${scope.agents.map(() => "?").join(", ")})`);
3255
+ params.push(...scope.agents);
3256
+ }
3257
+ if (scope?.projectScope) {
3258
+ const project = scope.projectScope;
3259
+ const path = normalizeProjectScopePath(project.path);
3260
+ const directory = "codesesh_project_scope_path(s.directory)";
3261
+ clauses.push(
3262
+ `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR (s.directory <> '' AND (${directory} = ? OR instr(${directory}, ? || '/') = 1 OR instr(?, ${directory} || '/') = 1)))`
3263
+ );
3264
+ params.push(project.identity.kind, project.identity.key, path, path, path);
3265
+ }
3266
+ return { clauses, params };
3267
+ }
3241
3268
  function escapeFtsTerm(value) {
3242
3269
  return value.replaceAll('"', '""');
3243
3270
  }
@@ -3433,9 +3460,8 @@ function sessionMatchesSearchCost(session, options, cost = session.stats.total_c
3433
3460
  }
3434
3461
  return true;
3435
3462
  }
3436
- function buildSessionSearchFilters(options) {
3437
- const clauses = [];
3438
- const params = [];
3463
+ function buildSessionSearchFilters(options, queryScope) {
3464
+ const { clauses, params } = buildSessionQueryScopeFilters(queryScope);
3439
3465
  if (options.agent) {
3440
3466
  clauses.push("s.agent_name = ?");
3441
3467
  params.push(options.agent);
@@ -3449,18 +3475,9 @@ function buildSessionSearchFilters(options) {
3449
3475
  }
3450
3476
  }
3451
3477
  if (options.projectScope) {
3452
- const scopePath = normalizeProjectScopePath(options.projectScope.path).toLowerCase();
3453
- const normalizedDirectory = "REPLACE(LOWER(s.directory), char(92), '/')";
3454
- clauses.push(
3455
- `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR ${normalizedDirectory} = ? OR instr(${normalizedDirectory}, ? || '/') = 1 OR instr(?, ${normalizedDirectory} || '/') = 1)`
3456
- );
3457
- params.push(
3458
- options.projectScope.identity.kind,
3459
- options.projectScope.identity.key,
3460
- scopePath,
3461
- scopePath,
3462
- scopePath
3463
- );
3478
+ const project = buildSessionQueryScopeFilters({ projectScope: options.projectScope });
3479
+ clauses.push(...project.clauses);
3480
+ params.push(...project.params);
3464
3481
  }
3465
3482
  if (options.project) {
3466
3483
  clauses.push(
@@ -3758,14 +3775,14 @@ function rowsToSearchResults(db, rows, textQuery) {
3758
3775
  };
3759
3776
  });
3760
3777
  }
3761
- function searchSessions(query, options = {}) {
3778
+ function searchSessions(query, options = {}, queryScope) {
3762
3779
  const search = mergeSearchQueryOptions(query, options);
3763
3780
  const normalizedQuery = search.text.trim();
3764
3781
  if (!hasCacheStorage()) {
3765
3782
  return [];
3766
3783
  }
3767
3784
  const results = withSearchDb((db) => {
3768
- const filters = buildSessionSearchFilters(search.options);
3785
+ const filters = buildSessionSearchFilters(search.options, queryScope);
3769
3786
  if (!normalizedQuery) {
3770
3787
  const rows2 = db.prepare(
3771
3788
  `
@@ -3808,14 +3825,10 @@ function searchSessions(query, options = {}) {
3808
3825
  }
3809
3826
  function fileActivityFilters(options) {
3810
3827
  const path = options.path ? normalizeFilePathSearch(options.path) : "";
3811
- const scope = options.projectScope;
3812
3828
  return {
3813
3829
  projectKind: options.projectKind ?? null,
3814
3830
  projectKey: options.projectKey ?? null,
3815
3831
  projectLike: options.project ? likePattern(options.project) : null,
3816
- scopeKind: scope?.identity.kind ?? null,
3817
- scopeKey: scope?.identity.key ?? null,
3818
- scopePath: scope ? normalizeProjectScopePath(scope.path).toLowerCase() : null,
3819
3832
  path,
3820
3833
  pathLike: path ? likePattern(path) : null
3821
3834
  };
@@ -3833,10 +3846,9 @@ function fileActivityFromRow(row) {
3833
3846
  latestTime: Number(row.latest_time ?? 0)
3834
3847
  };
3835
3848
  }
3836
- function buildFileActivityWhere(options) {
3849
+ function buildFileActivityWhere(options, queryScope) {
3837
3850
  const filters = fileActivityFilters(options);
3838
- const clauses = [];
3839
- const params = [];
3851
+ const { clauses, params } = buildSessionQueryScopeFilters(queryScope);
3840
3852
  if (options.agent != null) {
3841
3853
  clauses.push("fa.agent_name = ?");
3842
3854
  params.push(options.agent);
@@ -3859,18 +3871,10 @@ function buildFileActivityWhere(options) {
3859
3871
  );
3860
3872
  params.push(filters.projectLike, filters.projectLike, filters.projectLike);
3861
3873
  }
3862
- if (filters.scopeKey != null && filters.scopePath != null) {
3863
- const normalizedDirectory = "REPLACE(LOWER(s.directory), char(92), '/')";
3864
- clauses.push(
3865
- `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR ${normalizedDirectory} = ? OR instr(${normalizedDirectory}, ? || '/') = 1 OR instr(?, ${normalizedDirectory} || '/') = 1)`
3866
- );
3867
- params.push(
3868
- filters.scopeKind,
3869
- filters.scopeKey,
3870
- filters.scopePath,
3871
- filters.scopePath,
3872
- filters.scopePath
3873
- );
3874
+ if (options.projectScope) {
3875
+ const project = buildSessionQueryScopeFilters({ projectScope: options.projectScope });
3876
+ clauses.push(...project.clauses);
3877
+ params.push(...project.params);
3874
3878
  }
3875
3879
  if (filters.pathLike != null) {
3876
3880
  const pathQuery = filePathFtsQuery(filters.path);
@@ -3935,11 +3939,11 @@ var FILE_ACTIVITY_JOIN = `
3935
3939
  AND s.publication_id IS NULL
3936
3940
  `;
3937
3941
  var FILE_ACTIVITY_ORDER = "fa.latest_time DESC, fa.count DESC, fa.path";
3938
- function listFileActivity(options = {}) {
3939
- return queryFileActivity(options);
3942
+ function listFileActivity(options = {}, queryScope) {
3943
+ return queryFileActivity({ options, queryScope });
3940
3944
  }
3941
3945
  function fileActivityWhere(query) {
3942
- const filters = buildFileActivityWhere(query.options);
3946
+ const filters = buildFileActivityWhere(query.options, query.queryScope);
3943
3947
  const sessionFilters = query.sessionSearchOptions ? buildSessionSearchFilters(query.sessionSearchOptions) : { where: "", params: [] };
3944
3948
  const clauses = [
3945
3949
  filters.where.replace(/^WHERE /, ""),
@@ -3982,11 +3986,11 @@ function fileActivitySql(query, where) {
3982
3986
  LIMIT ?
3983
3987
  `;
3984
3988
  }
3985
- function queryFileActivity(options, sessionSearchOptions, onePerSession = false) {
3989
+ function queryFileActivity(query) {
3986
3990
  if (!hasCacheStorage()) {
3987
3991
  return [];
3988
3992
  }
3989
- const query = { options, sessionSearchOptions, onePerSession };
3993
+ const { options } = query;
3990
3994
  const { where, params } = fileActivityWhere(query);
3991
3995
  const sql = fileActivitySql(query, where);
3992
3996
  const queryRows = (db) => db.prepare(sql).all(...params, options.limit ?? 50);
@@ -4010,19 +4014,20 @@ function findFilePathHighlightRanges(path, query) {
4010
4014
  if (index < 0) return [];
4011
4015
  return [{ start: index, end: index + needle.length }];
4012
4016
  }
4013
- function searchFileActivitySessions(query, options = {}) {
4017
+ function searchFileActivitySessions(query, options = {}, queryScope) {
4014
4018
  const search = mergeSearchQueryOptions(query, options);
4015
4019
  const path = normalizeFilePathSearch(search.options.file ?? search.text);
4016
4020
  if (!path) return [];
4017
- const rows = queryFileActivity(
4018
- {
4021
+ const rows = queryFileActivity({
4022
+ options: {
4019
4023
  path,
4020
4024
  kind: search.options.fileKind,
4021
4025
  limit: search.options.limit ?? 50
4022
4026
  },
4023
- search.options,
4024
- true
4025
- );
4027
+ sessionSearchOptions: search.options,
4028
+ onePerSession: true,
4029
+ queryScope
4030
+ });
4026
4031
  return rows.map((row) => {
4027
4032
  const prefix = `${row.kind} `;
4028
4033
  return {
@@ -4037,8 +4042,12 @@ function searchFileActivitySessions(query, options = {}) {
4037
4042
  };
4038
4043
  });
4039
4044
  }
4045
+ function matchesSessionQueryScope(session, scope) {
4046
+ if (scope?.agents?.length && !scope.agents.includes(session.reference.agentName)) return false;
4047
+ return !scope?.projectScope || matchesProjectScope(session, scope.projectScope);
4048
+ }
4040
4049
 
4041
- // ../core/dist/chunk-A6Y7IAJ7.mjs
4050
+ // ../core/dist/chunk-7GIJYQP5.mjs
4042
4051
  import { existsSync as existsSync2, rmSync, unlinkSync } from "fs";
4043
4052
  import { availableParallelism } from "os";
4044
4053
  import { Worker } from "worker_threads";
@@ -4340,10 +4349,12 @@ function readCachedSessionMessageRows(db, agentName, sessionId, startIndex) {
4340
4349
  }
4341
4350
  function loadCachedSessionRawEntry(agentName, sessionId) {
4342
4351
  if (!hasCacheStorage()) return null;
4343
- const outcome = withCacheDbReadOnly((db) => {
4344
- const entry = loadCachedSessionEntryBase(db, agentName, sessionId);
4345
- return entry ? { ...entry, messageRows: readCachedSessionMessageRows(db, agentName, sessionId, 0) } : null;
4346
- });
4352
+ const outcome = withCacheDbReadOnly(
4353
+ (db) => db.transaction(() => {
4354
+ const entry = loadCachedSessionEntryBase(db, agentName, sessionId);
4355
+ return entry ? { ...entry, messageRows: readCachedSessionMessageRows(db, agentName, sessionId, 0) } : null;
4356
+ })()
4357
+ );
4347
4358
  return outcome.status === "success" ? outcome.value : null;
4348
4359
  }
4349
4360
  function readCachedSessionMessageDigest(db, agentName, sessionId, messageCount) {
@@ -4926,6 +4937,17 @@ async function selectAgentRefresh(agent, options) {
4926
4937
  }
4927
4938
  return { ...inspection, availabilityDurationMs };
4928
4939
  }
4940
+ async function beginAgentRefresh(agent, options) {
4941
+ const selection = await selectAgentRefresh(agent, options);
4942
+ return {
4943
+ selection,
4944
+ commit: () => {
4945
+ if (selection.kind === "recompute-derived" || selection.kind === "full-scan" || selection.kind === "incremental-scan") {
4946
+ commitAgentRefreshCheck(selection);
4947
+ }
4948
+ }
4949
+ };
4950
+ }
4929
4951
  function commitAgentRefreshCheck(refresh) {
4930
4952
  refresh.source.commitChangeCheck();
4931
4953
  }
@@ -5136,11 +5158,12 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5136
5158
  onProgress
5137
5159
  });
5138
5160
  }
5139
- const refresh = await selectAgentRefresh(agent, {
5161
+ const refreshTransaction = await beginAgentRefresh(agent, {
5140
5162
  initialized: true,
5141
5163
  sinceTimestamp: cached.timestamp,
5142
5164
  cachedSessions: cached.sessions
5143
5165
  });
5166
+ const refresh = refreshTransaction.selection;
5144
5167
  if (refresh.kind === "unavailable") {
5145
5168
  return finalizeAgentScanFailure(
5146
5169
  agent,
@@ -5235,7 +5258,7 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5235
5258
  ),
5236
5259
  onProgress
5237
5260
  });
5238
- if (result2.cachePersistence === "persisted") commitAgentRefreshCheck(refresh);
5261
+ if (result2.cachePersistence === "persisted") refreshTransaction.commit();
5239
5262
  return result2;
5240
5263
  }
5241
5264
  const result = await finalizeAgentScan(agent, cached.sessions, {
@@ -5246,7 +5269,7 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5246
5269
  completeness: "complete",
5247
5270
  onProgress
5248
5271
  });
5249
- commitAgentRefreshCheck(refresh);
5272
+ refreshTransaction.commit();
5250
5273
  return result;
5251
5274
  }
5252
5275
  }
@@ -5549,11 +5572,19 @@ function materializeStructuredSessionDetail(context, reference, cachedEntry = lo
5549
5572
  } : null;
5550
5573
  let sourceError;
5551
5574
  if (!data && head) {
5575
+ const sourceStartedAt = performance.now();
5552
5576
  try {
5553
5577
  data = agent.getSessionData(reference.sessionId);
5554
5578
  if (data) freshness = "fresh";
5555
5579
  } catch (error) {
5556
5580
  sourceError = error;
5581
+ } finally {
5582
+ getCoreDiagnostics()?.info?.("session_detail.source_read", {
5583
+ agent: reference.agentName,
5584
+ session_id: reference.sessionId,
5585
+ duration_ms: Math.round(performance.now() - sourceStartedAt),
5586
+ failed: sourceError != null
5587
+ });
5557
5588
  }
5558
5589
  }
5559
5590
  if (!data && cacheState === "stale" && cachedEntry) {
@@ -5603,7 +5634,12 @@ function* serializeCachedMessages(messageRows) {
5603
5634
  yield messageJsonFromCachedRow(messageRow);
5604
5635
  }
5605
5636
  }
5606
- function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5637
+ function materializeSessionDetail(scanResult, reference) {
5638
+ const context = getSessionDetailContext(scanResult, reference);
5639
+ if (!context) return { status: "unknown-agent" };
5640
+ return materializeStructuredSessionDetail(context, reference);
5641
+ }
5642
+ function materializeCachedSessionDetailResponse(scanResult, reference, options = {}) {
5607
5643
  const context = getSessionDetailContext(scanResult, reference);
5608
5644
  if (!context) return { status: "unknown-agent" };
5609
5645
  const currentMeta = context.head ? context.agent.getSessionCacheMeta(reference.sessionId) : void 0;
@@ -5620,16 +5656,14 @@ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5620
5656
  const cachedEntry = cursorRead?.entry ?? null;
5621
5657
  const cacheState = cursorRead?.cacheState ?? "missing";
5622
5658
  if (!cachedEntry || cacheState !== "fresh" || cachedEntry.data.smart_tags == null || cachedEntry.data.smart_tags_classifier_revision !== SMART_TAG_CLASSIFIER_REVISION) {
5623
- const result = materializeStructuredSessionDetail(context, reference, void 0);
5624
- return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5659
+ return null;
5625
5660
  }
5626
5661
  const data = cachedEntry.data;
5627
5662
  assertSessionMatchesReference(data, reference);
5628
5663
  const projectIdentity = getProjectIdentity(data, context.head);
5629
5664
  const stream = cursorRead?.stream;
5630
5665
  if (!stream) {
5631
- const result = materializeStructuredSessionDetail(context, reference, void 0);
5632
- return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5666
+ return null;
5633
5667
  }
5634
5668
  const partsJsonBytes = stream.messageRows.reduce(
5635
5669
  (total, row) => total + Buffer.byteLength(String(row.parts_json)),
@@ -5658,6 +5692,12 @@ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5658
5692
  sentMessageCount: stream.messageRows.length
5659
5693
  };
5660
5694
  }
5695
+ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5696
+ const cached = materializeCachedSessionDetailResponse(scanResult, reference, options);
5697
+ if (cached) return cached;
5698
+ const result = materializeSessionDetail(scanResult, reference);
5699
+ return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5700
+ }
5661
5701
  function listCachedProjectGroups(sessions) {
5662
5702
  if (sessions) {
5663
5703
  return buildProjectGroups(sessions);
@@ -6017,6 +6057,7 @@ export {
6017
6057
  searchSessions,
6018
6058
  listFileActivity,
6019
6059
  searchFileActivitySessions,
6060
+ matchesSessionQueryScope,
6020
6061
  readCachedSessions,
6021
6062
  loadCachedSessionHeads,
6022
6063
  readAgentCacheInitialization,
@@ -6043,12 +6084,14 @@ export {
6043
6084
  planAgentScan,
6044
6085
  inspectAgentRefresh,
6045
6086
  selectAgentRefresh,
6087
+ beginAgentRefresh,
6046
6088
  commitAgentRefreshCheck,
6047
6089
  scanSessions,
6090
+ materializeCachedSessionDetailResponse,
6048
6091
  materializeSessionDetailResponse,
6049
6092
  listCachedProjectGroups,
6050
6093
  listDashboardCostFacts,
6051
6094
  listModelCostDistribution,
6052
6095
  commitDurableSessionPublication
6053
6096
  };
6054
- //# sourceMappingURL=chunk-BYB77UAJ.js.map
6097
+ //# sourceMappingURL=chunk-TS3IWH5U.js.map