@orquentra/codebuddy 2.4.0 → 2.5.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/README.md +42 -1090
- package/dist/chunk-3XYQGFPB.js +91 -0
- package/dist/chunk-3XYQGFPB.js.map +1 -0
- package/dist/chunk-4BYGTEJT.js +103 -0
- package/dist/chunk-4BYGTEJT.js.map +1 -0
- package/dist/{chunk-ITGRANYW.js → chunk-6MKEIDX5.js} +2 -2
- package/dist/{chunk-K63EOA4B.js → chunk-776EQXDV.js} +25 -6
- package/dist/chunk-776EQXDV.js.map +1 -0
- package/dist/{chunk-5OWZVZSO.js → chunk-CQPCHMBS.js} +8 -165
- package/dist/chunk-CQPCHMBS.js.map +1 -0
- package/dist/chunk-JDZ3VK26.js +4006 -0
- package/dist/chunk-JDZ3VK26.js.map +1 -0
- package/dist/chunk-JMWJ7V6Y.js +99 -0
- package/dist/chunk-JMWJ7V6Y.js.map +1 -0
- package/dist/chunk-KYK6RPAJ.js +99 -0
- package/dist/chunk-KYK6RPAJ.js.map +1 -0
- package/dist/{chunk-IBMJYIEP.js → chunk-L5AYZC3F.js} +7 -7
- package/dist/{chunk-3ZELDCR3.js → chunk-PCE4STAY.js} +7 -7
- package/dist/{chunk-TI5TQD6D.js → chunk-QDBDYCM2.js} +2 -2
- package/dist/{chunk-DSN5CEHO.js → chunk-ROQTT5ZO.js} +3 -3
- package/dist/{chunk-IE2OUO54.js → chunk-UFZD3JAA.js} +3 -3
- package/dist/chunk-Z5QB367W.js +5028 -0
- package/dist/chunk-Z5QB367W.js.map +1 -0
- package/dist/cli/index.js +2 -2
- package/dist/cloud-GP6G3EAK.js +17 -0
- package/dist/{codebuddy-D2xJ6hFk.d.ts → codebuddy-DM-i0Fu5.d.ts} +49 -18
- package/dist/{config-S2TULOMK.js → config-KFEHLV6W.js} +3 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +34 -25
- package/dist/langgraph/index.d.ts +1 -1
- package/dist/lean-command-DA4ZNKG3.js +15 -0
- package/dist/local-3NGNESNB.js +13 -0
- package/dist/{main-ZZ3EQLYA.js → main-BDVQAGAS.js} +1261 -242
- package/dist/main-BDVQAGAS.js.map +1 -0
- package/dist/{memory-NIBFAMY4.js → memory-4RGVLPKG.js} +6 -6
- package/dist/operations-EQGOFCBD.js +24 -0
- package/dist/operations-EQGOFCBD.js.map +1 -0
- package/dist/{rerank-Q7MIFNKA.js → rerank-3P3C2UHN.js} +4 -4
- package/dist/{summaries-TSE44KUQ.js → summaries-ZBV5IN7Y.js} +6 -6
- package/dist/summaries-ZBV5IN7Y.js.map +1 -0
- package/dist/{zvec-F27AR357.js → zvec-MAPSJQSR.js} +3 -3
- package/dist/zvec-MAPSJQSR.js.map +1 -0
- package/package.json +7 -3
- package/dist/chunk-5OWZVZSO.js.map +0 -1
- package/dist/chunk-K63EOA4B.js.map +0 -1
- package/dist/chunk-SYHB3AMM.js +0 -8580
- package/dist/chunk-SYHB3AMM.js.map +0 -1
- package/dist/lean-command-D6TZJEFX.js +0 -13
- package/dist/main-ZZ3EQLYA.js.map +0 -1
- /package/dist/{chunk-ITGRANYW.js.map → chunk-6MKEIDX5.js.map} +0 -0
- /package/dist/{chunk-IBMJYIEP.js.map → chunk-L5AYZC3F.js.map} +0 -0
- /package/dist/{chunk-3ZELDCR3.js.map → chunk-PCE4STAY.js.map} +0 -0
- /package/dist/{chunk-TI5TQD6D.js.map → chunk-QDBDYCM2.js.map} +0 -0
- /package/dist/{chunk-DSN5CEHO.js.map → chunk-ROQTT5ZO.js.map} +0 -0
- /package/dist/{chunk-IE2OUO54.js.map → chunk-UFZD3JAA.js.map} +0 -0
- /package/dist/{config-S2TULOMK.js.map → cloud-GP6G3EAK.js.map} +0 -0
- /package/dist/{lean-command-D6TZJEFX.js.map → config-KFEHLV6W.js.map} +0 -0
- /package/dist/{summaries-TSE44KUQ.js.map → lean-command-DA4ZNKG3.js.map} +0 -0
- /package/dist/{zvec-F27AR357.js.map → local-3NGNESNB.js.map} +0 -0
- /package/dist/{memory-NIBFAMY4.js.map → memory-4RGVLPKG.js.map} +0 -0
- /package/dist/{rerank-Q7MIFNKA.js.map → rerank-3P3C2UHN.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/memory-lifecycle.ts","../src/db/schema.ts","../src/core/memory-search.ts","../src/providers/embedding-space.ts","../src/planner/default-policy.ts","../src/providers/huggingface.ts","../src/providers/resilience.ts","../src/tracing/langsmith.ts","../src/core/memory-file-store.ts","../src/core/worker.ts","../src/core/codebuddy.ts","../src/core/config.ts","../src/core/migrate-to-files.ts","../src/db/bootstrap.ts","../src/db/client.ts","../src/db/migrator.ts","../src/db/repository.ts","../src/core/operations.ts","../src/core/plan-file-store.ts","../src/core/plan-lifecycle.ts","../package.json","../src/version.ts","../src/risk/assessor.ts","../src/risk/signals/churn.ts","../src/risk/signals/incident.ts","../src/risk/signals/policy.ts","../src/risk/service.ts","../src/mcp/tools/index.ts","../src/context/delivery.ts","../src/context/budget.ts","../src/context/engine.ts","../src/worklog/store.ts","../src/hooks/runtime.ts","../src/memory-extract/engine.ts","../src/memory-extract/deterministic.ts","../src/memory-extract/llm.ts","../src/memory-extract/resolution.ts","../src/memory-extract/review-store.ts","../src/memory-extract/rules.ts","../src/hooks/staging.ts","../src/suggest/engine.ts","../src/suggest/types.ts","../src/mcp/tool-result.ts","../src/mcp/server.ts","../src/automation/project-sync.ts","../src/indexer/watch.ts","../src/mcp/database.ts"],"sourcesContent":["/** Lifecycle fields shared by Markdown facts and indexed (database) fact rows. */\nexport type MemoryLifecycle = {\n namespace?: string;\n sourceDeleted: boolean;\n supersededBy?: string | null;\n category?: string;\n resolvedBy?: string | null;\n};\n\n/**\n * The single eligibility rule for durable memory evidence. A fact is eligible\n * when it belongs to the requested namespace, its source was not deleted, and\n * it was not superseded. A resolved incident is eligible only for historical\n * inspection (`includeResolved`). File context, risk signals, and database\n * recall apply this before ranking or deduplication, so ineligible evidence\n * can never displace or suppress eligible evidence.\n */\nexport function isEligibleMemory(\n fact: MemoryLifecycle,\n options: { namespace?: string; includeResolved?: boolean } = {},\n): boolean {\n if (options.namespace && fact.namespace !== options.namespace) return false;\n if (fact.sourceDeleted || fact.supersededBy) return false;\n if (fact.category === \"incident\" && fact.resolvedBy && !options.includeResolved) return false;\n return true;\n}\n","import { sql } from \"drizzle-orm\";\nimport {\n boolean,\n customType,\n index,\n integer,\n jsonb,\n numeric,\n pgEnum,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n} from \"drizzle-orm/pg-core\";\n\nexport const VECTOR_DIMENSIONS = 384;\nexport const HNSW_M = 16;\nexport const HNSW_EF_CONSTRUCTION = 64;\n\nconst vector = customType<{ data: string; driverData: string }>({\n dataType() {\n return `vector(${VECTOR_DIMENSIONS})`;\n },\n});\n\nexport const memoryTypeEnum = pgEnum(\"memory_type\", [\"interaction\", \"fact\", \"summary\"]);\nexport const interactionRoleEnum = pgEnum(\"interaction_role\", [\"user\", \"assistant\", \"system\"]);\nexport const embeddingOwnerTypeEnum = pgEnum(\"embedding_owner_type\", [\n \"interaction\",\n \"fact\",\n \"summary\",\n]);\nexport const embeddingStatusEnum = pgEnum(\"embedding_status\", [\n \"pending\",\n \"processing\",\n \"ready\",\n \"failed\",\n]);\nexport const shareModeEnum = pgEnum(\"share_mode\", [\"reference\", \"snapshot\"]);\nexport const modelCallTypeEnum = pgEnum(\"model_call_type\", [\"embedding\", \"llm\"]);\nexport const modelCallStatusEnum = pgEnum(\"model_call_status\", [\n \"success\",\n \"failed\",\n \"timeout\",\n \"rate_limited\",\n \"gated\",\n \"fallback\",\n]);\nexport const auditActionEnum = pgEnum(\"audit_action\", [\n \"remember\",\n \"remember_batch\",\n \"share\",\n \"forget\",\n \"config\",\n]);\n\nconst createdAt = timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow();\nconst updatedAt = timestamp(\"updated_at\", { withTimezone: true }).notNull().defaultNow();\n\nexport const namespaces = pgTable(\n \"namespaces\",\n {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n createdAt,\n updatedAt,\n },\n (table) => ({\n nameUnique: uniqueIndex(\"namespaces_name_unique\").on(table.name),\n }),\n);\n\nexport const interactions = pgTable(\n \"interactions\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n sessionId: text(\"session_id\").notNull(),\n role: interactionRoleEnum(\"role\").notNull().default(\"user\"),\n content: text(\"content\").notNull(),\n contentHash: text(\"content_hash\").notNull(),\n tokenCount: integer(\"token_count\").notNull().default(0),\n createdByAgent: text(\"created_by_agent\"),\n createdAt,\n },\n (table) => ({\n namespaceContentHashUnique: uniqueIndex(\"interactions_namespace_content_hash_unique\").on(\n table.namespaceId,\n table.contentHash,\n ),\n namespaceSessionCreatedIdx: index(\"interactions_namespace_session_created_idx\").on(\n table.namespaceId,\n table.sessionId,\n table.createdAt,\n ),\n }),\n);\n\nexport const sessionSummaries = pgTable(\n \"session_summaries\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n sessionId: text(\"session_id\").notNull(),\n content: text(\"content\").notNull(),\n version: integer(\"version\").notNull().default(1),\n tokenCount: integer(\"token_count\").notNull().default(0),\n createdByAgent: text(\"created_by_agent\"),\n /** See facts.fileBacked. */\n fileBacked: boolean(\"file_backed\").notNull().default(false),\n createdAt,\n },\n (table) => ({\n namespaceSessionVersionIdx: index(\"session_summaries_namespace_session_version_idx\").on(\n table.namespaceId,\n table.sessionId,\n table.version,\n ),\n }),\n);\n\nexport const facts = pgTable(\n \"facts\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n subject: text(\"subject\").notNull(),\n predicate: text(\"predicate\").notNull(),\n object: text(\"object\").notNull(),\n propositionKey: text(\"proposition_key\"),\n content: text(\"content\").notNull(),\n contentHash: text(\"content_hash\").notNull(),\n confidence: numeric(\"confidence\", { precision: 5, scale: 4 }).notNull().default(\"1\"),\n /**\n * Historical provenance only — deliberately not a foreign key. Interactions\n * are ephemeral DB rows; Markdown facts must re-import after a rebuild that\n * lost them, and the ID must survive so `sourceDeleted` can be tracked.\n */\n sourceInteractionId: text(\"source_interaction_id\"),\n sourceDeleted: boolean(\"source_deleted\").notNull().default(false),\n supersededBy: text(\"superseded_by\"),\n /**\n * True once a reindex imported this row from its Markdown file. Only such\n * rows are deleted when the file disappears; DB-only legacy rows are kept.\n */\n fileBacked: boolean(\"file_backed\").notNull().default(false),\n embeddingModel: text(\"embedding_model\"),\n createdByAgent: text(\"created_by_agent\"),\n createdAt,\n updatedAt,\n },\n (table) => ({\n namespaceContentHashUnique: uniqueIndex(\"facts_namespace_content_hash_unique\").on(\n table.namespaceId,\n table.contentHash,\n ),\n namespaceSubjectIdx: index(\"facts_namespace_subject_idx\").on(table.namespaceId, table.subject),\n sourceInteractionIdx: index(\"facts_source_interaction_idx\").on(table.sourceInteractionId),\n }),\n);\n\nexport const embeddings = pgTable(\n \"embeddings\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n ownerType: embeddingOwnerTypeEnum(\"owner_type\").notNull(),\n ownerId: text(\"owner_id\").notNull(),\n vector: vector(\"vector\").notNull(),\n embeddingModel: text(\"embedding_model\").notNull(),\n embeddingSpace: text(\"embedding_space\"),\n status: embeddingStatusEnum(\"status\").notNull().default(\"pending\"),\n attempts: integer(\"attempts\").notNull().default(0),\n lastError: text(\"last_error\"),\n /** Lease deadline while status='processing'; null otherwise. */\n leaseUntil: timestamp(\"lease_until\", { withTimezone: true }),\n leaseToken: text(\"lease_token\"),\n createdAt,\n updatedAt,\n },\n (table) => ({\n ownerUnique: uniqueIndex(\"embeddings_owner_unique\").on(table.ownerType, table.ownerId),\n namespaceModelStatusIdx: index(\"embeddings_namespace_model_status_idx\").on(\n table.namespaceId,\n table.embeddingModel,\n table.status,\n ),\n namespaceSpaceStatusIdx: index(\"embeddings_namespace_space_status_idx\").on(\n table.namespaceId,\n table.embeddingSpace,\n table.status,\n ),\n vectorHnswIdx: index(\"embeddings_vector_hnsw_idx\").using(\n \"hnsw\",\n sql`${table.vector} vector_cosine_ops`,\n ),\n }),\n);\n\nexport const shares = pgTable(\n \"shares\",\n {\n id: text(\"id\").primaryKey(),\n fromNamespaceId: text(\"from_namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n toNamespaceId: text(\"to_namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n sourceFactId: text(\"source_fact_id\")\n .notNull()\n .references(() => facts.id, { onDelete: \"cascade\" }),\n snapshotFactId: text(\"snapshot_fact_id\").references(() => facts.id, { onDelete: \"set null\" }),\n mode: shareModeEnum(\"mode\").notNull().default(\"reference\"),\n tombstoned: boolean(\"tombstoned\").notNull().default(false),\n createdByAgent: text(\"created_by_agent\"),\n createdAt,\n },\n (table) => ({\n shareUnique: uniqueIndex(\"shares_target_source_unique\").on(\n table.toNamespaceId,\n table.sourceFactId,\n table.mode,\n ),\n fromNamespaceIdx: index(\"shares_from_namespace_idx\").on(table.fromNamespaceId),\n }),\n);\n\nexport const checkpoints = pgTable(\n \"checkpoints\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\")\n .notNull()\n .references(() => namespaces.id, { onDelete: \"cascade\" }),\n threadId: text(\"thread_id\").notNull(),\n checkpointId: text(\"checkpoint_id\").notNull(),\n parentId: text(\"parent_id\"),\n channelValues: jsonb(\"channel_values\").notNull().default(sql`'{}'::jsonb`),\n metadata: jsonb(\"metadata\").notNull().default(sql`'{}'::jsonb`),\n createdAt,\n },\n (table) => ({\n checkpointUnique: uniqueIndex(\"checkpoints_thread_checkpoint_unique\").on(\n table.namespaceId,\n table.threadId,\n table.checkpointId,\n ),\n }),\n);\n\nexport const modelCalls = pgTable(\n \"model_calls\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\").references(() => namespaces.id, { onDelete: \"set null\" }),\n model: text(\"model\").notNull(),\n type: modelCallTypeEnum(\"type\").notNull(),\n latencyMs: integer(\"latency_ms\"),\n tokens: integer(\"tokens\"),\n status: modelCallStatusEnum(\"status\").notNull(),\n error: text(\"error\"),\n metadata: jsonb(\"metadata\").notNull().default(sql`'{}'::jsonb`),\n createdAt,\n },\n (table) => ({\n modelCreatedIdx: index(\"model_calls_model_created_idx\").on(table.model, table.createdAt),\n namespaceCreatedIdx: index(\"model_calls_namespace_created_idx\").on(\n table.namespaceId,\n table.createdAt,\n ),\n }),\n);\n\nexport const auditLog = pgTable(\n \"audit_log\",\n {\n id: text(\"id\").primaryKey(),\n namespaceId: text(\"namespace_id\").references(() => namespaces.id, { onDelete: \"set null\" }),\n action: auditActionEnum(\"action\").notNull(),\n entityType: text(\"entity_type\").notNull(),\n entityId: text(\"entity_id\"),\n createdByAgent: text(\"created_by_agent\"),\n metadata: jsonb(\"metadata\").notNull().default(sql`'{}'::jsonb`),\n createdAt,\n },\n (table) => ({\n namespaceActionCreatedIdx: index(\"audit_log_namespace_action_created_idx\").on(\n table.namespaceId,\n table.action,\n table.createdAt,\n ),\n }),\n);\n","import { VECTOR_DIMENSIONS } from \"../db/schema.js\";\n\n/** Bound both DB hydration and the lexical query work independently of caller input. */\nexport function candidateLimit(limit: number): number {\n if (!Number.isFinite(limit)) return 256;\n return Math.max(1, Math.min(1024, Math.trunc(limit)));\n}\n\n/** pgvector stores float4, so values must stay finite after float4 rounding. */\nexport function validSearchVector(vector: number[]): boolean {\n return (\n vector.length === VECTOR_DIMENSIONS &&\n vector.every((value) => Number.isFinite(Math.fround(value))) &&\n vector.some((value) => value !== 0)\n );\n}\n\n/** Common prompt scaffolding should not make unrelated facts look relevant. */\nconst QUERY_STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"by\",\n \"can\",\n \"do\",\n \"does\",\n \"for\",\n \"from\",\n \"how\",\n \"i\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"or\",\n \"our\",\n \"please\",\n \"should\",\n \"that\",\n \"the\",\n \"these\",\n \"this\",\n \"to\",\n \"was\",\n \"what\",\n \"when\",\n \"where\",\n \"which\",\n \"who\",\n \"why\",\n \"with\",\n \"you\",\n]);\n\n/** Literal, case-insensitive terms; no SQL wildcard or query-language syntax. */\nexport function lexicalTerms(query: string): string[] {\n return [\n ...new Set(\n query\n .slice(0, 4096)\n .toLowerCase()\n .match(/[\\p{L}\\p{N}_]+/gu) ?? [],\n ),\n ]\n .filter((term) => !QUERY_STOPWORDS.has(term))\n .slice(0, 32)\n .map((term) => term.slice(0, 64));\n}\n\n/** Score complete-word evidence, favoring explicit fact fields over free text. */\nexport function lexicalFactScore(\n fact: { subject: string; object: string; content: string },\n terms: string[],\n): number {\n if (terms.length === 0) return 0;\n const structured = new Set(\n `${fact.subject} ${fact.object}`.toLowerCase().match(/[\\p{L}\\p{N}_]+/gu) ?? [],\n );\n const prose = new Set(fact.content.toLowerCase().match(/[\\p{L}\\p{N}_]+/gu) ?? []);\n const points = terms.reduce(\n (total, term) => total + (structured.has(term) ? 2 : 0) + (prose.has(term) ? 1 : 0),\n 0,\n );\n return points / (3 * terms.length);\n}\n\nexport function cosine(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n let dot = 0;\n let na = 0;\n let nb = 0;\n for (let i = 0; i < a.length; i++) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n dot += av * bv;\n na += av * av;\n nb += bv * bv;\n }\n const denom = Math.sqrt(na) * Math.sqrt(nb);\n return denom === 0 ? 0 : dot / denom;\n}\n","import type { EmbeddingResponse } from \"./adapter.js\";\n\n/** Identity of the coordinate system, including provider preprocessing. */\nexport type EmbeddingSpace = {\n model: string;\n revision: string;\n schema: string;\n dimensions: number;\n};\n\nexport type QueryEmbedding = { vector: number[]; space: EmbeddingSpace };\n\nexport function embeddingSpace(response: Omit<EmbeddingResponse, \"vectors\">): EmbeddingSpace {\n const space = {\n model: response.model,\n revision: response.revision ?? \"unversioned\",\n schema: response.schema ?? \"provider-v1\",\n dimensions: response.dimensions,\n };\n if (\n !space.model ||\n !space.revision ||\n !space.schema ||\n !Number.isSafeInteger(space.dimensions) ||\n space.dimensions <= 0\n ) {\n throw new Error(\"Invalid embedding space identity.\");\n }\n return space;\n}\n\nexport function embeddingSpaceKey(space: EmbeddingSpace): string {\n return JSON.stringify([space.model, space.revision, space.schema, space.dimensions]);\n}\n\nexport function validEmbeddingVector(vector: number[], dimensions: number): boolean {\n return dimensions > 0 && vector.length === dimensions && vector.every(Number.isFinite);\n}\n\nexport function validateEmbeddingResponse(response: EmbeddingResponse, count: number): void {\n embeddingSpace(response);\n if (\n response.vectors.length !== count ||\n response.vectors.some((vector) => !validEmbeddingVector(vector, response.dimensions))\n ) {\n throw new Error(\"Provider returned invalid embedding dimensions, values, or batch size.\");\n }\n}\n","import { isEligibleMemory } from \"../core/memory-lifecycle.js\";\nimport { candidateLimit, validSearchVector } from \"../core/memory-search.js\";\nimport type {\n RecentFact,\n RecentInteraction,\n RecentSummary,\n SimilarEmbedding,\n} from \"../core/repository.js\";\nimport { embeddingSpaceKey, validEmbeddingVector } from \"../providers/embedding-space.js\";\nimport { countTokens } from \"./budget.js\";\nimport type {\n ConflictMode,\n ContextPolicy,\n FactProvenance,\n PlanInput,\n PlannedContext,\n PlannedMessage,\n PlannerStats,\n SkipReason,\n} from \"./types.js\";\n\ntype Candidate = {\n key: string;\n role: PlannedMessage[\"role\"];\n content: string;\n tokens: number;\n score: number;\n source: \"interaction\" | \"fact\" | \"summary\";\n ownerId: string;\n createdAt: number;\n confidence: number;\n isRecencyFloor: boolean;\n fact?: FactProvenance;\n};\n\nexport type DefaultPolicyOptions = {\n recencyFloorSize?: number;\n embeddingCandidateLimit?: number;\n minVectorScore?: number;\n};\n\nexport class DefaultPolicy implements ContextPolicy {\n private readonly recencyFloorSize: number;\n private readonly embeddingCandidateLimit: number;\n private readonly minVectorScore: number;\n\n constructor(options: DefaultPolicyOptions = {}) {\n this.recencyFloorSize = options.recencyFloorSize ?? 3;\n this.embeddingCandidateLimit = candidateLimit(options.embeddingCandidateLimit ?? 256);\n this.minVectorScore = options.minVectorScore ?? 0.1;\n }\n\n async plan(input: PlanInput): Promise<PlannedContext> {\n const repo = input.repository;\n const counts = await repo.countEmbeddingStatuses(input.namespaceId);\n const query = input.queryEmbedding;\n const space = query ? embeddingSpaceKey(query.space) : null;\n let fallbackReason: PlannerStats[\"fallbackReason\"];\n if (!query) fallbackReason = \"query_embedding_unavailable\";\n else if (\n !validSearchVector(query.vector) ||\n !validEmbeddingVector(query.vector, query.space.dimensions)\n )\n fallbackReason = \"invalid_query_vector\";\n // No own-namespace precheck: live reference shares (#51) are searchable\n // even when the namespace has no ready embeddings of its own.\n\n const recencyInteractions = await repo.getRecentInteractions(\n input.namespaceId,\n input.sessionId,\n this.recencyFloorSize,\n );\n const coverage: NonNullable<PlannerStats[\"candidateCoverage\"]> = {\n scope: \"full_namespace\",\n method: \"lexical\",\n compatibleReady: 0,\n candidateLimit: this.embeddingCandidateLimit,\n vectorCandidates: 0,\n lexicalCandidates: 0,\n lexicalMatchedFacts: 0,\n hydratedCandidates: 0,\n spaceFilter: space,\n };\n let candidates: Candidate[] = [];\n let fallback: PlannerStats[\"fallback\"] = \"none\";\n if (!fallbackReason && query && space) {\n const search = await repo.searchSimilarEmbeddings({\n namespaceId: input.namespaceId,\n vector: query.vector,\n embeddingSpace: space,\n embeddingModel: query.space.model,\n limit: this.embeddingCandidateLimit,\n });\n coverage.compatibleReady = search.compatibleReady;\n coverage.vectorCandidates = search.candidates.length;\n coverage.method = search.method;\n const scored = search.candidates.map((row) => ({ row, score: row.score }));\n const ownerIdsByType = groupOwnerIdsByType(scored);\n const [factRows, interactionRows, summaryRows] = await Promise.all([\n repo.getFactsByIds(input.namespaceId, ownerIdsByType.fact),\n repo.getInteractionsByIds(input.namespaceId, ownerIdsByType.interaction),\n repo.getSummariesByIds(input.namespaceId, ownerIdsByType.summary),\n ]);\n candidates = this.hydrateScored(scored, factRows, interactionRows, summaryRows);\n coverage.hydratedCandidates = candidates.length;\n if (search.compatibleReady === 0)\n fallbackReason = counts.ready === 0 ? \"no_ready_embeddings\" : \"no_compatible_embeddings\";\n else if (candidates.length === 0) fallbackReason = \"no_hydratable_candidates\";\n }\n const useFallback = fallbackReason !== undefined;\n const lexical = await repo.searchFactsLexically(\n input.namespaceId,\n input.query,\n useFallback ? this.embeddingCandidateLimit : Math.min(this.embeddingCandidateLimit, 32),\n );\n coverage.lexicalCandidates = lexical.candidates.length;\n coverage.lexicalMatchedFacts = lexical.matchedFacts;\n if (useFallback) {\n const [summary, fallbackInteractions] = await Promise.all([\n repo.getLatestSummary(input.namespaceId, input.sessionId),\n repo.getRecentInteractions(\n input.namespaceId,\n input.sessionId,\n Math.max(this.recencyFloorSize, 10),\n ),\n ]);\n candidates = this.buildFallbackCandidates(fallbackInteractions, summary);\n if (summary && fallbackInteractions.length > 0) fallback = \"recency_summary\";\n else if (summary) fallback = \"summary\";\n else fallback = \"recency\";\n }\n const byKey = new Map(candidates.map((candidate) => [candidate.key, candidate] as const));\n for (const fact of lexical.candidates) {\n if (!isEligibleMemory(fact)) continue;\n // Lexical coverage is not cosine confidence. Reserve it as bounded supporting evidence.\n const candidate = factCandidate(fact, useFallback ? fact.score : 0.35 * fact.score);\n const existing = byKey.get(candidate.key);\n if (existing) existing.score = Math.max(existing.score, candidate.score);\n else byKey.set(candidate.key, candidate);\n }\n candidates = [...byKey.values()];\n candidates = this.applyRecencyFloor(candidates, recencyInteractions);\n\n candidates = this.applyConflictMode(candidates, input.conflictMode);\n candidates.sort((a, b) => {\n if (a.isRecencyFloor !== b.isRecencyFloor) return a.isRecencyFloor ? -1 : 1;\n return b.score - a.score || b.createdAt - a.createdAt || a.key.localeCompare(b.key);\n });\n\n const skipReasons: Partial<Record<SkipReason, number>> = {};\n const included: Candidate[] = [];\n let system = buildSystemPrompt(input.namespace, fallback, useFallback);\n let tokensUsed = countTokens(system);\n let itemsSkipped = 0;\n for (const candidate of candidates) {\n if (tokensUsed + candidate.tokens > input.budget) {\n bump(skipReasons, \"budget_exhausted\");\n itemsSkipped += 1;\n continue;\n }\n if (!candidate.isRecencyFloor && candidate.score < this.minVectorScore && !useFallback) {\n bump(skipReasons, \"low_score\");\n itemsSkipped += 1;\n continue;\n }\n included.push(candidate);\n tokensUsed += candidate.tokens;\n }\n\n const unresolvedKeys = [\n ...new Set(\n included.flatMap((c) =>\n c.fact?.conflict?.unresolved ? [c.fact.propositionKey ?? \"\"] : [],\n ),\n ),\n ].sort();\n if (unresolvedKeys.length > 0) {\n // Selection already reserved the base prompt; the note is added only if\n // it still fits. Each message's `fact.conflict` carries it either way.\n const noted = `${system} Unresolved fact conflicts (compare fact provenance): ${unresolvedKeys.join(\", \")}.`;\n const withNote = tokensUsed - countTokens(system) + countTokens(noted);\n if (withNote <= input.budget) {\n system = noted;\n tokensUsed = withNote;\n }\n }\n const messages: PlannedMessage[] = included.map((candidate) => ({\n role: candidate.role,\n content: candidate.content,\n ...(candidate.fact ? { fact: candidate.fact } : {}),\n }));\n\n const stats: PlannerStats = {\n tokensUsed,\n itemsIncluded: included.length,\n itemsSkipped,\n budgetHeadroom: Math.max(0, input.budget - tokensUsed),\n fallback,\n skipReasons,\n embeddingCoverage: counts,\n candidateCoverage: coverage,\n ...(fallbackReason ? { fallbackReason } : {}),\n explain: [\n `Candidate search covers the full namespace; limit ${this.embeddingCandidateLimit} applies after ranking.`,\n `Embedding space filter: ${coverage.spaceFilter ?? \"unavailable\"}; ${coverage.compatibleReady} compatible ready vectors; ${coverage.vectorCandidates} vector candidates; ${coverage.hydratedCandidates} hydrated.`,\n `Durable lexical facts: ${coverage.lexicalCandidates} candidates of ${coverage.lexicalMatchedFacts} matches.`,\n ...(useFallback\n ? [\n `Fallback: ${fallbackReason}; ${coverage.lexicalCandidates} durable lexical candidates of ${coverage.lexicalMatchedFacts} matches.`,\n ]\n : []),\n ],\n budgetClamped: false,\n budgetStatus: tokensUsed > input.budget ? \"overflow\" : \"within_budget\",\n ...(tokensUsed > input.budget\n ? { budgetWarning: \"Required memory system prompt exceeds budget.\" }\n : {}),\n };\n\n return { system, messages, stats };\n }\n\n private hydrateScored(\n scored: Array<{ row: SimilarEmbedding; score: number }>,\n factRows: RecentFact[],\n interactionRows: RecentInteraction[],\n summaryRows: RecentSummary[],\n ): Candidate[] {\n const factById = new Map(factRows.map((row) => [row.id, row] as const));\n const interactionById = new Map(interactionRows.map((row) => [row.id, row] as const));\n const summaryById = new Map(summaryRows.map((row) => [row.id, row] as const));\n\n const out: Candidate[] = [];\n for (const { row, score } of scored) {\n if (row.ownerType === \"fact\") {\n const fact = factById.get(row.ownerId);\n if (!fact || !isEligibleMemory(fact)) continue;\n out.push(factCandidate(fact, score));\n } else if (row.ownerType === \"interaction\") {\n const interaction = interactionById.get(row.ownerId);\n if (!interaction) continue;\n out.push({\n key: `interaction:${interaction.id}`,\n role: \"user\",\n content: interaction.content,\n tokens: countTokens(interaction.content),\n score,\n source: \"interaction\",\n ownerId: interaction.id,\n createdAt: interaction.createdAt.getTime(),\n confidence: 1,\n isRecencyFloor: false,\n });\n } else {\n const summary = summaryById.get(row.ownerId);\n if (!summary) continue;\n out.push({\n key: `summary:${summary.id}`,\n role: \"system\",\n content: summary.content,\n tokens: countTokens(summary.content),\n score,\n source: \"summary\",\n ownerId: summary.id,\n createdAt: summary.createdAt.getTime(),\n confidence: 1,\n isRecencyFloor: false,\n });\n }\n }\n return out;\n }\n\n private applyRecencyFloor(candidates: Candidate[], floor: RecentInteraction[]): Candidate[] {\n const byKey = new Map<string, Candidate>();\n for (const candidate of candidates) byKey.set(candidate.key, candidate);\n for (const row of floor) {\n const key = `interaction:${row.id}`;\n const existing = byKey.get(key);\n if (existing) {\n existing.isRecencyFloor = true;\n continue;\n }\n byKey.set(key, {\n key,\n role: \"user\",\n content: row.content,\n tokens: countTokens(row.content),\n score: 1,\n source: \"interaction\",\n ownerId: row.id,\n createdAt: row.createdAt.getTime(),\n confidence: 1,\n isRecencyFloor: true,\n });\n }\n return Array.from(byKey.values());\n }\n\n private buildFallbackCandidates(\n interactions: RecentInteraction[],\n summary: RecentSummary | null,\n ): Candidate[] {\n const out: Candidate[] = [];\n if (summary) {\n out.push({\n key: `summary:${summary.id}`,\n role: \"system\",\n content: summary.content,\n tokens: countTokens(summary.content),\n score: 1,\n source: \"summary\",\n ownerId: summary.id,\n createdAt: summary.createdAt.getTime(),\n confidence: 1,\n isRecencyFloor: true,\n });\n }\n for (const row of interactions) {\n out.push({\n key: `interaction:${row.id}`,\n role: \"user\",\n content: row.content,\n tokens: countTokens(row.content),\n score: 1,\n source: \"interaction\",\n ownerId: row.id,\n createdAt: row.createdAt.getTime(),\n confidence: 1,\n isRecencyFloor: true,\n });\n }\n return out;\n }\n\n /**\n * Resolve rival assertions of the same explicit proposition key. Facts without\n * a key are treated as multi-valued and never grouped, so identical or\n * different surface text alone never merges or splits claims.\n */\n private applyConflictMode(candidates: Candidate[], mode: ConflictMode): Candidate[] {\n const groups = new Map<string, Candidate[]>();\n for (const candidate of candidates) {\n const key = candidate.fact?.propositionKey;\n if (!key) continue;\n groups.set(key, [...(groups.get(key) ?? []), candidate]);\n }\n const dropped = new Set<string>();\n for (const bucket of groups.values()) {\n if (bucket.length < 2) continue;\n bucket.sort((a, b) => compareRivals(a, b, mode));\n const winner = bucket[0] as Candidate;\n // Rivals the mode cannot separate: everything for \"all\", exact ties otherwise.\n const contenders = bucket.filter(\n (c) =>\n mode === \"all\" ||\n (c.createdAt === winner.createdAt && c.confidence === winner.confidence),\n );\n const objects = new Set(contenders.map((c) => c.fact?.object.trim().toLowerCase()));\n const conflict = {\n candidateIds: bucket.map((c) => c.ownerId).sort(),\n unresolved: objects.size > 1,\n };\n for (const candidate of bucket) {\n if (mode !== \"all\" && candidate !== winner) dropped.add(candidate.key);\n else if (candidate.fact) candidate.fact = { ...candidate.fact, conflict };\n }\n }\n return candidates.filter((candidate) => !dropped.has(candidate.key));\n }\n}\n\n/** Mode order first, the other signal second, then id so ties are deterministic. */\nfunction compareRivals(a: Candidate, b: Candidate, mode: ConflictMode): number {\n const byTime = b.createdAt - a.createdAt;\n const byConfidence = b.confidence - a.confidence;\n const ordered = mode === \"highest_confidence\" ? byConfidence || byTime : byTime || byConfidence;\n return ordered || a.ownerId.localeCompare(b.ownerId);\n}\n\nfunction groupOwnerIdsByType(scored: Array<{ row: SimilarEmbedding }>): {\n fact: string[];\n interaction: string[];\n summary: string[];\n} {\n const out = { fact: [] as string[], interaction: [] as string[], summary: [] as string[] };\n for (const { row } of scored) {\n out[row.ownerType].push(row.ownerId);\n }\n return out;\n}\n\nfunction bump(map: Partial<Record<SkipReason, number>>, key: SkipReason): void {\n map[key] = (map[key] ?? 0) + 1;\n}\n\nfunction buildSystemPrompt(\n namespace: string,\n fallback: PlannerStats[\"fallback\"],\n isFallback: boolean,\n): string {\n const base = `Memory context for namespace \"${namespace}\".`;\n if (isFallback) {\n return `${base} Fallback active (${fallback}); vector search unavailable or empty.`;\n }\n return base;\n}\n\nfunction factCandidate(fact: RecentFact, score: number): Candidate {\n return {\n key: `fact:${fact.id}`,\n role: \"system\",\n content: fact.content,\n tokens: countTokens(fact.content),\n score,\n source: \"fact\",\n ownerId: fact.id,\n createdAt: fact.createdAt.getTime(),\n confidence: fact.confidence,\n isRecencyFloor: false,\n fact: {\n id: fact.id,\n subject: fact.subject,\n predicate: fact.predicate,\n object: fact.object,\n propositionKey: fact.propositionKey,\n confidence: fact.confidence,\n createdAt: fact.createdAt.toISOString(),\n createdByAgent: fact.createdByAgent,\n },\n };\n}\n","import { HfInference, setLogger } from \"@huggingface/inference\";\nimport type {\n EmbeddingRequest,\n EmbeddingResponse,\n ModelProvider,\n ProviderDiagnosticsHook,\n TextGenerationRequest,\n TextGenerationResponse,\n} from \"./adapter.js\";\nimport { validateEmbeddingResponse } from \"./embedding-space.js\";\nimport {\n assertCompatibleEmbeddingModels,\n DEFAULT_EMBEDDING_MODELS,\n DEFAULT_LLM_MODELS,\n EMBEDDING_DIMENSIONS,\n type ModelDefinition,\n} from \"./models.js\";\nimport {\n DEFAULT_RESILIENCE_OPTIONS,\n HuggingFaceResilience,\n type ResilienceOptions,\n} from \"./resilience.js\";\n\n// The library logs through `console` by default, and `console.log` is stdout:\n// the MCP JSON-RPC channel under `codebuddy serve`. Keep all of it on stderr.\nconst toStderr = (...args: unknown[]) => console.error(...args);\nsetLogger({ debug: toStderr, info: toStderr, log: toStderr, warn: toStderr, error: toStderr });\n\nexport type HuggingFaceProviderOptions = {\n apiKey?: string;\n client?: Pick<HfInference, \"featureExtraction\" | \"textGeneration\">;\n embeddingModels?: ModelDefinition[];\n llmModels?: ModelDefinition[];\n resilience?: Partial<ResilienceOptions>;\n onDiagnostic?: ProviderDiagnosticsHook;\n};\n\nexport class HuggingFaceProvider implements ModelProvider {\n private readonly client: Pick<HfInference, \"featureExtraction\" | \"textGeneration\">;\n private readonly embeddingModels: ModelDefinition[];\n private readonly llmModels: ModelDefinition[];\n private readonly resilience: HuggingFaceResilience;\n private readonly onDiagnostic: ProviderDiagnosticsHook | undefined;\n\n constructor(options: HuggingFaceProviderOptions = {}) {\n this.client = options.client ?? new HfInference(options.apiKey);\n this.embeddingModels = options.embeddingModels ?? DEFAULT_EMBEDDING_MODELS;\n this.llmModels = options.llmModels ?? DEFAULT_LLM_MODELS;\n this.resilience = new HuggingFaceResilience({\n ...DEFAULT_RESILIENCE_OPTIONS,\n ...options.resilience,\n });\n this.onDiagnostic = options.onDiagnostic;\n\n assertCompatibleEmbeddingModels(this.embeddingModels);\n }\n\n async embed(request: EmbeddingRequest): Promise<EmbeddingResponse> {\n const primaryModel = request.model ?? this.embeddingModels[0]?.id;\n if (!primaryModel) {\n throw new Error(\"No embedding model configured.\");\n }\n\n const fallbackModels = this.embeddingModels\n .map((model) => model.id)\n .filter((model) => model !== primaryModel);\n\n return this.resilience.execute({\n model: primaryModel,\n fallbackModels,\n type: \"embedding\",\n ...(this.onDiagnostic ? { onDiagnostic: this.onDiagnostic } : {}),\n call: async (model) => {\n const response = await this.client.featureExtraction({\n model,\n inputs: request.input,\n });\n\n const definition = this.embeddingModels.find((entry) => entry.id === model);\n const vectors = normalizeEmbeddingResponse(response);\n const dimensions = vectors[0]?.length ?? 0;\n const result = {\n model,\n revision: definition?.revision ?? \"unversioned\",\n schema: definition?.schema ?? \"hf-feature-extraction-v1\",\n dimensions,\n vectors,\n };\n validateEmbeddingResponse(\n result,\n typeof request.input === \"string\" ? 1 : request.input.length,\n );\n if (dimensions !== (definition?.dimensions ?? EMBEDDING_DIMENSIONS)) {\n throw new Error(\n `Embedding model ${model} returned unexpected dimensions: ${dimensions}.`,\n );\n }\n return result;\n },\n });\n }\n\n async generateText(request: TextGenerationRequest): Promise<TextGenerationResponse> {\n const primaryModel = request.model ?? this.llmModels[0]?.id;\n if (!primaryModel) {\n throw new Error(\"No LLM model configured.\");\n }\n\n const fallbackModels = this.llmModels\n .map((model) => model.id)\n .filter((model) => model !== primaryModel);\n\n return this.resilience.execute({\n model: primaryModel,\n fallbackModels,\n type: \"llm\",\n ...(this.onDiagnostic ? { onDiagnostic: this.onDiagnostic } : {}),\n call: async (model) => {\n const response = await this.client.textGeneration({\n model,\n inputs: request.prompt,\n });\n\n return {\n model,\n text: response.generated_text,\n };\n },\n });\n }\n}\n\nfunction normalizeEmbeddingResponse(response: unknown): number[][] {\n if (!Array.isArray(response)) {\n throw new Error(\"Unexpected Hugging Face embedding response.\");\n }\n\n if (response.every((value) => typeof value === \"number\")) {\n return [response as number[]];\n }\n\n if (\n response.every(\n (vector) => Array.isArray(vector) && vector.every((value) => typeof value === \"number\"),\n )\n ) {\n return response as number[][];\n }\n\n throw new Error(\"Unexpected Hugging Face embedding vector shape.\");\n}\n","import PQueue from \"p-queue\";\nimport pRetry, { AbortError } from \"p-retry\";\nimport pTimeout from \"p-timeout\";\nimport type { ProviderCallMetadata, ProviderCallType } from \"./adapter.js\";\n\nexport type ResilienceOptions = {\n retries: number;\n concurrency: number;\n rateLimitPerMinute: number;\n timeoutMs: number;\n warmCacheTtlMs: number;\n coldStartBufferMs: number;\n jitterMs: number;\n minRetryTimeoutMs: number;\n maxRetryTimeoutMs: number;\n};\n\nexport type ResilientCallInput<T> = {\n model: string;\n type: ProviderCallType;\n fallbackModels?: string[];\n call: (model: string) => Promise<T>;\n onDiagnostic?: ((metadata: ProviderCallMetadata) => void | Promise<void>) | undefined;\n sleep?: ((ms: number) => Promise<void>) | undefined;\n};\n\nexport type HuggingFaceErrorLike = Error & {\n status?: number;\n statusCode?: number;\n response?: {\n status?: number;\n headers?: {\n get?: (name: string) => string | null;\n };\n };\n httpResponse?: {\n status?: number;\n };\n estimated_time?: number;\n estimatedTime?: number;\n cause?: unknown;\n};\n\nexport const DEFAULT_RESILIENCE_OPTIONS: ResilienceOptions = {\n retries: 5,\n concurrency: 2,\n rateLimitPerMinute: 10,\n timeoutMs: 90_000,\n warmCacheTtlMs: 5 * 60_000,\n coldStartBufferMs: 2_000,\n jitterMs: 250,\n minRetryTimeoutMs: 1_000,\n maxRetryTimeoutMs: 30_000,\n};\n\nexport class GatedModelError extends Error {\n readonly model: string;\n\n constructor(model: string) {\n super(\n `Model ${model} is gated. Accept the license at https://huggingface.co/${model} and retry.`,\n );\n this.name = \"GatedModelError\";\n this.model = model;\n }\n}\n\nexport class UnauthorizedError extends Error {\n constructor() {\n super(\"Hugging Face rejected the API token (401). Set a valid HF token and retry.\");\n this.name = \"UnauthorizedError\";\n }\n}\n\nexport class ModelUnavailableError extends Error {\n readonly model: string;\n\n constructor(model: string, cause?: unknown) {\n super(`Model ${model} is unavailable.`);\n this.name = \"ModelUnavailableError\";\n this.model = model;\n this.cause = cause;\n }\n}\n\nexport class HuggingFaceResilience {\n private readonly options: ResilienceOptions;\n private readonly queues = new Map<string, PQueue>();\n private readonly warmUntil = new Map<string, number>();\n\n constructor(options: Partial<ResilienceOptions> = {}) {\n this.options = {\n ...DEFAULT_RESILIENCE_OPTIONS,\n ...options,\n };\n }\n\n isWarm(model: string, now = Date.now()): boolean {\n return (this.warmUntil.get(model) ?? 0) > now;\n }\n\n markWarm(model: string, now = Date.now()): void {\n this.warmUntil.set(model, now + this.options.warmCacheTtlMs);\n }\n\n async execute<T>(input: ResilientCallInput<T>): Promise<T> {\n const models = [input.model, ...(input.fallbackModels ?? [])];\n let lastError: unknown;\n\n for (const [index, model] of models.entries()) {\n const fallbackTriggered = index > 0;\n\n try {\n return await this.executeForModel(model, input, fallbackTriggered);\n } catch (error) {\n lastError = error;\n\n if (error instanceof GatedModelError || error instanceof UnauthorizedError) {\n throw error;\n }\n }\n }\n\n throw lastError instanceof Error ? lastError : new Error(\"All provider models failed.\");\n }\n\n private async executeForModel<T>(\n model: string,\n input: ResilientCallInput<T>,\n fallbackTriggered: boolean,\n ): Promise<T> {\n const queue = this.getQueue(model);\n const startedAt = Date.now();\n let retries = 0;\n let coldStartWaitMs = 0;\n let status: ProviderCallMetadata[\"status\"] = fallbackTriggered ? \"fallback\" : \"success\";\n\n try {\n const result = await queue.add(\n async () =>\n pRetry(\n async () => {\n try {\n return await pTimeout(input.call(model), {\n milliseconds: this.options.timeoutMs,\n });\n } catch (error) {\n const classified = classifyHuggingFaceError(error, model);\n\n if (classified.kind === \"gated\") {\n status = \"gated\";\n throw new AbortError(new GatedModelError(model));\n }\n\n if (classified.kind === \"unauthorized\") {\n throw new AbortError(new UnauthorizedError());\n }\n\n if (classified.kind === \"cold_start\") {\n const waitMs = this.calculateColdStartWaitMs(classified.estimatedTimeSeconds);\n coldStartWaitMs += waitMs;\n await (input.sleep ?? sleep)(waitMs);\n throw error;\n }\n\n if (classified.kind === \"rate_limited\") {\n status = \"rate_limited\";\n if (classified.retryAfterMs) {\n await (input.sleep ?? sleep)(classified.retryAfterMs);\n }\n throw error;\n }\n\n if (classified.kind === \"unavailable\") {\n throw new ModelUnavailableError(model, error);\n }\n\n if (classified.kind === \"timeout\") {\n status = \"timeout\";\n }\n\n throw error;\n }\n },\n {\n retries: this.options.retries,\n minTimeout: this.options.minRetryTimeoutMs,\n maxTimeout: this.options.maxRetryTimeoutMs,\n factor: 2,\n randomize: true,\n onFailedAttempt: (error) => {\n retries = error.attemptNumber;\n },\n },\n ),\n { throwOnTimeout: true },\n );\n\n this.markWarm(model);\n status = fallbackTriggered ? \"fallback\" : \"success\";\n await input.onDiagnostic?.({\n model,\n type: input.type,\n status,\n latencyMs: Date.now() - startedAt,\n retries,\n fallbackTriggered,\n coldStartWaitMs,\n });\n return result;\n } catch (error) {\n const finalError =\n error instanceof AbortError && error.originalError ? error.originalError : error;\n const classified = classifyHuggingFaceError(finalError, model);\n const finalStatus = statusForClassifiedError(classified.kind, status);\n\n await input.onDiagnostic?.({\n model,\n type: input.type,\n status: finalStatus,\n latencyMs: Date.now() - startedAt,\n error: finalError instanceof Error ? finalError.message : String(finalError),\n retries,\n fallbackTriggered,\n coldStartWaitMs,\n });\n\n throw finalError;\n }\n }\n\n private getQueue(model: string): PQueue {\n const existing = this.queues.get(model);\n if (existing) {\n return existing;\n }\n\n const queue = new PQueue({\n concurrency: this.options.concurrency,\n intervalCap: this.options.rateLimitPerMinute,\n interval: 60_000,\n });\n\n this.queues.set(model, queue);\n return queue;\n }\n\n private calculateColdStartWaitMs(estimatedTimeSeconds: number): number {\n return Math.ceil(\n estimatedTimeSeconds * 1_000 + this.options.coldStartBufferMs + this.randomJitter(),\n );\n }\n\n private randomJitter(): number {\n return Math.floor(Math.random() * this.options.jitterMs);\n }\n}\n\ntype ClassifiedError =\n | { kind: \"cold_start\"; estimatedTimeSeconds: number }\n | { kind: \"rate_limited\"; retryAfterMs?: number }\n | { kind: \"gated\" }\n | { kind: \"unauthorized\" }\n | { kind: \"unavailable\" }\n | { kind: \"timeout\" }\n | { kind: \"unknown\" };\n\nexport function classifyHuggingFaceError(error: unknown, model: string): ClassifiedError {\n if (error instanceof GatedModelError) {\n return { kind: \"gated\" };\n }\n\n if (error instanceof ModelUnavailableError) {\n return { kind: \"unavailable\" };\n }\n\n if (error instanceof UnauthorizedError) {\n return { kind: \"unauthorized\" };\n }\n\n if (error instanceof Error && error.name === \"TimeoutError\") {\n return { kind: \"timeout\" };\n }\n\n const hfError = error as HuggingFaceErrorLike;\n const status =\n hfError.status ??\n hfError.statusCode ??\n hfError.response?.status ??\n // @huggingface/inference 4.x errors carry the code here.\n hfError.httpResponse?.status;\n\n if (status === 401) {\n return { kind: \"unauthorized\" };\n }\n\n if (status === 403) {\n return { kind: \"gated\" };\n }\n\n if (status === 404) {\n return { kind: \"unavailable\" };\n }\n\n if (status === 429) {\n const retryAfterMs = readRetryAfterMs(hfError);\n return retryAfterMs === undefined\n ? { kind: \"rate_limited\" }\n : { kind: \"rate_limited\", retryAfterMs };\n }\n\n if (status === 503) {\n const estimatedTimeSeconds = readEstimatedTimeSeconds(hfError);\n if (estimatedTimeSeconds !== undefined) {\n return { kind: \"cold_start\", estimatedTimeSeconds };\n }\n }\n\n if (error instanceof Error && error.message.includes(\"timed out\")) {\n return { kind: \"timeout\" };\n }\n\n if (error instanceof Error && error.message.includes(model) && error.message.includes(\"gated\")) {\n return { kind: \"gated\" };\n }\n\n return { kind: \"unknown\" };\n}\n\nfunction statusForClassifiedError(\n kind: ClassifiedError[\"kind\"],\n currentStatus: ProviderCallMetadata[\"status\"],\n): ProviderCallMetadata[\"status\"] {\n if (kind === \"gated\") {\n return \"gated\";\n }\n if (kind === \"rate_limited\") {\n return \"rate_limited\";\n }\n if (kind === \"timeout\") {\n return \"timeout\";\n }\n if (currentStatus === \"fallback\") {\n return \"fallback\";\n }\n return \"failed\";\n}\n\nfunction readEstimatedTimeSeconds(error: HuggingFaceErrorLike): number | undefined {\n if (typeof error.estimated_time === \"number\") {\n return error.estimated_time;\n }\n if (typeof error.estimatedTime === \"number\") {\n return error.estimatedTime;\n }\n if (typeof error.cause === \"object\" && error.cause !== null && \"estimated_time\" in error.cause) {\n const estimatedTime = (error.cause as { estimated_time?: unknown }).estimated_time;\n return typeof estimatedTime === \"number\" ? estimatedTime : undefined;\n }\n return undefined;\n}\n\nfunction readRetryAfterMs(error: HuggingFaceErrorLike): number | undefined {\n const retryAfter = error.response?.headers?.get?.(\"retry-after\");\n if (!retryAfter) {\n return undefined;\n }\n\n const retryAfterSeconds = Number(retryAfter);\n return Number.isFinite(retryAfterSeconds) ? retryAfterSeconds * 1_000 : undefined;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","export type TraceMetadata = Record<string, unknown>;\n\nexport type TraceSpan = {\n end(metadata?: TraceMetadata): void;\n fail(error: unknown, metadata?: TraceMetadata): void;\n};\n\nexport type Tracer = {\n enabled: boolean;\n startSpan(name: string, input?: TraceMetadata): TraceSpan;\n withSpan<T>(name: string, input: TraceMetadata, fn: () => Promise<T>): Promise<T>;\n};\n\nexport function isLangSmithTracingEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.LANGCHAIN_TRACING_V2 === \"true\" || env.LANGSMITH_TRACING === \"true\";\n}\n\nexport function createTracer(env: NodeJS.ProcessEnv = process.env): Tracer {\n const enabled = isLangSmithTracingEnabled(env);\n if (!enabled) {\n return {\n enabled: false,\n startSpan: () => noopSpan,\n withSpan: async (_name, _input, fn) => fn(),\n };\n }\n return {\n enabled: true,\n startSpan(name, input) {\n const started = Date.now();\n log(\"span:start\", { name, input });\n return {\n end(metadata) {\n log(\"span:end\", { name, durationMs: Date.now() - started, metadata });\n },\n fail(error, metadata) {\n log(\"span:fail\", {\n name,\n durationMs: Date.now() - started,\n error: error instanceof Error ? error.message : String(error),\n metadata,\n });\n },\n };\n },\n async withSpan(name, input, fn) {\n const span = this.startSpan(name, input);\n try {\n const result = await fn();\n span.end();\n return result;\n } catch (error) {\n span.fail(error);\n throw error;\n }\n },\n };\n}\n\nconst noopSpan: TraceSpan = {\n end: () => undefined,\n fail: () => undefined,\n};\n\nfunction log(event: string, payload: TraceMetadata): void {\n if (process.env.NODE_ENV === \"test\") return;\n process.stderr.write(`${JSON.stringify({ at: \"tracer\", event, ...payload })}\\n`);\n}\n","import { mkdir, readdir, readFile, rm } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { redactPersisted } from \"../memory-extract/sensitive.js\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"./markdown-store-fs.js\";\nimport { isEligibleMemory } from \"./memory-lifecycle.js\";\n\nexport const FACT_CATEGORIES = [\"general\", \"incident\"] as const;\nexport type FactCategory = (typeof FACT_CATEGORIES)[number];\nexport const INCIDENT_SEVERITIES = [\"low\", \"medium\", \"high\", \"critical\"] as const;\nexport type IncidentSeverity = (typeof INCIDENT_SEVERITIES)[number];\n\nconst factFrontMatterSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^fact_[a-z0-9]+$/),\n namespace: z.string().min(1),\n type: z.literal(\"fact\"),\n subject: z.string(),\n predicate: z.string(),\n object: z.string(),\n /** Explicit single-valued claim identity; facts sharing it are rival assertions. */\n propositionKey: z.string().min(1).nullable().default(null),\n confidence: z.number().min(0).max(1),\n createdAt: z.preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime(),\n ),\n createdByAgent: z.string().nullable(),\n sourceInteractionId: z.string().nullable(),\n sourceDeleted: z.boolean(),\n category: z.enum(FACT_CATEGORIES).default(\"general\"),\n paths: z.array(z.string().min(1)).default([]),\n severity: z.enum(INCIDENT_SEVERITIES).nullable().default(null),\n introducedBy: z.string().nullable().default(null),\n resolvedBy: z.string().nullable().default(null),\n fingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .nullable()\n .default(null),\n sourcePlanId: z.string().nullable().default(null),\n sourceSessionId: z.string().nullable().default(null),\n verification: z.array(z.string()).default([]),\n supersededBy: z.string().nullable().default(null),\n /** Namespaces granted a live reference to this fact (durable form of reference shares). */\n sharedWith: z.array(z.string().min(1)).default([]),\n});\n\nconst summaryFrontMatterSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^sum_[a-z0-9]+$/),\n namespace: z.string().min(1),\n type: z.literal(\"summary\"),\n sessionId: z.string().min(1),\n version: z.number().int().positive(),\n tokenCount: z.number().int().nonnegative(),\n createdAt: z.preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime(),\n ),\n createdByAgent: z.string().nullable(),\n});\n\nexport type FactFile = z.infer<typeof factFrontMatterSchema> & {\n content: string;\n path: string;\n};\n\nexport type FactFileWrite = Omit<\n FactFile,\n | \"path\"\n | \"schemaVersion\"\n | \"type\"\n | \"category\"\n | \"paths\"\n | \"severity\"\n | \"introducedBy\"\n | \"resolvedBy\"\n | \"fingerprint\"\n | \"sourcePlanId\"\n | \"sourceSessionId\"\n | \"verification\"\n | \"supersededBy\"\n | \"sharedWith\"\n | \"propositionKey\"\n> &\n Partial<\n Pick<\n FactFile,\n | \"category\"\n | \"paths\"\n | \"severity\"\n | \"introducedBy\"\n | \"resolvedBy\"\n | \"fingerprint\"\n | \"sourcePlanId\"\n | \"sourceSessionId\"\n | \"verification\"\n | \"supersededBy\"\n | \"sharedWith\"\n | \"propositionKey\"\n >\n >;\nexport type IncidentFactFile = FactFile & {\n category: \"incident\";\n severity: IncidentSeverity;\n};\nexport type SummaryFile = z.infer<typeof summaryFrontMatterSchema> & {\n content: string;\n path: string;\n};\nexport type SummaryFileWrite = Omit<SummaryFile, \"path\" | \"schemaVersion\" | \"type\">;\n/** A managed memory file that exists on disk but could not be parsed. */\nexport type InvalidMemoryFile = { id: string; path: string; error: string };\n\nexport class MemoryFileStore {\n readonly repositoryRoot: string;\n readonly factsDirectory: string;\n readonly summariesDirectory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.factsDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"facts\");\n this.summariesDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"summaries\");\n }\n\n async writeFact(raw: FactFileWrite): Promise<string> {\n // Persistence boundary: every fact writer (capture, remember, outcomes,\n // migration, resolve/supersede rewrites) is redacted here.\n const input = redactPersisted(raw);\n const path = this.factPath(input.id);\n await this.prepareDirectory(this.factsDirectory);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n\n const metadata = {\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n type: \"fact\",\n subject: input.subject,\n predicate: input.predicate,\n object: input.object,\n propositionKey: input.propositionKey,\n confidence: input.confidence,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n sourceInteractionId: input.sourceInteractionId,\n sourceDeleted: input.sourceDeleted,\n category: input.category,\n paths: input.paths,\n severity: input.severity,\n introducedBy: input.introducedBy,\n resolvedBy: input.resolvedBy,\n fingerprint: input.fingerprint,\n sourcePlanId: input.sourcePlanId,\n sourceSessionId: input.sourceSessionId,\n verification: input.verification,\n supersededBy: input.supersededBy,\n sharedWith: input.sharedWith,\n };\n const frontMatter = stringifyYaml(stripUndefinedAndDefaultIncidentFields(metadata));\n\n await writeAtomic(path, composeMarkdown(frontMatter, input.content));\n return path;\n }\n\n async writeSummary(input: SummaryFileWrite): Promise<string> {\n const path = this.summaryPath(input.id);\n await this.prepareDirectory(this.summariesDirectory);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n const metadata = stringifyYaml({\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n type: \"summary\",\n sessionId: input.sessionId,\n version: input.version,\n tokenCount: input.tokenCount,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n });\n await writeAtomic(path, composeMarkdown(metadata, input.content));\n return path;\n }\n\n async readFact(pathOrId: string): Promise<FactFile> {\n const path = pathOrId.endsWith(\".md\") ? this.safePath(pathOrId) : this.factPath(pathOrId);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n const metadata = factFrontMatterSchema.parse(parseYaml(parsed.frontMatter));\n return {\n ...metadata,\n content: parsed.content.trim(),\n path,\n };\n }\n\n async listFacts(): Promise<FactFile[]> {\n return (await this.scanFacts()).facts;\n }\n\n /**\n * Parse every managed fact file. Hand-written markdown is ignored, and a\n * schema-invalid/corrupt fact is reported in `invalid` (not thrown) so one\n * bad file can't break recall, capture or reindexing for the whole project.\n * Invalid files stay on disk for manual repair.\n */\n async scanFacts(): Promise<{ facts: FactFile[]; invalid: InvalidMemoryFile[] }> {\n const scan = await this.scan(this.factsDirectory, /^fact_[a-z0-9]+\\.md$/, (path) =>\n this.readFact(path),\n );\n return { facts: scan.items, invalid: scan.invalid };\n }\n\n /**\n * List incident facts for the namespace, ranked by severity then recency.\n * Unlike {@link findIncidentFactsForPaths} this does not filter by path, so\n * callers (e.g. the context engine's project bootstrap) can surface the\n * repository's incident hotspots before any specific edit target is known.\n */\n async listIncidentFacts(\n input: { namespace?: string; includeResolved?: boolean } = {},\n ): Promise<IncidentFactFile[]> {\n const incidents = (await this.listFacts()).filter(\n (fact): fact is IncidentFactFile =>\n fact.category === \"incident\" && Boolean(fact.severity) && isEligibleMemory(fact, input),\n );\n\n return incidents.sort((left, right) => {\n const severity = severityRank(right.severity) - severityRank(left.severity);\n if (severity !== 0) return severity;\n return right.createdAt.localeCompare(left.createdAt);\n });\n }\n\n async findIncidentFactsForPaths(input: {\n namespace?: string;\n paths: string[];\n includeResolved?: boolean;\n }): Promise<IncidentFactFile[]> {\n const wanted = new Set(input.paths.map(normalizeMemoryPath));\n if (wanted.size === 0) return [];\n\n return (\n await this.listIncidentFacts({\n ...(input.namespace !== undefined ? { namespace: input.namespace } : {}),\n ...(input.includeResolved !== undefined ? { includeResolved: input.includeResolved } : {}),\n })\n ).filter((fact) => fact.paths.map(normalizeMemoryPath).some((path) => wanted.has(path)));\n }\n\n async readSummary(pathOrId: string): Promise<SummaryFile> {\n const path = pathOrId.endsWith(\".md\") ? this.safePath(pathOrId) : this.summaryPath(pathOrId);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n return {\n ...summaryFrontMatterSchema.parse(parseYaml(parsed.frontMatter)),\n content: parsed.content.trim(),\n path,\n };\n }\n\n async listSummaries(): Promise<SummaryFile[]> {\n return (await this.scanSummaries()).summaries;\n }\n\n async scanSummaries(): Promise<{ summaries: SummaryFile[]; invalid: InvalidMemoryFile[] }> {\n const scan = await this.scan(this.summariesDirectory, /^sum_[a-z0-9]+\\.md$/, (path) =>\n this.readSummary(path),\n );\n return { summaries: scan.items, invalid: scan.invalid };\n }\n\n private async scan<T extends { id: string }>(\n directory: string,\n managedName: RegExp,\n read: (path: string) => Promise<T>,\n ): Promise<{ items: T[]; invalid: InvalidMemoryFile[] }> {\n try {\n await this.prepareDirectory(directory);\n const entries = await readdir(directory, { withFileTypes: true });\n const result: { items: T[]; invalid: InvalidMemoryFile[] } = { items: [], invalid: [] };\n for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n if (!entry.isFile() || !managedName.test(entry.name)) continue;\n const path = join(directory, entry.name);\n try {\n const item = await read(path);\n const id = entry.name.slice(0, -\".md\".length);\n if (item.id !== id)\n throw new Error(`file ID ${id} differs from front matter ID ${item.id}`);\n result.items.push(item);\n } catch (error) {\n result.invalid.push({\n id: entry.name.slice(0, -\".md\".length),\n path,\n error: (error as Error).message.split(\"\\n\")[0]?.slice(0, 300) ?? \"unreadable\",\n });\n }\n }\n return result;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { items: [], invalid: [] };\n throw error;\n }\n }\n\n async deleteFact(id: string): Promise<void> {\n await rm(this.factPath(id), { force: true });\n }\n\n async markIncidentResolved(id: string, resolvedBy: string): Promise<void> {\n const fact = await this.readFact(id);\n await this.writeFact(copyFact(fact, { resolvedBy }));\n }\n\n async markFactSuperseded(id: string, supersededBy: string): Promise<void> {\n const fact = await this.readFact(id);\n await this.writeFact(copyFact(fact, { supersededBy }));\n }\n\n async setFactSharedWith(id: string, sharedWith: string[]): Promise<void> {\n const fact = await this.readFact(id);\n await this.writeFact(copyFact(fact, { sharedWith: [...new Set(sharedWith)].sort() }));\n }\n\n /** Persist interaction deletion in Markdown before the derived DB is updated. */\n async markSourceInteractionDeleted(\n namespace: string,\n sourceInteractionId: string,\n ): Promise<void> {\n const { facts } = await this.scanFacts();\n for (const fact of facts) {\n if (fact.namespace !== namespace || fact.sourceInteractionId !== sourceInteractionId)\n continue;\n if (fact.sourceDeleted) continue;\n await this.writeFact(copyFact(fact, { sourceDeleted: true }));\n }\n }\n\n /** Persist that a fact's source interaction was forgotten, keeping its provenance id. */\n async markFactSourceDeleted(id: string): Promise<void> {\n const fact = await this.readFact(id);\n await this.writeFact(copyFact(fact, { sourceDeleted: true }));\n }\n\n private factPath(id: string): string {\n if (!/^fact_[a-z0-9]+$/.test(id)) {\n throw new Error(`Invalid fact id: ${id}`);\n }\n return this.safePath(join(this.factsDirectory, `${id}.md`));\n }\n\n private summaryPath(id: string): string {\n if (!/^sum_[a-z0-9]+$/.test(id)) throw new Error(`Invalid summary id: ${id}`);\n return this.safePath(join(this.summariesDirectory, `${id}.md`));\n }\n\n private safePath(path: string): string {\n const absolute = resolve(path);\n const relativePath = relative(this.repositoryRoot, absolute);\n if (relativePath === \"..\" || relativePath.startsWith(`..${sep}`) || relativePath === \"\") {\n throw new Error(`Memory path escapes repository root: ${path}`);\n }\n return absolute;\n }\n\n private async prepareDirectory(directory: string): Promise<void> {\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(directory));\n await mkdir(directory, { recursive: true, mode: 0o700 });\n }\n}\n\nfunction copyFact(\n fact: FactFile,\n patch: Partial<Pick<FactFile, \"resolvedBy\" | \"supersededBy\" | \"sourceDeleted\" | \"sharedWith\">>,\n): FactFileWrite {\n const { path: _path, schemaVersion: _schemaVersion, type: _type, ...write } = fact;\n return { ...write, ...patch };\n}\n\nfunction stripUndefinedAndDefaultIncidentFields(\n metadata: Record<string, unknown>,\n): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(metadata).filter(([key, value]) => {\n if (value === undefined) return false;\n if (key === \"category\" && value === \"general\") return false;\n if ((key === \"paths\" || key === \"sharedWith\") && Array.isArray(value) && value.length === 0)\n return false;\n if (\n [\"severity\", \"introducedBy\", \"resolvedBy\", \"propositionKey\"].includes(key) &&\n (value === null || value === undefined)\n ) {\n return false;\n }\n return true;\n }),\n );\n}\n\nfunction normalizeMemoryPath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction severityRank(severity: IncidentSeverity): number {\n switch (severity) {\n case \"critical\":\n return 4;\n case \"high\":\n return 3;\n case \"medium\":\n return 2;\n case \"low\":\n return 1;\n }\n}\n","import type { ModelProvider } from \"../providers/adapter.js\";\nimport {\n embeddingSpace,\n embeddingSpaceKey,\n validateEmbeddingResponse,\n} from \"../providers/embedding-space.js\";\nimport { generateEntityId } from \"./ids.js\";\nimport type { EmbeddingJob, MemoryRepository, ModelCallEntry } from \"./repository.js\";\n\nexport type EmbeddingWorkerOptions = {\n repository: MemoryRepository;\n provider: ModelProvider;\n pollIntervalMs?: number;\n batchSize?: number;\n maxAttempts?: number;\n onDiagnostic?: ModelCallSink;\n};\n\nexport type ModelCallSink = (entry: ModelCallEntry) => void | Promise<void>;\n\nexport type WorkerState = \"idle\" | \"running\" | \"draining\" | \"stopped\";\n\nconst DEFAULT_POLL_MS = 250;\nconst DEFAULT_BATCH_SIZE = 8;\nconst DEFAULT_MAX_ATTEMPTS = 5;\n/** After a failed poll, wait this long before retrying so a DB outage doesn't spin. */\nconst ERROR_BACKOFF_MS = 2_000;\n\nexport class EmbeddingWorker {\n private readonly repo: MemoryRepository;\n private readonly provider: ModelProvider;\n private readonly pollIntervalMs: number;\n private readonly batchSize: number;\n private readonly maxAttempts: number;\n private readonly onDiagnostic: ModelCallSink | undefined;\n\n private state: WorkerState = \"idle\";\n private loopPromise: Promise<void> | null = null;\n private wake: (() => void) | null = null;\n private idleResolvers: Array<() => void> = [];\n private inFlight = 0;\n\n constructor(options: EmbeddingWorkerOptions) {\n this.repo = options.repository;\n this.provider = options.provider;\n this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_MS;\n this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;\n this.maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n this.onDiagnostic = options.onDiagnostic;\n }\n\n getState(): WorkerState {\n return this.state;\n }\n\n start(): void {\n // Never run two loops at once: a start() during 'draining' must not\n // overwrite loopPromise while the old loop is still finishing.\n if (this.loopPromise !== null) return;\n this.state = \"running\";\n this.loopPromise = this.loop().finally(() => {\n this.loopPromise = null;\n if (this.state === \"running\") this.state = \"idle\";\n });\n // A rejected loop must never become an unhandled rejection (Node 20 kills\n // the process); failures are contained per-iteration below.\n this.loopPromise.catch(() => {});\n }\n\n notify(): void {\n if (this.state === \"idle\" && this.loopPromise === null) this.start();\n if (this.wake) {\n const fn = this.wake;\n this.wake = null;\n fn();\n }\n }\n\n /**\n * Resolve once the worker reaches an empty poll (no in-flight jobs and\n * nothing left to claim). Retained for API compatibility: with\n * repository-side leases and backoff there is no unbounded claim window to\n * wait out anymore.\n */\n async drain(): Promise<void> {\n await new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n this.notify();\n });\n }\n\n async stop(): Promise<void> {\n if (this.state === \"stopped\" || this.state === \"idle\") {\n this.state = \"stopped\";\n return;\n }\n this.state = \"draining\";\n this.notify();\n if (this.loopPromise) {\n await this.loopPromise;\n }\n this.state = \"stopped\";\n }\n\n async shutdown(): Promise<void> {\n await this.stop();\n }\n\n getInFlight(): number {\n return this.inFlight;\n }\n\n private async loop(): Promise<void> {\n while (this.state === \"running\") {\n let jobs: EmbeddingJob[];\n try {\n jobs = await this.repo.claimPendingEmbeddings(this.batchSize);\n } catch (error) {\n // A transient DB error must never escape the loop — an escaping\n // rejection used to crash the whole MCP server process.\n console.error(\n `[worker] claimPendingEmbeddings failed: ${error instanceof Error ? error.message : String(error)}; retrying`,\n );\n if (this.state !== \"running\") break;\n // Do not let notify() interrupt outage backoff and create a hot loop.\n await new Promise((resolve) => setTimeout(resolve, ERROR_BACKOFF_MS));\n continue;\n }\n if (jobs.length === 0) {\n this.flushIdleResolvers();\n if (this.state !== \"running\") break;\n await this.sleep();\n continue;\n }\n\n this.inFlight += jobs.length;\n try {\n const outcomes = await Promise.allSettled(jobs.map((job) => this.processJob(job)));\n for (const outcome of outcomes) {\n if (outcome.status === \"rejected\") {\n console.error(`[worker] embedding job failed unexpectedly: ${String(outcome.reason)}`);\n }\n }\n } finally {\n this.inFlight -= jobs.length;\n }\n }\n this.flushIdleResolvers();\n }\n\n private flushIdleResolvers(): void {\n if (this.inFlight > 0) return;\n const resolvers = this.idleResolvers;\n this.idleResolvers = [];\n for (const resolve of resolvers) resolve();\n }\n\n private async processJob(job: EmbeddingJob): Promise<void> {\n let leaseLost = false;\n const renewal = setInterval(\n () => {\n void this.repo\n .renewEmbeddingLease(job.id, job.leaseToken)\n .then((renewed) => {\n if (!renewed) leaseLost = true;\n })\n .catch(() => {\n leaseLost = true;\n });\n },\n Math.max(250, Math.floor(job.leaseMs / 3)),\n );\n try {\n const response = await this.provider.embed({\n input: job.content,\n model: job.embeddingModel,\n });\n validateEmbeddingResponse(response, 1);\n const vector = response.vectors[0];\n if (!vector || vector.length === 0) {\n throw new Error(\"Provider returned no embedding vector.\");\n }\n if (\n leaseLost ||\n !(await this.repo.markEmbeddingReady(\n job.id,\n job.leaseToken,\n vector,\n response.model,\n embeddingSpaceKey(embeddingSpace(response)),\n ))\n )\n return;\n await this.emitDiagnostic({\n id: generateEntityId(\"mc\"),\n namespaceId: job.namespaceId,\n metadata: {\n model: response.model,\n type: \"embedding\",\n status: \"success\",\n latencyMs: 0,\n retries: 0,\n fallbackTriggered: false,\n coldStartWaitMs: 0,\n },\n });\n } catch (error) {\n const attempts = job.attempts + 1;\n const message = error instanceof Error ? error.message : String(error);\n if (leaseLost) return;\n try {\n if (\n !(await this.repo.markEmbeddingFailed(job.id, job.leaseToken, message, attempts, {\n maxAttempts: this.maxAttempts,\n }))\n )\n return;\n } catch (persistenceError) {\n console.error(\n `[worker] could not persist embedding failure: ${persistenceError instanceof Error ? persistenceError.message : String(persistenceError)}`,\n );\n return;\n }\n await this.emitDiagnostic({\n id: generateEntityId(\"mc\"),\n namespaceId: job.namespaceId,\n metadata: {\n model: job.embeddingModel,\n type: \"embedding\",\n status: attempts >= this.maxAttempts ? \"failed\" : \"fallback\",\n latencyMs: 0,\n error: message,\n retries: attempts,\n fallbackTriggered: false,\n coldStartWaitMs: 0,\n },\n });\n } finally {\n clearInterval(renewal);\n }\n }\n\n private emitDiagnostic(entry: ModelCallEntry): Promise<void> {\n const sink = this.onDiagnostic;\n if (!sink) return Promise.resolve();\n return Promise.resolve()\n .then(() => sink(entry))\n .catch(() => {\n /* diagnostic sink failure must not crash the worker */\n });\n }\n\n private sleep(ms?: number): Promise<void> {\n return new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n this.wake = null;\n resolve();\n }, ms ?? this.pollIntervalMs);\n this.wake = () => {\n clearTimeout(timer);\n resolve();\n };\n });\n }\n}\n","import pTimeout from \"p-timeout\";\nimport { REDACTED, redactPersisted } from \"../memory-extract/sensitive.js\";\nimport { clampBudgetForCallerModel, countTokens } from \"../planner/budget.js\";\nimport { DefaultPolicy } from \"../planner/default-policy.js\";\nimport type { ContextPolicy, PlanInput } from \"../planner/types.js\";\nimport type { ModelProvider } from \"../providers/adapter.js\";\nimport {\n embeddingSpace,\n embeddingSpaceKey,\n type QueryEmbedding,\n validateEmbeddingResponse,\n} from \"../providers/embedding-space.js\";\nimport { HuggingFaceProvider } from \"../providers/huggingface.js\";\nimport { DEFAULT_EMBEDDING_MODELS } from \"../providers/models.js\";\nimport { createTracer, type Tracer } from \"../tracing/langsmith.js\";\nimport { type ValidatedCodeBuddyConfig, validateConfig } from \"./config.js\";\nimport { defaultNamespaceForCwd, readConfigFile } from \"./config-file.js\";\nimport {\n computeContentHash,\n computeFactHash,\n generateEntityId,\n generateSessionId,\n generateUlid,\n} from \"./ids.js\";\nimport { type FactFile, MemoryFileStore, type SummaryFile } from \"./memory-file-store.js\";\nimport { isEligibleMemory } from \"./memory-lifecycle.js\";\nimport type {\n AuditEntry,\n FactInsert,\n FileUpsertResult,\n InteractionInsert,\n MemoryRepository,\n NamespaceRow,\n PendingEmbeddingInsert,\n ShareWriteInput,\n SummaryInsert,\n WriteResult,\n} from \"./repository.js\";\nimport type {\n CodeBuddyConfig,\n CodeBuddyStatus,\n ForgetResult,\n MemoryWriteType,\n RecallInput,\n RecallResult,\n RememberBatchItem,\n RememberInput,\n RememberResult,\n ShareInput,\n ShareResult,\n UnshareInput,\n UnshareResult,\n} from \"./types.js\";\nimport { EmbeddingWorker } from \"./worker.js\";\n\n/**\n * Recall is interactive: past this deadline it plans without a query vector\n * (the planner's no-vector fallback) instead of waiting out provider retries.\n * ponytail: fixed deadline; make it configurable if slow self-hosted providers need more.\n */\nexport const RECALL_EMBED_TIMEOUT_MS = 10_000;\n\nexport type CodeBuddyDependencies = {\n repository: MemoryRepository;\n memoryFileStore?: MemoryFileStore;\n provider?: ModelProvider;\n worker?: EmbeddingWorker;\n policy?: ContextPolicy;\n tracer?: Tracer;\n};\n\nexport class CodeBuddy {\n readonly config: ValidatedCodeBuddyConfig;\n private readonly repo: MemoryRepository;\n private readonly provider: ModelProvider;\n private readonly worker: EmbeddingWorker;\n private readonly policy: ContextPolicy;\n private readonly tracer: Tracer;\n private readonly memoryFileStore: MemoryFileStore | undefined;\n private namespaceId: string | null = null;\n private initialized = false;\n\n constructor(config: CodeBuddyConfig, deps?: CodeBuddyDependencies) {\n this.config = validateConfig(config);\n if (!deps?.repository) {\n throw new Error(\n \"CodeBuddy requires a MemoryRepository. Pass deps.repository (use createPostgresRepository for production).\",\n );\n }\n this.repo = deps.repository;\n this.memoryFileStore = deps.memoryFileStore;\n this.provider = deps.provider ?? buildProviderFromConfig(this.config.provider);\n this.worker =\n deps.worker ??\n new EmbeddingWorker({\n repository: this.repo,\n provider: this.provider,\n ...(this.config.worker?.pollIntervalMs !== undefined\n ? { pollIntervalMs: this.config.worker.pollIntervalMs }\n : {}),\n ...(this.config.worker?.batchSize !== undefined\n ? { batchSize: this.config.worker.batchSize }\n : {}),\n ...(this.config.worker?.maxAttempts !== undefined\n ? { maxAttempts: this.config.worker.maxAttempts }\n : {}),\n });\n this.policy = deps.policy ?? new DefaultPolicy();\n this.tracer = deps.tracer ?? createTracer();\n }\n\n async init(): Promise<CodeBuddyStatus> {\n const namespace = await this.repo.ensureNamespace(this.config.namespace);\n this.namespaceId = namespace.id;\n this.initialized = true;\n this.worker.start();\n return {\n ready: true,\n phase: \"runtime\",\n message: `CodeBuddy ready in namespace ${namespace.name}.`,\n namespaceId: namespace.id,\n };\n }\n\n async shutdown(): Promise<void> {\n await this.worker.shutdown();\n }\n\n getWorker(): EmbeddingWorker {\n return this.worker;\n }\n\n async remember(input: RememberInput): Promise<RememberResult> {\n const namespaceId = this.requireNamespaceId();\n const type: MemoryWriteType = input.type ?? \"interaction\";\n const sessionId = input.sessionId ?? generateSessionId();\n const content = input.content;\n if (!content || content.length === 0) {\n throw new Error(\"remember: content must not be empty.\");\n }\n const result = await this.repo.withSessionLock(namespaceId, sessionId, () =>\n this.writeOne({\n namespaceId,\n sessionId,\n type,\n content,\n idempotencyKey: input.idempotencyKey,\n ...(input.agentId !== undefined ? { agentId: input.agentId } : {}),\n }),\n );\n this.worker.notify();\n return {\n id: result.id,\n sessionId: result.sessionId,\n deduplicated: result.deduplicated,\n };\n }\n\n async rememberBatch(items: RememberBatchItem[]): Promise<RememberResult[]> {\n if (!Array.isArray(items) || items.length === 0) return [];\n const results: RememberResult[] = [];\n for (const item of items) {\n results.push(await this.remember(item));\n }\n return results;\n }\n\n async recall(input: RecallInput): Promise<RecallResult> {\n const namespaceId = this.requireNamespaceId();\n if (!input.query || input.query.length === 0) {\n throw new Error(\"recall: query must not be empty.\");\n }\n const requested = input.budget ?? this.config.tokenBudget ?? 4_000;\n const clamp = clampBudgetForCallerModel(requested, input.callerModel);\n const queryEmbedding = await this.embedQueryWithFallback(input.query);\n const planInput: PlanInput = {\n namespace: this.config.namespace,\n namespaceId,\n sessionId: input.sessionId,\n query: input.query,\n budget: clamp.budget,\n conflictMode: input.conflictMode ?? \"all\",\n queryEmbedding,\n repository: this.repo,\n ...(input.callerModel !== undefined ? { callerModel: input.callerModel } : {}),\n };\n\n const planned = await this.tracer.withSpan(\n \"codebuddy.recall\",\n {\n namespace: this.config.namespace,\n sessionId: input.sessionId,\n budget: clamp.budget,\n conflictMode: planInput.conflictMode,\n callerModel: input.callerModel ?? null,\n },\n () => this.policy.plan(planInput),\n );\n\n planned.stats.budgetClamped = clamp.clamped;\n if (clamp.clamped && clamp.reason) {\n planned.stats.budgetClampReason = clamp.reason;\n }\n return planned;\n }\n\n /** Score only eligible file facts supplied by the context engine, without generating text. */\n async rankContextFacts(task: string, factIds: string[]): Promise<Record<string, number>> {\n if (!task.trim() || factIds.length === 0) return {};\n const allowed = new Set(factIds.slice(0, 256));\n try {\n return await pTimeout(\n (async () => {\n const query = await this.embedQueryWithFallback(task.slice(0, 4096));\n if (!query) return {};\n const result = await this.repo.searchSimilarEmbeddings({\n namespaceId: this.requireNamespaceId(),\n vector: query.vector,\n embeddingSpace: embeddingSpaceKey(query.space),\n embeddingModel: query.space.model,\n limit: 256,\n });\n const scores: Record<string, number> = {};\n for (const row of result.candidates) {\n if (\n row.ownerType === \"fact\" &&\n allowed.has(row.ownerId) &&\n Number.isFinite(row.score) &&\n row.score > 0\n ) {\n scores[row.ownerId] = Math.max(scores[row.ownerId] ?? 0, Math.min(1, row.score) * 10);\n }\n }\n return scores;\n })(),\n { milliseconds: 350 },\n );\n } catch {\n return {};\n }\n }\n\n private async embedQueryWithFallback(query: string): Promise<QueryEmbedding | null> {\n try {\n const response = await this.tracer.withSpan(\n \"codebuddy.recall.embed_query\",\n { length: query.length },\n () =>\n pTimeout(this.provider.embed({ input: query }), {\n milliseconds: RECALL_EMBED_TIMEOUT_MS,\n }),\n );\n validateEmbeddingResponse(response, 1);\n const vector = response.vectors[0];\n return vector ? { vector, space: embeddingSpace(response) } : null;\n } catch {\n return null;\n }\n }\n\n /**\n * Share facts owned by the configured namespace. A reference is a live grant\n * recorded durably in the source fact's Markdown (`sharedWith`); a snapshot is\n * a copy owned by the target and written to the target project's own store.\n */\n async share(input: ShareInput): Promise<ShareResult> {\n if (!input.from || !input.to) {\n throw new Error(\"share: both 'from' and 'to' namespaces are required.\");\n }\n if (input.from === input.to) {\n throw new Error(\"share: 'from' and 'to' must differ.\");\n }\n const fromNamespaceId = this.requireNamespaceId();\n if (input.from !== this.config.namespace) {\n throw new Error(\n `share: only facts of the configured namespace \"${this.config.namespace}\" can be shared.`,\n );\n }\n if (!Array.isArray(input.factIds) || input.factIds.length === 0) {\n return { shared: 0 };\n }\n const mode = input.mode ?? \"reference\";\n let targetStore: MemoryFileStore | undefined;\n if (mode === \"snapshot\") {\n if (input.targetProjectRoot) {\n targetStore = await resolveTargetStore(input.targetProjectRoot, input.to);\n } else if (this.memoryFileStore) {\n throw new Error(\n \"share: snapshot mode requires targetProjectRoot so the copy is durable in the target project's Markdown store.\",\n );\n }\n }\n const toNs = await this.repo.ensureNamespace(input.to);\n let shared = 0;\n const embeddingModel = DEFAULT_EMBEDDING_MODELS[0]?.id ?? \"unknown\";\n\n for (const factId of input.factIds) {\n const auditId = generateEntityId(\"aud\");\n const shareId = generateEntityId(\"shr\");\n const source = await this.repo.getFactById(fromNamespaceId, factId);\n if (!source) {\n throw new Error(`share: fact ${factId} not found in namespace \"${input.from}\".`);\n }\n if (mode === \"reference\") {\n const write: ShareWriteInput = {\n id: shareId,\n fromNamespaceId,\n toNamespaceId: toNs.id,\n sourceFactId: factId,\n mode: \"reference\",\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n await this.repo.shareReference(write);\n await this.updateSharedWith(factId, (current) => [...current, toNs.name]);\n } else {\n // A snapshot must carry the source fact's actual knowledge. Fetch it\n // first: a missing fact id is an error, not a silently dangling\n // `__snapshot:` pointer.\n const snapshotContent = [\n `[shared from ${input.from}] ${source.subject} ${source.predicate} ${source.object}`,\n source.content,\n ].join(\"\\n\");\n const snapshotFactId = generateEntityId(\"fact\");\n const snapshotEmbeddingId = generateEntityId(\"emb\");\n const snapshotFact: FactInsert = {\n id: snapshotFactId,\n namespaceId: toNs.id,\n content: snapshotContent,\n contentHash: computeFactHash(toNs.name, snapshotContent),\n subject: source.subject,\n predicate: \"snapshot_of\",\n object: `${input.from}:${factId}`,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n const embedding: PendingEmbeddingInsert = {\n id: snapshotEmbeddingId,\n namespaceId: toNs.id,\n ownerType: \"fact\",\n ownerId: snapshotFactId,\n embeddingModel,\n };\n const write: ShareWriteInput = {\n id: shareId,\n fromNamespaceId,\n toNamespaceId: toNs.id,\n sourceFactId: factId,\n mode: \"snapshot\",\n snapshotFactId,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n const result = await this.repo.shareSnapshot({ share: write, snapshotFact, embedding });\n if (targetStore)\n await writeSnapshotFile(this.repo, targetStore, toNs, result.snapshotFactId);\n }\n const audit: AuditEntry = {\n id: auditId,\n namespaceId: fromNamespaceId,\n action: \"share\",\n entityType: \"fact\",\n entityId: factId,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n metadata: { mode, toNamespace: toNs.name, shareId },\n };\n await this.repo.recordAudit(audit);\n shared += 1;\n }\n this.worker.notify();\n return { shared };\n }\n\n /** Revoke live reference shares of configured-namespace facts to `to`. */\n async unshare(input: UnshareInput): Promise<UnshareResult> {\n const fromNamespaceId = this.requireNamespaceId();\n const toNs = await this.repo.getNamespaceByName(input.to);\n if (!toNs || input.factIds.length === 0) return { revoked: 0 };\n const revoked = await this.repo.revokeShares(fromNamespaceId, toNs.id, input.factIds);\n for (const factId of input.factIds) {\n await this.updateSharedWith(factId, (current) => current.filter((ns) => ns !== toNs.name));\n }\n if (revoked > 0) {\n await this.repo.recordAudit({\n id: generateEntityId(\"aud\"),\n namespaceId: fromNamespaceId,\n action: \"share\",\n entityType: \"fact\",\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n metadata: { mode: \"reference\", toNamespace: toNs.name, revoked: input.factIds },\n });\n }\n return { revoked };\n }\n\n /** Keep the source fact's durable `sharedWith` list in step with the shares table. */\n private async updateSharedWith(\n factId: string,\n next: (current: string[]) => string[],\n ): Promise<void> {\n if (!this.memoryFileStore) return;\n let file: FactFile;\n try {\n file = await this.memoryFileStore.readFact(factId);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n if (file.namespace !== this.config.namespace) return;\n await this.memoryFileStore.setFactSharedWith(factId, next(file.sharedWith));\n }\n\n async forget(id: string): Promise<ForgetResult> {\n if (!id) throw new Error(\"forget: id is required.\");\n const namespaceId = this.requireNamespaceId();\n const interactionAudit: AuditEntry = {\n id: generateEntityId(\"aud\"),\n namespaceId,\n action: \"forget\",\n entityType: \"interaction\",\n entityId: id,\n };\n const interactionResult = await this.repo.withSessionLock(\n namespaceId,\n REINDEX_LOCK_KEY,\n async () => {\n const existing = await this.repo.getInteractionsByIds(namespaceId, [id]);\n if (existing.length === 0) return { found: false, sourceDeletedFactIds: [] };\n await this.memoryFileStore?.markSourceInteractionDeleted(this.config.namespace, id);\n return this.repo.forgetInteraction(namespaceId, id, interactionAudit);\n },\n );\n if (interactionResult.found) {\n // Markdown is the source of truth: persist the lifecycle change so a\n // reindex cannot resurrect facts whose source was forgotten.\n for (const factId of interactionResult.sourceDeletedFactIds) {\n const file = await this.memoryFileStore?.readFact(factId).catch(() => null);\n if (file?.namespace === this.config.namespace) {\n await this.memoryFileStore?.markFactSourceDeleted(factId);\n }\n }\n return { ok: true, entityType: \"interaction\" };\n }\n const factAudit: AuditEntry = {\n id: generateEntityId(\"aud\"),\n namespaceId,\n action: \"forget\",\n entityType: \"fact\",\n entityId: id,\n };\n // Shares the reindex lock so a concurrent reindex that already scanned the\n // file cannot re-import the fact this call is deleting.\n const factResult = await this.repo.withSessionLock(namespaceId, REINDEX_LOCK_KEY, async () => {\n const result = await this.repo.forgetFact(namespaceId, id, factAudit);\n if (result.found) {\n const file = await this.memoryFileStore?.readFact(id).catch(() => null);\n if (file?.namespace === this.config.namespace) await this.memoryFileStore?.deleteFact(id);\n }\n return result;\n });\n if (factResult.found) return { ok: true, entityType: \"fact\" };\n return { ok: false, entityType: \"unknown\" };\n }\n\n /**\n * Reconcile the derived database with the Markdown memory files (the source\n * of truth) for this namespace: upsert by stable ID, preserving the file's\n * lifecycle metadata; re-embed only changed content; delete rows whose file\n * is gone. Only rows a reindex previously imported from Markdown\n * (`file_backed`) are ever deleted, so DB-only legacy memory survives. Each\n * file is applied independently: malformed or conflicting files are reported\n * in `failures` and never abort healthy imports (nor count as deletions).\n */\n async reindexMemory(): Promise<ReindexResult> {\n const namespaceId = this.requireNamespaceId();\n const store = this.memoryFileStore;\n if (!store) {\n throw new Error(\"Fact reindexing requires a repository-rooted MemoryFileStore.\");\n }\n const namespace = this.config.namespace;\n\n // One advisory lock per namespace serializes concurrent reindexes (two MCP\n // clients starting together) and fact forgets; files are scanned under it.\n // Each repository write inside is a savepoint, so a failing file rolls\n // back alone.\n const result = await this.repo.withSessionLock(namespaceId, REINDEX_LOCK_KEY, async () => {\n const [factScan, summaryScan] = await Promise.all([store.scanFacts(), store.scanSummaries()]);\n // Only eligible knowledge is indexed, so recall agrees with file context\n // (no deleted-source, superseded, or resolved-incident facts). An\n // ineligible file counts as absent, so its file-backed row is removed.\n const facts = factScan.facts.filter((file) => isEligibleMemory(file, { namespace }));\n const summaries = summaryScan.summaries.filter((file) => file.namespace === namespace);\n const failures: ReindexFailure[] = [\n ...factScan.invalid.map((file) => ({ kind: \"fact\" as const, ...file })),\n ...summaryScan.invalid.map((file) => ({ kind: \"summary\" as const, ...file })),\n ];\n const factCounts = emptyCounts(\n facts.length + factScan.invalid.length,\n factScan.invalid.length,\n );\n const summaryCounts = emptyCounts(\n summaries.length + summaryScan.invalid.length,\n summaryScan.invalid.length,\n );\n const apply = async (\n kind: ReindexFailure[\"kind\"],\n file: { id: string; path: string },\n counts: ReindexCounts,\n write: () => Promise<FileUpsertResult>,\n ): Promise<boolean> => {\n try {\n const { status } = await write();\n counts[status === \"inserted\" ? \"imported\" : status] += 1;\n return true;\n } catch (error) {\n counts.failed += 1;\n failures.push({ kind, id: file.id, path: file.path, error: describeError(error) });\n return false;\n }\n };\n // Remove absent file-backed rows before importing their replacements:\n // a new ID may legitimately reuse the old file's content hash. A file\n // that exists but is unreadable is not a deletion.\n const present = new Set([\n ...facts.map((file) => file.id),\n ...summaries.map((file) => file.id),\n ...factScan.invalid.map((file) => file.id),\n ...summaryScan.invalid.map((file) => file.id),\n ]);\n const owned = await this.repo.listFileBackedIds(namespaceId);\n for (const id of owned.facts.filter((id) => !present.has(id))) {\n const removed = await this.repo.forgetFact(\n namespaceId,\n id,\n reindexAudit(namespaceId, \"fact\", id),\n );\n if (removed.found) factCounts.deleted += 1;\n }\n for (const id of owned.summaries.filter((id) => !present.has(id))) {\n const removed = await this.repo.forgetSummary(\n namespaceId,\n id,\n reindexAudit(namespaceId, \"summary\", id),\n );\n if (removed.found) summaryCounts.deleted += 1;\n }\n for (const file of facts) {\n const imported = await apply(\"fact\", file, factCounts, () =>\n this.importFactFile(namespaceId, file),\n );\n // Reference shares are recorded in the source fact's front matter (#51),\n // so a rebuilt database recreates them.\n if (imported) await this.restoreShares(namespaceId, file);\n }\n for (const file of summaries) {\n await apply(\"summary\", file, summaryCounts, () =>\n this.importSummaryFile(namespaceId, file),\n );\n }\n return {\n facts: factCounts,\n summaries: summaryCounts,\n failures: failures.slice(0, MAX_REPORTED_FAILURES),\n };\n });\n this.worker.notify();\n return result;\n }\n\n async reindexFacts(): Promise<ReindexCounts> {\n return (await this.reindexMemory()).facts;\n }\n\n private requireNamespaceId(): string {\n if (!this.initialized || !this.namespaceId) {\n throw new Error(\"CodeBuddy.init() must complete before this method is called.\");\n }\n return this.namespaceId;\n }\n\n private async writeOne(input: {\n namespaceId: string;\n sessionId: string;\n type: MemoryWriteType;\n content: string;\n idempotencyKey?: string | undefined;\n agentId?: string | undefined;\n }): Promise<WriteResult> {\n const embeddingModel = DEFAULT_EMBEDDING_MODELS[0]?.id ?? \"unknown\";\n const ownerId = generateEntityId(prefixForType(input.type));\n // Facts are redacted once, here, BEFORE any persistence, so the DB row, its\n // content hash, the embedding input and the Markdown file all agree (a later\n // reindex rebuilds the same hash from the file).\n const claim = redactPersisted({\n subject: \"__inline__\",\n predicate: \"asserts\",\n object: input.content.slice(0, 200),\n content: input.content,\n });\n const content = input.type === \"fact\" ? claim.content : input.content;\n const contentHash =\n input.idempotencyKey ??\n (input.type === \"fact\"\n ? factContentHash(this.config.namespace, ownerId, content)\n : computeContentHash(this.config.namespace, input.sessionId, input.content));\n const tokenCount = estimateTokenCount(content);\n const embeddingId = generateEntityId(\"emb\");\n const embedding: PendingEmbeddingInsert = {\n id: embeddingId,\n namespaceId: input.namespaceId,\n ownerType: input.type,\n ownerId,\n embeddingModel,\n };\n const audit: AuditEntry = {\n id: generateEntityId(\"aud\"),\n namespaceId: input.namespaceId,\n action: \"remember\",\n entityType: input.type,\n entityId: ownerId,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n metadata: { sessionId: input.sessionId, type: input.type },\n };\n\n if (input.type === \"interaction\") {\n const interaction: InteractionInsert = {\n id: ownerId,\n namespaceId: input.namespaceId,\n sessionId: input.sessionId,\n content: input.content,\n contentHash,\n tokenCount,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n return this.repo.writeInteraction({ interaction, embedding, audit });\n }\n if (input.type === \"fact\") {\n const fact: FactInsert = {\n id: ownerId,\n namespaceId: input.namespaceId,\n content,\n contentHash,\n subject: claim.subject,\n predicate: claim.predicate,\n object: claim.object,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n const result = await this.repo.writeFact({ fact, embedding, audit });\n if (this.memoryFileStore) {\n if (result.deduplicated) {\n try {\n await this.memoryFileStore.readFact(result.id);\n return result;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n }\n await this.memoryFileStore.writeFact({\n id: result.id,\n namespace: this.config.namespace,\n subject: fact.subject,\n predicate: fact.predicate,\n object: fact.object,\n confidence: 1,\n createdAt: new Date().toISOString(),\n createdByAgent: input.agentId ?? null,\n sourceInteractionId: fact.sourceInteractionId ?? null,\n sourceDeleted: false,\n content: fact.content,\n });\n }\n return result;\n }\n const summary: SummaryInsert = {\n id: ownerId,\n namespaceId: input.namespaceId,\n sessionId: input.sessionId,\n content: input.content,\n tokenCount,\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n };\n const result = await this.repo.writeSummary({ summary, embedding, audit });\n if (this.memoryFileStore) {\n if (result.deduplicated) {\n try {\n await this.memoryFileStore.readSummary(result.id);\n return result;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n }\n await this.memoryFileStore.writeSummary({\n id: result.id,\n namespace: this.config.namespace,\n sessionId: result.sessionId,\n version: summary.version ?? 1,\n tokenCount: summary.tokenCount,\n createdAt: new Date().toISOString(),\n createdByAgent: input.agentId ?? null,\n content: summary.content,\n });\n }\n return result;\n }\n\n private async restoreShares(namespaceId: string, file: FactFile): Promise<void> {\n for (const to of file.sharedWith) {\n if (to === this.config.namespace) continue;\n const toNs = await this.repo.ensureNamespace(to);\n await this.repo.shareReference({\n id: generateEntityId(\"shr\"),\n fromNamespaceId: namespaceId,\n toNamespaceId: toNs.id,\n sourceFactId: file.id,\n mode: \"reference\",\n });\n }\n }\n\n private importFactFile(namespaceId: string, file: FactFile): Promise<FileUpsertResult> {\n return this.repo.upsertFactFromFile({\n fact: {\n id: file.id,\n namespaceId,\n content: file.content,\n contentHash: factContentHash(this.config.namespace, file.id, file.content),\n subject: file.subject,\n predicate: file.predicate,\n object: file.object,\n confidence: file.confidence,\n sourceInteractionId: file.sourceInteractionId ?? undefined,\n sourceDeleted: file.sourceDeleted,\n supersededBy: file.supersededBy,\n propositionKey: file.propositionKey ?? null,\n createdByAgent: file.createdByAgent ?? undefined,\n createdAt: new Date(file.createdAt),\n },\n embedding: pendingEmbedding(namespaceId, \"fact\", file.id),\n audit: {\n id: generateEntityId(\"aud\"),\n namespaceId,\n action: \"remember\",\n entityType: \"fact\",\n entityId: file.id,\n metadata: { source: \"reindex\", path: file.path },\n },\n });\n }\n\n private importSummaryFile(namespaceId: string, file: SummaryFile): Promise<FileUpsertResult> {\n return this.repo.upsertSummaryFromFile({\n summary: {\n id: file.id,\n namespaceId,\n sessionId: file.sessionId,\n content: file.content,\n version: file.version,\n tokenCount: file.tokenCount,\n createdByAgent: file.createdByAgent ?? undefined,\n createdAt: new Date(file.createdAt),\n },\n embedding: pendingEmbedding(namespaceId, \"summary\", file.id),\n audit: {\n id: generateEntityId(\"aud\"),\n namespaceId,\n action: \"remember\",\n entityType: \"summary\",\n entityId: file.id,\n metadata: { source: \"reindex\", path: file.path },\n },\n });\n }\n}\n\n/**\n * Resolve the target project's store explicitly and verify it belongs to the\n * target namespace, so a snapshot never lands under the wrong project.\n */\nasync function resolveTargetStore(root: string, namespace: string): Promise<MemoryFileStore> {\n const resolved = (await readConfigFile(root)).namespace ?? defaultNamespaceForCwd(root);\n if (resolved !== namespace) {\n throw new Error(\n `share: targetProjectRoot ${root} resolves to namespace \"${resolved}\", not \"${namespace}\".`,\n );\n }\n return new MemoryFileStore(root);\n}\n\nasync function writeSnapshotFile(\n repo: MemoryRepository,\n store: MemoryFileStore,\n namespace: NamespaceRow,\n factId: string,\n): Promise<void> {\n try {\n await store.readFact(factId);\n return;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n const fact = await repo.getFactById(namespace.id, factId);\n if (!fact)\n throw new Error(`share: snapshot ${factId} missing from namespace \"${namespace.name}\".`);\n await store.writeFact({\n id: fact.id,\n namespace: namespace.name,\n subject: fact.subject,\n predicate: fact.predicate,\n object: fact.object,\n confidence: fact.confidence,\n createdAt: fact.createdAt.toISOString(),\n createdByAgent: fact.createdByAgent,\n sourceInteractionId: null,\n sourceDeleted: false,\n content: fact.content,\n });\n}\n\nexport type ReindexCounts = {\n /** Managed files seen for this namespace (including malformed ones). */\n scanned: number;\n imported: number;\n updated: number;\n unchanged: number;\n /** File-backed rows removed because their Markdown file is gone. */\n deleted: number;\n failed: number;\n};\n\nexport type ReindexFailure = {\n kind: \"fact\" | \"summary\";\n id: string;\n path: string;\n error: string;\n};\n\nexport type ReindexResult = {\n facts: ReindexCounts;\n summaries: ReindexCounts;\n /** Per-file problems, capped at {@link MAX_REPORTED_FAILURES}; counts stay exact. */\n failures: ReindexFailure[];\n};\n\nconst REINDEX_LOCK_KEY = \"__codebuddy_markdown_reindex__\";\nconst MAX_REPORTED_FAILURES = 50;\n\nfunction emptyCounts(scanned: number, failed: number): ReindexCounts {\n return { scanned, imported: 0, updated: 0, unchanged: 0, deleted: 0, failed };\n}\n\nfunction pendingEmbedding(\n namespaceId: string,\n ownerType: MemoryWriteType,\n ownerId: string,\n): PendingEmbeddingInsert {\n return {\n id: generateEntityId(\"emb\"),\n namespaceId,\n ownerType,\n ownerId,\n embeddingModel: DEFAULT_EMBEDDING_MODELS[0]?.id ?? \"unknown\",\n };\n}\n\nfunction reindexAudit(namespaceId: string, entityType: string, entityId: string): AuditEntry {\n return {\n id: generateEntityId(\"aud\"),\n namespaceId,\n action: \"forget\",\n entityType,\n entityId,\n metadata: { source: \"reindex\", reason: \"no eligible markdown file\" },\n };\n}\n\n/** Driver errors embed the full SQL and parameters; keep only the cause. */\nfunction describeError(error: unknown): string {\n const cause = (error as { cause?: unknown }).cause;\n const message = cause instanceof Error ? cause.message : (error as Error).message;\n return String(message).split(\"\\n\")[0]?.slice(0, 300) ?? \"unknown error\";\n}\n\n/**\n * Fact content hash. Facts whose content was fully redacted all share one\n * placeholder, so the fact id is mixed in to keep distinct facts distinct\n * (the hash must not collapse them, and must not derive from the raw secret).\n * writeOne and reindex both pass the fact id, so they agree on the hash.\n */\nfunction factContentHash(namespace: string, id: string, content: string): string {\n return computeFactHash(namespace, content === REDACTED ? `${REDACTED}\\x1f${id}` : content);\n}\n\nfunction prefixForType(type: MemoryWriteType): string {\n if (type === \"interaction\") return \"int\";\n if (type === \"fact\") return \"fact\";\n return \"sum\";\n}\n\nfunction estimateTokenCount(content: string): number {\n return countTokens(content);\n}\n\nexport function newEntityId(prefix: string): string {\n return `${prefix}_${generateUlid().toLowerCase()}`;\n}\n\nfunction buildProviderFromConfig(provider: ValidatedCodeBuddyConfig[\"provider\"]): ModelProvider {\n return new HuggingFaceProvider(provider.apiKey ? { apiKey: provider.apiKey } : {});\n}\n","import { z } from \"zod\";\nimport type { CodeBuddyConfig } from \"./types.js\";\n\nconst providerSchema = z.object({\n type: z.literal(\"huggingface\"),\n apiKey: z.string().min(1).optional(),\n});\n\nexport const codeBuddyConfigSchema = z.object({\n postgresUrl: z.string().min(1, \"postgresUrl is required\"),\n provider: providerSchema,\n namespace: z\n .string()\n .min(1, \"namespace is required\")\n .max(128, \"namespace must be 128 chars or fewer\")\n .regex(/^[a-zA-Z0-9_.:-]+$/, \"namespace must match [a-zA-Z0-9_.:-]+\"),\n projectRoot: z.string().min(1).optional(),\n tokenBudget: z.number().int().positive().max(1_000_000).optional(),\n graphify: z\n .object({\n enabled: z.boolean(),\n graphPath: z.string().min(1).optional(),\n })\n .optional(),\n worker: z\n .object({\n pollIntervalMs: z.number().int().min(50).max(60_000).optional(),\n batchSize: z.number().int().min(1).max(64).optional(),\n maxAttempts: z.number().int().min(1).max(20).optional(),\n })\n .optional(),\n});\n\nexport type ValidatedCodeBuddyConfig = z.infer<typeof codeBuddyConfigSchema>;\n\nexport function validateConfig(config: CodeBuddyConfig): ValidatedCodeBuddyConfig {\n return codeBuddyConfigSchema.parse(config);\n}\n","import { createHash } from \"node:crypto\";\nimport { redactPersisted } from \"../memory-extract/sensitive.js\";\nimport type { MemoryFileStore } from \"./memory-file-store.js\";\nimport type { MemoryRepository } from \"./repository.js\";\n\nexport type MigrationConflict = {\n kind: \"fact\" | \"summary\";\n id: string;\n databaseChecksum: string;\n fileChecksum: string;\n};\n\nexport type MigrationFailure = {\n kind: \"fact\" | \"summary\";\n id: string;\n error: string;\n};\n\nexport type MigrationPreview = {\n namespace: string;\n dryRun: boolean;\n facts: { found: number; existing: number; toWrite: number; conflicts: number; written: number };\n summaries: {\n found: number;\n existing: number;\n toWrite: number;\n conflicts: number;\n written: number;\n };\n conflicts: MigrationConflict[];\n failures: MigrationFailure[];\n};\n\nexport async function migrateMemoryToFiles(input: {\n repository: MemoryRepository;\n store: MemoryFileStore;\n namespace: string;\n write: boolean;\n}): Promise<MigrationPreview> {\n const namespace = await input.repository.getNamespaceByName(input.namespace);\n if (!namespace) {\n return {\n namespace: input.namespace,\n dryRun: !input.write,\n facts: { found: 0, existing: 0, toWrite: 0, conflicts: 0, written: 0 },\n summaries: { found: 0, existing: 0, toWrite: 0, conflicts: 0, written: 0 },\n conflicts: [],\n failures: [],\n };\n }\n\n const [facts, summaries, existingFacts, existingSummaries] = await Promise.all([\n input.repository.listFacts({ namespaceId: namespace.id, limit: 100_000 }),\n input.repository.listSummaries({ namespaceId: namespace.id, limit: 100_000 }),\n input.store.listFacts(),\n input.store.listSummaries(),\n ]);\n // The DB reads are hard-capped at 100k rows; a namespace at that ceiling\n // may be silently truncated. Say so instead of implying completeness.\n const warnings =\n facts.length >= 100_000 || summaries.length >= 100_000\n ? [\n \"namespace is at or above the 100,000-row read cap; the migration may be partial — prune or export in batches\",\n ]\n : [];\n const existingFactsById = new Map(existingFacts.map((fact) => [fact.id, fact]));\n const existingSummariesById = new Map(existingSummaries.map((summary) => [summary.id, summary]));\n const conflicts: MigrationConflict[] = [];\n const failures: MigrationFailure[] = [];\n const factsToWrite = facts.filter((fact) => {\n const existing = existingFactsById.get(fact.id);\n if (!existing) return true;\n // The file holds the redacted form, so compare against that.\n const databaseChecksum = checksum(redactPersisted(fact).content);\n const fileChecksum = checksum(existing.content);\n if (databaseChecksum !== fileChecksum) {\n conflicts.push({ kind: \"fact\", id: fact.id, databaseChecksum, fileChecksum });\n }\n return false;\n });\n const summariesToWrite = summaries.filter((summary) => {\n const existing = existingSummariesById.get(summary.id);\n if (!existing) return true;\n const databaseChecksum = checksum(summary.content);\n const fileChecksum = checksum(existing.content);\n if (databaseChecksum !== fileChecksum) {\n conflicts.push({ kind: \"summary\", id: summary.id, databaseChecksum, fileChecksum });\n }\n return false;\n });\n let factsWritten = 0;\n let summariesWritten = 0;\n\n if (input.write) {\n for (const fact of factsToWrite) {\n try {\n await input.store.writeFact({\n id: fact.id,\n namespace: input.namespace,\n subject: fact.subject,\n predicate: fact.predicate,\n object: fact.object,\n confidence: fact.confidence,\n createdAt: fact.createdAt.toISOString(),\n createdByAgent: fact.createdByAgent,\n sourceInteractionId: fact.sourceInteractionId,\n sourceDeleted: fact.sourceDeleted,\n supersededBy: fact.supersededBy,\n content: fact.content,\n });\n factsWritten += 1;\n } catch (error) {\n failures.push({ kind: \"fact\", id: fact.id, error: (error as Error).message });\n }\n }\n for (const summary of summariesToWrite) {\n try {\n await input.store.writeSummary({\n id: summary.id,\n namespace: input.namespace,\n sessionId: summary.sessionId,\n version: summary.version,\n tokenCount: summary.tokenCount,\n createdAt: summary.createdAt.toISOString(),\n createdByAgent: summary.createdByAgent,\n content: summary.content,\n });\n summariesWritten += 1;\n } catch (error) {\n failures.push({ kind: \"summary\", id: summary.id, error: (error as Error).message });\n }\n }\n }\n\n const factConflicts = conflicts.filter((conflict) => conflict.kind === \"fact\").length;\n const summaryConflicts = conflicts.length - factConflicts;\n return {\n namespace: input.namespace,\n dryRun: !input.write,\n ...(warnings.length > 0 ? { warnings } : {}),\n facts: {\n found: facts.length,\n existing: facts.length - factsToWrite.length - factConflicts,\n toWrite: factsToWrite.length,\n conflicts: factConflicts,\n written: factsWritten,\n },\n summaries: {\n found: summaries.length,\n existing: summaries.length - summariesToWrite.length - summaryConflicts,\n toWrite: summariesToWrite.length,\n conflicts: summaryConflicts,\n written: summariesWritten,\n },\n conflicts,\n failures,\n };\n}\n\nfunction checksum(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n","import type { Sql } from \"postgres\";\nimport { VECTOR_DIMENSIONS } from \"./schema.js\";\n\nexport type PgvectorHealth = {\n available: boolean;\n installedVersion: string | null;\n};\n\nexport type EmbeddingDimensionCheck = {\n ok: boolean;\n expectedDimensions: number;\n configuredModels: string[];\n existingModels: string[];\n reason?: string;\n};\n\nexport async function enablePgvector(sql: Sql): Promise<void> {\n await sql`create extension if not exists vector`;\n}\n\nexport async function checkPgvector(sql: Sql): Promise<PgvectorHealth> {\n const result = await sql<{ extversion: string }[]>`\n select extversion from pg_extension where extname = 'vector'\n `;\n\n return {\n available: result.length > 0,\n installedVersion: result[0]?.extversion ?? null,\n };\n}\n\nexport async function getExistingEmbeddingModels(sql: Sql): Promise<string[]> {\n const rows = await sql<{ embedding_model: string }[]>`\n select distinct embedding_model\n from embeddings\n where embedding_model is not null\n order by embedding_model\n `;\n\n return rows.map((row) => row.embedding_model);\n}\n\nexport async function checkEmbeddingDimensionCompatibility(\n sql: Sql,\n configuredModels: Array<{ id: string; dimensions?: number }>,\n expectedDimensions = VECTOR_DIMENSIONS,\n): Promise<EmbeddingDimensionCheck> {\n const mismatchedConfiguredModel = configuredModels.find(\n (model) => model.dimensions !== expectedDimensions,\n );\n\n if (mismatchedConfiguredModel) {\n return {\n ok: false,\n expectedDimensions,\n configuredModels: configuredModels.map((model) => model.id),\n existingModels: [],\n reason: `Configured embedding model ${mismatchedConfiguredModel.id} does not match ${expectedDimensions} dimensions.`,\n };\n }\n\n const existingModels = await getExistingEmbeddingModels(sql);\n const configuredModelIds = new Set(configuredModels.map((model) => model.id));\n const unknownExistingModels = existingModels.filter((model) => !configuredModelIds.has(model));\n\n if (unknownExistingModels.length > 0) {\n return {\n ok: false,\n expectedDimensions,\n configuredModels: configuredModels.map((model) => model.id),\n existingModels,\n reason: `Existing embeddings use unconfigured models: ${unknownExistingModels.join(\", \")}.`,\n };\n }\n\n return {\n ok: true,\n expectedDimensions,\n configuredModels: configuredModels.map((model) => model.id),\n existingModels,\n };\n}\n\nexport async function bootstrapDatabase(sql: Sql): Promise<PgvectorHealth> {\n await enablePgvector(sql);\n return checkPgvector(sql);\n}\n","import { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport * as schema from \"./schema.js\";\n\nexport type DatabaseClientConfig = {\n postgresUrl: string;\n maxConnections?: number;\n};\n\nexport type DatabaseClient = ReturnType<typeof createDatabaseClient>;\n\nexport function createDatabaseClient(config: DatabaseClientConfig) {\n const sql = postgres(config.postgresUrl, {\n max: config.maxConnections ?? 10,\n // postgres.js logs NOTICE messages (e.g. \"extension already exists,\n // skipping\") to stdout by default. Over the MCP stdio transport stdout\n // carries JSON-RPC, so any notice corrupts the stream and the client\n // reports \"Unexpected token … is not valid JSON\". Route notices to\n // stderr instead, where logs belong.\n onnotice: (notice) => {\n process.stderr.write(`${JSON.stringify(notice)}\\n`);\n },\n });\n\n return {\n sql,\n db: drizzle(sql, { schema }),\n async close(): Promise<void> {\n await sql.end();\n },\n };\n}\n\nexport async function pingDatabase(client: Pick<ReturnType<typeof createDatabaseClient>, \"sql\">) {\n const result = await client.sql`select 1 as ok`;\n return result[0]?.ok === 1;\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { migrate } from \"drizzle-orm/postgres-js/migrator\";\nimport type { DatabaseClient } from \"./client.js\";\n\n/**\n * Locate the bundled migrations folder. We may be running from any of:\n * - source via tsx -> src/db/migrator.ts\n * - built dist -> dist/db.../<chunk>.js (tsup chunked layout)\n * - flat dist -> dist/index.js (single bundle)\n * - installed npm pkg -> node_modules/<pkg>/dist/... or src/db/migrations\n *\n * package.json `files` ships `src/db/migrations`, so even after publish the\n * SQL + meta files live at <pkg root>/src/db/migrations. We walk a few levels\n * up from import.meta.url looking for either `<here>/migrations` or\n * `<pkg root>/src/db/migrations`.\n */\nexport function resolveMigrationsFolder(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Co-located (src/db/ -> src/db/migrations)\n resolve(here, \"migrations\"),\n // Built dist (dist/<chunk>.js -> ../src/db/migrations relative paths)\n resolve(here, \"..\", \"src\", \"db\", \"migrations\"),\n resolve(here, \"..\", \"..\", \"src\", \"db\", \"migrations\"),\n resolve(here, \"..\", \"..\", \"..\", \"src\", \"db\", \"migrations\"),\n resolve(here, \"..\", \"..\", \"..\", \"..\", \"src\", \"db\", \"migrations\"),\n // CWD fallback (developer running from repo root)\n resolve(process.cwd(), \"src\", \"db\", \"migrations\"),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n throw new Error(\n `Could not locate migrations folder. Tried:\\n ${candidates.join(\"\\n \")}\\n` +\n `If this is an npm-installed package, make sure src/db/migrations was included in the tarball.`,\n );\n}\n\nexport async function runMigrations(client: DatabaseClient): Promise<void> {\n const migrationsFolder = resolveMigrationsFolder();\n await migrate(client.db, { migrationsFolder });\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport { and, desc, eq, inArray, isNull, lt, ne, or, type SQL, sql } from \"drizzle-orm\";\nimport { generateEntityId } from \"../core/ids.js\";\nimport { candidateLimit, lexicalTerms, validSearchVector } from \"../core/memory-search.js\";\nimport type {\n AgentWriteBreakdown,\n AuditEntry,\n EmbeddingJob,\n EmbeddingStatusSnapshot,\n FactCursor,\n FactFileUpsert,\n FactInsert,\n FileUpsertResult,\n InteractionInsert,\n LexicalFactSearchResult,\n ListedFact,\n MemoryRepository,\n MemoryStats,\n ModelCallEntry,\n NamespaceRow,\n NamespaceSummary,\n PendingEmbeddingCounts,\n PendingEmbeddingInsert,\n ReadyEmbedding,\n RecentFact,\n RecentInteraction,\n RecentSummary,\n ShareWriteInput,\n SimilaritySearchInput,\n SimilaritySearchResult,\n SummaryFileUpsert,\n SummaryInsert,\n VectorIndexHealth,\n WriteResult,\n} from \"../core/repository.js\";\nimport { embeddingSpace, embeddingSpaceKey } from \"../providers/embedding-space.js\";\nimport type { DatabaseClient } from \"./client.js\";\nimport {\n auditLog,\n embeddings,\n facts,\n interactions,\n modelCalls,\n namespaces,\n sessionSummaries,\n shares,\n} from \"./schema.js\";\n\ntype Db = DatabaseClient[\"db\"];\n\nexport class PostgresMemoryRepository implements MemoryRepository {\n private readonly client: DatabaseClient;\n private readonly sessionTransaction = new AsyncLocalStorage<Db>();\n\n constructor(client: DatabaseClient) {\n this.client = client;\n }\n\n private get db(): Db {\n return this.sessionTransaction.getStore() ?? this.client.db;\n }\n\n async ensureNamespace(name: string): Promise<NamespaceRow> {\n const existing = await this.getNamespaceByName(name);\n if (existing) return existing;\n const id = generateEntityId(\"ns\");\n await this.db\n .insert(namespaces)\n .values({ id, name })\n .onConflictDoNothing({ target: namespaces.name });\n const row = await this.getNamespaceByName(name);\n if (!row) throw new Error(`Failed to ensure namespace ${name}.`);\n return row;\n }\n\n async getNamespaceByName(name: string): Promise<NamespaceRow | null> {\n const rows = await this.db\n .select({ id: namespaces.id, name: namespaces.name })\n .from(namespaces)\n .where(eq(namespaces.name, name))\n .limit(1);\n return rows[0] ?? null;\n }\n\n async withSessionLock<T>(\n namespaceId: string,\n sessionId: string,\n fn: () => Promise<T>,\n ): Promise<T> {\n const [k1, k2] = advisoryLockKeys(namespaceId, sessionId);\n return this.client.db.transaction(async (tx) => {\n await tx.execute(sql`select pg_advisory_xact_lock(${k1}, ${k2})`);\n // Nested repository transactions become savepoints on this connection.\n // Without this context, fn() requests a second pool connection while\n // the lock holds the first and deadlocks when the pool is exhausted.\n return this.sessionTransaction.run(tx as unknown as Db, fn);\n });\n }\n\n async writeInteraction(input: {\n interaction: InteractionInsert;\n embedding: PendingEmbeddingInsert;\n audit: AuditEntry;\n }): Promise<WriteResult> {\n return this.db.transaction(async (tx) => {\n const existing = await tx\n .select({ id: interactions.id, sessionId: interactions.sessionId })\n .from(interactions)\n .where(\n and(\n eq(interactions.namespaceId, input.interaction.namespaceId),\n eq(interactions.contentHash, input.interaction.contentHash),\n ),\n )\n .limit(1);\n const existingRow = existing[0];\n if (existingRow) {\n return {\n id: existingRow.id,\n embeddingId: \"\",\n sessionId: existingRow.sessionId,\n deduplicated: true,\n };\n }\n await tx.insert(interactions).values({\n id: input.interaction.id,\n namespaceId: input.interaction.namespaceId,\n sessionId: input.interaction.sessionId,\n content: input.interaction.content,\n contentHash: input.interaction.contentHash,\n tokenCount: input.interaction.tokenCount,\n createdByAgent: input.interaction.createdByAgent ?? null,\n });\n await tx.insert(embeddings).values({\n id: input.embedding.id,\n namespaceId: input.embedding.namespaceId,\n ownerType: input.embedding.ownerType,\n ownerId: input.embedding.ownerId,\n vector: zeroVectorLiteral(),\n embeddingModel: input.embedding.embeddingModel,\n status: \"pending\",\n });\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return {\n id: input.interaction.id,\n embeddingId: input.embedding.id,\n sessionId: input.interaction.sessionId,\n deduplicated: false,\n };\n });\n }\n\n async writeFact(input: {\n fact: FactInsert;\n embedding: PendingEmbeddingInsert;\n audit: AuditEntry;\n }): Promise<WriteResult> {\n return this.db.transaction(async (tx) => {\n const existing = await tx\n .select({ id: facts.id })\n .from(facts)\n .where(\n and(\n eq(facts.namespaceId, input.fact.namespaceId),\n eq(facts.contentHash, input.fact.contentHash),\n ),\n )\n .limit(1);\n const existingRow = existing[0];\n if (existingRow) {\n return {\n id: existingRow.id,\n embeddingId: \"\",\n sessionId: \"\",\n deduplicated: true,\n };\n }\n // Same id under a different hash (e.g. a raw DB row later rebuilt from its\n // redacted Markdown) is the same fact, not a new one.\n const sameId = await tx\n .select({ id: facts.id })\n .from(facts)\n .where(eq(facts.id, input.fact.id))\n .limit(1);\n if (sameId[0]) {\n return { id: sameId[0].id, embeddingId: \"\", sessionId: \"\", deduplicated: true };\n }\n await tx.insert(facts).values({\n id: input.fact.id,\n namespaceId: input.fact.namespaceId,\n subject: input.fact.subject,\n predicate: input.fact.predicate,\n object: input.fact.object,\n content: input.fact.content,\n contentHash: input.fact.contentHash,\n propositionKey: input.fact.propositionKey ?? null,\n confidence: String(input.fact.confidence ?? 1),\n sourceDeleted: input.fact.sourceDeleted ?? false,\n supersededBy: input.fact.supersededBy ?? null,\n ...(input.fact.createdAt ? { createdAt: input.fact.createdAt } : {}),\n sourceInteractionId: input.fact.sourceInteractionId ?? null,\n createdByAgent: input.fact.createdByAgent ?? null,\n });\n await tx.insert(embeddings).values({\n id: input.embedding.id,\n namespaceId: input.embedding.namespaceId,\n ownerType: input.embedding.ownerType,\n ownerId: input.embedding.ownerId,\n vector: zeroVectorLiteral(),\n embeddingModel: input.embedding.embeddingModel,\n status: \"pending\",\n });\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return {\n id: input.fact.id,\n embeddingId: input.embedding.id,\n sessionId: \"\",\n deduplicated: false,\n };\n });\n }\n\n async writeSummary(input: {\n summary: SummaryInsert;\n embedding: PendingEmbeddingInsert;\n audit: AuditEntry;\n }): Promise<WriteResult> {\n return this.db.transaction(async (tx) => {\n const existing = await tx\n .select({ id: sessionSummaries.id, sessionId: sessionSummaries.sessionId })\n .from(sessionSummaries)\n .where(eq(sessionSummaries.id, input.summary.id))\n .limit(1);\n const existingRow = existing[0];\n if (existingRow) {\n return {\n id: existingRow.id,\n embeddingId: \"\",\n sessionId: existingRow.sessionId,\n deduplicated: true,\n };\n }\n await tx.insert(sessionSummaries).values({\n id: input.summary.id,\n namespaceId: input.summary.namespaceId,\n sessionId: input.summary.sessionId,\n content: input.summary.content,\n version: input.summary.version ?? 1,\n tokenCount: input.summary.tokenCount,\n createdByAgent: input.summary.createdByAgent ?? null,\n });\n await tx.insert(embeddings).values({\n id: input.embedding.id,\n namespaceId: input.embedding.namespaceId,\n ownerType: input.embedding.ownerType,\n ownerId: input.embedding.ownerId,\n vector: zeroVectorLiteral(),\n embeddingModel: input.embedding.embeddingModel,\n status: \"pending\",\n });\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return {\n id: input.summary.id,\n embeddingId: input.embedding.id,\n sessionId: input.summary.sessionId,\n deduplicated: false,\n };\n });\n }\n\n async upsertFactFromFile(input: {\n fact: FactFileUpsert;\n embedding: PendingEmbeddingInsert;\n audit: AuditEntry;\n }): Promise<FileUpsertResult> {\n const fact = input.fact;\n return this.db.transaction(async (tx) => {\n const [existing] = await tx\n .select()\n .from(facts)\n .where(eq(facts.id, fact.id))\n .for(\"update\")\n .limit(1);\n if (existing && existing.namespaceId !== fact.namespaceId) {\n throw new Error(`fact ${fact.id} already belongs to another namespace`);\n }\n const [duplicate] = await tx\n .select({ id: facts.id })\n .from(facts)\n .where(\n and(\n eq(facts.namespaceId, fact.namespaceId),\n eq(facts.contentHash, fact.contentHash),\n ne(facts.id, fact.id),\n ),\n )\n .limit(1);\n if (duplicate) throw new Error(`content duplicates fact ${duplicate.id}`);\n const values = {\n subject: fact.subject,\n predicate: fact.predicate,\n object: fact.object,\n content: fact.content,\n contentHash: fact.contentHash,\n confidence: String(fact.confidence),\n sourceInteractionId: fact.sourceInteractionId ?? null,\n sourceDeleted: fact.sourceDeleted,\n supersededBy: fact.supersededBy,\n propositionKey: fact.propositionKey ?? null,\n createdByAgent: fact.createdByAgent ?? null,\n createdAt: fact.createdAt,\n fileBacked: true,\n };\n if (!existing) {\n await tx.insert(facts).values({ id: fact.id, namespaceId: fact.namespaceId, ...values });\n await upsertPendingEmbedding(tx, input.embedding, true);\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return { status: \"inserted\" };\n }\n const contentChanged = existing.content !== fact.content;\n const metadataChanged =\n existing.subject !== values.subject ||\n existing.predicate !== values.predicate ||\n existing.object !== values.object ||\n Number(existing.confidence) !== Number(fact.confidence.toFixed(4)) ||\n existing.sourceInteractionId !== values.sourceInteractionId ||\n existing.sourceDeleted !== values.sourceDeleted ||\n existing.supersededBy !== values.supersededBy ||\n existing.propositionKey !== values.propositionKey ||\n existing.createdByAgent !== values.createdByAgent ||\n existing.createdAt.getTime() !== values.createdAt.getTime();\n if (contentChanged || metadataChanged || !existing.fileBacked) {\n await tx\n .update(facts)\n .set({ ...values, updatedAt: sql`now()` })\n .where(and(eq(facts.namespaceId, fact.namespaceId), eq(facts.id, fact.id)));\n }\n // Always ensure an embedding row exists (a partial DB loss may have\n // dropped it); reset it only when the embedded text changed.\n await upsertPendingEmbedding(tx, input.embedding, contentChanged);\n if (!contentChanged && !metadataChanged) return { status: \"unchanged\" };\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return { status: \"updated\" };\n });\n }\n\n async upsertSummaryFromFile(input: {\n summary: SummaryFileUpsert;\n embedding: PendingEmbeddingInsert;\n audit: AuditEntry;\n }): Promise<FileUpsertResult> {\n const summary = input.summary;\n return this.db.transaction(async (tx) => {\n const [existing] = await tx\n .select()\n .from(sessionSummaries)\n .where(eq(sessionSummaries.id, summary.id))\n .for(\"update\")\n .limit(1);\n if (existing && existing.namespaceId !== summary.namespaceId) {\n throw new Error(`summary ${summary.id} already belongs to another namespace`);\n }\n const values = {\n sessionId: summary.sessionId,\n content: summary.content,\n version: summary.version ?? 1,\n tokenCount: summary.tokenCount,\n createdByAgent: summary.createdByAgent ?? null,\n createdAt: summary.createdAt,\n fileBacked: true,\n };\n if (!existing) {\n await tx.insert(sessionSummaries).values({\n id: summary.id,\n namespaceId: summary.namespaceId,\n ...values,\n });\n await upsertPendingEmbedding(tx, input.embedding, true);\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return { status: \"inserted\" };\n }\n const contentChanged = existing.content !== summary.content;\n const metadataChanged =\n existing.sessionId !== values.sessionId ||\n existing.version !== values.version ||\n existing.tokenCount !== values.tokenCount ||\n existing.createdByAgent !== values.createdByAgent ||\n existing.createdAt.getTime() !== values.createdAt.getTime();\n if (contentChanged || metadataChanged || !existing.fileBacked) {\n await tx\n .update(sessionSummaries)\n .set(values)\n .where(\n and(\n eq(sessionSummaries.namespaceId, summary.namespaceId),\n eq(sessionSummaries.id, summary.id),\n ),\n );\n }\n await upsertPendingEmbedding(tx, input.embedding, contentChanged);\n if (!contentChanged && !metadataChanged) return { status: \"unchanged\" };\n await tx.insert(auditLog).values(toAuditRow(input.audit));\n return { status: \"updated\" };\n });\n }\n\n async listFileBackedIds(namespaceId: string): Promise<{ facts: string[]; summaries: string[] }> {\n const [factRows, summaryRows] = await Promise.all([\n this.db\n .select({ id: facts.id })\n .from(facts)\n .where(and(eq(facts.namespaceId, namespaceId), eq(facts.fileBacked, true))),\n this.db\n .select({ id: sessionSummaries.id })\n .from(sessionSummaries)\n .where(\n and(eq(sessionSummaries.namespaceId, namespaceId), eq(sessionSummaries.fileBacked, true)),\n ),\n ]);\n return { facts: factRows.map((row) => row.id), summaries: summaryRows.map((row) => row.id) };\n }\n\n /**\n * Claim up to `limit` embeddable jobs.\n *\n * A claim is a LEASE, not just a row lock: claimed rows move to\n * status='processing' with a `lease_until` deadline, so protection survives\n * the committing transaction. Concurrent workers (e.g. Claude Desktop and\n * Codex both running `codebuddy serve`) therefore never process the same\n * item twice. Expired leases are re-claimable, so a crashed worker's work is\n * picked up again instead of being stuck forever.\n */\n async claimPendingEmbeddings(limit: number): Promise<EmbeddingJob[]> {\n const rows = await this.client.sql<\n {\n id: string;\n lease_token: string;\n namespace_id: string;\n owner_type: \"interaction\" | \"fact\" | \"summary\";\n owner_id: string;\n embedding_model: string;\n attempts: number;\n content: string;\n }[]\n >`\n with claimed as (\n select id from embeddings\n where status = 'pending'\n or (status = 'processing' and (lease_until is null or lease_until < now()))\n order by created_at asc\n for update skip locked\n limit ${limit}\n )\n update embeddings e\n set status = 'processing',\n lease_until = now() + interval '120 seconds',\n lease_token = ${generateEntityId(\"lease\")},\n updated_at = now()\n from claimed\n where e.id = claimed.id\n returning\n e.id,\n e.lease_token,\n e.namespace_id,\n e.owner_type,\n e.owner_id,\n e.embedding_model,\n e.attempts,\n coalesce(\n (select content from interactions where id = e.owner_id),\n (select content from facts where id = e.owner_id),\n (select content from session_summaries where id = e.owner_id)\n ) as content\n `;\n return rows.map((row) => ({\n id: row.id,\n leaseToken: row.lease_token,\n leaseMs: 120_000,\n namespaceId: row.namespace_id,\n ownerType: row.owner_type,\n ownerId: row.owner_id,\n embeddingModel: row.embedding_model,\n attempts: row.attempts,\n content: row.content ?? \"\",\n }));\n }\n\n async renewEmbeddingLease(id: string, leaseToken: string): Promise<boolean> {\n const rows = await this.db\n .update(embeddings)\n .set({ leaseUntil: sql`now() + interval '120 seconds'` })\n .where(\n and(\n eq(embeddings.id, id),\n eq(embeddings.leaseToken, leaseToken),\n eq(embeddings.status, \"processing\"),\n sql`${embeddings.leaseUntil} > now()`,\n ),\n )\n .returning({ id: embeddings.id });\n return rows.length > 0;\n }\n\n async markEmbeddingReady(\n id: string,\n leaseToken: string,\n vector: number[],\n model: string,\n space?: string,\n ): Promise<boolean> {\n const literal = `[${vector.join(\",\")}]`;\n const rows = await this.db\n .update(embeddings)\n .set({\n status: \"ready\",\n vector: literal,\n embeddingModel: model,\n embeddingSpace:\n space ?? embeddingSpaceKey(embeddingSpace({ model, dimensions: vector.length })),\n lastError: null,\n leaseUntil: null,\n leaseToken: null,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n eq(embeddings.id, id),\n eq(embeddings.leaseToken, leaseToken),\n eq(embeddings.status, \"processing\"),\n sql`${embeddings.leaseUntil} > now()`,\n ),\n )\n .returning({ id: embeddings.id });\n return rows.length > 0;\n }\n\n /**\n * Record a failure. Below `maxAttempts`, the row goes back to\n * 'processing' with an exponentially growing lease (2s · 2^(attempts-1),\n * capped at 60s) that acts as a retry backoff timer — a rate-limited\n * endpoint is no longer hammered every poll tick. At `maxAttempts` the job\n * is parked as 'failed'.\n */\n async markEmbeddingFailed(\n id: string,\n leaseToken: string,\n error: string,\n attempts: number,\n options?: { maxAttempts?: number },\n ): Promise<boolean> {\n const maxAttempts = options?.maxAttempts ?? 5;\n const backoffSeconds = Math.min(60, 2 ** Math.max(0, attempts - 1));\n const rows = await this.db\n .update(embeddings)\n .set({\n status: sql`case when ${attempts} >= ${maxAttempts} then 'failed'::embedding_status else 'processing'::embedding_status end`,\n leaseUntil: sql`case when ${attempts} >= ${maxAttempts} then null else now() + (${backoffSeconds} || ' seconds')::interval end`,\n leaseToken: null,\n attempts,\n lastError: error,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n eq(embeddings.id, id),\n eq(embeddings.leaseToken, leaseToken),\n eq(embeddings.status, \"processing\"),\n sql`${embeddings.leaseUntil} > now()`,\n ),\n )\n .returning({ id: embeddings.id });\n return rows.length > 0;\n }\n\n async getEmbeddingStatus(id: string): Promise<EmbeddingStatusSnapshot | null> {\n const rows = await this.db\n .select({\n id: embeddings.id,\n status: embeddings.status,\n attempts: embeddings.attempts,\n lastError: embeddings.lastError,\n })\n .from(embeddings)\n .where(eq(embeddings.id, id))\n .limit(1);\n const row = rows[0];\n if (!row) return null;\n return {\n id: row.id,\n status: row.status,\n attempts: row.attempts,\n lastError: row.lastError,\n };\n }\n\n async shareReference(input: ShareWriteInput): Promise<void> {\n await this.db\n .insert(shares)\n .values({\n id: input.id,\n fromNamespaceId: input.fromNamespaceId,\n toNamespaceId: input.toNamespaceId,\n sourceFactId: input.sourceFactId,\n mode: \"reference\",\n createdByAgent: input.createdByAgent ?? null,\n })\n .onConflictDoUpdate({\n target: [shares.toNamespaceId, shares.sourceFactId, shares.mode],\n set: { tombstoned: false },\n });\n }\n\n async revokeShares(\n fromNamespaceId: string,\n toNamespaceId: string,\n factIds: string[],\n ): Promise<number> {\n if (factIds.length === 0) return 0;\n const revoked = await this.db\n .update(shares)\n .set({ tombstoned: true })\n .where(\n and(\n eq(shares.fromNamespaceId, fromNamespaceId),\n eq(shares.toNamespaceId, toNamespaceId),\n eq(shares.mode, \"reference\"),\n eq(shares.tombstoned, false),\n inArray(shares.sourceFactId, factIds),\n ),\n )\n .returning({ id: shares.id });\n return revoked.length;\n }\n\n async shareSnapshot(input: {\n share: ShareWriteInput;\n snapshotFact: FactInsert;\n embedding: PendingEmbeddingInsert;\n }): Promise<{ snapshotFactId: string }> {\n return this.db.transaction(async (tx) => {\n const prior = await tx\n .select({ snapshotFactId: shares.snapshotFactId })\n .from(shares)\n .where(\n and(\n eq(shares.toNamespaceId, input.share.toNamespaceId),\n eq(shares.sourceFactId, input.share.sourceFactId),\n eq(shares.mode, \"snapshot\"),\n ),\n )\n .limit(1);\n const priorId = prior[0]?.snapshotFactId;\n if (priorId) return { snapshotFactId: priorId };\n // An identical copy may already exist (e.g. rebuilt from the target's Markdown).\n const copy = await tx\n .select({ id: facts.id })\n .from(facts)\n .where(\n and(\n eq(facts.namespaceId, input.snapshotFact.namespaceId),\n eq(facts.contentHash, input.snapshotFact.contentHash),\n ),\n )\n .limit(1);\n const snapshotFactId = copy[0]?.id ?? input.snapshotFact.id;\n if (!copy[0]) {\n await tx.insert(facts).values({\n id: input.snapshotFact.id,\n namespaceId: input.snapshotFact.namespaceId,\n subject: input.snapshotFact.subject,\n predicate: input.snapshotFact.predicate,\n object: input.snapshotFact.object,\n content: input.snapshotFact.content,\n contentHash: input.snapshotFact.contentHash,\n sourceInteractionId: input.snapshotFact.sourceInteractionId ?? null,\n createdByAgent: input.snapshotFact.createdByAgent ?? null,\n });\n await tx.insert(embeddings).values({\n id: input.embedding.id,\n namespaceId: input.embedding.namespaceId,\n ownerType: input.embedding.ownerType,\n ownerId: input.embedding.ownerId,\n vector: zeroVectorLiteral(),\n embeddingModel: input.embedding.embeddingModel,\n status: \"pending\",\n });\n }\n await tx\n .insert(shares)\n .values({\n id: input.share.id,\n fromNamespaceId: input.share.fromNamespaceId,\n toNamespaceId: input.share.toNamespaceId,\n sourceFactId: input.share.sourceFactId,\n snapshotFactId,\n mode: \"snapshot\",\n createdByAgent: input.share.createdByAgent ?? null,\n })\n .onConflictDoUpdate({\n target: [shares.toNamespaceId, shares.sourceFactId, shares.mode],\n set: { snapshotFactId },\n });\n return { snapshotFactId };\n });\n }\n\n async forgetInteraction(\n namespaceId: string,\n id: string,\n audit: AuditEntry,\n ): Promise<{ found: boolean; sourceDeletedFactIds: string[] }> {\n return this.db.transaction(async (tx) => {\n // Lock the interaction first: concurrent fact inserts referencing it\n // block on the FK check, so no dependent can slip past the marking.\n const existing = await tx\n .select({ id: interactions.id })\n .from(interactions)\n .where(and(eq(interactions.namespaceId, namespaceId), eq(interactions.id, id)))\n .for(\"update\");\n if (existing.length === 0) return { found: false, sourceDeletedFactIds: [] };\n // Mark dependents BEFORE the delete: the FK is ON DELETE SET NULL, so\n // afterwards nothing would match source_interaction_id.\n const marked = await tx\n .update(facts)\n .set({ sourceDeleted: true })\n .where(and(eq(facts.namespaceId, namespaceId), eq(facts.sourceInteractionId, id)))\n .returning({ id: facts.id });\n await tx\n .delete(interactions)\n .where(and(eq(interactions.namespaceId, namespaceId), eq(interactions.id, id)));\n await tx\n .delete(embeddings)\n .where(\n and(\n eq(embeddings.namespaceId, namespaceId),\n eq(embeddings.ownerType, \"interaction\"),\n eq(embeddings.ownerId, id),\n ),\n );\n await tx.insert(auditLog).values(toAuditRow(audit));\n return { found: true, sourceDeletedFactIds: marked.map((row) => row.id) };\n });\n }\n\n async forgetFact(\n namespaceId: string,\n id: string,\n audit: AuditEntry,\n ): Promise<{ found: boolean }> {\n return this.db.transaction(async (tx) => {\n const deleted = await tx\n .delete(facts)\n .where(and(eq(facts.namespaceId, namespaceId), eq(facts.id, id)))\n .returning({ id: facts.id });\n if (deleted.length === 0) return { found: false };\n await tx\n .delete(embeddings)\n .where(\n and(\n eq(embeddings.namespaceId, namespaceId),\n eq(embeddings.ownerType, \"fact\"),\n eq(embeddings.ownerId, id),\n ),\n );\n await tx\n .update(shares)\n .set({ tombstoned: true })\n .where(\n and(\n eq(shares.fromNamespaceId, namespaceId),\n eq(shares.sourceFactId, id),\n eq(shares.mode, \"reference\"),\n ),\n );\n await tx.insert(auditLog).values(toAuditRow(audit));\n return { found: true };\n });\n }\n\n async forgetSummary(\n namespaceId: string,\n id: string,\n audit: AuditEntry,\n ): Promise<{ found: boolean }> {\n return this.db.transaction(async (tx) => {\n const deleted = await tx\n .delete(sessionSummaries)\n .where(and(eq(sessionSummaries.namespaceId, namespaceId), eq(sessionSummaries.id, id)))\n .returning({ id: sessionSummaries.id });\n if (deleted.length === 0) return { found: false };\n await tx\n .delete(embeddings)\n .where(\n and(\n eq(embeddings.namespaceId, namespaceId),\n eq(embeddings.ownerType, \"summary\"),\n eq(embeddings.ownerId, id),\n ),\n );\n await tx.insert(auditLog).values(toAuditRow(audit));\n return { found: true };\n });\n }\n\n async recordModelCall(entry: ModelCallEntry): Promise<void> {\n await this.db.insert(modelCalls).values({\n id: entry.id,\n namespaceId: entry.namespaceId ?? null,\n model: entry.metadata.model,\n type: entry.metadata.type,\n latencyMs: entry.metadata.latencyMs,\n tokens: entry.metadata.tokens ?? null,\n status: entry.metadata.status,\n error: entry.metadata.error ?? null,\n metadata: {\n retries: entry.metadata.retries,\n fallbackTriggered: entry.metadata.fallbackTriggered,\n coldStartWaitMs: entry.metadata.coldStartWaitMs,\n },\n });\n }\n\n async recordAudit(entry: AuditEntry): Promise<void> {\n await this.db.insert(auditLog).values(toAuditRow(entry));\n }\n\n async getReadyEmbeddings(\n namespaceId: string,\n limit: number,\n space?: string,\n ): Promise<ReadyEmbedding[]> {\n const rows = await this.client.sql<\n {\n id: string;\n owner_type: \"interaction\" | \"fact\" | \"summary\";\n owner_id: string;\n embedding_model: string;\n embedding_space: string | null;\n vector: string;\n }[]\n >`\n select e.id, e.owner_type, e.owner_id, e.embedding_model, e.embedding_space,\n e.vector::text as vector\n from embeddings e\n where e.status = 'ready'\n and (${space ?? null}::text is null or e.embedding_space = ${space ?? null})\n and (\n e.namespace_id = ${namespaceId}\n or (\n e.owner_type = 'fact'\n and exists (\n select 1 from shares s\n where s.to_namespace_id = ${namespaceId}\n and s.from_namespace_id = e.namespace_id\n and s.source_fact_id = e.owner_id\n and s.mode = 'reference'\n and not s.tombstoned\n )\n )\n )\n order by e.updated_at desc\n limit ${limit}\n `;\n return rows.map((row) => ({\n embeddingId: row.id,\n ownerType: row.owner_type,\n ownerId: row.owner_id,\n embeddingModel: row.embedding_model,\n embeddingSpace: row.embedding_space,\n vector: parseVectorLiteral(row.vector),\n }));\n }\n\n async searchSimilarEmbeddings(input: SimilaritySearchInput): Promise<SimilaritySearchResult> {\n if (!validSearchVector(input.vector))\n return { method: \"exact_pgvector\", candidates: [], compatibleReady: 0 };\n // Materialization deliberately gives exact coverage of the filtered space.\n // HNSW post-filters can underfill a namespace/model result or miss its best row.\n // Only bounded IDs/scores cross the DB boundary; never download the vectors.\n const rows = await this.db.execute<{\n id: string;\n owner_type: \"interaction\" | \"fact\" | \"summary\";\n owner_id: string;\n embedding_model: string;\n embedding_space: string | null;\n score: number;\n total: string;\n }>(sql`\n with compatible as materialized (\n select id, owner_type, owner_id, embedding_model, embedding_space, vector\n from embeddings\n where status = 'ready'\n and (\n namespace_id = ${input.namespaceId}\n or (\n owner_type = 'fact'\n and ${liveReference(input.namespaceId, sql`embeddings.namespace_id`, sql`embeddings.owner_id`)}\n )\n )\n and embedding_space = ${input.embeddingSpace}\n and embedding_model = ${input.embeddingModel}\n and vector_norm(vector) > 0\n and not exists (\n select 1 from facts f\n where owner_type = 'fact' and f.namespace_id = embeddings.namespace_id\n and f.id = embeddings.owner_id\n and (f.source_deleted or f.superseded_by is not null)\n )\n )\n select id, owner_type, owner_id, embedding_model, embedding_space,\n 1 - (vector <=> ${JSON.stringify(input.vector)}::vector) as score,\n count(*) over () as total\n from compatible\n order by vector <=> ${JSON.stringify(input.vector)}::vector, id collate \"C\"\n limit ${candidateLimit(input.limit)}\n `);\n return {\n method: \"exact_pgvector\",\n compatibleReady: Number(rows[0]?.total ?? 0),\n candidates: rows.map((row) => ({\n embeddingId: row.id,\n ownerType: row.owner_type,\n ownerId: row.owner_id,\n embeddingModel: row.embedding_model,\n embeddingSpace: row.embedding_space,\n score: Number(row.score),\n })),\n };\n }\n\n async searchFactsLexically(\n namespaceId: string,\n query: string,\n limit: number,\n ): Promise<LexicalFactSearchResult> {\n const terms = lexicalTerms(query);\n if (!terms.length) return { candidates: [], matchedFacts: 0 };\n const rows = await this.db.execute<{\n id: string;\n content: string;\n subject: string;\n predicate: string;\n object: string;\n proposition_key: string | null;\n confidence: string;\n created_by_agent: string | null;\n created_at: Date;\n score: number;\n total: string;\n }>(sql`\n with scored as materialized (\n select id, content, subject, predicate, object, proposition_key, confidence,\n created_by_agent, created_at,\n (select coalesce(sum(\n (case when strpos(' ' || regexp_replace(lower(subject || ' ' || object), '[^[:alnum:]_]+', ' ', 'g') || ' ', ' ' || term || ' ') > 0 then 2 else 0 end) +\n (case when strpos(' ' || regexp_replace(lower(content), '[^[:alnum:]_]+', ' ', 'g') || ' ', ' ' || term || ' ') > 0 then 1 else 0 end)\n ), 0)::float / ${3 * terms.length} from\n jsonb_array_elements_text(${JSON.stringify(terms)}::jsonb) term\n ) as score\n from facts\n where not source_deleted and superseded_by is null\n and (\n namespace_id = ${namespaceId}\n or ${liveReference(namespaceId, sql`facts.namespace_id`, sql`facts.id`)}\n )\n )\n select *, count(*) over () as total from scored where score > 0\n order by score desc, created_at desc, id collate \"C\"\n limit ${candidateLimit(limit)}\n `);\n return {\n matchedFacts: Number(rows[0]?.total ?? 0),\n candidates: rows.map((row) => ({\n id: row.id,\n content: row.content,\n subject: row.subject,\n predicate: row.predicate,\n object: row.object,\n propositionKey: row.proposition_key,\n confidence: Number(row.confidence),\n sourceDeleted: false,\n supersededBy: null,\n createdByAgent: row.created_by_agent,\n createdAt: new Date(row.created_at),\n score: Number(row.score),\n })),\n };\n }\n\n async getRecentInteractions(\n namespaceId: string,\n sessionId: string,\n limit: number,\n ): Promise<RecentInteraction[]> {\n const rows = await this.db\n .select({\n id: interactions.id,\n sessionId: interactions.sessionId,\n content: interactions.content,\n tokenCount: interactions.tokenCount,\n createdAt: interactions.createdAt,\n })\n .from(interactions)\n .where(and(eq(interactions.namespaceId, namespaceId), eq(interactions.sessionId, sessionId)))\n .orderBy(desc(interactions.createdAt))\n .limit(limit);\n return rows.map((row) => ({ ...row, createdAt: row.createdAt }));\n }\n\n async getRecentFacts(namespaceId: string, limit: number): Promise<RecentFact[]> {\n const rows = await this.db\n .select(recentFactColumns)\n .from(facts)\n .where(\n and(\n eq(facts.namespaceId, namespaceId),\n eq(facts.sourceDeleted, false),\n isNull(facts.supersededBy),\n ),\n )\n .orderBy(desc(facts.createdAt))\n .limit(limit);\n return rows.map((row) => ({ ...row, confidence: Number(row.confidence ?? 1) }));\n }\n\n async getLatestSummary(namespaceId: string, sessionId: string): Promise<RecentSummary | null> {\n const rows = await this.db\n .select({\n id: sessionSummaries.id,\n sessionId: sessionSummaries.sessionId,\n content: sessionSummaries.content,\n tokenCount: sessionSummaries.tokenCount,\n createdAt: sessionSummaries.createdAt,\n })\n .from(sessionSummaries)\n .where(\n and(\n eq(sessionSummaries.namespaceId, namespaceId),\n eq(sessionSummaries.sessionId, sessionId),\n ),\n )\n .orderBy(desc(sessionSummaries.version))\n .limit(1);\n return rows[0] ?? null;\n }\n\n async getInteractionsByIds(namespaceId: string, ids: string[]): Promise<RecentInteraction[]> {\n if (ids.length === 0) return [];\n const rows = await this.db\n .select({\n id: interactions.id,\n sessionId: interactions.sessionId,\n content: interactions.content,\n tokenCount: interactions.tokenCount,\n createdAt: interactions.createdAt,\n })\n .from(interactions)\n .where(and(eq(interactions.namespaceId, namespaceId), inArray(interactions.id, ids)));\n return rows;\n }\n\n async getFactsByIds(namespaceId: string, ids: string[]): Promise<RecentFact[]> {\n if (ids.length === 0) return [];\n const rows = await this.db\n .select(recentFactColumns)\n .from(facts)\n .where(\n and(\n inArray(facts.id, ids),\n isNull(facts.supersededBy),\n or(\n eq(facts.namespaceId, namespaceId),\n liveReference(namespaceId, sql`${facts.namespaceId}`, sql`${facts.id}`),\n ),\n ),\n );\n return rows.map((row) => ({ ...row, confidence: Number(row.confidence ?? 1) }));\n }\n\n async getSummariesByIds(namespaceId: string, ids: string[]): Promise<RecentSummary[]> {\n if (ids.length === 0) return [];\n const rows = await this.db\n .select({\n id: sessionSummaries.id,\n sessionId: sessionSummaries.sessionId,\n content: sessionSummaries.content,\n tokenCount: sessionSummaries.tokenCount,\n createdAt: sessionSummaries.createdAt,\n })\n .from(sessionSummaries)\n .where(and(eq(sessionSummaries.namespaceId, namespaceId), inArray(sessionSummaries.id, ids)));\n return rows;\n }\n\n async getFactById(namespaceId: string, id: string): Promise<ListedFact | null> {\n const rows = await this.db\n .select({\n id: facts.id,\n subject: facts.subject,\n predicate: facts.predicate,\n object: facts.object,\n content: facts.content,\n confidence: facts.confidence,\n sourceInteractionId: facts.sourceInteractionId,\n sourceDeleted: facts.sourceDeleted,\n supersededBy: facts.supersededBy,\n createdByAgent: facts.createdByAgent,\n createdAt: facts.createdAt,\n })\n .from(facts)\n .where(and(eq(facts.namespaceId, namespaceId), eq(facts.id, id)))\n .limit(1);\n const row = rows[0];\n if (!row) return null;\n return { ...row, confidence: Number(row.confidence ?? 1) };\n }\n\n async countEmbeddingStatuses(namespaceId: string): Promise<PendingEmbeddingCounts> {\n const rows = await this.client.sql<{ status: string; count: string }[]>`\n select status::text as status, count(*)::text as count\n from embeddings\n where namespace_id = ${namespaceId}\n group by status\n `;\n let pending = 0;\n let processing = 0;\n let failed = 0;\n let ready = 0;\n for (const row of rows) {\n const value = Number(row.count);\n if (row.status === \"pending\") pending = value;\n else if (row.status === \"processing\") processing = value;\n else if (row.status === \"failed\") failed = value;\n else if (row.status === \"ready\") ready = value;\n }\n return { pending, processing, failed, ready };\n }\n\n async listFacts(input: {\n namespaceId: string;\n subject?: string;\n limit: number;\n cursor?: FactCursor;\n }): Promise<ListedFact[]> {\n const where = [\n eq(facts.namespaceId, input.namespaceId),\n eq(facts.sourceDeleted, false),\n isNull(facts.supersededBy),\n input.subject ? eq(facts.subject, input.subject) : undefined,\n input.cursor\n ? or(\n lt(facts.createdAt, input.cursor.createdAt),\n and(eq(facts.createdAt, input.cursor.createdAt), lt(facts.id, input.cursor.id)),\n )\n : undefined,\n ].filter((clause): clause is NonNullable<typeof clause> => Boolean(clause));\n const rows = await this.db\n .select({\n id: facts.id,\n subject: facts.subject,\n predicate: facts.predicate,\n object: facts.object,\n content: facts.content,\n confidence: facts.confidence,\n sourceInteractionId: facts.sourceInteractionId,\n sourceDeleted: facts.sourceDeleted,\n supersededBy: facts.supersededBy,\n createdByAgent: facts.createdByAgent,\n createdAt: facts.createdAt,\n })\n .from(facts)\n .where(and(...where))\n .orderBy(desc(facts.createdAt), desc(facts.id))\n .limit(input.limit);\n return rows.map((row) => ({ ...row, confidence: Number(row.confidence ?? 1) }));\n }\n\n async listSummaries(input: {\n namespaceId: string;\n limit: number;\n }): Promise<import(\"../core/repository.js\").ListedSummary[]> {\n return this.db\n .select({\n id: sessionSummaries.id,\n sessionId: sessionSummaries.sessionId,\n content: sessionSummaries.content,\n version: sessionSummaries.version,\n tokenCount: sessionSummaries.tokenCount,\n createdByAgent: sessionSummaries.createdByAgent,\n createdAt: sessionSummaries.createdAt,\n })\n .from(sessionSummaries)\n .where(eq(sessionSummaries.namespaceId, input.namespaceId))\n .orderBy(desc(sessionSummaries.createdAt))\n .limit(input.limit);\n }\n\n async listNamespaces(): Promise<NamespaceSummary[]> {\n const rows = await this.client.sql<\n { name: string; fact_count: string; last_activity: Date | null }[]\n >`\n select\n n.name,\n count(f.id)::text as fact_count,\n greatest(\n max(f.created_at),\n max(i.created_at),\n max(s.created_at),\n n.updated_at\n ) as last_activity\n from namespaces n\n left join facts f on f.namespace_id = n.id and f.source_deleted = false\n left join interactions i on i.namespace_id = n.id\n left join session_summaries s on s.namespace_id = n.id\n group by n.id, n.name, n.updated_at\n order by last_activity desc nulls last, n.name asc\n `;\n return rows.map((row) => ({\n name: row.name,\n factCount: Number(row.fact_count),\n lastActivity: row.last_activity,\n }));\n }\n\n async getAgentWriteBreakdown(namespaceId?: string): Promise<AgentWriteBreakdown[]> {\n const rows = namespaceId\n ? await this.client.sql<{ agent_id: string | null; writes: string }[]>`\n select agent_id, sum(writes)::text as writes\n from (\n select created_by_agent as agent_id, count(*) as writes from interactions where namespace_id = ${namespaceId} group by created_by_agent\n union all\n select created_by_agent as agent_id, count(*) as writes from facts where namespace_id = ${namespaceId} group by created_by_agent\n union all\n select created_by_agent as agent_id, count(*) as writes from session_summaries where namespace_id = ${namespaceId} group by created_by_agent\n ) t\n group by agent_id\n order by writes desc\n `\n : await this.client.sql<{ agent_id: string | null; writes: string }[]>`\n select agent_id, sum(writes)::text as writes\n from (\n select created_by_agent as agent_id, count(*) as writes from interactions group by created_by_agent\n union all\n select created_by_agent as agent_id, count(*) as writes from facts group by created_by_agent\n union all\n select created_by_agent as agent_id, count(*) as writes from session_summaries group by created_by_agent\n ) t\n group by agent_id\n order by writes desc\n `;\n return rows.map((row) => ({ agentId: row.agent_id, writes: Number(row.writes) }));\n }\n\n async getStats(namespaceId?: string): Promise<MemoryStats> {\n const namespaceRows = await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from namespaces`;\n const interactionRows = namespaceId\n ? await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from interactions where namespace_id = ${namespaceId}`\n : await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from interactions`;\n const factRows = namespaceId\n ? await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from facts where namespace_id = ${namespaceId}`\n : await this.client.sql<{ count: string }[]>`select count(*)::text as count from facts`;\n const summaryRows = namespaceId\n ? await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from session_summaries where namespace_id = ${namespaceId}`\n : await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from session_summaries`;\n const embeddingRows = namespaceId\n ? await this.client.sql<{ status: string; count: string }[]>`\n select status::text as status, count(*)::text as count from embeddings where namespace_id = ${namespaceId} group by status\n `\n : await this.client.sql<{ status: string; count: string }[]>`\n select status::text as status, count(*)::text as count from embeddings group by status\n `;\n const callRows = namespaceId\n ? await this.client.sql<\n { last_60s: string; last_hour: string; last_24h: string; gated_failures: string }[]\n >`\n select\n count(*) filter (where created_at >= now() - interval '60 seconds')::text as last_60s,\n count(*) filter (where created_at >= now() - interval '1 hour')::text as last_hour,\n count(*) filter (where created_at >= now() - interval '24 hours')::text as last_24h,\n count(*) filter (where status = 'gated' and created_at >= now() - interval '24 hours')::text as gated_failures\n from model_calls\n where namespace_id = ${namespaceId}\n `\n : await this.client.sql<\n { last_60s: string; last_hour: string; last_24h: string; gated_failures: string }[]\n >`\n select\n count(*) filter (where created_at >= now() - interval '60 seconds')::text as last_60s,\n count(*) filter (where created_at >= now() - interval '1 hour')::text as last_hour,\n count(*) filter (where created_at >= now() - interval '24 hours')::text as last_24h,\n count(*) filter (where status = 'gated' and created_at >= now() - interval '24 hours')::text as gated_failures\n from model_calls\n `;\n const embeddingsCount = { pending: 0, processing: 0, failed: 0, ready: 0 };\n for (const row of embeddingRows) {\n if (row.status === \"pending\") embeddingsCount.pending = Number(row.count);\n if (row.status === \"processing\") embeddingsCount.processing = Number(row.count);\n if (row.status === \"failed\") embeddingsCount.failed = Number(row.count);\n if (row.status === \"ready\") embeddingsCount.ready = Number(row.count);\n }\n const calls = callRows[0] ?? {\n last_60s: \"0\",\n last_hour: \"0\",\n last_24h: \"0\",\n gated_failures: \"0\",\n };\n return {\n namespaces: Number(namespaceRows[0]?.count ?? 0),\n interactions: Number(interactionRows[0]?.count ?? 0),\n facts: Number(factRows[0]?.count ?? 0),\n summaries: Number(summaryRows[0]?.count ?? 0),\n embeddings: embeddingsCount,\n modelCalls: {\n last60s: Number(calls.last_60s),\n lastHour: Number(calls.last_hour),\n last24h: Number(calls.last_24h),\n gatedFailures: Number(calls.gated_failures),\n },\n };\n }\n\n async pruneBefore(\n cutoff: Date,\n ): Promise<{ interactions: number; facts: number; summaries: number }> {\n return this.db.transaction(async (tx) => {\n // Embeddings have no FK on owner_id, so pruned owners must have their\n // embedding rows removed explicitly — otherwise orphan vectors bloat\n // the HNSW index forever and consume recall limit slots.\n const deletedInteractions = await tx\n .delete(interactions)\n .where(lt(interactions.createdAt, cutoff))\n .returning({ id: interactions.id });\n if (deletedInteractions.length > 0) {\n await tx.delete(embeddings).where(\n and(\n eq(embeddings.ownerType, \"interaction\"),\n inArray(\n embeddings.ownerId,\n deletedInteractions.map((row) => row.id),\n ),\n ),\n );\n }\n const deletedFacts = await tx\n .delete(facts)\n .where(lt(facts.createdAt, cutoff))\n .returning({ id: facts.id });\n if (deletedFacts.length > 0) {\n await tx.delete(embeddings).where(\n and(\n eq(embeddings.ownerType, \"fact\"),\n inArray(\n embeddings.ownerId,\n deletedFacts.map((row) => row.id),\n ),\n ),\n );\n await tx\n .update(shares)\n .set({ tombstoned: true })\n .where(\n and(\n eq(shares.mode, \"reference\"),\n inArray(\n shares.sourceFactId,\n deletedFacts.map((row) => row.id),\n ),\n ),\n );\n }\n const deletedSummaries = await tx\n .delete(sessionSummaries)\n .where(lt(sessionSummaries.createdAt, cutoff))\n .returning({ id: sessionSummaries.id });\n if (deletedSummaries.length > 0) {\n await tx.delete(embeddings).where(\n and(\n eq(embeddings.ownerType, \"summary\"),\n inArray(\n embeddings.ownerId,\n deletedSummaries.map((row) => row.id),\n ),\n ),\n );\n }\n return {\n interactions: deletedInteractions.length,\n facts: deletedFacts.length,\n summaries: deletedSummaries.length,\n };\n });\n }\n\n async getVectorIndexHealth(namespaceId?: string): Promise<VectorIndexHealth> {\n const countRows = namespaceId\n ? await this.client.sql<\n { count: string }[]\n >`select count(*)::text as count from embeddings where namespace_id = ${namespaceId}`\n : await this.client.sql<{ count: string }[]>`select count(*)::text as count from embeddings`;\n const indexRows = await this.client.sql<{ indexname: string; indexdef: string }[]>`\n select indexname, indexdef from pg_indexes\n where schemaname = current_schema()\n and tablename = 'embeddings'\n and indexname = 'embeddings_vector_hnsw_idx'\n limit 1\n `;\n const vectorCount = Number(countRows[0]?.count ?? 0);\n const index = indexRows[0];\n return {\n vectorCount,\n indexName: index?.indexname ?? null,\n indexDefinition: index?.indexdef ?? null,\n needsTuning: vectorCount >= 100_000,\n };\n }\n}\n\nexport function createPostgresRepository(client: DatabaseClient): MemoryRepository {\n return new PostgresMemoryRepository(client);\n}\n\nfunction toAuditRow(entry: AuditEntry) {\n return {\n id: entry.id,\n namespaceId: entry.namespaceId,\n action: entry.action,\n entityType: entry.entityType,\n entityId: entry.entityId ?? null,\n createdByAgent: entry.createdByAgent ?? null,\n metadata: entry.metadata ?? {},\n };\n}\n\n/**\n * Ensure the owner's embedding row exists. With `reset`, an existing row goes\n * back to `pending` and drops its lease token, so a worker still embedding the\n * old text is fenced out (#50) and the new text gets a fresh vector.\n */\nasync function upsertPendingEmbedding(\n tx: Pick<Db, \"insert\">,\n embedding: PendingEmbeddingInsert,\n reset: boolean,\n): Promise<void> {\n const insert = tx.insert(embeddings).values({\n id: embedding.id,\n namespaceId: embedding.namespaceId,\n ownerType: embedding.ownerType,\n ownerId: embedding.ownerId,\n vector: zeroVectorLiteral(),\n embeddingModel: embedding.embeddingModel,\n status: \"pending\",\n });\n const target = [embeddings.ownerType, embeddings.ownerId];\n if (!reset) {\n await insert.onConflictDoNothing({ target });\n return;\n }\n await insert.onConflictDoUpdate({\n target,\n set: {\n vector: zeroVectorLiteral(),\n embeddingModel: embedding.embeddingModel,\n status: \"pending\",\n attempts: 0,\n lastError: null,\n leaseUntil: null,\n leaseToken: null,\n updatedAt: sql`now()`,\n },\n });\n}\n\nfunction zeroVectorLiteral(): string {\n return `[${Array.from({ length: 384 }, () => 0).join(\",\")}]`;\n}\n\nfunction parseVectorLiteral(literal: string): number[] {\n const trimmed = literal.startsWith(\"[\") ? literal.slice(1, -1) : literal;\n if (!trimmed) return [];\n return trimmed.split(\",\").map((value) => Number(value));\n}\n\nfunction advisoryLockKeys(namespaceId: string, sessionId: string): [number, number] {\n const digest = createHash(\"sha256\").update(`${namespaceId}\\x1f${sessionId}`).digest();\n const k1 = digest.readInt32BE(0);\n const k2 = digest.readInt32BE(4);\n return [k1, k2];\n}\n\nconst recentFactColumns = {\n id: facts.id,\n content: facts.content,\n subject: facts.subject,\n predicate: facts.predicate,\n object: facts.object,\n propositionKey: facts.propositionKey,\n confidence: facts.confidence,\n sourceDeleted: facts.sourceDeleted,\n supersededBy: facts.supersededBy,\n createdByAgent: facts.createdByAgent,\n createdAt: facts.createdAt,\n};\n\n/** A live (non-tombstoned) reference share of `factId` from its owner to `namespaceId`. */\nfunction liveReference(namespaceId: string, ownerNamespace: SQL, factId: SQL): SQL {\n return sql`exists (\n select 1 from shares s\n where s.to_namespace_id = ${namespaceId}\n and s.from_namespace_id = ${ownerNamespace}\n and s.source_fact_id = ${factId}\n and s.mode = 'reference'\n and not s.tombstoned\n )`;\n}\n","import { bootstrapDatabase, checkPgvector } from \"../db/bootstrap.js\";\nimport { createDatabaseClient, pingDatabase } from \"../db/client.js\";\nimport { runMigrations } from \"../db/migrator.js\";\nimport { createPostgresRepository } from \"../db/repository.js\";\nimport type { ModelProvider } from \"../providers/adapter.js\";\nimport { DEFAULT_EMBEDDING_MODELS, DEFAULT_LLM_MODELS } from \"../providers/models.js\";\nimport { CodeBuddy } from \"./codebuddy.js\";\nimport {\n checkConfigPermissions,\n checkProjectScaffold,\n defaultNamespaceForCwd,\n loadRuntimeConfig,\n MISSING_DATABASE_URL,\n readConfigFile,\n redactSecrets,\n} from \"./config-file.js\";\nimport { MemoryFileStore } from \"./memory-file-store.js\";\nimport type { MemoryRepository } from \"./repository.js\";\nimport type { CodeBuddyConfig } from \"./types.js\";\n\nexport type RuntimeHandle = {\n memory: CodeBuddy;\n repository: MemoryRepository;\n close(): Promise<void>;\n};\n\nexport type CreateRuntimeOptions = {\n /**\n * When true (default for `serve`), enable pgvector and apply any pending\n * SQL migrations before the SDK initialises. Safe to run repeatedly —\n * Drizzle skips migrations it has already applied.\n */\n autoBootstrap?: boolean;\n repositoryRoot?: string;\n};\n\nexport async function createRuntime(\n config?: CodeBuddyConfig,\n options: CreateRuntimeOptions = {},\n): Promise<RuntimeHandle> {\n const runtimeConfig = config ?? (await loadRuntimeConfig());\n if (!runtimeConfig.postgresUrl) throw new Error(MISSING_DATABASE_URL);\n const client = createDatabaseClient({ postgresUrl: runtimeConfig.postgresUrl });\n try {\n if (options.autoBootstrap) {\n await bootstrapDatabase(client.sql);\n await runMigrations(client);\n }\n const repository = createPostgresRepository(client);\n const memory = new CodeBuddy(runtimeConfig, {\n repository,\n memoryFileStore: new MemoryFileStore(\n options.repositoryRoot ?? runtimeConfig.projectRoot ?? process.cwd(),\n ),\n });\n // init() starts the embedding worker only after its last fallible step,\n // so a failure here leaves just the pool to release.\n await memory.init();\n return {\n memory,\n repository,\n async close() {\n await memory.shutdown();\n await client.close();\n },\n };\n } catch (error) {\n await client.close().catch(() => undefined);\n throw error;\n }\n}\n\nexport function encodeFactCursor(fact: { createdAt: Date; id: string }): string {\n return Buffer.from(JSON.stringify([fact.createdAt.toISOString(), fact.id]), \"utf8\").toString(\n \"base64url\",\n );\n}\n\nexport function decodeFactCursor(cursor: string): { createdAt: Date; id: string } {\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf8\"));\n } catch {\n throw new Error(\"Invalid cursor: expected a base64url-encoded [createdAt, id] pair.\");\n }\n if (\n !Array.isArray(parsed) ||\n parsed.length !== 2 ||\n typeof parsed[0] !== \"string\" ||\n typeof parsed[1] !== \"string\" ||\n Number.isNaN(Date.parse(parsed[0]))\n ) {\n throw new Error(\"Invalid cursor: expected a base64url-encoded [createdAt, id] pair.\");\n }\n const [createdAt, id] = parsed as [string, string];\n return { createdAt: new Date(createdAt), id };\n}\n\nexport async function listFactsPage(\n memory: CodeBuddy,\n repository: MemoryRepository,\n input: { subject?: string; limit?: number; cursor?: string },\n) {\n const namespace = await repository.ensureNamespace(memory.config.namespace);\n const requestedLimit = input.limit ?? 50;\n const limit = Math.max(1, Math.min(100, requestedLimit));\n const facts = await repository.listFacts({\n namespaceId: namespace.id,\n ...(input.subject ? { subject: input.subject } : {}),\n limit: limit + 1,\n ...(input.cursor ? { cursor: decodeFactCursor(input.cursor) } : {}),\n });\n const page = facts.slice(0, limit);\n const next = facts.length > limit ? page.at(-1) : undefined;\n return {\n facts: page,\n ...(next ? { nextCursor: encodeFactCursor(next) } : {}),\n };\n}\n\nexport async function inspectNamespace(repository: MemoryRepository, namespace?: string) {\n if (!namespace) {\n return {\n namespaces: await repository.listNamespaces(),\n agents: await repository.getAgentWriteBreakdown(),\n };\n }\n const row = await repository.getNamespaceByName(namespace);\n if (!row) return { namespace, exists: false, facts: [], agents: [] };\n return {\n namespace,\n exists: true,\n facts: await repository.listFacts({ namespaceId: row.id, limit: 50 }),\n agents: await repository.getAgentWriteBreakdown(row.id),\n };\n}\n\nexport type DoctorReport = {\n db: { ok: boolean; error?: string; canConnect?: boolean; postgresUrlSource?: string };\n pgvector: { ok: boolean; error?: string };\n vectors: { count: number; index: string | null; needsTuning: boolean };\n models: {\n id: string;\n reachable: boolean;\n status: \"unknown\" | \"warm\" | \"cold\" | \"gated\" | \"failed\";\n error?: string;\n }[];\n usage: {\n last60s: number;\n lastHour: number;\n last24h: number;\n estimatedDailyCapRemaining: number;\n warning80Percent: boolean;\n };\n scaffold: Awaited<ReturnType<typeof checkProjectScaffold>>;\n config: Awaited<ReturnType<typeof checkConfigPermissions>>;\n namespace: {\n expectedDefault: string;\n configured: string | null;\n runtime: string | null;\n ok: boolean;\n warning?: string;\n };\n};\n\nexport async function runDoctor(\n options: {\n config?: CodeBuddyConfig;\n repository?: MemoryRepository;\n provider?: ModelProvider;\n skipModelCheck?: boolean;\n } = {},\n): Promise<DoctorReport> {\n const fileConfig = await readConfigFile();\n const scaffold = await checkProjectScaffold();\n const configPermissions = await checkConfigPermissions();\n // Same helper the runtime and every CLI command use — one rule everywhere.\n const expectedDefaultNamespace = defaultNamespaceForCwd();\n const runtimeNamespace =\n process.env.CODEBUDDY_NAMESPACE ?? fileConfig.namespace ?? options.config?.namespace ?? null;\n const namespaceReport: DoctorReport[\"namespace\"] = {\n expectedDefault: expectedDefaultNamespace,\n configured: fileConfig.namespace ?? null,\n runtime: runtimeNamespace,\n ok:\n !fileConfig.namespace ||\n fileConfig.namespace === expectedDefaultNamespace ||\n process.env.CODEBUDDY_NAMESPACE !== undefined,\n ...(!fileConfig.namespace ||\n fileConfig.namespace === expectedDefaultNamespace ||\n process.env.CODEBUDDY_NAMESPACE !== undefined\n ? {}\n : {\n warning: `Configured namespace \"${fileConfig.namespace}\" differs from this folder's default \"${expectedDefaultNamespace}\". Confirm your MCP entries point at the intended namespace.`,\n }),\n };\n\n let config = options.config;\n if (!config) {\n try {\n config = await loadRuntimeConfig();\n } catch (error) {\n const message = String(redactSecrets((error as Error).message));\n return {\n db: {\n ok: false,\n error: message,\n canConnect: false,\n postgresUrlSource: \"missing\",\n },\n pgvector: { ok: false, error: \"Postgres is not configured yet.\" },\n vectors: { count: 0, index: null, needsTuning: false },\n models: await checkModels(options.provider, true),\n usage: {\n last60s: 0,\n lastHour: 0,\n last24h: 0,\n estimatedDailyCapRemaining: 10_000,\n warning80Percent: false,\n },\n scaffold,\n config: configPermissions,\n namespace: namespaceReport,\n };\n }\n }\n\n let repository = options.repository;\n let close: (() => Promise<void>) | undefined;\n let db = { ok: true } as DoctorReport[\"db\"];\n let pgvector = { ok: true } as DoctorReport[\"pgvector\"];\n\n if (!repository) {\n const postgresUrlSource =\n options.config?.postgresUrl !== undefined\n ? \"explicit\"\n : process.env.DATABASE_URL\n ? \"environment\"\n : fileConfig.postgresUrl\n ? \"config\"\n : \"missing\";\n const client = createDatabaseClient({ postgresUrl: config.postgresUrl });\n repository = createPostgresRepository(client);\n close = () => client.close();\n try {\n const canConnect = await pingDatabase(client);\n db = { ok: canConnect, canConnect, postgresUrlSource };\n if (!canConnect) db.error = \"Postgres did not respond to a simple ping.\";\n } catch (error) {\n db = {\n ok: false,\n canConnect: false,\n postgresUrlSource,\n error: String(redactSecrets((error as Error).message)),\n };\n }\n try {\n const health = await checkPgvector(client.sql);\n pgvector = {\n ok: health.available,\n ...(health.available ? {} : { error: \"pgvector extension is not installed.\" }),\n };\n } catch (error) {\n pgvector = { ok: false, error: String(redactSecrets((error as Error).message)) };\n }\n }\n\n try {\n if (!db.ok) {\n return {\n db,\n pgvector,\n vectors: { count: 0, index: null, needsTuning: false },\n models: await checkModels(options.provider, true),\n usage: {\n last60s: 0,\n lastHour: 0,\n last24h: 0,\n estimatedDailyCapRemaining: 10_000,\n warning80Percent: false,\n },\n scaffold,\n config: configPermissions,\n namespace: namespaceReport,\n };\n }\n const namespace = await repository.ensureNamespace(config.namespace);\n const [stats, vectorHealth] = await Promise.all([\n repository.getStats(namespace.id),\n repository.getVectorIndexHealth(namespace.id),\n ]);\n const models = await checkModels(options.provider, options.skipModelCheck);\n const dailyCap = 10_000;\n const used = stats.modelCalls.last24h;\n return {\n db,\n pgvector,\n vectors: {\n count: vectorHealth.vectorCount,\n index: vectorHealth.indexName,\n needsTuning: vectorHealth.needsTuning,\n },\n models,\n usage: {\n last60s: stats.modelCalls.last60s,\n lastHour: stats.modelCalls.lastHour,\n last24h: used,\n estimatedDailyCapRemaining: Math.max(0, dailyCap - used),\n warning80Percent: used >= dailyCap * 0.8,\n },\n scaffold,\n config: configPermissions,\n namespace: namespaceReport,\n };\n } finally {\n await close?.();\n }\n}\n\nasync function checkModels(\n provider?: ModelProvider,\n skip = false,\n): Promise<DoctorReport[\"models\"]> {\n const ids = [...DEFAULT_EMBEDDING_MODELS, ...DEFAULT_LLM_MODELS].map((model) => model.id);\n if (!provider || skip) {\n return ids.map((id) => ({ id, reachable: false, status: \"unknown\" }));\n }\n const results: DoctorReport[\"models\"] = [];\n for (const id of ids) {\n try {\n if (DEFAULT_EMBEDDING_MODELS.some((model) => model.id === id)) {\n await provider.embed({ model: id, input: \"doctor\" });\n } else {\n await provider.generateText({ model: id, prompt: \"doctor\" });\n }\n results.push({ id, reachable: true, status: \"warm\" });\n } catch (error) {\n const message = String(redactSecrets((error as Error).message));\n results.push({\n id,\n reachable: false,\n status: /gated|403/i.test(message)\n ? \"gated\"\n : /cold|503/i.test(message)\n ? \"cold\"\n : \"failed\",\n error: message,\n });\n }\n }\n return results;\n}\n","import { mkdir, open, readdir, readFile, rm, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"./markdown-store-fs.js\";\n\n/**\n * Plans are durable Markdown artifacts under `.codebuddy/plans/`. Git is\n * the version history; PostgreSQL (when present) is a derived index, never\n * the source of truth. This store owns the on-disk representation:\n * schema, round-trip serialization, atomic writes, and the locks that keep\n * concurrent CLI/MCP clients from corrupting a plan or approving two active\n * plans in one namespace.\n */\n\nexport const PLAN_STATUSES = [\"draft\", \"approved\", \"executing\", \"complete\", \"abandoned\"] as const;\nexport type PlanStatus = (typeof PLAN_STATUSES)[number];\n\n/** A plan is \"active\" while approved or executing — at most one per namespace. */\nexport const ACTIVE_PLAN_STATUSES: readonly PlanStatus[] = [\"approved\", \"executing\"];\n\nconst plannedFileSchema = z.object({\n path: z.string().min(1),\n action: z.enum([\"create\", \"edit\", \"delete\"]),\n notes: z.string().default(\"\"),\n});\n\nconst plannedTestSchema = z.object({\n path: z.string().min(1),\n description: z.string().default(\"\"),\n});\n\nconst nullableDateTime = z\n .preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime().nullable(),\n )\n .nullable();\n\nconst planFrontMatterSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^pln_[a-z0-9]+$/),\n namespace: z.string().min(1),\n type: z.literal(\"plan\"),\n title: z.string().min(1),\n status: z.enum(PLAN_STATUSES),\n brief: z.string(),\n filesToTouch: z.array(plannedFileSchema).default([]),\n testsToAdd: z.array(plannedTestSchema).default([]),\n outOfScope: z.array(z.string()).default([]),\n risks: z.array(z.string()).default([]),\n createdAt: z.preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime(),\n ),\n createdByAgent: z.string().nullable(),\n approvedAt: nullableDateTime,\n executingAt: nullableDateTime,\n completedAt: nullableDateTime,\n abandonedAt: nullableDateTime,\n commitSha: z.string().nullable(),\n abandonReason: z.string().nullable(),\n});\n\nexport type PlannedFile = z.infer<typeof plannedFileSchema>;\nexport type PlannedTest = z.infer<typeof plannedTestSchema>;\nexport type PlanFrontMatter = z.infer<typeof planFrontMatterSchema>;\n\n/** A fully materialized plan: front matter + Markdown body + on-disk path. */\nexport type PlanSpec = PlanFrontMatter & {\n body: string;\n path: string;\n};\n\n/** Shape accepted by `writePlan` — path/schemaVersion/type are managed here. */\nexport type PlanWrite = Omit<PlanFrontMatter, \"schemaVersion\" | \"type\"> & {\n body: string;\n};\n\nexport type PlanLockOptions = {\n /** Max time to wait for the lock before failing. */\n timeoutMs?: number;\n /** A lock older than this is considered abandoned and stolen. */\n staleMs?: number;\n /** Poll interval while waiting. */\n pollMs?: number;\n};\n\nexport class PlanLockError extends Error {\n constructor(resource: string) {\n super(\n `Could not acquire lock for ${resource} within the timeout. Another client may be holding it.`,\n );\n this.name = \"PlanLockError\";\n }\n}\n\nexport class PlanValidationError extends Error {\n constructor(path: string, issues: string[]) {\n super(`Invalid plan file ${path}:\\n${issues.map((issue) => ` - ${issue}`).join(\"\\n\")}`);\n this.name = \"PlanValidationError\";\n }\n}\n\nconst DEFAULT_LOCK: Required<PlanLockOptions> = {\n timeoutMs: 5_000,\n staleMs: 30_000,\n pollMs: 50,\n};\n\nexport class PlanFileStore {\n readonly repositoryRoot: string;\n readonly plansDirectory: string;\n readonly locksDirectory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.plansDirectory = join(this.repositoryRoot, \".codebuddy\", \"plans\");\n this.locksDirectory = join(this.plansDirectory, \".locks\");\n }\n\n // ── Read / write ────────────────────────────────────────────────────\n\n async writePlan(input: PlanWrite): Promise<string> {\n const path = this.planPath(input.id);\n await this.prepareDirectory(this.plansDirectory);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n type: \"plan\",\n title: input.title,\n status: input.status,\n brief: input.brief,\n filesToTouch: input.filesToTouch,\n testsToAdd: input.testsToAdd,\n outOfScope: input.outOfScope,\n risks: input.risks,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n approvedAt: input.approvedAt,\n executingAt: input.executingAt,\n completedAt: input.completedAt,\n abandonedAt: input.abandonedAt,\n commitSha: input.commitSha,\n abandonReason: input.abandonReason,\n });\n\n await writeAtomic(path, composeMarkdown(frontMatter, input.body));\n return path;\n }\n\n async readPlan(pathOrId: string): Promise<PlanSpec> {\n const path = pathOrId.endsWith(\".md\") ? this.safePath(pathOrId) : this.planPath(pathOrId);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n const result = planFrontMatterSchema.safeParse(parseYaml(parsed.frontMatter));\n if (!result.success) {\n throw new PlanValidationError(path, formatIssues(result.error));\n }\n return { ...result.data, body: parsed.content.trim(), path };\n }\n\n async listPlans(): Promise<PlanSpec[]> {\n try {\n await this.prepareDirectory(this.plansDirectory);\n const entries = await readdir(this.plansDirectory, { withFileTypes: true });\n const plans: PlanSpec[] = [];\n for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n // Plans are always written as `<pln_id>.md`. Ignore any other markdown\n // (hand-written notes, READMEs, build plans) so a shared plans dir with\n // non-plan files can't make discovery throw.\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n if (!/^pln_[a-z0-9]+\\.md$/.test(entry.name)) continue;\n plans.push(await this.readPlan(join(this.plansDirectory, entry.name)));\n }\n return plans;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n }\n\n async deletePlan(id: string): Promise<void> {\n await rm(this.planPath(id), { force: true });\n }\n\n /**\n * The single approved-or-executing plan in `namespace`, or null. If the\n * filesystem somehow holds more than one (a hand edit, a crash mid-\n * transition), the earliest-created wins and the situation is the\n * caller's to reconcile.\n */\n async findActivePlan(namespace: string): Promise<PlanSpec | null> {\n const active = (await this.listPlans()).filter(\n (plan) => plan.namespace === namespace && ACTIVE_PLAN_STATUSES.includes(plan.status),\n );\n if (active.length === 0) return null;\n active.sort((left, right) => left.createdAt.localeCompare(right.createdAt));\n return active[0] ?? null;\n }\n\n // ── Locking ─────────────────────────────────────────────────────────\n\n /** Serialize amendments to a single plan. */\n async withPlanLock<T>(id: string, fn: () => Promise<T>, options?: PlanLockOptions): Promise<T> {\n this.assertPlanId(id);\n return this.withLock(`${id}.lock`, id, fn, options);\n }\n\n /**\n * Serialize lifecycle transitions across an entire namespace so two\n * clients cannot both promote a plan to active. Hold this around the\n * read-active-then-write window.\n */\n async withNamespaceLock<T>(\n namespace: string,\n fn: () => Promise<T>,\n options?: PlanLockOptions,\n ): Promise<T> {\n const safeName = namespace.replace(/[^a-zA-Z0-9_.:-]/g, \"-\");\n return this.withLock(`namespace_${safeName}.lock`, `namespace ${namespace}`, fn, options);\n }\n\n private async withLock<T>(\n lockFileName: string,\n resourceLabel: string,\n fn: () => Promise<T>,\n options?: PlanLockOptions,\n ): Promise<T> {\n const config = { ...DEFAULT_LOCK, ...options };\n await this.prepareDirectory(this.locksDirectory);\n const lockPath = join(this.locksDirectory, lockFileName);\n const deadline = Date.now() + config.timeoutMs;\n\n for (;;) {\n try {\n const handle = await open(lockPath, \"wx\", 0o600);\n await handle.writeFile(`${process.pid}\\n${new Date().toISOString()}\\n`, \"utf8\");\n await handle.close();\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n if (await this.tryStealStaleLock(lockPath, config.staleMs)) continue;\n if (Date.now() >= deadline) throw new PlanLockError(resourceLabel);\n await delay(config.pollMs);\n }\n }\n\n try {\n return await fn();\n } finally {\n await releaseOwnedLock(lockPath);\n }\n }\n\n private async tryStealStaleLock(lockPath: string, staleMs: number): Promise<boolean> {\n try {\n const info = await stat(lockPath);\n if (Date.now() - info.mtimeMs > staleMs) {\n await rm(lockPath, { force: true });\n return true;\n }\n } catch (error) {\n // Lock vanished between EEXIST and stat — treat as free, retry.\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return true;\n throw error;\n }\n return false;\n }\n\n // ── Paths ───────────────────────────────────────────────────────────\n\n private planPath(id: string): string {\n this.assertPlanId(id);\n return this.safePath(join(this.plansDirectory, `${id}.md`));\n }\n\n private assertPlanId(id: string): void {\n if (!/^pln_[a-z0-9]+$/.test(id)) {\n throw new Error(`Invalid plan id: ${id}`);\n }\n }\n\n private safePath(path: string): string {\n const absolute = resolve(path);\n const relativePath = relative(this.repositoryRoot, absolute);\n if (relativePath === \"..\" || relativePath.startsWith(`..${sep}`) || relativePath === \"\") {\n throw new Error(`Plan path escapes repository root: ${path}`);\n }\n return absolute;\n }\n\n private async prepareDirectory(directory: string): Promise<void> {\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(directory));\n await mkdir(directory, { recursive: true, mode: 0o700 });\n }\n}\n\nfunction formatIssues(error: z.ZodError): string[] {\n return error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return `${path}: ${issue.message}`;\n });\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Delete `lockPath` only when it still belongs to this process. If a holder's\n * work ran past `staleMs`, another client may have stolen and re-created the\n * lock — deleting it unconditionally would release *their* critical section.\n */\nasync function releaseOwnedLock(lockPath: string): Promise<void> {\n try {\n const contents = await readFile(lockPath, \"utf8\");\n const ownerPid = Number.parseInt(contents.split(\"\\n\")[0] ?? \"\", 10);\n if (ownerPid === process.pid) {\n await rm(lockPath, { force: true });\n }\n } catch {\n // Lock already vanished (stolen then released) — nothing to release.\n }\n}\n","import { generateEntityId } from \"./ids.js\";\nimport {\n ACTIVE_PLAN_STATUSES,\n type PlanFileStore,\n type PlannedFile,\n type PlannedTest,\n type PlanSpec,\n type PlanStatus,\n} from \"./plan-file-store.js\";\n\n/**\n * The plan lifecycle service enforces the state machine on top of the\n * file store. The store knows how to read/write/lock; this service knows\n * which transitions are legal and guarantees that at most one plan in a\n * namespace is active at a time. Transitions that change active state run\n * under the namespace lock; amendments run under the per-plan lock.\n */\n\n/** Legal transitions. Terminal states (complete, abandoned) have none. */\nconst TRANSITIONS: Record<PlanStatus, readonly PlanStatus[]> = {\n draft: [\"approved\", \"abandoned\"],\n approved: [\"executing\", \"abandoned\"],\n executing: [\"complete\", \"abandoned\"],\n complete: [],\n abandoned: [],\n};\n\n/** Only these states accept content amendments. */\nconst AMENDABLE: readonly PlanStatus[] = [\"draft\", \"executing\"];\n\nexport class PlanTransitionError extends Error {\n constructor(from: PlanStatus, to: PlanStatus) {\n super(`Illegal plan transition: ${from} → ${to}.`);\n this.name = \"PlanTransitionError\";\n }\n}\n\nexport class PlanNotFoundError extends Error {\n constructor(id: string) {\n super(`Plan ${id} not found.`);\n this.name = \"PlanNotFoundError\";\n }\n}\n\nexport class ActivePlanExistsError extends Error {\n readonly activePlanId: string;\n constructor(namespace: string, activePlanId: string) {\n super(\n `Namespace \"${namespace}\" already has an active plan (${activePlanId}). ` +\n `Complete or abandon it before approving another.`,\n );\n this.name = \"ActivePlanExistsError\";\n this.activePlanId = activePlanId;\n }\n}\n\nexport type CreatePlanInput = {\n namespace: string;\n title: string;\n brief: string;\n body?: string;\n filesToTouch?: PlannedFile[];\n testsToAdd?: PlannedTest[];\n outOfScope?: string[];\n risks?: string[];\n createdByAgent?: string | null;\n now?: string;\n};\n\nexport type AmendPlanPatch = {\n title?: string;\n brief?: string;\n body?: string;\n filesToTouch?: PlannedFile[];\n testsToAdd?: PlannedTest[];\n outOfScope?: string[];\n risks?: string[];\n};\n\nexport type CompleteOptions = { commitSha?: string; notes?: string };\nexport type AbandonOptions = { reason?: string };\n\nconst DEFAULT_BODY = [\n \"# Goal\",\n \"\",\n \"(what this plan achieves)\",\n \"\",\n \"# Approach\",\n \"\",\n \"(ordered steps)\",\n \"\",\n \"# Notes\",\n \"\",\n \"(freeform; ignored by tooling)\",\n].join(\"\\n\");\n\nexport class PlanLifecycle {\n private readonly store: PlanFileStore;\n\n constructor(store: PlanFileStore) {\n this.store = store;\n }\n\n async create(input: CreatePlanInput): Promise<PlanSpec> {\n const id = generateEntityId(\"pln\");\n const now = input.now ?? new Date().toISOString();\n await this.store.writePlan({\n id,\n namespace: input.namespace,\n title: input.title,\n status: \"draft\",\n brief: input.brief,\n filesToTouch: input.filesToTouch ?? [],\n testsToAdd: input.testsToAdd ?? [],\n outOfScope: input.outOfScope ?? [],\n risks: input.risks ?? [],\n createdAt: now,\n createdByAgent: input.createdByAgent ?? null,\n approvedAt: null,\n executingAt: null,\n completedAt: null,\n abandonedAt: null,\n commitSha: null,\n abandonReason: null,\n body: input.body ?? DEFAULT_BODY,\n });\n return this.store.readPlan(id);\n }\n\n async approve(id: string, now = new Date().toISOString()): Promise<PlanSpec> {\n const current = await this.require(id);\n // The active-plan guard and the write must be atomic across the\n // namespace, otherwise two approvals could both observe \"no active plan\".\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"approved\");\n const active = await this.store.findActivePlan(fresh.namespace);\n if (active && active.id !== id) {\n throw new ActivePlanExistsError(fresh.namespace, active.id);\n }\n return this.rewrite(fresh, { status: \"approved\", approvedAt: now });\n });\n }\n\n async start(id: string, now = new Date().toISOString()): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"executing\");\n return this.rewrite(fresh, { status: \"executing\", executingAt: now });\n });\n }\n\n async complete(\n id: string,\n options: CompleteOptions = {},\n now = new Date().toISOString(),\n ): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"complete\");\n return this.rewrite(fresh, {\n status: \"complete\",\n completedAt: now,\n ...(options.commitSha !== undefined ? { commitSha: options.commitSha } : {}),\n });\n });\n }\n\n async abandon(\n id: string,\n options: AbandonOptions = {},\n now = new Date().toISOString(),\n ): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"abandoned\");\n return this.rewrite(fresh, {\n status: \"abandoned\",\n abandonedAt: now,\n ...(options.reason !== undefined ? { abandonReason: options.reason } : {}),\n });\n });\n }\n\n async amend(id: string, patch: AmendPlanPatch): Promise<PlanSpec> {\n // Amend takes the NAMESPACE lock, like every lifecycle transition. The\n // per-plan lock alone let an amend interleave with e.g. abandon():\n // amend reads `draft` -> abandon writes `abandoned` -> amend writes back\n // its stale full snapshot, resurrecting the plan as `draft`. One shared\n // mutex makes read-check-write atomic across all mutators.\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n if (!AMENDABLE.includes(fresh.status)) {\n throw new Error(\n `Plan ${id} is ${fresh.status}; only draft or executing plans can be amended.`,\n );\n }\n return this.rewrite(fresh, {\n ...(patch.title !== undefined ? { title: patch.title } : {}),\n ...(patch.brief !== undefined ? { brief: patch.brief } : {}),\n ...(patch.filesToTouch !== undefined ? { filesToTouch: patch.filesToTouch } : {}),\n ...(patch.testsToAdd !== undefined ? { testsToAdd: patch.testsToAdd } : {}),\n ...(patch.outOfScope !== undefined ? { outOfScope: patch.outOfScope } : {}),\n ...(patch.risks !== undefined ? { risks: patch.risks } : {}),\n ...(patch.body !== undefined ? { body: patch.body } : {}),\n });\n });\n }\n\n async current(namespace: string): Promise<PlanSpec | null> {\n return this.store.findActivePlan(namespace);\n }\n\n private assertTransition(from: PlanStatus, to: PlanStatus): void {\n if (!TRANSITIONS[from].includes(to)) {\n throw new PlanTransitionError(from, to);\n }\n }\n\n private async require(id: string): Promise<PlanSpec> {\n try {\n return await this.store.readPlan(id);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new PlanNotFoundError(id);\n }\n throw error;\n }\n }\n\n /** Rewrite the plan file with a partial set of changed fields. */\n private async rewrite(plan: PlanSpec, changes: Partial<PlanSpec>): Promise<PlanSpec> {\n const next = { ...plan, ...changes };\n await this.store.writePlan({\n id: next.id,\n namespace: next.namespace,\n title: next.title,\n status: next.status,\n brief: next.brief,\n filesToTouch: next.filesToTouch,\n testsToAdd: next.testsToAdd,\n outOfScope: next.outOfScope,\n risks: next.risks,\n createdAt: next.createdAt,\n createdByAgent: next.createdByAgent,\n approvedAt: next.approvedAt,\n executingAt: next.executingAt,\n completedAt: next.completedAt,\n abandonedAt: next.abandonedAt,\n commitSha: next.commitSha,\n abandonReason: next.abandonReason,\n body: next.body,\n });\n return this.store.readPlan(next.id);\n }\n}\n\nexport { ACTIVE_PLAN_STATUSES };\n","{\n \"name\": \"@orquentra/codebuddy\",\n \"version\": \"2.4.0\",\n \"description\": \"Local-first MCP memory and project context for coding agents. Formerly @ayushkumar320/codebuddy; historical releases and download records remain under the original package.\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"author\": \"Orquentra Inc\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/Orquentra-Inc/CodeBuddy\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"bin\": {\n \"codebuddy\": \"./dist/cli/index.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./langgraph\": {\n \"types\": \"./dist/langgraph/index.d.ts\",\n \"import\": \"./dist/langgraph/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"src/db/migrations\",\n \"README.md\",\n \"CLAUDE_CODEX.md\",\n \"ARCHITECTURE.md\",\n \"WORKFLOW.md\",\n \"LICENSE\",\n \"docker-compose.yml\",\n \"examples\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/cli/index.ts\",\n \"db:generate\": \"drizzle-kit generate\",\n \"db:migrate\": \"drizzle-kit migrate\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run --passWithNoTests\",\n \"test:pg\": \"bash scripts/test-pg-recovery.sh\",\n \"eval:agent-ab\": \"tsx scripts/eval-agent-ab.mts\",\n \"eval:memory-ab\": \"tsx scripts/eval-memory-ab.mts\",\n \"eval:retrieval\": \"tsx scripts/eval-retrieval.mts\",\n \"eval:savings\": \"tsx scripts/eval-task-savings.mts\",\n \"branches:prune\": \"bash scripts/prune-merged-branches.sh\",\n \"lint\": \"biome check .\",\n \"format\": \"biome format --write .\",\n \"prepublishOnly\": \"npm run typecheck && npm test && npm run build\"\n },\n \"keywords\": [\n \"mcp\",\n \"memory\",\n \"agent\",\n \"multi-agent\",\n \"huggingface\",\n \"pgvector\",\n \"postgres\",\n \"langgraph\",\n \"claude\"\n ],\n \"homepage\": \"https://github.com/Orquentra-Inc/CodeBuddy\",\n \"bugs\": {\n \"url\": \"https://github.com/Orquentra-Inc/CodeBuddy/issues\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^0.11.0\",\n \"@huggingface/inference\": \"^4.13.19\",\n \"@modelcontextprotocol/sdk\": \"^1.17.5\",\n \"commander\": \"^14.0.0\",\n \"drizzle-orm\": \"^0.45.2\",\n \"js-tiktoken\": \"^1.0.21\",\n \"langsmith\": \"^0.7.10\",\n \"ora\": \"^8.2.0\",\n \"p-queue\": \"^8.1.0\",\n \"p-retry\": \"^6.2.1\",\n \"p-timeout\": \"^6.1.4\",\n \"picocolors\": \"^1.1.1\",\n \"pino\": \"^9.9.0\",\n \"pino-pretty\": \"^13.1.1\",\n \"postgres\": \"^3.4.7\",\n \"yaml\": \"^2.9.0\",\n \"zod\": \"^4.6.7\"\n },\n \"peerDependencies\": {\n \"@langchain/langgraph\": \"^0.2.0 || ^0.3.0\"\n },\n \"peerDependenciesMeta\": {\n \"@langchain/langgraph\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.5.0\",\n \"@types/node\": \"^24.3.0\",\n \"drizzle-kit\": \"^0.31.10\",\n \"tsup\": \"^8.5.0\",\n \"tsx\": \"^4.20.5\",\n \"typescript\": \"^5.9.2\",\n \"vitest\": \"^4.1.12\"\n }\n}\n","import pkg from \"../package.json\" with { type: \"json\" };\n\n/**\n * The single source of truth for the product version. `package.json` is the\n * canonical value (npm reads it for the published package); the CLI `--version`\n * flag and the MCP server handshake both import it from here so a version bump\n * only ever touches `package.json`. The bundler inlines this at build time, so\n * there is no runtime file read.\n */\nexport const VERSION: string = pkg.version;\n","import type {\n Assessment,\n AssessmentInput,\n Evidence,\n RiskCategory,\n RiskItem,\n Signal,\n SignalContribution,\n SignalStat,\n} from \"./types.js\";\n\nexport type AssessorOptions = {\n /** Items scoring below this are dropped from the result. Default 0. */\n minScore?: number;\n};\n\ntype ContributionWithSignal = {\n signal: Signal;\n contribution: SignalContribution;\n};\n\n/**\n * Runs every enabled signal in parallel and folds their per-path\n * contributions into a single ranked list. Scoring is deterministic: the\n * same inputs and the same cache state always produce the same output, with\n * stable tie-breaking.\n */\nexport class RiskAssessor {\n private readonly signals: Signal[];\n private readonly minScore: number;\n\n constructor(signals: Signal[], options: AssessorOptions = {}) {\n this.signals = signals;\n this.minScore = options.minScore ?? 0;\n }\n\n async assess(input: AssessmentInput): Promise<Assessment> {\n const enabled = this.signals.filter((signal) => signal.enabled);\n\n const settled = await Promise.all(\n enabled.map(async (signal) => ({\n signal,\n contributions: await signal.assess(input),\n })),\n );\n\n // Group contributions by path, remembering which signal produced each.\n const byPath = new Map<string, ContributionWithSignal[]>();\n const perSignal = new Map<string, SignalStat>();\n\n for (const { signal, contributions } of settled) {\n const stat: SignalStat = perSignal.get(signal.id) ?? {\n id: signal.id,\n category: signal.category,\n contributions: 0,\n totalWeight: 0,\n };\n for (const contribution of contributions) {\n // A signal that returns no evidence for a path does not get to vote —\n // the normalization only counts signals that actually have something\n // to say. This keeps a silent signal from diluting a real one.\n if (contribution.evidence.length === 0) continue;\n const list = byPath.get(contribution.path) ?? [];\n list.push({ signal, contribution });\n byPath.set(contribution.path, list);\n stat.contributions += 1;\n stat.totalWeight += contribution.weight;\n }\n perSignal.set(signal.id, stat);\n }\n\n const items: RiskItem[] = [];\n for (const [path, contributions] of byPath) {\n items.push(this.fold(path, contributions));\n }\n\n const ranked = items.filter((item) => item.score >= this.minScore).sort(compareRiskItems);\n\n return {\n items: ranked,\n stats: {\n pathsConsidered: input.paths.length,\n itemsProduced: ranked.length,\n signalsRun: enabled.length,\n perSignal: [...perSignal.values()].sort((a, b) => a.id.localeCompare(b.id)),\n },\n };\n }\n\n /** Fold all contributions for one path into a single RiskItem. */\n private fold(path: string, contributions: ContributionWithSignal[]): RiskItem {\n let weightedSum = 0;\n let coefficientSum = 0;\n let dominant: ContributionWithSignal | null = null;\n const evidence: Evidence[] = [];\n const contributingSignals: string[] = [];\n\n for (const entry of contributions) {\n const coefficient = entry.signal.coefficient;\n weightedSum += entry.contribution.weight * coefficient;\n coefficientSum += coefficient;\n evidence.push(...entry.contribution.evidence);\n contributingSignals.push(entry.signal.id);\n if (!dominant || dominantWeight(entry) > dominantWeight(dominant)) {\n dominant = entry;\n }\n }\n\n // Normalize only over the signals that contributed, so a path is not\n // punished for the signals that stayed silent about it.\n const score = coefficientSum === 0 ? 0 : clip(weightedSum / coefficientSum, 0, 100);\n const category: RiskCategory = dominant?.signal.category ?? \"policy\";\n const reason = dominant?.contribution.reason ?? \"\";\n\n return {\n path,\n score: round2(score),\n category,\n reason,\n contributingSignals: contributingSignals.sort(),\n evidence,\n };\n }\n}\n\nfunction dominantWeight(entry: ContributionWithSignal): number {\n return entry.contribution.weight * entry.signal.coefficient;\n}\n\n/** Deterministic ordering: score desc, then more signals, then path asc. */\nfunction compareRiskItems(a: RiskItem, b: RiskItem): number {\n if (b.score !== a.score) return b.score - a.score;\n if (b.contributingSignals.length !== a.contributingSignals.length) {\n return b.contributingSignals.length - a.contributingSignals.length;\n }\n return a.path.localeCompare(b.path);\n}\n\nfunction clip(value: number, low: number, high: number): number {\n return Math.min(high, Math.max(low, value));\n}\n\nfunction round2(value: number): number {\n return Math.round(value * 100) / 100;\n}\n","import { spawn } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nexport type ChurnSignalOptions = {\n repositoryRoot: string;\n enabled?: boolean;\n coefficient?: number;\n since?: string;\n};\n\ntype CommitRecord = {\n sha: string;\n author: string;\n ts: string;\n message: string;\n};\n\nconst GIT_LOG_CONCURRENCY = 4;\n\nexport function createChurnSignal(options: ChurnSignalOptions): Signal {\n return {\n id: \"git-churn\",\n category: \"churn\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 0.7,\n async assess(input) {\n // Churn is only meaningful at the repository root. Check it once per\n // assessment, not once per path: it was half of every git spawn (#45).\n const root = await runGit(options.repositoryRoot, [\"rev-parse\", \"--show-toplevel\"]);\n // git prints the symlink-resolved top level (macOS /var -> /private/var).\n const expected = await realpath(options.repositoryRoot).catch(() =>\n resolve(options.repositoryRoot),\n );\n if (root.code !== 0 || resolve(root.stdout.trim()) !== expected) {\n return [];\n }\n // `git log --follow` takes one path: run a few at a time, kept in path order.\n const since = options.since ?? \"30 days ago\";\n const logs: CommitRecord[][] = [];\n for (let start = 0; start < input.paths.length; start += GIT_LOG_CONCURRENCY) {\n const batch = input.paths.slice(start, start + GIT_LOG_CONCURRENCY);\n logs.push(\n ...(await Promise.all(\n batch.map((path) => gitLogForPath(options.repositoryRoot, path, since)),\n )),\n );\n }\n const contributions: SignalContribution[] = [];\n for (const [index, path] of input.paths.entries()) {\n const commits = logs[index] ?? [];\n if (commits.length === 0) continue;\n const authors = new Set(commits.map((commit) => commit.author));\n const reverts = commits.filter((commit) => /revert|rollback|backout/i.test(commit.message));\n const weight = Math.min(100, commits.length * 8 + authors.size * 12 + reverts.length * 20);\n contributions.push({\n path,\n weight,\n reason: `${path} changed ${commits.length} time${commits.length === 1 ? \"\" : \"s\"} in the recent git history by ${authors.size} author${authors.size === 1 ? \"\" : \"s\"}.`,\n evidence: commits.slice(0, 5).map((commit) => ({\n kind: \"git_commit\" as const,\n sha: commit.sha,\n message: commit.message,\n ts: commit.ts,\n })),\n });\n }\n return contributions;\n },\n };\n}\n\nasync function gitLogForPath(\n repositoryRoot: string,\n path: string,\n since: string,\n): Promise<CommitRecord[]> {\n const result = await runGit(repositoryRoot, [\n \"log\",\n \"--follow\",\n `--since=${since}`,\n \"--format=%H%x1f%an%x1f%cI%x1f%s%x1e\",\n \"--\",\n path,\n ]);\n if (result.code !== 0 || result.stdout.trim().length === 0) return [];\n return result.stdout\n .split(\"\\x1e\")\n .map((record) => record.trim())\n .filter(Boolean)\n .map((record) => {\n const [sha = \"\", author = \"\", ts = \"\", message = \"\"] = record.split(\"\\x1f\");\n return { sha, author, ts, message };\n })\n .filter((record) => record.sha.length > 0);\n}\n\nfunction runGit(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"git\", args, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolve({ code: code ?? 0, stdout, stderr }));\n });\n}\n","import type { IncidentSeverity, MemoryFileStore } from \"../../core/memory-file-store.js\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nexport type IncidentSignalOptions = {\n store: MemoryFileStore;\n enabled?: boolean;\n coefficient?: number;\n includeResolved?: boolean;\n};\n\n/**\n * Historical incident signal (Proposal 03.2/03.5 foundation). It reads\n * structured incident metadata from Markdown facts and produces one\n * evidence-backed contribution per affected path.\n */\nexport function createIncidentSignal(options: IncidentSignalOptions): Signal {\n return {\n id: \"incident-memory\",\n category: \"incident\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 1.2,\n async assess(input) {\n const incidents = await options.store.findIncidentFactsForPaths({\n namespace: input.namespace,\n paths: input.paths,\n includeResolved: options.includeResolved ?? false,\n });\n\n const byPath = new Map<string, SignalContribution>();\n for (const incident of incidents) {\n for (const path of input.paths) {\n if (!incident.paths.map(normalizePath).includes(normalizePath(path))) continue;\n const existing = byPath.get(path);\n const evidence = {\n kind: \"memory_fact\" as const,\n factId: incident.id,\n content: incident.content,\n createdAt: incident.createdAt,\n };\n if (!existing) {\n byPath.set(path, {\n path,\n weight: severityWeight(incident.severity),\n reason: `This file is linked to prior ${incident.severity} incident memory.`,\n evidence: [evidence],\n });\n continue;\n }\n existing.weight = Math.max(existing.weight, severityWeight(incident.severity));\n existing.reason = `This file is linked to ${existing.evidence.length + 1} prior incident memories.`;\n existing.evidence.push(evidence);\n }\n }\n\n return [...byPath.values()];\n },\n };\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction severityWeight(severity: IncidentSeverity): number {\n switch (severity) {\n case \"critical\":\n return 95;\n case \"high\":\n return 80;\n case \"medium\":\n return 55;\n case \"low\":\n return 30;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nconst policyRuleSchema = z.object({\n id: z.string().min(1),\n pattern: z.string().min(1),\n message: z.string().min(1).optional(),\n reason: z.string().min(1).optional(),\n weight: z.number().min(0).max(100).default(50),\n});\n\nconst policyFileSchema = z.object({\n rules: z.array(policyRuleSchema).default([]),\n});\n\nexport type PolicyRule = z.infer<typeof policyRuleSchema>;\nexport type PolicyFile = z.infer<typeof policyFileSchema>;\n\nexport type PolicySignalOptions = {\n repositoryRoot: string;\n enabled?: boolean;\n coefficient?: number;\n policyPath?: string;\n};\n\nexport function createPolicySignal(options: PolicySignalOptions): Signal {\n return {\n id: \"policy\",\n category: \"policy\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 1,\n async assess(input) {\n const policy = await readPolicyFile(\n options.policyPath ?? join(options.repositoryRoot, \".codebuddy\", \"policies.yaml\"),\n );\n if (policy.rules.length === 0) return [];\n\n const byPath = new Map<string, SignalContribution>();\n for (const path of input.paths) {\n for (const rule of policy.rules) {\n if (!matchesPolicyGlob(path, rule.pattern)) continue;\n const existing = byPath.get(path);\n const evidence = { kind: \"policy_rule\" as const, ruleId: rule.id, pattern: rule.pattern };\n const reason = rule.message ?? rule.reason ?? `Policy rule ${rule.id} matched ${path}.`;\n if (!existing) {\n byPath.set(path, {\n path,\n weight: rule.weight,\n reason,\n evidence: [evidence],\n });\n continue;\n }\n existing.weight = Math.max(existing.weight, rule.weight);\n existing.evidence.push(evidence);\n if (rule.weight >= existing.weight) existing.reason = reason;\n }\n }\n return [...byPath.values()];\n },\n };\n}\n\nexport async function readPolicyFile(path: string): Promise<PolicyFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n return policyFileSchema.parse(parseYaml(raw) ?? {});\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { rules: [] };\n throw error;\n }\n}\n\n/** Match a repo-relative path against a simple `*` / `**` glob pattern. */\nexport function matchesPolicyGlob(path: string, glob: string): boolean {\n const normalizedPath = normalize(path);\n const normalizedGlob = normalize(glob);\n const pattern = normalizedGlob\n .split(\"**\")\n .map((part) => part.split(\"*\").map(escapeRegExp).join(\"[^/]*\"))\n .join(\".*\");\n return new RegExp(`^${pattern}$`).test(normalizedPath);\n}\n\nfunction normalize(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n}\n","import { spawn } from \"node:child_process\";\nimport { relative, resolve, sep } from \"node:path\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { PlanFileStore } from \"../core/plan-file-store.js\";\nimport { RiskAssessor } from \"./assessor.js\";\nimport { createChurnSignal } from \"./signals/churn.js\";\nimport { createIncidentSignal } from \"./signals/incident.js\";\nimport { createPolicySignal } from \"./signals/policy.js\";\nimport type { Assessment, Signal } from \"./types.js\";\n\nexport type RiskAssessRequest = {\n repositoryRoot?: string;\n namespace: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n limit?: number;\n signals?: Signal[];\n};\n\nexport async function assessRisk(input: RiskAssessRequest): Promise<Assessment> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const paths = await resolveRiskPaths({\n repositoryRoot,\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n });\n if (paths.length === 0) {\n return {\n items: [],\n stats: { pathsConsidered: 0, itemsProduced: 0, signalsRun: 0, perSignal: [] },\n };\n }\n\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const signals = input.signals ?? [\n createIncidentSignal({ store: memoryStore }),\n createPolicySignal({ repositoryRoot }),\n ...(input.useGit === false ? [] : [createChurnSignal({ repositoryRoot })]),\n ];\n\n const assessment = await new RiskAssessor(signals).assess({\n paths,\n repositoryRoot,\n namespace: input.namespace,\n });\n return {\n ...assessment,\n items: input.limit ? assessment.items.slice(0, input.limit) : assessment.items,\n };\n}\n\nexport async function resolveRiskPaths(input: {\n repositoryRoot: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n}): Promise<string[]> {\n const paths = new Set<string>();\n for (const path of input.paths ?? []) {\n if (!path.trim()) continue;\n // Containment guard: tool callers can pass arbitrary path strings, and a\n // `../`-style escape must never flow into file reads downstream\n // (computeTargetSymbols, savings fallbacks, etc.). Kept paths are\n // rewritten to their resolved repo-relative POSIX form.\n const contained = containedRelativePath(input.repositoryRoot, path);\n if (contained) paths.add(contained);\n }\n\n if (input.planId) {\n const plan = await new PlanFileStore(input.repositoryRoot).readPlan(input.planId);\n for (const file of plan.filesToTouch) {\n const contained = containedRelativePath(input.repositoryRoot, file.path);\n if (contained) paths.add(contained);\n }\n }\n\n if (input.useGit !== false && (input.useGit || paths.size === 0)) {\n for (const path of await changedGitPaths(input.repositoryRoot)) {\n const contained = containedRelativePath(input.repositoryRoot, path);\n if (contained) paths.add(contained);\n }\n }\n\n const resolved = [...paths].sort();\n // Bound the change set so one huge branch cannot blow any payload derived\n // from it. Sorted above, so the cap keeps the lexicographically-first paths.\n return resolved.length > MAX_RESOLVED_PATHS ? resolved.slice(0, MAX_RESOLVED_PATHS) : resolved;\n}\n\n/** Hard cap on resolved target paths per assessment/context call. */\nexport const MAX_RESOLVED_PATHS = 200;\n\n/**\n * Resolve `path` against `root`; return its repo-relative POSIX form when it\n * stays inside the repository, or null when it escapes (or is empty).\n * Rejects NUL bytes and absolute paths pointing outside the root.\n */\nfunction containedRelativePath(root: string, path: string): string | null {\n const trimmed = normalizePath(path);\n if (!trimmed || trimmed.includes(\"\\0\")) return null;\n const absolute = resolve(root, trimmed);\n const relativePath = relative(resolve(root), absolute).split(sep).join(\"/\");\n if (relativePath === \"\" || relativePath === \"..\" || relativePath.startsWith(\"../\")) return null;\n return relativePath;\n}\n\nasync function changedGitPaths(repositoryRoot: string): Promise<string[]> {\n const [tracked, untracked] = await Promise.all([\n runGit(repositoryRoot, [\"diff\", \"--name-only\", \"HEAD\"]),\n runGit(repositoryRoot, [\"ls-files\", \"--others\", \"--exclude-standard\"]),\n ]);\n return [...tracked.stdout.split(\"\\n\"), ...untracked.stdout.split(\"\\n\")]\n .map((path) => path.trim())\n .filter(\n (path) =>\n path && !path.startsWith(\".codebuddy/cache/\") && !path.startsWith(\".codebuddy/worklog/\"),\n );\n}\n\nfunction runGit(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolveResult, reject) => {\n const child = spawn(\"git\", args, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolveResult({ code: code ?? 0, stdout, stderr }));\n });\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { applySessionDelivery, type DeliveryOptions } from \"../../context/delivery.js\";\nimport { buildBeforeEditContext, buildBootstrapContext } from \"../../context/engine.js\";\nimport type { CodeBuddy } from \"../../core/codebuddy.js\";\nimport { loadPlanPolicy } from \"../../core/config-file.js\";\nimport { listFactsPage } from \"../../core/operations.js\";\nimport { PlanFileStore } from \"../../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../../core/plan-lifecycle.js\";\nimport type { MemoryRepository } from \"../../core/repository.js\";\nimport type { CodeBuddyConfig, RecallInput, RememberInput } from \"../../core/types.js\";\nimport { llmMemoryOptions } from \"../../hooks/runtime.js\";\nimport { loadFreshIndex } from \"../../indexer/engine.js\";\nimport { loadArchitectureMap } from \"../../map/cache.js\";\nimport { buildArchitectureMap, neighbours, queryMap } from \"../../map/indexer.js\";\nimport { captureAfterTurn } from \"../../memory-extract/engine.js\";\nimport { assessRisk } from \"../../risk/service.js\";\nimport { generateSuggestions } from \"../../suggest/engine.js\";\nimport type { DatabaseServices, LazyDatabase } from \"../database.js\";\nimport { serializeToolResult } from \"../tool-result.js\";\n\n/**\n * Input caps. The output side is bounded (LIMITS in the context engine,\n * list_facts ≤ 100); the input side must be too — one tool call should never\n * push megabytes of content into Postgres, the embedding queue, or a plan\n * file that later flows back into agent context.\n */\nconst INPUT_LIMITS = {\n contentChars: 32_000,\n batchItems: 100,\n summaryChars: 32_000,\n planBodyChars: 64_000,\n planBriefChars: 4_000,\n titleChars: 300,\n arrayItems: 100,\n pathChars: 1_024,\n taskChars: 2_000,\n agentIdChars: 200,\n} as const;\n\n/** Optional session-aware delivery fields shared by the context tools. */\nconst deliverySchema = {\n sessionId: z.string().min(1).max(200).optional(),\n ack: z\n .string()\n .regex(/^dlv_[a-z0-9]+$/)\n .optional(),\n full: z.boolean().optional(),\n};\n\nconst rememberSchema = {\n sessionId: z.string().min(1).max(200).optional(),\n content: z.string().min(1).max(INPUT_LIMITS.contentChars),\n type: z.enum([\"interaction\", \"fact\", \"summary\"]).optional(),\n idempotencyKey: z.string().min(1).max(200).optional(),\n agentId: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n};\n\nconst recallSchema = {\n sessionId: z.string().min(1).max(200),\n query: z.string().min(1).max(INPUT_LIMITS.taskChars),\n budget: z.number().int().positive().optional(),\n callerModel: z.string().min(1).max(200).optional(),\n conflictMode: z.enum([\"all\", \"latest\", \"highest_confidence\"]).optional(),\n};\n\nconst shareSchema = {\n from: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n to_namespace: z.string().min(1).max(INPUT_LIMITS.agentIdChars),\n factIds: z.array(z.string().min(1).max(100)).min(1).max(INPUT_LIMITS.arrayItems),\n mode: z.enum([\"reference\", \"snapshot\"]).optional(),\n /** Snapshot mode: the target project's root; its Markdown store receives the copy. */\n to_project_root: z.string().min(1).max(INPUT_LIMITS.pathChars).optional(),\n agentId: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n};\n\nconst unshareSchema = {\n to_namespace: z.string().min(1).max(INPUT_LIMITS.agentIdChars),\n factIds: z.array(z.string().min(1).max(100)).min(1).max(INPUT_LIMITS.arrayItems),\n agentId: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n};\n\nconst plannedFileSchema = z.object({\n path: z.string().min(1).max(INPUT_LIMITS.pathChars),\n action: z.enum([\"create\", \"edit\", \"delete\"]),\n notes: z.string().max(INPUT_LIMITS.taskChars).optional(),\n});\nconst plannedTestSchema = z.object({\n path: z.string().min(1).max(INPUT_LIMITS.pathChars),\n description: z.string().max(INPUT_LIMITS.taskChars).optional(),\n});\nconst planPatchSchema = {\n title: z.string().min(1).max(INPUT_LIMITS.titleChars).optional(),\n brief: z.string().max(INPUT_LIMITS.planBriefChars).optional(),\n body: z.string().max(INPUT_LIMITS.planBodyChars).optional(),\n filesToTouch: z.array(plannedFileSchema).max(INPUT_LIMITS.arrayItems).optional(),\n testsToAdd: z.array(plannedTestSchema).max(INPUT_LIMITS.arrayItems).optional(),\n outOfScope: z\n .array(z.string().max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n risks: z.array(z.string().max(INPUT_LIMITS.taskChars)).max(INPUT_LIMITS.arrayItems).optional(),\n};\n\nexport const mcpToolInputSchemas = {\n remember: z.object(rememberSchema),\n remember_batch: z.object({ items: z.array(z.object(rememberSchema)).min(1) }),\n recall: z.object(recallSchema),\n list_facts: z.object({\n subject: z.string().optional(),\n limit: z.number().int().positive().max(100).default(50),\n cursor: z.string().optional(),\n }),\n list_namespaces: z.object({}),\n forget: z.object({ id: z.string().min(1) }),\n share: z.object(shareSchema),\n unshare: z.object(unshareSchema),\n plan_current: z.object({}),\n plan_create: z.object({\n title: z.string().min(1).max(INPUT_LIMITS.titleChars),\n brief: z.string().min(1).max(INPUT_LIMITS.planBriefChars),\n body: z.string().max(INPUT_LIMITS.planBodyChars).optional(),\n filesToTouch: z.array(plannedFileSchema).max(INPUT_LIMITS.arrayItems).optional(),\n testsToAdd: z.array(plannedTestSchema).max(INPUT_LIMITS.arrayItems).optional(),\n outOfScope: z\n .array(z.string().max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n risks: z.array(z.string().max(INPUT_LIMITS.taskChars)).max(INPUT_LIMITS.arrayItems).optional(),\n agentId: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n }),\n plan_amend: z.object({ id: z.string().min(1), patch: z.object(planPatchSchema) }),\n plan_status: z.object({\n id: z.string().min(1),\n status: z.enum([\"approved\", \"executing\", \"complete\", \"abandoned\"]),\n commitSha: z.string().optional(),\n notes: z.string().optional(),\n reason: z.string().optional(),\n }),\n risk_assess: z.object({\n planId: z.string().min(1).max(100).optional(),\n paths: z\n .array(z.string().min(1).max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n evidence: z.enum([\"overview\", \"source\"]).optional(),\n useGit: z.boolean().optional(),\n limit: z.number().int().positive().max(100).optional(),\n }),\n map_query: z.object({\n from: z.string().min(1).max(INPUT_LIMITS.pathChars).optional(),\n to: z.string().min(1).max(INPUT_LIMITS.pathChars).optional(),\n limit: z.number().int().positive().max(100).optional(),\n }),\n map_neighbours: z.object({\n module: z.string().min(1).max(INPUT_LIMITS.pathChars),\n direction: z.enum([\"in\", \"out\", \"both\"]).default(\"both\"),\n }),\n context_bootstrap: z.object({ ...deliverySchema }),\n context_before_edit: z.object({\n task: z.string().min(1).max(INPUT_LIMITS.taskChars).optional(),\n paths: z\n .array(z.string().min(1).max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n planId: z.string().min(1).max(100).optional(),\n evidence: z.enum([\"overview\", \"source\"]).optional(),\n useGit: z.boolean().optional(),\n tokenBudget: z.number().int().positive().max(100_000).optional(),\n ...deliverySchema,\n }),\n context_pack: z.object({\n task: z.string().min(1).max(INPUT_LIMITS.taskChars),\n paths: z\n .array(z.string().min(1).max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n planId: z.string().min(1).max(100).optional(),\n evidence: z.enum([\"overview\", \"source\"]).optional(),\n useGit: z.boolean().optional(),\n tokenBudget: z.number().int().positive().max(100_000).optional(),\n ...deliverySchema,\n }),\n context_after_turn: z.object({\n summary: z.string().min(1).max(INPUT_LIMITS.summaryChars),\n changedFiles: z\n .array(z.string().min(1).max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n planId: z.string().min(1).max(100).optional(),\n taskType: z.string().min(1).max(100).optional(),\n agentId: z.string().min(1).max(INPUT_LIMITS.agentIdChars).optional(),\n sessionId: z.string().min(1).max(200).optional(),\n verification: z.array(z.string().min(1).max(500)).max(20).optional(),\n commitSha: z.string().min(7).max(64).optional(),\n }),\n code_suggestions: z.object({\n paths: z\n .array(z.string().min(1).max(INPUT_LIMITS.pathChars))\n .max(INPUT_LIMITS.arrayItems)\n .optional(),\n planId: z.string().min(1).max(100).optional(),\n evidence: z.enum([\"overview\", \"source\"]).optional(),\n useGit: z.boolean().optional(),\n limit: z.number().int().positive().max(100).optional(),\n }),\n health: z.object({}),\n} as const;\n\n/** Tools that need PostgreSQL; every other tool is file-based. */\nconst DATABASE_TOOLS = [\n \"remember\",\n \"remember_batch\",\n \"recall\",\n \"list_facts\",\n \"list_namespaces\",\n \"forget\",\n \"share\",\n \"unshare\",\n];\nconst FILE_TOOLS = Object.keys(mcpToolInputSchemas).filter(\n (name) => !DATABASE_TOOLS.includes(name),\n);\nconst DEGRADED_FALLBACK =\n \"PostgreSQL is unavailable, so this call did nothing. File-based tools still work; read the repository directly and say recall is unavailable instead of guessing. Run `codebuddy db doctor` to diagnose; the next call after retryInMs reconnects.\";\n\n/**\n * Client tool profiles (#45). `full` (default) lists every tool; `core` lists\n * only the automatic context workflow, so a client pays a fraction of the\n * tool-schema tokens per session. Set `CODEBUDDY_TOOL_PROFILE=core` in the\n * client's MCP server environment.\n */\nexport type ToolProfile = \"core\" | \"full\";\nexport const CORE_TOOLS = [\n \"context_pack\",\n \"context_bootstrap\",\n \"context_before_edit\",\n \"context_after_turn\",\n \"code_suggestions\",\n \"health\",\n];\n\nexport function resolveToolProfile(value = process.env.CODEBUDDY_TOOL_PROFILE): ToolProfile {\n if (value === undefined || value === \"\" || value === \"full\") return \"full\";\n if (value === \"core\") return \"core\";\n throw new Error(`CODEBUDDY_TOOL_PROFILE must be \"core\" or \"full\", got \"${value}\"`);\n}\n\nexport type RegisterCodeBuddyToolsOptions =\n | { memory: CodeBuddy; repository: MemoryRepository }\n | {\n /** File-based tools read only namespace/projectRoot/tokenBudget from this. */\n config: Pick<CodeBuddyConfig, \"namespace\"> & {\n projectRoot?: string | undefined;\n tokenBudget?: number | undefined;\n };\n /** Optional PostgreSQL services; database tools degrade while it is unavailable. */\n database: Pick<LazyDatabase, \"get\" | \"status\">;\n };\n\n/** Cap plan bodies returned over MCP so a huge plan can't blow the context. */\nconst PLAN_BODY_LIMIT = 8_000;\n\nfunction serializePlan(plan: import(\"../../core/plan-file-store.js\").PlanSpec | null) {\n if (!plan) return { plan: null };\n const body =\n plan.body.length > PLAN_BODY_LIMIT\n ? `${plan.body.slice(0, PLAN_BODY_LIMIT)}\\n\\n…[truncated]`\n : plan.body;\n return { plan: { ...plan, body } };\n}\n\nexport function registerCodeBuddyTools(\n server: McpServer,\n options: RegisterCodeBuddyToolsOptions,\n profile: ToolProfile = \"full\",\n) {\n const exposed = (name: string) => profile === \"full\" || CORE_TOOLS.includes(name);\n // Every tool is defined once; tools outside the profile are dropped from tools/list.\n const register: McpServer[\"registerTool\"] = (name, config, callback) => {\n const tool = server.registerTool(name, config, callback);\n if (!exposed(name)) tool.remove();\n return tool;\n };\n const json = serializeToolResult;\n\n const config = \"database\" in options ? options.config : options.memory.config;\n const database: Pick<LazyDatabase, \"get\" | \"status\"> =\n \"database\" in options\n ? options.database\n : { get: async () => options, status: () => ({ available: true, state: \"ready\" }) };\n /** Run a database tool, or return an explicit, bounded degraded result. */\n const viaDatabase = async (tool: string, run: (db: DatabaseServices) => Promise<unknown>) => {\n let db: DatabaseServices;\n try {\n db = await database.get();\n } catch {\n return {\n ...json({ degraded: true, tool, database: database.status(), fallback: DEGRADED_FALLBACK }),\n isError: true,\n };\n }\n return json(await run(db));\n };\n\n const namespace = config.namespace;\n const projectRoot = config.projectRoot ?? process.cwd();\n const rankContextFacts = async (\n task: string,\n candidates: Array<{ id: string; text: string }>,\n ) => {\n // File context never starts or waits for an unavailable database connection.\n if (database.status().state !== \"ready\") return {};\n try {\n const { memory } = await database.get();\n return await memory.rankContextFacts(\n task,\n candidates.map(({ id }) => id),\n );\n } catch {\n return {};\n }\n };\n const planStore = new PlanFileStore(projectRoot);\n const planLifecycle = new PlanLifecycle(planStore);\n const toFiles = (\n items?: Array<{\n path: string;\n action: \"create\" | \"edit\" | \"delete\";\n notes?: string | undefined;\n }>,\n ) => items?.map((item) => ({ path: item.path, action: item.action, notes: item.notes ?? \"\" }));\n const toTests = (items?: Array<{ path: string; description?: string | undefined }>) =>\n items?.map((item) => ({ path: item.path, description: item.description ?? \"\" }));\n\n register(\n \"remember\",\n {\n title: \"Remember\",\n description: \"Store one CodeBuddy memory item.\",\n inputSchema: mcpToolInputSchemas.remember.shape,\n },\n async (input) => viaDatabase(\"remember\", (db) => db.memory.remember(toRememberInput(input))),\n );\n\n register(\n \"remember_batch\",\n {\n title: \"Remember batch\",\n description: \"Store multiple CodeBuddy memory items.\",\n inputSchema: mcpToolInputSchemas.remember_batch.shape,\n },\n async (input) =>\n viaDatabase(\"remember_batch\", async (db) => ({\n items: await db.memory.rememberBatch(input.items.map(toRememberInput)),\n })),\n );\n\n register(\n \"recall\",\n {\n title: \"Recall\",\n description: \"Recall prompt-ready CodeBuddy context.\",\n inputSchema: mcpToolInputSchemas.recall.shape,\n },\n async (input) => viaDatabase(\"recall\", (db) => db.memory.recall(toRecallInput(input))),\n );\n\n register(\n \"list_facts\",\n {\n title: \"List facts\",\n description: \"List facts in the configured namespace.\",\n inputSchema: mcpToolInputSchemas.list_facts.shape,\n },\n async (input) =>\n viaDatabase(\"list_facts\", (db) =>\n listFactsPage(\n db.memory,\n db.repository,\n cleanOptional(input) as { subject?: string; limit?: number; cursor?: string },\n ),\n ),\n );\n\n register(\n \"list_namespaces\",\n {\n title: \"List namespaces\",\n description: \"List CodeBuddy namespaces.\",\n inputSchema: mcpToolInputSchemas.list_namespaces.shape,\n },\n async () =>\n viaDatabase(\"list_namespaces\", async (db) => ({\n namespaces: await db.repository.listNamespaces(),\n })),\n );\n\n register(\n \"forget\",\n {\n title: \"Forget\",\n description: \"Delete an interaction or fact by id.\",\n inputSchema: mcpToolInputSchemas.forget.shape,\n },\n async (input) => viaDatabase(\"forget\", (db) => db.memory.forget(input.id)),\n );\n\n register(\n \"share\",\n {\n title: \"Share\",\n description:\n \"Share facts from the configured namespace to another namespace. Reference (default) is a live, revocable grant; snapshot copies the fact into the target project's Markdown store (requires to_project_root).\",\n inputSchema: mcpToolInputSchemas.share.shape,\n },\n async (input) =>\n viaDatabase(\"share\", (db) =>\n db.memory.share({\n from: input.from ?? namespace,\n to: input.to_namespace,\n factIds: input.factIds,\n ...(input.mode ? { mode: input.mode } : {}),\n ...(input.to_project_root ? { targetProjectRoot: input.to_project_root } : {}),\n ...(input.agentId ? { agentId: input.agentId } : {}),\n }),\n ),\n );\n\n register(\n \"unshare\",\n {\n title: \"Unshare\",\n description:\n \"Revoke live reference shares of configured-namespace facts to another namespace.\",\n inputSchema: mcpToolInputSchemas.unshare.shape,\n },\n async (input) =>\n viaDatabase(\"unshare\", (db) =>\n db.memory.unshare({\n to: input.to_namespace,\n factIds: input.factIds,\n ...(input.agentId ? { agentId: input.agentId } : {}),\n }),\n ),\n );\n\n // ── Plan tools (Proposal 02.6) ────────────────────────────────────\n register(\n \"plan_current\",\n {\n title: \"Current plan\",\n description: \"Return the active (approved or executing) plan for this namespace, or null.\",\n inputSchema: mcpToolInputSchemas.plan_current.shape,\n },\n async () => {\n const [current, policy] = await Promise.all([\n planLifecycle.current(namespace),\n loadPlanPolicy(projectRoot),\n ]);\n return json({ ...serializePlan(current), policy });\n },\n );\n\n register(\n \"plan_create\",\n {\n title: \"Create plan\",\n description: \"Create a draft plan in this namespace.\",\n inputSchema: mcpToolInputSchemas.plan_create.shape,\n },\n async (input) => {\n const files = toFiles(input.filesToTouch);\n const tests = toTests(input.testsToAdd);\n const created = await planLifecycle.create({\n namespace,\n title: input.title,\n brief: input.brief,\n ...(input.body !== undefined ? { body: input.body } : {}),\n ...(files ? { filesToTouch: files } : {}),\n ...(tests ? { testsToAdd: tests } : {}),\n ...(input.outOfScope !== undefined ? { outOfScope: input.outOfScope } : {}),\n ...(input.risks !== undefined ? { risks: input.risks } : {}),\n ...(input.agentId !== undefined ? { createdByAgent: input.agentId } : {}),\n });\n return json(serializePlan(created));\n },\n );\n\n register(\n \"plan_amend\",\n {\n title: \"Amend plan\",\n description: \"Amend a draft or executing plan's content fields.\",\n inputSchema: mcpToolInputSchemas.plan_amend.shape,\n },\n async (input) => {\n const patch = input.patch;\n const files = toFiles(patch.filesToTouch);\n const tests = toTests(patch.testsToAdd);\n const amended = await planLifecycle.amend(input.id, {\n ...(patch.title !== undefined ? { title: patch.title } : {}),\n ...(patch.brief !== undefined ? { brief: patch.brief } : {}),\n ...(patch.body !== undefined ? { body: patch.body } : {}),\n ...(files ? { filesToTouch: files } : {}),\n ...(tests ? { testsToAdd: tests } : {}),\n ...(patch.outOfScope !== undefined ? { outOfScope: patch.outOfScope } : {}),\n ...(patch.risks !== undefined ? { risks: patch.risks } : {}),\n });\n return json(serializePlan(amended));\n },\n );\n\n register(\n \"plan_status\",\n {\n title: \"Transition plan\",\n description: \"Move a plan through its lifecycle: approved, executing, complete, abandoned.\",\n inputSchema: mcpToolInputSchemas.plan_status.shape,\n },\n async (input) => {\n let next: import(\"../../core/plan-file-store.js\").PlanSpec;\n if (input.status === \"approved\") next = await planLifecycle.approve(input.id);\n else if (input.status === \"executing\") next = await planLifecycle.start(input.id);\n else if (input.status === \"complete\")\n next = await planLifecycle.complete(input.id, {\n ...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n ...(input.notes !== undefined ? { notes: input.notes } : {}),\n });\n else\n next = await planLifecycle.abandon(\n input.id,\n input.reason !== undefined ? { reason: input.reason } : {},\n );\n return json(serializePlan(next));\n },\n );\n\n register(\n \"risk_assess\",\n {\n title: \"Assess risk\",\n description: \"Assess evidence-backed risk for a plan, explicit paths, or git changes.\",\n inputSchema: mcpToolInputSchemas.risk_assess.shape,\n },\n async (input) =>\n json(\n await assessRisk({\n repositoryRoot: projectRoot,\n namespace,\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n ...(input.limit !== undefined ? { limit: input.limit } : {}),\n }),\n ),\n );\n\n register(\n \"map_query\",\n {\n title: \"Query architecture map\",\n description: \"Query lightweight module import edges in the current repository.\",\n inputSchema: mcpToolInputSchemas.map_query.shape,\n },\n async (input) => {\n const graph = await cachedMap();\n return json(\n queryMap(graph, {\n ...(input.from !== undefined ? { from: input.from } : {}),\n ...(input.to !== undefined ? { to: input.to } : {}),\n ...(input.limit !== undefined ? { limit: input.limit } : {}),\n }),\n );\n },\n );\n\n register(\n \"map_neighbours\",\n {\n title: \"Module neighbours\",\n description: \"Return inbound/outbound neighbours for a repository module.\",\n inputSchema: mcpToolInputSchemas.map_neighbours.shape,\n },\n async (input) => json(neighbours(await cachedMap(), input.module, input.direction)),\n );\n\n // ── Context engine tools (Proposal 04.2) ──────────────────────────\n const tokenBudget = config.tokenBudget;\n\n /**\n * The map cache (`.codebuddy/cache/architecture.json`) is the same source the\n * context engine uses. The index is validated against current source first\n * so edited imports are re-read; fall back to a fresh build only when no\n * cache exists yet.\n */\n const cachedMap = async () => {\n const { manifest } = await loadFreshIndex(projectRoot);\n const cached = await loadArchitectureMap(projectRoot, manifest);\n if (cached.map.modules.length > 0) return cached.map;\n return buildArchitectureMap(projectRoot);\n };\n\n register(\n \"context_bootstrap\",\n {\n title: \"Bootstrap project context\",\n description:\n \"Return compact project awareness for the start of a turn: identity, active plan and policy, top policy rules, incident hotspots, and an architecture summary. Prefer this over a manual recall at session start. Optional sessionId enables session-aware delivery: pass the previous response's delivery.deliveryId as ack and unchanged sections are omitted (listed in delivery.unchanged); pass full=true to get everything again.\",\n inputSchema: mcpToolInputSchemas.context_bootstrap.shape,\n },\n async (input) =>\n json(\n await applySessionDelivery(\n projectRoot,\n await buildBootstrapContext({\n repositoryRoot: projectRoot,\n namespace,\n ...(tokenBudget !== undefined ? { tokenBudget } : {}),\n }),\n deliveryOptions(input),\n ),\n ),\n );\n\n register(\n \"context_before_edit\",\n {\n title: \"Context before edit\",\n description:\n \"Assemble relevant context before changing code: resolves target files from paths, a plan, or git, then returns the relevant plan, matching policy rules, incident memory, an evidence-backed risk assessment, and import neighbours. Optional sessionId enables session-aware delivery: pass the previous response's delivery.deliveryId as ack and unchanged sections are omitted (listed in delivery.unchanged); pass full=true to get everything again.\",\n inputSchema: mcpToolInputSchemas.context_before_edit.shape,\n },\n async (input) =>\n json(\n await applySessionDelivery(\n projectRoot,\n await buildBeforeEditContext({\n repositoryRoot: projectRoot,\n namespace,\n semanticRanker: rankContextFacts,\n ...(input.evidence ? { evidence: input.evidence } : {}),\n ...(input.task !== undefined ? { task: input.task } : {}),\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n ...(input.tokenBudget !== undefined ? { tokenBudget: input.tokenBudget } : {}),\n ...(tokenBudget !== undefined && input.tokenBudget === undefined\n ? { tokenBudget }\n : {}),\n }),\n deliveryOptions(input),\n ),\n ),\n );\n\n register(\n \"context_pack\",\n {\n title: \"Build task context pack\",\n description:\n \"Build the smallest useful context pack for a coding task. Automatically finds relevant files from the local index when paths are omitted, then includes only bounded symbols, policies, risks, incidents, architecture neighbours, and relevant team facts within the requested token budget. Use this once at the start of a task instead of manually chaining context, risk, map, and memory tools. Request evidence=source with exact paths when short excerpts omit needed behavior; source excerpts remain bounded by the token budget. Optional sessionId enables session-aware delivery: pass the previous response's delivery.deliveryId as ack and unchanged sections are omitted (listed in delivery.unchanged); pass full=true to get everything again.\",\n inputSchema: mcpToolInputSchemas.context_pack.shape,\n },\n async (input) =>\n json(\n await applySessionDelivery(\n projectRoot,\n await buildBeforeEditContext({\n repositoryRoot: projectRoot,\n namespace,\n task: input.task,\n semanticRanker: rankContextFacts,\n ...(input.evidence ? { evidence: input.evidence } : {}),\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n tokenBudget: input.tokenBudget ?? tokenBudget ?? 4_000,\n }),\n deliveryOptions(input),\n ),\n ),\n );\n\n register(\n \"context_after_turn\",\n {\n title: \"Capture context after a turn\",\n description:\n \"Extract durable knowledge from a turn summary. Confident facts/decisions/incidents are auto-saved as Markdown; temporary notes, low-confidence, and sensitive items are queued for review under .codebuddy/memory/review/; chatter is ignored. Never saves sensitive content automatically. Turns that changed files or report verification also record a bounded worklog handoff under .codebuddy/worklog/ so later chats can recover the work.\",\n inputSchema: mcpToolInputSchemas.context_after_turn.shape,\n },\n async (input) => {\n const result = await captureAfterTurn(\n {\n summary: input.summary,\n namespace,\n ...(input.changedFiles !== undefined ? { changedFiles: input.changedFiles } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.taskType !== undefined ? { taskType: input.taskType } : {}),\n ...(input.agentId !== undefined ? { agentId: input.agentId } : {}),\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.verification !== undefined ? { verification: input.verification } : {}),\n ...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n },\n {\n repositoryRoot: projectRoot,\n ...((input.changedFiles?.length ?? 0) > 0 ? await llmMemoryOptions(projectRoot) : {}),\n },\n );\n // Capture writes reviewable Markdown first. Import it immediately so\n // database recall and the embedding worker see the same memory without\n // requiring a restart or a manual `codebuddy reindex`. Without a\n // database the Markdown is still saved and imported on reconnect.\n const db = await database.get().catch(() => undefined);\n await db?.memory.reindexMemory();\n return json({\n saved: result.saved.map((d) => ({\n id: d.ref,\n class: d.candidate.class,\n subject: d.candidate.subject,\n })),\n queuedForReview: result.queuedForReview.map((d) => ({\n id: d.ref,\n class: d.candidate.class,\n reason: d.reason,\n sensitive: d.sensitive,\n })),\n ignored: result.ignored.length,\n reasons: result.reasons,\n extractor: result.extractor,\n worklogId: result.worklogId,\n ...(db ? {} : { degraded: true, database: database.status() }),\n });\n },\n );\n\n register(\n \"code_suggestions\",\n {\n title: \"Code suggestions\",\n description:\n \"Return read-only, evidence-backed code-quality suggestions for a change set (paths, a plan, or git). Composes risk, plan divergence, architecture blast radius, incident history, missing tests, and stale policies. Never edits code.\",\n inputSchema: mcpToolInputSchemas.code_suggestions.shape,\n },\n async (input) =>\n json(\n await generateSuggestions({\n repositoryRoot: projectRoot,\n namespace,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n ...(input.limit !== undefined ? { limit: input.limit } : {}),\n }),\n ),\n );\n\n register(\n \"health\",\n {\n title: \"Health\",\n description:\n \"Report which CodeBuddy tools are available right now: file-based tools always work; database tools (recall, remember, facts) need PostgreSQL. Does not wait on a connection attempt.\",\n inputSchema: mcpToolInputSchemas.health.shape,\n },\n async () =>\n json({\n database: database.status(),\n tools: {\n profile,\n file: FILE_TOOLS.filter(exposed),\n database: DATABASE_TOOLS.filter(exposed),\n },\n }),\n );\n}\n\nfunction deliveryOptions(input: {\n sessionId?: string | undefined;\n ack?: string | undefined;\n full?: boolean | undefined;\n}): DeliveryOptions {\n return cleanOptional(input as Record<string, unknown>) as DeliveryOptions;\n}\n\nfunction toRememberInput(input: z.infer<typeof mcpToolInputSchemas.remember>): RememberInput {\n return cleanOptional(input) as RememberInput;\n}\n\nfunction toRecallInput(input: z.infer<typeof mcpToolInputSchemas.recall>): RecallInput {\n return cleanOptional(input) as RecallInput;\n}\n\nfunction cleanOptional(input: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));\n}\n","import { createHash } from \"node:crypto\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { enforceContextBudget } from \"./budget.js\";\nimport { SessionCapsuleLedger } from \"./session-ledger.js\";\n\n/**\n * Session-aware delivery for the MCP context tools. With a `sessionId`, a\n * section whose exact content the client already confirmed receiving (via\n * `ack`) in this session is omitted and listed in `delivery.unchanged`; the\n * ledger keeps a few acknowledged versions per section, so switching back to\n * an earlier task does not resend what the client still holds. Without a\n * `sessionId` the payload is returned untouched, so clients without session\n * support always get complete context.\n *\n * Safety evidence that changes per call (target paths, risks, diffs) is never\n * omitted. Any ledger failure falls back to the full payload.\n */\n\n/** Delivery contract version, bumped on any incompatible change. */\nexport const DELIVERY_VERSION = 1;\n\n/** Sections that may be omitted when unchanged. Everything else is always sent. */\nconst OMITTABLE_SECTIONS = [\n \"plan\",\n \"policyRules\",\n \"incidents\",\n \"facts\",\n \"rules\",\n \"handoffs\",\n \"architecture\",\n \"symbols\",\n \"neighbours\",\n] as const;\n\n/**\n * An acknowledged section is only treated as already-seen for this long; after\n * that it is resent, bounding how stale a client's copy can get.\n */\nconst SESSION_TTL_MS = 30 * 60 * 1000;\n\nexport type DeliveryOptions = {\n sessionId?: string;\n /** The `deliveryId` of the previous response the client actually received. */\n ack?: string;\n /** Resend every section, e.g. after the client's context was compacted. */\n full?: boolean;\n};\n\nexport type DeliveryInfo = {\n version: typeof DELIVERY_VERSION;\n sessionId: string;\n deliveryId: string;\n ack: \"none\" | \"accepted\" | \"unknown\";\n unchanged: string[];\n avoidedTokens: number;\n note: string;\n};\n\nexport async function applySessionDelivery(\n repositoryRoot: string,\n payload: object,\n options: DeliveryOptions,\n): Promise<Record<string, unknown>> {\n let output: Record<string, unknown> = { ...payload };\n if (!options.sessionId) return output;\n\n // Keys stay `mcp:`-prefixed on purpose, separate from the hook capsule keys\n // (`plan`, `fact:<id>`, ...) in the same session ledger. The hook block sends\n // bounded one-line renderings marked on write; these hashes cover the full\n // JSON section and count only once acknowledged. A shared key would let a\n // clipped hook line suppress a full section it never carried, or the two\n // paths overwrite each other's records. The paths share only reset.\n const sections = OMITTABLE_SECTIONS.filter((key) => output[key] !== undefined).map((key) => ({\n key: `mcp:${key}`,\n hash: createHash(\"sha256\").update(JSON.stringify(output[key])).digest(\"hex\"),\n }));\n\n try {\n await new SessionCapsuleLedger(repositoryRoot).exchange(options.sessionId, sections, {\n ...(options.ack !== undefined ? { ack: options.ack } : {}),\n ttlMs: SESSION_TTL_MS,\n ...(options.full ? { full: true } : {}),\n prepare: (exchange) => {\n const unchanged = exchange.unchanged.map((key) => key.slice(\"mcp:\".length));\n let avoidedTokens = 0;\n for (const key of unchanged) {\n avoidedTokens += estimateTokens(output[key]);\n delete output[key];\n }\n const delivery: DeliveryInfo = {\n version: DELIVERY_VERSION,\n sessionId: options.sessionId as string,\n deliveryId: exchange.deliveryId,\n ack: exchange.ack,\n unchanged,\n avoidedTokens,\n note: \"Pass deliveryId as ack. Use full=true after losing context.\",\n };\n output.delivery = delivery;\n output = enforceContextBudget(output);\n // Hash what was actually delivered. A section shortened or omitted by\n // the budget must never acknowledge its original, complete version.\n return OMITTABLE_SECTIONS.filter((key) => output[key] !== undefined).map((key) => ({\n key: `mcp:${key}`,\n hash: createHash(\"sha256\").update(JSON.stringify(output[key])).digest(\"hex\"),\n }));\n },\n });\n return output;\n } catch {\n return enforceContextBudget({ ...payload });\n }\n}\n","import { estimateTokens } from \"../savings/tokens.js\";\nimport type { TokenStats } from \"./types.js\";\n\nconst WARNING = \"Context incomplete: inspect omitted policies, risks and incidents before editing.\";\n\ntype Payload = Record<string, unknown> & { tokens: TokenStats };\ntype Candidate = { section: string; value: unknown; priority: number; essential: boolean };\n\n/** Budget the complete compact JSON text, including this accounting and delivery metadata. */\nexport function enforceContextBudget<T extends object>(input: T): T {\n const output = structuredClone(input) as Payload;\n if (!output.tokens) return input;\n output.tokens.essentialOmitted ??= 0;\n if (account(output) <= output.tokens.budget) return output as T;\n\n const candidates: Candidate[] = [];\n const add = (section: string, value: unknown, priority: number, essential = false) => {\n candidates.push({ section, value, priority, essential });\n };\n for (const [section, priority] of [\n [\"diffs\", 10],\n [\"neighbours\", 20],\n [\"handoffs\", 30],\n [\"facts\", 40],\n [\"rules\", 45],\n [\"symbols\", 50],\n [\"policyRules\", 90],\n [\"incidents\", 80],\n ] as const) {\n const values = output[section];\n if (!Array.isArray(values)) continue;\n for (const value of values) {\n const essential = section === \"policyRules\" || (section === \"incidents\" && !value.resolved);\n const severity =\n section === \"incidents\"\n ? ({ critical: 4, high: 3, medium: 2, low: 1 }[value.severity as string] ?? 0)\n : 0;\n add(section, value, priority + severity, essential);\n }\n output[section] = [];\n }\n const risks = output.risks as { items: Array<{ score: number }> } | undefined;\n if (risks) {\n for (const value of risks.items)\n add(\n \"risks\",\n value,\n value.score >= 50 ? 100 + value.score : 60 + value.score / 100,\n value.score > 0,\n );\n risks.items = [];\n }\n if (output.plan) {\n add(\"plan\", output.plan, 55);\n output.plan = null;\n }\n const architecture = output.architecture as { hotspots: unknown[] } | undefined;\n if (architecture) {\n for (const value of architecture.hotspots) add(\"hotspots\", value, 25);\n architecture.hotspots = [];\n }\n output.explain = [];\n if (typeof output.task === \"string\") output.task = compact(output.task, 160);\n const riskStats = (output.risks as { stats?: { perSignal: unknown[] } } | undefined)?.stats;\n if (riskStats) riskStats.perSignal = [];\n\n // Reserve a bounded warning before selecting evidence so adding it cannot\n // silently displace the last safety item. Identity and target paths are exact.\n const previousOmitted = output.tokens.essentialOmitted;\n output.tokens.essentialOmitted = previousOmitted + candidates.filter((c) => c.essential).length;\n output.tokens.warning = WARNING;\n if (account(output) > output.tokens.budget && output.task) output.task = null;\n // No candidate selection can rescue a target set that alone exceeds the\n // budget. Avoid repeatedly tokenizing enormous change sets in that case.\n if (\n estimateTokens({ project: output.project, targetPaths: output.targetPaths }) >\n output.tokens.budget\n ) {\n account(output);\n return output as T;\n }\n\n candidates.sort((a, b) => b.priority - a.priority);\n for (const candidate of candidates) {\n const insert = (value: unknown) => {\n if (candidate.section === \"plan\") output.plan = value;\n else if (candidate.section === \"risks\") risks?.items.push(value as { score: number });\n else if (candidate.section === \"hotspots\") architecture?.hotspots.push(value);\n else (output[candidate.section] as unknown[]).push(value);\n };\n const remove = () => {\n if (candidate.section === \"plan\") output.plan = null;\n else if (candidate.section === \"risks\") risks?.items.pop();\n else if (candidate.section === \"hotspots\") architecture?.hotspots.pop();\n else (output[candidate.section] as unknown[]).pop();\n };\n insert(candidate.value);\n if (candidate.essential) output.tokens.essentialOmitted--;\n if (account(output) <= output.tokens.budget) continue;\n remove();\n if (candidate.essential) output.tokens.essentialOmitted++;\n // Keep policy instructions verbatim. A shortened safety item is explicitly\n // incomplete and retains the warning.\n const smaller = candidate.essential\n ? compactSafety(candidate.value)\n : compact(candidate.value, 100);\n insert(smaller);\n if (account(output) <= output.tokens.budget) continue;\n remove();\n }\n if (output.tokens.essentialOmitted === 0) delete output.tokens.warning;\n account(output);\n return output as T;\n}\n\nfunction compactSafety(value: unknown): unknown {\n if (!value || typeof value !== \"object\") return value;\n const item = value as Record<string, unknown>;\n // Patterns, messages, identities and paths remain exact. Risk/incident\n // narratives may be shortened with an explicit incomplete status.\n return {\n ...item,\n ...(typeof item.reason === \"string\" ? { reason: compact(item.reason, 100) } : {}),\n ...(typeof item.summary === \"string\" ? { summary: compact(item.summary, 100) } : {}),\n ...(Array.isArray(item.evidence)\n ? { evidence: item.evidence.slice(0, 1).map((entry) => compact(entry, 100)) }\n : {}),\n };\n}\n\nfunction compact(value: unknown, limit: number): unknown {\n if (typeof value === \"string\")\n return value.length > limit ? `${value.slice(0, limit - 1)}…` : value;\n if (Array.isArray(value)) return value.slice(0, 3).map((item) => compact(item, limit));\n if (value && typeof value === \"object\")\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, compact(item, limit)]),\n );\n return value;\n}\n\n/** Find an exact fixed point because the reported count itself occupies tokens. */\nfunction account(output: Payload): number {\n const tokens = output.tokens;\n const set = (count: number) => {\n tokens.returnedEstimate = count;\n tokens.countedSurface = \"compact_json\";\n tokens.status =\n count > tokens.budget\n ? \"overflow\"\n : tokens.essentialOmitted > 0\n ? \"minimum_envelope\"\n : \"within_budget\";\n if (tokens.status === \"overflow\") tokens.warning = WARNING;\n };\n // Numeric token boundaries can form a cycle. A JSON whitespace field gives\n // deterministic alternative encodings without changing any evidence.\n for (let padding = 0; padding < 32; padding++) {\n if (padding > 0) output.accountingPadding = \" \".repeat(padding);\n let count = estimateTokens(output);\n for (let attempt = 0; attempt < 12; attempt++) {\n set(count);\n const measured = estimateTokens(output);\n if (measured === count) return count;\n count = measured;\n }\n }\n throw new Error(\"Could not stabilize compact context token accounting\");\n}\n","import { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { loadPlanPolicy } from \"../core/config-file.js\";\nimport {\n type FactFile,\n type IncidentFactFile,\n MemoryFileStore,\n} from \"../core/memory-file-store.js\";\nimport { isEligibleMemory } from \"../core/memory-lifecycle.js\";\nimport { PlanFileStore, type PlanSpec } from \"../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../core/plan-lifecycle.js\";\nimport { loadFreshIndex } from \"../indexer/engine.js\";\nimport { extractSymbolTable, type SymbolSpan, supportsSymbols } from \"../indexer/symbols.js\";\nimport type { ArchitectureMap } from \"../map/types.js\";\nimport type { RetrievalHit } from \"../retrieval/zvec.js\";\nimport { assessRisk, resolveRiskPaths } from \"../risk/service.js\";\nimport { matchesPolicyGlob, type PolicyRule, readPolicyFile } from \"../risk/signals/policy.js\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { type HandoffSummary, WorklogStore } from \"../worklog/store.js\";\nimport { enforceContextBudget } from \"./budget.js\";\nimport {\n countTerms,\n discoverTaskPaths,\n identifierTokens,\n loadProjectArchitectureMap,\n namedSegments,\n readBoundedSource,\n TASK_PATH_LIMIT,\n taskTerms,\n} from \"./discovery.js\";\nimport { detectTestCommand, findCoveringTest } from \"./tests.js\";\nimport type {\n ArchitectureSummary,\n BeforeEditContext,\n BootstrapContext,\n ContextSpan,\n DiffHunk,\n FileSymbols,\n IncidentSummary,\n ModuleNeighbours,\n PathSource,\n PlanSummary,\n PolicyRuleSummary,\n RelevantFactSummary,\n TokenStats,\n} from \"./types.js\";\n\n/**\n * Bounds. These keep both tool outputs compact regardless of repository size —\n * a bootstrap or before-edit payload should orient the agent, not dump the\n * whole project. Tune here rather than at each call site.\n */\nconst LIMITS = {\n bootstrapIncidents: 5,\n beforeEditIncidents: 8,\n policyRules: 5,\n hotspots: 5,\n neighbourPaths: 10,\n neighbourEdges: 10,\n incidentSummaryChars: 140,\n symbolFiles: TASK_PATH_LIMIT,\n symbolsPerFile: 12,\n spanFiles: 3,\n excerptLines: 6,\n excerptCharsPerSpan: 400,\n excerptChars: 1_200,\n relevantFacts: 5,\n} as const;\n\nconst DEFAULT_TOKEN_BUDGET = 4_000;\nconst MAX_DIFF_FILES = 8;\nconst MAX_DIFF_CHARS_PER_FILE = 2_400;\nconst execFileAsync = promisify(execFile);\n\nexport type BootstrapInput = {\n repositoryRoot?: string;\n namespace: string;\n tokenBudget?: number;\n};\n\nexport type BeforeEditInput = {\n repositoryRoot?: string;\n namespace: string;\n task?: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n tokenBudget?: number;\n semanticRanker?: SemanticRelevanceRanker;\n evidence?: \"overview\" | \"source\";\n};\n\nexport type SemanticRelevanceRanker = (\n task: string,\n candidates: Array<{ id: string; text: string }>,\n) => Promise<Record<string, number>>;\n\n/**\n * Assemble compact project awareness for the start of a turn: identity, the\n * active plan and policy, top policy rules, incident hotspots, and a\n * lightweight architecture summary. No edit target is required.\n */\nexport async function buildBootstrapContext(input: BootstrapInput): Promise<BootstrapContext> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const namespace = input.namespace;\n\n const planStore = new PlanFileStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const freshPromise = loadFreshIndex(repositoryRoot);\n const manifestPromise = freshPromise.then((fresh) => fresh.manifest);\n const mapPromise = loadProjectArchitectureMap(repositoryRoot, manifestPromise);\n\n const [activePlan, policy, policyFile, incidents, facts, fresh, map, handoffs] =\n await Promise.all([\n new PlanLifecycle(planStore).current(namespace),\n loadPlanPolicy(repositoryRoot),\n readPolicyFile(join(repositoryRoot, \".codebuddy\", \"policies.yaml\")),\n memoryStore.listIncidentFacts({ namespace }),\n memoryStore.listFacts(),\n freshPromise,\n mapPromise,\n recallHandoffs(repositoryRoot, { namespace }),\n ]);\n\n const explain: string[] = [fresh.explain];\n const plan = summarizePlan(activePlan);\n explain.push(plan ? `plan: active plan ${plan.id} (${plan.status})` : \"plan: no active plan\");\n explain.push(`policy: plan policy is \"${policy}\"`);\n\n const policyRules = summarizePolicyRules(policyFile.rules);\n if (policyRules.length > 0) explain.push(`policyRules: ${policyRules.length} rule(s) by weight`);\n\n const incidentSummaries = sortIncidents(incidents)\n .slice(0, LIMITS.bootstrapIncidents)\n .map(summarizeIncident);\n if (incidentSummaries.length > 0) {\n explain.push(`incidents: ${incidentSummaries.length} unresolved incident hotspot(s)`);\n }\n\n const architecture = summarizeArchitecture(map);\n explain.push(\n `architecture: ${architecture.moduleCount} module(s), ${architecture.edgeCount} edge(s)` +\n (map.source ? ` (${map.source})` : \"\"),\n );\n\n const rules = selectRules(facts, namespace);\n if (rules.length > 0) {\n const procedures = rules.filter((rule) => rule.subject === \"procedure\").length;\n explain.push(`rules: ${rules.length - procedures} rule(s), ${procedures} procedure(s)`);\n }\n const bootstrapFacts = await rankRelevantFacts(\n facts.filter((fact) => !STANDING_PREDICATES.has(fact.predicate)),\n namespace,\n \"\",\n [],\n );\n explainHandoffs(explain, handoffs);\n const assembled = {\n project: { namespace, root: repositoryRoot },\n plan,\n policy,\n policyRules,\n incidents: incidentSummaries,\n facts: bootstrapFacts,\n rules,\n handoffs,\n architecture,\n explain,\n };\n const tokens = buildTokenStats(assembled, input.tokenBudget);\n return enforceContextBudget({ ...assembled, tokens });\n}\n\n/**\n * Assemble the most relevant context before an edit: resolve the target files\n * (explicit paths, a plan, or git), then attach the relevant plan, policy\n * rules, incident memory for those files, an evidence-backed risk assessment,\n * and the import neighbours of each target.\n */\nexport async function buildBeforeEditContext(input: BeforeEditInput): Promise<BeforeEditContext> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const namespace = input.namespace;\n\n const hasExplicitTargets = (input.paths?.length ?? 0) > 0 || input.planId !== undefined;\n // Validate the index against current source before any indexed symbol,\n // summary or import is trusted (issue #34).\n const fresh = await loadFreshIndex(repositoryRoot);\n const manifest = fresh.manifest;\n const resolvedPaths = await resolveRiskPaths({\n repositoryRoot,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(hasExplicitTargets\n ? { useGit: false }\n : input.useGit !== undefined\n ? { useGit: input.useGit }\n : {}),\n });\n const mapPromise = loadProjectArchitectureMap(repositoryRoot, manifest);\n const discovery =\n !hasExplicitTargets && input.task\n ? await discoverTaskPaths(repositoryRoot, input.task, manifest, mapPromise)\n : { paths: [], hits: [], explain: [] };\n const taskPaths = discovery.paths;\n const targetPaths = hasExplicitTargets\n ? resolvedPaths\n : taskPaths.length > 0\n ? taskPaths\n : resolvedPaths;\n const discoveredFromTask = taskPaths.length > 0;\n const pathSource = classifyPathSource(input, targetPaths.length, discoveredFromTask);\n\n const planStore = new PlanFileStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n\n const [referencedPlan, policy, policyFile, incidents, facts, risks, map, diffs, handoffs] =\n await Promise.all([\n resolveRelevantPlan(planStore, namespace, input.planId),\n loadPlanPolicy(repositoryRoot),\n readPolicyFile(join(repositoryRoot, \".codebuddy\", \"policies.yaml\")),\n memoryStore.findIncidentFactsForPaths({ namespace, paths: targetPaths }),\n memoryStore.listFacts(),\n assessRisk({\n repositoryRoot,\n namespace,\n ...(targetPaths.length > 0 ? { paths: targetPaths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n useGit: !hasExplicitTargets && input.useGit !== false,\n }),\n mapPromise,\n input.useGit === false\n ? Promise.resolve([] as DiffHunk[])\n : readGitDiffs(repositoryRoot, targetPaths),\n recallHandoffs(repositoryRoot, {\n namespace,\n paths: targetPaths,\n ...(input.task !== undefined ? { task: input.task } : {}),\n }),\n ]);\n\n const explain: string[] = [];\n explain.push(`paths: ${targetPaths.length} target(s) resolved from ${pathSource}`);\n explain.push(fresh.explain);\n if (discoveredFromTask && resolvedPaths.length > 0) {\n explain.push(\n `git: ${resolvedPaths.length} observed changed path(s) assessed separately from task targets`,\n );\n }\n explain.push(...discovery.explain);\n\n const plan = summarizePlan(referencedPlan);\n if (plan) explain.push(`plan: ${plan.id} (${plan.status})`);\n\n const policyRules = summarizeMatchingPolicyRules(policyFile.rules, targetPaths);\n if (policyRules.length > 0) {\n explain.push(`policyRules: ${policyRules.length} rule(s) match target paths`);\n }\n\n const incidentSummaries = sortIncidents(incidents)\n .slice(0, LIMITS.beforeEditIncidents)\n .map(summarizeIncident);\n if (incidentSummaries.length > 0) {\n explain.push(`incidents: ${incidentSummaries.length} incident(s) touch target paths`);\n }\n\n if (risks.items.length > 0) explain.push(`risks: ${risks.items.length} scored path(s)`);\n\n const neighbours = computeNeighbours(map, targetPaths);\n if (neighbours.length > 0)\n explain.push(\n `neighbours: import graph for ${neighbours.length} file(s)` +\n (map.source ? ` (${map.source})` : \"\"),\n );\n\n const symbols = await computeTargetSymbols(\n repositoryRoot,\n targetPaths,\n input.task ?? \"\",\n discovery.hits,\n \"symbols\" in discovery ? (discovery.symbols ?? {}) : {},\n input.evidence ?? \"overview\",\n );\n if (symbols.length > 0) {\n const spans = symbols.reduce((total, file) => total + (file.spans?.length ?? 0), 0);\n explain.push(\n `symbols: signatures for ${symbols.length} target file(s) (in place of full source)` +\n (spans > 0 ? `; ${spans} task-ranked span(s) read from current source` : \"\"),\n );\n }\n\n const relevantFacts = await rankRelevantFacts(\n facts.filter((fact) => !STANDING_PREDICATES.has(fact.predicate)),\n namespace,\n input.task ?? \"\",\n targetPaths,\n input.semanticRanker,\n );\n if (relevantFacts.length > 0) {\n explain.push(\n `facts: ${relevantFacts.length} durable fact(s) ranked by task/path relevance` +\n (input.semanticRanker ? \"\" : \" (lexical only; no semantic fact ranker configured)\"),\n );\n }\n explainHandoffs(explain, handoffs);\n\n const indexed = new Set(Object.keys(manifest.entries));\n const tests = targetPaths.flatMap((path) => {\n const test = findCoveringTest(path, indexed);\n return test ? [{ path, test }] : [];\n });\n const testCommand = targetPaths.length > 0 ? await detectTestCommand(repositoryRoot) : null;\n if (tests.length > 0 || testCommand) {\n explain.push(\n `tests: ${tests.length} covering test(s) by naming convention; command ${testCommand ?? \"unknown\"}`,\n );\n }\n\n const assembled = {\n project: { namespace, root: repositoryRoot },\n task: input.task ?? null,\n targetPaths,\n pathSource,\n plan,\n policy,\n policyRules,\n incidents: incidentSummaries,\n facts: relevantFacts,\n handoffs,\n risks,\n neighbours,\n symbols,\n tests,\n testCommand,\n diffs,\n explain,\n };\n const tokens = buildTokenStats(assembled, input.tokenBudget);\n return enforceContextBudget({ ...assembled, tokens });\n}\n\n// ── helpers ─────────────────────────────────────────────────────────\n\n/** Prior worklog handoffs. A broken worklog must never break context assembly. */\nasync function recallHandoffs(\n repositoryRoot: string,\n input: Parameters<WorklogStore[\"recall\"]>[0],\n): Promise<HandoffSummary[]> {\n try {\n return await new WorklogStore(repositoryRoot).recall(input);\n } catch {\n return [];\n }\n}\n\nfunction explainHandoffs(explain: string[], handoffs: HandoffSummary[]): void {\n if (handoffs.length === 0) return;\n const stale = handoffs.filter((h) => h.changedSince.length > 0 || h.missing.length > 0).length;\n explain.push(\n `handoffs: ${handoffs.length} prior worklog entr${handoffs.length === 1 ? \"y\" : \"ies\"}` +\n (stale > 0 ? ` (${stale} with files changed or missing since — verify before relying)` : \"\"),\n );\n}\n\nfunction summarizePlan(plan: PlanSpec | null): PlanSummary {\n if (!plan) return null;\n return {\n id: plan.id,\n title: plan.title,\n status: plan.status,\n brief: plan.brief,\n filesToTouch: plan.filesToTouch.map((file) => file.path),\n risks: plan.risks,\n };\n}\n\n/**\n * Prefer an explicitly referenced plan; fall back to the namespace's active\n * plan so before-edit context stays useful even when the caller passes only\n * paths.\n */\nasync function resolveRelevantPlan(\n store: PlanFileStore,\n namespace: string,\n planId?: string,\n): Promise<PlanSpec | null> {\n if (planId) {\n try {\n return await store.readPlan(planId);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n }\n return new PlanLifecycle(store).current(namespace);\n}\n\nfunction sortIncidents(incidents: IncidentFactFile[]): IncidentFactFile[] {\n const severity = { critical: 4, high: 3, medium: 2, low: 1 };\n return [...incidents].sort(\n (a, b) =>\n Number(a.resolvedBy !== null) - Number(b.resolvedBy !== null) ||\n severity[b.severity] - severity[a.severity],\n );\n}\n\nfunction summarizeIncident(fact: IncidentFactFile): IncidentSummary {\n return {\n id: fact.id,\n severity: fact.severity,\n subject: fact.subject,\n summary: truncate(fact.content || fact.object || fact.subject, LIMITS.incidentSummaryChars),\n paths: fact.paths,\n resolved: fact.resolvedBy !== null,\n createdAt: fact.createdAt,\n };\n}\n\nfunction summarizePolicyRules(rules: PolicyRule[]): PolicyRuleSummary[] {\n return [...rules]\n .sort((left, right) => right.weight - left.weight)\n .slice(0, LIMITS.policyRules)\n .map((rule) => ({\n id: rule.id,\n pattern: rule.pattern,\n message: rule.message ?? rule.reason ?? `Policy rule ${rule.id}.`,\n weight: rule.weight,\n }));\n}\n\nfunction summarizeMatchingPolicyRules(rules: PolicyRule[], paths: string[]): PolicyRuleSummary[] {\n const matching = rules.filter((rule) =>\n paths.some((path) => matchesPolicyGlob(path, rule.pattern)),\n );\n return summarizePolicyRules(matching);\n}\n\nfunction summarizeArchitecture(map: ArchitectureMap): ArchitectureSummary {\n const inbound = new Map<string, number>();\n const outbound = new Map<string, number>();\n for (const edge of map.edges) {\n outbound.set(edge.from, (outbound.get(edge.from) ?? 0) + 1);\n inbound.set(edge.to, (inbound.get(edge.to) ?? 0) + 1);\n }\n\n const hotspots = map.modules\n .map((module) => ({\n path: module.path,\n inbound: inbound.get(module.path) ?? 0,\n outbound: outbound.get(module.path) ?? 0,\n }))\n .filter((entry) => entry.inbound + entry.outbound > 0)\n .sort((left, right) => {\n const degree = right.inbound + right.outbound - (left.inbound + left.outbound);\n if (degree !== 0) return degree;\n return left.path.localeCompare(right.path);\n })\n .slice(0, LIMITS.hotspots);\n\n return { moduleCount: map.modules.length, edgeCount: map.edges.length, hotspots };\n}\n\nfunction computeNeighbours(map: ArchitectureMap, paths: string[]): ModuleNeighbours[] {\n const result: ModuleNeighbours[] = [];\n for (const path of paths.slice(0, LIMITS.neighbourPaths)) {\n // Dedupe BEFORE slicing: duplicate edges from a many-to-many import would\n // otherwise crowd unique neighbours out of the bounded payload.\n const dependsOn = [\n ...new Set(map.edges.filter((edge) => edge.from === path).map((edge) => edge.to)),\n ].slice(0, LIMITS.neighbourEdges);\n const dependedOnBy = [\n ...new Set(map.edges.filter((edge) => edge.to === path).map((edge) => edge.from)),\n ].slice(0, LIMITS.neighbourEdges);\n if (dependsOn.length === 0 && dependedOnBy.length === 0) continue;\n const usesSymbols: Record<string, string[]> = {};\n for (const dependency of dependsOn) {\n const symbols = map.edges.find(\n (edge) => edge.from === path && edge.to === dependency,\n )?.symbols;\n if (symbols?.length) usesSymbols[dependency] = symbols;\n }\n result.push({\n path,\n dependsOn,\n dependedOnBy,\n ...(Object.keys(usesSymbols).length > 0 ? { usesSymbols } : {}),\n });\n }\n return result;\n}\n\n/**\n * Read the target files' public API as compact signatures (Roadmap N.3), so the\n * agent can see what each file offers without the tool sending its full source.\n * The whole bounded symbol table is ranked by the task *before* it is limited,\n * so a relevant thirteenth declaration still wins (issue #35); declarations\n * overlapping a semantic hit are preferred. The best match comes back as a span\n * read from current source, with a short excerpt drawn from one global budget.\n * Bounded and best-effort: unreadable files are skipped.\n */\nasync function computeTargetSymbols(\n repositoryRoot: string,\n targetPaths: string[],\n task: string,\n hits: RetrievalHit[],\n /** Symbols the BYOK rerank named per file; they outrank term matches. */\n picked: Record<string, string[]> = {},\n evidence: \"overview\" | \"source\" = \"overview\",\n): Promise<FileSymbols[]> {\n const terms = taskTerms(task);\n const tokens = identifierTokens(task);\n const result: FileSymbols[] = [];\n let excerptBudget: number = evidence === \"source\" ? 5400 : LIMITS.excerptChars;\n let spanned = 0;\n for (const path of targetPaths.slice(0, LIMITS.symbolFiles)) {\n const source = await readBoundedSource(repositoryRoot, path);\n if (source === null) continue;\n const lines = source.split(/\\r?\\n/);\n // zg's index may be stale: only trust hit ranges that still fit the file.\n const fileHits = hits.filter((hit) => hit.path === path && hit.endLine <= lines.length);\n const table = supportsSymbols(path) ? extractSymbolTable(source) : [];\n // Each semantic hit credits only the narrowest declaration containing it,\n // so a method beats its enclosing class.\n const credited = new Map<SymbolSpan, RetrievalHit>();\n for (const hit of fileHits) {\n const owner = table\n .filter((symbol) => hit.startLine <= symbol.endLine && hit.endLine >= symbol.startLine)\n .sort(\n (left, right) => left.endLine - left.startLine - (right.endLine - right.startLine),\n )[0];\n if (owner && !credited.has(owner)) credited.set(owner, hit);\n }\n const ranked = table\n .map((symbol) => {\n const hit = credited.get(symbol);\n // A class body repeats its methods' words; let the narrower method win.\n const body =\n symbol.kind === \"class\"\n ? \"\"\n : lines.slice(symbol.startLine - 1, symbol.endLine).join(\" \");\n const score =\n (picked[path]?.includes(symbol.name) ? 1_000 : 0) +\n 100 * namedSegments(symbol.name, tokens) +\n (hit ? 10 : 0) +\n 3 * countTerms(lines[symbol.startLine - 1] ?? \"\", terms) +\n countTerms(body, terms);\n return { symbol, hit, score };\n })\n .sort(\n (left, right) => right.score - left.score || left.symbol.startLine - right.symbol.startLine,\n );\n // Methods only earn a signature line when the task points at them.\n const signatures = ranked\n .filter(({ symbol, score }) => symbol.kind !== \"method\" || score > 0)\n .slice(0, LIMITS.symbolsPerFile)\n .map(({ symbol }) => symbol.signature);\n // One grounded span per file: the best task match, else the top semantic\n // hit (unsupported languages, or no declaration matched). Only the first\n // few files get one, so the extra tokens stay bounded.\n const best = ranked[0]?.score ? ranked[0] : undefined;\n const hit = best ? best.hit : fileHits[0];\n const range = best?.symbol ?? hit;\n const spans: ContextSpan[] = [];\n if (range && spanned < LIMITS.spanFiles) {\n const span: ContextSpan = {\n ...(best ? { name: best.symbol.name } : {}),\n startLine: range.startLine,\n endLine: range.endLine,\n ...(hit\n ? { source: hit.source, rank: hit.rank, freshness: \"current-source\" }\n : { source: \"lexical\", freshness: \"current-source\" }),\n };\n if (excerptBudget > 0) {\n const headShown = best !== undefined && headInSignature(lines, best.symbol);\n span.excerpt = sourceExcerpt(\n lines,\n span,\n terms,\n hit?.startLine,\n hit?.endLine,\n excerptBudget,\n headShown,\n evidence,\n );\n excerptBudget -= span.excerpt.text.length;\n }\n spans.push(span);\n spanned++;\n }\n if (signatures.length > 0 || spans.length > 0) {\n result.push({ path, signatures, ...(spans.length > 0 ? { spans } : {}) });\n }\n }\n return result;\n}\n\n/**\n * A few lines of current source around the best task-term line (or the semantic\n * hit), so behavior and comments a signature can't show are still grounded.\n */\nfunction sourceExcerpt(\n lines: string[],\n span: ContextSpan,\n terms: string[],\n anchorLine: number | undefined,\n anchorEndLine: number | undefined,\n budget: number,\n headShown = false,\n evidence: \"overview\" | \"source\" = \"overview\",\n): NonNullable<ContextSpan[\"excerpt\"]> {\n let anchor = Math.max(span.startLine, anchorLine ?? span.startLine);\n let best = 0;\n if (anchorLine === undefined) {\n for (let line = span.startLine; line <= span.endLine; line++) {\n const score = countTerms(lines[line - 1] ?? \"\", terms);\n if (score > best) {\n best = score;\n anchor = line;\n }\n }\n }\n const detailed = evidence === \"source\";\n const windowStart =\n detailed && span.endLine - span.startLine < 40\n ? span.startLine\n : Math.max(span.startLine, anchor - 1);\n const endLine = Math.min(\n span.endLine,\n windowStart + (detailed ? 40 : LIMITS.excerptLines) - 1,\n detailed || anchorEndLine === undefined ? span.endLine : anchorEndLine + 1,\n );\n // The declaration line is already a listed signature; don't send it twice.\n const startLine =\n headShown && windowStart === span.startLine && endLine > windowStart\n ? windowStart + 1\n : windowStart;\n const raw = lines.slice(startLine - 1, endLine).join(\"\\n\");\n const text = raw.slice(0, Math.min(budget, detailed ? 1800 : LIMITS.excerptCharsPerSpan));\n return {\n startLine,\n endLine: startLine + text.split(\"\\n\").length - 1,\n text,\n truncated: windowStart > span.startLine || endLine < span.endLine || text.length < raw.length,\n };\n}\n\n/** True when the declaration line adds nothing beyond its (untruncated) signature. */\nfunction headInSignature(lines: string[], symbol: SymbolSpan): boolean {\n const head =\n symbol.kind === \"method\"\n ? symbol.signature.slice(symbol.signature.indexOf(\": \") + 2)\n : symbol.signature;\n const line = (lines[symbol.startLine - 1] ?? \"\").trim();\n return (\n !head.endsWith(\"…\") && line.startsWith(head) && /^[\\s{=>(]*$/.test(line.slice(head.length))\n );\n}\n\n/**\n * Read the current staged and unstaged hunks for target paths. The result is\n * bounded per file so a large change cannot crowd out plan and risk context.\n */\nasync function readGitDiffs(repositoryRoot: string, paths: string[]): Promise<DiffHunk[]> {\n if (paths.length === 0) return [];\n const sections: string[] = [];\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"diff\", \"HEAD\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n { cwd: repositoryRoot, maxBuffer: 2_000_000 },\n );\n sections.push(stdout);\n } catch {\n // Repositories without a first commit cannot use `git diff HEAD`. Their\n // staged and unstaged tracked changes are still useful independently.\n for (const args of [\n [\"diff\", \"--cached\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n [\"diff\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n ]) {\n try {\n const { stdout } = await execFileAsync(\"git\", args, {\n cwd: repositoryRoot,\n maxBuffer: 2_000_000,\n });\n sections.push(stdout);\n } catch {\n // Fall through to untracked-file handling.\n }\n }\n }\n\n const parsed = parseGitDiff(sections.join(\"\\n\"));\n const known = new Set(parsed.map((diff) => diff.path));\n const untracked = await listUntrackedPaths(repositoryRoot, paths);\n for (const path of untracked) {\n if (known.has(path)) continue;\n const patch = await buildUntrackedPatch(repositoryRoot, path);\n if (patch) parsed.push(patch);\n }\n return parsed.slice(0, MAX_DIFF_FILES);\n}\n\nfunction parseGitDiff(diff: string): DiffHunk[] {\n return diff\n .split(/(?=^diff --git )/m)\n .filter((section) => section.startsWith(\"diff --git \"))\n .flatMap((section) => {\n const header = section.match(/^diff --git a\\/(.+?) b\\/(.+?)\\n/m);\n if (!header?.[2]) return [];\n const rawPatch = section.trim();\n const patch = rawPatch.slice(0, MAX_DIFF_CHARS_PER_FILE).trim();\n return patch\n ? [\n {\n path: header[2],\n patch,\n ...(patch.length < rawPatch.length ? { truncated: true } : {}),\n },\n ]\n : [];\n });\n}\n\nasync function listUntrackedPaths(repositoryRoot: string, paths: string[]): Promise<string[]> {\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"ls-files\", \"--others\", \"--exclude-standard\", \"--\", ...paths],\n { cwd: repositoryRoot, maxBuffer: 1_000_000 },\n );\n return stdout\n .split(/\\r?\\n/)\n .map((path) => path.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\nasync function buildUntrackedPatch(repositoryRoot: string, path: string): Promise<DiffHunk | null> {\n try {\n const content = await readFile(join(repositoryRoot, path), \"utf8\");\n if (content.includes(\"\\0\")) return null;\n const lines = content.split(/\\r?\\n/);\n const body = lines.map((line) => `+${line}`).join(\"\\n\");\n const rawPatch = [\n `diff --git a/${path} b/${path}`,\n \"new file mode 100644\",\n \"--- /dev/null\",\n `+++ b/${path}`,\n `@@ -0,0 +1,${lines.length} @@`,\n body,\n ].join(\"\\n\");\n const patch = rawPatch.slice(0, MAX_DIFF_CHARS_PER_FILE).trim();\n return {\n path,\n patch,\n ...(patch.length < rawPatch.length ? { truncated: true } : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** Facts delivered as standing guidance, not ranked against the task. */\nconst STANDING_PREDICATES = new Set([\"rule\", \"procedure\"]);\nconst STANDING_LIMITS = { rule: 5, procedure: 3, chars: 200 } as const;\n\n/** Live user rules (newest 5) then procedures (newest 3), regardless of task overlap. */\nfunction selectRules(facts: FactFile[], namespace: string): RelevantFactSummary[] {\n const newest = (predicate: \"rule\" | \"procedure\") =>\n facts\n .filter((fact) => fact.predicate === predicate && isEligibleMemory(fact, { namespace }))\n .sort((left, right) => right.createdAt.localeCompare(left.createdAt))\n .slice(0, STANDING_LIMITS[predicate]);\n return [...newest(\"rule\"), ...newest(\"procedure\")].map((fact) => ({\n id: fact.id,\n subject: fact.predicate,\n summary: truncate(fact.object, STANDING_LIMITS.chars),\n paths: fact.paths,\n confidence: fact.confidence,\n relevance: 0,\n reason:\n fact.predicate === \"rule\" ? \"standing user rule\" : \"verification that passed repeatedly\",\n createdAt: fact.createdAt,\n createdByAgent: fact.createdByAgent,\n }));\n}\n\nasync function rankRelevantFacts(\n facts: FactFile[],\n namespace: string,\n task: string,\n targetPaths: string[],\n semanticRanker?: SemanticRelevanceRanker,\n): Promise<RelevantFactSummary[]> {\n // Eligibility runs before ranking and duplicate suppression, so only\n // same-namespace, live incidents can suppress a fact with identical text.\n const eligible = facts.filter((fact) => isEligibleMemory(fact, { namespace }));\n const incidentText = new Set(\n eligible\n .filter((fact) => fact.category === \"incident\")\n .map((fact) => normalizeText(fact.content || fact.object)),\n );\n const candidates = eligible\n .filter((fact) => fact.category !== \"incident\")\n .map((fact) => {\n const text = `${fact.subject} ${fact.predicate} ${fact.object} ${fact.content}`;\n const taskScore = relevanceScore(text, task);\n // A path match is strong supporting evidence, but must not overwhelm a\n // clearly different task (for example database work near an auth file).\n const pathScore = fact.paths.some((path) => targetPaths.includes(path)) ? 5 : 0;\n const relevance = taskScore + pathScore + Math.round(fact.confidence * 5);\n return {\n fact,\n relevance,\n reason:\n pathScore > 0\n ? \"matches a target path\"\n : taskScore > 0\n ? `shares ${taskScore} task relevance point(s)`\n : \"recent project fact\",\n };\n });\n let semanticScores: Record<string, number> = {};\n if (semanticRanker && task.trim()) {\n try {\n semanticScores = await semanticRanker(\n task,\n candidates.map(({ fact }) => ({\n id: fact.id,\n text: `${fact.subject} ${fact.predicate} ${fact.object} ${fact.content}`,\n })),\n );\n } catch {\n semanticScores = {};\n }\n }\n return candidates\n .map((candidate) => {\n const raw = semanticScores[candidate.fact.id] ?? 0;\n const semantic = Number.isFinite(raw) ? Math.max(0, Math.min(10, raw)) : 0;\n return {\n ...candidate,\n relevance: candidate.relevance + semantic,\n reason: semantic > 0 ? `${candidate.reason}; semantic relevance` : candidate.reason,\n };\n })\n .filter(({ fact, relevance }) => {\n if (incidentText.has(normalizeText(fact.content || fact.object))) return false;\n return task.trim() === \"\" || relevance > Math.round(fact.confidence * 5);\n })\n .sort((left, right) => {\n if (right.relevance !== left.relevance) return right.relevance - left.relevance;\n return right.fact.createdAt.localeCompare(left.fact.createdAt);\n })\n .slice(0, LIMITS.relevantFacts)\n .map(({ fact, relevance, reason }) => ({\n id: fact.id,\n subject: fact.subject,\n summary: truncate(fact.content || fact.object, LIMITS.incidentSummaryChars),\n paths: fact.paths,\n confidence: fact.confidence,\n relevance,\n reason,\n createdAt: fact.createdAt,\n createdByAgent: fact.createdByAgent,\n }));\n}\n\nfunction relevanceScore(value: string, task: string): number {\n const terms = new Set(\n normalizeText(task)\n .split(\" \")\n .filter((term) => term.length > 2),\n );\n if (terms.size === 0) return 0;\n const haystack = new Set(normalizeText(value).split(\" \"));\n let score = 0;\n for (const term of terms) if (haystack.has(term)) score += 3;\n return score;\n}\n\nfunction normalizeText(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9_./-]+/g, \" \")\n .trim();\n}\n\nfunction classifyPathSource(\n input: BeforeEditInput,\n resolvedCount: number,\n discoveredFromTask: boolean,\n): PathSource {\n if (resolvedCount === 0) return \"none\";\n if (discoveredFromTask) return \"task\";\n if (input.paths && input.paths.length > 0) return \"paths\";\n if (input.planId) return \"plan\";\n return \"git\";\n}\n\n/** Estimate the payload's token footprint against its budget. */\nfunction buildTokenStats(payload: unknown, tokenBudget: number | undefined): TokenStats {\n return {\n budget: tokenBudget ?? DEFAULT_TOKEN_BUDGET,\n returnedEstimate: estimateTokens(payload ?? {}),\n status: \"within_budget\",\n countedSurface: \"compact_json\",\n essentialOmitted: 0,\n };\n}\n\nfunction truncate(value: string, max: number): string {\n const trimmed = value.trim();\n return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max - 1)}…`;\n}\n\nexport { rankTaskPaths, scoreTaskPaths } from \"./discovery.js\";\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { generateEntityId } from \"../core/ids.js\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"../core/markdown-store-fs.js\";\nimport { scanSensitive } from \"../memory-extract/sensitive.js\";\n\n/**\n * The worklog is a chronological record of completed turns — what was done,\n * which files, what memory it produced, how it was verified — so a fresh chat\n * can pick up prior work without the transcript. It is a timeline, not project\n * truth: durable facts stay in `.codebuddy/memory/` and the working tree stays\n * authoritative, so every recalled entry carries a freshness check against the\n * current files. Entries are bounded Markdown under `.codebuddy/worklog/`; raw\n * transcripts are never stored and sensitive summaries are redacted.\n */\n\nconst LIMITS = {\n summaryChars: 600,\n files: 50,\n verification: 10,\n verificationChars: 200,\n} as const;\n\nconst REDACTED = \"[REDACTED SENSITIVE CONTENT]\";\n\nconst entrySchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^wlg_[a-z0-9]+$/),\n namespace: z.string().min(1),\n createdAt: z.string(),\n sourceSessionId: z.string().nullable().default(null),\n sourcePlanId: z.string().nullable().default(null),\n commitSha: z.string().nullable().default(null),\n agentId: z.string().nullable().default(null),\n files: z.array(z.string()).default([]),\n verification: z.array(z.string()).default([]),\n savedMemory: z.array(z.string()).default([]),\n queuedForReview: z.array(z.string()).default([]),\n fingerprint: z.string().regex(/^[a-f0-9]{64}$/),\n});\n\nexport type WorklogEntry = z.infer<typeof entrySchema> & { summary: string; path: string };\n\nexport type WorklogRecordInput = {\n namespace: string;\n summary: string;\n files?: string[];\n verification?: string[];\n savedMemory?: string[];\n queuedForReview?: string[];\n sessionId?: string;\n planId?: string;\n commitSha?: string;\n agentId?: string;\n};\n\n/** A worklog entry as recalled into context, with freshness against the working tree. */\nexport type HandoffSummary = {\n id: string;\n createdAt: string;\n ageDays: number;\n summary: string;\n files: string[];\n verification: string[];\n savedMemory: string[];\n /** Recorded files modified after the entry was written. */\n changedSince: string[];\n /** Recorded files that no longer exist. */\n missing: string[];\n reason: string;\n};\n\nexport class WorklogStore {\n readonly repositoryRoot: string;\n readonly directory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.directory = join(this.repositoryRoot, \".codebuddy\", \"worklog\");\n }\n\n /**\n * Record one entry for a completed turn. A retry of the same turn (same\n * namespace, session, summary and files) returns the existing id instead of\n * writing a duplicate.\n */\n async record(input: WorklogRecordInput, now = new Date()): Promise<string> {\n const files = [...new Set((input.files ?? []).map(normalizePath))]\n .filter(Boolean)\n .sort()\n .slice(0, LIMITS.files);\n const summary = boundSummary(input.summary, files);\n const verification = (input.verification ?? [])\n .map((line) => line.trim().slice(0, LIMITS.verificationChars))\n .filter((line) => line && !scanSensitive(line).sensitive)\n .slice(0, LIMITS.verification);\n const fingerprint = createHash(\"sha256\")\n .update(\n JSON.stringify({\n namespace: input.namespace.trim().toLowerCase(),\n session: input.sessionId ?? null,\n summary: summary.replace(/\\s+/g, \" \").toLowerCase(),\n files,\n }),\n )\n .digest(\"hex\");\n\n const existing = (await this.list()).find((entry) => entry.fingerprint === fingerprint);\n if (existing) return existing.id;\n\n const id = generateEntityId(\"wlg\", now.getTime());\n const path = this.entryPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id,\n namespace: input.namespace,\n createdAt: now.toISOString(),\n sourceSessionId: input.sessionId ?? null,\n sourcePlanId: input.planId ?? null,\n commitSha: input.commitSha ?? null,\n agentId: input.agentId ?? null,\n files,\n verification,\n savedMemory: input.savedMemory ?? [],\n queuedForReview: input.queuedForReview ?? [],\n fingerprint,\n });\n await writeAtomic(path, composeMarkdown(frontMatter, summary));\n return id;\n }\n\n async read(id: string): Promise<WorklogEntry> {\n const path = this.entryPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n return {\n ...entrySchema.parse(parseYaml(parsed.frontMatter)),\n summary: parsed.content.trim(),\n path,\n };\n }\n\n /** All readable entries, newest first. Corrupt or foreign files are skipped. */\n // ponytail: full directory scan per call; add an index file if worklogs reach thousands of entries.\n async list(namespace?: string): Promise<WorklogEntry[]> {\n let names: string[];\n try {\n await assertNoSymlinkBetween(this.repositoryRoot, this.directory);\n names = await readdir(this.directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n const entries: WorklogEntry[] = [];\n for (const name of names) {\n if (!/^wlg_[a-z0-9]+\\.md$/.test(name)) continue;\n try {\n const entry = await this.read(name.replace(/\\.md$/, \"\"));\n if (namespace === undefined || entry.namespace === namespace) entries.push(entry);\n } catch {\n // Leave corrupt entries on disk for inspection; never fail recall on one.\n }\n }\n return entries.sort(\n (left, right) =>\n right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id),\n );\n }\n\n /**\n * Prior handoffs for a new turn. With target paths or a task, only entries\n * that overlap them are returned (ranked by overlap, then recency); without\n * either, the most recent entries are returned.\n */\n async recall(input: {\n namespace: string;\n paths?: string[];\n task?: string;\n limit?: number;\n now?: Date;\n }): Promise<HandoffSummary[]> {\n const now = input.now ?? new Date();\n const limit = input.limit ?? 3;\n const entries = await this.list(input.namespace);\n const paths = new Set((input.paths ?? []).map(normalizePath));\n const taskWords = words(input.task ?? \"\");\n const targeted = paths.size > 0 || taskWords.size > 0;\n\n const ranked = entries\n .map((entry, recency) => {\n const fileHits = entry.files.filter((file) => paths.has(file));\n const summaryWords = words(entry.summary);\n const wordHits = [...taskWords].filter((word) => summaryWords.has(word));\n const score = fileHits.length * 3 + Math.min(wordHits.length, 5);\n const reason = !targeted\n ? \"recent work\"\n : [\n fileHits.length > 0 ? `touched ${fileHits.slice(0, 3).join(\", \")}` : \"\",\n wordHits.length > 0 ? `task terms: ${wordHits.slice(0, 5).join(\", \")}` : \"\",\n ]\n .filter(Boolean)\n .join(\"; \");\n return { entry, score, recency, reason };\n })\n .filter((item) => !targeted || item.score > 0)\n .sort((left, right) => right.score - left.score || left.recency - right.recency)\n .slice(0, limit);\n\n return Promise.all(\n ranked.map(async ({ entry, reason }) => {\n const freshness = await this.freshness(entry);\n return {\n id: entry.id,\n createdAt: entry.createdAt,\n ageDays: Math.max(\n 0,\n Math.floor((now.getTime() - Date.parse(entry.createdAt)) / 86_400_000),\n ),\n summary: entry.summary.slice(0, 240),\n files: entry.files.slice(0, 8),\n verification: entry.verification.slice(0, 3),\n savedMemory: entry.savedMemory,\n ...freshness,\n reason,\n };\n }),\n );\n }\n\n private async freshness(\n entry: WorklogEntry,\n ): Promise<{ changedSince: string[]; missing: string[] }> {\n const createdAt = Date.parse(entry.createdAt);\n const changedSince: string[] = [];\n const missing: string[] = [];\n for (const file of entry.files) {\n const absolute = resolve(this.repositoryRoot, file);\n const rel = relative(this.repositoryRoot, absolute);\n if (rel.startsWith(`..${sep}`) || rel === \"..\") continue;\n try {\n if ((await stat(absolute)).mtimeMs > createdAt) changedSince.push(file);\n } catch {\n missing.push(file);\n }\n }\n return { changedSince, missing };\n }\n\n private entryPath(id: string): string {\n if (!/^wlg_[a-z0-9]+$/.test(id)) throw new Error(`Invalid worklog id: ${id}`);\n return join(this.directory, `${id}.md`);\n }\n}\n\n/**\n * Keep the human summary, drop the hook's trailing \"Changed files:\" line (files\n * are recorded separately), cap the length, and redact anything sensitive.\n */\nfunction boundSummary(summary: string, files: string[]): string {\n const text = summary\n .replace(/\\n*Changed files: [^\\n]*\\.?\\s*$/, \"\")\n .trim()\n .slice(0, LIMITS.summaryChars);\n if (!text) return files.length > 0 ? `Changed ${files.slice(0, 5).join(\", \")}.` : \"(no summary)\";\n return redactSentences(text);\n}\n\n/**\n * Redact only the sentences (or lines) that scan sensitive, so one pasted key\n * does not erase the whole handoff. If the result still scans sensitive (a\n * credential split across a sentence boundary), redact the whole summary.\n */\nfunction redactSentences(text: string): string {\n if (!scanSensitive(text).sensitive) return text;\n const redacted = text\n .split(/(?<=[.!?])\\s+|\\n+/)\n .map((sentence) => (scanSensitive(sentence).sensitive ? REDACTED : sentence))\n .join(\" \");\n return scanSensitive(redacted).sensitive ? REDACTED : redacted;\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").trim();\n}\n\nfunction words(text: string): Set<string> {\n return new Set(text.toLowerCase().match(/[a-z0-9_]{4,}/g) ?? []);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { buildBeforeEditContext, buildBootstrapContext } from \"../context/engine.js\";\nimport { type ContextCapsule, SessionCapsuleLedger } from \"../context/session-ledger.js\";\nimport type { BeforeEditContext, BootstrapContext } from \"../context/types.js\";\nimport { readConfigFile } from \"../core/config-file.js\";\nimport { captureAfterTurn } from \"../memory-extract/engine.js\";\nimport { extractUserRules } from \"../memory-extract/rules.js\";\nimport type { AfterTurnResult } from \"../memory-extract/types.js\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { HookStagingStore } from \"./staging.js\";\n\n/**\n * The runtime side of `codebuddy hooks`. Each function is the deterministic\n * action a Claude Code hook triggers, independent of whether the model chose to\n * call anything:\n * - context: recall — compact project context, injected at prompt submit.\n * - stage: record the files an edit tool just changed.\n * - capture: at turn end, capture durable memory from the real change set.\n *\n * All are best-effort: a hook must never break the user's turn, so callers wrap\n * these and always exit 0.\n */\n\n/** The subset of a Claude Code hook payload CodeBuddy reads. */\nexport type HookInput = {\n session_id?: string;\n transcript_path?: string;\n cwd?: string;\n hook_event_name?: string;\n prompt?: string;\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n /** SessionStart only: startup | resume | clear | compact. */\n source?: string;\n /** Turn end, for hosts without a transcript file (OpenCode): the last assistant text. */\n last_assistant_message?: string;\n /** Turn end, for hosts without a transcript file: shell commands run this turn. */\n shell_commands?: Array<{ command: string; exit_code: number | null }>;\n /**\n * The host injects the block into this turn only and never keeps it in the\n * conversation (Hermes pre_llm_call), so nothing may be skipped as already sent.\n */\n ephemeral_context?: boolean;\n};\n\nconst CONTEXT_BLOCK_MAX_CHARS = 1800;\n\n/**\n * A block built later than this is dropped instead of emitted. Every bridge\n * kills the hook later (OpenCode and Hermes after 20s from spawn, Claude Code\n * after 60s), so a block is marked delivered only when it was written with\n * seconds to spare, never just before a host timeout throws the output away.\n */\nexport const CONTEXT_HOOK_BUDGET_MS = 15_000;\n\nasync function resolveNamespace(repositoryRoot: string): Promise<string> {\n if (process.env.CODEBUDDY_NAMESPACE) return process.env.CODEBUDDY_NAMESPACE;\n const file = await readConfigFile(repositoryRoot);\n return file.namespace ?? basename(repositoryRoot);\n}\n\n/**\n * UserPromptSubmit → a compact, injectable context block (recall).\n *\n * `emit` writes the block to the client. Capsules are recorded as delivered\n * only after it resolves, so a failed write leaves the session ledger untouched.\n */\nexport async function runContextHook(\n input: HookInput,\n emit?: (block: string) => Promise<void>,\n budgetMs = CONTEXT_HOOK_BUDGET_MS,\n): Promise<string> {\n const started = Date.now();\n const repositoryRoot = resolve(input.cwd ?? process.cwd());\n const namespace = await resolveNamespace(repositoryRoot);\n\n const bootstrap = await buildBootstrapContext({ repositoryRoot, namespace });\n let beforeEdit: BeforeEditContext | null = null;\n try {\n beforeEdit = await buildBeforeEditContext({\n repositoryRoot,\n namespace,\n useGit: true,\n ...(input.prompt ? { task: input.prompt } : {}),\n });\n } catch {\n beforeEdit = null;\n }\n const ledger = new SessionCapsuleLedger(repositoryRoot);\n const sessionId = input.session_id ?? \"default\";\n // Earlier blocks are gone from the model's view. No host event says when\n // MCP results are compacted away either, so the whole session starts over.\n if (input.ephemeral_context) await ledger.reset(sessionId);\n const { text, emitted } = await renderContextBlock(\n bootstrap,\n beforeEdit,\n ledger,\n sessionId,\n input.session_id !== undefined,\n );\n // Too late: the host may already have given up on this hook. Nothing is\n // marked, so the next prompt delivers the block.\n if (Date.now() - started >= budgetMs) return \"\";\n if (text.trim()) await emit?.(text);\n await ledger.markSent(sessionId, emitted);\n return text;\n}\n\n/** PostToolUse(edit) → stage the changed paths for capture. */\nexport async function runStageHook(input: HookInput): Promise<string[]> {\n const repositoryRoot = resolve(input.cwd ?? process.cwd());\n const paths = extractEditedPaths(input.tool_input)\n .map((path) => toRepoRelative(repositoryRoot, path))\n .filter((path): path is string => path !== null);\n await new HookStagingStore(repositoryRoot).add(input.session_id ?? \"default\", paths);\n return paths;\n}\n\nexport type CaptureHookResult = {\n changedFiles: string[];\n result: AfterTurnResult | null;\n};\n\n/** BYOK memory extraction options (empty when the layer or its memory feature is off). */\nexport async function llmMemoryOptions(\n repositoryRoot: string,\n): Promise<Awaited<ReturnType<typeof import(\"../llm/memory.js\").llmCaptureOptions>>> {\n try {\n return await (await import(\"../llm/memory.js\")).llmCaptureOptions(repositoryRoot);\n } catch {\n return {};\n }\n}\n\n/** A turn with no edits still leaves a handoff when the assistant reported at least this much. */\nconst INVESTIGATION_MIN_CHARS = 200;\n/** A handoff must point at code: a file path with an extension, or a backticked identifier. */\nconst NAMES_CODE =\n /[\\w.-]+\\/[\\w./-]*\\.\\w{1,5}\\b|\\b[\\w-]+\\.(?:ts|tsx|js|jsx|mjs|py|go|rs|java|rb|php|cs|c|cpp|h|swift|kt)\\b|`[^`\\s]+`/;\n\n/**\n * Stop → capture durable memory from the staged change set + transcript. A\n * turn without edits is still captured when the user stated or withdrew a\n * rule, or when the assistant reported findings (an investigation handoff).\n */\nexport async function runCaptureHook(input: HookInput): Promise<CaptureHookResult> {\n const repositoryRoot = resolve(input.cwd ?? process.cwd());\n const staging = new HookStagingStore(repositoryRoot);\n const sessionId = input.session_id ?? \"default\";\n // null: another capture holds this session's lock and handles the turn.\n const claimed = await staging.claim(sessionId);\n if (claimed === null) return { changedFiles: [], result: null };\n const changedFiles = claimed;\n try {\n const prompts = input.transcript_path ? await turnUserPrompts(input.transcript_path) : [];\n const { rules, revocations } = extractUserRules(prompts);\n let investigation = false;\n if (changedFiles.length === 0) {\n const assistant = input.transcript_path\n ? await lastAssistantMessage(input.transcript_path)\n : (input.last_assistant_message?.trim() ?? \"\");\n investigation = assistant.length >= INVESTIGATION_MIN_CHARS && NAMES_CODE.test(assistant);\n if (!investigation && rules.length === 0 && revocations.length === 0) {\n await staging.acknowledge(sessionId);\n return { changedFiles, result: null };\n }\n }\n const namespace = await resolveNamespace(repositoryRoot);\n const summary = await deriveSummary(\n input.transcript_path,\n changedFiles,\n input.last_assistant_message,\n );\n const verification = input.transcript_path\n ? await turnVerification(input.transcript_path)\n : verificationLines(\n (input.shell_commands ?? []).map(({ command, exit_code }) => ({\n command,\n ok: typeof exit_code === \"number\" ? exit_code === 0 : undefined,\n })),\n );\n const result = await captureAfterTurn(\n {\n summary,\n changedFiles,\n namespace,\n sessionId,\n ...(verification.length > 0 ? { verification } : {}),\n ...(rules.length > 0 ? { userRules: rules } : {}),\n ...(revocations.length > 0 ? { revokedRules: revocations } : {}),\n ...(investigation ? { investigation } : {}),\n // Without edits, only the user's own rules and a handoff are kept: an\n // explanation is not evidence of a decision or an incident.\n ...(changedFiles.length === 0 ? { extract: false } : {}),\n },\n {\n repositoryRoot,\n ...(changedFiles.length > 0 ? await llmMemoryOptions(repositoryRoot) : {}),\n },\n );\n await staging.acknowledge(sessionId);\n return { changedFiles, result };\n } catch (error) {\n await staging.rollback(sessionId);\n throw error;\n }\n}\n\n/** SessionStart(compact|clear) → resend all context on the next prompt. */\nexport async function runResetHook(input: HookInput): Promise<void> {\n const repositoryRoot = resolve(input.cwd ?? process.cwd());\n await new SessionCapsuleLedger(repositoryRoot).reset(input.session_id ?? \"default\");\n}\n\n// ── helpers ─────────────────────────────────────────────────────────\n\n/**\n * Pull edited paths out of a tool input: Claude Edit/Write (`file_path`),\n * MultiEdit (`edits[]`), OpenCode edit/write (`filePath`) and apply_patch/patch\n * (`patchText` file headers, including move targets), Hermes write_file and\n * patch replace mode (`path`) and patch mode (V4A headers in `patch`).\n */\nexport function extractEditedPaths(toolInput: Record<string, unknown> | undefined): string[] {\n if (!toolInput) return [];\n const paths: string[] = [];\n const push = (value: unknown) => {\n if (typeof value === \"string\" && value.trim()) paths.push(value);\n };\n push(toolInput.file_path);\n push(toolInput.filePath);\n push(toolInput.path);\n for (const patch of [toolInput.patchText, toolInput.patch]) {\n if (typeof patch !== \"string\") continue;\n for (const match of patch.matchAll(\n /^\\*\\*\\*\\s+(?:(?:Add|Update|Delete)\\s+File|Move\\s+to):\\s*(.+)$/gm,\n )) {\n push(match[1]?.trim());\n }\n }\n if (Array.isArray(toolInput.edits)) {\n for (const edit of toolInput.edits) {\n if (edit && typeof edit === \"object\") push((edit as Record<string, unknown>).file_path);\n }\n }\n return [...new Set(paths)];\n}\n\nfunction toRepoRelative(repositoryRoot: string, path: string): string | null {\n const absolute = isAbsolute(path) ? resolve(path) : resolve(repositoryRoot, path);\n const rel = relative(repositoryRoot, absolute);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return null;\n return rel.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\n/**\n * Build a capture summary from the turn transcript (the last assistant message)\n * plus the change set. If the transcript can't be read, fall back to a plain\n * file list — which the conservative extractor will simply not turn into durable\n * facts, exactly the safe outcome.\n */\nexport async function deriveSummary(\n transcriptPath: string | undefined,\n changedFiles: string[],\n /** Used when there is no transcript (OpenCode passes the last assistant text). */\n lastAssistantText?: string,\n): Promise<string> {\n const fileList = changedFiles.length > 0 ? `Changed files: ${changedFiles.join(\", \")}.` : \"\";\n const assistantText = transcriptPath\n ? await lastAssistantMessage(transcriptPath)\n : (lastAssistantText?.trim().slice(0, 2000) ?? \"\");\n return [assistantText, fileList].filter(Boolean).join(\"\\n\\n\");\n}\n\n/**\n * A shell segment counts as verification when a known runner invokes a\n * test/lint/typecheck/build step (`rm -rf build` does not count).\n */\nconst VERIFICATION_SEGMENT =\n /^\\s*(?:\\w+=\\S*\\s+)*(?:npm|pnpm|yarn|bun|npx|cargo|go|make|mvn|gradle|\\.\\/gradlew|tsc|vitest|jest|pytest|python3? -m pytest|ruff|mypy|eslint|biome)\\b.*\\b(?:test|tests|lint|typecheck|tsc|build|check|vet|clippy|vitest|jest|pytest|ruff|mypy|eslint|biome)\\b/;\n\nfunction isVerificationCommand(command: string): boolean {\n return command.split(/&&|\\|\\||;/).some((segment) => VERIFICATION_SEGMENT.test(segment));\n}\n\n/**\n * Verification evidence for the current turn: test/lint/typecheck/build shell\n * commands run since the user's last prompt, with pass/fail from the tool\n * result. Only commands and outcomes are kept, never their output.\n */\nexport async function turnVerification(transcriptPath: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(transcriptPath, \"utf8\");\n } catch {\n return [];\n }\n let commands = new Map<string, string>();\n const outcomes = new Map<string, boolean>();\n for (const line of raw.split(\"\\n\")) {\n let entry: Record<string, unknown>;\n try {\n entry = JSON.parse(line) as Record<string, unknown>;\n } catch {\n continue;\n }\n const message = (entry.message ?? {}) as Record<string, unknown>;\n const content = message.content;\n if (message.role === \"user\") {\n // A real prompt (not just tool results) starts a new turn.\n const isPrompt =\n typeof content === \"string\" ||\n (Array.isArray(content) && content.some((block) => block?.type === \"text\"));\n if (isPrompt) {\n commands = new Map();\n outcomes.clear();\n }\n for (const block of Array.isArray(content) ? content : []) {\n if (block?.type === \"tool_result\" && typeof block.tool_use_id === \"string\") {\n outcomes.set(block.tool_use_id, block.is_error !== true);\n }\n }\n continue;\n }\n for (const block of Array.isArray(content) ? content : []) {\n const command = block?.input?.command;\n if (block?.type !== \"tool_use\" || block.name !== \"Bash\" || typeof command !== \"string\") {\n continue;\n }\n if (isVerificationCommand(command)) commands.set(block.id, command);\n }\n }\n return verificationLines(\n [...commands].map(([id, command]) => ({ command, ok: outcomes.get(id) })),\n );\n}\n\n/** Format verification runs (non-checks dropped); `ok` undefined = no result. */\nexport function verificationLines(\n runs: Array<{ command: string; ok: boolean | undefined }>,\n): string[] {\n const lines = runs\n .filter((run) => isVerificationCommand(run.command))\n .map(({ command, ok }) => {\n const label = ok === undefined ? \"no result\" : ok ? \"passed\" : \"failed\";\n return `${command.replace(/\\s+/g, \" \").trim().slice(0, 120)}: ${label}`;\n });\n // Keep the latest runs; a re-run after a fix is the one that matters.\n return lines.slice(-10);\n}\n\n/** Prompts longer than this are pasted material, not instructions to remember. */\nconst MAX_RULE_PROMPT_CHARS = 1500;\n/** Harness-inserted markup (reminders, slash-command echoes) inside user content. */\nconst TAGGED_BLOCK = /<([a-z][\\w-]*)[^>]*>[\\s\\S]*?<\\/\\1>/gi;\n\n/**\n * The user's own prompt text for the current turn (since the last assistant\n * reply): tool results, harness-inserted meta messages (skill bodies, command\n * output) and tagged blocks are excluded, so only what the user typed can\n * become a rule.\n */\nexport async function turnUserPrompts(transcriptPath: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(transcriptPath, \"utf8\");\n } catch {\n return [];\n }\n let prompts: string[] = [];\n let answered = false;\n for (const line of raw.split(\"\\n\")) {\n let entry: Record<string, unknown>;\n try {\n entry = JSON.parse(line) as Record<string, unknown>;\n } catch {\n continue;\n }\n const message = (entry.message ?? {}) as Record<string, unknown>;\n if (message.role === \"assistant\") {\n answered = true;\n continue;\n }\n if (message.role !== \"user\" || entry.isMeta === true) continue;\n const text = extractText(message.content).replace(TAGGED_BLOCK, \" \").trim();\n if (!text) continue;\n if (answered) {\n prompts = [];\n answered = false;\n }\n if (text.length <= MAX_RULE_PROMPT_CHARS) prompts.push(text);\n }\n return prompts;\n}\n\nexport async function lastAssistantMessage(transcriptPath: string): Promise<string> {\n try {\n const raw = await readFile(transcriptPath, \"utf8\");\n let latest = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const entry = JSON.parse(trimmed) as Record<string, unknown>;\n const message = (entry.message ?? entry) as Record<string, unknown>;\n const role = message.role ?? entry.type;\n if (role !== \"assistant\") continue;\n const text = extractText(message.content);\n if (text) latest = text;\n } catch {\n // Skip malformed lines; transcripts are best-effort input.\n }\n }\n return latest.slice(0, 2000);\n } catch {\n return \"\";\n }\n}\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((block) =>\n block && typeof block === \"object\" && (block as Record<string, unknown>).type === \"text\"\n ? String((block as Record<string, unknown>).text ?? \"\")\n : \"\",\n )\n .join(\" \")\n .trim();\n}\n\n/** Below this a risk score (0–100) is one routine signal, e.g. a few commits. */\nconst RISK_LINE_MIN_SCORE = 50;\n\n/** A rendered line; lower `priority` is packed first. */\ntype BlockItem = { priority: number; text: string; capsule?: ContextCapsule };\n\n/** Capsule text is bounded so one huge subject can never become undeliverable. */\nfunction bound(text: string, max = 300): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\n/**\n * Pack whole lines into the block by priority (current-task risk, relevant\n * facts, then broad bootstrap evidence) and return only the capsules whose\n * full text made it in. Lines are never cut; omitted capsules stay unseen.\n */\nexport async function renderContextBlock(\n bootstrap: BootstrapContext,\n beforeEdit: BeforeEditContext | null,\n ledger: SessionCapsuleLedger,\n sessionId: string,\n announceSession = false,\n): Promise<{ text: string; emitted: ContextCapsule[] }> {\n const capsules: Array<{ priority: number; capsule: ContextCapsule }> = [\n // Sent once per session (and again after a reset): MCP context calls that\n // pass it as `sessionId` share this ledger, so compaction resets both paths.\n ...(announceSession\n ? [\n {\n priority: 1,\n capsule: {\n key: \"session\",\n text: `session: ${sessionId} (pass as sessionId to CodeBuddy tools)`,\n },\n },\n ]\n : []),\n { priority: 4, capsule: { key: \"project\", text: `project: ${bootstrap.project.namespace}` } },\n {\n priority: 4,\n capsule: {\n key: \"plan\",\n text: `plan: ${bootstrap.plan ? `${bootstrap.plan.title} (${bootstrap.plan.status})` : \"none\"}`,\n },\n },\n { priority: 4, capsule: { key: \"plan-policy\", text: `plan policy: ${bootstrap.policy}` } },\n ];\n // Only rules that match this prompt's target files; the full rule list is\n // the same on every prompt and rarely relevant.\n const policyRules = beforeEdit?.policyRules ?? [];\n if (policyRules.length > 0) {\n capsules.push({\n priority: 4,\n capsule: {\n key: \"policies\",\n text: `policies: ${policyRules.map((r) => `${r.id}(${r.weight})`).join(\", \")}`,\n },\n });\n }\n for (const incident of bootstrap.incidents) {\n capsules.push({\n priority: 5,\n capsule: {\n key: `incident:${incident.id}`,\n text: `incident: ${bound(incident.subject)} [${incident.severity}]`,\n },\n });\n }\n for (const rule of bootstrap.rules ?? []) {\n const procedure = rule.subject === \"procedure\";\n capsules.push({\n priority: 2,\n capsule: {\n key: `${procedure ? \"procedure\" : \"rule\"}:${rule.id}`,\n text: bound(`${procedure ? \"verify\" : \"rule\"}: ${rule.summary}`),\n },\n });\n }\n for (const fact of bootstrap.facts) {\n capsules.push({\n priority: 6,\n capsule: { key: `fact:${fact.id}`, text: bound(`fact: ${fact.summary}`) },\n });\n }\n for (const handoff of bootstrap.handoffs) {\n const drift = [\n handoff.changedSince.length > 0 ? `${handoff.changedSince.length} file(s) changed since` : \"\",\n handoff.missing.length > 0 ? `${handoff.missing.length} missing` : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n capsules.push({\n priority: 7,\n capsule: {\n key: `handoff:${handoff.id}`,\n text: `prior work (${handoff.ageDays}d ago${drift ? `; ${drift}` : \"\"}): ${handoff.summary\n .replace(/\\s+/g, \" \")\n .slice(0, 160)}`,\n },\n });\n }\n if (beforeEdit?.testCommand) {\n capsules.push({\n priority: 3,\n capsule: { key: \"test-command\", text: `test command: ${beforeEdit.testCommand}` },\n });\n }\n capsules.push({\n priority: 8,\n capsule: {\n key: \"architecture\",\n text: `architecture: ${bootstrap.architecture.moduleCount} modules, ${bootstrap.architecture.edgeCount} edges`,\n },\n });\n\n const seen = await ledger.seen(\n sessionId,\n capsules.map((entry) => entry.capsule),\n );\n const items: BlockItem[] = [\n { priority: 0, text: \"## CodeBuddy project context (auto-recalled)\" },\n ];\n const unchanged: ContextCapsule[] = [];\n for (const { priority, capsule } of capsules) {\n if (seen.has(capsule.key)) unchanged.push(capsule);\n else items.push({ priority, text: capsule.text, capsule });\n }\n if (unchanged.length > 0) {\n const avoided = unchanged.reduce((sum, capsule) => sum + estimateTokens(capsule.text), 0);\n items.push({\n priority: 10,\n text: `unchanged since earlier in this session (not resent, ~${avoided} tokens): ${describeKeys(unchanged.map((c) => c.key))}`,\n });\n }\n\n if (beforeEdit && beforeEdit.targetPaths.length > 0) {\n // Only git-derived targets are edits in progress; task/plan/explicit paths are not.\n const targetLabel = beforeEdit.pathSource === \"git\" ? \"current changes\" : \"task files\";\n const tests = (beforeEdit.tests ?? []).map((entry) => entry.test);\n items.push({\n priority: 3,\n text: bound(\n `${targetLabel}: ${beforeEdit.targetPaths.slice(0, 8).join(\", \")}` +\n (tests.length > 0 ? `; tests: ${tests.join(\", \")}` : \"\"),\n 500,\n ),\n });\n // Facts already listed as bootstrap capsules (sent now or earlier this session) are not repeated.\n const bootstrapFactIds = new Set(bootstrap.facts.map((fact) => fact.id));\n const relevantFacts = beforeEdit.facts.filter((fact) => !bootstrapFactIds.has(fact.id));\n if (relevantFacts.length > 0) {\n items.push({\n priority: 2,\n text: bound(\n `relevant facts: ${relevantFacts\n .slice(0, 3)\n .map((fact) => fact.summary)\n .join(\"; \")}`,\n 500,\n ),\n });\n }\n // Risk for the listed files only (task discovery also assesses unrelated\n // git changes), and only when the score means something.\n const targets = new Set(beforeEdit.targetPaths);\n const risks = beforeEdit.risks.items.filter(\n (item) => targets.has(item.path) && item.score >= RISK_LINE_MIN_SCORE,\n );\n if (risks.length > 0) {\n items.push({\n priority: 1,\n text: bound(\n `risk: ${risks\n .slice(0, 3)\n .map((item) => `${item.path}=${item.score}`)\n .join(\", \")}`,\n 500,\n ),\n });\n }\n }\n\n // Greedy by priority; a line that does not fit is skipped whole, a smaller one may still fit.\n const chosen = new Set<BlockItem>();\n let used = -1; // joining \"\\n\" is only paid between lines\n const byPriority = items\n .map((item, index) => ({ item, index }))\n .sort((a, b) => a.item.priority - b.item.priority || a.index - b.index);\n for (const { item } of byPriority) {\n const cost = item.text.length + 1;\n if (used + cost > CONTEXT_BLOCK_MAX_CHARS) continue;\n used += cost;\n chosen.add(item);\n }\n const packed = items.filter((item) => chosen.has(item));\n return {\n text: packed.map((item) => item.text).join(\"\\n\"),\n emitted: packed.flatMap((item) => (item.capsule ? [item.capsule] : [])),\n };\n}\n\n/** \"project, plan, 3 fact, 1 incident\" — readable names instead of opaque hashes. */\nfunction describeKeys(keys: string[]): string {\n const counts = new Map<string, number>();\n for (const key of keys) {\n const kind = key.includes(\":\") ? key.slice(0, key.indexOf(\":\")) : key;\n counts.set(kind, (counts.get(kind) ?? 0) + 1);\n }\n return [...counts]\n .map(([kind, count]) => (count > 1 || kinds.has(kind) ? `${count} ${kind}` : kind))\n .join(\", \");\n}\n\nconst kinds = new Set([\"fact\", \"incident\", \"handoff\", \"rule\", \"procedure\"]);\n","import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { generateEntityId } from \"../core/ids.js\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { isEligibleMemory } from \"../core/memory-lifecycle.js\";\nimport { WorklogStore } from \"../worklog/store.js\";\nimport { incidentDoubt } from \"./deterministic.js\";\nimport { type ExtractOptions, extractCandidates } from \"./llm.js\";\nimport { matchResolution } from \"./resolution.js\";\nimport { ReviewStore } from \"./review-store.js\";\nimport { revokes } from \"./rules.js\";\nimport { claimText, redactPersisted, type SensitivityResult, scanFields } from \"./sensitive.js\";\nimport type {\n AfterTurnResult,\n CandidateDecision,\n ExtractionInput,\n MemoryCandidate,\n} from \"./types.js\";\n\n/**\n * The capture orchestrator (`context_after_turn`). It extracts candidates,\n * then gates each one:\n *\n * - `ignored` → dropped.\n * - sensitive content → queued for review, flagged (never auto-saved).\n * - `note` (temporary) → queued for review (never durable).\n * - confident fact/decision/incident (≥ threshold) → saved as durable Markdown.\n * - everything else → queued for review (low confidence).\n *\n * The bias is deliberate: durable memory is the exception, review is the rule.\n */\n\n/** Minimum confidence for a fact/decision/incident to skip review. */\nconst AUTO_SAVE_THRESHOLD = 0.7;\n/** The user stated it (rule) or it passed repeatedly (procedure): trusted, still sensitive-scanned. */\nconst STATED_CONFIDENCE = 0.9;\n\nexport type CaptureOptions = ExtractOptions & {\n repositoryRoot?: string;\n now?: () => Date;\n};\n\nexport async function captureAfterTurn(\n input: ExtractionInput,\n options: CaptureOptions = {},\n): Promise<AfterTurnResult> {\n const repositoryRoot = resolve(options.repositoryRoot ?? process.cwd());\n const now = options.now ?? (() => new Date());\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const reviewStore = new ReviewStore(repositoryRoot);\n\n const extracted =\n input.extract === false\n ? { candidates: [], source: \"deterministic\" as const }\n : await extractCandidates(input, options);\n const source = extracted.source;\n const candidates = [\n ...extracted.candidates,\n ...(input.userRules ?? []).map(ruleCandidate),\n ...(await procedureCandidates(input, repositoryRoot)),\n ];\n\n const saved: CandidateDecision[] = [];\n const queuedForReview: CandidateDecision[] = [];\n const ignored: CandidateDecision[] = [];\n const reasons: string[] = [];\n\n for (const candidate of candidates) {\n // Scan every text surface that reaches durable Markdown: all candidate\n // fields plus the turn's provenance (verification, paths, agent/plan/session/commit).\n const sensitivity = scanFields([\n claimText(candidate),\n candidate.content,\n candidate.subject,\n candidate.predicate,\n candidate.object,\n ...candidate.paths,\n ...(input.verification ?? []),\n input.agentId,\n input.planId,\n input.sessionId,\n input.commitSha,\n ]);\n const decision = await gate({\n candidate,\n input,\n sensitivity,\n memoryStore,\n reviewStore,\n now,\n });\n reasons.push(`${candidate.class}: ${decision.outcome} — ${decision.reason}`);\n if (decision.outcome === \"saved\") saved.push(decision);\n else if (decision.outcome === \"queued\") queuedForReview.push(decision);\n else ignored.push(decision);\n }\n\n for (const revocation of input.revokedRules ?? []) {\n const decision = await revokeRule(revocation, input, memoryStore, reviewStore, now);\n reasons.push(`rule: ${decision.outcome} — ${decision.reason}`);\n // A matched revocation changes existing memory; only an unmatched one is new.\n if (decision.outcome === \"queued\") queuedForReview.push(decision);\n }\n\n const worklogId = await recordWorklog(\n input,\n saved,\n queuedForReview,\n repositoryRoot,\n now,\n reasons,\n );\n return { saved, queuedForReview, ignored, reasons, extractor: source, worklogId };\n}\n\n/**\n * One worklog entry per meaningful turn (files changed, memory saved, or\n * verification reported), so a later chat can recover the work. A worklog\n * failure never undoes or blocks the memory capture above.\n */\nasync function recordWorklog(\n input: ExtractionInput,\n saved: CandidateDecision[],\n queued: CandidateDecision[],\n repositoryRoot: string,\n now: () => Date,\n reasons: string[],\n): Promise<string | null> {\n const files = input.changedFiles ?? [];\n const verification = input.verification ?? [];\n if (files.length === 0 && saved.length === 0 && verification.length === 0 && !input.investigation)\n return null;\n try {\n return await new WorklogStore(repositoryRoot).record(\n {\n namespace: input.namespace,\n summary: input.summary,\n files,\n verification,\n savedMemory: saved.flatMap((decision) => (decision.ref ? [decision.ref] : [])),\n queuedForReview: queued.flatMap((decision) => (decision.ref ? [decision.ref] : [])),\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n ...(input.agentId !== undefined ? { agentId: input.agentId } : {}),\n },\n now(),\n );\n } catch (error) {\n reasons.push(`worklog: not recorded — ${(error as Error).message}`);\n return null;\n }\n}\n\nfunction ruleCandidate(rule: string): MemoryCandidate {\n return {\n class: \"decision\",\n content: rule,\n subject: \"rule\",\n predicate: \"rule\",\n object: rule,\n confidence: STATED_CONFIDENCE,\n paths: [],\n severity: null,\n };\n}\n\n/**\n * A verification command that passed this turn and in at least one earlier\n * captured turn becomes a procedure (\"Verify with: npm test\"). Dedupe is the\n * usual fingerprint, so it is saved once.\n */\nasync function procedureCandidates(\n input: ExtractionInput,\n repositoryRoot: string,\n): Promise<MemoryCandidate[]> {\n const passed = (input.verification ?? []).filter((line) => line.endsWith(\": passed\"));\n if (passed.length === 0) return [];\n let history: string[][];\n try {\n history = (await new WorklogStore(repositoryRoot).list(input.namespace)).map(\n (entry) => entry.verification,\n );\n } catch {\n return [];\n }\n return [...new Set(passed)]\n .filter((line) => history.some((verification) => verification.includes(line)))\n .map((line) => {\n const command = line.slice(0, -\": passed\".length);\n return {\n class: \"fact\" as const,\n content: `Verify with: ${command}`,\n subject: \"procedure\",\n predicate: \"procedure\",\n object: command,\n confidence: STATED_CONFIDENCE,\n paths: [],\n severity: null,\n };\n });\n}\n\n/** Supersede the live rules a user sentence withdraws; with no match, ask a human. */\nasync function revokeRule(\n revocation: string,\n input: ExtractionInput,\n memoryStore: MemoryFileStore,\n reviewStore: ReviewStore,\n now: () => Date,\n): Promise<CandidateDecision> {\n const candidate: MemoryCandidate = {\n class: \"note\",\n content: revocation,\n subject: \"rule\",\n predicate: \"revoke\",\n object: revocation,\n confidence: 0.4,\n paths: [],\n severity: null,\n };\n const matches = (await memoryStore.listFacts()).filter(\n (fact) =>\n fact.predicate === \"rule\" &&\n isEligibleMemory(fact, { namespace: input.namespace }) &&\n revokes(revocation, fact.object),\n );\n const base = { candidate, sensitive: false, sensitiveReasons: [] };\n if (matches.length === 0) {\n const sensitivity = scanFields([revocation]);\n const decision = await gate({ candidate, input, sensitivity, memoryStore, reviewStore, now });\n return { ...decision, reason: `revocation matched no rule; ${decision.reason}` };\n }\n const marker = `revoked:${now().toISOString()}`;\n for (const fact of matches) await memoryStore.markFactSuperseded(fact.id, marker);\n return {\n ...base,\n outcome: \"saved\",\n reason: `revoked ${matches.map((fact) => fact.id).join(\", \")}`,\n ref: matches[0]?.id as string,\n };\n}\n\nasync function gate(args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n sensitivity: SensitivityResult;\n memoryStore: MemoryFileStore;\n reviewStore: ReviewStore;\n now: () => Date;\n}): Promise<CandidateDecision> {\n const { candidate, sensitivity } = args;\n const fingerprint = candidateFingerprint(args.input.namespace, candidate);\n const base = {\n candidate,\n sensitive: sensitivity.sensitive,\n sensitiveReasons: sensitivity.reasons,\n };\n\n if (candidate.class === \"ignored\") {\n return { ...base, outcome: \"ignored\", reason: \"classified as chatter\" };\n }\n\n if (sensitivity.sensitive) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n const ref =\n existing?.id ?? (await queue(args, `sensitive content (${sensitivity.reasons.join(\", \")})`));\n return {\n ...base,\n outcome: \"queued\",\n reason: `sensitive: ${sensitivity.reasons.join(\", \")}`,\n ref,\n };\n }\n\n if (candidate.class === \"note\") {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n if (existing) {\n return { ...base, outcome: \"queued\", reason: \"duplicate review candidate\", ref: existing.id };\n }\n const ref = await queue(args, \"temporary note\");\n return { ...base, outcome: \"queued\", reason: \"temporary note held for review\", ref };\n }\n\n if (candidate.confidence < AUTO_SAVE_THRESHOLD) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n if (existing) {\n return { ...base, outcome: \"queued\", reason: \"duplicate review candidate\", ref: existing.id };\n }\n const ref = await queue(args, `low confidence (${candidate.confidence.toFixed(2)})`);\n return {\n ...base,\n outcome: \"queued\",\n reason: `low confidence ${candidate.confidence.toFixed(2)} < ${AUTO_SAVE_THRESHOLD}`,\n ref,\n };\n }\n\n if (candidate.class === \"incident\") {\n const doubt = incidentDoubt(candidate.content);\n if (doubt) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n const ref = existing?.id ?? (await queue(args, `uncertain incident: ${doubt}`));\n return { ...base, outcome: \"queued\", reason: `uncertain incident: ${doubt}`, ref };\n }\n }\n\n if (candidate.class === \"incident\" && isResolution(candidate.content)) {\n const unresolved = await args.memoryStore.listIncidentFacts({\n namespace: args.input.namespace,\n });\n const sharingPaths = await args.memoryStore.findIncidentFactsForPaths({\n namespace: args.input.namespace,\n paths: candidate.paths,\n });\n const match = matchResolution(candidate.content, sharingPaths, unresolved);\n if (match.kind === \"queue\") {\n const ref = await queue(\n args,\n `incident resolution not grounded: ${match.reason}`,\n match.candidates,\n );\n return {\n ...base,\n outcome: \"queued\",\n reason: `resolution not grounded: ${match.reason}`,\n ref,\n };\n }\n await args.memoryStore.markIncidentResolved(match.incident.id, fingerprint);\n return {\n ...base,\n outcome: \"saved\",\n reason: `resolved incident ${match.incident.id} (${match.reason})`,\n ref: match.incident.id,\n };\n }\n\n const ref = await saveDurable(args);\n const superseded = candidate.content.match(/\\bsupersedes\\s+(fact_[a-z0-9]+)\\b/i)?.[1];\n if (superseded && superseded !== ref) {\n try {\n await args.memoryStore.markFactSuperseded(superseded, ref);\n } catch {\n // A missing/invalid referenced fact does not invalidate the new decision.\n }\n }\n return { ...base, outcome: \"saved\", reason: `confident ${candidate.class} auto-saved`, ref };\n}\n\nasync function saveDurable(args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n memoryStore: MemoryFileStore;\n now: () => Date;\n}): Promise<string> {\n const { candidate, input, memoryStore, now } = args;\n const fingerprint = candidateFingerprint(input.namespace, candidate);\n const existing = (await memoryStore.listFacts()).find(\n (fact) => fact.namespace === input.namespace && fact.fingerprint === fingerprint,\n );\n if (existing) return existing.id;\n const id = generateEntityId(\"fact\");\n const isIncident = candidate.class === \"incident\";\n await memoryStore.writeFact({\n id,\n namespace: input.namespace,\n subject: candidate.subject,\n predicate: candidate.predicate,\n object: candidate.object,\n confidence: candidate.confidence,\n createdAt: now().toISOString(),\n createdByAgent: input.agentId ?? null,\n sourceInteractionId: null,\n sourceDeleted: false,\n content: candidate.content,\n category: isIncident ? \"incident\" : \"general\",\n paths: candidate.paths,\n severity: isIncident ? candidate.severity : null,\n fingerprint,\n sourcePlanId: input.planId ?? null,\n sourceSessionId: input.sessionId ?? null,\n verification: input.verification ?? [],\n introducedBy: isIncident ? (input.commitSha ?? null) : null,\n });\n return id;\n}\n\nasync function queue(\n args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n sensitivity: SensitivityResult;\n reviewStore: ReviewStore;\n now: () => Date;\n },\n reason: string,\n resolvesIncidents: string[] | null = null,\n): Promise<string> {\n const { candidate, input, sensitivity, reviewStore, now } = args;\n const fingerprint = candidateFingerprint(input.namespace, candidate);\n const id = generateEntityId(\"rev\");\n await reviewStore.write({\n id,\n namespace: input.namespace,\n class: candidate.class,\n subject: candidate.subject,\n predicate: candidate.predicate,\n object: candidate.object,\n confidence: candidate.confidence,\n paths: candidate.paths,\n severity: candidate.severity,\n sensitive: sensitivity.sensitive,\n sensitiveReasons: sensitivity.reasons,\n reason,\n createdAt: now().toISOString(),\n createdByAgent: input.agentId ?? null,\n sourcePlanId: input.planId ?? null,\n fingerprint,\n sourceSessionId: input.sessionId ?? null,\n verification: input.verification ?? [],\n content: candidate.content,\n resolvesIncidents,\n });\n await reviewStore.enforceLimit();\n return id;\n}\n\nfunction isResolution(content: string): boolean {\n return /\\b(fixed|resolved|closed|no longer reproduces|verified the fix)\\b/i.test(content);\n}\n\nexport function candidateFingerprint(namespace: string, raw: MemoryCandidate): string {\n // Hash the redacted form so the persisted fingerprint never derives from a raw secret.\n const candidate = redactPersisted(raw);\n const canonical = JSON.stringify({\n namespace: namespace.trim().toLowerCase(),\n class: candidate.class,\n subject: candidate.subject.trim().toLowerCase(),\n predicate: candidate.predicate.trim().toLowerCase(),\n object: candidate.object.trim().replace(/\\s+/g, \" \").toLowerCase(),\n content: candidate.content.trim().replace(/\\s+/g, \" \").toLowerCase(),\n paths: [...new Set(candidate.paths.map((path) => path.replace(/\\\\/g, \"/\")))].sort(),\n });\n return createHash(\"sha256\").update(canonical).digest(\"hex\");\n}\n\n/**\n * Promote a queued review item to a durable fact and remove it from the queue.\n * A queued incident resolution instead resolves the chosen existing incident\n * (`incidentId`, or the single recorded candidate) and returns its id.\n * Powers `codebuddy memory review approve`.\n */\nexport async function approveReviewItem(\n id: string,\n options: { repositoryRoot?: string; now?: () => Date; incidentId?: string } = {},\n): Promise<string> {\n const repositoryRoot = resolve(options.repositoryRoot ?? process.cwd());\n const now = options.now ?? (() => new Date());\n const reviewStore = new ReviewStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n\n const item = await reviewStore.read(id);\n\n // A queued resolution closes an existing incident; it never writes a new one.\n if (item.resolvesIncidents) {\n const unresolved = await memoryStore.listIncidentFacts({ namespace: item.namespace });\n const target =\n options.incidentId ??\n (item.resolvesIncidents.length === 1 ? item.resolvesIncidents[0] : undefined);\n if (!target) {\n throw new Error(\n item.resolvesIncidents.length === 0\n ? `Review item ${id} is an incident resolution with no candidate incident; pass an incident id to resolve.`\n : `Review item ${id} is an ambiguous incident resolution; pass one incident id. Candidates: ${item.resolvesIncidents.join(\", \")}`,\n );\n }\n if (!unresolved.some((incident) => incident.id === target)) {\n throw new Error(`${target} is not an unresolved incident in namespace ${item.namespace}.`);\n }\n await memoryStore.markIncidentResolved(target, item.fingerprint ?? id);\n await reviewStore.delete(id);\n return target;\n }\n\n const factId = generateEntityId(\"fact\");\n const isIncident = item.class === \"incident\";\n await memoryStore.writeFact({\n id: factId,\n namespace: item.namespace,\n subject: item.subject,\n predicate: item.predicate,\n object: item.object,\n confidence: item.confidence,\n createdAt: now().toISOString(),\n createdByAgent: item.createdByAgent,\n sourceInteractionId: null,\n sourceDeleted: false,\n content: item.content,\n category: isIncident ? \"incident\" : \"general\",\n paths: item.paths,\n severity: isIncident ? (item.severity ?? \"medium\") : null,\n fingerprint: item.fingerprint,\n sourcePlanId: item.sourcePlanId,\n sourceSessionId: item.sourceSessionId,\n verification: item.verification,\n });\n await reviewStore.delete(id);\n return factId;\n}\n","import type { IncidentSeverity } from \"../core/memory-file-store.js\";\nimport type { ExtractionInput, MemoryCandidate, MemoryClass } from \"./types.js\";\n\n/**\n * Deterministic, no-LLM extraction. This is the always-available baseline\n * (offline mode) and the fallback when LLM extraction fails validation. It\n * segments the turn summary into sentences and classifies each with ordered\n * keyword rules. The same input always yields the same candidates, which keeps\n * capture predictable and auditable.\n *\n * Rule order matters: a \"TODO: fix the crash\" is a note, not an incident, so\n * note markers are checked before incident markers.\n */\n\ntype Rule = {\n class: MemoryClass;\n regex: RegExp;\n confidence: number;\n predicate: string;\n subject: string;\n};\n\n/** \"Resolved fact_abc123\": names its incident, so it is unambiguous by construction. */\nconst EXPLICIT_RESOLUTION = /\\b(?:fixed|resolved|closed)\\b.*\\bfact_[a-z0-9]+\\b/i;\n\nconst RULES: Rule[] = [\n {\n class: \"note\",\n subject: \"note\",\n predicate: \"todo\",\n confidence: 0.4,\n regex:\n /\\b(todo|to-do|follow[- ]?up|later|remember to|revisit|temporary|tmp|next time|should probably)\\b/i,\n },\n {\n // Explicit resolution of a named incident (\"Resolved fact_abc123\").\n class: \"incident\",\n subject: \"incident\",\n predicate: \"resolved\",\n confidence: 0.8,\n regex: EXPLICIT_RESOLUTION,\n },\n {\n class: \"decision\",\n subject: \"decision\",\n predicate: \"made\",\n confidence: 0.8,\n regex:\n /\\b(decided|chose|choose|we will|going with|switched to|switch to|adopt(?:ed)?|agreed|settled on|opt(?:ed)? for)\\b/i,\n },\n {\n class: \"incident\",\n subject: \"incident\",\n predicate: \"occurred\",\n confidence: 0.75,\n regex:\n /\\b(bug|regression|broke|broken|crash(?:ed)?|outage|incident|root cause|failure|failed|null pointer|race condition|deadlock)\\b/i,\n },\n {\n class: \"fact\",\n subject: \"project\",\n predicate: \"fact\",\n confidence: 0.55,\n regex:\n /\\b(uses?|is|are|requires?|depends on|stores?|returns?|implemented|added|supports?|configured|lives in|located|handles?)\\b/i,\n },\n];\n\nconst INCIDENT_REGEX = (RULES.find((rule) => rule.predicate === \"occurred\") as Rule).regex;\nexport const SPECULATIVE =\n /\\b(might|maybe|possibly|could|consider(?:ing)?|planned|planning|should|if|would|unless|whether|suppose|hypothetical(?:ly)?|in theory|in case)\\b/i;\n// \"no longer reproduces\" is a resolution, not a negation.\nconst NEGATION =\n /\\b(no|not|never|none|nothing|nobody|without|zero|neither|nor|cannot)\\b(?!\\s+longer)|\\w+n['’]t\\b/i;\nconst EXAMPLE = /\\b(?:e\\.g|i\\.e|for example|for instance|such as|example|sample|hypothetical)\\b/i;\n// Balanced \"double\", \\u201ccurly\\u201d and `code` quotes.\nconst QUOTED = /\"[^\"]*\"|\\u201c[^\\u201d]*\\u201d|`[^`]*`/g;\n\n/**\n * Why an incident-looking sentence is not trustworthy enough to become a\n * durable incident: negated (\"no crash occurred\"), hypothetical (\"if it\n * crashes\"), or quoted/example text. Returns null when it reads as a real\n * event. Shared by the deterministic extractor and the capture gate so LLM\n * candidates get the same scrutiny.\n */\nexport function incidentDoubt(sentence: string): string | null {\n if (EXPLICIT_RESOLUTION.test(sentence)) return null;\n const unquoted = sentence.replace(QUOTED, \" \");\n const onlyQuoted = INCIDENT_REGEX.test(sentence) && !INCIDENT_REGEX.test(unquoted);\n const unbalanced = (sentence.match(/[\"\\u201c\\u201d]/g)?.length ?? 0) % 2 === 1;\n if (onlyQuoted || unbalanced || EXAMPLE.test(sentence)) return \"quoted or example text\";\n if (NEGATION.test(unquoted)) return \"negated statement\";\n if (SPECULATIVE.test(unquoted) && !EXPLICIT_DECISION.test(unquoted))\n return \"hypothetical statement\";\n return null;\n}\nconst EXPLICIT_DECISION = /\\b(decided|chose|agreed|settled on|adopted|switched to)\\b/i;\n\nconst SEVERITY_MARKERS: Array<{ severity: IncidentSeverity; regex: RegExp }> = [\n { severity: \"critical\", regex: /\\b(critical|outage|data loss|corruption|security)\\b/i },\n {\n severity: \"high\",\n regex: /\\b(high severity|regression|crash(?:ed)?|deadlock|broke production)\\b/i,\n },\n { severity: \"low\", regex: /\\b(minor|cosmetic|typo|trivial)\\b/i },\n];\n\nexport function deterministicExtract(input: ExtractionInput): MemoryCandidate[] {\n const changedFiles = (input.changedFiles ?? []).filter(Boolean);\n const candidates: MemoryCandidate[] = [];\n\n for (const sentence of splitSentences(input.summary)) {\n const classified = classify(sentence);\n const doubt = classified?.class === \"incident\" ? incidentDoubt(sentence) : null;\n const rule =\n doubt ||\n (SPECULATIVE.test(sentence) &&\n !EXPLICIT_DECISION.test(sentence) &&\n !EXPLICIT_RESOLUTION.test(sentence))\n ? {\n class: \"note\" as const,\n subject: \"speculation\",\n predicate: \"consider\",\n confidence: 0.3,\n regex: SPECULATIVE,\n }\n : classified;\n if (!rule) {\n candidates.push(ignoredCandidate(sentence));\n continue;\n }\n\n const isIncident = rule.class === \"incident\";\n let confidence = rule.confidence;\n if (isIncident && /\\broot cause\\b/i.test(sentence)) confidence = Math.min(1, confidence + 0.1);\n\n candidates.push({\n class: rule.class,\n content: sentence,\n subject: rule.subject,\n predicate: rule.predicate,\n object: sentence,\n confidence,\n // Incidents and decisions carry the change set so recall can link them to\n // the files they concern (the risk incident signal matches on paths).\n paths: rule.class === \"incident\" || rule.class === \"decision\" ? changedFiles : [],\n severity: isIncident ? guessSeverity(sentence) : null,\n });\n }\n\n return candidates;\n}\n\nfunction classify(sentence: string): Rule | null {\n for (const rule of RULES) {\n if (rule.regex.test(sentence)) return rule;\n }\n return null;\n}\n\nfunction ignoredCandidate(sentence: string): MemoryCandidate {\n return {\n class: \"ignored\",\n content: sentence,\n subject: \"chatter\",\n predicate: \"ignored\",\n object: sentence,\n confidence: 0.2,\n paths: [],\n severity: null,\n };\n}\n\nfunction guessSeverity(sentence: string): IncidentSeverity {\n for (const marker of SEVERITY_MARKERS) {\n if (marker.regex.test(sentence)) return marker.severity;\n }\n return \"medium\";\n}\n\n/** Split into trimmed sentences on terminators and newlines; drop tiny fragments. */\nexport function splitSentences(summary: string): string[] {\n return summary\n .split(/(?<=[.!?])(?<!\\b(?:e\\.g|i\\.e|vs|etc)\\.)\\s+|\\n+/)\n .map((sentence) => sentence.trim().replace(/^[-*•]\\s*/, \"\"))\n .filter((sentence) => sentence.length > 3);\n}\n","import { z } from \"zod\";\nimport { deterministicExtract } from \"./deterministic.js\";\nimport { type ExtractionInput, type MemoryCandidate, memoryCandidateSchema } from \"./types.js\";\n\n/**\n * LLM-assisted extraction is optional and never trusted blindly. An extractor\n * returns raw JSON; we validate it strictly against the candidate schema and\n * retry a bounded number of times. If it never produces valid output — or no\n * extractor is configured — we fall back to the deterministic parser rather\n * than inventing certainty. Raw LLM output is a suggestion, not a fact.\n */\n\n/** Pluggable model backend. Returns unvalidated candidate JSON. */\nexport type MemoryExtractor = {\n extract(input: ExtractionInput): Promise<unknown>;\n};\n\nconst candidateArraySchema = z.array(memoryCandidateSchema);\n\nexport type ExtractOptions = {\n extractor?: MemoryExtractor;\n retries?: number;\n};\n\nexport type ExtractOutcome = {\n candidates: MemoryCandidate[];\n source: \"deterministic\" | \"llm\";\n};\n\nexport async function extractCandidates(\n input: ExtractionInput,\n options: ExtractOptions = {},\n): Promise<ExtractOutcome> {\n if (options.extractor) {\n const validated = await tryLlmExtraction(input, options.extractor, options.retries ?? 2);\n if (validated) return { candidates: validated, source: \"llm\" };\n }\n return { candidates: deterministicExtract(input), source: \"deterministic\" };\n}\n\nasync function tryLlmExtraction(\n input: ExtractionInput,\n extractor: MemoryExtractor,\n retries: number,\n): Promise<MemoryCandidate[] | null> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const parsed = candidateArraySchema.safeParse(await extractor.extract(input));\n if (parsed.success) return parsed.data;\n } catch {\n // Swallow and retry; a throwing extractor is treated like invalid output.\n }\n }\n return null;\n}\n","import type { IncidentFactFile } from \"../core/memory-file-store.js\";\n\n/**\n * Deciding which unresolved incident a \"fixed X\" statement closes. A shared\n * file is never enough: resolution needs an explicit incident id, or fix text\n * that matches exactly one candidate's terms better than every other one.\n * Anything else is ambiguous and goes to review. Severity/recency never break\n * ties, so a generic fix can't close an unrelated higher-severity incident.\n *\n * Terms every candidate shares (e.g. the module name) say nothing about WHICH\n * incident was fixed, so only terms that tell candidates apart count, and the\n * fix must hit exactly one candidate's distinctive terms. A multi-topic fix\n * that touches two incidents is therefore ambiguous, however many terms match.\n */\n\nexport type ResolutionMatch =\n | { kind: \"resolved\"; incident: IncidentFactFile; reason: string }\n /** `candidates` are the unresolved incident ids a reviewer may pick from. */\n | { kind: \"queue\"; reason: string; candidates: string[] };\n\nconst FACT_ID = /\\bfact_[a-z0-9]+\\b/gi;\n\n// Words that carry no event identity: grammar plus generic fix/bug vocabulary.\nconst GENERIC = new Set(\n (\n \"a an the and or but of in on at to for from by with as is are was were be been it its this that these those \" +\n \"we i you they he she them there then than so not no also again now still just only into onto after before when while \" +\n \"fix fixed fixes fixing resolve resolved resolves resolving close closed closes verify verified verifies \" +\n \"bug bugs issue issues problem problems incident incidents error errors regression longer reproduce reproduces \" +\n \"test tests passed passing work works worked working change changed changes\"\n ).split(\" \"),\n);\n\n/** Lowercased content terms with a crude suffix stem (\"crashed\"/\"crashes\" -> \"crash\"). */\nexport function groundingTerms(text: string): Set<string> {\n const terms = new Set<string>();\n for (const word of text.toLowerCase().match(/[a-z][a-z0-9]+/g) ?? []) {\n if (GENERIC.has(word) || /^fact_/.test(word)) continue;\n terms.add(word.length > 4 ? word.replace(/(ing|ed|es|s)$/, \"\") : word);\n }\n return terms;\n}\n\nexport function matchResolution(\n fixText: string,\n pathCandidates: IncidentFactFile[],\n unresolved: IncidentFactFile[],\n): ResolutionMatch {\n const explicit = [...new Set(fixText.match(FACT_ID)?.map((id) => id.toLowerCase()))];\n if (explicit.length > 0) {\n const named = unresolved.filter((incident) => explicit.includes(incident.id));\n const [only] = named;\n if (named.length === 1 && only) {\n return { kind: \"resolved\", incident: only, reason: `explicit incident id ${only.id}` };\n }\n return {\n kind: \"queue\",\n candidates: named.map((incident) => incident.id),\n reason:\n named.length === 0\n ? \"explicit incident id does not name an unresolved incident\"\n : \"explicit ids name several incidents\",\n };\n }\n\n const candidates = pathCandidates.map((incident) => incident.id);\n const fixTerms = groundingTerms(fixText);\n if (pathCandidates.length === 0) {\n return {\n kind: \"queue\",\n candidates,\n reason: \"no unresolved incident touches the changed paths\",\n };\n }\n if (fixTerms.size === 0) {\n return { kind: \"queue\", candidates, reason: \"fix text names no specific event\" };\n }\n\n const incidentTerms = pathCandidates.map((incident) =>\n groundingTerms(`${incident.subject} ${incident.content}`),\n );\n // With several candidates, ignore terms all of them share (no discriminating power).\n const distinctive = (term: string) =>\n pathCandidates.length === 1 || incidentTerms.some((terms) => !terms.has(term));\n const hits = incidentTerms.map((terms) => [...fixTerms].filter((term) => terms.has(term)));\n const withDistinctive = hits\n .map((matched, index) => ({ index, matched, count: matched.filter(distinctive).length }))\n .filter((entry) => entry.count > 0 || pathCandidates.length === 1);\n\n const [best] = withDistinctive;\n if (!best || withDistinctive.length > 1) {\n return {\n kind: \"queue\",\n candidates,\n reason: best\n ? \"fix text matches distinctive terms of several unresolved incidents\"\n : \"fix text does not single out any unresolved incident\",\n };\n }\n const need = Math.min(2, fixTerms.size);\n if (best.matched.length < need) {\n return { kind: \"queue\", candidates, reason: \"fix text is too weakly grounded in the incident\" };\n }\n const incident = pathCandidates[best.index] as IncidentFactFile;\n return {\n kind: \"resolved\",\n incident,\n reason: `grounded match on ${best.matched.length} shared term${best.matched.length === 1 ? \"\" : \"s\"}`,\n };\n}\n","import { mkdir, readdir, readFile, rename, rm } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"../core/markdown-store-fs.js\";\nimport { INCIDENT_SEVERITIES } from \"../core/memory-file-store.js\";\nimport { redactPersisted } from \"./sensitive.js\";\nimport { MEMORY_CLASSES } from \"./types.js\";\n\n/**\n * The review queue holds memory candidates that are not safe to auto-save —\n * low confidence, sensitive content, or an inherently temporary note. Items are\n * plain Markdown with YAML front matter under `.codebuddy/memory/review/`, so\n * they are inspectable, diffable, and deletable by hand. Approving an item\n * promotes it to a durable fact; rejecting deletes it. Nothing here is ever\n * committed automatically.\n */\n\nconst reviewSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^rev_[a-z0-9]+$/),\n namespace: z.string().min(1),\n class: z.enum(MEMORY_CLASSES),\n subject: z.string().min(1),\n predicate: z.string().min(1),\n object: z.string().min(1),\n confidence: z.number().min(0).max(1),\n paths: z.array(z.string().min(1)).default([]),\n severity: z.enum(INCIDENT_SEVERITIES).nullable().default(null),\n sensitive: z.boolean().default(false),\n sensitiveReasons: z.array(z.string()).default([]),\n reason: z.string(),\n createdAt: z.string(),\n createdByAgent: z.string().nullable(),\n sourcePlanId: z.string().nullable().default(null),\n fingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .nullable()\n .default(null),\n sourceSessionId: z.string().nullable().default(null),\n verification: z.array(z.string()).default([]),\n /**\n * Set only on a queued incident *resolution* (\"Fixed X\") that could not be\n * grounded: the unresolved incident ids it might close. Approving it resolves\n * one of them instead of writing a new incident. null = ordinary item.\n */\n resolvesIncidents: z.array(z.string()).nullable().default(null),\n});\n\nexport type ReviewItemWrite = Omit<\n z.infer<typeof reviewSchema>,\n \"schemaVersion\" | \"fingerprint\" | \"sourceSessionId\" | \"verification\" | \"resolvesIncidents\"\n> & {\n resolvesIncidents?: string[] | null;\n fingerprint?: string | null;\n sourceSessionId?: string | null;\n verification?: string[];\n content: string;\n};\nexport type ReviewItem = z.infer<typeof reviewSchema> & { content: string; path: string };\n\nexport class ReviewStore {\n readonly repositoryRoot: string;\n readonly reviewDirectory: string;\n readonly archiveDirectory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.reviewDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"review\");\n this.archiveDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"review-archive\");\n }\n\n async write(raw: ReviewItemWrite): Promise<string> {\n // Persistence boundary: nothing sensitive reaches disk, whatever the caller did.\n const input = redactPersisted(raw);\n const path = this.itemPath(input.id);\n await this.prepareDirectory();\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n class: input.class,\n subject: input.subject,\n predicate: input.predicate,\n object: input.object,\n confidence: input.confidence,\n paths: input.paths,\n severity: input.severity,\n sensitive: input.sensitive,\n sensitiveReasons: input.sensitiveReasons,\n reason: input.reason,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n sourcePlanId: input.sourcePlanId,\n fingerprint: input.fingerprint,\n sourceSessionId: input.sourceSessionId,\n verification: input.verification,\n resolvesIncidents: input.resolvesIncidents ?? null,\n });\n await writeAtomic(path, composeMarkdown(frontMatter, input.content));\n return path;\n }\n\n async read(id: string): Promise<ReviewItem> {\n const path = this.itemPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n return {\n ...reviewSchema.parse(parseYaml(parsed.frontMatter)),\n content: parsed.content.trim(),\n path,\n };\n }\n\n async list(): Promise<ReviewItem[]> {\n try {\n await this.prepareDirectory();\n const entries = await readdir(this.reviewDirectory, { withFileTypes: true });\n const items: ReviewItem[] = [];\n for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n // Only managed review files are queue items. A hand-written README.md\n // (or any non-rev_ markdown) must be ignored, not thrown on — one\n // stray file used to brick every future capture turn.\n if (!/^rev_[a-z0-9]+\\.md$/.test(entry.name)) continue;\n try {\n items.push(await this.read(entry.name.replace(/\\.md$/, \"\")));\n } catch {\n // A single corrupt item is skipped rather than poisoning the whole\n // queue; it stays on disk for manual inspection.\n }\n }\n return items;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n }\n\n async delete(id: string): Promise<void> {\n await rm(this.itemPath(id), { force: true });\n }\n\n async archiveExpired(options: { olderThanDays?: number; now?: Date } = {}): Promise<number> {\n const cutoff =\n (options.now ?? new Date()).getTime() - (options.olderThanDays ?? 30) * 24 * 60 * 60 * 1000;\n const items = await this.list();\n let archived = 0;\n for (const item of items) {\n if (Date.parse(item.createdAt) >= cutoff) continue;\n await this.archive(item);\n archived++;\n }\n return archived;\n }\n\n async enforceLimit(maxItems = 500): Promise<number> {\n const items = (await this.list()).sort((left, right) =>\n left.createdAt.localeCompare(right.createdAt),\n );\n const overflow = Math.max(0, items.length - maxItems);\n for (const item of items.slice(0, overflow)) await this.archive(item);\n return overflow;\n }\n\n private async archive(item: ReviewItem): Promise<void> {\n await mkdir(this.archiveDirectory, { recursive: true, mode: 0o700 });\n await assertNoSymlinkBetween(this.repositoryRoot, this.archiveDirectory);\n await rename(item.path, join(this.archiveDirectory, `${item.id}.md`));\n }\n\n private itemPath(id: string): string {\n if (!/^rev_[a-z0-9]+$/.test(id)) throw new Error(`Invalid review id: ${id}`);\n return this.safePath(join(this.reviewDirectory, `${id}.md`));\n }\n\n private safePath(path: string): string {\n const absolute = resolve(path);\n const relativePath = relative(this.repositoryRoot, absolute);\n if (relativePath === \"..\" || relativePath.startsWith(`..${sep}`) || relativePath === \"\") {\n throw new Error(`Review path escapes repository root: ${path}`);\n }\n return absolute;\n }\n\n private async prepareDirectory(): Promise<void> {\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(this.reviewDirectory));\n await mkdir(this.reviewDirectory, { recursive: true, mode: 0o700 });\n }\n}\n","import { SPECULATIVE } from \"./deterministic.js\";\n\n/**\n * Standing rules the user states (\"from now on…\", \"never…\", \"every PR\n * must…\") and revocations of them (\"stop…\", \"no longer…\"). A rule the user\n * stated is the most trustworthy memory there is, so it is read from the\n * user's own prompt, never from the assistant's paraphrase. Questions and\n * speculation are not rules.\n */\n\nconst MAX_RULE_CHARS = 300;\n/** CodeBuddy's injected context starts here; nothing after it is the user's. */\nconst INJECTED_BLOCK = /^##\\s*CodeBuddy\\b/m;\n/** Quoted or code material is never an instruction to this project. */\nconst FENCED_CODE = /```[\\s\\S]*?(?:```|$)/g;\nconst QUOTE_LINE = /^\\s*>.*$/gm;\n/** An explicit rule introduction: \"from now on\", \"going forward\", \"(a) rule (for …):\". */\nconst RULE_PREFIX =\n /^(?:also,?\\s+|please,?\\s+)?(?:from now on|going forward|(?:a\\s+)?rule\\b[^:.]{0,60}:)[,:]?\\s*/i;\n/** Imperative position: the sentence itself starts with the marker, or \"we/you always|never|must\". */\nconst IMPERATIVE =\n /^(?:please,?\\s+)?(?:always|never)\\s+\\S+\\s+\\S+|^(?:we|you)\\s+(?:always|never|must)\\b|^every\\s+(?!time\\b)\\S+.*\\bmust\\b/i;\nconst QUESTION_START =\n /^(?:why|how|what|when|where|which|who|can|could|would|will|do|does|did|is|are|should)\\b/i;\n/** Withdrawal of a rule: \"stop <verb>ing\", \"no longer\", \"don't … anymore\", \"forget the rule\". */\nconst REVOCATION_MARKER =\n /^(?:please,?\\s+)?stop\\s+\\w+ing\\b|\\bno longer\\b|\\b(?:don't|do not)\\b.*\\banymore\\b|\\b(?:forget|drop|remove)\\s+the\\s+rule\\b/i;\nconst STOPWORDS = new Set([\n \"the\",\n \"and\",\n \"for\",\n \"from\",\n \"now\",\n \"always\",\n \"never\",\n \"rule\",\n \"about\",\n \"longer\",\n \"don't\",\n \"anymore\",\n \"every\",\n \"must\",\n \"please\",\n \"with\",\n \"that\",\n \"this\",\n \"our\",\n \"you\",\n]);\n\nexport function extractUserRules(prompts: string[]): { rules: string[]; revocations: string[] } {\n const rules = new Map<string, string>();\n const revocations = new Map<string, string>();\n for (const prompt of prompts) {\n const own = (prompt.split(INJECTED_BLOCK)[0] ?? \"\")\n .replace(FENCED_CODE, \"\\n\")\n .replace(QUOTE_LINE, \"\");\n for (const raw of own.split(/(?<=[.!?])\\s+|\\n+/)) {\n const sentence = raw.trim();\n if (!sentence || sentence.length > MAX_RULE_CHARS || sentence.endsWith(\"?\")) continue;\n if (QUESTION_START.test(sentence)) continue;\n const key = sentence\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .replace(/[.!]+$/, \"\");\n if (REVOCATION_MARKER.test(sentence)) {\n if (!revocations.has(key)) revocations.set(key, sentence);\n } else if (isRule(sentence) && !SPECULATIVE.test(sentence)) {\n if (!rules.has(key)) rules.set(key, sentence);\n }\n }\n }\n return { rules: [...rules.values()], revocations: [...revocations.values()] };\n}\n\n/** A rule is explicitly introduced, or an imperative with at least a verb and an object. */\nfunction isRule(sentence: string): boolean {\n const rest = sentence.replace(RULE_PREFIX, \"\");\n if (rest !== sentence) return rest.split(/\\s+/).filter(Boolean).length >= 3;\n return IMPERATIVE.test(sentence);\n}\n\n/** Content words, crudely stemmed so \"running\"/\"run\" and \"committing\"/\"commit\" match. */\nexport function ruleWords(text: string): Set<string> {\n return new Set(\n (text.toLowerCase().match(/[a-z][a-z'-]+/g) ?? [])\n .filter((word) => word.length >= 3 && !STOPWORDS.has(word))\n .map((word) => word.replace(/(?:ing|ed|es|s)$/, \"\").replace(/([b-df-hj-np-tv-z])\\1$/, \"$1\")),\n );\n}\n\n/**\n * A revocation names a rule only when it repeats every content word of the\n * rule; anything looser goes to review instead of silently dropping a rule.\n */\nexport function revokes(revocation: string, rule: string): boolean {\n const ruleSet = ruleWords(rule);\n if (ruleSet.size === 0) return false;\n const words = ruleWords(revocation);\n return [...ruleSet].every((word) => words.has(word));\n}\n","import { mkdir, readFile, rename, rm, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * Between the edit hook and the turn-end hook, CodeBuddy needs to remember which\n * files an agent actually changed. This staging store holds that set per session\n * under `.codebuddy/cache/hooks/` (rebuildable, local, gitignored). The turn-end\n * capture hook drains it, so capture works from the *real* change set rather\n * than a summary the model may or may not write.\n */\nexport class HookStagingStore {\n readonly directory: string;\n private operations = Promise.resolve();\n\n constructor(repositoryRoot = process.cwd()) {\n this.directory = join(resolve(repositoryRoot), \".codebuddy\", \"cache\", \"hooks\");\n }\n\n async add(sessionId: string, paths: string[]): Promise<void> {\n await this.serialize(async () => {\n const clean = paths.map(normalize).filter(Boolean);\n if (clean.length === 0) return;\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n await this.withFileLock(sessionId, async () => {\n const merged = [...new Set([...(await this.read(sessionId)), ...clean])].sort();\n await writeAtomic(\n this.filePath(sessionId),\n `${JSON.stringify({ paths: merged }, null, 2)}\\n`,\n );\n });\n });\n }\n\n async read(sessionId: string): Promise<string[]> {\n try {\n const parsed = JSON.parse(await readFile(this.filePath(sessionId), \"utf8\"));\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((p: unknown) => typeof p === \"string\")\n : [];\n } catch {\n return [];\n }\n }\n\n /** Return the staged paths and clear them. */\n async drain(sessionId: string): Promise<string[]> {\n return this.serialize(async () => {\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n return this.withFileLock(sessionId, async () => {\n const path = this.filePath(sessionId);\n const draining = `${path}.${process.pid}.${Date.now()}.drain`;\n try {\n await rename(path, draining);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n try {\n const parsed = JSON.parse(await readFile(draining, \"utf8\"));\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((item: unknown) => typeof item === \"string\")\n : [];\n } finally {\n await rm(draining, { force: true });\n }\n });\n });\n }\n\n /** Claim a batch without consuming edits staged while capture runs. */\n async claim(sessionId: string): Promise<string[] | null> {\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n const captureLock = `${this.filePath(sessionId)}.capture-lock`;\n for (let attempt = 0; ; attempt++) {\n try {\n await mkdir(captureLock);\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const age =\n Date.now() - (await stat(captureLock).catch(() => ({ mtimeMs: Date.now() }))).mtimeMs;\n if (age > 60_000) {\n await rm(captureLock, { recursive: true, force: true });\n continue;\n }\n if (attempt >= 200) return null;\n await new Promise((resolveWait) => setTimeout(resolveWait, 10));\n }\n }\n try {\n return await this.withFileLock(sessionId, async () => {\n const claimed = this.claimPath(sessionId);\n try {\n return parsePaths(await readFile(claimed, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n try {\n await rename(this.filePath(sessionId), claimed);\n return parsePaths(await readFile(claimed, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n });\n } catch (error) {\n await rm(captureLock, { recursive: true, force: true });\n throw error;\n }\n }\n\n /** Acknowledge only the claimed batch; later edits remain staged. */\n async acknowledge(sessionId: string): Promise<void> {\n await this.withFileLock(sessionId, async () => {\n await rm(this.claimPath(sessionId), { force: true });\n });\n await rm(`${this.filePath(sessionId)}.capture-lock`, { recursive: true, force: true });\n }\n\n /** Restore the claimed batch for retry, merging edits that arrived during capture. */\n async rollback(sessionId: string): Promise<void> {\n await this.withFileLock(sessionId, async () => {\n const claimed = await readFile(this.claimPath(sessionId), \"utf8\")\n .then(parsePaths)\n .catch(() => []);\n const merged = [...new Set([...claimed, ...(await this.read(sessionId))])].sort();\n if (merged.length > 0)\n await writeAtomic(\n this.filePath(sessionId),\n `${JSON.stringify({ paths: merged }, null, 2)}\\n`,\n );\n await rm(this.claimPath(sessionId), { force: true });\n });\n await rm(`${this.filePath(sessionId)}.capture-lock`, { recursive: true, force: true });\n }\n\n private claimPath(sessionId: string): string {\n return `${this.filePath(sessionId)}.claimed`;\n }\n\n private async withFileLock<T>(sessionId: string, operation: () => Promise<T>): Promise<T> {\n const lock = `${this.filePath(sessionId)}.lock`;\n for (let attempt = 0; ; attempt++) {\n try {\n await mkdir(lock);\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\" || attempt >= 200) throw error;\n await new Promise((resolveWait) => setTimeout(resolveWait, 10));\n }\n }\n try {\n return await operation();\n } finally {\n await rm(lock, { recursive: true, force: true });\n }\n }\n\n private async serialize<T>(operation: () => Promise<T>): Promise<T> {\n const previous = this.operations;\n let release!: () => void;\n this.operations = new Promise<void>((resolveOperation) => {\n release = resolveOperation;\n });\n await previous;\n try {\n return await operation();\n } finally {\n release();\n }\n }\n\n private filePath(sessionId: string): string {\n const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, \"_\") || \"default\";\n return join(this.directory, `${safe}.json`);\n }\n}\n\nfunction normalize(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").trim();\n}\n\nfunction parsePaths(raw: string): string[] {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((path: unknown): path is string => typeof path === \"string\")\n : [];\n}\n","import { constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { extname, join, resolve } from \"node:path\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { PlanFileStore, type PlanSpec } from \"../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../core/plan-lifecycle.js\";\nimport { buildArchitectureMap } from \"../map/indexer.js\";\nimport type { ArchitectureMap } from \"../map/types.js\";\nimport { assessRisk, resolveRiskPaths } from \"../risk/service.js\";\nimport { readPolicyFile } from \"../risk/signals/policy.js\";\nimport { SEVERITY_RANK, type Suggestion, type SuggestResult } from \"./types.js\";\n\n/**\n * Deterministic, read-only suggestion generation. Nothing here writes to disk\n * or edits code — it only reads the working tree and CodeBuddy's own artifacts.\n * Each category attaches its own evidence; anything without evidence is not\n * emitted. Findings are de-duplicated per (category, path) and ranked by\n * severity so the few important ones surface first.\n */\n\nconst RISK_SUGGEST_THRESHOLD = 50;\nconst BLAST_RADIUS_MEDIUM = 5;\nconst BLAST_RADIUS_HIGH = 10;\nconst CODE_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"]);\n\nexport type SuggestInput = {\n repositoryRoot?: string;\n namespace: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n limit?: number;\n};\n\nexport async function generateSuggestions(input: SuggestInput): Promise<SuggestResult> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const namespace = input.namespace;\n\n const targetPaths = await resolveRiskPaths({\n repositoryRoot,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n });\n\n const planStore = new PlanFileStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n\n const [risks, plan, incidents, map, policyFile] = await Promise.all([\n assessRisk({\n repositoryRoot,\n namespace,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n }),\n resolveRelevantPlan(planStore, namespace, input.planId),\n memoryStore.findIncidentFactsForPaths({ namespace, paths: targetPaths }),\n buildArchitectureMap(repositoryRoot),\n readPolicyFile(join(repositoryRoot, \".codebuddy\", \"policies.yaml\")),\n ]);\n\n const suggestions: Suggestion[] = [];\n\n // 1. Risk — surface the change set's highest-scoring paths.\n for (const item of risks.items) {\n if (item.score < RISK_SUGGEST_THRESHOLD) continue;\n suggestions.push({\n id: `risk:${item.path}`,\n category: \"risk\",\n severity: item.score >= 75 ? \"high\" : \"medium\",\n title: `Review high-risk change to ${item.path}`,\n detail: item.reason,\n path: item.path,\n evidence: [\n { kind: \"risk_score\", detail: `score ${item.score} (${item.category})` },\n ...(item.evidence.length > 0\n ? [{ kind: \"risk_evidence\", detail: `${item.evidence.length} evidence item(s)` }]\n : []),\n ],\n commandHint: `codebuddy risk assess --paths ${item.path} --explain`,\n });\n }\n\n // 2. Incident history — files with an unresolved past incident.\n for (const incident of incidents) {\n const path = incident.paths[0] ?? \"(unknown)\";\n suggestions.push({\n id: `incident:${path}`,\n category: \"incident\",\n severity: \"high\",\n title: `Recurring incident hotspot: ${path}`,\n detail: `${incident.subject} — proceed carefully; this area has an unresolved incident.`,\n path,\n evidence: [{ kind: \"incident\", detail: `${incident.id} severity=${incident.severity}` }],\n });\n }\n\n // 3. Architecture — high blast radius (many dependents).\n const inbound = inboundDegrees(map);\n for (const path of targetPaths) {\n const dependents = inbound.get(path) ?? 0;\n if (dependents < BLAST_RADIUS_MEDIUM) continue;\n suggestions.push({\n id: `architecture:${path}`,\n category: \"architecture\",\n severity: dependents >= BLAST_RADIUS_HIGH ? \"high\" : \"medium\",\n title: `High blast radius: ${path}`,\n detail: `${dependents} module(s) import ${path}; a change here ripples widely.`,\n path,\n evidence: [{ kind: \"dependents\", detail: `${dependents} inbound import(s)` }],\n commandHint: `codebuddy map dependents ${path}`,\n });\n }\n\n // 4. Plan divergence — editing files the active plan does not cover.\n if (plan) {\n const planned = new Set(plan.filesToTouch.map((file) => normalize(file.path)));\n const strays = targetPaths.filter((path) => !planned.has(normalize(path)));\n if (planned.size > 0 && strays.length > 0) {\n suggestions.push({\n id: `plan_divergence:${plan.id}`,\n category: \"plan_divergence\",\n severity: \"medium\",\n title: `Change set diverges from plan ${plan.id}`,\n detail: `${strays.length} target file(s) are outside the active plan's scope: ${strays\n .slice(0, 5)\n .join(\", \")}.`,\n evidence: [\n { kind: \"plan\", detail: `plan ${plan.id} (${plan.status})` },\n { kind: \"out_of_scope\", detail: strays.slice(0, 5).join(\", \") },\n ],\n commandHint: `codebuddy plan show ${plan.id}`,\n });\n }\n }\n\n // 5. Missing tests — changed code files with no discoverable test.\n for (const path of targetPaths) {\n if (!isTestableCode(path)) continue;\n if (await hasSiblingTest(repositoryRoot, path)) continue;\n suggestions.push({\n id: `missing_test:${path}`,\n category: \"missing_test\",\n severity: \"low\",\n title: `No test found for ${path}`,\n detail: \"Consider adding a test alongside this change.\",\n path,\n evidence: [{ kind: \"no_test\", detail: \"no *.test.* / *.spec.* sibling found\" }],\n });\n }\n\n // 6. Stale policy — a rule whose target directory no longer exists.\n for (const rule of policyFile.rules) {\n const prefix = literalPrefix(rule.pattern);\n if (!prefix) continue;\n if (await pathExists(join(repositoryRoot, prefix))) continue;\n suggestions.push({\n id: `stale_policy:${rule.id}`,\n category: \"stale_policy\",\n severity: \"low\",\n title: `Stale policy rule \"${rule.id}\"`,\n detail: `Pattern \"${rule.pattern}\" targets \"${prefix}\", which does not exist.`,\n evidence: [{ kind: \"policy_rule\", detail: `${rule.id} → ${rule.pattern}` }],\n });\n }\n\n const deduped = dedupe(suggestions).sort(compareSuggestions);\n const limited = input.limit ? deduped.slice(0, input.limit) : deduped;\n\n return {\n suggestions: limited,\n stats: buildStats(targetPaths.length, limited),\n };\n}\n\n// ── helpers ─────────────────────────────────────────────────────────\n\nasync function resolveRelevantPlan(\n store: PlanFileStore,\n namespace: string,\n planId?: string,\n): Promise<PlanSpec | null> {\n if (planId) {\n try {\n return await store.readPlan(planId);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n }\n return new PlanLifecycle(store).current(namespace);\n}\n\nfunction inboundDegrees(map: ArchitectureMap): Map<string, number> {\n const inbound = new Map<string, number>();\n for (const edge of map.edges) inbound.set(edge.to, (inbound.get(edge.to) ?? 0) + 1);\n return inbound;\n}\n\nfunction isTestableCode(path: string): boolean {\n if (/\\.(test|spec)\\.[cm]?[jt]sx?$/.test(path)) return false;\n if (path.endsWith(\".d.ts\")) return false;\n if (path.includes(\"__tests__/\")) return false;\n return CODE_EXTENSIONS.has(extname(path).toLowerCase());\n}\n\nasync function hasSiblingTest(repositoryRoot: string, path: string): Promise<boolean> {\n const ext = extname(path);\n const base = path.slice(0, path.length - ext.length);\n const dir = base.includes(\"/\") ? base.slice(0, base.lastIndexOf(\"/\")) : \"\";\n const name = base.includes(\"/\") ? base.slice(base.lastIndexOf(\"/\") + 1) : base;\n const candidates = [\n `${base}.test${ext}`,\n `${base}.spec${ext}`,\n `${dir ? `${dir}/` : \"\"}__tests__/${name}${ext}`,\n `${dir ? `${dir}/` : \"\"}__tests__/${name}.test${ext}`,\n ];\n for (const candidate of candidates) {\n if (await pathExists(join(repositoryRoot, candidate))) return true;\n }\n return false;\n}\n\n/**\n * The literal directory prefix of a glob — everything before the first\n * wildcard, trimmed to a whole path segment. `src/auth/**` → `src/auth`,\n * `src/**/*.ts` → `src`, `*.env` → `` (no literal prefix to check).\n */\nfunction literalPrefix(pattern: string): string {\n const normalized = normalize(pattern);\n const wildcard = normalized.search(/[*?[]/);\n if (wildcard === -1) return normalized.replace(/\\/+$/, \"\");\n const beforeWildcard = normalized.slice(0, wildcard);\n const lastSlash = beforeWildcard.lastIndexOf(\"/\");\n return lastSlash === -1 ? \"\" : beforeWildcard.slice(0, lastSlash);\n}\n\nfunction dedupe(suggestions: Suggestion[]): Suggestion[] {\n const byId = new Map<string, Suggestion>();\n for (const suggestion of suggestions) {\n const existing = byId.get(suggestion.id);\n if (!existing || SEVERITY_RANK[suggestion.severity] > SEVERITY_RANK[existing.severity]) {\n byId.set(suggestion.id, suggestion);\n }\n }\n return [...byId.values()];\n}\n\nfunction compareSuggestions(left: Suggestion, right: Suggestion): number {\n const severity = SEVERITY_RANK[right.severity] - SEVERITY_RANK[left.severity];\n if (severity !== 0) return severity;\n if (left.category !== right.category) return left.category.localeCompare(right.category);\n return (left.path ?? \"\").localeCompare(right.path ?? \"\");\n}\n\nfunction buildStats(pathsConsidered: number, suggestions: Suggestion[]) {\n const byCategory: Record<string, number> = {};\n const bySeverity: Record<string, number> = {};\n for (const suggestion of suggestions) {\n byCategory[suggestion.category] = (byCategory[suggestion.category] ?? 0) + 1;\n bySeverity[suggestion.severity] = (bySeverity[suggestion.severity] ?? 0) + 1;\n }\n return { pathsConsidered, produced: suggestions.length, byCategory, bySeverity };\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction normalize(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n","/**\n * Suggestion model (Proposal 04 Phase 04.6). The suggestion engine reads the\n * signals CodeBuddy already computes — risk, the active plan, the architecture\n * map, incident memory — plus a couple of deterministic checks (missing tests,\n * stale policies) and turns them into a short list of evidence-backed, severity-\n * ranked suggestions. It is strictly read-only: it never edits code, and it\n * never emits a suggestion without evidence. The bias is a careful senior\n * reviewer, not a noisy linter — few strong findings over many weak ones.\n */\n\nexport const SUGGESTION_CATEGORIES = [\n \"risk\",\n \"plan_divergence\",\n \"architecture\",\n \"incident\",\n \"missing_test\",\n \"stale_policy\",\n] as const;\nexport type SuggestionCategory = (typeof SUGGESTION_CATEGORIES)[number];\n\nexport const SUGGESTION_SEVERITIES = [\"info\", \"low\", \"medium\", \"high\"] as const;\nexport type SuggestionSeverity = (typeof SUGGESTION_SEVERITIES)[number];\n\n/** Every suggestion cites at least one of these. No evidence, no suggestion. */\nexport type SuggestionEvidence = {\n kind: string;\n detail: string;\n};\n\nexport type Suggestion = {\n /** Stable id (`category:path`) so a UI can dedupe and track across runs. */\n id: string;\n category: SuggestionCategory;\n severity: SuggestionSeverity;\n title: string;\n detail: string;\n path?: string;\n evidence: SuggestionEvidence[];\n /** Optional follow-up command, e.g. `codebuddy risk assess --paths …`. */\n commandHint?: string;\n};\n\nexport type SuggestionStats = {\n pathsConsidered: number;\n produced: number;\n byCategory: Record<string, number>;\n bySeverity: Record<string, number>;\n};\n\nexport type SuggestResult = {\n suggestions: Suggestion[];\n stats: SuggestionStats;\n};\n\nexport const SEVERITY_RANK: Record<SuggestionSeverity, number> = {\n high: 3,\n medium: 2,\n low: 1,\n info: 0,\n};\n","/** Preserve compatibility by default; hosts forwarding both forms can select text. */\nexport function serializeToolResult(\n value: unknown,\n format = process.env.CODEBUDDY_RESPONSE_FORMAT ?? \"both\",\n) {\n if (format !== \"text\" && format !== \"both\") {\n throw new Error('CODEBUDDY_RESPONSE_FORMAT must be \"text\" or \"both\"');\n }\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(value) }],\n ...(format === \"both\" && value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? { structuredContent: value as Record<string, unknown> }\n : {}),\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport pino from \"pino\";\nimport { startProjectSync } from \"../automation/project-sync.js\";\nimport type { CodeBuddy } from \"../core/codebuddy.js\";\nimport { codeBuddyConfigSchema } from \"../core/config.js\";\nimport { loadRuntimeConfig } from \"../core/config-file.js\";\nimport { createRuntime } from \"../core/operations.js\";\nimport type { CodeBuddyConfig } from \"../core/types.js\";\nimport { VERSION } from \"../version.js\";\nimport { createLazyDatabase } from \"./database.js\";\nimport { registerCodeBuddyTools, resolveToolProfile } from \"./tools/index.js\";\n\nexport type StartMcpServerOptions = {\n config?: CodeBuddyConfig;\n};\n\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const logger = pino({ level: process.env.LOG_LEVEL ?? \"info\" }, process.stderr);\n const config =\n options.config ?? (await loadRuntimeConfig(process.cwd(), { requireDatabase: false }));\n // Invalid config is a startup error; a missing or unreachable database is not.\n (config.postgresUrl\n ? codeBuddyConfigSchema\n : codeBuddyConfigSchema.omit({ postgresUrl: true })\n ).parse(config);\n const toolProfile = resolveToolProfile();\n const projectRoot = config.projectRoot ?? process.env.CODEBUDDY_PROJECT_ROOT ?? process.cwd();\n // PostgreSQL is optional: file-based tools are served immediately and the\n // database tools report a degraded result until a connection succeeds.\n // A failed or partial memory import must not hide the healthy file-only\n // context, so it is logged, never thrown.\n const importMemory = async (memory: CodeBuddy) => {\n try {\n const result = await memory.reindexMemory();\n for (const failure of result.failures) {\n logger.error(`[sync] memory file skipped (${failure.id}): ${failure.error}`);\n }\n } catch (error) {\n logger.error(`[sync] Markdown memory import failed: ${(error as Error).message}`);\n }\n };\n const database = createLazyDatabase(async () => {\n try {\n const runtime = await createRuntime(config, { autoBootstrap: true });\n await importMemory(runtime.memory);\n logger.info(\"PostgreSQL connected; memory tools available\");\n return runtime;\n } catch (error) {\n logger.warn(\n `PostgreSQL unavailable; serving file-based tools only: ${(error as Error).message}`,\n );\n throw error;\n }\n });\n void database.get().catch(() => undefined);\n const sync = startProjectSync({\n repositoryRoot: projectRoot,\n ...(config.graphify ? { graphify: config.graphify } : {}),\n logger,\n // Hand edits re-import live once PostgreSQL is connected; until then the\n // next successful connect imports everything.\n onMemoryChange: async () => {\n if (database.status().state === \"ready\") await importMemory((await database.get()).memory);\n },\n });\n const server = new McpServer({ name: \"codebuddy\", version: VERSION });\n registerCodeBuddyTools(server, { config, database }, toolProfile);\n\n const shutdown = async () => {\n logger.info(\"codebuddy MCP server shutting down\");\n await server.close();\n await sync.close();\n await database.close();\n };\n let stopping: Promise<void> | undefined;\n const stop = () => {\n stopping ??= shutdown().finally(() => process.exit(0));\n };\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n // EOF on stdin means the client is gone; without this the server outlives it.\n process.stdin.once(\"end\", stop);\n\n try {\n await sync.ready;\n await server.connect(new StdioServerTransport());\n } catch (error) {\n await sync.close();\n await database.close();\n throw error;\n }\n logger.info(`codebuddy MCP server started over stdio (tool profile: ${toolProfile})`);\n}\n","import { type FSWatcher, watch as fsWatch } from \"node:fs\";\nimport { join, relative, resolve, sep } from \"node:path\";\nimport { indexRepository } from \"../indexer/engine.js\";\nimport { createCoalescer, watchRepository } from \"../indexer/watch.js\";\nimport { generateGraphifyGraph } from \"../integrations/graphify.js\";\nimport { refreshZvecIndex, type ZvecRefresh } from \"../retrieval/zvec.js\";\n\nexport type ProjectSyncOptions = {\n repositoryRoot: string;\n graphify?: { enabled: boolean; graphPath?: string | undefined };\n logger?: Pick<Console, \"info\" | \"error\">;\n /**\n * Called (coalesced) when a managed Markdown memory file changes. The owner\n * of the database runtime re-imports memory; sync itself never needs it.\n */\n onMemoryChange?: () => Promise<void>;\n};\n\nexport type ProjectSyncHandle = {\n ready: Promise<void>;\n close(): Promise<void>;\n};\n\n/**\n * Owns all derived project state. A running MCP server should never require a\n * user or an agent to remember `index`, `graphify`, or `reindex` commands.\n */\nexport function startProjectSync(options: ProjectSyncOptions): ProjectSyncHandle {\n const repositoryRoot = resolve(options.repositoryRoot);\n const logger = options.logger ?? console;\n const controller = new AbortController();\n let watcher: Promise<void> | null = null;\n let closing = false;\n let memoryWatcher: FSWatcher | null = null;\n let memoryRefresh: ReturnType<typeof createCoalescer> | null = null;\n\n /** Run a derived-state refresh in the background, coalescing overlapping requests. */\n const backgroundRefresh = (task: () => Promise<void>) => {\n let current: Promise<void> | null = null;\n let pending = false;\n const schedule = () => {\n if (closing) return;\n if (current) {\n pending = true;\n return;\n }\n current = (async () => {\n do {\n pending = false;\n await task();\n } while (pending && !closing);\n })().finally(() => {\n current = null;\n if (pending && !closing) schedule();\n });\n };\n return { schedule, settled: async () => current?.catch(() => undefined) };\n };\n\n const graphRefresh = backgroundRefresh(() =>\n refreshGraph().catch((error) =>\n logger.error(`[sync] Graphify refresh failed: ${(error as Error).message}`),\n ),\n );\n // Queries never refresh zg on the prompt path (`--refresh off`); this keeps\n // the zg index incrementally current instead, and is a no-op unless enabled.\n // Closing aborts a running `zg index` rather than waiting it out.\n const zvecRefresh = backgroundRefresh(async () => {\n const result = await refreshZvecIndex(repositoryRoot, { signal: controller.signal }).catch(\n (error): ZvecRefresh => ({\n status: \"failed\",\n reason: (error as Error).message,\n }),\n );\n if (result.status !== \"disabled\") logger.info(`[sync] ${result.reason}`);\n });\n\n const ready = (async () => {\n // The index is the useful fallback if Graphify is unavailable in a\n // pre-made repository. Markdown memory is imported by the database\n // runtime when (and whenever) PostgreSQL connects.\n await indexRepository({ repositoryRoot });\n zvecRefresh.schedule();\n watchMemory();\n if (options.graphify?.enabled) {\n await refreshGraph().catch((error) =>\n logger.error(`[sync] Graphify startup refresh failed: ${(error as Error).message}`),\n );\n }\n\n watcher = watchRepository({\n repositoryRoot,\n signal: controller.signal,\n ...(options.graphify?.enabled\n ? {\n ignoredPaths: [\n options.graphify.graphPath\n ? relative(repositoryRoot, resolve(repositoryRoot, options.graphify.graphPath))\n .split(sep)\n .join(\"/\")\n : \"graphify-out\",\n ],\n }\n : {}),\n onIndex: (result) => {\n if (result.added + result.changed + result.removed === 0) return;\n zvecRefresh.schedule();\n if (options.graphify?.enabled) graphRefresh.schedule();\n },\n onError: (error) => logger.error(`[sync] repository watch failed: ${error.message}`),\n });\n // watchRepository performs its own initial index. It is intentionally\n // detached after the awaited startup pass so MCP can accept requests.\n // A platform without recursive fs.watch still gets a healthy MCP server\n // and the completed startup index.\n void watcher.catch((error) =>\n logger.error(`[sync] live repository watch unavailable: ${(error as Error).message}`),\n );\n })().catch((error) => {\n logger.error(`[sync] startup synchronization failed: ${(error as Error).message}`);\n throw error;\n });\n\n // The repository watcher ignores `.codebuddy/`; Markdown memory is the\n // source of truth, so hand edits and deletions are re-imported live.\n function watchMemory(): void {\n const onMemoryChange = options.onMemoryChange;\n if (closing || !onMemoryChange) return;\n try {\n memoryRefresh = createCoalescer(\n () =>\n onMemoryChange().catch((error) =>\n logger.error(`[sync] memory reindex failed: ${(error as Error).message}`),\n ),\n 300,\n );\n memoryWatcher = fsWatch(\n join(repositoryRoot, \".codebuddy\", \"memory\"),\n { recursive: true },\n (_event, filename) => {\n const name = filename?.replace(/\\\\/g, \"/\") ?? \"\";\n if (/^(facts\\/fact|summaries\\/sum)_[a-z0-9]+\\.md$/.test(name)) memoryRefresh?.trigger();\n },\n );\n memoryWatcher.on(\"error\", () => memoryWatcher?.close());\n } catch (error) {\n logger.error(`[sync] live memory watch unavailable: ${(error as Error).message}`);\n }\n }\n\n async function refreshGraph(): Promise<void> {\n const result = await generateGraphifyGraph({\n repositoryRoot,\n ...(options.graphify?.graphPath ? { graphPath: options.graphify.graphPath } : {}),\n });\n logger.info(`[sync] Graphify updated (${result.nodes} nodes, ${result.edges} edges)`);\n }\n\n return {\n ready,\n async close() {\n closing = true;\n controller.abort();\n memoryRefresh?.stop();\n memoryWatcher?.close();\n await watcher?.catch(() => undefined);\n await Promise.all([graphRefresh.settled(), zvecRefresh.settled()]);\n },\n };\n}\n","import { watch as fsWatch } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { type IndexOptions, indexRepository } from \"./engine.js\";\nimport type { IndexResult } from \"./types.js\";\n\n/**\n * `codebuddy watch` is an explicit, foreground incremental indexer — not a\n * hidden daemon (Proposal 04.3 non-goal). It coalesces bursts of file-save\n * events into a single index pass so a formatter rewriting fifty files triggers\n * one refresh, not fifty.\n */\n\nconst DEFAULT_DEBOUNCE_MS = 300;\n\n/**\n * A trailing debouncer: `trigger()` schedules `fn` to run after `delayMs` of\n * quiet, collapsing any calls made in that window into one. Runs are\n * serialized. A trigger marks the work dirty; a run clears the mark when it\n * starts, so an event that lands while a pass is in flight is never lost — the\n * pass reschedules itself when it settles. `stop()` cancels pending work and\n * resolves once any in-flight pass has finished. Exposed on its own so the\n * coalescing logic is testable without touching the filesystem.\n */\nexport function createCoalescer(\n fn: () => Promise<void>,\n delayMs: number,\n): { trigger: () => void; stop: () => Promise<void> } {\n let timer: NodeJS.Timeout | null = null;\n let running: Promise<void> | null = null;\n let dirty = false;\n let stopped = false;\n // Trailing debounce alone starves under sustained event streams (every new\n // event resets the window). maxWait forces a run this long after the FIRST\n // deferred trigger, so continuous activity still indexes eventually.\n let firstTriggerAt: number | null = null;\n let maxWaitTimer: NodeJS.Timeout | null = null;\n\n const clearTimers = () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n if (maxWaitTimer) {\n clearTimeout(maxWaitTimer);\n maxWaitTimer = null;\n }\n firstTriggerAt = null;\n };\n\n const run = () => {\n // A busy run keeps `dirty` set; its settle step reschedules.\n if (stopped || running) return;\n clearTimers();\n dirty = false;\n running = (async () => {\n try {\n await fn();\n } finally {\n running = null;\n if (dirty) schedule();\n }\n })();\n };\n\n const schedule = () => {\n if (stopped) return;\n dirty = true;\n if (firstTriggerAt === null) {\n firstTriggerAt = Date.now();\n maxWaitTimer = setTimeout(run, MAX_WAIT_MS);\n }\n if (timer) clearTimeout(timer);\n timer = setTimeout(run, delayMs);\n };\n\n return {\n trigger: schedule,\n stop: async () => {\n stopped = true;\n clearTimers();\n await running?.catch(() => undefined);\n },\n };\n}\n\n/** Hard ceiling on how long a burst of events can defer a run. */\nconst MAX_WAIT_MS = 5_000;\n\nexport type WatchOptions = IndexOptions & {\n debounceMs?: number;\n ignoredPaths?: string[];\n onIndex?: (result: IndexResult) => void;\n onError?: (error: Error) => void;\n /** Abort to stop the watcher (e.g. wired to SIGINT). */\n signal?: AbortSignal;\n};\n\n/** Ignore churn we cause ourselves or that git would ignore. */\nexport function isIgnoredEvent(filename: string | null, ignoredPaths: string[] = []): boolean {\n if (!filename) return false;\n const normalized = filename.replace(/\\\\/g, \"/\");\n return (\n ignoredPaths.some((path) => normalized === path || normalized.startsWith(`${path}/`)) ||\n normalized.startsWith(\".codebuddy/\") ||\n normalized.includes(\"/.git/\") ||\n normalized.startsWith(\".git/\") ||\n normalized.includes(\"/node_modules/\") ||\n normalized.startsWith(\"node_modules/\") ||\n normalized.endsWith(\".tmp\")\n );\n}\n\n/**\n * Watch `repositoryRoot` recursively and run an incremental index on change.\n * Resolves when the signal aborts. Does an initial index pass on start so the\n * manifest is fresh before the first edit.\n */\nexport async function watchRepository(options: WatchOptions = {}): Promise<void> {\n const repositoryRoot = resolve(options.repositoryRoot ?? process.cwd());\n const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n\n const runIndex = async () => {\n try {\n const result = await indexRepository({\n repositoryRoot,\n ...(options.now ? { now: options.now } : {}),\n });\n options.onIndex?.(result);\n } catch (error) {\n options.onError?.(error as Error);\n }\n };\n\n await runIndex();\n\n const coalescer = createCoalescer(runIndex, debounceMs);\n const watcher = fsWatch(repositoryRoot, { recursive: true }, (_event, filename) => {\n if (isIgnoredEvent(filename, options.ignoredPaths)) return;\n coalescer.trigger();\n });\n\n return new Promise<void>((resolvePromise) => {\n const stop = () => {\n watcher.close();\n // Resolve only after an in-flight pass settles, so callers that stop the\n // watcher never race a manifest write.\n void coalescer.stop().then(() => resolvePromise());\n };\n if (options.signal) {\n if (options.signal.aborted) return stop();\n options.signal.addEventListener(\"abort\", stop, { once: true });\n }\n watcher.on(\"error\", () => stop());\n });\n}\n","import type { CodeBuddy } from \"../core/codebuddy.js\";\nimport { redactSecrets } from \"../core/config-file.js\";\nimport type { RuntimeHandle } from \"../core/operations.js\";\nimport type { MemoryRepository } from \"../core/repository.js\";\n\nexport type DatabaseServices = { memory: CodeBuddy; repository: MemoryRepository };\n\nexport type DatabaseStatus = {\n available: boolean;\n state: \"idle\" | \"connecting\" | \"ready\" | \"unavailable\";\n error?: string;\n retryInMs?: number;\n};\n\nexport type LazyDatabase = {\n /** Resolve the runtime, connecting (or retrying after the cooldown) on demand. */\n get(): Promise<DatabaseServices>;\n status(): DatabaseStatus;\n close(): Promise<void>;\n};\n\n/**\n * Owns the optional PostgreSQL runtime for the MCP server so file-based tools\n * never wait on it. One connection attempt runs at a time; a failure is cached\n * for `retryMs` so database tools answer fast while Postgres is down, and the\n * first call after the cooldown retries. Once connected, the runtime (and its\n * embedding worker) is created exactly once.\n */\nexport function createLazyDatabase(\n connect: () => Promise<RuntimeHandle>,\n options: { retryMs?: number } = {},\n): LazyDatabase {\n const retryMs = options.retryMs ?? 5_000;\n let runtime: RuntimeHandle | undefined;\n let pending: Promise<RuntimeHandle> | undefined;\n let failure: { error: string; at: number } | undefined;\n let closed = false;\n\n return {\n get() {\n if (runtime) return Promise.resolve(runtime);\n if (closed) return Promise.reject(new Error(\"CodeBuddy MCP server is shutting down.\"));\n if (pending) return pending;\n if (failure && Date.now() - failure.at < retryMs) {\n return Promise.reject(new Error(failure.error));\n }\n pending = connect()\n .then(\n async (handle) => {\n if (closed) {\n await handle.close();\n throw new Error(\"CodeBuddy MCP server is shutting down.\");\n }\n runtime = handle;\n failure = undefined;\n return handle;\n },\n (error: unknown) => {\n failure = { error: describeError(error), at: Date.now() };\n throw error;\n },\n )\n .finally(() => {\n pending = undefined;\n });\n return pending;\n },\n status() {\n if (runtime) return { available: true, state: \"ready\" };\n if (pending) return { available: false, state: \"connecting\" };\n if (!failure) return { available: false, state: \"idle\" };\n return {\n available: false,\n state: \"unavailable\",\n error: failure.error,\n retryInMs: Math.max(0, failure.at + retryMs - Date.now()),\n };\n },\n async close() {\n closed = true;\n await pending?.catch(() => undefined);\n const current = runtime;\n runtime = undefined;\n await current?.close();\n },\n };\n}\n\n/** Bounded, credential-free error text (connection errors can echo the URL). */\nfunction describeError(error: unknown): string {\n const err = error as { message?: string; code?: string } | undefined;\n const text = err?.message || err?.code || String(error);\n return String(redactSecrets(text)).slice(0, 300);\n}\n"],"mappings":"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","names":["vector","vector","interactions","index","queue","resolve","vector","facts","resolve","vector","pTimeout","z","pTimeout","vector","facts","id","result","facts","sql","sql","sql","dirname","resolve","createHash","sql","sql","vector","index","createHash","createdAt","facts","mkdir","readdir","readFile","rm","dirname","join","relative","resolve","sep","parseYaml","stringifyYaml","z","z","resolve","join","dirname","stringifyYaml","readFile","parseYaml","readdir","rm","relative","sep","mkdir","stat","resolve","index","readFile","join","parseYaml","z","spawn","relative","resolve","sep","resolve","normalizePath","relative","sep","runGit","spawn","z","createHash","createHash","readFile","join","resolve","createHash","mkdir","readdir","readFile","stat","dirname","join","relative","resolve","sep","parseYaml","stringifyYaml","z","REDACTED","z","resolve","join","normalizePath","createHash","dirname","mkdir","stringifyYaml","readFile","parseYaml","readdir","createdAt","relative","sep","stat","text","LIMITS","resolve","fresh","facts","join","neighbours","hit","text","readFile","readFile","relative","resolve","sep","createHash","resolve","z","z","text","incident","index","mkdir","readdir","readFile","rm","dirname","join","relative","resolve","sep","parseYaml","stringifyYaml","z","z","resolve","join","dirname","stringifyYaml","readFile","parseYaml","readdir","rm","mkdir","relative","sep","text","words","resolve","ref","createHash","mkdir","readFile","rename","rm","stat","join","resolve","join","resolve","normalize","mkdir","readFile","rename","rm","stat","resolve","text","relative","sep","readFile","index","join","resolve","resolve","resolveRelevantPlan","join","normalize","z","plannedFileSchema","plannedTestSchema","config","fsWatch","join","relative","resolve","sep","resolve","resolve","resolve","relative","sep","fsWatch","join","describeError","text"]}
|