valija 0.1.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/delivery/cli/program.ts","../src/delivery/container.ts","../src/shared/domain/result.ts","../src/context/domain/errors.ts","../src/context/domain/values/project-name.ts","../src/context/application/export-pack.ts","../src/context/application/get-context-pack.ts","../src/context/application/list-projects.ts","../src/context/domain/entities/context-item.ts","../src/context/domain/values/item-type.ts","../src/context/domain/values/tag.ts","../src/context/application/save-context.ts","../src/context/application/search-context.ts","../src/context/application/show-project.ts","../src/shared/infra/migrations/001-init.ts","../src/shared/infra/migrations.ts","../src/shared/infra/sqlite.ts","../src/vault/domain/errors.ts","../src/vault/infra/vault-header.ts","../src/context/infra/item-repo.ts","../src/context/infra/project-repo.ts","../src/context/infra/session-factory.ts","../src/shared/infra/vault-paths.ts","../src/vault/application/hex.ts","../src/vault/application/ports/crypto.ts","../src/vault/application/create-vault.ts","../src/vault/application/lock-vault.ts","../src/vault/application/unlock-vault.ts","../src/vault/application/vault-status.ts","../src/vault/infra/argon2.ts","../src/vault/infra/file-vault-store.ts","../src/vault/infra/keyring.ts","../src/delivery/mcp/server.ts","../src/delivery/version.ts","../src/delivery/cli/content-commands.ts","../src/delivery/cli/render.ts","../src/delivery/cli/doctor.ts","../src/delivery/cli/installer.ts","../src/vault/infra/recovery-kit.ts","../src/delivery/cli/prompt.ts","../src/delivery/cli/vault-commands.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { buildContainer } from \"../container.js\";\nimport { runMcpServer } from \"../mcp/server.js\";\nimport { VERSION } from \"../version.js\";\nimport { exportCommand, projectsCommand, searchCommand, showCommand } from \"./content-commands.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { CLIENTS, type ClientId, installIntoClient, manualInstructions } from \"./installer.js\";\nimport { initCommand, lockCommand, statusCommand, unlockCommand } from \"./vault-commands.js\";\n\nconst program = new Command();\nconst container = buildContainer();\n\nprogram\n .name(\"valija\")\n .description(\"Encrypted context vault for developers who use several AI tools.\")\n .version(VERSION);\n\nprogram\n .command(\"init\")\n .description(\"Create the encrypted vault (passphrase + recovery kit).\")\n .action(() => initCommand(container));\n\nprogram\n .command(\"unlock\")\n .description(\"Unlock the vault for this session (key goes to the OS keychain).\")\n .option(\"--recovery-key <hex>\", \"unlock with the raw key from your recovery kit\")\n .action((options: { recoveryKey?: string }) => unlockCommand(container, options));\n\nprogram\n .command(\"lock\")\n .description(\"Lock the vault (remove the key from the OS keychain).\")\n .action(() => lockCommand(container));\n\nprogram\n .command(\"status\")\n .description(\"Show vault location and lock state.\")\n .action(() => statusCommand(container));\n\nprogram\n .command(\"projects\")\n .description(\"List projects with item counts and last activity.\")\n .action(() => projectsCommand(container));\n\nprogram\n .command(\"show\")\n .description(\"Print the items of a project.\")\n .argument(\"<project>\", \"project slug\")\n .option(\"--type <type>\", \"filter by type (decision|progress|preference|fact|handoff)\")\n .action((project: string, options: { type?: string }) =>\n showCommand(container, project, options),\n );\n\nprogram\n .command(\"search\")\n .description(\"Full-text search across saved context.\")\n .argument(\"<query>\", \"search terms\")\n .option(\"-p, --project <project>\", \"limit to one project\")\n .action((query: string, options: { project?: string }) =>\n searchCommand(container, query, options),\n );\n\nprogram\n .command(\"export\")\n .description(\"Export a project's context pack (markdown by default).\")\n .argument(\"<project>\", \"project slug\")\n .option(\"--json\", \"export as JSON instead of markdown\")\n .option(\"-o, --output <file>\", \"write to a file instead of stdout\")\n .action((project: string, options: { json?: boolean; output?: string }) =>\n exportCommand(container, project, options),\n );\n\nprogram\n .command(\"install\")\n .description(\"Wire the valija MCP server into an AI tool's config.\")\n .argument(\"<client>\", `one of: ${CLIENTS.join(\", \")}`)\n .action((client: string) => {\n if (!(CLIENTS as readonly string[]).includes(client)) {\n console.error(`error: unknown client \"${client}\". Use one of: ${CLIENTS.join(\", \")}`);\n process.exit(1);\n }\n try {\n const result = installIntoClient(client as ClientId);\n console.log(`valija MCP server added to ${result.configPath}`);\n if (result.backupPath) console.log(`Backup of the previous config: ${result.backupPath}`);\n console.log(`Restart ${client} to pick it up.`);\n } catch (e) {\n console.error(`Could not update the config automatically: ${(e as Error).message}\\n`);\n console.error(manualInstructions(client as ClientId));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"mcp\")\n .description(\"Run the MCP server on stdio (used by AI tools, not by humans).\")\n .action(async () => {\n await runMcpServer(container);\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Check environment, vault, keychain, and client configs.\")\n .action(() => doctorCommand(container));\n\nprogram.parseAsync().catch((error: unknown) => {\n console.error(`error: ${(error as Error).message}`);\n process.exit(1);\n});\n","import { ulid } from \"ulid\";\nimport { ExportPack } from \"../context/application/export-pack.js\";\nimport { GetContextPack } from \"../context/application/get-context-pack.js\";\nimport { ListProjects } from \"../context/application/list-projects.js\";\nimport { SaveContext } from \"../context/application/save-context.js\";\nimport { SearchContext } from \"../context/application/search-context.js\";\nimport { ShowProject } from \"../context/application/show-project.js\";\nimport { SqliteVaultSessionFactory } from \"../context/infra/session-factory.js\";\nimport type { Clock, IdGenerator } from \"../shared/application/ports/clock.js\";\nimport { resolveVaultPaths, type VaultPaths } from \"../shared/infra/vault-paths.js\";\nimport { CreateVault } from \"../vault/application/create-vault.js\";\nimport { LockVault } from \"../vault/application/lock-vault.js\";\nimport { UnlockVault } from \"../vault/application/unlock-vault.js\";\nimport { VaultStatus } from \"../vault/application/vault-status.js\";\nimport { Argon2VaultCrypto } from \"../vault/infra/argon2.js\";\nimport { FileVaultStore } from \"../vault/infra/file-vault-store.js\";\nimport { OsKeychain } from \"../vault/infra/keyring.js\";\n\nconst systemClock: Clock = { now: () => new Date() };\nconst ulidIds: IdGenerator = { next: () => ulid() };\n\nexport interface Container {\n paths: VaultPaths;\n createVault: CreateVault;\n unlockVault: UnlockVault;\n lockVault: LockVault;\n vaultStatus: VaultStatus;\n saveContext: SaveContext;\n listProjects: ListProjects;\n searchContext: SearchContext;\n getContextPack: GetContextPack;\n exportPack: ExportPack;\n showProject: ShowProject;\n}\n\nexport function buildContainer(): Container {\n const paths = resolveVaultPaths();\n const store = new FileVaultStore(paths);\n const crypto = new Argon2VaultCrypto();\n const keychain = new OsKeychain();\n const sessions = new SqliteVaultSessionFactory(paths, keychain);\n const getContextPack = new GetContextPack(sessions, systemClock);\n return {\n paths,\n createVault: new CreateVault(store, crypto, keychain, systemClock, ulidIds),\n unlockVault: new UnlockVault(store, crypto, keychain),\n lockVault: new LockVault(store, keychain),\n vaultStatus: new VaultStatus(store, keychain),\n saveContext: new SaveContext(sessions, systemClock, ulidIds),\n listProjects: new ListProjects(sessions),\n searchContext: new SearchContext(sessions),\n getContextPack,\n exportPack: new ExportPack(sessions, getContextPack),\n showProject: new ShowProject(sessions),\n };\n}\n","export type Result<T, E = DomainError> = { ok: true; value: T } | { ok: false; error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\n/**\n * Base error shared by every module. Each bounded context narrows `code`\n * through its own constructor (vaultErr / contextErr).\n */\nexport class DomainError extends Error {\n constructor(\n readonly code: string,\n message: string,\n ) {\n super(message);\n this.name = \"DomainError\";\n }\n}\n","import { DomainError, err, type Result } from \"../../shared/domain/result.js\";\n\n/** Error vocabulary of the CONTEXT bounded context (content language). */\nexport type ContextErrorCode =\n | \"INVALID_PROJECT_NAME\"\n | \"INVALID_ITEM_TYPE\"\n | \"INVALID_TAG\"\n | \"CONTENT_TOO_LARGE\"\n | \"CONTENT_EMPTY\"\n | \"TOO_MANY_TAGS\"\n | \"PROJECT_NOT_FOUND\"\n | \"ITEM_NOT_FOUND\";\n\nexport const contextErr = (code: ContextErrorCode, message: string): Result<never, DomainError> =>\n err(new DomainError(code, message));\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nconst PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;\n\n/** Unique project slug: 1-64 chars, lowercase letters, digits, hyphens (not leading). */\nexport type ProjectName = string & { readonly __brand: \"ProjectName\" };\n\nexport function parseProjectName(raw: string): Result<ProjectName, DomainError> {\n const normalized = raw.trim().toLowerCase();\n if (!PATTERN.test(normalized)) {\n return contextErr(\n \"INVALID_PROJECT_NAME\",\n `Project name must be 1-64 chars of [a-z0-9-], starting with a letter or digit. Got: \"${raw}\"`,\n );\n }\n return ok(normalized as ProjectName);\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { contextErr } from \"../domain/errors.js\";\nimport { parseProjectName } from \"../domain/values/project-name.js\";\nimport type { GetContextPack } from \"./get-context-pack.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\n\nexport type ExportFormat = \"md\" | \"json\";\n\nexport class ExportPack {\n constructor(\n private readonly sessions: VaultSessionFactory,\n private readonly getContextPack: GetContextPack,\n ) {}\n\n execute(project: string, format: ExportFormat): Result<string, DomainError> {\n if (format === \"md\") {\n // Export is the everything-escape-hatch: no budget.\n const pack = this.getContextPack.execute({ project, budgetTokens: Number.MAX_SAFE_INTEGER });\n return pack.ok ? ok(pack.value.markdown) : pack;\n }\n\n const name = parseProjectName(project);\n if (!name.ok) return name;\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n const found = session.value.projects.findByName(name.value);\n if (found === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n const items = session.value.items.findByProject(found.id).map((item) => ({\n id: item.id,\n type: item.type,\n content: item.content,\n tags: item.tags,\n pinned: item.pinned,\n source: item.source ?? null,\n createdAt: item.createdAt.toISOString(),\n }));\n return ok(JSON.stringify({ project: name.value, items }, null, 2));\n } finally {\n session.value.close();\n }\n }\n}\n","import type { Clock } from \"../../shared/application/ports/clock.js\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { ContextItem } from \"../domain/entities/context-item.js\";\nimport { contextErr } from \"../domain/errors.js\";\nimport { parseProjectName } from \"../domain/values/project-name.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\n\nexport const DEFAULT_BUDGET_TOKENS = 4000;\n\n/** Cheap token estimate: ~4 chars per token. Good enough for a budget, no tokenizer dep. */\nexport const estimateTokens = (text: string): number => Math.ceil(text.length / 4);\n\nconst SECTION_ORDER = [\"decision\", \"preference\", \"progress\", \"fact\"] as const;\n\nconst SECTION_LABELS: Record<(typeof SECTION_ORDER)[number], string> = {\n decision: \"Decisions\",\n preference: \"Preferences\",\n progress: \"Progress\",\n fact: \"Facts\",\n};\n\nexport interface GetContextPackInput {\n project: string;\n budgetTokens?: number;\n}\n\nexport interface ContextPack {\n markdown: string;\n includedCount: number;\n totalCount: number;\n estimatedTokens: number;\n}\n\nconst renderItem = (item: ContextItem): string => {\n const date = item.createdAt.toISOString().slice(0, 10);\n const tags = item.tags.length > 0 ? ` · ${item.tags.map((t) => `#${t}`).join(\" \")}` : \"\";\n return `### ${item.type} · ${date}${tags}\\n\\n${item.content}\\n`;\n};\n\nexport class GetContextPack {\n constructor(\n private readonly sessions: VaultSessionFactory,\n private readonly clock: Clock,\n ) {}\n\n execute(input: GetContextPackInput): Result<ContextPack, DomainError> {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n const budget = input.budgetTokens ?? DEFAULT_BUDGET_TOKENS;\n\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n const project = session.value.projects.findByName(name.value);\n if (project === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n // Newest first, archived excluded — repository contract.\n const all = session.value.items.findByProject(project.id);\n const included = new Set<string>();\n const parts: string[] = [];\n let used = 0;\n\n const header =\n `# Context pack: ${name.value}\\n\\n` +\n `> ${all.length} items in vault · generated ${this.clock.now().toISOString()}\\n`;\n used += estimateTokens(header);\n\n // 1. Pinned: all included, newest first; if they alone bust the budget,\n // the oldest pinned are cut first — but never the newest one.\n const pinned = all.filter((i) => i.pinned);\n const pinnedKept: ContextItem[] = [];\n for (const item of pinned) {\n const cost = estimateTokens(renderItem(item));\n if (pinnedKept.length > 0 && used + cost > budget) break;\n pinnedKept.push(item);\n used += cost;\n }\n if (pinnedKept.length > 0) {\n parts.push(\"\\n## Pinned\\n\");\n for (const item of pinnedKept) {\n parts.push(renderItem(item));\n included.add(item.id);\n }\n }\n\n // 2. Latest handoff, if it fits.\n const handoff = all.find((i) => i.type === \"handoff\" && !included.has(i.id));\n if (handoff) {\n const rendered = renderItem(handoff);\n const cost = estimateTokens(rendered);\n if (used + cost <= budget) {\n parts.push(\"\\n## Latest handoff\\n\", rendered);\n included.add(handoff.id);\n used += cost;\n }\n }\n\n // 3. Recent items by type, in section order, newest first, until the budget is reached.\n for (const type of SECTION_ORDER) {\n const items = all.filter((i) => i.type === type && !included.has(i.id));\n let sectionOpened = false;\n for (const item of items) {\n const rendered = renderItem(item);\n const sectionHeader = sectionOpened ? \"\" : `\\n## ${SECTION_LABELS[type]}\\n`;\n const cost = estimateTokens(sectionHeader + rendered);\n if (used + cost > budget) break;\n if (!sectionOpened) {\n parts.push(sectionHeader);\n sectionOpened = true;\n }\n parts.push(rendered);\n included.add(item.id);\n used += cost;\n }\n }\n\n const markdown = header + parts.join(\"\\n\");\n return ok({\n markdown,\n includedCount: included.size,\n totalCount: all.length,\n estimatedTokens: estimateTokens(markdown),\n });\n } finally {\n session.value.close();\n }\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\n\nexport interface ProjectListEntry {\n name: string;\n description?: string;\n itemCount: number;\n lastActivityAt: string | null;\n}\n\nexport class ListProjects {\n constructor(private readonly sessions: VaultSessionFactory) {}\n\n execute(): Result<ProjectListEntry[], DomainError> {\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n const entries = session.value.projects.list().map((summary) => ({\n name: summary.project.name as string,\n ...(summary.project.description === undefined\n ? {}\n : { description: summary.project.description }),\n itemCount: summary.itemCount,\n lastActivityAt: summary.lastActivityAt?.toISOString() ?? null,\n }));\n return ok(entries);\n } finally {\n session.value.close();\n }\n }\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\nimport type { ItemType } from \"../values/item-type.js\";\nimport type { Tag } from \"../values/tag.js\";\n\nexport const MAX_CONTENT_BYTES = 32 * 1024;\n\nexport interface ContextItem {\n readonly id: string;\n readonly projectId: string;\n readonly type: ItemType;\n readonly content: string;\n readonly tags: readonly Tag[];\n readonly pinned: boolean;\n readonly source?: string;\n readonly archived: boolean;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport function validateContent(content: string): Result<string, DomainError> {\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return contextErr(\"CONTENT_EMPTY\", \"Content must not be empty.\");\n }\n const bytes = new TextEncoder().encode(trimmed).length;\n if (bytes > MAX_CONTENT_BYTES) {\n return contextErr(\n \"CONTENT_TOO_LARGE\",\n `Content is ${bytes} bytes; the maximum is ${MAX_CONTENT_BYTES} (32 KB). Distill it.`,\n );\n }\n return ok(trimmed);\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nexport const ITEM_TYPES = [\"decision\", \"progress\", \"preference\", \"fact\", \"handoff\"] as const;\n\nexport type ItemType = (typeof ITEM_TYPES)[number];\n\nexport function parseItemType(raw: string): Result<ItemType, DomainError> {\n if ((ITEM_TYPES as readonly string[]).includes(raw)) {\n return ok(raw as ItemType);\n }\n return contextErr(\n \"INVALID_ITEM_TYPE\",\n `Item type must be one of ${ITEM_TYPES.join(\", \")}. Got: \"${raw}\"`,\n );\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nconst PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;\n\nexport const MAX_TAGS = 10;\n\n/** Lowercase tag: 1-32 chars of [a-z0-9-]. */\nexport type Tag = string & { readonly __brand: \"Tag\" };\n\nexport function parseTag(raw: string): Result<Tag, DomainError> {\n const normalized = raw.trim().toLowerCase();\n if (!PATTERN.test(normalized)) {\n return contextErr(\"INVALID_TAG\", `Tag must be 1-32 chars of [a-z0-9-]. Got: \"${raw}\"`);\n }\n return ok(normalized as Tag);\n}\n\nexport function parseTags(raw: readonly string[]): Result<Tag[], DomainError> {\n if (raw.length > MAX_TAGS) {\n return contextErr(\"TOO_MANY_TAGS\", `At most ${MAX_TAGS} tags allowed. Got ${raw.length}.`);\n }\n const tags: Tag[] = [];\n for (const r of raw) {\n const parsed = parseTag(r);\n if (!parsed.ok) return parsed;\n if (!tags.includes(parsed.value)) tags.push(parsed.value);\n }\n return ok(tags);\n}\n","import type { Clock, IdGenerator } from \"../../shared/application/ports/clock.js\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { validateContent } from \"../domain/entities/context-item.js\";\nimport type { Project } from \"../domain/entities/project.js\";\nimport { type ItemType, parseItemType } from \"../domain/values/item-type.js\";\nimport { parseProjectName } from \"../domain/values/project-name.js\";\nimport { parseTags } from \"../domain/values/tag.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\n\nexport interface SaveContextInput {\n project: string;\n content: string;\n type?: string;\n tags?: string[];\n pinned?: boolean;\n source?: string;\n}\n\nexport interface SaveContextOutput {\n itemId: string;\n project: string;\n type: ItemType;\n projectCreated: boolean;\n}\n\nexport class SaveContext {\n constructor(\n private readonly sessions: VaultSessionFactory,\n private readonly clock: Clock,\n private readonly idGen: IdGenerator,\n ) {}\n\n execute(input: SaveContextInput): Result<SaveContextOutput, DomainError> {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n const type = parseItemType(input.type ?? \"fact\");\n if (!type.ok) return type;\n const tags = parseTags(input.tags ?? []);\n if (!tags.ok) return tags;\n const content = validateContent(input.content);\n if (!content.ok) return content;\n\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n const now = this.clock.now();\n let project = session.value.projects.findByName(name.value);\n const projectCreated = project === null;\n if (project === null) {\n project = {\n id: this.idGen.next(),\n name: name.value,\n createdAt: now,\n updatedAt: now,\n } satisfies Project;\n session.value.projects.save(project);\n }\n const itemId = this.idGen.next();\n session.value.items.save({\n id: itemId,\n projectId: project.id,\n type: type.value,\n content: content.value,\n tags: tags.value,\n pinned: input.pinned ?? false,\n ...(input.source === undefined ? {} : { source: input.source }),\n archived: false,\n createdAt: now,\n updatedAt: now,\n });\n return ok({ itemId, project: name.value, type: type.value, projectCreated });\n } finally {\n session.value.close();\n }\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { contextErr } from \"../domain/errors.js\";\nimport type { ItemType } from \"../domain/values/item-type.js\";\nimport { parseProjectName } from \"../domain/values/project-name.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\n\nexport interface SearchContextInput {\n query: string;\n project?: string;\n limit?: number;\n}\n\nexport interface SearchHit {\n id: string;\n project: string;\n type: ItemType;\n content: string;\n tags: string[];\n pinned: boolean;\n createdAt: string;\n}\n\nexport class SearchContext {\n constructor(private readonly sessions: VaultSessionFactory) {}\n\n execute(input: SearchContextInput): Result<SearchHit[], DomainError> {\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n let projectId: string | undefined;\n if (input.project !== undefined) {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n const project = session.value.projects.findByName(name.value);\n if (project === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n projectId = project.id;\n }\n const limit = Math.min(Math.max(input.limit ?? 20, 1), 100);\n const hits = session.value.items.search(input.query, projectId, limit).map((result) => ({\n id: result.item.id,\n project: result.projectName as string,\n type: result.item.type,\n content: result.item.content,\n tags: [...result.item.tags],\n pinned: result.item.pinned,\n createdAt: result.item.createdAt.toISOString(),\n }));\n return ok(hits);\n } finally {\n session.value.close();\n }\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { contextErr } from \"../domain/errors.js\";\nimport { type ItemType, parseItemType } from \"../domain/values/item-type.js\";\nimport { parseProjectName } from \"../domain/values/project-name.js\";\nimport type { VaultSessionFactory } from \"./ports/vault-session.js\";\nimport type { SearchHit } from \"./search-context.js\";\n\nexport class ShowProject {\n constructor(private readonly sessions: VaultSessionFactory) {}\n\n execute(project: string, type?: string): Result<SearchHit[], DomainError> {\n const name = parseProjectName(project);\n if (!name.ok) return name;\n let typeValue: ItemType | undefined;\n if (type !== undefined) {\n const parsed = parseItemType(type);\n if (!parsed.ok) return parsed;\n typeValue = parsed.value;\n }\n const session = this.sessions.open();\n if (!session.ok) return session;\n try {\n const found = session.value.projects.findByName(name.value);\n if (found === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n const items = session.value.items.findByProject(\n found.id,\n typeValue === undefined ? {} : { type: typeValue },\n );\n return ok(\n items.map((item) => ({\n id: item.id,\n project: name.value as string,\n type: item.type,\n content: item.content,\n tags: [...item.tags],\n pinned: item.pinned,\n createdAt: item.createdAt.toISOString(),\n })),\n );\n } finally {\n session.value.close();\n }\n }\n}\n","export const MIGRATION_001 = `\nCREATE TABLE projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE context_items (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id),\n type TEXT NOT NULL CHECK (type IN ('decision','progress','preference','fact','handoff')),\n content TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n pinned INTEGER NOT NULL DEFAULT 0,\n source TEXT,\n archived INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE INDEX idx_items_project ON context_items(project_id, created_at DESC);\n\nCREATE VIRTUAL TABLE context_items_fts USING fts5(\n content,\n tags,\n content='context_items',\n content_rowid='rowid'\n);\n\nCREATE TRIGGER items_ai AFTER INSERT ON context_items BEGIN\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n\nCREATE TRIGGER items_ad AFTER DELETE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\nEND;\n\nCREATE TRIGGER items_au AFTER UPDATE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n`;\n","import type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport { MIGRATION_001 } from \"./migrations/001-init.js\";\n\nconst MIGRATIONS: ReadonlyArray<{ version: number; sql: string }> = [\n { version: 1, sql: MIGRATION_001 },\n];\n\nexport function migrate(db: Database): void {\n db.exec(\"CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)\");\n const row = db.prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\").get() as\n | { value: string }\n | undefined;\n const current = row ? Number(row.value) : 0;\n for (const migration of MIGRATIONS) {\n if (migration.version <= current) continue;\n db.transaction(() => {\n db.exec(migration.sql);\n db.prepare(\n \"INSERT INTO meta (key, value) VALUES ('schema_version', ?) \" +\n \"ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n ).run(String(migration.version));\n })();\n }\n}\n\nexport function schemaVersion(db: Database): number {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\").get() as\n | { value: string }\n | undefined;\n return row ? Number(row.value) : 0;\n}\n","import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport SqliteDatabase, { type Database } from \"better-sqlite3-multiple-ciphers\";\n\n/**\n * Open (or create) the SQLCipher vault database with a raw 32-byte key.\n * Throws SqliteError (SQLITE_NOTADB) if the key is wrong for an existing file.\n *\n * The single physical database is the shared persistence kernel: the vault\n * module opens it to verify keys, the context module opens it for repositories.\n */\nexport function openVaultDb(dbPath: string, keyHex: string): Database {\n if (!/^[0-9a-f]{64}$/i.test(keyHex)) {\n throw new Error(\"Vault key must be 64 hex characters (32 bytes).\");\n }\n mkdirSync(dirname(dbPath), { recursive: true });\n const db = new SqliteDatabase(dbPath);\n try {\n db.pragma(\"cipher='sqlcipher'\");\n db.pragma(`key=\"x'${keyHex}'\"`);\n // Touching the schema forces key verification: wrong key -> SQLITE_NOTADB.\n db.prepare(\"SELECT count(*) FROM sqlite_master\").get();\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n return db;\n } catch (error) {\n db.close();\n throw error;\n }\n}\n\nexport function isWrongKeyError(error: unknown): boolean {\n return (\n error instanceof Error &&\n \"code\" in error &&\n (error as { code?: string }).code === \"SQLITE_NOTADB\"\n );\n}\n","import { DomainError, err, type Result } from \"../../shared/domain/result.js\";\n\n/** Error vocabulary of the VAULT bounded context (security language). */\nexport type VaultErrorCode =\n | \"VAULT_NOT_FOUND\"\n | \"VAULT_ALREADY_EXISTS\"\n | \"VAULT_LOCKED\"\n | \"WRONG_PASSPHRASE\"\n | \"WEAK_PASSPHRASE\"\n | \"KEYCHAIN_ERROR\"\n | \"STORAGE_ERROR\";\n\nexport const vaultErr = (code: VaultErrorCode, message: string): Result<never, DomainError> =>\n err(new DomainError(code, message));\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { VaultHeaderData } from \"../application/ports/vault-store.js\";\nimport { vaultErr } from \"../domain/errors.js\";\n\nconst headerSchema = z.object({\n vaultId: z.string().min(1),\n schemaVersion: z.literal(1),\n kdf: z.object({\n algorithm: z.literal(\"argon2id\"),\n memoryKiB: z.number().int().positive(),\n iterations: z.number().int().positive(),\n parallelism: z.number().int().positive(),\n }),\n saltBase64: z.string().min(1),\n createdAt: z.string(),\n});\n\nexport type VaultHeader = VaultHeaderData;\n\nexport function writeVaultHeader(path: string, header: VaultHeader): void {\n const json = {\n vaultId: header.vaultId,\n schemaVersion: header.schemaVersion,\n kdf: header.kdf,\n saltBase64: Buffer.from(header.salt).toString(\"base64\"),\n createdAt: header.createdAt,\n };\n writeFileSync(path, `${JSON.stringify(json, null, 2)}\\n`, \"utf8\");\n}\n\nexport function readVaultHeader(path: string): Result<VaultHeader, DomainError> {\n if (!existsSync(path)) {\n return vaultErr(\"VAULT_NOT_FOUND\", `No vault header found at ${path}. Run \"valija init\".`);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return vaultErr(\"STORAGE_ERROR\", `Vault header at ${path} is not valid JSON.`);\n }\n const parsed = headerSchema.safeParse(raw);\n if (!parsed.success) {\n return vaultErr(\n \"STORAGE_ERROR\",\n `Vault header at ${path} is malformed: ${parsed.error.message}`,\n );\n }\n const h = parsed.data;\n return ok({\n vaultId: h.vaultId,\n schemaVersion: h.schemaVersion,\n kdf: h.kdf,\n salt: new Uint8Array(Buffer.from(h.saltBase64, \"base64\")),\n createdAt: h.createdAt,\n });\n}\n","import type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport type {\n ContextItemRepository,\n FindByProjectFilters,\n SearchResult,\n} from \"../application/ports/repositories.js\";\nimport type { ContextItem } from \"../domain/entities/context-item.js\";\nimport type { ItemType } from \"../domain/values/item-type.js\";\nimport type { ProjectName } from \"../domain/values/project-name.js\";\nimport type { Tag } from \"../domain/values/tag.js\";\n\ninterface ItemRow {\n id: string;\n project_id: string;\n type: string;\n content: string;\n tags: string;\n pinned: number;\n source: string | null;\n archived: number;\n created_at: string;\n updated_at: string;\n}\n\nconst toItem = (row: ItemRow): ContextItem => ({\n id: row.id,\n projectId: row.project_id,\n type: row.type as ItemType,\n content: row.content,\n tags: JSON.parse(row.tags) as Tag[],\n pinned: row.pinned === 1,\n ...(row.source === null ? {} : { source: row.source }),\n archived: row.archived === 1,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n});\n\n/** Quote each term so user input cannot break FTS5 query syntax. Terms are ANDed. */\nconst toFtsQuery = (query: string): string =>\n query\n .split(/\\s+/)\n .filter(Boolean)\n .map((term) => `\"${term.replace(/\"/g, '\"\"')}\"`)\n .join(\" \");\n\nexport class SqliteContextItemRepository implements ContextItemRepository {\n constructor(private readonly db: Database) {}\n\n save(item: ContextItem): void {\n this.db\n .prepare(\n `INSERT INTO context_items\n (id, project_id, type, content, tags, pinned, source, archived, created_at, updated_at)\n VALUES (@id, @projectId, @type, @content, @tags, @pinned, @source, @archived, @createdAt, @updatedAt)\n ON CONFLICT(id) DO UPDATE SET\n type = excluded.type,\n content = excluded.content,\n tags = excluded.tags,\n pinned = excluded.pinned,\n source = excluded.source,\n archived = excluded.archived,\n updated_at = excluded.updated_at`,\n )\n .run({\n id: item.id,\n projectId: item.projectId,\n type: item.type,\n content: item.content,\n tags: JSON.stringify(item.tags),\n pinned: item.pinned ? 1 : 0,\n source: item.source ?? null,\n archived: item.archived ? 1 : 0,\n createdAt: item.createdAt.toISOString(),\n updatedAt: item.updatedAt.toISOString(),\n });\n }\n\n findByProject(projectId: string, filters: FindByProjectFilters = {}): ContextItem[] {\n const conditions = [\"project_id = @projectId\"];\n const params: Record<string, unknown> = { projectId };\n if (!filters.includeArchived) conditions.push(\"archived = 0\");\n if (filters.type !== undefined) {\n conditions.push(\"type = @type\");\n params.type = filters.type;\n }\n if (filters.pinned !== undefined) {\n conditions.push(\"pinned = @pinned\");\n params.pinned = filters.pinned ? 1 : 0;\n }\n const limit = filters.limit !== undefined ? ` LIMIT ${Math.max(0, filters.limit)}` : \"\";\n const rows = this.db\n .prepare(\n `SELECT * FROM context_items WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC${limit}`,\n )\n .all(params) as ItemRow[];\n return rows.map(toItem);\n }\n\n search(query: string, projectId?: string, limit = 20): SearchResult[] {\n const fts = toFtsQuery(query);\n if (fts.length === 0) return [];\n const projectFilter = projectId !== undefined ? \"AND i.project_id = @projectId\" : \"\";\n const rows = this.db\n .prepare(\n `SELECT i.*, p.name AS project_name\n FROM context_items_fts f\n JOIN context_items i ON i.rowid = f.rowid\n JOIN projects p ON p.id = i.project_id\n WHERE context_items_fts MATCH @fts AND i.archived = 0 ${projectFilter}\n ORDER BY rank LIMIT @limit`,\n )\n .all({ fts, projectId, limit }) as Array<ItemRow & { project_name: string }>;\n return rows.map((row) => ({\n item: toItem(row),\n projectName: row.project_name as ProjectName,\n }));\n }\n\n archive(itemId: string): boolean {\n const result = this.db\n .prepare(\"UPDATE context_items SET archived = 1 WHERE id = ?\")\n .run(itemId);\n return result.changes > 0;\n }\n}\n","import type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport type { ProjectRepository } from \"../application/ports/repositories.js\";\nimport type { Project, ProjectSummary } from \"../domain/entities/project.js\";\nimport type { ProjectName } from \"../domain/values/project-name.js\";\n\ninterface ProjectRow {\n id: string;\n name: string;\n description: string | null;\n created_at: string;\n updated_at: string;\n}\n\nconst toProject = (row: ProjectRow): Project => ({\n id: row.id,\n name: row.name as ProjectName,\n ...(row.description === null ? {} : { description: row.description }),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n});\n\nexport class SqliteProjectRepository implements ProjectRepository {\n constructor(private readonly db: Database) {}\n\n save(project: Project): void {\n this.db\n .prepare(\n `INSERT INTO projects (id, name, description, created_at, updated_at)\n VALUES (@id, @name, @description, @createdAt, @updatedAt)\n ON CONFLICT(id) DO UPDATE SET\n name = excluded.name,\n description = excluded.description,\n updated_at = excluded.updated_at`,\n )\n .run({\n id: project.id,\n name: project.name,\n description: project.description ?? null,\n createdAt: project.createdAt.toISOString(),\n updatedAt: project.updatedAt.toISOString(),\n });\n }\n\n findByName(name: ProjectName): Project | null {\n const row = this.db.prepare(\"SELECT * FROM projects WHERE name = ?\").get(name) as\n | ProjectRow\n | undefined;\n return row ? toProject(row) : null;\n }\n\n list(): ProjectSummary[] {\n const rows = this.db\n .prepare(\n `SELECT p.*,\n COUNT(i.id) AS item_count,\n MAX(i.updated_at) AS last_activity\n FROM projects p\n LEFT JOIN context_items i ON i.project_id = p.id AND i.archived = 0\n GROUP BY p.id\n ORDER BY last_activity DESC NULLS LAST, p.name ASC`,\n )\n .all() as Array<ProjectRow & { item_count: number; last_activity: string | null }>;\n return rows.map((row) => ({\n project: toProject(row),\n itemCount: row.item_count,\n lastActivityAt: row.last_activity ? new Date(row.last_activity) : null,\n }));\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { migrate } from \"../../shared/infra/migrations.js\";\nimport { isWrongKeyError, openVaultDb } from \"../../shared/infra/sqlite.js\";\nimport type { VaultPaths } from \"../../shared/infra/vault-paths.js\";\nimport type { KeychainPort } from \"../../vault/application/ports/keychain.js\";\nimport { vaultErr } from \"../../vault/domain/errors.js\";\nimport { readVaultHeader } from \"../../vault/infra/vault-header.js\";\nimport type { VaultSession, VaultSessionFactory } from \"../application/ports/vault-session.js\";\nimport { SqliteContextItemRepository } from \"./item-repo.js\";\nimport { SqliteProjectRepository } from \"./project-repo.js\";\n\nconst LOCKED_MESSAGE = 'Vault is locked. Ask the user to run \"valija unlock\" in a terminal.';\n\n/**\n * Implements the context-owned VaultSessionFactory port by wiring vault\n * concerns (keychain, header) to the shared SQLite engine. This is the\n * one place where the context module depends on the vault module.\n */\nexport class SqliteVaultSessionFactory implements VaultSessionFactory {\n constructor(\n private readonly paths: VaultPaths,\n private readonly keychain: KeychainPort,\n ) {}\n\n open(): Result<VaultSession, DomainError> {\n const header = readVaultHeader(this.paths.header);\n if (!header.ok) return header;\n\n const keyHex = this.keychain.getKey(header.value.vaultId);\n if (keyHex === null) return vaultErr(\"VAULT_LOCKED\", LOCKED_MESSAGE);\n\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n migrate(db);\n return ok({\n projects: new SqliteProjectRepository(db),\n items: new SqliteContextItemRepository(db),\n close: () => db.close(),\n });\n } catch (error) {\n if (isWrongKeyError(error)) {\n // Stale key in the keychain (e.g. vault file replaced) — treat as locked.\n this.keychain.deleteKey(header.value.vaultId);\n return vaultErr(\"VAULT_LOCKED\", LOCKED_MESSAGE);\n }\n return vaultErr(\"STORAGE_ERROR\", `Could not open vault: ${(error as Error).message}`);\n }\n }\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface VaultPaths {\n root: string;\n header: string;\n db: string;\n}\n\nexport function resolveVaultPaths(rootOverride?: string): VaultPaths {\n const root = rootOverride ?? process.env.VALIJA_HOME ?? join(homedir(), \".valija\");\n return {\n root,\n header: join(root, \"vault.json\"),\n db: join(root, \"vault.db\"),\n };\n}\n","export const bytesToHex = (bytes: Uint8Array): string =>\n Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\nexport const isKeyHex = (value: string): boolean => /^[0-9a-f]{64}$/i.test(value);\n","export interface KdfParams {\n readonly algorithm: \"argon2id\";\n readonly memoryKiB: number;\n readonly iterations: number;\n readonly parallelism: number;\n}\n\nexport const DEFAULT_KDF_PARAMS: KdfParams = {\n algorithm: \"argon2id\",\n memoryKiB: 64 * 1024,\n iterations: 3,\n parallelism: 1,\n};\n\nexport interface VaultCrypto {\n /** Derive a 32-byte raw key from a passphrase. */\n deriveKey(passphrase: string, salt: Uint8Array, params: KdfParams): Promise<Uint8Array>;\n generateSalt(): Uint8Array;\n}\n","import type { Clock, IdGenerator } from \"../../shared/application/ports/clock.js\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { vaultErr } from \"../domain/errors.js\";\nimport { bytesToHex } from \"./hex.js\";\nimport { DEFAULT_KDF_PARAMS, type VaultCrypto } from \"./ports/crypto.js\";\nimport type { KeychainPort } from \"./ports/keychain.js\";\nimport type { VaultStore } from \"./ports/vault-store.js\";\n\nexport const MIN_PASSPHRASE_LENGTH = 8;\n\nexport interface CreateVaultOutput {\n vaultId: string;\n keyHex: string;\n createdAt: string;\n}\n\nexport class CreateVault {\n constructor(\n private readonly store: VaultStore,\n private readonly crypto: VaultCrypto,\n private readonly keychain: KeychainPort,\n private readonly clock: Clock,\n private readonly idGen: IdGenerator,\n ) {}\n\n async execute(passphrase: string): Promise<Result<CreateVaultOutput, DomainError>> {\n if (this.store.headerExists()) {\n return vaultErr(\"VAULT_ALREADY_EXISTS\", \"A vault already exists on this machine.\");\n }\n if (passphrase.length < MIN_PASSPHRASE_LENGTH) {\n return vaultErr(\n \"WEAK_PASSPHRASE\",\n `Passphrase must be at least ${MIN_PASSPHRASE_LENGTH} characters.`,\n );\n }\n const vaultId = this.idGen.next();\n const salt = this.crypto.generateSalt();\n const key = await this.crypto.deriveKey(passphrase, salt, DEFAULT_KDF_PARAMS);\n const keyHex = bytesToHex(key);\n const createdAt = this.clock.now().toISOString();\n\n this.store.writeHeader({ vaultId, schemaVersion: 1, kdf: DEFAULT_KDF_PARAMS, salt, createdAt });\n const init = this.store.initializeDb(keyHex);\n if (!init.ok) return init;\n\n // Convenience: a freshly created vault starts unlocked.\n this.keychain.setKey(vaultId, keyHex);\n return ok({ vaultId, keyHex, createdAt });\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { KeychainPort } from \"./ports/keychain.js\";\nimport type { VaultStore } from \"./ports/vault-store.js\";\n\nexport class LockVault {\n constructor(\n private readonly store: VaultStore,\n private readonly keychain: KeychainPort,\n ) {}\n\n execute(): Result<{ wasUnlocked: boolean }, DomainError> {\n const header = this.store.readHeader();\n if (!header.ok) return header;\n const wasUnlocked = this.keychain.deleteKey(header.value.vaultId);\n return ok({ wasUnlocked });\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { vaultErr } from \"../domain/errors.js\";\nimport { bytesToHex, isKeyHex } from \"./hex.js\";\nimport type { VaultCrypto } from \"./ports/crypto.js\";\nimport type { KeychainPort } from \"./ports/keychain.js\";\nimport type { VaultStore } from \"./ports/vault-store.js\";\n\nexport interface UnlockInput {\n passphrase?: string;\n recoveryKeyHex?: string;\n}\n\nexport class UnlockVault {\n constructor(\n private readonly store: VaultStore,\n private readonly crypto: VaultCrypto,\n private readonly keychain: KeychainPort,\n ) {}\n\n async execute(input: UnlockInput): Promise<Result<{ vaultId: string }, DomainError>> {\n const header = this.store.readHeader();\n if (!header.ok) return header;\n\n let keyHex: string;\n if (input.recoveryKeyHex !== undefined) {\n if (!isKeyHex(input.recoveryKeyHex)) {\n return vaultErr(\"WRONG_PASSPHRASE\", \"Recovery key must be 64 hex characters.\");\n }\n keyHex = input.recoveryKeyHex.toLowerCase();\n } else if (input.passphrase !== undefined) {\n const key = await this.crypto.deriveKey(\n input.passphrase,\n header.value.salt,\n header.value.kdf,\n );\n keyHex = bytesToHex(key);\n } else {\n return vaultErr(\"WRONG_PASSPHRASE\", \"Provide a passphrase or a recovery key.\");\n }\n\n const verified = this.store.verifyKey(keyHex);\n if (!verified.ok) return verified;\n\n this.keychain.setKey(header.value.vaultId, keyHex);\n return ok({ vaultId: header.value.vaultId });\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { KeychainPort } from \"./ports/keychain.js\";\nimport type { VaultStore } from \"./ports/vault-store.js\";\n\nexport interface VaultStatusOutput {\n initialized: boolean;\n unlocked: boolean;\n vaultId?: string;\n dbPath: string;\n}\n\nexport class VaultStatus {\n constructor(\n private readonly store: VaultStore,\n private readonly keychain: KeychainPort,\n ) {}\n\n execute(): Result<VaultStatusOutput, DomainError> {\n const dbPath = this.store.dbPath();\n if (!this.store.headerExists()) {\n return ok({ initialized: false, unlocked: false, dbPath });\n }\n const header = this.store.readHeader();\n if (!header.ok) return header;\n\n const keyHex = this.keychain.getKey(header.value.vaultId);\n const unlocked = keyHex !== null && this.store.verifyKey(keyHex).ok;\n return ok({ initialized: true, unlocked, vaultId: header.value.vaultId, dbPath });\n }\n}\n","import { randomBytes } from \"node:crypto\";\nimport argon2 from \"argon2\";\nimport type { KdfParams, VaultCrypto } from \"../application/ports/crypto.js\";\n\nexport const KEY_LENGTH = 32;\nexport const SALT_LENGTH = 16;\n\nexport class Argon2VaultCrypto implements VaultCrypto {\n async deriveKey(passphrase: string, salt: Uint8Array, params: KdfParams): Promise<Uint8Array> {\n const key = await argon2.hash(passphrase, {\n type: argon2.argon2id,\n raw: true,\n salt: Buffer.from(salt),\n memoryCost: params.memoryKiB,\n timeCost: params.iterations,\n parallelism: params.parallelism,\n hashLength: KEY_LENGTH,\n });\n return new Uint8Array(key);\n }\n\n generateSalt(): Uint8Array {\n return new Uint8Array(randomBytes(SALT_LENGTH));\n }\n}\n\nexport const toHex = (bytes: Uint8Array): string => Buffer.from(bytes).toString(\"hex\");\nexport const fromHex = (hex: string): Uint8Array => new Uint8Array(Buffer.from(hex, \"hex\"));\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { migrate } from \"../../shared/infra/migrations.js\";\nimport { isWrongKeyError, openVaultDb } from \"../../shared/infra/sqlite.js\";\nimport type { VaultPaths } from \"../../shared/infra/vault-paths.js\";\nimport type { VaultHeaderData, VaultStore } from \"../application/ports/vault-store.js\";\nimport { vaultErr } from \"../domain/errors.js\";\nimport { readVaultHeader, writeVaultHeader } from \"./vault-header.js\";\n\nexport class FileVaultStore implements VaultStore {\n constructor(private readonly paths: VaultPaths) {}\n\n headerExists(): boolean {\n return existsSync(this.paths.header);\n }\n\n readHeader(): Result<VaultHeaderData, DomainError> {\n return readVaultHeader(this.paths.header);\n }\n\n writeHeader(header: VaultHeaderData): void {\n mkdirSync(this.paths.root, { recursive: true });\n writeVaultHeader(this.paths.header, header);\n }\n\n initializeDb(keyHex: string): Result<void, DomainError> {\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n migrate(db);\n db.close();\n return ok(undefined);\n } catch (error) {\n return vaultErr(\"STORAGE_ERROR\", `Could not create vault db: ${(error as Error).message}`);\n }\n }\n\n verifyKey(keyHex: string): Result<void, DomainError> {\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n db.close();\n return ok(undefined);\n } catch (error) {\n if (isWrongKeyError(error)) {\n return vaultErr(\"WRONG_PASSPHRASE\", \"Wrong passphrase (or recovery key) for this vault.\");\n }\n return vaultErr(\"STORAGE_ERROR\", `Could not open vault db: ${(error as Error).message}`);\n }\n }\n\n dbPath(): string {\n return this.paths.db;\n }\n}\n","import { Entry } from \"@napi-rs/keyring\";\nimport type { KeychainPort } from \"../application/ports/keychain.js\";\n\nconst SERVICE = \"valija\";\n\nexport class OsKeychain implements KeychainPort {\n setKey(vaultId: string, keyHex: string): void {\n new Entry(SERVICE, vaultId).setPassword(keyHex);\n }\n\n getKey(vaultId: string): string | null {\n try {\n return new Entry(SERVICE, vaultId).getPassword();\n } catch {\n return null;\n }\n }\n\n deleteKey(vaultId: string): boolean {\n try {\n return new Entry(SERVICE, vaultId).deletePassword();\n } catch {\n return false;\n }\n }\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { ITEM_TYPES } from \"../../context/domain/values/item-type.js\";\nimport type { DomainError } from \"../../shared/domain/result.js\";\nimport type { Container } from \"../container.js\";\nimport { VERSION } from \"../version.js\";\n\nconst ok = (text: string) => ({ content: [{ type: \"text\" as const, text }] });\nconst err = (error: DomainError) => ({\n content: [{ type: \"text\" as const, text: `${error.message} [${error.code}]` }],\n isError: true,\n});\n\nconst DESCRIPTIONS = {\n save_context:\n \"Save durable context about a project for future sessions in any AI tool. \" +\n \"Use when the user asks to save or remember something, or at the end of a working session. \" +\n \"Write `content` so it is self-contained and specific for a reader with no other context: \" +\n \"decisions made and why, current state, conventions and preferences established, next steps, \" +\n \"unresolved questions. Never include secrets, API keys, or passwords.\",\n save_handoff:\n \"Package the state of THIS conversation so another AI tool or session can continue seamlessly. \" +\n \"Structure `content` as: goal, what was done, current blockers, exact next step, \" +\n \"relevant files or links.\",\n get_context:\n \"Load the saved context pack for a project before starting work on it. Returns pinned and \" +\n \"recent context (decisions, preferences, progress, latest handoff) as markdown within a \" +\n \"token budget. Call this when the user asks to load, resume, or continue a project.\",\n search_context:\n \"Full-text search across saved context. Use for specific recall questions such as \" +\n \"'what did we decide about auth?'. Returns matching items with project, type, and date.\",\n list_projects:\n \"List existing projects with item counts and last activity. Use to disambiguate which \" +\n \"project the user means before saving or loading.\",\n} as const;\n\nexport function buildMcpServer(c: Container): McpServer {\n const server = new McpServer({ name: \"valija\", version: VERSION });\n const clientName = (): string | undefined => server.server.getClientVersion()?.name;\n\n server.registerTool(\n \"save_context\",\n {\n title: \"Save context\",\n description: DESCRIPTIONS.save_context,\n inputSchema: {\n project: z\n .string()\n .describe(\"Project slug, e.g. 'vault-app'. Created if it does not exist.\"),\n content: z.string().describe(\"Self-contained markdown. Max 32 KB.\"),\n type: z.enum(ITEM_TYPES).optional().describe(\"Kind of context. Defaults to 'fact'.\"),\n tags: z.array(z.string()).max(10).optional().describe(\"Lowercase tags for recall.\"),\n },\n },\n async ({ project, content, type, tags }) => {\n const source = clientName();\n const r = c.saveContext.execute({\n project,\n content,\n ...(type === undefined ? {} : { type }),\n ...(tags === undefined ? {} : { tags }),\n ...(source === undefined ? {} : { source }),\n });\n if (!r.ok) return err(r.error);\n return ok(\n `Saved ${r.value.type} to project \"${r.value.project}\"` +\n `${r.value.projectCreated ? \" (project created)\" : \"\"}. Item id: ${r.value.itemId}.`,\n );\n },\n );\n\n server.registerTool(\n \"save_handoff\",\n {\n title: \"Save handoff\",\n description: DESCRIPTIONS.save_handoff,\n inputSchema: {\n project: z.string().describe(\"Project slug. Created if it does not exist.\"),\n content: z\n .string()\n .describe(\"Goal, what was done, blockers, exact next step, relevant files or links.\"),\n },\n },\n async ({ project, content }) => {\n const source = clientName();\n const r = c.saveContext.execute({\n project,\n content,\n type: \"handoff\",\n ...(source === undefined ? {} : { source }),\n });\n if (!r.ok) return err(r.error);\n return ok(`Handoff saved to project \"${r.value.project}\". Item id: ${r.value.itemId}.`);\n },\n );\n\n server.registerTool(\n \"get_context\",\n {\n title: \"Get context pack\",\n description: DESCRIPTIONS.get_context,\n inputSchema: {\n project: z.string().describe(\"Project slug to load.\"),\n budget: z.number().int().positive().optional().describe(\"Token budget. Default 4000.\"),\n },\n },\n async ({ project, budget }) => {\n const r = c.getContextPack.execute({\n project,\n ...(budget === undefined ? {} : { budgetTokens: budget }),\n });\n if (!r.ok) return err(r.error);\n return ok(r.value.markdown);\n },\n );\n\n server.registerTool(\n \"search_context\",\n {\n title: \"Search context\",\n description: DESCRIPTIONS.search_context,\n inputSchema: {\n query: z.string().describe(\"Full-text query, e.g. 'auth decision'.\"),\n project: z.string().optional().describe(\"Limit to one project.\"),\n limit: z.number().int().positive().max(100).optional().describe(\"Max results. Default 20.\"),\n },\n },\n async ({ query, project, limit }) => {\n const r = c.searchContext.execute({\n query,\n ...(project === undefined ? {} : { project }),\n ...(limit === undefined ? {} : { limit }),\n });\n if (!r.ok) return err(r.error);\n if (r.value.length === 0) return ok(\"No matches.\");\n const lines = r.value.map(\n (hit) => `- [${hit.project}] (${hit.type}, ${hit.createdAt.slice(0, 10)}) ${hit.content}`,\n );\n return ok(`${r.value.length} match(es):\\n\\n${lines.join(\"\\n\")}`);\n },\n );\n\n server.registerTool(\n \"list_projects\",\n {\n title: \"List projects\",\n description: DESCRIPTIONS.list_projects,\n inputSchema: {},\n },\n async () => {\n const r = c.listProjects.execute();\n if (!r.ok) return err(r.error);\n if (r.value.length === 0) return ok(\"No projects in the vault yet.\");\n const lines = r.value.map(\n (p) =>\n `- ${p.name}: ${p.itemCount} item(s), last activity ${p.lastActivityAt?.slice(0, 10) ?? \"never\"}`,\n );\n return ok(lines.join(\"\\n\"));\n },\n );\n\n server.registerPrompt(\n \"save-context\",\n {\n title: \"Save session context to valija\",\n description: \"Distill this session into a self-contained context save.\",\n argsSchema: { project: z.string().optional() },\n },\n ({ project }) => ({\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Review this conversation and save its durable context to valija${project ? ` under the project \"${project}\"` : \"\"}.\\n\\n` +\n \"1. If the project is ambiguous, call list_projects first and confirm with me.\\n\" +\n \"2. Compose content that is self-contained for a reader with no other context: \" +\n \"decisions made and why, current state, conventions/preferences established, \" +\n \"next steps, unresolved questions. No secrets, API keys, or passwords.\\n\" +\n \"3. Pick the right type (decision/progress/preference/fact) and 1-5 tags.\\n\" +\n \"4. Call save_context, then tell me what you saved in one line.\",\n },\n },\n ],\n }),\n );\n\n server.registerPrompt(\n \"load-context\",\n {\n title: \"Load project context from valija\",\n description: \"Load a project's context pack and resume work.\",\n argsSchema: { project: z.string() },\n },\n ({ project }) => ({\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Call get_context for the project \"${project}\". Then:\\n` +\n \"1. Summarize the current state in 3 lines max.\\n\" +\n \"2. Propose the next step based on the latest handoff or progress.\\n\" +\n \"Do not repeat the whole pack back to me.\",\n },\n },\n ],\n }),\n );\n\n return server;\n}\n\nexport async function runMcpServer(c: Container): Promise<void> {\n const server = buildMcpServer(c);\n await server.connect(new StdioServerTransport());\n}\n","export const VERSION = \"0.1.0\";\n","import { writeFileSync } from \"node:fs\";\nimport type { Container } from \"../container.js\";\nimport { fail, formatDate, truncate } from \"./render.js\";\n\nexport function projectsCommand(c: Container): void {\n const result = c.listProjects.execute();\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\n \"No projects yet. Save context from an AI tool, or check back after your first session.\",\n );\n return;\n }\n console.log(\"PROJECT ITEMS LAST ACTIVITY\");\n for (const p of result.value) {\n console.log(\n `${p.name.padEnd(32)} ${String(p.itemCount).padStart(5)} ${formatDate(p.lastActivityAt)}`,\n );\n }\n}\n\nexport function showCommand(c: Container, project: string, options: { type?: string }): void {\n const result = c.showProject.execute(project, options.type);\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\"No items.\");\n return;\n }\n for (const item of result.value) {\n const pin = item.pinned ? \" 📌\" : \"\";\n const tags = item.tags.length > 0 ? ` [${item.tags.join(\", \")}]` : \"\";\n console.log(`\\n— ${item.type} · ${formatDate(item.createdAt)}${pin}${tags}`);\n console.log(item.content);\n }\n}\n\nexport function searchCommand(c: Container, query: string, options: { project?: string }): void {\n const result = c.searchContext.execute({\n query,\n ...(options.project === undefined ? {} : { project: options.project }),\n });\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\"No matches.\");\n return;\n }\n for (const hit of result.value) {\n console.log(\n `${hit.project} ${hit.type.padEnd(10)} ${formatDate(hit.createdAt)} ${truncate(hit.content)}`,\n );\n }\n}\n\nexport function exportCommand(\n c: Container,\n project: string,\n options: { json?: boolean; output?: string },\n): void {\n const format = options.json ? \"json\" : \"md\";\n const result = c.exportPack.execute(project, format);\n if (!result.ok) fail(result.error);\n if (options.output !== undefined) {\n writeFileSync(options.output, result.value, \"utf8\");\n console.error(`Exported ${project} (${format}) to ${options.output}`);\n } else {\n console.log(result.value);\n }\n}\n","import type { DomainError } from \"../../shared/domain/result.js\";\n\nexport function fail(error: DomainError): never {\n console.error(`error [${error.code}]: ${error.message}`);\n process.exit(1);\n}\n\nexport function truncate(text: string, max = 80): string {\n const oneLine = text.replace(/\\s+/g, \" \").trim();\n return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}…`;\n}\n\nexport function formatDate(iso: string | null): string {\n return iso === null ? \"—\" : iso.slice(0, 10);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { OsKeychain } from \"../../vault/infra/keyring.js\";\nimport type { Container } from \"../container.js\";\nimport { CLIENTS, clientConfigPath } from \"./installer.js\";\n\ninterface Check {\n name: string;\n ok: boolean;\n detail: string;\n fatal?: boolean;\n}\n\nexport async function doctorCommand(c: Container): Promise<void> {\n const checks: Check[] = [];\n\n const [major] = process.versions.node.split(\".\").map(Number);\n checks.push({\n name: \"node\",\n ok: (major ?? 0) >= 22,\n detail: `v${process.versions.node} (need >=22)`,\n fatal: true,\n });\n\n try {\n const { default: Db } = await import(\"better-sqlite3-multiple-ciphers\");\n const db = new Db(\":memory:\");\n db.pragma(\"cipher='sqlcipher'\");\n db.close();\n checks.push({ name: \"sqlcipher\", ok: true, detail: \"native module loads\" });\n } catch (e) {\n checks.push({ name: \"sqlcipher\", ok: false, detail: (e as Error).message, fatal: true });\n }\n\n try {\n const keychain = new OsKeychain();\n keychain.setKey(\"doctor-probe\", \"test\");\n const roundtrip = keychain.getKey(\"doctor-probe\") === \"test\";\n keychain.deleteKey(\"doctor-probe\");\n checks.push({ name: \"keychain\", ok: roundtrip, detail: \"OS keychain read/write\" });\n } catch (e) {\n checks.push({ name: \"keychain\", ok: false, detail: (e as Error).message });\n }\n\n const status = c.vaultStatus.execute();\n if (status.ok) {\n checks.push({\n name: \"vault\",\n ok: status.value.initialized,\n detail: status.value.initialized\n ? `${status.value.unlocked ? \"unlocked\" : \"locked\"} at ${status.value.dbPath}`\n : 'not initialized — run \"valija init\"',\n });\n } else {\n checks.push({ name: \"vault\", ok: false, detail: status.error.message });\n }\n\n for (const client of CLIENTS) {\n const path = clientConfigPath(client);\n let detail = \"config not found\";\n let installed = false;\n if (existsSync(path)) {\n detail = \"config found, valija not installed\";\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n installed = parsed.mcpServers?.valija !== undefined;\n if (installed) detail = \"valija installed\";\n } catch {\n detail = \"config exists but is not valid JSON\";\n }\n }\n checks.push({ name: client, ok: installed, detail });\n }\n\n let fatal = false;\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name.padEnd(16)} ${check.detail}`);\n if (!check.ok && check.fatal) fatal = true;\n }\n if (fatal) process.exit(1);\n}\n","import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const CLIENTS = [\"claude-code\", \"claude-desktop\", \"cursor\"] as const;\nexport type ClientId = (typeof CLIENTS)[number];\n\nconst MCP_ENTRY = { command: \"npx\", args: [\"-y\", \"valija\", \"mcp\"] };\n\nexport function clientConfigPath(client: ClientId, platform = process.platform): string {\n const home = homedir();\n switch (client) {\n case \"claude-code\":\n return join(home, \".claude.json\");\n case \"cursor\":\n return join(home, \".cursor\", \"mcp.json\");\n case \"claude-desktop\": {\n if (platform === \"win32\")\n return join(\n process.env.APPDATA ?? join(home, \"AppData\", \"Roaming\"),\n \"Claude\",\n \"claude_desktop_config.json\",\n );\n if (platform === \"darwin\")\n return join(home, \"Library\", \"Application Support\", \"Claude\", \"claude_desktop_config.json\");\n return join(home, \".config\", \"Claude\", \"claude_desktop_config.json\");\n }\n }\n}\n\nexport interface InstallResult {\n configPath: string;\n backupPath: string | null;\n}\n\n/** Merge the valija MCP entry into the client config, backing up the original file first. */\nexport function installIntoClient(client: ClientId): InstallResult {\n const configPath = clientConfigPath(client);\n let existing: Record<string, unknown> = {};\n let backupPath: string | null = null;\n\n if (existsSync(configPath)) {\n const raw = readFileSync(configPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw); // malformed JSON -> throw, never overwrite\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${configPath} does not contain a JSON object; not touching it.`);\n }\n existing = parsed as Record<string, unknown>;\n backupPath = `${configPath}.backup-${Date.now()}`;\n copyFileSync(configPath, backupPath);\n } else {\n mkdirSync(dirname(configPath), { recursive: true });\n }\n\n const servers =\n typeof existing.mcpServers === \"object\" && existing.mcpServers !== null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n const merged = { ...existing, mcpServers: { ...servers, valija: MCP_ENTRY } };\n writeFileSync(configPath, `${JSON.stringify(merged, null, 2)}\\n`, \"utf8\");\n return { configPath, backupPath };\n}\n\nexport function manualInstructions(client: ClientId): string {\n return (\n `Add this to the \"mcpServers\" object of ${clientConfigPath(client)}:\\n\\n` +\n ` \"valija\": ${JSON.stringify(MCP_ENTRY, null, 2).replace(/\\n/g, \"\\n \")}\\n`\n );\n}\n","export function renderRecoveryKit(vaultId: string, keyHex: string, createdAt: string): string {\n return `================================================================\n VALIJA RECOVERY KIT\n================================================================\n\nCreated: ${createdAt}\nVault id: ${vaultId}\n\nRAW ENCRYPTION KEY (hex):\n\n ${keyHex}\n\n----------------------------------------------------------------\nWHAT THIS IS\n\nThis key decrypts your valija vault (~/.valija/vault.db) WITHOUT\nthe passphrase. It is the only way back in if you forget your\npassphrase. There is no server, no account, no reset email.\n\n passphrase lost + this kit lost = your data is gone. Forever.\n\nWHAT TO DO WITH IT\n\n 1. Print this file or copy it by hand.\n 2. Store it OFFLINE: a drawer, a safe, a password manager you\n trust — anywhere that is not this computer.\n 3. Delete this file from disk once stored.\n\nHOW TO RECOVER\n\n valija unlock --recovery-key <the hex above>\n\nAnyone holding this key can read your vault. Guard it like a key.\n================================================================\n`;\n}\n","import { createInterface, type Interface } from \"node:readline\";\n\nconst CTRL_C = String.fromCharCode(0x03);\nconst BACKSPACE = String.fromCharCode(0x08);\nconst DEL = String.fromCharCode(0x7f);\n\n// Shared line reader for piped stdin: one chunk can carry several lines,\n// so a per-prompt reader would swallow the lines meant for later prompts.\nlet reader: Interface | undefined;\nconst bufferedLines: string[] = [];\nconst waiters: Array<(line: string) => void> = [];\n\nfunction readPipedLine(): Promise<string> {\n if (reader === undefined) {\n reader = createInterface({ input: process.stdin });\n reader.on(\"line\", (line) => {\n const waiter = waiters.shift();\n if (waiter) waiter(line);\n else bufferedLines.push(line);\n if (waiters.length === 0) reader?.pause();\n });\n }\n const queued = bufferedLines.shift();\n if (queued !== undefined) return Promise.resolve(queued);\n reader.resume();\n return new Promise((resolve) => waiters.push(resolve));\n}\n\nfunction readHiddenTtyLine(): Promise<string> {\n return new Promise((resolve) => {\n const { stdin, stdout } = process;\n const chars: string[] = [];\n const onData = (buf: Buffer) => {\n for (const c of buf.toString(\"utf8\")) {\n if (c === \"\\r\" || c === \"\\n\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n stdout.write(\"\\n\");\n resolve(chars.join(\"\"));\n return;\n }\n if (c === CTRL_C) {\n stdin.setRawMode(false);\n stdout.write(\"\\n\");\n process.exit(130);\n }\n if (c === BACKSPACE || c === DEL) chars.pop();\n else chars.push(c);\n }\n };\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n\n/** Prompt for a secret. Hides input on a TTY; reads plain lines when piped. */\nexport function promptHidden(question: string): Promise<string> {\n process.stdout.write(question);\n return process.stdin.isTTY === true ? readHiddenTtyLine() : readPipedLine();\n}\n","import { renderRecoveryKit } from \"../../vault/infra/recovery-kit.js\";\nimport type { Container } from \"../container.js\";\nimport { promptHidden } from \"./prompt.js\";\nimport { fail } from \"./render.js\";\n\nexport async function initCommand(c: Container): Promise<void> {\n console.log(\"Creating your encrypted vault.\\n\");\n console.log(\"Choose a passphrase (min 8 chars). You will need it to unlock the vault.\");\n console.log(\"If you lose it AND the recovery kit, your data is gone. No reset exists.\\n\");\n\n const passphrase = await promptHidden(\"Passphrase: \");\n const confirmation = await promptHidden(\"Repeat passphrase: \");\n if (passphrase !== confirmation) {\n console.error(\"error: passphrases do not match.\");\n process.exit(1);\n }\n\n console.log(\"\\nDeriving key (Argon2id, ~1s)...\");\n const result = await c.createVault.execute(passphrase);\n if (!result.ok) fail(result.error);\n\n const kit = renderRecoveryKit(result.value.vaultId, result.value.keyHex, result.value.createdAt);\n console.log(`\\nVault created at ${c.paths.root} and unlocked.\\n`);\n console.log(kit);\n console.log(\"^ THIS IS YOUR RECOVERY KIT — it is shown ONCE and never stored.\");\n console.log(\" Copy it somewhere safe (offline) before you close this terminal.\\n\");\n console.log('Next: run \"valija install claude-code\" (or claude-desktop, cursor).');\n}\n\nexport async function unlockCommand(\n c: Container,\n options: { recoveryKey?: string },\n): Promise<void> {\n const input =\n options.recoveryKey !== undefined\n ? { recoveryKeyHex: options.recoveryKey }\n : { passphrase: await promptHidden(\"Passphrase: \") };\n const result = await c.unlockVault.execute(input);\n if (!result.ok) fail(result.error);\n console.log(\"Vault unlocked. MCP tools can now read and write context.\");\n console.log('Lock it again with \"valija lock\".');\n}\n\nexport function lockCommand(c: Container): void {\n const result = c.lockVault.execute();\n if (!result.ok) fail(result.error);\n console.log(result.value.wasUnlocked ? \"Vault locked.\" : \"Vault was already locked.\");\n}\n\nexport function statusCommand(c: Container): void {\n const result = c.vaultStatus.execute();\n if (!result.ok) fail(result.error);\n const s = result.value;\n if (!s.initialized) {\n console.log('No vault on this machine. Run \"valija init\" to create one.');\n return;\n }\n console.log(`vault: ${s.dbPath}`);\n console.log(`vault id: ${s.vaultId}`);\n console.log(`state: ${s.unlocked ? \"UNLOCKED\" : \"LOCKED\"}`);\n}\n"],"mappings":"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","names":["PATTERN","existsSync","mkdirSync","existsSync","mkdirSync","z","ok","err","z","writeFileSync","writeFileSync","existsSync","readFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","existsSync","readFileSync"]}
1
+ {"version":3,"sources":["../src/delivery/cli/program.ts","../src/delivery/container.ts","../src/shared/domain/result.ts","../src/context/domain/errors.ts","../src/context/domain/services/context-pack.ts","../src/context/domain/values/project-name.ts","../src/context/application/use-cases/get-context-pack.use-case.ts","../src/context/domain/entities/context-item.ts","../src/context/domain/values/content.ts","../src/context/domain/values/tag.ts","../src/context/application/use-cases/import-items.use-case.ts","../src/context/application/use-cases/list-projects.use-case.ts","../src/context/domain/values/item-type.ts","../src/context/application/use-cases/save-context.use-case.ts","../src/context/application/dto/context-item-view.ts","../src/context/application/use-cases/search-context.use-case.ts","../src/context/application/use-cases/show-project.use-case.ts","../src/shared/infra/migrations.ts","../src/shared/infra/migrations/001-init.ts","../src/shared/infra/migrations/002-imported-type.ts","../src/shared/infra/sqlite.ts","../src/vault/domain/errors.ts","../src/vault/infra/vault-header.ts","../src/context/infra/item-repo.ts","../src/context/infra/project-repo.ts","../src/context/infra/vault-sessions.ts","../src/importers/domain/errors.ts","../src/importers/domain/services/chunk-render.ts","../src/importers/domain/services/selection.ts","../src/importers/application/use-cases/import-conversations.use-case.ts","../src/importers/infra/file-export-reader.ts","../src/importers/infra/parsers/chatgpt-parser.ts","../src/importers/infra/parsers/claude-parser.ts","../src/importers/infra/parsers/generic-parser.ts","../src/importers/infra/parser-registry.ts","../src/shared/infra/vault-paths.ts","../src/vault/domain/values/key-hex.ts","../src/vault/domain/values/passphrase.ts","../src/vault/application/ports/crypto.ts","../src/vault/application/use-cases/create-vault.use-case.ts","../src/vault/application/use-cases/lock-vault.use-case.ts","../src/vault/application/use-cases/unlock-vault.use-case.ts","../src/vault/application/use-cases/vault-status.use-case.ts","../src/vault/infra/argon2.ts","../src/vault/infra/file-vault-store.ts","../src/vault/infra/keyring.ts","../src/delivery/mcp/server.ts","../src/delivery/context-pack-markdown.ts","../src/delivery/version.ts","../src/delivery/cli/content-commands.ts","../src/delivery/cli/render.ts","../src/delivery/cli/doctor.ts","../src/delivery/cli/installer.ts","../src/importers/domain/values/import-source.ts","../src/delivery/cli/import-command.ts","../src/vault/infra/recovery-kit.ts","../src/delivery/cli/prompt.ts","../src/delivery/cli/vault-commands.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { buildContainer } from \"../container.js\";\nimport { runMcpServer } from \"../mcp/server.js\";\nimport { VERSION } from \"../version.js\";\nimport { exportCommand, projectsCommand, searchCommand, showCommand } from \"./content-commands.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { importCommand } from \"./import-command.js\";\nimport { CLIENTS, type ClientId, installIntoClient, manualInstructions } from \"./installer.js\";\nimport { initCommand, lockCommand, statusCommand, unlockCommand } from \"./vault-commands.js\";\n\nconst program = new Command();\nconst container = buildContainer();\n\nprogram\n .name(\"valija\")\n .description(\"Encrypted context vault for developers who use several AI tools.\")\n .version(VERSION);\n\nprogram\n .command(\"init\")\n .description(\"Create the encrypted vault (passphrase + recovery kit).\")\n .action(() => initCommand(container));\n\nprogram\n .command(\"unlock\")\n .description(\"Unlock the vault for this session (key goes to the OS keychain).\")\n .option(\"--recovery-key <hex>\", \"unlock with the raw key from your recovery kit\")\n .action((options: { recoveryKey?: string }) => unlockCommand(container, options));\n\nprogram\n .command(\"lock\")\n .description(\"Lock the vault (remove the key from the OS keychain).\")\n .action(() => lockCommand(container));\n\nprogram\n .command(\"status\")\n .description(\"Show vault location and lock state.\")\n .action(() => statusCommand(container));\n\nprogram\n .command(\"projects\")\n .description(\"List projects with item counts and last activity.\")\n .action(() => projectsCommand(container));\n\nprogram\n .command(\"show\")\n .description(\"Print the items of a project.\")\n .argument(\"<project>\", \"project slug\")\n .option(\"--type <type>\", \"filter by type (decision|progress|preference|fact|handoff|imported)\")\n .action((project: string, options: { type?: string }) =>\n showCommand(container, project, options),\n );\n\nprogram\n .command(\"search\")\n .description(\"Full-text search across saved context.\")\n .argument(\"<query>\", \"search terms\")\n .option(\"-p, --project <project>\", \"limit to one project\")\n .action((query: string, options: { project?: string }) =>\n searchCommand(container, query, options),\n );\n\nprogram\n .command(\"export\")\n .description(\"Export a project's context pack (markdown by default).\")\n .argument(\"<project>\", \"project slug\")\n .option(\"--json\", \"export as JSON instead of markdown\")\n .option(\"-o, --output <file>\", \"write to a file instead of stdout\")\n .action((project: string, options: { json?: boolean; output?: string }) =>\n exportCommand(container, project, options),\n );\n\nprogram\n .command(\"import\")\n .description(\"Import chatbot history (ChatGPT/Claude/generic export) into the vault.\")\n .argument(\"<file>\", \"path to an export file (.json or .zip)\")\n .option(\"-p, --project <project>\", \"target project (required to import; created if new)\")\n .option(\"--from <source>\", \"chatgpt | claude | generic (auto-detected if omitted)\")\n .option(\"--list\", \"list conversations and exit (the default when no selection is given)\")\n .option(\"--pick <spec>\", \"1-based indices/ranges into the list, e.g. 1,3-5\")\n .option(\"--query <text>\", \"select conversations whose title contains this text\")\n .option(\"--since <date>\", \"select conversations on or after YYYY-MM-DD\")\n .option(\"--all\", \"import every conversation\")\n .option(\"--dry-run\", \"report what would be imported; write nothing\")\n .action((file: string, options: Parameters<typeof importCommand>[2]) =>\n importCommand(container, file, options),\n );\n\nprogram\n .command(\"install\")\n .description(\"Wire the valija MCP server into an AI tool's config.\")\n .argument(\"<client>\", `one of: ${CLIENTS.join(\", \")}`)\n .action((client: string) => {\n if (!(CLIENTS as readonly string[]).includes(client)) {\n console.error(`error: unknown client \"${client}\". Use one of: ${CLIENTS.join(\", \")}`);\n process.exit(1);\n }\n try {\n const result = installIntoClient(client as ClientId);\n console.log(`valija MCP server added to ${result.configPath}`);\n if (result.backupPath) console.log(`Backup of the previous config: ${result.backupPath}`);\n console.log(`Restart ${client} to pick it up.`);\n } catch (e) {\n console.error(`Could not update the config automatically: ${(e as Error).message}\\n`);\n console.error(manualInstructions(client as ClientId));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"mcp\")\n .description(\"Run the MCP server on stdio (used by AI tools, not by humans).\")\n .action(async () => {\n await runMcpServer(container);\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Check environment, vault, keychain, and client configs.\")\n .action(() => doctorCommand(container));\n\nprogram.parseAsync().catch((error: unknown) => {\n console.error(`error: ${(error as Error).message}`);\n process.exit(1);\n});\n","import { ulid } from \"ulid\";\nimport { GetContextPack } from \"../context/application/use-cases/get-context-pack.use-case.js\";\nimport { ImportItems } from \"../context/application/use-cases/import-items.use-case.js\";\nimport { ListProjects } from \"../context/application/use-cases/list-projects.use-case.js\";\nimport { SaveContext } from \"../context/application/use-cases/save-context.use-case.js\";\nimport { SearchContext } from \"../context/application/use-cases/search-context.use-case.js\";\nimport { ShowProject } from \"../context/application/use-cases/show-project.use-case.js\";\nimport { SqliteVaultSessions } from \"../context/infra/vault-sessions.js\";\nimport { ImportConversations } from \"../importers/application/use-cases/import-conversations.use-case.js\";\nimport { FileExportReader } from \"../importers/infra/file-export-reader.js\";\nimport { parserRegistry } from \"../importers/infra/parser-registry.js\";\nimport type { Clock, IdGenerator } from \"../shared/application/ports/clock.js\";\nimport { resolveVaultPaths, type VaultPaths } from \"../shared/infra/vault-paths.js\";\nimport { CreateVault } from \"../vault/application/use-cases/create-vault.use-case.js\";\nimport { LockVault } from \"../vault/application/use-cases/lock-vault.use-case.js\";\nimport { UnlockVault } from \"../vault/application/use-cases/unlock-vault.use-case.js\";\nimport { VaultStatus } from \"../vault/application/use-cases/vault-status.use-case.js\";\nimport { Argon2VaultCrypto } from \"../vault/infra/argon2.js\";\nimport { FileVaultStore } from \"../vault/infra/file-vault-store.js\";\nimport { OsKeychain } from \"../vault/infra/keyring.js\";\n\nconst systemClock: Clock = { now: () => new Date() };\nconst ulidIds: IdGenerator = { next: () => ulid() };\n\nexport interface Container {\n paths: VaultPaths;\n createVault: CreateVault;\n unlockVault: UnlockVault;\n lockVault: LockVault;\n vaultStatus: VaultStatus;\n saveContext: SaveContext;\n listProjects: ListProjects;\n searchContext: SearchContext;\n getContextPack: GetContextPack;\n showProject: ShowProject;\n importConversations: ImportConversations;\n}\n\nexport function buildContainer(): Container {\n const paths = resolveVaultPaths();\n const store = new FileVaultStore(paths);\n const crypto = new Argon2VaultCrypto();\n const keychain = new OsKeychain();\n const sessions = new SqliteVaultSessions(paths, keychain);\n const importItems = new ImportItems(sessions, systemClock, ulidIds);\n return {\n paths,\n createVault: new CreateVault(store, crypto, keychain, systemClock, ulidIds),\n unlockVault: new UnlockVault(store, crypto, keychain),\n lockVault: new LockVault(store, keychain),\n vaultStatus: new VaultStatus(store, keychain),\n saveContext: new SaveContext(sessions, systemClock, ulidIds),\n listProjects: new ListProjects(sessions),\n searchContext: new SearchContext(sessions),\n getContextPack: new GetContextPack(sessions, systemClock),\n showProject: new ShowProject(sessions),\n importConversations: new ImportConversations(\n new FileExportReader(),\n parserRegistry,\n importItems,\n systemClock,\n ),\n };\n}\n","export type Result<T, E = DomainError> = { ok: true; value: T } | { ok: false; error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\n/**\n * Base error shared by every module. Each bounded context narrows `code`\n * through its own constructor (vaultErr / contextErr).\n */\nexport class DomainError extends Error {\n constructor(\n readonly code: string,\n message: string,\n ) {\n super(message);\n this.name = \"DomainError\";\n }\n}\n","import { DomainError, err, type Result } from \"../../shared/domain/result.js\";\n\n/** Error vocabulary of the CONTEXT bounded context (content language). */\nexport type ContextErrorCode =\n | \"INVALID_PROJECT_NAME\"\n | \"INVALID_ITEM_TYPE\"\n | \"INVALID_TAG\"\n | \"CONTENT_TOO_LARGE\"\n | \"CONTENT_EMPTY\"\n | \"TOO_MANY_TAGS\"\n | \"PROJECT_NOT_FOUND\"\n | \"ITEM_NOT_FOUND\";\n\nexport const contextErr = (code: ContextErrorCode, message: string): Result<never, DomainError> =>\n err(new DomainError(code, message));\n","import type { ContextItem } from \"../entities/context-item.js\";\nimport type { ItemType } from \"../values/item-type.js\";\nimport type { ProjectName } from \"../values/project-name.js\";\n\nexport const DEFAULT_BUDGET_TOKENS = 4000;\n\n/** Cheap token estimate: ~4 chars per token. Good enough for a budget, no tokenizer dep. */\nexport const estimateTokens = (text: string): number => Math.ceil(text.length / 4);\n\n/** What one item costs against the budget: its body plus the metadata that travels with it. */\nexport const estimateItemTokens = (item: ContextItem): number =>\n estimateTokens(\n `${item.type} ${item.createdAt.toISOString().slice(0, 10)} ${item.tags.join(\" \")}\\n\\n${item.content}`,\n );\n\n/** Types that get their own section, in the order they appear in the pack. */\nconst SECTION_TYPE_ORDER = [\"decision\", \"preference\", \"progress\", \"fact\"] as const;\n\nexport type PackSection =\n | { readonly kind: \"pinned\"; readonly items: readonly ContextItem[] }\n | { readonly kind: \"latest-handoff\"; readonly items: readonly ContextItem[] }\n | { readonly kind: \"by-type\"; readonly type: ItemType; readonly items: readonly ContextItem[] };\n\nexport interface ContextPack {\n readonly projectName: ProjectName;\n readonly generatedAt: Date;\n readonly sections: readonly PackSection[];\n readonly includedCount: number;\n readonly totalCount: number;\n readonly estimatedTokens: number;\n}\n\nexport interface AssembleContextPackInput {\n readonly projectName: ProjectName;\n /** Newest first, archived excluded — the repository contract. */\n readonly items: readonly ContextItem[];\n readonly generatedAt: Date;\n /** Omit for an unbudgeted pack (export); Infinity means the same thing. */\n readonly budgetTokens?: number;\n}\n\n/** Mutable working state while the pack is being assembled. */\ninterface Draft {\n readonly sections: PackSection[];\n readonly included: Set<string>;\n readonly budget: number;\n usedTokens: number;\n}\n\nconst estimatePreambleTokens = (input: AssembleContextPackInput): number =>\n estimateTokens(\n `Context pack: ${input.projectName} — ${input.items.length} items, generated ${input.generatedAt.toISOString()}`,\n );\n\n/**\n * Choose what fits in the budget, newest first, and in what order it reads:\n * pinned, then the latest handoff, then a section per type. No item repeats.\n * Formatting is not this layer's business — sections carry entities.\n */\nexport function assembleContextPack(input: AssembleContextPackInput): ContextPack {\n const draft: Draft = {\n sections: [],\n included: new Set(),\n budget: input.budgetTokens ?? Number.POSITIVE_INFINITY,\n usedTokens: estimatePreambleTokens(input),\n };\n\n addPinned(draft, input.items);\n addLatestHandoff(draft, input.items);\n addTypeSections(draft, input.items);\n\n return {\n projectName: input.projectName,\n generatedAt: input.generatedAt,\n sections: draft.sections,\n includedCount: draft.included.size,\n totalCount: input.items.length,\n estimatedTokens: draft.usedTokens,\n };\n}\n\n/**\n * Pinned items, newest first. The newest pinned item is always included,\n * even over budget; when the budget runs out, the oldest pinned are cut first.\n */\nfunction addPinned(draft: Draft, items: readonly ContextItem[]): void {\n const pinned = items.filter((item) => item.pinned);\n if (pinned.length === 0) return;\n\n draft.usedTokens += estimateTokens(\"Pinned\");\n const kept: ContextItem[] = [];\n for (const item of pinned) {\n const cost = estimateItemTokens(item);\n if (kept.length > 0 && draft.usedTokens + cost > draft.budget) break;\n kept.push(item);\n draft.usedTokens += cost;\n draft.included.add(item.id);\n }\n draft.sections.push({ kind: \"pinned\", items: kept });\n}\n\n/** The latest handoff, if any and if it fits the remaining budget. */\nfunction addLatestHandoff(draft: Draft, items: readonly ContextItem[]): void {\n const handoff = items.find((item) => item.type === \"handoff\" && !draft.included.has(item.id));\n if (handoff === undefined) return;\n\n const cost = estimateItemTokens(handoff) + estimateTokens(\"Latest handoff\");\n if (draft.usedTokens + cost > draft.budget) return;\n draft.usedTokens += cost;\n draft.sections.push({ kind: \"latest-handoff\", items: [handoff] });\n draft.included.add(handoff.id);\n}\n\n/** Recent items by type in section order, newest first, until the budget is reached. */\nfunction addTypeSections(draft: Draft, items: readonly ContextItem[]): void {\n for (const type of SECTION_TYPE_ORDER) {\n const candidates = items.filter((item) => item.type === type && !draft.included.has(item.id));\n const kept: ContextItem[] = [];\n for (const item of candidates) {\n const cost = estimateItemTokens(item) + (kept.length === 0 ? estimateTokens(type) : 0);\n if (draft.usedTokens + cost > draft.budget) break;\n kept.push(item);\n draft.usedTokens += cost;\n draft.included.add(item.id);\n }\n if (kept.length > 0) draft.sections.push({ kind: \"by-type\", type, items: kept });\n }\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nconst PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;\n\n/** Unique project slug: 1-64 chars, lowercase letters, digits, hyphens (not leading). */\nexport type ProjectName = string & { readonly __brand: \"ProjectName\" };\n\nexport function parseProjectName(raw: string): Result<ProjectName, DomainError> {\n const normalized = raw.trim().toLowerCase();\n if (!PATTERN.test(normalized)) {\n return contextErr(\n \"INVALID_PROJECT_NAME\",\n `Project name must be 1-64 chars of [a-z0-9-], starting with a letter or digit. Got: \"${raw}\"`,\n );\n }\n return ok(normalized as ProjectName);\n}\n","import type { Clock } from \"../../../shared/application/ports/clock.js\";\nimport type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../../domain/errors.js\";\nimport {\n assembleContextPack,\n type ContextPack,\n DEFAULT_BUDGET_TOKENS,\n} from \"../../domain/services/context-pack.js\";\nimport { parseProjectName } from \"../../domain/values/project-name.js\";\nimport type { VaultSessions } from \"../ports/vault-session.js\";\n\nexport interface GetContextPackInput {\n project: string;\n /** Defaults to DEFAULT_BUDGET_TOKENS. Pass Infinity for the whole project (export). */\n budgetTokens?: number;\n}\n\nexport class GetContextPack implements UseCase<GetContextPackInput, ContextPack> {\n constructor(\n private readonly sessions: VaultSessions,\n private readonly clock: Clock,\n ) {}\n\n execute(input: GetContextPackInput): Result<ContextPack, DomainError> {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n\n return this.sessions.withSession((session) => {\n const project = session.projects.findByName(name.value);\n if (project === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n return ok(\n assembleContextPack({\n projectName: name.value,\n items: session.items.findByProject(project.id),\n generatedAt: this.clock.now(),\n budgetTokens: input.budgetTokens ?? DEFAULT_BUDGET_TOKENS,\n }),\n );\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { Content } from \"../values/content.js\";\nimport type { ItemType, StorableItemType } from \"../values/item-type.js\";\nimport type { Tag } from \"../values/tag.js\";\n\nexport interface ContextItem {\n readonly id: string;\n readonly projectId: string;\n readonly type: StorableItemType;\n readonly content: Content;\n readonly tags: readonly Tag[];\n readonly pinned: boolean;\n readonly source?: string;\n readonly archived: boolean;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport interface NewContextItem {\n readonly id: string;\n readonly projectId: string;\n readonly type: ItemType;\n readonly content: Content;\n readonly tags: readonly Tag[];\n readonly pinned: boolean;\n readonly source?: string;\n readonly now: Date;\n}\n\n/**\n * Mint a brand-new item. Total, not a Result: every field arrives as an\n * already-parsed value object, so there is no invariant left to break here.\n * Rehydration from storage is the repository's job.\n */\nexport function createContextItem(input: NewContextItem): ContextItem {\n return {\n id: input.id,\n projectId: input.projectId,\n type: input.type,\n content: input.content,\n tags: input.tags,\n pinned: input.pinned,\n ...(input.source === undefined ? {} : { source: input.source }),\n archived: false,\n createdAt: input.now,\n updatedAt: input.now,\n };\n}\n\nexport interface NewImportedContextItem {\n readonly projectId: string;\n /** The import source, e.g. \"chatgpt\" — kept as a plain string so the entity owes nothing to the importers module. */\n readonly source: string;\n readonly conversationId: string;\n readonly chunkIndex: number;\n readonly content: Content;\n readonly tags: readonly Tag[];\n /** The original conversation date — chronology is preserved. */\n readonly createdAt: Date;\n /** The import instant — so the project surfaces as freshly active. */\n readonly now: Date;\n}\n\n/**\n * A deterministic id for an imported chunk: the same (source, conversation,\n * chunk) always maps to the same id, so re-importing the same export upserts\n * instead of duplicating. Not a ULID — that is fine, ordering everywhere is by\n * created_at, never by id. Hashing is a pure computation, so it belongs here.\n */\nexport function importedItemId(\n projectId: string,\n source: string,\n conversationId: string,\n chunkIndex: number,\n): string {\n const digest = createHash(\"sha256\")\n .update(`${projectId} ${source} ${conversationId} ${chunkIndex}`)\n .digest(\"hex\");\n return `imp-${digest.slice(0, 32)}`;\n}\n\n/**\n * Mint an imported item. Total, like createContextItem, but it stamps the\n * historical createdAt separately from the import instant (updatedAt), fixes the\n * type to `imported`, is never pinned, and derives its id deterministically.\n */\nexport function createImportedContextItem(input: NewImportedContextItem): ContextItem {\n return {\n id: importedItemId(input.projectId, input.source, input.conversationId, input.chunkIndex),\n projectId: input.projectId,\n type: \"imported\",\n content: input.content,\n tags: input.tags,\n pinned: false,\n source: `${input.source}-import`,\n archived: false,\n createdAt: input.createdAt,\n updatedAt: input.now,\n };\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nexport const MAX_CONTENT_BYTES = 32 * 1024;\n\n/** The body of a context item: trimmed, non-empty, at most 32 KB of UTF-8. */\nexport type Content = string & { readonly __brand: \"Content\" };\n\nexport function parseContent(raw: string): Result<Content, DomainError> {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n return contextErr(\"CONTENT_EMPTY\", \"Content must not be empty.\");\n }\n const bytes = new TextEncoder().encode(trimmed).length;\n if (bytes > MAX_CONTENT_BYTES) {\n return contextErr(\n \"CONTENT_TOO_LARGE\",\n `Content is ${bytes} bytes; the maximum is ${MAX_CONTENT_BYTES} (32 KB). Distill it.`,\n );\n }\n return ok(trimmed as Content);\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nconst PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;\n\nexport const MAX_TAGS = 10;\n\n/** Lowercase tag: 1-32 chars of [a-z0-9-]. */\nexport type Tag = string & { readonly __brand: \"Tag\" };\n\nexport function parseTag(raw: string): Result<Tag, DomainError> {\n const normalized = raw.trim().toLowerCase();\n if (!PATTERN.test(normalized)) {\n return contextErr(\"INVALID_TAG\", `Tag must be 1-32 chars of [a-z0-9-]. Got: \"${raw}\"`);\n }\n return ok(normalized as Tag);\n}\n\nexport function parseTags(raw: readonly string[]): Result<Tag[], DomainError> {\n if (raw.length > MAX_TAGS) {\n return contextErr(\"TOO_MANY_TAGS\", `At most ${MAX_TAGS} tags allowed. Got ${raw.length}.`);\n }\n const tags: Tag[] = [];\n for (const r of raw) {\n const parsed = parseTag(r);\n if (!parsed.ok) return parsed;\n if (!tags.includes(parsed.value)) tags.push(parsed.value);\n }\n return ok(tags);\n}\n","import type { Clock, IdGenerator } from \"../../../shared/application/ports/clock.js\";\nimport type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { createImportedContextItem } from \"../../domain/entities/context-item.js\";\nimport type { Project } from \"../../domain/entities/project.js\";\nimport { parseContent } from \"../../domain/values/content.js\";\nimport { type ProjectName, parseProjectName } from \"../../domain/values/project-name.js\";\nimport { parseTags } from \"../../domain/values/tag.js\";\nimport type { VaultSession, VaultSessions } from \"../ports/vault-session.js\";\n\n/** One imported chunk, ready to persist. `source` is a plain string so context owes nothing to importers. */\nexport interface ImportedItemInput {\n source: string;\n conversationId: string;\n chunkIndex: number;\n content: string;\n createdAt: Date;\n tags: string[];\n}\n\nexport interface ImportItemsInput {\n projectName: string;\n items: ImportedItemInput[];\n}\n\nexport interface ImportItemFailure {\n conversationId: string;\n reason: string;\n}\n\nexport interface ImportItemsOutput {\n projectCreated: boolean;\n imported: number;\n failed: number;\n failures: ImportItemFailure[];\n}\n\n/**\n * Persist a batch of imported items in ONE session, auto-creating the target\n * project. Context stays the sole guardian of ContextItem and the `imported`\n * type; the importer only hands it drafts. Ids are deterministic, so re-running\n * an import upserts instead of duplicating. A single bad chunk is collected as a\n * failure, never aborting the batch.\n */\nexport class ImportItems implements UseCase<ImportItemsInput, ImportItemsOutput> {\n constructor(\n private readonly sessions: VaultSessions,\n private readonly clock: Clock,\n private readonly idGen: IdGenerator,\n ) {}\n\n execute(input: ImportItemsInput): Result<ImportItemsOutput, DomainError> {\n const name = parseProjectName(input.projectName);\n if (!name.ok) return name;\n\n return this.sessions.withSession((session) => {\n const { project, created } = this.findOrCreateProject(session, name.value);\n const failures: ImportItemFailure[] = [];\n let imported = 0;\n for (const draft of input.items) {\n const saved = this.saveDraft(session, project.id, draft);\n if (saved.ok) imported += 1;\n else failures.push({ conversationId: draft.conversationId, reason: saved.error.message });\n }\n return ok({ projectCreated: created, imported, failed: failures.length, failures });\n });\n }\n\n /** Re-validate tags and content at the vault boundary — defense in depth, even though the renderer aims well under the limit. */\n private saveDraft(\n session: VaultSession,\n projectId: string,\n draft: ImportedItemInput,\n ): Result<void, DomainError> {\n const tags = parseTags(draft.tags);\n if (!tags.ok) return tags;\n const content = parseContent(draft.content);\n if (!content.ok) return content;\n\n session.items.save(\n createImportedContextItem({\n projectId,\n source: draft.source,\n conversationId: draft.conversationId,\n chunkIndex: draft.chunkIndex,\n content: content.value,\n tags: tags.value,\n createdAt: draft.createdAt,\n now: this.clock.now(),\n }),\n );\n return ok(undefined);\n }\n\n private findOrCreateProject(\n session: VaultSession,\n name: ProjectName,\n ): { project: Project; created: boolean } {\n const existing = session.projects.findByName(name);\n if (existing !== null) return { project: existing, created: false };\n\n const now = this.clock.now();\n const project: Project = { id: this.idGen.next(), name, createdAt: now, updatedAt: now };\n session.projects.save(project);\n return { project, created: true };\n }\n}\n","import type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type { VaultSessions } from \"../ports/vault-session.js\";\n\nexport interface ProjectListEntry {\n name: string;\n description?: string;\n itemCount: number;\n lastActivityAt: string | null;\n}\n\nexport class ListProjects implements UseCase<void, ProjectListEntry[]> {\n constructor(private readonly sessions: VaultSessions) {}\n\n execute(): Result<ProjectListEntry[], DomainError> {\n return this.sessions.withSession((session) => {\n const entries = session.projects.list().map((summary) => ({\n name: summary.project.name as string,\n ...(summary.project.description === undefined\n ? {}\n : { description: summary.project.description }),\n itemCount: summary.itemCount,\n lastActivityAt: summary.lastActivityAt?.toISOString() ?? null,\n }));\n return ok(entries);\n });\n }\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../errors.js\";\n\nexport const ITEM_TYPES = [\"decision\", \"progress\", \"preference\", \"fact\", \"handoff\"] as const;\n\nexport type ItemType = (typeof ITEM_TYPES)[number];\n\nexport function parseItemType(raw: string): Result<ItemType, DomainError> {\n if ((ITEM_TYPES as readonly string[]).includes(raw)) {\n return ok(raw as ItemType);\n }\n return contextErr(\n \"INVALID_ITEM_TYPE\",\n `Item type must be one of ${ITEM_TYPES.join(\", \")}. Got: \"${raw}\"`,\n );\n}\n\n/**\n * Every type that may be STORED, including `imported`. Deliberately wider than\n * ITEM_TYPES (the five a user or AI may save): imported items are minted only by\n * the importer, never through the save path or the MCP surface — so widening\n * what can be stored never widens what a model can create.\n */\nexport const STORABLE_ITEM_TYPES = [...ITEM_TYPES, \"imported\"] as const;\n\nexport type StorableItemType = (typeof STORABLE_ITEM_TYPES)[number];\n\nexport function parseStorableItemType(raw: string): Result<StorableItemType, DomainError> {\n if ((STORABLE_ITEM_TYPES as readonly string[]).includes(raw)) {\n return ok(raw as StorableItemType);\n }\n return contextErr(\n \"INVALID_ITEM_TYPE\",\n `Item type must be one of ${STORABLE_ITEM_TYPES.join(\", \")}. Got: \"${raw}\"`,\n );\n}\n","import type { Clock, IdGenerator } from \"../../../shared/application/ports/clock.js\";\nimport type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { createContextItem } from \"../../domain/entities/context-item.js\";\nimport type { Project } from \"../../domain/entities/project.js\";\nimport { type Content, parseContent } from \"../../domain/values/content.js\";\nimport { type ItemType, parseItemType } from \"../../domain/values/item-type.js\";\nimport { type ProjectName, parseProjectName } from \"../../domain/values/project-name.js\";\nimport { parseTags, type Tag } from \"../../domain/values/tag.js\";\nimport type { VaultSession, VaultSessions } from \"../ports/vault-session.js\";\n\nexport interface SaveContextInput {\n project: string;\n content: string;\n type?: string;\n tags?: string[];\n pinned?: boolean;\n source?: string;\n}\n\nexport interface SaveContextOutput {\n itemId: string;\n project: string;\n type: ItemType;\n projectCreated: boolean;\n}\n\ninterface ValidatedSave {\n name: ProjectName;\n type: ItemType;\n tags: Tag[];\n content: Content;\n pinned: boolean;\n source?: string;\n}\n\nexport class SaveContext implements UseCase<SaveContextInput, SaveContextOutput> {\n constructor(\n private readonly sessions: VaultSessions,\n private readonly clock: Clock,\n private readonly idGen: IdGenerator,\n ) {}\n\n execute(input: SaveContextInput): Result<SaveContextOutput, DomainError> {\n const validated = this.parseInput(input);\n if (!validated.ok) return validated;\n\n return this.sessions.withSession((session) => {\n const { project, created } = this.findOrCreateProject(session, validated.value.name);\n const item = createContextItem({\n id: this.idGen.next(),\n projectId: project.id,\n type: validated.value.type,\n content: validated.value.content,\n tags: validated.value.tags,\n pinned: validated.value.pinned,\n ...(validated.value.source === undefined ? {} : { source: validated.value.source }),\n now: this.clock.now(),\n });\n session.items.save(item);\n return ok({\n itemId: item.id,\n project: validated.value.name as string,\n type: validated.value.type,\n projectCreated: created,\n });\n });\n }\n\n /** Everything is parsed before a session is opened: bad input never touches the vault. */\n private parseInput(input: SaveContextInput): Result<ValidatedSave, DomainError> {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n const type = parseItemType(input.type ?? \"fact\");\n if (!type.ok) return type;\n const tags = parseTags(input.tags ?? []);\n if (!tags.ok) return tags;\n const content = parseContent(input.content);\n if (!content.ok) return content;\n return ok({\n name: name.value,\n type: type.value,\n tags: tags.value,\n content: content.value,\n pinned: input.pinned ?? false,\n ...(input.source === undefined ? {} : { source: input.source }),\n });\n }\n\n private findOrCreateProject(\n session: VaultSession,\n name: ProjectName,\n ): { project: Project; created: boolean } {\n const existing = session.projects.findByName(name);\n if (existing !== null) return { project: existing, created: false };\n\n const now = this.clock.now();\n const project: Project = { id: this.idGen.next(), name, createdAt: now, updatedAt: now };\n session.projects.save(project);\n return { project, created: true };\n }\n}\n","import type { ContextItem } from \"../../domain/entities/context-item.js\";\nimport type { StorableItemType } from \"../../domain/values/item-type.js\";\nimport type { ProjectName } from \"../../domain/values/project-name.js\";\n\n/**\n * How a context item leaves the application layer: primitives only, no value\n * objects and no Date. Shared by every read use case so delivery has one shape\n * to render.\n */\nexport interface ContextItemView {\n id: string;\n project: string;\n type: StorableItemType;\n content: string;\n tags: string[];\n pinned: boolean;\n source?: string;\n createdAt: string;\n}\n\nexport const toContextItemView = (\n item: ContextItem,\n projectName: ProjectName,\n): ContextItemView => ({\n id: item.id,\n project: projectName as string,\n type: item.type,\n content: item.content as string,\n tags: [...item.tags],\n pinned: item.pinned,\n ...(item.source === undefined ? {} : { source: item.source }),\n createdAt: item.createdAt.toISOString(),\n});\n","import type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../../domain/errors.js\";\nimport { parseProjectName } from \"../../domain/values/project-name.js\";\nimport { type ContextItemView, toContextItemView } from \"../dto/context-item-view.js\";\nimport type { VaultSession, VaultSessions } from \"../ports/vault-session.js\";\n\nexport interface SearchContextInput {\n query: string;\n project?: string;\n limit?: number;\n}\n\nconst MAX_LIMIT = 100;\nconst DEFAULT_LIMIT = 20;\n\nexport class SearchContext implements UseCase<SearchContextInput, ContextItemView[]> {\n constructor(private readonly sessions: VaultSessions) {}\n\n execute(input: SearchContextInput): Result<ContextItemView[], DomainError> {\n return this.sessions.withSession((session) => {\n const scope = this.resolveProjectScope(session, input.project);\n if (!scope.ok) return scope;\n\n const limit = Math.min(Math.max(input.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);\n const hits = session.items\n .search(input.query, scope.value, limit)\n .map((result) => toContextItemView(result.item, result.projectName));\n return ok(hits);\n });\n }\n\n /** No project given → search everywhere; otherwise the project must exist. */\n private resolveProjectScope(\n session: VaultSession,\n project: string | undefined,\n ): Result<string | undefined, DomainError> {\n if (project === undefined) return ok(undefined);\n const name = parseProjectName(project);\n if (!name.ok) return name;\n const found = session.projects.findByName(name.value);\n if (found === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${name.value}\".`);\n }\n return ok(found.id);\n }\n}\n","import type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { contextErr } from \"../../domain/errors.js\";\nimport { parseStorableItemType, type StorableItemType } from \"../../domain/values/item-type.js\";\nimport { type ProjectName, parseProjectName } from \"../../domain/values/project-name.js\";\nimport { type ContextItemView, toContextItemView } from \"../dto/context-item-view.js\";\nimport type { VaultSessions } from \"../ports/vault-session.js\";\n\nexport interface ShowProjectInput {\n project: string;\n type?: string;\n}\n\ninterface ShowFilters {\n name: ProjectName;\n type?: StorableItemType;\n}\n\nexport class ShowProject implements UseCase<ShowProjectInput, ContextItemView[]> {\n constructor(private readonly sessions: VaultSessions) {}\n\n execute(input: ShowProjectInput): Result<ContextItemView[], DomainError> {\n const filters = this.parseFilters(input);\n if (!filters.ok) return filters;\n\n return this.sessions.withSession((session) => {\n const found = session.projects.findByName(filters.value.name);\n if (found === null) {\n return contextErr(\"PROJECT_NOT_FOUND\", `No project named \"${filters.value.name}\".`);\n }\n const items = session.items.findByProject(\n found.id,\n filters.value.type === undefined ? {} : { type: filters.value.type },\n );\n return ok(items.map((item) => toContextItemView(item, filters.value.name)));\n });\n }\n\n private parseFilters(input: ShowProjectInput): Result<ShowFilters, DomainError> {\n const name = parseProjectName(input.project);\n if (!name.ok) return name;\n if (input.type === undefined) return ok({ name: name.value });\n const parsed = parseStorableItemType(input.type);\n if (!parsed.ok) return parsed;\n return ok({ name: name.value, type: parsed.value });\n }\n}\n","import { copyFileSync, rmSync } from \"node:fs\";\nimport type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport { MIGRATION_001 } from \"./migrations/001-init.js\";\nimport { MIGRATION_002 } from \"./migrations/002-imported-type.js\";\n\ninterface Migration {\n version: number;\n sql: string;\n /** Take a ciphertext backup before applying — for table-rebuild migrations that touch real data. */\n backup?: boolean;\n}\n\nconst MIGRATIONS: readonly Migration[] = [\n { version: 1, sql: MIGRATION_001 },\n { version: 2, sql: MIGRATION_002, backup: true },\n];\n\n/**\n * Bring the database up to the latest schema. `dbPath` is optional so callers\n * that only need the schema (a fresh init) can omit it; when a backup-flagged\n * migration upgrades a populated vault, the path lets the runner snapshot the\n * ciphertext file first.\n */\nexport function migrate(db: Database, dbPath?: string): void {\n db.exec(\"CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)\");\n const current = schemaVersion(db);\n for (const migration of MIGRATIONS) {\n if (migration.version <= current) continue;\n applyMigration(db, migration, current, dbPath);\n }\n}\n\n/**\n * Apply one migration atomically. A backup is taken only when upgrading an\n * existing vault (current >= 1) with a known path — never on a fresh init. The\n * transaction commits or rolls back as a unit; on failure the backup is kept for\n * recovery, on success it is removed.\n */\nfunction applyMigration(\n db: Database,\n migration: Migration,\n current: number,\n dbPath: string | undefined,\n): void {\n const backupPath =\n migration.backup === true && current >= 1 && dbPath !== undefined\n ? backupCiphertext(db, dbPath, migration.version)\n : null;\n\n db.transaction(() => {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.version);\n })();\n\n if (backupPath !== null) rmSync(backupPath, { force: true });\n}\n\n/** Checkpoint the WAL so the file on disk is complete, then copy the still-encrypted db aside. */\nfunction backupCiphertext(db: Database, dbPath: string, version: number): string {\n db.pragma(\"wal_checkpoint(TRUNCATE)\");\n const backupPath = `${dbPath}.pre-${String(version).padStart(3, \"0\")}.bak`;\n copyFileSync(dbPath, backupPath);\n return backupPath;\n}\n\nfunction setSchemaVersion(db: Database, version: number): void {\n db.prepare(\n \"INSERT INTO meta (key, value) VALUES ('schema_version', ?) \" +\n \"ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n ).run(String(version));\n}\n\nexport function schemaVersion(db: Database): number {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\").get() as\n | { value: string }\n | undefined;\n return row ? Number(row.value) : 0;\n}\n","export const MIGRATION_001 = `\nCREATE TABLE projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE context_items (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id),\n type TEXT NOT NULL CHECK (type IN ('decision','progress','preference','fact','handoff')),\n content TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n pinned INTEGER NOT NULL DEFAULT 0,\n source TEXT,\n archived INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE INDEX idx_items_project ON context_items(project_id, created_at DESC);\n\nCREATE VIRTUAL TABLE context_items_fts USING fts5(\n content,\n tags,\n content='context_items',\n content_rowid='rowid'\n);\n\nCREATE TRIGGER items_ai AFTER INSERT ON context_items BEGIN\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n\nCREATE TRIGGER items_ad AFTER DELETE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\nEND;\n\nCREATE TRIGGER items_au AFTER UPDATE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n`;\n","/**\n * Extends the context_items.type CHECK to accept 'imported'. SQLite cannot ALTER\n * a CHECK constraint, so the table is rebuilt: drop the FTS triggers, recreate\n * the table with the wider CHECK, copy every row, swap names, recreate the index\n * and triggers, then rebuild the FTS index (the rebuild changes rowids, and the\n * external-content FTS is keyed on rowid — skipping the rebuild would silently\n * break search). The whole script runs inside the migration runner's single\n * transaction, so it commits or rolls back as a unit.\n */\nexport const MIGRATION_002 = `\nDROP TRIGGER items_ai;\nDROP TRIGGER items_ad;\nDROP TRIGGER items_au;\n\nCREATE TABLE context_items_new (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id),\n type TEXT NOT NULL CHECK (type IN ('decision','progress','preference','fact','handoff','imported')),\n content TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n pinned INTEGER NOT NULL DEFAULT 0,\n source TEXT,\n archived INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nINSERT INTO context_items_new\n (id, project_id, type, content, tags, pinned, source, archived, created_at, updated_at)\nSELECT\n id, project_id, type, content, tags, pinned, source, archived, created_at, updated_at\nFROM context_items;\n\nDROP TABLE context_items;\nALTER TABLE context_items_new RENAME TO context_items;\n\nCREATE INDEX idx_items_project ON context_items(project_id, created_at DESC);\n\nCREATE TRIGGER items_ai AFTER INSERT ON context_items BEGIN\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n\nCREATE TRIGGER items_ad AFTER DELETE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\nEND;\n\nCREATE TRIGGER items_au AFTER UPDATE ON context_items BEGIN\n INSERT INTO context_items_fts(context_items_fts, rowid, content, tags)\n VALUES ('delete', old.rowid, old.content, old.tags);\n INSERT INTO context_items_fts(rowid, content, tags)\n VALUES (new.rowid, new.content, new.tags);\nEND;\n\nINSERT INTO context_items_fts(context_items_fts) VALUES('rebuild');\n`;\n","import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport SqliteDatabase, { type Database } from \"better-sqlite3-multiple-ciphers\";\n\n/**\n * Open (or create) the SQLCipher vault database with a raw 32-byte key.\n * Throws SqliteError (SQLITE_NOTADB) if the key is wrong for an existing file.\n *\n * The single physical database is the shared persistence kernel: the vault\n * module opens it to verify keys, the context module opens it for repositories.\n */\nexport function openVaultDb(dbPath: string, keyHex: string): Database {\n if (!/^[0-9a-f]{64}$/i.test(keyHex)) {\n throw new Error(\"Vault key must be 64 hex characters (32 bytes).\");\n }\n mkdirSync(dirname(dbPath), { recursive: true });\n const db = new SqliteDatabase(dbPath);\n try {\n db.pragma(\"cipher='sqlcipher'\");\n db.pragma(`key=\"x'${keyHex}'\"`);\n // Touching the schema forces key verification: wrong key -> SQLITE_NOTADB.\n db.prepare(\"SELECT count(*) FROM sqlite_master\").get();\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n return db;\n } catch (error) {\n db.close();\n throw error;\n }\n}\n\nexport function isWrongKeyError(error: unknown): boolean {\n return (\n error instanceof Error &&\n \"code\" in error &&\n (error as { code?: string }).code === \"SQLITE_NOTADB\"\n );\n}\n","import { DomainError, err, type Result } from \"../../shared/domain/result.js\";\n\n/** Error vocabulary of the VAULT bounded context (security language). */\nexport type VaultErrorCode =\n | \"VAULT_NOT_FOUND\"\n | \"VAULT_ALREADY_EXISTS\"\n | \"VAULT_LOCKED\"\n | \"WRONG_PASSPHRASE\"\n | \"WEAK_PASSPHRASE\"\n | \"KEYCHAIN_ERROR\"\n | \"STORAGE_ERROR\";\n\nexport const vaultErr = (code: VaultErrorCode, message: string): Result<never, DomainError> =>\n err(new DomainError(code, message));\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { VaultHeaderData } from \"../application/ports/vault-store.js\";\nimport { vaultErr } from \"../domain/errors.js\";\n\nconst headerSchema = z.object({\n vaultId: z.string().min(1),\n schemaVersion: z.literal(1),\n kdf: z.object({\n algorithm: z.literal(\"argon2id\"),\n memoryKiB: z.number().int().positive(),\n iterations: z.number().int().positive(),\n parallelism: z.number().int().positive(),\n }),\n saltBase64: z.string().min(1),\n createdAt: z.string(),\n});\n\nexport type VaultHeader = VaultHeaderData;\n\nexport function writeVaultHeader(path: string, header: VaultHeader): void {\n const json = {\n vaultId: header.vaultId,\n schemaVersion: header.schemaVersion,\n kdf: header.kdf,\n saltBase64: Buffer.from(header.salt).toString(\"base64\"),\n createdAt: header.createdAt,\n };\n writeFileSync(path, `${JSON.stringify(json, null, 2)}\\n`, \"utf8\");\n}\n\nexport function readVaultHeader(path: string): Result<VaultHeader, DomainError> {\n if (!existsSync(path)) {\n return vaultErr(\"VAULT_NOT_FOUND\", `No vault header found at ${path}. Run \"valija init\".`);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return vaultErr(\"STORAGE_ERROR\", `Vault header at ${path} is not valid JSON.`);\n }\n const parsed = headerSchema.safeParse(raw);\n if (!parsed.success) {\n return vaultErr(\n \"STORAGE_ERROR\",\n `Vault header at ${path} is malformed: ${parsed.error.message}`,\n );\n }\n const h = parsed.data;\n return ok({\n vaultId: h.vaultId,\n schemaVersion: h.schemaVersion,\n kdf: h.kdf,\n salt: new Uint8Array(Buffer.from(h.saltBase64, \"base64\")),\n createdAt: h.createdAt,\n });\n}\n","import type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport type {\n ContextItemRepository,\n FindByProjectFilters,\n SearchResult,\n} from \"../application/ports/repositories.js\";\nimport type { ContextItem } from \"../domain/entities/context-item.js\";\nimport type { Content } from \"../domain/values/content.js\";\nimport type { StorableItemType } from \"../domain/values/item-type.js\";\nimport type { ProjectName } from \"../domain/values/project-name.js\";\nimport type { Tag } from \"../domain/values/tag.js\";\n\ninterface ItemRow {\n id: string;\n project_id: string;\n type: string;\n content: string;\n tags: string;\n pinned: number;\n source: string | null;\n archived: number;\n created_at: string;\n updated_at: string;\n}\n\nconst toItem = (row: ItemRow): ContextItem => ({\n id: row.id,\n projectId: row.project_id,\n type: row.type as StorableItemType,\n content: row.content as Content,\n tags: JSON.parse(row.tags) as Tag[],\n pinned: row.pinned === 1,\n ...(row.source === null ? {} : { source: row.source }),\n archived: row.archived === 1,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n});\n\n/** Quote each term so user input cannot break FTS5 query syntax. Terms are ANDed. */\nconst toFtsQuery = (query: string): string =>\n query\n .split(/\\s+/)\n .filter(Boolean)\n .map((term) => `\"${term.replace(/\"/g, '\"\"')}\"`)\n .join(\" \");\n\nexport class SqliteContextItemRepository implements ContextItemRepository {\n constructor(private readonly db: Database) {}\n\n save(item: ContextItem): void {\n this.db\n .prepare(\n `INSERT INTO context_items\n (id, project_id, type, content, tags, pinned, source, archived, created_at, updated_at)\n VALUES (@id, @projectId, @type, @content, @tags, @pinned, @source, @archived, @createdAt, @updatedAt)\n ON CONFLICT(id) DO UPDATE SET\n type = excluded.type,\n content = excluded.content,\n tags = excluded.tags,\n pinned = excluded.pinned,\n source = excluded.source,\n archived = excluded.archived,\n updated_at = excluded.updated_at`,\n )\n .run({\n id: item.id,\n projectId: item.projectId,\n type: item.type,\n content: item.content,\n tags: JSON.stringify(item.tags),\n pinned: item.pinned ? 1 : 0,\n source: item.source ?? null,\n archived: item.archived ? 1 : 0,\n createdAt: item.createdAt.toISOString(),\n updatedAt: item.updatedAt.toISOString(),\n });\n }\n\n findByProject(projectId: string, filters: FindByProjectFilters = {}): ContextItem[] {\n const conditions = [\"project_id = @projectId\"];\n const params: Record<string, unknown> = { projectId };\n if (!filters.includeArchived) conditions.push(\"archived = 0\");\n if (filters.type !== undefined) {\n conditions.push(\"type = @type\");\n params.type = filters.type;\n }\n if (filters.pinned !== undefined) {\n conditions.push(\"pinned = @pinned\");\n params.pinned = filters.pinned ? 1 : 0;\n }\n const limit = filters.limit !== undefined ? ` LIMIT ${Math.max(0, filters.limit)}` : \"\";\n const rows = this.db\n .prepare(\n `SELECT * FROM context_items WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC${limit}`,\n )\n .all(params) as ItemRow[];\n return rows.map(toItem);\n }\n\n search(query: string, projectId?: string, limit = 20): SearchResult[] {\n const fts = toFtsQuery(query);\n if (fts.length === 0) return [];\n const projectFilter = projectId !== undefined ? \"AND i.project_id = @projectId\" : \"\";\n const rows = this.db\n .prepare(\n `SELECT i.*, p.name AS project_name\n FROM context_items_fts f\n JOIN context_items i ON i.rowid = f.rowid\n JOIN projects p ON p.id = i.project_id\n WHERE context_items_fts MATCH @fts AND i.archived = 0 ${projectFilter}\n ORDER BY rank LIMIT @limit`,\n )\n .all({ fts, projectId, limit }) as Array<ItemRow & { project_name: string }>;\n return rows.map((row) => ({\n item: toItem(row),\n projectName: row.project_name as ProjectName,\n }));\n }\n\n archive(itemId: string): boolean {\n const result = this.db\n .prepare(\"UPDATE context_items SET archived = 1 WHERE id = ?\")\n .run(itemId);\n return result.changes > 0;\n }\n}\n","import type { Database } from \"better-sqlite3-multiple-ciphers\";\nimport type { ProjectRepository } from \"../application/ports/repositories.js\";\nimport type { Project, ProjectSummary } from \"../domain/entities/project.js\";\nimport type { ProjectName } from \"../domain/values/project-name.js\";\n\ninterface ProjectRow {\n id: string;\n name: string;\n description: string | null;\n created_at: string;\n updated_at: string;\n}\n\nconst toProject = (row: ProjectRow): Project => ({\n id: row.id,\n name: row.name as ProjectName,\n ...(row.description === null ? {} : { description: row.description }),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n});\n\nexport class SqliteProjectRepository implements ProjectRepository {\n constructor(private readonly db: Database) {}\n\n save(project: Project): void {\n this.db\n .prepare(\n `INSERT INTO projects (id, name, description, created_at, updated_at)\n VALUES (@id, @name, @description, @createdAt, @updatedAt)\n ON CONFLICT(id) DO UPDATE SET\n name = excluded.name,\n description = excluded.description,\n updated_at = excluded.updated_at`,\n )\n .run({\n id: project.id,\n name: project.name,\n description: project.description ?? null,\n createdAt: project.createdAt.toISOString(),\n updatedAt: project.updatedAt.toISOString(),\n });\n }\n\n findByName(name: ProjectName): Project | null {\n const row = this.db.prepare(\"SELECT * FROM projects WHERE name = ?\").get(name) as\n | ProjectRow\n | undefined;\n return row ? toProject(row) : null;\n }\n\n list(): ProjectSummary[] {\n const rows = this.db\n .prepare(\n `SELECT p.*,\n COUNT(i.id) AS item_count,\n MAX(i.updated_at) AS last_activity\n FROM projects p\n LEFT JOIN context_items i ON i.project_id = p.id AND i.archived = 0\n GROUP BY p.id\n ORDER BY last_activity DESC NULLS LAST, p.name ASC`,\n )\n .all() as Array<ProjectRow & { item_count: number; last_activity: string | null }>;\n return rows.map((row) => ({\n project: toProject(row),\n itemCount: row.item_count,\n lastActivityAt: row.last_activity ? new Date(row.last_activity) : null,\n }));\n }\n}\n","import { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { migrate } from \"../../shared/infra/migrations.js\";\nimport { isWrongKeyError, openVaultDb } from \"../../shared/infra/sqlite.js\";\nimport type { VaultPaths } from \"../../shared/infra/vault-paths.js\";\nimport type { KeychainPort } from \"../../vault/application/ports/keychain.js\";\nimport { vaultErr } from \"../../vault/domain/errors.js\";\nimport { readVaultHeader } from \"../../vault/infra/vault-header.js\";\nimport type { VaultSession, VaultSessions } from \"../application/ports/vault-session.js\";\nimport { SqliteContextItemRepository } from \"./item-repo.js\";\nimport { SqliteProjectRepository } from \"./project-repo.js\";\n\nconst LOCKED_MESSAGE = 'Vault is locked. Ask the user to run \"valija unlock\" in a terminal.';\n\n/**\n * Open a session, run the action, and always close the session — even when the\n * action throws. Kept generic (no SQLite here) so the lifecycle guarantee can be\n * verified in isolation.\n */\nexport function runWithSession<T>(\n open: () => Result<VaultSession, DomainError>,\n action: (session: VaultSession) => Result<T, DomainError>,\n): Result<T, DomainError> {\n const session = open();\n if (!session.ok) return session;\n try {\n return action(session.value);\n } finally {\n session.value.close();\n }\n}\n\n/**\n * Implements the context-owned VaultSessions port by wiring vault concerns\n * (keychain, header) to the shared SQLite engine. This is the one place where\n * the context module depends on the vault module.\n */\nexport class SqliteVaultSessions implements VaultSessions {\n constructor(\n private readonly paths: VaultPaths,\n private readonly keychain: KeychainPort,\n ) {}\n\n withSession<T>(\n action: (session: VaultSession) => Result<T, DomainError>,\n ): Result<T, DomainError> {\n return runWithSession(() => this.open(), action);\n }\n\n private open(): Result<VaultSession, DomainError> {\n const header = readVaultHeader(this.paths.header);\n if (!header.ok) return header;\n\n const keyHex = this.requireKey(header.value.vaultId);\n if (!keyHex.ok) return keyHex;\n\n return this.openRepositories(header.value.vaultId, keyHex.value);\n }\n\n /** The session key must be present in the OS keychain — otherwise the vault is locked. */\n private requireKey(vaultId: string): Result<string, DomainError> {\n const keyHex = this.keychain.getKey(vaultId);\n if (keyHex === null) return vaultErr(\"VAULT_LOCKED\", LOCKED_MESSAGE);\n return ok(keyHex);\n }\n\n private openRepositories(vaultId: string, keyHex: string): Result<VaultSession, DomainError> {\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n migrate(db, this.paths.db);\n return ok({\n projects: new SqliteProjectRepository(db),\n items: new SqliteContextItemRepository(db),\n close: () => db.close(),\n });\n } catch (error) {\n if (isWrongKeyError(error)) {\n // Stale key in the keychain (e.g. vault file replaced) — treat as locked.\n this.keychain.deleteKey(vaultId);\n return vaultErr(\"VAULT_LOCKED\", LOCKED_MESSAGE);\n }\n return vaultErr(\"STORAGE_ERROR\", `Could not open vault: ${(error as Error).message}`);\n }\n }\n}\n","import { DomainError, err, type Result } from \"../../shared/domain/result.js\";\n\n/** Error vocabulary of the IMPORTERS bounded context (conversation-import language). */\nexport type ImporterErrorCode =\n | \"UNSUPPORTED_SOURCE\"\n | \"MALFORMED_EXPORT\"\n | \"EMPTY_EXPORT\"\n | \"UNREADABLE_FILE\"\n | \"CORRUPT_ARCHIVE\"\n | \"INVALID_SELECTION\"\n | \"NO_CONVERSATIONS_SELECTED\"\n | \"UNSUPPORTED_GENERIC_VERSION\";\n\nexport const importerErr = (code: ImporterErrorCode, message: string): Result<never, DomainError> =>\n err(new DomainError(code, message));\n","import type { Conversation, Message, Role } from \"../entities/conversation.js\";\nimport type { ImportSource } from \"../values/import-source.js\";\n\n/**\n * Turn one normalized conversation into one-or-more markdown item bodies, each\n * sized to land safely inside the vault's content limit (32 KB UTF-8). The 28 KB\n * budget is deliberate headroom so the provenance header and markdown never push\n * a chunk over. Pure and deterministic — no vault, no fflate, no I/O.\n */\nconst DEFAULT_BYTE_BUDGET = 28 * 1024;\nconst HEADER_RESERVE = 768;\nconst SEPARATOR = \"\\n\\n\";\nconst MAX_TITLE_CHARS = 120;\n\nconst encoder = new TextEncoder();\nconst byteLength = (text: string): number => encoder.encode(text).length;\n\nconst ROLE_LABEL: Record<Role, string> = { user: \"User\", assistant: \"Assistant\", system: \"System\" };\nconst SOURCE_LABEL: Record<ImportSource, string> = {\n chatgpt: \"ChatGPT\",\n claude: \"Claude\",\n generic: \"Generic\",\n};\n\nconst renderMessage = (message: Message): string =>\n `**${ROLE_LABEL[message.role]}:** ${message.content}`;\n\n/** Split one string at codepoint boundaries so no piece exceeds `limit` bytes and UTF-8 is never cut mid-sequence. */\nfunction hardSplit(text: string, limit: number): string[] {\n const pieces: string[] = [];\n let buffer = \"\";\n let bufferBytes = 0;\n for (const char of text) {\n const charBytes = byteLength(char);\n if (bufferBytes + charBytes > limit && buffer.length > 0) {\n pieces.push(buffer);\n buffer = \"\";\n bufferBytes = 0;\n }\n buffer += char;\n bufferBytes += charBytes;\n }\n if (buffer.length > 0) pieces.push(buffer);\n return pieces;\n}\n\n/** Greedily pack rendered messages into bodies that each fit within `limit` bytes, splitting on message boundaries first. */\nfunction packBodies(messages: readonly Message[], limit: number): string[] {\n const bodies: string[] = [];\n let current: string[] = [];\n let currentBytes = 0;\n\n const flush = (): void => {\n if (current.length > 0) {\n bodies.push(current.join(SEPARATOR));\n current = [];\n currentBytes = 0;\n }\n };\n\n for (const message of messages) {\n const block = renderMessage(message);\n const blockBytes = byteLength(block);\n\n if (blockBytes > limit) {\n flush();\n for (const piece of hardSplit(block, limit)) bodies.push(piece);\n continue;\n }\n\n const cost = (current.length > 0 ? byteLength(SEPARATOR) : 0) + blockBytes;\n if (currentBytes + cost > limit) flush();\n current.push(block);\n currentBytes += current.length > 1 ? byteLength(SEPARATOR) + blockBytes : blockBytes;\n }\n flush();\n return bodies;\n}\n\nfunction provenanceHeader(\n conversation: Conversation,\n source: ImportSource,\n part: number,\n total: number,\n): string {\n const title =\n conversation.title.length > MAX_TITLE_CHARS\n ? `${conversation.title.slice(0, MAX_TITLE_CHARS - 3)}...`\n : conversation.title;\n const date = conversation.createdAt.toISOString().slice(0, 10);\n return `> Imported from ${SOURCE_LABEL[source]} · \"${title}\" · ${date} · part ${part}/${total}`;\n}\n\nexport function renderConversationChunks(\n conversation: Conversation,\n source: ImportSource,\n byteBudget: number = DEFAULT_BYTE_BUDGET,\n): string[] {\n const limit = byteBudget - HEADER_RESERVE;\n const bodies = packBodies(conversation.messages, limit);\n const total = bodies.length;\n return bodies.map(\n (body, index) => `${provenanceHeader(conversation, source, index + 1, total)}\\n\\n${body}`,\n );\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type { Conversation } from \"../entities/conversation.js\";\nimport { importerErr } from \"../errors.js\";\n\nexport interface SelectionFilters {\n all?: boolean;\n pick?: string;\n query?: string;\n since?: string;\n}\n\n/**\n * Parse a `--pick` spec like \"1,3-5\" into sorted, unique, **0-based** indices.\n * Indices are 1-based in the spec (they mirror the printed listing); any\n * non-numeric token, out-of-range value, or reversed range is a selection error.\n */\nexport function parsePickSpec(spec: string, count: number): Result<number[], DomainError> {\n const tokens = spec\n .split(\",\")\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n if (tokens.length === 0) {\n return importerErr(\"INVALID_SELECTION\", \"--pick is empty.\");\n }\n\n const indices = new Set<number>();\n for (const token of tokens) {\n const range = token.match(/^(\\d+)-(\\d+)$/);\n const single = token.match(/^(\\d+)$/);\n if (range) {\n const start = Number(range[1]);\n const end = Number(range[2]);\n if (start < 1 || end > count || start > end) {\n return importerErr(\n \"INVALID_SELECTION\",\n `--pick range \"${token}\" is out of bounds (valid: 1-${count}).`,\n );\n }\n for (let i = start; i <= end; i++) indices.add(i - 1);\n } else if (single) {\n const index = Number(single[1]);\n if (index < 1 || index > count) {\n return importerErr(\n \"INVALID_SELECTION\",\n `--pick index \"${token}\" is out of bounds (valid: 1-${count}).`,\n );\n }\n indices.add(index - 1);\n } else {\n return importerErr(\"INVALID_SELECTION\", `--pick token \"${token}\" is not a number or range.`);\n }\n }\n return ok([...indices].sort((a, b) => a - b));\n}\n\n/**\n * Narrow a chronological-ascending conversation list by the CLI selection flags.\n * `--pick` resolves against the full printed order first, so its indices stay\n * stable regardless of the other flags; `--since` and `--query` then filter.\n * An empty result is a selection error, never a silent no-op.\n */\nexport function selectConversations(\n conversations: readonly Conversation[],\n filters: SelectionFilters,\n): Result<Conversation[], DomainError> {\n let selected = [...conversations];\n\n if (filters.pick !== undefined) {\n const picked = parsePickSpec(filters.pick, conversations.length);\n if (!picked.ok) return picked;\n selected = picked.value\n .map((index) => conversations[index])\n .filter((conversation): conversation is Conversation => conversation !== undefined);\n }\n\n if (filters.since !== undefined) {\n const since = new Date(filters.since);\n if (Number.isNaN(since.getTime())) {\n return importerErr(\n \"INVALID_SELECTION\",\n `--since \"${filters.since}\" is not a valid date (use YYYY-MM-DD).`,\n );\n }\n selected = selected.filter(\n (conversation) => conversation.createdAt.getTime() >= since.getTime(),\n );\n }\n\n if (filters.query !== undefined) {\n const needle = filters.query.toLowerCase();\n selected = selected.filter((conversation) => conversation.title.toLowerCase().includes(needle));\n }\n\n if (selected.length === 0) {\n return importerErr(\"NO_CONVERSATIONS_SELECTED\", \"No conversations matched the given filters.\");\n }\n return ok(selected);\n}\n","import type {\n ImportedItemInput,\n ImportItemsInput,\n ImportItemsOutput,\n} from \"../../../context/application/use-cases/import-items.use-case.js\";\nimport type { Clock } from \"../../../shared/application/ports/clock.js\";\nimport type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type { Conversation } from \"../../domain/entities/conversation.js\";\nimport { importerErr } from \"../../domain/errors.js\";\nimport { renderConversationChunks } from \"../../domain/services/chunk-render.js\";\nimport { selectConversations } from \"../../domain/services/selection.js\";\nimport type { ImportSource } from \"../../domain/values/import-source.js\";\nimport type { ExportReader } from \"../ports/export-reader.js\";\nimport type { ConversationParser } from \"../ports/parser.js\";\nimport type { ParserRegistry } from \"../ports/parser-registry.js\";\n\nexport interface ImportConversationsInput {\n filePath: string;\n projectName?: string;\n from?: ImportSource;\n list?: boolean;\n pick?: string;\n query?: string;\n since?: string;\n all?: boolean;\n dryRun?: boolean;\n}\n\nexport interface ListingRow {\n index: number;\n title: string;\n date: string;\n messageCount: number;\n estimatedChunks: number;\n}\n\nexport interface ImportFailure {\n conversation: string;\n reason: string;\n}\n\nexport type ImportMode = \"list\" | \"dry-run\" | \"import\";\n\nexport interface ImportConversationsOutput {\n mode: ImportMode;\n source: ImportSource;\n project?: string;\n listing?: ListingRow[];\n imported: number;\n /** Conversations that contributed at least one item. */\n conversations: number;\n skipped: number;\n failed: number;\n failures: ImportFailure[];\n}\n\n/**\n * Orchestrates an import: read the file, resolve a parser, parse to the\n * normalized IR, select, chunk, and (unless listing or dry-running) hand the\n * chunks to context's ImportItems for the single-session write. It never touches\n * the vault directly — the whole write path lives behind the injected use case.\n */\nexport class ImportConversations\n implements UseCase<ImportConversationsInput, ImportConversationsOutput>\n{\n constructor(\n private readonly reader: ExportReader,\n private readonly registry: ParserRegistry,\n private readonly importItems: UseCase<ImportItemsInput, ImportItemsOutput>,\n private readonly clock: Clock,\n ) {}\n\n execute(input: ImportConversationsInput): Result<ImportConversationsOutput, DomainError> {\n const docs = this.reader.read(input.filePath);\n if (!docs.ok) return docs;\n\n const resolved = this.resolveParser(docs.value, input.from);\n if (!resolved.ok) return resolved;\n\n const parsed = resolved.value.parser.parse(resolved.value.doc);\n if (!parsed.ok) return parsed;\n\n const source = resolved.value.parser.source;\n const conversations = [...parsed.value.conversations].sort(\n (a, b) => a.createdAt.getTime() - b.createdAt.getTime(),\n );\n const parseFailures: ImportFailure[] = parsed.value.failures.map((failure) => ({\n conversation: failure.title,\n reason: failure.reason,\n }));\n\n const mode = this.resolveMode(input);\n if (mode === \"list\") {\n return ok(\n this.summary(mode, source, input, parseFailures, {\n listing: this.toListing(conversations, source),\n }),\n );\n }\n\n const selected = selectConversations(conversations, {\n ...(input.all === undefined ? {} : { all: input.all }),\n ...(input.pick === undefined ? {} : { pick: input.pick }),\n ...(input.query === undefined ? {} : { query: input.query }),\n ...(input.since === undefined ? {} : { since: input.since }),\n });\n if (!selected.ok) return selected;\n\n const { items, skipped, contributed } = this.buildItems(selected.value, source);\n if (mode === \"dry-run\") {\n return ok(\n this.summary(mode, source, input, parseFailures, {\n imported: items.length,\n conversations: contributed,\n skipped,\n }),\n );\n }\n\n const written = this.importItems.execute({ projectName: input.projectName ?? \"\", items });\n if (!written.ok) return written;\n const importFailures: ImportFailure[] = written.value.failures.map((failure) => ({\n conversation: failure.conversationId,\n reason: failure.reason,\n }));\n return ok(\n this.summary(mode, source, input, [...parseFailures, ...importFailures], {\n imported: written.value.imported,\n conversations: contributed,\n skipped,\n }),\n );\n }\n\n /** With `--from`, use that parser and surface its parse error verbatim; otherwise first `detect()` wins. */\n private resolveParser(\n docs: readonly unknown[],\n from: ImportSource | undefined,\n ): Result<{ parser: ConversationParser; doc: unknown }, DomainError> {\n if (from !== undefined) {\n const parser = this.registry.forSource(from);\n const doc = docs.find((candidate) => parser.detect(candidate)) ?? docs[0];\n if (doc === undefined) return importerErr(\"EMPTY_EXPORT\", \"The export was empty.\");\n return ok({ parser, doc });\n }\n for (const parser of this.registry.autodetect) {\n const doc = docs.find((candidate) => parser.detect(candidate));\n if (doc !== undefined) return ok({ parser, doc });\n }\n return importerErr(\n \"UNSUPPORTED_SOURCE\",\n \"Could not detect the export format. Pass --from chatgpt, claude, or generic.\",\n );\n }\n\n /** No selection flag (or an explicit --list) lists; otherwise --dry-run previews, else import. */\n private resolveMode(input: ImportConversationsInput): ImportMode {\n const hasSelection =\n input.all === true ||\n input.pick !== undefined ||\n input.query !== undefined ||\n input.since !== undefined;\n if (input.list === true || !hasSelection) return \"list\";\n return input.dryRun === true ? \"dry-run\" : \"import\";\n }\n\n private toListing(conversations: readonly Conversation[], source: ImportSource): ListingRow[] {\n return conversations.map((conversation, index) => ({\n index: index + 1,\n title: conversation.title,\n date: conversation.createdAt.toISOString().slice(0, 10),\n messageCount: conversation.messages.length,\n estimatedChunks: renderConversationChunks(conversation, source).length,\n }));\n }\n\n private buildItems(\n conversations: readonly Conversation[],\n source: ImportSource,\n ): { items: ImportedItemInput[]; skipped: number; contributed: number } {\n const now = this.clock.now();\n const items: ImportedItemInput[] = [];\n let skipped = 0;\n let contributed = 0;\n for (const conversation of conversations) {\n const chunks = renderConversationChunks(conversation, source);\n if (chunks.length === 0) {\n skipped += 1;\n continue;\n }\n contributed += 1;\n // A conversation with no derivable date carries the epoch sentinel; stamp the import instant instead.\n const createdAt = conversation.createdAt.getTime() === 0 ? now : conversation.createdAt;\n chunks.forEach((content, chunkIndex) => {\n items.push({\n source,\n conversationId: conversation.id,\n chunkIndex,\n content,\n createdAt,\n tags: [\"imported\", source],\n });\n });\n }\n return { items, skipped, contributed };\n }\n\n private summary(\n mode: ImportMode,\n source: ImportSource,\n input: ImportConversationsInput,\n failures: ImportFailure[],\n counts: { imported?: number; conversations?: number; skipped?: number; listing?: ListingRow[] },\n ): ImportConversationsOutput {\n return {\n mode,\n source,\n ...(input.projectName === undefined ? {} : { project: input.projectName }),\n ...(counts.listing === undefined ? {} : { listing: counts.listing }),\n imported: counts.imported ?? 0,\n conversations: counts.conversations ?? 0,\n skipped: counts.skipped ?? 0,\n failed: failures.length,\n failures,\n };\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { unzipSync } from \"fflate\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { ExportReader } from \"../application/ports/export-reader.js\";\nimport { importerErr } from \"../domain/errors.js\";\n\n/**\n * Decompression-bomb guards: a `.zip` entry (or the running total across kept\n * entries) whose *uncompressed* size exceeds these caps is rejected before it\n * is ever inflated, so a tiny malicious archive cannot exhaust memory.\n */\nexport const MAX_ENTRY_BYTES = 128 * 1024 * 1024;\nexport const MAX_TOTAL_BYTES = 256 * 1024 * 1024;\n\nconst decoder = new TextDecoder();\n\n/** Decode UTF-8 bytes and JSON-parse them; a decode/parse failure is a malformed export. */\nfunction parseJsonBytes(bytes: Uint8Array): Result<unknown, DomainError> {\n try {\n return ok(JSON.parse(decoder.decode(bytes)));\n } catch (error) {\n return importerErr(\"MALFORMED_EXPORT\", `Invalid JSON: ${(error as Error).message}`);\n }\n}\n\n/**\n * Reads an export file into candidate JSON documents — one for a plain `.json`,\n * one per `.json` entry for a `.zip`. The archive is inflated entirely in\n * memory via fflate; nothing is ever written to disk.\n */\nexport class FileExportReader implements ExportReader {\n constructor(\n private readonly maxEntryBytes: number = MAX_ENTRY_BYTES,\n private readonly maxTotalBytes: number = MAX_TOTAL_BYTES,\n ) {}\n\n read(filePath: string): Result<unknown[], DomainError> {\n let bytes: Uint8Array;\n try {\n bytes = readFileSync(filePath);\n } catch (error) {\n return importerErr(\n \"UNREADABLE_FILE\",\n `Could not read \"${filePath}\": ${(error as Error).message}`,\n );\n }\n return filePath.toLowerCase().endsWith(\".zip\") ? this.readZip(bytes) : this.readJson(bytes);\n }\n\n private readJson(bytes: Uint8Array): Result<unknown[], DomainError> {\n const parsed = parseJsonBytes(bytes);\n if (!parsed.ok) return parsed;\n return ok([parsed.value]);\n }\n\n private readZip(bytes: Uint8Array): Result<unknown[], DomainError> {\n let entries: Record<string, Uint8Array>;\n let total = 0;\n try {\n entries = unzipSync(bytes, {\n filter: (file) => {\n if (!file.name.toLowerCase().endsWith(\".json\")) return false;\n if (file.originalSize > this.maxEntryBytes) {\n throw new Error(`entry \"${file.name}\" exceeds the ${this.maxEntryBytes}-byte cap`);\n }\n total += file.originalSize;\n if (total > this.maxTotalBytes) {\n throw new Error(`archive exceeds the ${this.maxTotalBytes}-byte total cap`);\n }\n return true;\n },\n });\n } catch (error) {\n return importerErr(\n \"CORRUPT_ARCHIVE\",\n `Could not read the archive: ${(error as Error).message}`,\n );\n }\n\n const docs: unknown[] = [];\n for (const entryBytes of Object.values(entries)) {\n const parsed = parseJsonBytes(entryBytes);\n if (!parsed.ok) return parsed;\n docs.push(parsed.value);\n }\n if (docs.length === 0) {\n return importerErr(\"EMPTY_EXPORT\", \"The archive contained no .json files.\");\n }\n return ok(docs);\n }\n}\n","import { z } from \"zod\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type {\n ConversationFailure,\n ConversationParser,\n ParsedExport,\n} from \"../../application/ports/parser.js\";\nimport type { Conversation, Message, Role } from \"../../domain/entities/conversation.js\";\nimport { importerErr } from \"../../domain/errors.js\";\n\n/**\n * Parses an official ChatGPT data export (`conversations.json`): an array of\n * conversations, each a `mapping` tree of nodes. We linearize the tree by\n * message `create_time` and keep user/assistant/system turns with text.\n */\nconst ChatgptMessage = z.object({\n author: z.object({ role: z.string().optional() }).nullish(),\n content: z.object({ parts: z.array(z.unknown()).optional() }).nullish(),\n create_time: z.number().nullish(),\n});\n\nconst ChatgptConversation = z.object({\n id: z.string().optional(),\n conversation_id: z.string().optional(),\n title: z.string().optional(),\n create_time: z.number().nullish(),\n mapping: z.record(z.string(), z.object({ message: ChatgptMessage.nullish() })),\n});\n\nconst HasMapping = z.object({ mapping: z.record(z.string(), z.unknown()) });\n\ntype ChatgptConversationData = z.infer<typeof ChatgptConversation>;\n\n/** ChatGPT exports may be a bare array or a `{ conversations: [...] }` wrapper. */\nfunction toArray(doc: unknown): unknown[] | null {\n if (Array.isArray(doc)) return doc;\n if (doc !== null && typeof doc === \"object\" && \"conversations\" in doc) {\n const inner = (doc as { conversations: unknown }).conversations;\n return Array.isArray(inner) ? inner : null;\n }\n return null;\n}\n\nfunction mapRole(role: string | null | undefined): Role | null {\n return role === \"user\" || role === \"assistant\" || role === \"system\" ? role : null;\n}\n\nfunction joinParts(parts: readonly unknown[] | null | undefined): string {\n if (!parts) return \"\";\n return parts.filter((part): part is string => typeof part === \"string\").join(\"\\n\");\n}\n\nfunction linearize(data: ChatgptConversationData, index: number): Conversation {\n const timed: { message: Message; time: number }[] = [];\n for (const node of Object.values(data.mapping)) {\n const raw = node.message;\n const role = mapRole(raw?.author?.role);\n if (raw === null || raw === undefined || role === null) continue;\n const text = joinParts(raw.content?.parts);\n if (text.trim().length === 0) continue;\n const time = typeof raw.create_time === \"number\" ? raw.create_time : 0;\n const message: Message = {\n role,\n content: text,\n ...(typeof raw.create_time === \"number\"\n ? { createdAt: new Date(raw.create_time * 1000) }\n : {}),\n };\n timed.push({ message, time });\n }\n timed.sort((a, b) => a.time - b.time);\n\n const firstTime = timed[0]?.time;\n const convTime = data.create_time ?? firstTime;\n return {\n id: data.id ?? data.conversation_id ?? `chatgpt-${index}`,\n title: data.title ?? \"Untitled\",\n createdAt: typeof convTime === \"number\" ? new Date(convTime * 1000) : new Date(0),\n messages: timed.map((entry) => entry.message),\n };\n}\n\nexport class ChatgptParser implements ConversationParser {\n readonly source = \"chatgpt\" as const;\n\n detect(doc: unknown): boolean {\n const arr = toArray(doc);\n const first = arr?.[0];\n return first !== undefined && HasMapping.safeParse(first).success;\n }\n\n parse(doc: unknown): Result<ParsedExport, DomainError> {\n const arr = toArray(doc);\n if (arr === null) {\n return importerErr(\"MALFORMED_EXPORT\", \"Expected an array of ChatGPT conversations.\");\n }\n const conversations: Conversation[] = [];\n const failures: ConversationFailure[] = [];\n for (const [index, raw] of arr.entries()) {\n const parsed = ChatgptConversation.safeParse(raw);\n if (!parsed.success) {\n failures.push({\n title: `Conversation ${index + 1}`,\n reason: parsed.error.issues[0]?.message ?? \"invalid conversation shape\",\n });\n continue;\n }\n conversations.push(linearize(parsed.data, index));\n }\n if (conversations.length === 0 && failures.length === 0) {\n return importerErr(\"EMPTY_EXPORT\", \"No conversations found in the ChatGPT export.\");\n }\n return ok({ conversations, failures });\n }\n}\n","import { z } from \"zod\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type {\n ConversationFailure,\n ConversationParser,\n ParsedExport,\n} from \"../../application/ports/parser.js\";\nimport type { Conversation, Message } from \"../../domain/entities/conversation.js\";\nimport { importerErr } from \"../../domain/errors.js\";\n\n/**\n * Parses an official Claude data export: a top-level array of conversations,\n * each with `chat_messages`. A message's text is its `text` field, or the\n * joined `text` of its typed content blocks. `sender: \"human\"` maps to user.\n */\nconst ClaudeMessage = z.object({\n sender: z.string().optional(),\n text: z.string().optional(),\n content: z\n .array(z.object({ type: z.string().optional(), text: z.string().optional() }))\n .optional(),\n created_at: z.string().optional(),\n});\n\nconst ClaudeConversation = z.object({\n uuid: z.string().optional(),\n name: z.string().optional(),\n created_at: z.string().optional(),\n chat_messages: z.array(ClaudeMessage),\n});\n\nconst HasChatMessages = z.object({ chat_messages: z.array(z.unknown()) });\n\ntype ClaudeMessageData = z.infer<typeof ClaudeMessage>;\n\n/** A valid Date from an ISO string, or null when absent/unparseable. */\nfunction parseDate(iso: string | undefined): Date | null {\n if (iso === undefined) return null;\n const date = new Date(iso);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\nfunction messageText(message: ClaudeMessageData): string {\n if (message.text !== undefined && message.text.trim().length > 0) return message.text;\n if (message.content === undefined) return \"\";\n return message.content\n .filter((block) => block.type === \"text\" && typeof block.text === \"string\")\n .map((block) => block.text)\n .join(\"\\n\");\n}\n\nexport class ClaudeParser implements ConversationParser {\n readonly source = \"claude\" as const;\n\n detect(doc: unknown): boolean {\n const first = Array.isArray(doc) ? doc[0] : undefined;\n return first !== undefined && HasChatMessages.safeParse(first).success;\n }\n\n parse(doc: unknown): Result<ParsedExport, DomainError> {\n if (!Array.isArray(doc)) {\n return importerErr(\"MALFORMED_EXPORT\", \"Expected an array of Claude conversations.\");\n }\n const conversations: Conversation[] = [];\n const failures: ConversationFailure[] = [];\n for (const [index, raw] of doc.entries()) {\n const parsed = ClaudeConversation.safeParse(raw);\n if (!parsed.success) {\n failures.push({\n title: `Conversation ${index + 1}`,\n reason: parsed.error.issues[0]?.message ?? \"invalid conversation shape\",\n });\n continue;\n }\n const messages: Message[] = [];\n for (const rawMessage of parsed.data.chat_messages) {\n const role = rawMessage.sender === \"human\" ? \"user\" : \"assistant\";\n const text = messageText(rawMessage);\n if (text.trim().length === 0) continue;\n const at = parseDate(rawMessage.created_at);\n messages.push({ role, content: text, ...(at === null ? {} : { createdAt: at }) });\n }\n const firstAt = messages[0]?.createdAt;\n const convAt = parseDate(parsed.data.created_at) ?? firstAt ?? new Date(0);\n conversations.push({\n id: parsed.data.uuid ?? `claude-${index}`,\n title: parsed.data.name ?? \"Untitled\",\n createdAt: convAt,\n messages,\n });\n }\n if (conversations.length === 0 && failures.length === 0) {\n return importerErr(\"EMPTY_EXPORT\", \"No conversations found in the Claude export.\");\n }\n return ok({ conversations, failures });\n }\n}\n","import { z } from \"zod\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type {\n ConversationFailure,\n ConversationParser,\n ParsedExport,\n} from \"../../application/ports/parser.js\";\nimport type { Conversation, Message } from \"../../domain/entities/conversation.js\";\nimport { importerErr } from \"../../domain/errors.js\";\n\n/**\n * Parses valija's own generic import envelope — the universal escape hatch for\n * any provider without a dedicated parser. Versioned so it can evolve loudly:\n * an unknown version is rejected, never mis-read. Never auto-selected; reachable\n * only via an explicit `--from generic`.\n */\nexport const GENERIC_IMPORT_VERSION = 1;\n\nconst GenericMessage = z.object({\n role: z.enum([\"user\", \"assistant\", \"system\"]),\n content: z.string(),\n createdAt: z.string().optional(),\n});\n\nconst GenericConversation = z.object({\n id: z.string(),\n title: z.string().optional(),\n createdAt: z.string(),\n messages: z.array(GenericMessage),\n});\n\nconst GenericEnvelope = z.object({\n valija_import_version: z.number(),\n conversations: z.array(z.unknown()),\n});\n\nfunction parseDate(iso: string | undefined): Date | null {\n if (iso === undefined) return null;\n const date = new Date(iso);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\nexport class GenericParser implements ConversationParser {\n readonly source = \"generic\" as const;\n\n detect(doc: unknown): boolean {\n return (\n doc !== null &&\n typeof doc === \"object\" &&\n !Array.isArray(doc) &&\n \"valija_import_version\" in doc\n );\n }\n\n parse(doc: unknown): Result<ParsedExport, DomainError> {\n const envelope = GenericEnvelope.safeParse(doc);\n if (!envelope.success) {\n return importerErr(\"MALFORMED_EXPORT\", \"Not a valija generic import envelope.\");\n }\n if (envelope.data.valija_import_version !== GENERIC_IMPORT_VERSION) {\n return importerErr(\n \"UNSUPPORTED_GENERIC_VERSION\",\n `Unsupported generic import version ${envelope.data.valija_import_version}; this valija supports version ${GENERIC_IMPORT_VERSION}.`,\n );\n }\n\n const conversations: Conversation[] = [];\n const failures: ConversationFailure[] = [];\n for (const [index, raw] of envelope.data.conversations.entries()) {\n const parsed = GenericConversation.safeParse(raw);\n if (!parsed.success) {\n failures.push({\n title: `Conversation ${index + 1}`,\n reason: parsed.error.issues[0]?.message ?? \"invalid conversation shape\",\n });\n continue;\n }\n const createdAt = parseDate(parsed.data.createdAt);\n if (createdAt === null) {\n failures.push({\n title: parsed.data.title ?? parsed.data.id,\n reason: `Invalid createdAt: \"${parsed.data.createdAt}\"`,\n });\n continue;\n }\n const messages: Message[] = parsed.data.messages.map((message) => {\n const at = parseDate(message.createdAt);\n return {\n role: message.role,\n content: message.content,\n ...(at === null ? {} : { createdAt: at }),\n };\n });\n conversations.push({\n id: parsed.data.id,\n title: parsed.data.title ?? \"Untitled\",\n createdAt,\n messages,\n });\n }\n if (conversations.length === 0 && failures.length === 0) {\n return importerErr(\"EMPTY_EXPORT\", \"No conversations found in the generic export.\");\n }\n return ok({ conversations, failures });\n }\n}\n","import type { ConversationParser } from \"../application/ports/parser.js\";\nimport type { ParserRegistry } from \"../application/ports/parser-registry.js\";\nimport type { ImportSource } from \"../domain/values/import-source.js\";\nimport { ChatgptParser } from \"./parsers/chatgpt-parser.js\";\nimport { ClaudeParser } from \"./parsers/claude-parser.js\";\nimport { GenericParser } from \"./parsers/generic-parser.js\";\n\nconst chatgpt = new ChatgptParser();\nconst claude = new ClaudeParser();\nconst generic = new GenericParser();\n\nconst BY_SOURCE: Record<ImportSource, ConversationParser> = { chatgpt, claude, generic };\n\n/**\n * The concrete parser registry. `generic` is deliberately absent from\n * `autodetect`: a permissive envelope match could swallow a malformed official\n * export, so it is reachable only via an explicit `--from generic`. Adding a\n * provider later is one new file plus one line here.\n */\nexport const parserRegistry: ParserRegistry = {\n autodetect: [chatgpt, claude],\n forSource: (source) => BY_SOURCE[source],\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface VaultPaths {\n root: string;\n header: string;\n db: string;\n}\n\nexport function resolveVaultPaths(rootOverride?: string): VaultPaths {\n const root = rootOverride ?? process.env.VALIJA_HOME ?? join(homedir(), \".valija\");\n return {\n root,\n header: join(root, \"vault.json\"),\n db: join(root, \"vault.db\"),\n };\n}\n","/**\n * The vault key rendered as hex — the vault's canonical key format:\n * exactly 64 hex characters (32 bytes). This is what lives in the OS\n * keychain and what a recovery kit prints.\n */\nexport const bytesToHex = (bytes: Uint8Array): string =>\n Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\nexport const isKeyHex = (value: string): boolean => /^[0-9a-f]{64}$/i.test(value);\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { vaultErr } from \"../errors.js\";\n\nexport const MIN_PASSPHRASE_LENGTH = 8;\n\n/** A passphrase long enough to derive a vault key from. Never trimmed: spaces are entropy. */\nexport type Passphrase = string & { readonly __brand: \"Passphrase\" };\n\nexport function parsePassphrase(raw: string): Result<Passphrase, DomainError> {\n if (raw.length < MIN_PASSPHRASE_LENGTH) {\n return vaultErr(\n \"WEAK_PASSPHRASE\",\n `Passphrase must be at least ${MIN_PASSPHRASE_LENGTH} characters.`,\n );\n }\n return ok(raw as Passphrase);\n}\n","export interface KdfParams {\n readonly algorithm: \"argon2id\";\n readonly memoryKiB: number;\n readonly iterations: number;\n readonly parallelism: number;\n}\n\nexport const DEFAULT_KDF_PARAMS: KdfParams = {\n algorithm: \"argon2id\",\n memoryKiB: 64 * 1024,\n iterations: 3,\n parallelism: 1,\n};\n\nexport interface VaultCrypto {\n /** Derive a 32-byte raw key from a passphrase. */\n deriveKey(passphrase: string, salt: Uint8Array, params: KdfParams): Promise<Uint8Array>;\n generateSalt(): Uint8Array;\n}\n","import type { Clock, IdGenerator } from \"../../../shared/application/ports/clock.js\";\nimport type { AsyncUseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { vaultErr } from \"../../domain/errors.js\";\nimport { bytesToHex } from \"../../domain/values/key-hex.js\";\nimport { type Passphrase, parsePassphrase } from \"../../domain/values/passphrase.js\";\nimport { DEFAULT_KDF_PARAMS, type VaultCrypto } from \"../ports/crypto.js\";\nimport type { KeychainPort } from \"../ports/keychain.js\";\nimport type { VaultHeaderData, VaultStore } from \"../ports/vault-store.js\";\n\nexport interface CreateVaultOutput {\n vaultId: string;\n keyHex: string;\n createdAt: string;\n}\n\ninterface ForgedVault {\n header: VaultHeaderData;\n keyHex: string;\n}\n\nexport class CreateVault implements AsyncUseCase<string, CreateVaultOutput> {\n constructor(\n private readonly store: VaultStore,\n private readonly crypto: VaultCrypto,\n private readonly keychain: KeychainPort,\n private readonly clock: Clock,\n private readonly idGen: IdGenerator,\n ) {}\n\n async execute(passphrase: string): Promise<Result<CreateVaultOutput, DomainError>> {\n if (this.store.headerExists()) {\n return vaultErr(\"VAULT_ALREADY_EXISTS\", \"A vault already exists on this machine.\");\n }\n const parsed = parsePassphrase(passphrase);\n if (!parsed.ok) return parsed;\n\n const vault = await this.forgeVault(parsed.value);\n this.store.writeHeader(vault.header);\n const initialized = this.store.initializeDb(vault.keyHex);\n if (!initialized.ok) return initialized;\n\n // Convenience: a freshly created vault starts unlocked.\n this.keychain.setKey(vault.header.vaultId, vault.keyHex);\n return ok({\n vaultId: vault.header.vaultId,\n keyHex: vault.keyHex,\n createdAt: vault.header.createdAt,\n });\n }\n\n /** Mint the vault identity: id + salt + key derived from the passphrase. */\n private async forgeVault(passphrase: Passphrase): Promise<ForgedVault> {\n const vaultId = this.idGen.next();\n const salt = this.crypto.generateSalt();\n const key = await this.crypto.deriveKey(passphrase, salt, DEFAULT_KDF_PARAMS);\n return {\n header: {\n vaultId,\n schemaVersion: 1,\n kdf: DEFAULT_KDF_PARAMS,\n salt,\n createdAt: this.clock.now().toISOString(),\n },\n keyHex: bytesToHex(key),\n };\n }\n}\n","import type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type { KeychainPort } from \"../ports/keychain.js\";\nimport type { VaultStore } from \"../ports/vault-store.js\";\n\nexport class LockVault implements UseCase<void, { wasUnlocked: boolean }> {\n constructor(\n private readonly store: VaultStore,\n private readonly keychain: KeychainPort,\n ) {}\n\n execute(): Result<{ wasUnlocked: boolean }, DomainError> {\n const header = this.store.readHeader();\n if (!header.ok) return header;\n const wasUnlocked = this.keychain.deleteKey(header.value.vaultId);\n return ok({ wasUnlocked });\n }\n}\n","import type { AsyncUseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { vaultErr } from \"../../domain/errors.js\";\nimport { bytesToHex, isKeyHex } from \"../../domain/values/key-hex.js\";\nimport type { VaultCrypto } from \"../ports/crypto.js\";\nimport type { KeychainPort } from \"../ports/keychain.js\";\nimport type { VaultHeaderData, VaultStore } from \"../ports/vault-store.js\";\n\nexport interface UnlockInput {\n passphrase?: string;\n recoveryKeyHex?: string;\n}\n\nexport class UnlockVault implements AsyncUseCase<UnlockInput, { vaultId: string }> {\n constructor(\n private readonly store: VaultStore,\n private readonly crypto: VaultCrypto,\n private readonly keychain: KeychainPort,\n ) {}\n\n async execute(input: UnlockInput): Promise<Result<{ vaultId: string }, DomainError>> {\n const header = this.store.readHeader();\n if (!header.ok) return header;\n\n const keyHex = await this.resolveKey(input, header.value);\n if (!keyHex.ok) return keyHex;\n\n const verified = this.store.verifyKey(keyHex.value);\n if (!verified.ok) return verified;\n\n this.keychain.setKey(header.value.vaultId, keyHex.value);\n return ok({ vaultId: header.value.vaultId });\n }\n\n /** A recovery key is used as-is; a passphrase is derived with the header's salt + KDF params. */\n private async resolveKey(\n input: UnlockInput,\n header: VaultHeaderData,\n ): Promise<Result<string, DomainError>> {\n if (input.recoveryKeyHex !== undefined) {\n if (!isKeyHex(input.recoveryKeyHex)) {\n return vaultErr(\"WRONG_PASSPHRASE\", \"Recovery key must be 64 hex characters.\");\n }\n return ok(input.recoveryKeyHex.toLowerCase());\n }\n if (input.passphrase !== undefined) {\n const key = await this.crypto.deriveKey(input.passphrase, header.salt, header.kdf);\n return ok(bytesToHex(key));\n }\n return vaultErr(\"WRONG_PASSPHRASE\", \"Provide a passphrase or a recovery key.\");\n }\n}\n","import type { UseCase } from \"../../../shared/application/use-case.js\";\nimport { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport type { KeychainPort } from \"../ports/keychain.js\";\nimport type { VaultStore } from \"../ports/vault-store.js\";\n\nexport interface VaultStatusOutput {\n initialized: boolean;\n unlocked: boolean;\n vaultId?: string;\n dbPath: string;\n}\n\nexport class VaultStatus implements UseCase<void, VaultStatusOutput> {\n constructor(\n private readonly store: VaultStore,\n private readonly keychain: KeychainPort,\n ) {}\n\n execute(): Result<VaultStatusOutput, DomainError> {\n const dbPath = this.store.dbPath();\n if (!this.store.headerExists()) {\n return ok({ initialized: false, unlocked: false, dbPath });\n }\n const header = this.store.readHeader();\n if (!header.ok) return header;\n\n const keyHex = this.keychain.getKey(header.value.vaultId);\n const unlocked = keyHex !== null && this.store.verifyKey(keyHex).ok;\n return ok({ initialized: true, unlocked, vaultId: header.value.vaultId, dbPath });\n }\n}\n","import { randomBytes } from \"node:crypto\";\nimport argon2 from \"argon2\";\nimport type { KdfParams, VaultCrypto } from \"../application/ports/crypto.js\";\n\nexport const KEY_LENGTH = 32;\nexport const SALT_LENGTH = 16;\n\nexport class Argon2VaultCrypto implements VaultCrypto {\n async deriveKey(passphrase: string, salt: Uint8Array, params: KdfParams): Promise<Uint8Array> {\n const key = await argon2.hash(passphrase, {\n type: argon2.argon2id,\n raw: true,\n salt: Buffer.from(salt),\n memoryCost: params.memoryKiB,\n timeCost: params.iterations,\n parallelism: params.parallelism,\n hashLength: KEY_LENGTH,\n });\n return new Uint8Array(key);\n }\n\n generateSalt(): Uint8Array {\n return new Uint8Array(randomBytes(SALT_LENGTH));\n }\n}\n\nexport const toHex = (bytes: Uint8Array): string => Buffer.from(bytes).toString(\"hex\");\nexport const fromHex = (hex: string): Uint8Array => new Uint8Array(Buffer.from(hex, \"hex\"));\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport { migrate } from \"../../shared/infra/migrations.js\";\nimport { isWrongKeyError, openVaultDb } from \"../../shared/infra/sqlite.js\";\nimport type { VaultPaths } from \"../../shared/infra/vault-paths.js\";\nimport type { VaultHeaderData, VaultStore } from \"../application/ports/vault-store.js\";\nimport { vaultErr } from \"../domain/errors.js\";\nimport { readVaultHeader, writeVaultHeader } from \"./vault-header.js\";\n\nexport class FileVaultStore implements VaultStore {\n constructor(private readonly paths: VaultPaths) {}\n\n headerExists(): boolean {\n return existsSync(this.paths.header);\n }\n\n readHeader(): Result<VaultHeaderData, DomainError> {\n return readVaultHeader(this.paths.header);\n }\n\n writeHeader(header: VaultHeaderData): void {\n mkdirSync(this.paths.root, { recursive: true });\n writeVaultHeader(this.paths.header, header);\n }\n\n initializeDb(keyHex: string): Result<void, DomainError> {\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n migrate(db, this.paths.db);\n db.close();\n return ok(undefined);\n } catch (error) {\n return vaultErr(\"STORAGE_ERROR\", `Could not create vault db: ${(error as Error).message}`);\n }\n }\n\n verifyKey(keyHex: string): Result<void, DomainError> {\n try {\n const db = openVaultDb(this.paths.db, keyHex);\n db.close();\n return ok(undefined);\n } catch (error) {\n if (isWrongKeyError(error)) {\n return vaultErr(\"WRONG_PASSPHRASE\", \"Wrong passphrase (or recovery key) for this vault.\");\n }\n return vaultErr(\"STORAGE_ERROR\", `Could not open vault db: ${(error as Error).message}`);\n }\n }\n\n dbPath(): string {\n return this.paths.db;\n }\n}\n","import { Entry } from \"@napi-rs/keyring\";\nimport type { KeychainPort } from \"../application/ports/keychain.js\";\n\nconst SERVICE = \"valija\";\n\nexport class OsKeychain implements KeychainPort {\n setKey(vaultId: string, keyHex: string): void {\n new Entry(SERVICE, vaultId).setPassword(keyHex);\n }\n\n getKey(vaultId: string): string | null {\n try {\n return new Entry(SERVICE, vaultId).getPassword();\n } catch {\n return null;\n }\n }\n\n deleteKey(vaultId: string): boolean {\n try {\n return new Entry(SERVICE, vaultId).deletePassword();\n } catch {\n return false;\n }\n }\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { ITEM_TYPES } from \"../../context/domain/values/item-type.js\";\nimport type { DomainError } from \"../../shared/domain/result.js\";\nimport type { Container } from \"../container.js\";\nimport { renderContextPackMarkdown } from \"../context-pack-markdown.js\";\nimport { VERSION } from \"../version.js\";\n\nconst ok = (text: string) => ({ content: [{ type: \"text\" as const, text }] });\nconst err = (error: DomainError) => ({\n content: [{ type: \"text\" as const, text: `${error.message} [${error.code}]` }],\n isError: true,\n});\n\nconst DESCRIPTIONS = {\n save_context:\n \"Save durable context about a project for future sessions in any AI tool. \" +\n \"Use when the user asks to save or remember something, or at the end of a working session. \" +\n \"Write `content` so it is self-contained and specific for a reader with no other context: \" +\n \"decisions made and why, current state, conventions and preferences established, next steps, \" +\n \"unresolved questions. Never include secrets, API keys, or passwords.\",\n save_handoff:\n \"Package the state of THIS conversation so another AI tool or session can continue seamlessly. \" +\n \"Structure `content` as: goal, what was done, current blockers, exact next step, \" +\n \"relevant files or links.\",\n get_context:\n \"Load the saved context pack for a project before starting work on it. Returns pinned and \" +\n \"recent context (decisions, preferences, progress, latest handoff) as markdown within a \" +\n \"token budget. Call this when the user asks to load, resume, or continue a project.\",\n search_context:\n \"Full-text search across saved context. Use for specific recall questions such as \" +\n \"'what did we decide about auth?'. Returns matching items with project, type, and date.\",\n list_projects:\n \"List existing projects with item counts and last activity. Use to disambiguate which \" +\n \"project the user means before saving or loading.\",\n} as const;\n\nexport function buildMcpServer(c: Container): McpServer {\n const server = new McpServer({ name: \"valija\", version: VERSION });\n const clientName = (): string | undefined => server.server.getClientVersion()?.name;\n\n server.registerTool(\n \"save_context\",\n {\n title: \"Save context\",\n description: DESCRIPTIONS.save_context,\n inputSchema: {\n project: z\n .string()\n .describe(\"Project slug, e.g. 'vault-app'. Created if it does not exist.\"),\n content: z.string().describe(\"Self-contained markdown. Max 32 KB.\"),\n type: z.enum(ITEM_TYPES).optional().describe(\"Kind of context. Defaults to 'fact'.\"),\n tags: z.array(z.string()).max(10).optional().describe(\"Lowercase tags for recall.\"),\n },\n },\n async ({ project, content, type, tags }) => {\n const source = clientName();\n const r = c.saveContext.execute({\n project,\n content,\n ...(type === undefined ? {} : { type }),\n ...(tags === undefined ? {} : { tags }),\n ...(source === undefined ? {} : { source }),\n });\n if (!r.ok) return err(r.error);\n return ok(\n `Saved ${r.value.type} to project \"${r.value.project}\"` +\n `${r.value.projectCreated ? \" (project created)\" : \"\"}. Item id: ${r.value.itemId}.`,\n );\n },\n );\n\n server.registerTool(\n \"save_handoff\",\n {\n title: \"Save handoff\",\n description: DESCRIPTIONS.save_handoff,\n inputSchema: {\n project: z.string().describe(\"Project slug. Created if it does not exist.\"),\n content: z\n .string()\n .describe(\"Goal, what was done, blockers, exact next step, relevant files or links.\"),\n },\n },\n async ({ project, content }) => {\n const source = clientName();\n const r = c.saveContext.execute({\n project,\n content,\n type: \"handoff\",\n ...(source === undefined ? {} : { source }),\n });\n if (!r.ok) return err(r.error);\n return ok(`Handoff saved to project \"${r.value.project}\". Item id: ${r.value.itemId}.`);\n },\n );\n\n server.registerTool(\n \"get_context\",\n {\n title: \"Get context pack\",\n description: DESCRIPTIONS.get_context,\n inputSchema: {\n project: z.string().describe(\"Project slug to load.\"),\n budget: z.number().int().positive().optional().describe(\"Token budget. Default 4000.\"),\n },\n },\n async ({ project, budget }) => {\n const r = c.getContextPack.execute({\n project,\n ...(budget === undefined ? {} : { budgetTokens: budget }),\n });\n if (!r.ok) return err(r.error);\n return ok(renderContextPackMarkdown(r.value));\n },\n );\n\n server.registerTool(\n \"search_context\",\n {\n title: \"Search context\",\n description: DESCRIPTIONS.search_context,\n inputSchema: {\n query: z.string().describe(\"Full-text query, e.g. 'auth decision'.\"),\n project: z.string().optional().describe(\"Limit to one project.\"),\n limit: z.number().int().positive().max(100).optional().describe(\"Max results. Default 20.\"),\n },\n },\n async ({ query, project, limit }) => {\n const r = c.searchContext.execute({\n query,\n ...(project === undefined ? {} : { project }),\n ...(limit === undefined ? {} : { limit }),\n });\n if (!r.ok) return err(r.error);\n if (r.value.length === 0) return ok(\"No matches.\");\n const lines = r.value.map(\n (hit) => `- [${hit.project}] (${hit.type}, ${hit.createdAt.slice(0, 10)}) ${hit.content}`,\n );\n return ok(`${r.value.length} match(es):\\n\\n${lines.join(\"\\n\")}`);\n },\n );\n\n server.registerTool(\n \"list_projects\",\n {\n title: \"List projects\",\n description: DESCRIPTIONS.list_projects,\n inputSchema: {},\n },\n async () => {\n const r = c.listProjects.execute();\n if (!r.ok) return err(r.error);\n if (r.value.length === 0) return ok(\"No projects in the vault yet.\");\n const lines = r.value.map(\n (p) =>\n `- ${p.name}: ${p.itemCount} item(s), last activity ${p.lastActivityAt?.slice(0, 10) ?? \"never\"}`,\n );\n return ok(lines.join(\"\\n\"));\n },\n );\n\n server.registerPrompt(\n \"save-context\",\n {\n title: \"Save session context to valija\",\n description: \"Distill this session into a self-contained context save.\",\n argsSchema: { project: z.string().optional() },\n },\n ({ project }) => ({\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Review this conversation and save its durable context to valija${project ? ` under the project \"${project}\"` : \"\"}.\\n\\n` +\n \"1. If the project is ambiguous, call list_projects first and confirm with me.\\n\" +\n \"2. Compose content that is self-contained for a reader with no other context: \" +\n \"decisions made and why, current state, conventions/preferences established, \" +\n \"next steps, unresolved questions. No secrets, API keys, or passwords.\\n\" +\n \"3. Pick the right type (decision/progress/preference/fact) and 1-5 tags.\\n\" +\n \"4. Call save_context, then tell me what you saved in one line.\",\n },\n },\n ],\n }),\n );\n\n server.registerPrompt(\n \"load-context\",\n {\n title: \"Load project context from valija\",\n description: \"Load a project's context pack and resume work.\",\n argsSchema: { project: z.string() },\n },\n ({ project }) => ({\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Call get_context for the project \"${project}\". Then:\\n` +\n \"1. Summarize the current state in 3 lines max.\\n\" +\n \"2. Propose the next step based on the latest handoff or progress.\\n\" +\n \"Do not repeat the whole pack back to me.\",\n },\n },\n ],\n }),\n );\n\n return server;\n}\n\nexport async function runMcpServer(c: Container): Promise<void> {\n const server = buildMcpServer(c);\n await server.connect(new StdioServerTransport());\n}\n","import type { ContextItem } from \"../context/domain/entities/context-item.js\";\nimport type { ContextPack, PackSection } from \"../context/domain/services/context-pack.js\";\nimport type { ItemType } from \"../context/domain/values/item-type.js\";\n\n/** Section headings. The domain orders sections; naming them is presentation. */\nconst TYPE_LABELS: Record<ItemType, string> = {\n decision: \"Decisions\",\n preference: \"Preferences\",\n progress: \"Progress\",\n fact: \"Facts\",\n handoff: \"Handoffs\",\n};\n\nconst sectionTitle = (section: PackSection): string => {\n switch (section.kind) {\n case \"pinned\":\n return \"Pinned\";\n case \"latest-handoff\":\n return \"Latest handoff\";\n case \"by-type\":\n return TYPE_LABELS[section.type];\n }\n};\n\nconst renderItem = (item: ContextItem): string => {\n const date = item.createdAt.toISOString().slice(0, 10);\n const tags = item.tags.length > 0 ? ` · ${item.tags.map((t) => `#${t}`).join(\" \")}` : \"\";\n return `### ${item.type} · ${date}${tags}\\n\\n${item.content}\\n`;\n};\n\n/** Render an assembled pack as the markdown handed to a human or an LLM. */\nexport function renderContextPackMarkdown(pack: ContextPack): string {\n const header =\n `# Context pack: ${pack.projectName}\\n\\n` +\n `> ${pack.totalCount} items in vault · generated ${pack.generatedAt.toISOString()}\\n`;\n const parts = pack.sections.flatMap((section) => [\n `\\n## ${sectionTitle(section)}\\n`,\n ...section.items.map(renderItem),\n ]);\n return header + parts.join(\"\\n\");\n}\n","export const VERSION = \"0.2.0\";\n","import { writeFileSync } from \"node:fs\";\nimport { type DomainError, ok, type Result } from \"../../shared/domain/result.js\";\nimport type { Container } from \"../container.js\";\nimport { renderContextPackMarkdown } from \"../context-pack-markdown.js\";\nimport { fail, formatDate, truncate } from \"./render.js\";\n\nexport function projectsCommand(c: Container): void {\n const result = c.listProjects.execute();\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\n \"No projects yet. Save context from an AI tool, or check back after your first session.\",\n );\n return;\n }\n console.log(\"PROJECT ITEMS LAST ACTIVITY\");\n for (const p of result.value) {\n console.log(\n `${p.name.padEnd(32)} ${String(p.itemCount).padStart(5)} ${formatDate(p.lastActivityAt)}`,\n );\n }\n}\n\nexport function showCommand(c: Container, project: string, options: { type?: string }): void {\n const result = c.showProject.execute({\n project,\n ...(options.type === undefined ? {} : { type: options.type }),\n });\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\"No items.\");\n return;\n }\n for (const item of result.value) {\n const pin = item.pinned ? \" 📌\" : \"\";\n const tags = item.tags.length > 0 ? ` [${item.tags.join(\", \")}]` : \"\";\n console.log(`\\n— ${item.type} · ${formatDate(item.createdAt)}${pin}${tags}`);\n console.log(item.content);\n }\n}\n\nexport function searchCommand(c: Container, query: string, options: { project?: string }): void {\n const result = c.searchContext.execute({\n query,\n ...(options.project === undefined ? {} : { project: options.project }),\n });\n if (!result.ok) fail(result.error);\n if (result.value.length === 0) {\n console.log(\"No matches.\");\n return;\n }\n for (const hit of result.value) {\n console.log(\n `${hit.project} ${hit.type.padEnd(10)} ${formatDate(hit.createdAt)} ${truncate(hit.content)}`,\n );\n }\n}\n\n/** Export is the everything-escape-hatch: the whole project, no budget. */\nconst exportMarkdown = (c: Container, project: string): Result<string, DomainError> => {\n const pack = c.getContextPack.execute({ project, budgetTokens: Number.POSITIVE_INFINITY });\n return pack.ok ? ok(renderContextPackMarkdown(pack.value)) : pack;\n};\n\nconst exportJson = (c: Container, project: string): Result<string, DomainError> => {\n const items = c.showProject.execute({ project });\n return items.ok ? ok(JSON.stringify({ project, items: items.value }, null, 2)) : items;\n};\n\nexport function exportCommand(\n c: Container,\n project: string,\n options: { json?: boolean; output?: string },\n): void {\n const format = options.json ? \"json\" : \"md\";\n const result = options.json ? exportJson(c, project) : exportMarkdown(c, project);\n if (!result.ok) fail(result.error);\n if (options.output !== undefined) {\n writeFileSync(options.output, result.value, \"utf8\");\n console.error(`Exported ${project} (${format}) to ${options.output}`);\n } else {\n console.log(result.value);\n }\n}\n","import type { DomainError } from \"../../shared/domain/result.js\";\n\nexport function fail(error: DomainError): never {\n console.error(`error [${error.code}]: ${error.message}`);\n process.exit(1);\n}\n\nexport function truncate(text: string, max = 80): string {\n const oneLine = text.replace(/\\s+/g, \" \").trim();\n return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}…`;\n}\n\nexport function formatDate(iso: string | null): string {\n return iso === null ? \"—\" : iso.slice(0, 10);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { OsKeychain } from \"../../vault/infra/keyring.js\";\nimport type { Container } from \"../container.js\";\nimport { CLIENTS, type ClientId, clientConfigPath } from \"./installer.js\";\n\ninterface Check {\n name: string;\n ok: boolean;\n detail: string;\n fatal?: boolean;\n}\n\nfunction checkNode(): Check {\n const [major] = process.versions.node.split(\".\").map(Number);\n return {\n name: \"node\",\n ok: (major ?? 0) >= 22,\n detail: `v${process.versions.node} (need >=22)`,\n fatal: true,\n };\n}\n\nasync function checkSqlcipher(): Promise<Check> {\n try {\n const { default: Db } = await import(\"better-sqlite3-multiple-ciphers\");\n const db = new Db(\":memory:\");\n db.pragma(\"cipher='sqlcipher'\");\n db.close();\n return { name: \"sqlcipher\", ok: true, detail: \"native module loads\" };\n } catch (e) {\n return { name: \"sqlcipher\", ok: false, detail: (e as Error).message, fatal: true };\n }\n}\n\nfunction checkKeychain(): Check {\n try {\n const keychain = new OsKeychain();\n keychain.setKey(\"doctor-probe\", \"test\");\n const roundtrip = keychain.getKey(\"doctor-probe\") === \"test\";\n keychain.deleteKey(\"doctor-probe\");\n return { name: \"keychain\", ok: roundtrip, detail: \"OS keychain read/write\" };\n } catch (e) {\n return { name: \"keychain\", ok: false, detail: (e as Error).message };\n }\n}\n\nfunction checkVault(c: Container): Check {\n const status = c.vaultStatus.execute();\n if (!status.ok) return { name: \"vault\", ok: false, detail: status.error.message };\n return {\n name: \"vault\",\n ok: status.value.initialized,\n detail: status.value.initialized\n ? `${status.value.unlocked ? \"unlocked\" : \"locked\"} at ${status.value.dbPath}`\n : 'not initialized — run \"valija init\"',\n };\n}\n\nfunction checkClient(client: ClientId): Check {\n const path = clientConfigPath(client);\n if (!existsSync(path)) return { name: client, ok: false, detail: \"config not found\" };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n const installed = parsed.mcpServers?.valija !== undefined;\n return {\n name: client,\n ok: installed,\n detail: installed ? \"valija installed\" : \"config found, valija not installed\",\n };\n } catch {\n return { name: client, ok: false, detail: \"config exists but is not valid JSON\" };\n }\n}\n\nexport async function doctorCommand(c: Container): Promise<void> {\n const checks: Check[] = [\n checkNode(),\n await checkSqlcipher(),\n checkKeychain(),\n checkVault(c),\n ...CLIENTS.map(checkClient),\n ];\n\n let fatal = false;\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name.padEnd(16)} ${check.detail}`);\n if (!check.ok && check.fatal) fatal = true;\n }\n if (fatal) process.exit(1);\n}\n","import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const CLIENTS = [\"claude-code\", \"claude-desktop\", \"cursor\"] as const;\nexport type ClientId = (typeof CLIENTS)[number];\n\nconst MCP_ENTRY = { command: \"npx\", args: [\"-y\", \"valija\", \"mcp\"] };\n\nexport function clientConfigPath(client: ClientId, platform = process.platform): string {\n const home = homedir();\n switch (client) {\n case \"claude-code\":\n return join(home, \".claude.json\");\n case \"cursor\":\n return join(home, \".cursor\", \"mcp.json\");\n case \"claude-desktop\": {\n if (platform === \"win32\")\n return join(\n process.env.APPDATA ?? join(home, \"AppData\", \"Roaming\"),\n \"Claude\",\n \"claude_desktop_config.json\",\n );\n if (platform === \"darwin\")\n return join(home, \"Library\", \"Application Support\", \"Claude\", \"claude_desktop_config.json\");\n return join(home, \".config\", \"Claude\", \"claude_desktop_config.json\");\n }\n }\n}\n\nexport interface InstallResult {\n configPath: string;\n backupPath: string | null;\n}\n\n/** Read the client config as an object; malformed or non-object content aborts — never overwrite it. */\nfunction readExistingConfig(configPath: string): Record<string, unknown> {\n if (!existsSync(configPath)) return {};\n const parsed: unknown = JSON.parse(readFileSync(configPath, \"utf8\"));\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${configPath} does not contain a JSON object; not touching it.`);\n }\n return parsed as Record<string, unknown>;\n}\n\n/** Copy the current config aside before modifying it; ensure the directory for fresh installs. */\nfunction backupExisting(configPath: string): string | null {\n if (!existsSync(configPath)) {\n mkdirSync(dirname(configPath), { recursive: true });\n return null;\n }\n const backupPath = `${configPath}.backup-${Date.now()}`;\n copyFileSync(configPath, backupPath);\n return backupPath;\n}\n\n/** Merge the valija server into mcpServers, preserving everything else in the config. */\nfunction mergeValijaEntry(existing: Record<string, unknown>): Record<string, unknown> {\n const servers =\n typeof existing.mcpServers === \"object\" && existing.mcpServers !== null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n return { ...existing, mcpServers: { ...servers, valija: MCP_ENTRY } };\n}\n\nexport function installIntoClient(client: ClientId): InstallResult {\n const configPath = clientConfigPath(client);\n const existing = readExistingConfig(configPath);\n const backupPath = backupExisting(configPath);\n const merged = mergeValijaEntry(existing);\n writeFileSync(configPath, `${JSON.stringify(merged, null, 2)}\\n`, \"utf8\");\n return { configPath, backupPath };\n}\n\nexport function manualInstructions(client: ClientId): string {\n return (\n `Add this to the \"mcpServers\" object of ${clientConfigPath(client)}:\\n\\n` +\n ` \"valija\": ${JSON.stringify(MCP_ENTRY, null, 2).replace(/\\n/g, \"\\n \")}\\n`\n );\n}\n","import { type DomainError, ok, type Result } from \"../../../shared/domain/result.js\";\nimport { importerErr } from \"../errors.js\";\n\n/**\n * Where an imported conversation came from. Part of the importers' ubiquitous\n * language: it names the parser, tags each imported item, and labels provenance\n * headers. Lives in the domain so every layer depends inward on it.\n */\nexport const IMPORT_SOURCES = [\"chatgpt\", \"claude\", \"generic\"] as const;\n\nexport type ImportSource = (typeof IMPORT_SOURCES)[number];\n\nexport function parseImportSource(raw: string): Result<ImportSource, DomainError> {\n if ((IMPORT_SOURCES as readonly string[]).includes(raw)) {\n return ok(raw as ImportSource);\n }\n return importerErr(\n \"UNSUPPORTED_SOURCE\",\n `Source must be one of ${IMPORT_SOURCES.join(\", \")}. Got: \"${raw}\"`,\n );\n}\n","import type {\n ImportConversationsInput,\n ImportConversationsOutput,\n} from \"../../importers/application/use-cases/import-conversations.use-case.js\";\nimport {\n type ImportSource,\n parseImportSource,\n} from \"../../importers/domain/values/import-source.js\";\nimport type { Container } from \"../container.js\";\nimport { fail, truncate } from \"./render.js\";\n\ninterface ImportOptions {\n project?: string;\n from?: string;\n list?: boolean;\n pick?: string;\n query?: string;\n since?: string;\n all?: boolean;\n dryRun?: boolean;\n}\n\nexport function importCommand(c: Container, file: string, options: ImportOptions): void {\n // A selection flag means a real import or dry-run preview, which report against a target,\n // so -p is required. With no selection the command just lists (a bare --dry-run lists too).\n const hasSelection =\n options.all === true ||\n options.pick !== undefined ||\n options.query !== undefined ||\n options.since !== undefined;\n if (hasSelection && options.project === undefined) {\n console.error(\"error: -p <project> is required to import. Run with --list first to preview.\");\n process.exit(1);\n }\n\n const input: ImportConversationsInput = {\n filePath: file,\n ...(options.project === undefined ? {} : { projectName: options.project }),\n ...(options.from === undefined ? {} : { from: resolveSource(options.from) }),\n ...(options.list === undefined ? {} : { list: options.list }),\n ...(options.pick === undefined ? {} : { pick: options.pick }),\n ...(options.query === undefined ? {} : { query: options.query }),\n ...(options.since === undefined ? {} : { since: options.since }),\n ...(options.all === undefined ? {} : { all: options.all }),\n ...(options.dryRun === undefined ? {} : { dryRun: options.dryRun }),\n };\n\n const result = c.importConversations.execute(input);\n if (!result.ok) fail(result.error);\n\n if (result.value.mode === \"list\") renderListing(result.value);\n else renderSummary(result.value);\n}\n\nfunction resolveSource(raw: string): ImportSource {\n const parsed = parseImportSource(raw);\n if (!parsed.ok) fail(parsed.error);\n return parsed.value;\n}\n\nfunction renderListing(summary: ImportConversationsOutput): void {\n const rows = summary.listing ?? [];\n if (rows.length === 0) {\n console.log(\"No conversations found in this export.\");\n return;\n }\n console.log(`${rows.length} conversation(s) in this ${summary.source} export:\\n`);\n console.log(\" # DATE CHUNKS TITLE\");\n for (const row of rows) {\n console.log(\n `${String(row.index).padStart(3)} ${row.date} ${String(row.estimatedChunks).padStart(6)} ${truncate(row.title, 48)}`,\n );\n }\n console.log(\n \"\\nSelect with --pick 1,3-5, --query <text>, --since <YYYY-MM-DD>, or --all. Add --dry-run to preview.\",\n );\n}\n\nfunction renderSummary(summary: ImportConversationsOutput): void {\n const target = summary.project === undefined ? \"\" : ` into \"${summary.project}\"`;\n const verb = summary.mode === \"dry-run\" ? \"Would import\" : \"Imported\";\n console.log(\n `${verb} ${summary.imported} item(s) from ${summary.conversations} conversation(s)${target} (skipped ${summary.skipped}, failed ${summary.failed}).`,\n );\n for (const failure of summary.failures) {\n console.error(` failed: ${failure.conversation} — ${failure.reason}`);\n }\n}\n","export function renderRecoveryKit(vaultId: string, keyHex: string, createdAt: string): string {\n return `================================================================\n VALIJA RECOVERY KIT\n================================================================\n\nCreated: ${createdAt}\nVault id: ${vaultId}\n\nRAW ENCRYPTION KEY (hex):\n\n ${keyHex}\n\n----------------------------------------------------------------\nWHAT THIS IS\n\nThis key decrypts your valija vault (~/.valija/vault.db) WITHOUT\nthe passphrase. It is the only way back in if you forget your\npassphrase. There is no server, no account, no reset email.\n\n passphrase lost + this kit lost = your data is gone. Forever.\n\nWHAT TO DO WITH IT\n\n 1. Print this file or copy it by hand.\n 2. Store it OFFLINE: a drawer, a safe, a password manager you\n trust — anywhere that is not this computer.\n 3. Delete this file from disk once stored.\n\nHOW TO RECOVER\n\n valija unlock --recovery-key <the hex above>\n\nAnyone holding this key can read your vault. Guard it like a key.\n================================================================\n`;\n}\n","import { createInterface, type Interface } from \"node:readline\";\n\nconst CTRL_C = String.fromCharCode(0x03);\nconst BACKSPACE = String.fromCharCode(0x08);\nconst DEL = String.fromCharCode(0x7f);\n\n// Shared line reader for piped stdin: one chunk can carry several lines,\n// so a per-prompt reader would swallow the lines meant for later prompts.\nlet reader: Interface | undefined;\nconst bufferedLines: string[] = [];\nconst waiters: Array<(line: string) => void> = [];\n\nfunction readPipedLine(): Promise<string> {\n if (reader === undefined) {\n reader = createInterface({ input: process.stdin });\n reader.on(\"line\", (line) => {\n const waiter = waiters.shift();\n if (waiter) waiter(line);\n else bufferedLines.push(line);\n if (waiters.length === 0) reader?.pause();\n });\n }\n const queued = bufferedLines.shift();\n if (queued !== undefined) return Promise.resolve(queued);\n reader.resume();\n return new Promise((resolve) => waiters.push(resolve));\n}\n\nfunction readHiddenTtyLine(): Promise<string> {\n return new Promise((resolve) => {\n const { stdin, stdout } = process;\n const chars: string[] = [];\n const onData = (buf: Buffer) => {\n for (const c of buf.toString(\"utf8\")) {\n if (c === \"\\r\" || c === \"\\n\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n stdout.write(\"\\n\");\n resolve(chars.join(\"\"));\n return;\n }\n if (c === CTRL_C) {\n stdin.setRawMode(false);\n stdout.write(\"\\n\");\n process.exit(130);\n }\n if (c === BACKSPACE || c === DEL) chars.pop();\n else chars.push(c);\n }\n };\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n\n/** Prompt for a secret. Hides input on a TTY; reads plain lines when piped. */\nexport function promptHidden(question: string): Promise<string> {\n process.stdout.write(question);\n return process.stdin.isTTY === true ? readHiddenTtyLine() : readPipedLine();\n}\n","import { renderRecoveryKit } from \"../../vault/infra/recovery-kit.js\";\nimport type { Container } from \"../container.js\";\nimport { promptHidden } from \"./prompt.js\";\nimport { fail } from \"./render.js\";\n\nexport async function initCommand(c: Container): Promise<void> {\n console.log(\"Creating your encrypted vault.\\n\");\n console.log(\"Choose a passphrase (min 8 chars). You will need it to unlock the vault.\");\n console.log(\"If you lose it AND the recovery kit, your data is gone. No reset exists.\\n\");\n\n const passphrase = await promptHidden(\"Passphrase: \");\n const confirmation = await promptHidden(\"Repeat passphrase: \");\n if (passphrase !== confirmation) {\n console.error(\"error: passphrases do not match.\");\n process.exit(1);\n }\n\n console.log(\"\\nDeriving key (Argon2id, ~1s)...\");\n const result = await c.createVault.execute(passphrase);\n if (!result.ok) fail(result.error);\n\n const kit = renderRecoveryKit(result.value.vaultId, result.value.keyHex, result.value.createdAt);\n console.log(`\\nVault created at ${c.paths.root} and unlocked.\\n`);\n console.log(kit);\n console.log(\"^ THIS IS YOUR RECOVERY KIT — it is shown ONCE and never stored.\");\n console.log(\" Copy it somewhere safe (offline) before you close this terminal.\\n\");\n console.log('Next: run \"valija install claude-code\" (or claude-desktop, cursor).');\n}\n\nexport async function unlockCommand(\n c: Container,\n options: { recoveryKey?: string },\n): Promise<void> {\n const input =\n options.recoveryKey !== undefined\n ? { recoveryKeyHex: options.recoveryKey }\n : { passphrase: await promptHidden(\"Passphrase: \") };\n const result = await c.unlockVault.execute(input);\n if (!result.ok) fail(result.error);\n console.log(\"Vault unlocked. MCP tools can now read and write context.\");\n console.log('Lock it again with \"valija lock\".');\n}\n\nexport function lockCommand(c: Container): void {\n const result = c.lockVault.execute();\n if (!result.ok) fail(result.error);\n console.log(result.value.wasUnlocked ? \"Vault locked.\" : \"Vault was already locked.\");\n}\n\nexport function statusCommand(c: Container): void {\n const result = c.vaultStatus.execute();\n if (!result.ok) fail(result.error);\n const s = result.value;\n if (!s.initialized) {\n console.log('No vault on this machine. Run \"valija init\" to create one.');\n return;\n }\n console.log(`vault: ${s.dbPath}`);\n console.log(`vault id: ${s.vaultId}`);\n console.log(`state: ${s.unlocked ? \"UNLOCKED\" : \"LOCKED\"}`);\n}\n"],"mappings":"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","names":["PATTERN","reader","readFileSync","readFileSync","z","z","z","z","z","z","parseDate","existsSync","mkdirSync","existsSync","mkdirSync","z","ok","err","z","writeFileSync","writeFileSync","existsSync","readFileSync","copyFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","existsSync","readFileSync"]}