@earthlink/dotvault 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +229 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2326 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../shared/src/api-types.ts","../../shared/src/errors.ts","../../shared/src/capabilities.ts","../src/config.ts","../src/env-vars.ts","../src/http.ts","../src/keychain.ts","../src/commands/global.ts","../src/commands/list.ts","../src/prompt.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/pull.ts","../src/env-writer.ts","../src/commands/run.ts","../src/commands/files.ts","../src/scan.ts","../src/commands/write.ts","../src/commands/whoami.ts","../src/commands/init.ts","../src/commands/project.ts","../src/commands/token.ts"],"sourcesContent":["#!/usr/bin/env node\n// dotvault CLI — top-level commander integration. Each subcommand delegates\n// to a pure function in ./commands/* so unit tests can exercise the logic\n// without spawning the bin.\n\nimport { realpathSync } from 'node:fs';\nimport { basename } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createRequire } from 'node:module';\nimport { Command } from 'commander';\nimport { isEnvSyncError, ValidationError } from '@earthlink/env-sync-shared';\nimport {\n globalDeleteCommand,\n globalDescribeCommand,\n globalDropCommand,\n globalKeysCommand,\n globalSetCommand,\n globalStatusCommand,\n globalUseCommand,\n} from './commands/global.js';\nimport { listCommand } from './commands/list.js';\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { pullCommand, type PullStage } from './commands/pull.js';\nimport { runCommand } from './commands/run.js';\nimport { filesCommand, pushCommand } from './commands/files.js';\nimport { scanPaths } from './scan.js';\nimport {\n deleteCommand,\n describeCommand,\n importCommand,\n parsePairs,\n rollbackCommand,\n setCommand,\n versionsCommand,\n} from './commands/write.js';\nimport { whoamiCommand } from './commands/whoami.js';\nimport { initCommand } from './commands/init.js';\nimport { projectCreateCommand } from './commands/project.js';\nimport { tokenCreateCommand, tokenListCommand, tokenRevokeCommand } from './commands/token.js';\n\n// Minimal hand-rolled ANSI helpers — no chalk/ora dependency for a handful\n// of colored lines. Colors and the in-place progress bar are both skipped\n// when stdout isn't a TTY (redirected to a file/CI log) or NO_COLOR is set,\n// so piped output stays plain text.\nconst useColor = (stream: NodeJS.WriteStream): boolean =>\n stream.isTTY === true && process.env.NO_COLOR === undefined;\n\nconst paint = (code: string, s: string, stream: NodeJS.WriteStream): string =>\n useColor(stream) ? `\\x1b[${code}m${s}\\x1b[0m` : s;\n\nconst green = (s: string): string => paint('32', s, process.stdout);\nconst red = (s: string): string => paint('31', s, process.stderr);\nconst cyan = (s: string): string => paint('36', s, process.stdout);\nconst bold = (s: string): string => paint('1', s, process.stdout);\nconst dim = (s: string): string => paint('2', s, process.stdout);\n\nconst PULL_STAGES: readonly PullStage[] = ['authenticating', 'fetching', 'writing'];\nconst PULL_STAGE_LABELS: Record<PullStage, string> = {\n authenticating: 'Authenticating…',\n fetching: 'Fetching secrets…',\n writing: 'Writing files…',\n};\n\nfunction renderProgressBar(step: number, total: number, width = 20): string {\n const filled = Math.round((step / total) * width);\n return `[${'█'.repeat(filled)}${'-'.repeat(width - filled)}]`;\n}\n\n/** Renders an in-place (carriage-return) progress line for each pull stage.\n * No-op on non-TTY stdout so redirected/CI output has no control chars. */\nfunction pullProgressReporter(): (stage: PullStage) => void {\n return (stage: PullStage) => {\n if (!useColor(process.stdout)) return;\n const step = PULL_STAGES.indexOf(stage) + 1;\n const bar = renderProgressBar(step, PULL_STAGES.length);\n process.stdout.write(`\\r\\x1b[K${cyan(bar)} ${dim(PULL_STAGE_LABELS[stage])}`);\n };\n}\n\nfunction clearProgressLine(): void {\n if (!useColor(process.stdout)) return;\n process.stdout.write('\\r\\x1b[K');\n}\n\n// Read the version from package.json at runtime so the CLI always reports\n// the version that was actually published — no hardcoded strings to drift.\nfunction readPackageVersion(): string {\n try {\n // createRequire works in both ESM (bundled) and CJS contexts.\n const require = createRequire(import.meta.url);\n const pkg = require('../package.json') as { version: string };\n return pkg.version;\n } catch {\n // Fallback for unusual environments (symlinked global installs, etc.)\n return '0.0.0-unknown';\n }\n}\n\nexport const PACKAGE_VERSION = readPackageVersion();\n\nexport function buildProgram(): Command {\n const program = new Command();\n // Positional options + pass-through so flags after the command (e.g.\n // `dotvault run -- node --inspect server.js`) go to the child, not dotvault.\n program.enablePositionalOptions();\n program\n .name('dotvault')\n .description(\n 'dotvault — sync .env / .npmrc / .gitconfig and any config file across machines and CI/CD. No AWS account required.',\n )\n .usage('<command> [options]')\n .version(PACKAGE_VERSION);\n\n program.addHelpText(\n 'after',\n `\nExamples:\n $ dotvault login # browser-based auth (Cognito)\n $ dotvault pull # write .env / .npmrc etc. to local disk\n $ dotvault run -- npm run dev # inject secrets into child process (no file written)\n $ dotvault push .npmrc # add any file to the sync set\n $ dotvault scan . # detect committed secrets\n\nCommon workflows:\n - First-time setup: dotvault login → dotvault pull\n - Local dev: dotvault run -- npm run dev\n - CI/CD pull: dotvault login (service token) → dotvault pull --env production\n - Audit history: dotvault versions DATABASE_URL\n - Roll back a secret: dotvault rollback DATABASE_URL --to 4\n - Mint a CI token: dotvault token create --org <id> --name ci --role viewer\n - Share a key org-wide: dotvault global keys → dotvault global use <KEY>\n\nMore:\n Admin console: https://app.dotvault.io\n Help & FAQ: https://app.dotvault.io/admin/help\n Docs: https://github.com/EarthLinkNetwork/dotvault#readme`,\n );\n\n program\n .command('init')\n .description('Create project-config.json with sensible defaults')\n .option('-n, --name <name>', 'project name (default: current directory name)')\n .option('--api <url>', 'API base URL (default: https://api.dotvault.io/v1)')\n .option('-f, --force', 'overwrite existing config')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault init\n $ dotvault init --name my-app\n $ dotvault init --name my-app --api https://self-hosted.example.com/v1`,\n )\n .action(async (opts: { name?: string; api?: string; force?: boolean }) => {\n const result = await initCommand(opts);\n process.stdout.write(\n `Created project-config.json (project=${result.project}). Next: dotvault login && dotvault pull\\n`,\n );\n });\n\n program\n .command('login')\n .description('Log in with email + password and store tokens in OS keychain')\n .option('-e, --email <email>', 'email (skip the prompt)')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault login # prompts for email + password\n $ dotvault login -e you@dotvault.io`,\n )\n .action(async (opts: { email?: string }) => {\n const result = await loginCommand({ email: opts.email });\n const expiresIn = Math.max(0, result.expiresAt - Math.floor(Date.now() / 1000));\n process.stdout.write(\n `Logged in as ${result.email}. Token expires in ${expiresIn}s. Refresh token saved.\\n`,\n );\n });\n\n program\n .command('pull')\n .description('Pull env vars and write them to every declared file (markers preserved).')\n .option('-p, --project <project>', 'override project name')\n .option('-E, --env <env>', 'environment: development | staging | production')\n .option('-f, --file <file>', 'pull only this file (e.g. .env.local)')\n .option('-t, --target <path>', 'DEPRECATED — pre-2.7.0 alias for --file. Use --file instead.')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault pull # all declared files\n $ dotvault pull --file .env.local # .env.local only\n $ dotvault pull --env staging # staging environment`,\n )\n .action(async (opts: { project?: string; env?: string; file?: string; target?: string }) => {\n if (opts.target !== undefined && opts.file === undefined) {\n process.stderr.write('warning: --target is deprecated as of v0.5.0; use --file instead.\\n');\n }\n let result;\n try {\n result = await pullCommand({ ...opts, onProgress: pullProgressReporter() });\n } catch (err) {\n // A mid-flight failure leaves the progress bar sitting on its own\n // unterminated line — clear it so the red error below doesn't get\n // glued onto the end of \"Fetching secrets…\" etc.\n clearProgressLine();\n throw err;\n }\n clearProgressLine();\n for (const f of result.files) {\n process.stdout.write(\n `${green('✓')} Wrote ${f.writtenKeys.length} keys to ${f.target} ` +\n `(project=${result.project}, env=${result.env}, file=${f.file}). Markers preserved.\\n`,\n );\n }\n const { filesSynced, filesExcluded, totalKeys } = result.summary;\n process.stdout.write(\n `${bold(green('✔'))} ${filesSynced} file${filesSynced === 1 ? '' : 's'} synced, ` +\n `${filesExcluded} excluded, ${totalKeys} key${totalKeys === 1 ? '' : 's'} total\\n`,\n );\n });\n\n program\n .command('run')\n .description(\n 'Inject secrets into a child process (no .env written). Recommended for local dev and CI.',\n )\n .option('-p, --project <project>', 'override project name')\n .option('-E, --env <env>', 'environment: development | staging | production')\n .option('-f, --file <file>', 'inject only this file (e.g. .env.local)')\n .argument('<command...>', 'command to run with secrets injected into its environment')\n .passThroughOptions()\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault run -- node server.js\n $ dotvault run --env production -- npm start`,\n )\n .action(\n async (commandParts: string[], opts: { project?: string; env?: string; file?: string }) => {\n const [command, ...args] = commandParts;\n const result = await runCommand({\n project: opts.project,\n env: opts.env,\n file: opts.file,\n command: command ?? '',\n args,\n });\n process.exitCode = result.exitCode;\n },\n );\n\n const writeOpts = (cmd: Command): Command =>\n cmd\n .option('-p, --project <project>', 'override project name')\n .option('-E, --env <env>', 'environment: development | staging | production')\n .option('-f, --file <file>', 'target file (e.g. .env.local)');\n\n writeOpts(\n program\n .command('set')\n .description('Set one or more secrets.')\n .argument('<pairs...>', 'KEY=VALUE pairs')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault set DATABASE_URL=postgres://localhost\n $ dotvault set FOO=1 BAR=2 BAZ=3`,\n ),\n ).action(async (pairs: string[], opts: { project?: string; env?: string; file?: string }) => {\n const r = await setCommand({ ...opts, pairs });\n for (const k of r.results) {\n process.stdout.write(`set ${k.key} (v${k.version}) in ${r.file} [${r.project}/${r.env}]\\n`);\n }\n });\n\n writeOpts(\n program\n .command('describe')\n .description(\"Set or clear a secret's description (metadata, not the value).\")\n .argument('<key>', 'the key')\n .argument('<text>', 'description text; pass \"\" to clear')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault describe DATABASE_URL \"prod read replica, rotated quarterly\"\n $ dotvault describe DATABASE_URL \"\" # clears the description`,\n ),\n ).action(\n async (key: string, text: string, opts: { project?: string; env?: string; file?: string }) => {\n const r = await describeCommand({ ...opts, key, text });\n if (r.notFound !== undefined && r.notFound.length > 0) {\n process.stderr.write(\n `warning: ${key} has no current value in ${r.file} [${r.project}/${r.env}] — description not applied\\n`,\n );\n process.exitCode = 1;\n return;\n }\n process.stdout.write(`described ${key} in ${r.file} [${r.project}/${r.env}]\\n`);\n },\n );\n\n writeOpts(\n program\n .command('delete')\n .description('Delete one or more secrets.')\n .argument('<keys...>', 'keys to delete')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault delete OLD_API_KEY`,\n ),\n ).action(async (keys: string[], opts: { project?: string; env?: string; file?: string }) => {\n const r = await deleteCommand({ ...opts, keys });\n process.stdout.write(\n `deleted ${r.deleted.length} keys from ${r.file} [${r.project}/${r.env}]\\n`,\n );\n });\n\n writeOpts(\n program\n .command('import')\n .description('Import all key/value pairs from a .env file.')\n .argument('<path>', 'path to a .env file')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault import .env.production`,\n ),\n ).action(async (path: string, opts: { project?: string; env?: string; file?: string }) => {\n const r = await importCommand({ ...opts, path });\n process.stdout.write(\n `imported ${r.results.length} keys into ${r.file} [${r.project}/${r.env}]\\n`,\n );\n });\n\n writeOpts(\n program\n .command('versions')\n .description('Show version history of a secret key.')\n .argument('<key>', 'the key')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault versions DATABASE_URL`,\n ),\n ).action(async (key: string, opts: { project?: string; env?: string; file?: string }) => {\n const r = await versionsCommand({ ...opts, key });\n process.stdout.write(\n `${r.key} [${r.project}/${r.env}/${r.file}] — ${r.versions.length} versions\\n`,\n );\n for (const v of r.versions) {\n process.stdout.write(\n ` v${v.version} ${v.createdAt} by ${v.createdBy} sha=${v.valueSha256.slice(0, 12)}\\n`,\n );\n }\n });\n\n writeOpts(\n program\n .command('rollback')\n .description('Restore a secret key to a prior version.')\n .argument('<key>', 'the key')\n .requiredOption('--to <version>', 'version number to restore')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault rollback DATABASE_URL --to 4`,\n ),\n ).action(\n async (key: string, opts: { project?: string; env?: string; file?: string; to: string }) => {\n const r = await rollbackCommand({ ...opts, key, toVersion: Number(opts.to) });\n process.stdout.write(\n `rolled back ${r.key} to v${r.restoredFrom} (now v${r.version}) in ${r.file} [${r.project}/${r.env}]\\n`,\n );\n },\n );\n\n program\n .command('list')\n .description('List the (env, file) inventory available to pull for this project.')\n .option('-p, --project <project>', 'override project name')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault list\n $ dotvault list --project my-app`,\n )\n .action(async (opts: { project?: string }) => {\n const result = await listCommand(opts);\n if (result.files.length === 0) {\n process.stdout.write(`project=${result.project}: no files visible.\\n`);\n return;\n }\n // Simple table — keep formatting predictable for shell pipelines.\n const widths = {\n env: Math.max(3, ...result.files.map((f) => f.env.length)),\n file: Math.max(4, ...result.files.map((f) => f.file.length)),\n keys: 4,\n };\n const pad = (s: string, w: number): string => s.padEnd(w);\n process.stdout.write(`project=${result.project}\\n`);\n process.stdout.write(\n `${pad('env', widths.env)} ${pad('file', widths.file)} ${pad('keys', widths.keys)} last_modified\\n`,\n );\n for (const f of result.files) {\n process.stdout.write(\n `${pad(f.env, widths.env)} ${pad(f.file, widths.file)} ${pad(String(f.keyCount), widths.keys)} ${f.lastModifiedAt ?? '-'}\\n`,\n );\n }\n });\n\n // ADR-0022 D5 — manage this project's binding to the org's shared\n // \"global\" key pool. `pull` needs no CLI change: bound keys are already\n // merged in server-side.\n const globalGroup = program\n .command('global')\n .description('Manage this project\\'s binding to the org\\'s shared \"global\" key pool.');\n\n globalGroup\n .command('keys')\n .description(\"List the org's global key pool (name + description + which envs have a value).\")\n .option(\n '--org <id>',\n 'org id — required when signed in via `dotvault login` (ignored for service tokens, which already encode their org)',\n )\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global keys\n $ dotvault global keys --org org_eln`,\n )\n .action(async (opts: { org?: string }) => {\n const result = await globalKeysCommand({ orgId: opts.org });\n if (result.keys.length === 0) {\n process.stdout.write('org has no global keys.\\n');\n return;\n }\n // ADR-0024 D2: a key can have the common (`_all`) value, per-env\n // overrides, or both — display them as `common,<override>,...` so\n // it's clear which envs get the common value vs. an explicit\n // override (resolution at pull time is override(env) ?? common).\n const formatEnvs = (k: { has_common: boolean; override_envs: string[] }): string =>\n [...(k.has_common ? ['common'] : []), ...k.override_envs].join(',') || '-';\n const widths = {\n key: Math.max(3, ...result.keys.map((k) => k.key.length)),\n envs: Math.max(4, ...result.keys.map((k) => formatEnvs(k).length)),\n };\n const pad = (s: string, w: number): string => s.padEnd(w);\n process.stdout.write(`${pad('key', widths.key)} ${pad('envs', widths.envs)} description\\n`);\n for (const k of result.keys) {\n process.stdout.write(\n `${pad(k.key, widths.key)} ${pad(formatEnvs(k), widths.envs)} ${k.description ?? '-'}\\n`,\n );\n }\n });\n\n globalGroup\n .command('set')\n .description('Add or update one or more values in the global key pool (ADR-0023).')\n .argument('<pairs...>', 'KEY=VALUE pairs')\n .option(\n '-E, --env <env>',\n 'environment (development/staging/production, or a custom env) — omit for the common value shared by every env unless overridden',\n )\n .option('--org <id>', 'org id — required when signed in via `dotvault login`')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global set SENTRY_DSN=https://... # common value (all envs)\n $ dotvault global set SENTRY_DSN=https://... -E production # override for production only`,\n )\n .action(async (pairs: string[], opts: { env?: string; org?: string }) => {\n const keys = parsePairs(pairs);\n if (Object.keys(keys).length === 0) {\n throw new ValidationError('global set requires at least one KEY=VALUE');\n }\n const result = await globalSetCommand({ env: opts.env, orgId: opts.org, keys });\n process.stdout.write(\n `set ${result.results.length} key(s) in the global pool [${result.env}]\\n`,\n );\n if (result.notFound !== undefined && result.notFound.length > 0) {\n process.stdout.write(`Warning: no description target for: ${result.notFound.join(', ')}\\n`);\n }\n });\n\n globalGroup\n .command('delete')\n .description('Remove one or more keys from the global key pool (ADR-0023).')\n .argument('<keys...>', 'key names')\n .option(\n '-E, --env <env>',\n 'environment (development/staging/production, or a custom env) — omit to delete the common value',\n )\n .option('--org <id>', 'org id — required when signed in via `dotvault login`')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global delete SENTRY_DSN # deletes the common value\n $ dotvault global delete SENTRY_DSN -E production # deletes the production override only`,\n )\n .action(async (keys: string[], opts: { env?: string; org?: string }) => {\n const result = await globalDeleteCommand({ env: opts.env, orgId: opts.org, keys });\n process.stdout.write(\n `deleted ${result.deleted.length} key(s) from the global pool [${result.env}]\\n`,\n );\n });\n\n globalGroup\n .command('describe')\n .description(\"Set or clear (empty text) a global pool key's description (ADR-0020).\")\n .argument('<KEY>', 'global key name')\n .argument('<text>', 'description text (empty string clears it)')\n .option(\n '-E, --env <env>',\n 'environment (development/staging/production, or a custom env) — omit for the common value',\n )\n .option('--org <id>', 'org id — required when signed in via `dotvault login`')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global describe SENTRY_DSN \"Shared Sentry project DSN\" -E production`,\n )\n .action(async (key: string, text: string, opts: { env?: string; org?: string }) => {\n const result = await globalDescribeCommand({ env: opts.env, orgId: opts.org, key, text });\n process.stdout.write(`described ${key} in the global pool [${result.env}]\\n`);\n });\n\n globalGroup\n .command('status')\n .description(\"Show this project's current global-key bindings.\")\n .option('-p, --project <project>', 'override project name')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global status`,\n )\n .action(async (opts: { project?: string }) => {\n const result = await globalStatusCommand(opts);\n if (result.bindings.length === 0) {\n process.stdout.write(`project=${result.project}: no global keys bound.\\n`);\n return;\n }\n process.stdout.write(`project=${result.project}\\n`);\n for (const b of result.bindings) {\n process.stdout.write(b.alias !== undefined ? `${b.key} -> ${b.alias}\\n` : `${b.key}\\n`);\n }\n });\n\n globalGroup\n .command('use')\n .description('Bind an org global key to this project (received on the next pull).')\n .argument('<KEY>', 'global key name')\n .option('-p, --project <project>', 'override project name')\n .option('--as <name>', 'rename the key on output (defaults to the key name)')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global use SENTRY_DSN\n $ dotvault global use GH_TOKEN --as GITHUB_TOKEN`,\n )\n .action(async (key: string, opts: { project?: string; as?: string }) => {\n const result = await globalUseCommand({ project: opts.project, key, alias: opts.as });\n const asSuffix = opts.as !== undefined ? ` (as ${opts.as})` : '';\n process.stdout.write(`Bound ${key}${asSuffix} to ${result.project}.\\n`);\n if (result.unknown_keys !== undefined && result.unknown_keys.length > 0) {\n process.stdout.write(\n `Warning: the global project has no value yet for: ${result.unknown_keys.join(', ')}\\n`,\n );\n }\n });\n\n globalGroup\n .command('drop')\n .description('Unbind an org global key from this project.')\n .argument('<KEY>', 'global key name')\n .option('-p, --project <project>', 'override project name')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault global drop SENTRY_DSN`,\n )\n .action(async (key: string, opts: { project?: string }) => {\n const result = await globalDropCommand({ project: opts.project, key });\n process.stdout.write(`Dropped ${key} from ${result.project}.\\n`);\n });\n\n writeOpts(\n program\n .command('push')\n .description('Sync a whole file as-is (.npmrc, kubeconfig, certs, etc.). Zero extra config.')\n .argument('<path>', 'file to upload')\n .option('--as <destPath>', 'destination path on pull/run (default: same as path)')\n .option('--pointer <env>', 'pointer env var for run (default: known-tool table)')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault push .npmrc\n $ dotvault push ~/.kube/config --as .kube/config --pointer KUBECONFIG`,\n ),\n ).action(\n async (\n path: string,\n opts: { project?: string; env?: string; as?: string; pointer?: string },\n ) => {\n const r = await pushCommand({\n project: opts.project,\n env: opts.env,\n path,\n as: opts.as,\n pointer: opts.pointer,\n });\n process.stdout.write(\n `pushed ${r.name} (v${r.version}) → ${r.destPath}` +\n (r.pointerEnv ? ` [run sets ${r.pointerEnv}]` : '') +\n '\\n',\n );\n },\n );\n\n program\n .command('files')\n .description('List files synced for this project/env.')\n .option('-p, --project <project>', 'override project name')\n .option('-E, --env <env>', 'environment')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault files\n $ dotvault files --env production`,\n )\n .action(async (opts: { project?: string; env?: string }) => {\n const files = await filesCommand(opts);\n if (files.length === 0) {\n process.stdout.write('No files synced.\\n');\n return;\n }\n for (const f of files) {\n process.stdout.write(\n `${f.name} → ${f.destPath}${f.pointerEnv ? ` (${f.pointerEnv})` : ''}\\n`,\n );\n }\n });\n\n program\n .command('scan')\n .description('Scan files for committed secrets (offline). Exits non-zero if any found.')\n .argument('[paths...]', 'files or directories to scan (default: current directory)')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault scan . # current directory\n $ dotvault scan src/ tests/ # multiple targets`,\n )\n .action((paths: string[]) => {\n const targets = paths.length > 0 ? paths : ['.'];\n const findings = scanPaths(targets);\n if (findings.length === 0) {\n process.stdout.write('No secrets found.\\n');\n return;\n }\n for (const f of findings) {\n process.stdout.write(`${f.file}:${f.line} [${f.rule}] ${f.description} — ${f.excerpt}\\n`);\n }\n process.stderr.write(`\\n${findings.length} potential secret(s) found.\\n`);\n process.exitCode = 1;\n });\n\n const token = program\n .command('token')\n .description('Manage service tokens (CI/CD machine identity). Requires org_admin.');\n\n token\n .command('list')\n .description('List service tokens for an org.')\n .requiredOption('--org <id>', 'org id (see `dotvault whoami` or the admin console)')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault token list --org org_abc123`,\n )\n .action(async (opts: { org: string }) => {\n const result = await tokenListCommand({ orgId: opts.org });\n if (result.tokens.length === 0) {\n process.stdout.write('No service tokens.\\n');\n return;\n }\n const widths = {\n id: Math.max(8, ...result.tokens.map((t) => t.tokenId.length)),\n name: Math.max(4, ...result.tokens.map((t) => t.name.length)),\n role: 6,\n };\n const pad = (s: string, w: number): string => s.padEnd(w);\n process.stdout.write(\n `${pad('token_id', widths.id)} ${pad('name', widths.name)} ${pad('role', widths.role)} expires_at revoked\\n`,\n );\n for (const t of result.tokens) {\n const exp = t.expiresAt === null ? 'never' : new Date(t.expiresAt * 1000).toISOString();\n process.stdout.write(\n `${pad(t.tokenId, widths.id)} ${pad(t.name, widths.name)} ${pad(t.role, widths.role)} ${exp} ${t.revoked ? 'yes' : 'no'}\\n`,\n );\n }\n });\n\n token\n .command('create')\n .description('Mint a new service token. The token value is shown ONCE.')\n .requiredOption('--org <id>', 'org id')\n .requiredOption('--name <name>', 'human-readable label (e.g. \"ci-prod\")')\n .requiredOption('--role <role>', 'viewer | member | provisioner')\n .option('--project <id>', 'restrict the token to a single project')\n .option('--ttl <seconds>', 'seconds until expiry (default: never)', (v) => Number(v))\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault token create --org org_abc --name ci-prod --role viewer\n $ dotvault token create --org org_abc --name ci-deploy --role member --ttl 2592000\n $ dotvault token create --org org_abc --name claude-provision --role provisioner\n\nA provisioner token (ADR-0018) can create projects but cannot read or write\nsecrets; use it as DOTVAULT_ADMIN_TOKEN (or legacy ENV_SYNC_ADMIN_TOKEN) for\nheadless \\`project create\\`.\n\nSave the printed est_… token in your CI secret store immediately — it cannot\nbe retrieved again.`,\n )\n .action(\n async (opts: { org: string; name: string; role: string; project?: string; ttl?: number }) => {\n if (opts.role !== 'viewer' && opts.role !== 'member' && opts.role !== 'provisioner') {\n process.stderr.write(\n `role must be 'viewer', 'member', or 'provisioner' (got '${opts.role}')\\n`,\n );\n process.exitCode = 1;\n return;\n }\n if (opts.ttl !== undefined && (!Number.isFinite(opts.ttl) || opts.ttl <= 0)) {\n process.stderr.write(`--ttl must be a positive integer (seconds)\\n`);\n process.exitCode = 1;\n return;\n }\n const result = await tokenCreateCommand({\n orgId: opts.org,\n name: opts.name,\n role: opts.role,\n projectId: opts.project,\n ttlSeconds: opts.ttl,\n });\n process.stdout.write(`token_id: ${result.tokenId}\\n`);\n process.stdout.write(`name: ${result.name}\\n`);\n process.stdout.write(`role: ${result.role}\\n`);\n if (result.projectId !== undefined) {\n process.stdout.write(`project: ${result.projectId}\\n`);\n }\n process.stdout.write(\n `expires: ${result.expiresAt === null ? 'never' : new Date(result.expiresAt * 1000).toISOString()}\\n`,\n );\n process.stdout.write(`\\ntoken (save now — shown only once):\\n${result.token}\\n`);\n },\n );\n\n token\n .command('revoke')\n .description('Revoke a service token by id.')\n .requiredOption('--org <id>', 'org id')\n .requiredOption('--id <token_id>', 'token id to revoke')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault token revoke --org org_abc --id est_meta_xyz`,\n )\n .action(async (opts: { org: string; id: string }) => {\n await tokenRevokeCommand({ orgId: opts.org, tokenId: opts.id });\n process.stdout.write(`Revoked token ${opts.id}.\\n`);\n });\n\n const project = program\n .command('project')\n .description('Manage projects (create without the admin web console — ADR-0018).');\n\n project\n .command('create')\n .description('Create a project. Works headlessly with a provisioner token.')\n .requiredOption('--name <name>', 'project name (^[a-z0-9][a-z0-9_-]*$)')\n .option('--org <id>', 'owning org id (optional with a provisioner token)')\n .addHelpText(\n 'after',\n `\nCredential precedence: DOTVAULT_ADMIN_TOKEN (or legacy ENV_SYNC_ADMIN_TOKEN) →\nDOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) → keychain login.\n\nExample (headless — Claude Code / CI):\n $ DOTVAULT_ADMIN_TOKEN=est_… dotvault project create --name myapp\n\nExample (interactive):\n $ dotvault login && dotvault project create --name myapp --org org_abc`,\n )\n .action(async (opts: { name: string; org?: string }) => {\n const result = await projectCreateCommand({ name: opts.name, orgId: opts.org });\n process.stdout.write(`project: ${result.project}\\n`);\n if (result.project_id !== undefined) {\n process.stdout.write(`project_id: ${result.project_id}\\n`);\n }\n if (result.owning_org_id !== undefined) {\n process.stdout.write(`org: ${result.owning_org_id}\\n`);\n }\n process.stdout.write(`created_at: ${result.createdAt}\\n`);\n });\n\n program\n .command('logout')\n .description('Remove stored tokens from the OS keychain.')\n .action(async () => {\n const email = await logoutCommand();\n if (email === null) {\n process.stdout.write('Not logged in.\\n');\n } else {\n process.stdout.write(`Logged out ${email}.\\n`);\n }\n });\n\n program\n .command('whoami')\n .description('Show the logged-in user and token expiry.')\n .addHelpText(\n 'after',\n `\nExample:\n $ dotvault whoami`,\n )\n .action(async () => {\n const result = await whoamiCommand();\n if (result === null) {\n process.stdout.write('Not logged in.\\n');\n process.exitCode = 3;\n return;\n }\n if (result.kind === 'service') {\n process.stdout.write(\n `Service token (DOTVAULT_TOKEN=${result.tokenPrefix}…) — CI / Lambda mode\\n`,\n );\n return;\n }\n process.stdout.write(`${result.email} (token expires in ${result.expiresInSeconds}s)\\n`);\n });\n\n return program;\n}\n\n// ADR-0026 D1: the CLI is invoked via two bin names — `dotvault` (primary)\n// and `env-sync` (compat alias, kept working indefinitely). When invoked via\n// the legacy name, print a one-line stderr notice so users learn about the\n// rename without breaking their existing scripts/aliases. `argv1` is the\n// literal path the shell/kernel passed as argv[1] (the invoked bin symlink\n// name, not its realpath-resolved target — POSIX shebang semantics), so\n// this reflects the name the user actually typed.\nexport function renameNoticeFor(argv1: string | undefined): string | null {\n if (argv1 === undefined) return null;\n // Split on both separators: on POSIX, node:path's basename() already\n // handles `/`, but a Windows global-install shim path (backslashes) can\n // reach this function even when the CLI itself runs on POSIX (e.g. under\n // test), so strip both defensively before falling back to path.basename.\n const lastSegment = argv1.split(/[/\\\\]/).pop() ?? argv1;\n const base = basename(lastSegment).replace(/\\.(cmd|ps1|exe)$/i, '');\n if (base !== 'env-sync') return null;\n return 'env-sync is now dotvault — the env-sync command keeps working as an alias.';\n}\n\nexport async function main(\n argv: readonly string[],\n argv1: string | undefined = process.argv[1],\n): Promise<number> {\n const notice = renameNoticeFor(argv1);\n if (notice !== null) {\n process.stderr.write(`${notice}\\n`);\n }\n const program = buildProgram();\n try {\n await program.parseAsync(argv as string[], { from: 'user' });\n const code = process.exitCode;\n return typeof code === 'number' ? code : 0;\n } catch (err) {\n if (isEnvSyncError(err)) {\n process.stderr.write(`${red('✖')} ${err.code}: ${err.message}\\n`);\n return err.exitCode;\n }\n process.stderr.write(`${red('✖')} unexpected: ${(err as Error).message}\\n`);\n return 99;\n }\n}\n\nconst isDirectRun = (() => {\n if (process.argv[1] === undefined) return false;\n try {\n return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1]);\n } catch {\n return false;\n }\n})();\n\nif (isDirectRun) {\n main(process.argv.slice(2)).then((code) => {\n process.exit(code);\n });\n}\n","// API contract types. Source of truth: claude-plugins/SDD-0007 §4 + SDD-0008\n// (mirrored here so CLI and Lambda type-check against an identical shape and\n// any drift surfaces at compile time).\n\nexport interface AuthLoginRequest {\n email: string;\n password: string;\n}\n\nexport interface AuthLoginResponse {\n idToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n/** Returned by /auth/login when the user has TOTP MFA enrolled (PRD-0006 E17a).\n * The caller must answer with the TOTP code via /auth/mfa-respond. */\nexport interface AuthChallengeResponse {\n challenge: 'SOFTWARE_TOKEN_MFA';\n session: string;\n email: string;\n}\n\nexport type AuthLoginResult = AuthLoginResponse | AuthChallengeResponse;\n\nexport function isAuthChallenge(r: AuthLoginResult): r is AuthChallengeResponse {\n return 'challenge' in r;\n}\n\nexport interface AuthMfaRespondRequest {\n email: string;\n session: string;\n /** 6-digit TOTP code from the authenticator app. */\n code: string;\n}\n\nexport interface AuthRefreshRequest {\n refreshToken: string;\n}\n\nexport interface AuthRefreshResponse {\n idToken: string;\n expiresIn: number;\n}\n\nexport type EnvName = 'development' | 'staging' | 'production';\n\nexport const STANDARD_ENVS: readonly EnvName[] = ['development', 'staging', 'production'];\n\nexport function isStandardEnv(value: string): value is EnvName {\n return value === 'development' || value === 'staging' || value === 'production';\n}\n\n// ADR-0024 D1 — env names are no longer a closed enum. The standard 3 remain\n// system-wide and always present; each project may additionally declare its\n// own custom envs (projects-table `environments` attribute, custom-only).\n// `EnvNameOrCustom` documents that intent at the type level while remaining\n// `string` at runtime — the server is the source of truth for validity via\n// `isStandardEnv` + the project's declared list (see\n// packages/lambda/src/lib/env-validation.ts). Do not add client-side enum\n// checks against this type (ADR-0024 Consequences — CLI `-E` defers fully to\n// the server).\nexport type EnvNameOrCustom = string;\n\n// Custom env name rule (ADR-0024 D1): lowercase start, then lowercase\n// alphanumeric/dash, 1-32 chars total.\nexport const CUSTOM_ENV_NAME_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;\n\n// Reserved words a custom env name may never equal: the standard 3, the\n// always-present `_shared` per-project layer, the `_global` pool namespace,\n// the `_all` pool pseudo-env (ADR-0024 D2), and the reserved global file\n// slug (\"env\") which would otherwise collide with SECRETS_TABLE SK prefixes.\nexport const RESERVED_ENV_NAMES: ReadonlySet<string> = new Set([\n 'development',\n 'staging',\n 'production',\n '_shared',\n '_global',\n '_all',\n 'env',\n]);\n\nexport function isValidCustomEnvName(value: string): boolean {\n return CUSTOM_ENV_NAME_PATTERN.test(value) && !RESERVED_ENV_NAMES.has(value);\n}\n\n// ── ADR-0025 D1: environment metadata (description, rename-ability) ────────\n\n/** `standard` = the fixed 3 (dev/staging/production). `shared` = the\n * always-on `_shared` per-project merge layer. `custom` = a project-declared\n * env (ADR-0024 D1). Only `custom` envs are deletable/renamable/describable\n * by the project owner — standard/shared are structural and immutable. */\nexport type EnvironmentKind = 'standard' | 'shared' | 'custom';\n\nexport interface EnvironmentDetail {\n name: string;\n kind: EnvironmentKind;\n /** `null` for a custom env that has never had a description set. Always\n * non-null for standard/shared (server-constant default text below). */\n description: string | null;\n deletable: boolean;\n renamable: boolean;\n}\n\n/** Server-constant default descriptions for the standard 3 — surfaced via\n * `environment_details` (ADR-0025 D1) when a project has never overridden\n * them (which it can't: standard envs never accept `environment_meta`). */\nexport const STANDARD_ENV_DESCRIPTIONS: Readonly<Record<EnvName, string>> = {\n development: '開発環境。日々の開発作業に使う値を保存します。',\n staging: 'ステージング環境。本番反映前の検証に使う値を保存します。',\n production: '本番環境。実際にサービスへ反映される値を保存します。',\n};\n\n/** ADR-0025 D5 — the `_shared` layer's fixed description text. */\nexport const SHARED_ENV_DESCRIPTION =\n '全環境の pull に merge される共通層。削除・名前変更はできません。環境別の同名キーが優先されます。';\n\n/** Per-custom-env metadata (ADR-0025 D1). Keyed by env name; only ever holds\n * entries for envs in the project's `environments` (custom) list — standard\n * 3 / `_shared` never appear here (server rejects meta writes for them). */\nexport interface EnvironmentMetaEntry {\n description?: string;\n}\nexport type EnvironmentMetaMap = Record<string, EnvironmentMetaEntry>;\n\n// ADR-0024 D2 — the global pool's pseudo-env for the common/shared-across-all\n// value (`SECRET#<org>#_global#_all`). Any real env (standard or custom) can\n// hold an override row on top of it; resolution at pull time is\n// `override(env) ?? GLOBAL_ALL_ENV`. Shared here (not just in\n// packages/lambda/src/lib/global-namespace.ts) so the CLI can default an\n// omitted `-E` on `global set/delete/describe` to the same literal without\n// duplicating the string.\nexport const GLOBAL_ALL_ENV = '_all';\n\nexport type FileSlug = string;\n\n/** File slug used when SSM params live at the legacy /env/<env>/<KEY> depth\n * (no per-file layer). Maps to the on-disk filename \".env.local\". */\nexport const DEFAULT_FILE_SLUG: FileSlug = 'env.local';\n\n/** Slug character set: alphanumeric + dot + underscore + dash. The first\n * character must be alphanumeric to forbid hidden slugs like \"..\" and\n * cross-platform path traversal. (NFR-3 in PRD-0008.) */\nexport const FILE_SLUG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\n\nexport function isValidFileSlug(value: string): boolean {\n if (value.length === 0 || value.length > 64) return false;\n if (value.includes('..')) return false;\n return FILE_SLUG_PATTERN.test(value);\n}\n\n/** \".env.local\" → \"env.local\". Strips a single leading dot if present so the\n * slug matches what we store in SSM. Throws on slugs that fail validation. */\nexport function fileNameToSlug(fileName: string): FileSlug {\n const slug = fileName.startsWith('.') ? fileName.slice(1) : fileName;\n if (!isValidFileSlug(slug)) {\n throw new Error(`Invalid env file name: ${JSON.stringify(fileName)}`);\n }\n return slug;\n}\n\n/** \"env.local\" → \".env.local\". Adds a leading dot iff missing. */\nexport function slugToFileName(slug: FileSlug): string {\n return slug.startsWith('.') ? slug : `.${slug}`;\n}\n\nexport interface EnvPullQuery {\n project: string;\n env: EnvNameOrCustom;\n /** Optional. When set, server returns only the named file. When absent,\n * server returns every file declared for the project (multi-file mode). */\n file?: string;\n}\n\nexport interface EnvPullResponse {\n project: string;\n env: EnvNameOrCustom;\n /** Filename the response applies to, e.g. \".env.local\". Always present\n * starting in schema 2.7.0 (was implicit \".env.local\" before). */\n file: string;\n keys: Record<string, string>;\n source: {\n shared: string[];\n envSpecific: string[];\n /** ADR-0023: keys sourced from the org's `_global` key pool (bound via\n * ADR-0022 explicit binding), merged in as the lowest-precedence layer.\n * Absent/undefined when the consumer project has zero bindings. */\n global?: string[];\n };\n}\n\nexport interface FileEnvKeys {\n /** \".env.local\", \".env.development\", etc. — ready to use as target path. */\n file: string;\n keys: Record<string, string>;\n source: {\n shared: string[];\n envSpecific: string[];\n /** ADR-0023: keys sourced from the org's `_global` key pool (bound via\n * ADR-0022 explicit binding), merged in as the lowest-precedence layer.\n * Absent/undefined when the consumer project has zero bindings. */\n global?: string[];\n };\n}\n\nexport interface EnvPullAllResponse {\n project: string;\n env: EnvNameOrCustom;\n files: FileEnvKeys[];\n}\n\nexport interface EnvListQuery {\n project: string;\n}\n\nexport interface FileMeta {\n env: EnvNameOrCustom;\n /** \".env.local\" form, ready to render. */\n file: string;\n keyCount: number;\n /** ISO 8601 UTC of the most recently modified param in this (env, file)\n * bucket, or null if no params exist yet (registered but empty). */\n lastModifiedAt: string | null;\n}\n\nexport interface EnvListResponse {\n project: string;\n files: FileMeta[];\n}\n\n// ── E2 write path (PRD-0006 E2) ────────────────────────────────────────────\n\nexport interface EnvKeysWriteQuery {\n project: string;\n env: EnvNameOrCustom;\n /** Target file (e.g. \".env.local\"). */\n file: string;\n}\n\n/** PUT /v1/env/keys — set one or more keys and/or descriptions (ADR-0020).\n * At least one of `keys` / `descriptions` must be non-empty. */\nexport interface EnvSetRequest {\n keys?: Record<string, string>;\n /** Per-key description text; `''` clears an existing description. */\n descriptions?: Record<string, string>;\n}\n\nexport interface KeyVersionResult {\n key: string;\n version: number;\n}\n\nexport interface EnvSetResponse {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n results: KeyVersionResult[];\n /** Keys present only in `descriptions` (no current value) — description\n * was NOT applied for these. Only present when non-empty. */\n notFound?: string[];\n}\n\n/** DELETE /v1/env/keys — delete one or more keys. */\nexport interface EnvDeleteRequest {\n keys: string[];\n}\n\nexport interface EnvDeleteResponse {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n deleted: string[];\n}\n\n// ── E3 versioning (PRD-0006 E3 / ADR-0012) ─────────────────────────────────\n\nexport interface EnvVersionsQuery {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n key: string;\n}\n\nexport interface SecretVersion {\n key: string;\n version: number;\n valueSha256: string;\n createdAt: string;\n createdBy: string;\n}\n\nexport interface EnvVersionsResponse {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n key: string;\n versions: SecretVersion[];\n}\n\nexport interface EnvRollbackRequest {\n key: string;\n toVersion: number;\n}\n\nexport interface EnvRollbackResponse {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n key: string;\n version: number;\n restoredFrom: number;\n}\n\nexport interface ApiError {\n error: string;\n message: string;\n requestId?: string;\n}\n\n// ── E4 machine identity / service tokens (PRD-0006 E4) ─────────────────────\n\n// `viewer`/`member` are data-plane roles (read / write secrets). `provisioner`\n// (ADR-0018) is an admin-plane-only role: it can create projects in its org and\n// nothing else — it cannot read or write secrets.\nexport type ServiceTokenRole = 'viewer' | 'member' | 'provisioner';\n\nexport interface ServiceTokenCreateRequest {\n name: string;\n role: ServiceTokenRole;\n /** Restrict the token to a single project (optional). */\n projectId?: string;\n /** Seconds until expiry; null/omitted = never expires. */\n ttlSeconds?: number | null;\n}\n\nexport interface ServiceTokenMetaDTO {\n tokenId: string;\n orgId: string;\n role: ServiceTokenRole;\n projectId?: string;\n name: string;\n createdBy: string;\n createdAt: string;\n expiresAt: number | null;\n revoked: boolean;\n}\n\nexport interface ServiceTokenCreateResponse extends ServiceTokenMetaDTO {\n /** The full token — shown exactly once; only its hash is stored. */\n token: string;\n}\n\nexport interface ServiceTokenListResponse {\n tokens: ServiceTokenMetaDTO[];\n}\n\n// ── Admin: project creation (ADR-0018 — headless via provisioner token) ─────\n\nexport interface ProjectCreateRequest {\n name: string;\n /** Owning org. Optional for a provisioner token (defaults to its org). */\n owning_org_id?: string;\n}\n\nexport interface ProjectCreateResponse {\n project: string;\n /** Present on the org-aware path (absent only on the deprecated legacy path). */\n project_id?: string;\n owning_org_id?: string;\n createdAt: string;\n createdBySub: string;\n}\n\n// ── Admin: project metadata update ──────────────────────────────────────────\n// ADR-0019's is_global flag (org-wide \"global\" bucket via a regular project)\n// was removed by ADR-0023 — global keys now live in the reserved `_global`\n// namespace, never a projects-table row. See GlobalKeysQuery/Response below.\n\nexport interface ProjectUpdateRequest {\n description?: string;\n tags?: string[];\n /** ADR-0024 D1 — full replace of the project's CUSTOM env list (standard 3\n * + `_shared` are implicit and never sent here). Omitted = leave\n * unchanged. An env removed from this list that still has secrets or\n * permission rows is rejected with 409 (see admin-projects-update.ts). */\n environments?: string[];\n /** ADR-0025 D1 — full replace of the project's custom-env description map.\n * Keys not present in the (post-update) `environments` custom list, or\n * keys equal to a standard-3 name / `_shared`, are rejected with 400.\n * Omitted = leave unchanged. */\n environment_meta?: EnvironmentMetaMap;\n}\n\nexport interface ProjectUpdateResponse {\n project_id: string;\n name: string;\n org_id: string;\n description: string;\n tags: string[];\n created_at: string;\n updated_at: string;\n /** ADR-0024 D1 — full resolved env list: standard 3 + this project's\n * declared custom envs (does not include `_shared`, which is a distinct\n * always-on layer, not a selectable env). */\n environments: string[];\n /** ADR-0024 D1 — the custom-only subset of `environments` (i.e. exactly\n * what was stored in the projects-table `environments` attribute). */\n custom_environments: string[];\n /** ADR-0025 D1 — every selectable env (standard 3 + `_shared` + custom)\n * enriched with kind/description/deletable/renamable, for the Settings\n * table. Order: standard 3, `_shared`, then custom envs as declared. */\n environment_details: EnvironmentDetail[];\n}\n\n// GET /admin/projects/{name} (single-project detail) reuses ProjectUpdateResponse\n// as-is — same shape, no new type needed (see admin-projects-get.ts).\n\n// ── Admin: custom environment rename (ADR-0025 D2) ─────────────────────────\n\nexport interface EnvironmentRenameRequest {\n from: string;\n to: string;\n}\n\nexport interface EnvironmentRenameResponse {\n from: string;\n to: string;\n environments: string[];\n custom_environments: string[];\n environment_details: EnvironmentDetail[];\n}\n\n// ── Admin: projects list (GET /admin/projects, no org_id — the shape the\n// admin console's Projects list and standalone Global Keys dashboard both\n// consume) ───────────────────────────────────────────────────────────────\n\nexport interface AdminProjectListItem {\n name: string;\n /** Legacy SSM-walk path only: envs observed in stored param paths (a\n * different concept from the projects-table `environments` attribute —\n * see `environments`/`custom_environments` below). */\n envs: string[];\n /** ADR-0024 D1 — full resolved env list (standard 3 + declared custom\n * envs). Present on the DDB org-scoped path only; absent on the legacy\n * SSM-walk path (no projects-table row to read it from). */\n environments?: string[];\n /** ADR-0024 D1 — the custom-only subset of `environments`. */\n custom_environments?: string[];\n}\n\nexport interface AdminProjectsListResponse {\n projects: AdminProjectListItem[];\n /** Present only on the legacy SSM-walk path — true when MAX_PAGES was hit\n * before enumerating every project (see admin-projects-list.ts). */\n truncated?: boolean;\n}\n\n// ── ADR-0022: explicit per-project binding of global keys ──────────────────\n// Amends ADR-0019 — a project only receives the global-project keys it has\n// explicitly bound (with an optional alias), never the full global set.\n//\n// ADR-0023 replaced the \"is_global project\" storage/anchor with the reserved\n// `_global` namespace (no projects-table row). GlobalKeysQuery/Response below\n// reflect that: `project` is no longer an org anchor (org resolves via the\n// caller's service token / X-Org-Context header instead) and is optional only\n// for backward compatibility with callers that still send it.\n\n/** One global key as seen from the org's global-key inventory (GET\n * /env/global-keys). Never carries a value — only name, ADR-0020\n * description, and which envs currently hold a value for it. */\nexport interface GlobalKeyInfo {\n key: string;\n description: string | null;\n /** ADR-0024 D2 — true when the common (`_all`) value is set for this key. */\n has_common: boolean;\n /** ADR-0024 D2 — standard/custom env names holding an override value for\n * this key, in addition to (or instead of) the common value. Resolution\n * at pull time is `override(env) ?? common`. */\n override_envs: string[];\n}\n\nexport interface GlobalKeysQuery {\n /** Deprecated (ADR-0019) — ignored if sent. Org is resolved from the\n * caller's auth (service token org, or X-Org-Context + org_members for\n * Cognito) under ADR-0023. */\n project?: string;\n}\n\nexport interface GlobalKeysResponse {\n keys: GlobalKeyInfo[];\n}\n\n// ── ADR-0023: global key pool write path (PUT/DELETE /env/global-keys) ─────\n// Writes target the reserved `_global` namespace's single implicit \".env\"\n// file — same secrets-repo machinery as EnvSetRequest/EnvDeleteRequest\n// (E2), just without a `project`/`file` dimension.\n\nexport interface GlobalKeysWriteQuery {\n /** ADR-0024 D2 — optional. Omitted = the common `_all` pseudo-env (write\n * the org-wide default value). Set to write a per-env override instead. */\n env?: EnvNameOrCustom;\n}\n\n/** PUT /env/global-keys?env=E — set/update global keys and/or descriptions.\n * At least one of `keys` / `descriptions` must be non-empty. */\nexport interface GlobalKeysSetRequest {\n keys?: Record<string, string>;\n /** Per-key description text; `''` clears an existing description. */\n descriptions?: Record<string, string>;\n}\n\nexport interface GlobalKeysSetResponse {\n /** The env actually written — echoes back `_all` when the request omitted\n * `env` (ADR-0024 D2). */\n env: EnvNameOrCustom;\n results: KeyVersionResult[];\n /** Keys present only in `descriptions` (no current value) — description\n * was NOT applied for these. Only present when non-empty. */\n notFound?: string[];\n}\n\n/** DELETE /env/global-keys?env=E — delete one or more global keys. */\nexport interface GlobalKeysDeleteRequest {\n keys: string[];\n}\n\nexport interface GlobalKeysDeleteResponse {\n /** The env actually deleted from — echoes back `_all` when the request\n * omitted `env` (ADR-0024 D2). */\n env: EnvNameOrCustom;\n deleted: string[];\n}\n\n/** One project's binding of a global key, with its optional output-name\n * alias (D1 — output name defaults to the key name when alias is absent). */\nexport interface GlobalBindingEntry {\n key: string;\n alias?: string;\n}\n\nexport interface GlobalBindingsQuery {\n project: string;\n}\n\nexport interface GlobalBindingsResponse {\n project: string;\n bindings: GlobalBindingEntry[];\n}\n\nexport interface GlobalBindingsPatchRequest {\n add?: GlobalBindingEntry[];\n remove?: string[];\n}\n\nexport interface GlobalBindingsPatchResponse {\n project: string;\n bindings: GlobalBindingEntry[];\n /** `add` entries whose key does not currently exist on the global\n * project — accepted anyway (declared for a future key), surfaced here\n * as a non-fatal warning (ADR-0022 D3). */\n unknown_keys?: string[];\n}\n\n// ── E10 one-time secret sharing (PRD-0006 E10) ─────────────────────────────\n\nexport interface ShareCreateRequest {\n value: string;\n /** Seconds until expiry (default 24h, capped 7d). */\n ttlSeconds?: number;\n /** Max views (default 1, capped 100). */\n maxViews?: number;\n}\n\nexport interface ShareCreateResponse {\n shareId: string;\n expiresAt: number;\n maxViews: number;\n}\n\nexport interface ShareViewResponse {\n value: string;\n}\n\n// ── E7 webhooks (PRD-0006 E7) ──────────────────────────────────────────────\n\nexport type WebhookEventType =\n | 'key.created'\n | 'key.updated'\n | 'key.deleted'\n | 'key.rolledback'\n | 'share.created';\n\nexport interface WebhookCreateRequest {\n url: string;\n events: WebhookEventType[];\n}\n\nexport interface WebhookMetaDTO {\n webhookId: string;\n orgId: string;\n url: string;\n events: WebhookEventType[];\n active: boolean;\n createdBy: string;\n createdAt: string;\n}\n\nexport interface WebhookCreateResponse extends WebhookMetaDTO {\n /** The signing secret — shown exactly once. */\n signingSecret: string;\n}\n\nexport interface WebhookListResponse {\n webhooks: WebhookMetaDTO[];\n}\n\n// ── E8 secret rotation (PRD-0006 E8) ───────────────────────────────────────\n\nexport type RotationProvider = 'random' | 'manual';\n\nexport interface RotationSetRequest {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n key: string;\n provider: RotationProvider;\n intervalSeconds: number;\n}\n\nexport interface RotationSetResponse {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n key: string;\n provider: RotationProvider;\n intervalSeconds: number;\n nextDueAt: number;\n}\n\n// ── E9 dynamic secrets (PRD-0006 E9) ───────────────────────────────────────\n\nexport type DynamicProvider = 'ephemeral';\n\nexport interface DynamicIssueRequest {\n configId: string;\n provider?: DynamicProvider;\n ttlSeconds?: number;\n}\n\nexport interface DynamicIssueResponse {\n leaseId: string;\n credentials: Record<string, string>;\n expiresAt: number;\n}\n\n// ── E12 approval workflows (PRD-0006 E12) ──────────────────────────────────\n\nexport type ApprovalKind = 'access' | 'change';\nexport type ApprovalStatus = 'pending' | 'approved' | 'rejected';\nexport type ApprovalAction = 'approve' | 'reject';\n\nexport interface ApprovalCreateRequest {\n kind: ApprovalKind;\n payload: Record<string, unknown>;\n}\n\nexport interface ApprovalCreateResponse {\n requestId: string;\n status: ApprovalStatus;\n}\n\nexport interface ApprovalDecideRequest {\n action: ApprovalAction;\n reason?: string;\n}\n\nexport interface ApprovalDTO {\n requestId: string;\n orgId: string;\n kind: ApprovalKind;\n requester: string;\n status: ApprovalStatus;\n payload: Record<string, unknown>;\n createdAt: string;\n decidedBy?: string;\n decidedAt?: string;\n reason?: string;\n}\n\nexport interface ApprovalListResponse {\n requests: ApprovalDTO[];\n}\n\n// ── E6 integrations / sync (PRD-0006 E6) ───────────────────────────────────\n\nexport type IntegrationProvider = 'vercel' | 'github-actions' | 'aws-ssm';\n\nexport interface IntegrationCreateRequest {\n projectId: string;\n provider: IntegrationProvider;\n target: Record<string, string>;\n}\n\nexport interface IntegrationDTO {\n integrationId: string;\n orgId: string;\n projectId: string;\n provider: IntegrationProvider;\n target: Record<string, string>;\n active: boolean;\n createdAt: string;\n}\n\nexport interface IntegrationListResponse {\n integrations: IntegrationDTO[];\n}\n\n// ── E15 plan capability catalog editor (ADR-0013) ──────────────────────────\n\nexport interface PlanCatalogResponse {\n /** plan → enabled capability ids. */\n catalog: Record<string, string[]>;\n}\n\nexport interface PlanCatalogPutRequest {\n capabilities: string[];\n}\n\n// ── P7-01: extended plan catalog entry (limits + allowed_roles) ───────────\n\n/** Per-plan resource limits. null means unlimited. */\nexport interface PlanLimits {\n max_users: number | null;\n max_orgs: number | null;\n max_projects: number | null;\n max_keys: number | null;\n max_teams: number | null;\n}\n\n/**\n * Full plan catalog entry with capabilities, limits, and role restrictions.\n * Stored in DynamoDB plan-catalog table (one row per plan).\n */\nexport interface PlanCatalogEntry {\n plan: 'free' | 'team' | 'business' | 'enterprise';\n /** Enabled capability ids (ADR-0013). */\n capabilities: string[];\n /** Resource limits for this plan. */\n limits: PlanLimits;\n /** Org roles that may be assigned within this plan tier.\n * e.g. free excludes team_admin; enterprise allows all. */\n allowed_roles: OrgRoleString[];\n version: number;\n updated_at: string;\n updated_by: string;\n}\n\n/** GET /v1/platform/plan-catalog/extended — full entries with limits + roles. */\nexport interface PlanCatalogExtendedResponse {\n entries: Record<string, PlanCatalogEntry>;\n}\n\n/** PUT /v1/platform/plan-catalog/{plan}/extended — update limits + allowed_roles (+ capabilities). */\nexport interface PlanCatalogExtendedPutRequest {\n capabilities?: string[];\n limits?: PlanLimits;\n allowed_roles?: OrgRoleString[];\n}\n\n// ── E18 arbitrary file sync (PRD-0006 E18) ─────────────────────────────────\n\n/** PUT /v1/env/files?project=&env= — register/update a whole file. */\nexport interface FilePutRequest {\n /** Relative path/name, e.g. \".npmrc\" or \"config/prod.json\". */\n name: string;\n /** File content (UTF-8). */\n content: string;\n /** Where `pull` writes it (defaults to name). */\n destPath?: string;\n /** Pointer env var for `run` materialization (defaults to the known-tool\n * table; explicit value overrides). */\n pointerEnv?: string;\n}\n\nexport interface FileMetaDTO {\n name: string;\n destPath: string;\n pointerEnv?: string;\n version: number;\n valueSha256: string;\n createdAt: string;\n createdBy: string;\n}\n\nexport type FilePutResponse = FileMetaDTO;\n\nexport interface FileListResponse {\n files: FileMetaDTO[];\n}\n\nexport interface FileContentDTO {\n name: string;\n destPath: string;\n pointerEnv?: string;\n content: string;\n}\n\n/** GET /v1/env/files?project=&env= (content) — for pull/run materialization. */\nexport interface FilePullResponse {\n project: string;\n env: EnvNameOrCustom;\n files: FileContentDTO[];\n}\n\n// ── Auto-sync include/exclude metadata (F-5) ──────────────────────────────\n// GET/PUT /v1/admin/projects/{name}/envs/{env}/files/{file}/sync-config\n// A file with no stored metadata is treated as include=true (backward compat).\n\nexport interface SyncConfigPutRequest {\n include: boolean;\n}\n\nexport interface SyncConfigDTO {\n project: string;\n env: string;\n /** \".env.local\" form. */\n file: string;\n include: boolean;\n /** null when the file has no explicit metadata (defaulted to include=true). */\n updatedAt: string | null;\n updatedBy: string | null;\n}\n\nexport type SyncConfigGetResponse = SyncConfigDTO;\nexport type SyncConfigPutResponse = SyncConfigDTO;\n\n// ── Org role hierarchy (PLAN-0006 Phase 6) ────────────────────────────────\n\nexport type OrgRoleString = 'member' | 'team_admin' | 'org_admin' | 'platform_admin';\n\nexport const VALID_ORG_ROLES: OrgRoleString[] = [\n 'member',\n 'team_admin',\n 'org_admin',\n 'platform_admin',\n];\n\n/**\n * Numeric rank: higher value = higher privilege.\n * super_admin > org_admin > team_admin > member\n */\nexport const ROLE_HIERARCHY: Record<OrgRoleString, number> = {\n platform_admin: 4,\n org_admin: 3,\n team_admin: 2,\n member: 1,\n};\n\n/** Returns true when userRole has strictly greater privilege than targetRole. */\nexport function isHigherRole(userRole: OrgRoleString, targetRole: OrgRoleString): boolean {\n return ROLE_HIERARCHY[userRole] > ROLE_HIERARCHY[targetRole];\n}\n\n/**\n * Returns true when a user with `userRole` is allowed to manage (promote /\n * demote / remove) a user currently holding `targetRole`.\n * Rule: a principal can only manage roles strictly below their own level.\n */\nexport function canManageRole(userRole: OrgRoleString, targetRole: OrgRoleString): boolean {\n return isHigherRole(userRole, targetRole);\n}\n\nexport const PROJECT_ID_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\nexport function isValidProjectId(value: string): boolean {\n return PROJECT_ID_PATTERN.test(value);\n}\n\nexport function isValidEnvName(value: string): value is EnvName {\n return value === 'development' || value === 'staging' || value === 'production';\n}\n\n/** Extracts (file_slug, key) from a fully-qualified SSM parameter name.\n *\n * New layout (PRD-0008 / ADR-0015):\n * /eln/projects/<name>/env/<env>/<file_slug>/<KEY>\n * Backward-compat layout (PRD-0007 / ADR-0013):\n * /eln/projects/<name>/env/<env>/<KEY>\n *\n * Returns null for paths that don't match either shape so callers can skip\n * garbage entries instead of throwing.\n */\nexport function extractFileSlugAndKey(paramName: string): { slug: FileSlug; key: string } | null {\n const parts = paramName.split('/').filter((p) => p.length > 0);\n // parts: ['eln', 'projects', <name>, 'env', <env>, ...rest]\n if (parts.length < 6) return null;\n if (parts[0] !== 'eln' || parts[1] !== 'projects' || parts[3] !== 'env') return null;\n const rest = parts.slice(5);\n if (rest.length === 1) {\n return { slug: DEFAULT_FILE_SLUG, key: rest[0]! };\n }\n if (rest.length === 2) {\n const [slug, key] = rest;\n if (!isValidFileSlug(slug!)) return null;\n return { slug: slug!, key: key! };\n }\n return null;\n}\n","// Error classes. Exit codes are consumed by CLI process.exit and must match\n// claude-plugins/SDD-0007 §6-4 exactly.\n\nexport class EnvSyncError extends Error {\n readonly code: string;\n readonly exitCode: number;\n\n constructor(code: string, message: string, exitCode: number) {\n super(message);\n this.name = 'EnvSyncError';\n this.code = code;\n this.exitCode = exitCode;\n }\n}\n\nexport class AuthRequiredError extends EnvSyncError {\n constructor(msg = 'Not logged in. Run `dotvault login` first.') {\n super('AUTH_REQUIRED', msg, 3);\n this.name = 'AuthRequiredError';\n }\n}\n\nexport class AuthExpiredError extends EnvSyncError {\n constructor(msg = 'Session expired. Run `dotvault login`.') {\n super('AUTH_EXPIRED', msg, 3);\n this.name = 'AuthExpiredError';\n }\n}\n\nexport class InvalidCredentialsError extends EnvSyncError {\n constructor(msg = 'Invalid email or password.') {\n super('INVALID_CREDENTIALS', msg, 3);\n this.name = 'InvalidCredentialsError';\n }\n}\n\nexport class PermissionDeniedError extends EnvSyncError {\n constructor(project: string, env: string) {\n super(\n 'PERMISSION_DENIED',\n `You do not have permission for project '${project}' env '${env}'. Ask an org admin to grant access at https://app.dotvault.io.`,\n 4,\n );\n this.name = 'PermissionDeniedError';\n }\n}\n\nexport class ProjectNotFoundError extends EnvSyncError {\n constructor(project: string, env: string) {\n super(\n 'PROJECT_NOT_FOUND',\n `No secrets found for project '${project}' env '${env}'. Check the names — they are case-sensitive — and that the project exists in the admin console.`,\n 5,\n );\n this.name = 'ProjectNotFoundError';\n }\n}\n\nexport class InvalidMfaCodeError extends EnvSyncError {\n constructor(msg = 'Invalid MFA code. Try again.') {\n super('INVALID_MFA_CODE', msg, 3);\n this.name = 'InvalidMfaCodeError';\n }\n}\n\nexport class MfaSessionExpiredError extends EnvSyncError {\n constructor(msg = 'MFA session expired. Run `dotvault login` again.') {\n super('MFA_SESSION_EXPIRED', msg, 3);\n this.name = 'MfaSessionExpiredError';\n }\n}\n\nexport class NetworkError extends EnvSyncError {\n constructor(msg: string) {\n super('NETWORK_ERROR', msg, 2);\n this.name = 'NetworkError';\n }\n}\n\nexport class ValidationError extends EnvSyncError {\n constructor(msg: string) {\n super('VALIDATION_ERROR', msg, 6);\n this.name = 'ValidationError';\n }\n}\n\nexport function isEnvSyncError(value: unknown): value is EnvSyncError {\n return value instanceof EnvSyncError;\n}\n","// Plan-gated capabilities — ADR-0013.\n//\n// The single source of truth for \"which features exist\" and \"the default\n// plan → capability matrix\". The runtime matrix lives in DynamoDB\n// (eln-env-sync-plan-catalog) so a platform admin can tune it without a\n// deploy; this default is seeded at deploy time and used as the fallback.\n//\n// P7-01: extended with PlanLimits + allowed_roles defaults per plan.\n\nexport type Plan = 'free' | 'team' | 'business' | 'enterprise';\n\nexport const PLANS: readonly Plan[] = ['free', 'team', 'business', 'enterprise'];\n\nexport type Capability =\n | 'secret.versioning'\n | 'injection.run'\n | 'cli.write'\n | 'sdk.access'\n | 'integration.sync'\n | 'integration.webhook'\n | 'dynamic.secrets'\n | 'secret.rotation'\n | 'secret.sharing'\n | 'sso.saml_oidc'\n | 'scim.provisioning'\n | 'approval.workflow'\n | 'audit.search'\n | 'audit.export'\n | 'audit.siem_stream'\n | 'config.inheritance';\n\nexport const ALL_CAPABILITIES: readonly Capability[] = [\n 'secret.versioning',\n 'injection.run',\n 'cli.write',\n 'sdk.access',\n 'integration.sync',\n 'integration.webhook',\n 'dynamic.secrets',\n 'secret.rotation',\n 'secret.sharing',\n 'sso.saml_oidc',\n 'scim.provisioning',\n 'approval.workflow',\n 'audit.search',\n 'audit.export',\n 'audit.siem_stream',\n 'config.inheritance',\n];\n\n/** Default plan → enabled capabilities (ADR-0013 §1). Tunable at runtime. */\nexport const DEFAULT_PLAN_CAPABILITIES: Record<Plan, readonly Capability[]> = {\n free: ['secret.versioning', 'injection.run', 'cli.write', 'sdk.access'],\n team: [\n 'secret.versioning',\n 'injection.run',\n 'cli.write',\n 'sdk.access',\n 'integration.sync',\n 'integration.webhook',\n 'secret.sharing',\n 'audit.search',\n 'config.inheritance',\n ],\n business: [\n 'secret.versioning',\n 'injection.run',\n 'cli.write',\n 'sdk.access',\n 'integration.sync',\n 'integration.webhook',\n 'secret.sharing',\n 'audit.search',\n 'config.inheritance',\n 'approval.workflow',\n 'dynamic.secrets',\n 'secret.rotation',\n 'audit.export',\n 'sso.saml_oidc',\n ],\n enterprise: [...ALL_CAPABILITIES],\n};\n\n/** Pure check against the default matrix. Runtime callers should prefer the\n * DDB-backed capability-guard, which falls back to this. */\nexport function planHasCapabilityByDefault(plan: Plan, cap: Capability): boolean {\n return DEFAULT_PLAN_CAPABILITIES[plan].includes(cap);\n}\n\nexport function isCapability(value: string): value is Capability {\n return (ALL_CAPABILITIES as readonly string[]).includes(value);\n}\n\n// ── P7-01: default limits + allowed_roles per plan ───────────────────────\n\nimport type { PlanLimits, PlanCatalogEntry } from './api-types.js';\nimport type { OrgRoleString } from './api-types.js';\n\n/** Default resource limits per plan. null = unlimited. */\nexport const DEFAULT_PLAN_LIMITS: Record<Plan, PlanLimits> = {\n free: {\n max_users: 10,\n max_orgs: 1,\n max_projects: 5,\n max_keys: 50,\n max_teams: null,\n },\n team: {\n max_users: 100,\n max_orgs: 3,\n max_projects: 50,\n max_keys: 500,\n max_teams: 10,\n },\n business: {\n max_users: 500,\n max_orgs: null,\n max_projects: null,\n max_keys: null,\n max_teams: null,\n },\n enterprise: {\n max_users: null,\n max_orgs: null,\n max_projects: null,\n max_keys: null,\n max_teams: null,\n },\n};\n\n/** Default allowed org roles per plan.\n * free: no team_admin (team management not included).\n * team/business: member + team_admin + org_admin.\n * enterprise: all roles including platform_admin. */\nexport const DEFAULT_PLAN_ALLOWED_ROLES: Record<Plan, OrgRoleString[]> = {\n free: ['member', 'org_admin'],\n team: ['member', 'team_admin', 'org_admin'],\n business: ['member', 'team_admin', 'org_admin'],\n enterprise: ['member', 'team_admin', 'org_admin', 'platform_admin'],\n};\n\n/** Full seeded catalog entry for a plan (capabilities + limits + roles).\n * Used as DDB seed data and as a fallback when DDB row is absent. */\nexport const DEFAULT_PLAN_CATALOG: Record<Plan, PlanCatalogEntry> = {\n free: {\n plan: 'free',\n capabilities: [...DEFAULT_PLAN_CAPABILITIES.free],\n limits: DEFAULT_PLAN_LIMITS.free,\n allowed_roles: DEFAULT_PLAN_ALLOWED_ROLES.free,\n version: 1,\n updated_at: '1970-01-01T00:00:00.000Z',\n updated_by: 'system',\n },\n team: {\n plan: 'team',\n capabilities: [...DEFAULT_PLAN_CAPABILITIES.team],\n limits: DEFAULT_PLAN_LIMITS.team,\n allowed_roles: DEFAULT_PLAN_ALLOWED_ROLES.team,\n version: 1,\n updated_at: '1970-01-01T00:00:00.000Z',\n updated_by: 'system',\n },\n business: {\n plan: 'business',\n capabilities: [...DEFAULT_PLAN_CAPABILITIES.business],\n limits: DEFAULT_PLAN_LIMITS.business,\n allowed_roles: DEFAULT_PLAN_ALLOWED_ROLES.business,\n version: 1,\n updated_at: '1970-01-01T00:00:00.000Z',\n updated_by: 'system',\n },\n enterprise: {\n plan: 'enterprise',\n capabilities: [...DEFAULT_PLAN_CAPABILITIES.enterprise],\n limits: DEFAULT_PLAN_LIMITS.enterprise,\n allowed_roles: DEFAULT_PLAN_ALLOWED_ROLES.enterprise,\n version: 1,\n updated_at: '1970-01-01T00:00:00.000Z',\n updated_by: 'system',\n },\n};\n","// Reads project-config.json from the current working directory (or a\n// caller-provided path) and extracts the env-sync proxy bootstrap subset\n// the CLI needs. Validates required fields up front so command code can\n// assume invariants hold.\n//\n// Schema 2.7.0 introduces `envSync.files: string[]` (the canonical list of\n// target filenames). Schema 2.6.0's `envSync.target` is still accepted for\n// backward compatibility — when only `target` is present we treat\n// `files = [target]`. A deprecation warning is surfaced through the\n// `targetIsDeprecated` flag so command code can echo it to stderr exactly\n// once per invocation.\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { fileNameToSlug, type EnvNameOrCustom, ValidationError } from '@earthlink/env-sync-shared';\nimport { resolveApiUrlOverride } from './env-vars.js';\n\nexport interface ProxyBootstrapConfig {\n apiUrl: string;\n cognitoUserPoolId?: string;\n cognitoClientId?: string;\n}\n\nexport interface EnvSyncSettings {\n enabled: boolean;\n /** Canonical list of target files (schema 2.7.0). Always non-empty after\n * parsing; if the project-config.json only specified the legacy `target`,\n * this is `[target]` and `targetIsDeprecated` is true. */\n files: string[];\n /** Deprecated 2.6.0 single-file target. Kept here so commands that take\n * `--target` for backward compat have somewhere to read it. */\n target: string;\n /** True iff project-config.json relied on legacy `target` instead of the\n * new `files`. CLI surfaces this once as a stderr warning. */\n targetIsDeprecated: boolean;\n defaultEnv: 'development' | 'staging' | 'production';\n}\n\nexport interface ProjectConfig {\n name: string;\n proxy: ProxyBootstrapConfig;\n envSync: EnvSyncSettings;\n}\n\ninterface RawProjectConfig {\n name?: unknown;\n setup?: {\n bootstrap?: {\n mode?: unknown;\n proxy?: {\n apiUrl?: unknown;\n cognitoUserPoolId?: unknown;\n cognitoClientId?: unknown;\n };\n };\n envSync?: {\n enabled?: unknown;\n target?: unknown;\n files?: unknown;\n defaultEnv?: unknown;\n };\n };\n}\n\nexport async function loadProjectConfig(cwd: string = process.cwd()): Promise<ProjectConfig> {\n const path = resolve(cwd, 'project-config.json');\n const cfg = await loadProjectConfigIfPresent(cwd);\n if (cfg === null) {\n throw new ValidationError(\n `No project-config.json found at ${path}. Run \\`env-sync init\\` here, or run env-sync from a directory that has one.`,\n );\n }\n return cfg;\n}\n\n/** Like {@link loadProjectConfig} but returns null when the file is absent.\n * A file that exists but fails to read/parse still throws — a corrupt config\n * must never be silently treated as \"no config\". */\nexport async function loadProjectConfigIfPresent(\n cwd: string = process.cwd(),\n): Promise<ProjectConfig | null> {\n const path = resolve(cwd, 'project-config.json');\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === 'ENOENT') return null;\n throw new ValidationError(\n `Could not read project-config.json at ${path}: ${(err as Error).message}`,\n );\n }\n return parseProjectConfig(raw, path);\n}\n\n/** Canonical production API base — same value `env-sync init` scaffolds. */\nexport const DEFAULT_API_URL = 'https://api.dotvault.io/v1';\n\n/** Resolve the API base URL for commands that don't need a project context\n * (login, whoami, …): DOTVAULT_API_URL (or legacy ENV_SYNC_API_URL) override\n * → project-config.json when present → the well-known default. `login`\n * stores credentials in the OS keychain (machine-scoped), so it must work\n * from any directory. */\nexport async function resolveApiUrl(cwd: string = process.cwd()): Promise<string> {\n const override = resolveApiUrlOverride();\n if (override !== undefined && override.length > 0) return override;\n const cfg = await loadProjectConfigIfPresent(cwd);\n return cfg?.proxy.apiUrl ?? DEFAULT_API_URL;\n}\n\nexport function parseProjectConfig(raw: string, source = '<inline>'): ProjectConfig {\n let parsed: RawProjectConfig;\n try {\n parsed = JSON.parse(raw) as RawProjectConfig;\n } catch (err) {\n throw new ValidationError(`Invalid JSON in ${source}: ${(err as Error).message}`);\n }\n\n const name = parsed.name;\n if (typeof name !== 'string' || name.length === 0) {\n throw new ValidationError(`${source}: 'name' is required and must be a non-empty string`);\n }\n\n const proxyRaw = parsed.setup?.bootstrap?.proxy;\n const apiUrl = proxyRaw?.apiUrl;\n if (typeof apiUrl !== 'string' || apiUrl.length === 0) {\n throw new ValidationError(\n `${source}: 'setup.bootstrap.proxy.apiUrl' is required for env-sync CLI`,\n );\n }\n\n const envSyncRaw = parsed.setup?.envSync;\n const filesRaw = envSyncRaw?.files;\n const targetRaw = envSyncRaw?.target;\n\n let files: string[];\n let target: string;\n let targetIsDeprecated = false;\n\n if (Array.isArray(filesRaw) && filesRaw.length > 0) {\n files = [];\n for (const f of filesRaw) {\n if (typeof f !== 'string' || f.length === 0) {\n throw new ValidationError(\n `${source}: 'setup.envSync.files' must be a non-empty array of file name strings`,\n );\n }\n // Reject anything that fails the slug check after dropping the leading\n // dot. This catches \"../etc/passwd\", absolute paths, and embedded\n // separators before the value reaches the file system.\n try {\n fileNameToSlug(f);\n } catch (err) {\n throw new ValidationError(\n `${source}: 'setup.envSync.files' entry ${JSON.stringify(f)} is invalid: ${(err as Error).message}`,\n );\n }\n files.push(f);\n }\n target = typeof targetRaw === 'string' && targetRaw.length > 0 ? targetRaw : files[0]!;\n } else if (typeof targetRaw === 'string' && targetRaw.length > 0) {\n // Schema 2.6.0 fallback. Validate it as a file name too.\n try {\n fileNameToSlug(targetRaw);\n } catch (err) {\n throw new ValidationError(\n `${source}: 'setup.envSync.target' is invalid: ${(err as Error).message}`,\n );\n }\n files = [targetRaw];\n target = targetRaw;\n targetIsDeprecated = true;\n } else {\n throw new ValidationError(\n `${source}: provide 'setup.envSync.files' (preferred, schema 2.7.0) or 'setup.envSync.target' (deprecated, schema 2.6.0)`,\n );\n }\n\n const defaultEnv = envSyncRaw?.defaultEnv;\n if (defaultEnv !== 'development' && defaultEnv !== 'staging' && defaultEnv !== 'production') {\n throw new ValidationError(\n `${source}: 'setup.envSync.defaultEnv' must be one of development/staging/production`,\n );\n }\n const enabledRaw = envSyncRaw?.enabled;\n const enabled = typeof enabledRaw === 'boolean' ? enabledRaw : false;\n\n const cognitoUserPoolId =\n typeof proxyRaw?.cognitoUserPoolId === 'string' ? proxyRaw.cognitoUserPoolId : undefined;\n const cognitoClientId =\n typeof proxyRaw?.cognitoClientId === 'string' ? proxyRaw.cognitoClientId : undefined;\n\n return {\n name,\n proxy: { apiUrl, cognitoUserPoolId, cognitoClientId },\n envSync: { enabled, files, target, targetIsDeprecated, defaultEnv },\n };\n}\n\n// Resolve the env to pull. Precedence (claude-plugins/SDD-0007 §6-3 / ADR-0013 D4):\n// 1. explicit --env flag\n// 2. APP_ENV environment variable\n// 3. project-config.json setup.envSync.defaultEnv\n//\n// ADR-0024 D1/D3' — env names are no longer a closed client-side enum: a\n// project may declare custom envs beyond the standard 3, and only the\n// server (which knows the project's declared list) can say whether a given\n// name is actually valid. This function used to throw on anything outside\n// development/staging/production; that check is deliberately removed here\n// (see EnvNameOrCustom's doc comment in packages/shared/src/api-types.ts) —\n// an invalid or undeclared env now surfaces as a server-side 400 instead of\n// a client-side ValidationError, keeping validation in exactly one place.\nexport function resolveEnv(\n flag: string | undefined,\n appEnvVar: string | undefined,\n defaultEnv: ProjectConfig['envSync']['defaultEnv'],\n): EnvNameOrCustom {\n return flag ?? appEnvVar ?? defaultEnv;\n}\n","// ADR-0026 D3: env var rename with indefinite legacy fallback. Each resolver\n// checks the new DOTVAULT_* name first, then the legacy ENV_SYNC_* name for\n// the *same* concept (per-variable precedence, not cross-variable) — e.g.\n// DOTVAULT_ADMIN_TOKEN never falls back to ENV_SYNC_TOKEN, only to\n// ENV_SYNC_ADMIN_TOKEN.\n\nexport function resolveServiceToken(env: NodeJS.ProcessEnv = process.env): string | undefined {\n return env.DOTVAULT_TOKEN ?? env.ENV_SYNC_TOKEN;\n}\n\nexport function resolveAdminServiceToken(env: NodeJS.ProcessEnv = process.env): string | undefined {\n return env.DOTVAULT_ADMIN_TOKEN ?? env.ENV_SYNC_ADMIN_TOKEN;\n}\n\nexport function resolveApiUrlOverride(env: NodeJS.ProcessEnv = process.env): string | undefined {\n return env.DOTVAULT_API_URL ?? env.ENV_SYNC_API_URL;\n}\n","// Thin HTTP wrapper around global fetch. Translates HTTP responses into\n// EnvSyncError subclasses with correct exit codes; the rest of the CLI never\n// touches Response objects directly. Tests inject a fetch impl rather than\n// stubbing the global.\n\nimport {\n AuthExpiredError,\n AuthRequiredError,\n EnvSyncError,\n InvalidCredentialsError,\n InvalidMfaCodeError,\n MfaSessionExpiredError,\n NetworkError,\n PermissionDeniedError,\n ProjectNotFoundError,\n type ApiError,\n type AuthLoginRequest,\n type AuthLoginResponse,\n type AuthLoginResult,\n type AuthMfaRespondRequest,\n type AuthRefreshRequest,\n type AuthRefreshResponse,\n type EnvNameOrCustom,\n type EnvListQuery,\n type EnvListResponse,\n type EnvPullAllResponse,\n type EnvPullQuery,\n type EnvPullResponse,\n type EnvKeysWriteQuery,\n type EnvSetRequest,\n type EnvSetResponse,\n type EnvDeleteRequest,\n type EnvDeleteResponse,\n type EnvVersionsQuery,\n type EnvVersionsResponse,\n type EnvRollbackRequest,\n type EnvRollbackResponse,\n type FilePutRequest,\n type FilePutResponse,\n type FilePullResponse,\n type GlobalBindingsPatchRequest,\n type GlobalBindingsPatchResponse,\n type GlobalBindingsQuery,\n type GlobalBindingsResponse,\n type GlobalKeysQuery,\n type GlobalKeysResponse,\n type GlobalKeysWriteQuery,\n type GlobalKeysSetRequest,\n type GlobalKeysSetResponse,\n type GlobalKeysDeleteRequest,\n type GlobalKeysDeleteResponse,\n type ProjectCreateRequest,\n type ProjectCreateResponse,\n type ProjectUpdateRequest,\n type ProjectUpdateResponse,\n type ServiceTokenCreateRequest,\n type ServiceTokenCreateResponse,\n type ServiceTokenListResponse,\n} from '@earthlink/env-sync-shared';\n\nexport type FetchLike = typeof fetch;\n\nexport interface HttpClient {\n /** Returns tokens, or an MFA challenge when the user has TOTP enrolled. */\n login(req: AuthLoginRequest): Promise<AuthLoginResult>;\n /** Answer a SOFTWARE_TOKEN_MFA challenge with a TOTP code. */\n mfaRespond(req: AuthMfaRespondRequest): Promise<AuthLoginResponse>;\n refresh(req: AuthRefreshRequest): Promise<AuthRefreshResponse>;\n /** Single-file pull: server returns one file's merged keys. The `file`\n * field on the query is REQUIRED for this overload; callers that want\n * every file should use `envPullAll` instead. */\n envPull(token: string, query: EnvPullQuery & { file: string }): Promise<EnvPullResponse>;\n /** Multi-file pull: server returns every file declared for the project. */\n envPullAll(token: string, query: Omit<EnvPullQuery, 'file'>): Promise<EnvPullAllResponse>;\n /** Inventory: enumerate (env, file) pairs the user is allowed to pull. */\n envList(token: string, query: EnvListQuery): Promise<EnvListResponse>;\n /** Set one or more keys (E2). */\n envKeysPut(token: string, query: EnvKeysWriteQuery, body: EnvSetRequest): Promise<EnvSetResponse>;\n /** Delete one or more keys (E2). */\n envKeysDelete(\n token: string,\n query: EnvKeysWriteQuery,\n body: EnvDeleteRequest,\n ): Promise<EnvDeleteResponse>;\n /** List a key's version history (E3). */\n envVersions(token: string, query: EnvVersionsQuery): Promise<EnvVersionsResponse>;\n /** Roll a key back to a prior version (E3). */\n envRollback(\n token: string,\n query: EnvKeysWriteQuery,\n body: EnvRollbackRequest,\n ): Promise<EnvRollbackResponse>;\n /** Register/update a whole file (E18). */\n envFilesPut(\n token: string,\n query: { project: string; env: EnvNameOrCustom },\n body: FilePutRequest,\n ): Promise<FilePutResponse>;\n /** Fetch all file secrets with content for pull/run materialization (E18). */\n envFilesGet(\n token: string,\n query: { project: string; env: EnvNameOrCustom },\n ): Promise<FilePullResponse>;\n /** ADR-0023 D3: org global-key inventory (name + ADR-0020 description +\n * which envs have a value — never the value itself). `orgId`, when set,\n * is sent as `X-Org-Context` — required for the Cognito auth path (a\n * service token's own org is used automatically server-side and needs\n * no header). `query.project` is accepted only for backward compatibility\n * with older servers/consoles and is otherwise ignored. */\n envGlobalKeys(\n token: string,\n query?: GlobalKeysQuery,\n opts?: { orgId?: string },\n ): Promise<GlobalKeysResponse>;\n /** ADR-0023 D3(b): set/update one or more global keys and/or descriptions\n * for `query.env`. Same `orgId`/X-Org-Context rule as envGlobalKeys. */\n envGlobalKeysSet(\n token: string,\n query: GlobalKeysWriteQuery,\n body: GlobalKeysSetRequest,\n opts?: { orgId?: string },\n ): Promise<GlobalKeysSetResponse>;\n /** ADR-0023 D3(b): delete one or more global keys for `query.env`. Same\n * `orgId`/X-Org-Context rule as envGlobalKeys. */\n envGlobalKeysDelete(\n token: string,\n query: GlobalKeysWriteQuery,\n body: GlobalKeysDeleteRequest,\n opts?: { orgId?: string },\n ): Promise<GlobalKeysDeleteResponse>;\n /** ADR-0022 D3: this project's current global-key bindings. */\n envGlobalBindingsGet(token: string, query: GlobalBindingsQuery): Promise<GlobalBindingsResponse>;\n /** ADR-0022 D3: diff-apply add/remove against this project's bindings. */\n envGlobalBindingsPatch(\n token: string,\n query: GlobalBindingsQuery,\n body: GlobalBindingsPatchRequest,\n ): Promise<GlobalBindingsPatchResponse>;\n /** List service tokens for an org (E4). */\n adminTokensList(token: string, query: { orgId: string }): Promise<ServiceTokenListResponse>;\n /** Mint a service token (E4). Token is returned ONCE; only its hash is stored. */\n adminTokensCreate(\n token: string,\n query: { orgId: string },\n body: ServiceTokenCreateRequest,\n ): Promise<ServiceTokenCreateResponse>;\n /** Revoke a service token by id (E4). */\n adminTokensRevoke(token: string, query: { orgId: string; tokenId: string }): Promise<void>;\n /** Create a project (ADR-0018). Works with a provisioner service token. */\n adminProjectsCreate(token: string, body: ProjectCreateRequest): Promise<ProjectCreateResponse>;\n /** Update project metadata (description, tags). */\n adminProjectsUpdate(\n token: string,\n projectRef: string,\n body: ProjectUpdateRequest,\n ): Promise<ProjectUpdateResponse>;\n}\n\nexport function createHttpClient(apiUrl: string, fetchImpl: FetchLike = fetch): HttpClient {\n const base = apiUrl.replace(/\\/+$/, '');\n\n async function post<TReq, TRes>(path: string, body: TReq, token?: string): Promise<TRes> {\n const res = await callFetch(fetchImpl, `${base}${path}`, {\n method: 'POST',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<TRes>(res);\n }\n\n return {\n async login(req) {\n return post<AuthLoginRequest, AuthLoginResult>('/auth/login', req);\n },\n\n async mfaRespond(req) {\n return post<AuthMfaRespondRequest, AuthLoginResponse>('/auth/mfa-respond', req);\n },\n\n async refresh(req) {\n return post<AuthRefreshRequest, AuthRefreshResponse>('/auth/refresh', req);\n },\n\n async envPull(token, query) {\n const url = new URL(`${base}/env/pull`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n url.searchParams.set('file', query.file);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<EnvPullResponse>(res);\n },\n\n async envPullAll(token, query) {\n const url = new URL(`${base}/env/pull`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<EnvPullAllResponse>(res);\n },\n\n async envList(token, query) {\n const url = new URL(`${base}/env/list`);\n url.searchParams.set('project', query.project);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<EnvListResponse>(res);\n },\n\n async envKeysPut(token, query, body) {\n const url = writeUrl(base, '/env/keys', query);\n const res = await callFetch(fetchImpl, url, {\n method: 'PUT',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<EnvSetResponse>(res);\n },\n\n async envKeysDelete(token, query, body) {\n const url = writeUrl(base, '/env/keys', query);\n const res = await callFetch(fetchImpl, url, {\n method: 'DELETE',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<EnvDeleteResponse>(res);\n },\n\n async envVersions(token, query) {\n const url = new URL(`${base}/env/versions`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n url.searchParams.set('file', query.file);\n url.searchParams.set('key', query.key);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<EnvVersionsResponse>(res);\n },\n\n async envRollback(token, query, body) {\n const url = writeUrl(base, '/env/rollback', query);\n const res = await callFetch(fetchImpl, url, {\n method: 'POST',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<EnvRollbackResponse>(res);\n },\n\n async envFilesPut(token, query, body) {\n const url = new URL(`${base}/env/files`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'PUT',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<FilePutResponse>(res);\n },\n\n async envFilesGet(token, query) {\n const url = new URL(`${base}/env/files`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<FilePullResponse>(res);\n },\n\n async envGlobalKeys(token, query, opts) {\n const url = new URL(`${base}/env/global-keys`);\n // ADR-0023: `project` is no longer an org anchor for this endpoint —\n // sent only for backward compatibility with older servers, and only\n // when the caller still passes one.\n if (query?.project !== undefined) url.searchParams.set('project', query.project);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token, opts?.orgId),\n });\n return handleResponse<GlobalKeysResponse>(res);\n },\n\n async envGlobalKeysSet(token, query, body, opts) {\n const url = new URL(`${base}/env/global-keys`);\n // ADR-0024 D2 — `env` is optional: omitted means write the common\n // `_all` pseudo-env, which is also the server's own default when the\n // query param is absent entirely (not just empty).\n if (query.env !== undefined) url.searchParams.set('env', query.env);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'PUT',\n headers: jsonHeaders(token, opts?.orgId),\n body: JSON.stringify(body),\n });\n return handleResponse<GlobalKeysSetResponse>(res);\n },\n\n async envGlobalKeysDelete(token, query, body, opts) {\n const url = new URL(`${base}/env/global-keys`);\n // ADR-0024 D2 — see envGlobalKeysSet above.\n if (query.env !== undefined) url.searchParams.set('env', query.env);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'DELETE',\n headers: jsonHeaders(token, opts?.orgId),\n body: JSON.stringify(body),\n });\n return handleResponse<GlobalKeysDeleteResponse>(res);\n },\n\n async envGlobalBindingsGet(token, query) {\n const url = new URL(`${base}/env/global-bindings`);\n url.searchParams.set('project', query.project);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'GET',\n headers: jsonHeaders(token),\n });\n return handleResponse<GlobalBindingsResponse>(res);\n },\n\n async envGlobalBindingsPatch(token, query, body) {\n const url = new URL(`${base}/env/global-bindings`);\n url.searchParams.set('project', query.project);\n const res = await callFetch(fetchImpl, url.toString(), {\n method: 'PATCH',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<GlobalBindingsPatchResponse>(res);\n },\n\n async adminTokensList(token, query) {\n const res = await callFetch(\n fetchImpl,\n `${base}/admin/orgs/${encodeURIComponent(query.orgId)}/tokens`,\n { method: 'GET', headers: jsonHeaders(token) },\n );\n return handleResponse<ServiceTokenListResponse>(res);\n },\n\n async adminTokensCreate(token, query, body) {\n const res = await callFetch(\n fetchImpl,\n `${base}/admin/orgs/${encodeURIComponent(query.orgId)}/tokens`,\n { method: 'POST', headers: jsonHeaders(token), body: JSON.stringify(body) },\n );\n return handleResponse<ServiceTokenCreateResponse>(res);\n },\n\n async adminTokensRevoke(token, query) {\n const res = await callFetch(\n fetchImpl,\n `${base}/admin/orgs/${encodeURIComponent(query.orgId)}/tokens/${encodeURIComponent(query.tokenId)}`,\n { method: 'DELETE', headers: jsonHeaders(token) },\n );\n if (!res.ok) {\n await handleResponse<unknown>(res); // throws\n }\n },\n\n async adminProjectsCreate(token, body) {\n const res = await callFetch(fetchImpl, `${base}/admin/projects`, {\n method: 'POST',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n });\n return handleResponse<ProjectCreateResponse>(res);\n },\n\n async adminProjectsUpdate(token, projectRef, body) {\n const res = await callFetch(\n fetchImpl,\n `${base}/admin/projects/${encodeURIComponent(projectRef)}`,\n {\n method: 'PUT',\n headers: jsonHeaders(token),\n body: JSON.stringify(body),\n },\n );\n return handleResponse<ProjectUpdateResponse>(res);\n },\n };\n}\n\n/** Build a URL for the write endpoints with project/env/file query params. */\nfunction writeUrl(base: string, path: string, query: EnvKeysWriteQuery): string {\n const url = new URL(`${base}${path}`);\n url.searchParams.set('project', query.project);\n url.searchParams.set('env', query.env);\n url.searchParams.set('file', query.file);\n return url.toString();\n}\n\n/** `orgId`, when set, is sent as `X-Org-Context` — required by the\n * `/env/global-*` endpoints' Cognito auth path (ADR-0023 D3): the server\n * resolves org membership from this header since a Cognito IdToken carries\n * no org claim and `project` is no longer an org anchor for those routes. */\nfunction jsonHeaders(token?: string, orgId?: string): Record<string, string> {\n const h: Record<string, string> = { 'content-type': 'application/json' };\n if (token !== undefined) h.authorization = `Bearer ${token}`;\n if (orgId !== undefined && orgId.length > 0) h['x-org-context'] = orgId;\n return h;\n}\n\nasync function callFetch(fetchImpl: FetchLike, url: string, init: RequestInit): Promise<Response> {\n try {\n return await fetchImpl(url, init);\n } catch (err) {\n const msg = (err as Error).message;\n throw new NetworkError(\n `Could not reach ${new URL(url).host} (${msg}). Check your network and the apiUrl in project-config.json.`,\n );\n }\n}\n\nasync function handleResponse<T>(res: Response): Promise<T> {\n if (res.ok) {\n return (await res.json()) as T;\n }\n const body = await res.text();\n let parsed: ApiError | undefined;\n try {\n parsed = JSON.parse(body) as ApiError;\n } catch {\n parsed = undefined;\n }\n const code = parsed?.error ?? `HTTP_${res.status}`;\n const message = parsed?.message ?? `Request failed: HTTP ${res.status}`;\n\n if (res.status === 400) {\n throw new EnvSyncError(code, message, 1);\n }\n if (res.status === 401) {\n if (code === 'INVALID_CREDENTIALS') throw new InvalidCredentialsError(message);\n if (code === 'INVALID_MFA_CODE') throw new InvalidMfaCodeError(message);\n if (code === 'MFA_SESSION_EXPIRED') throw new MfaSessionExpiredError(message);\n if (code === 'AUTH_EXPIRED') throw new AuthExpiredError(message);\n throw new AuthRequiredError(message);\n }\n if (res.status === 403) {\n throw new PermissionDeniedError('unknown', 'unknown');\n }\n if (res.status === 404) {\n throw new ProjectNotFoundError('unknown', 'unknown');\n }\n throw new EnvSyncError(code, message, 99);\n}\n","// OS keychain wrapper around `keytar`. Stores Cognito tokens per email\n// account under a fixed service name so multiple env-sync users can coexist\n// on one machine and `findCredentials` enumerates them.\n//\n// Imported via dynamic import so tests can mock without native bindings.\n\nconst SERVICE = 'eln-env-sync';\n\nexport interface TokenSet {\n idToken: string;\n refreshToken: string;\n expiresAt: number;\n}\n\ninterface KeytarLike {\n setPassword(service: string, account: string, password: string): Promise<void>;\n getPassword(service: string, account: string): Promise<string | null>;\n deletePassword(service: string, account: string): Promise<boolean>;\n findCredentials(service: string): Promise<Array<{ account: string; password: string }>>;\n}\n\nlet keytarInstance: KeytarLike | undefined;\n\nasync function getKeytar(): Promise<KeytarLike> {\n if (keytarInstance === undefined) {\n const mod = await import('keytar');\n keytarInstance = (mod.default ?? mod) as KeytarLike;\n }\n return keytarInstance;\n}\n\n// Test seam: inject a mock implementation. Production code never calls this.\nexport function __setKeytarForTest(mock: KeytarLike | undefined): void {\n keytarInstance = mock;\n}\n\nexport async function saveTokens(email: string, tokens: TokenSet): Promise<void> {\n const k = await getKeytar();\n await k.setPassword(SERVICE, email, JSON.stringify(tokens));\n}\n\nexport async function loadTokens(email: string): Promise<TokenSet | null> {\n const k = await getKeytar();\n const raw = await k.getPassword(SERVICE, email);\n if (raw === null) return null;\n return JSON.parse(raw) as TokenSet;\n}\n\nexport async function deleteTokens(email: string): Promise<boolean> {\n const k = await getKeytar();\n return k.deletePassword(SERVICE, email);\n}\n\nexport async function getCurrentUser(): Promise<string | null> {\n const k = await getKeytar();\n const accts = await k.findCredentials(SERVICE);\n return accts.length > 0 ? (accts[0]?.account ?? null) : null;\n}\n","// `dotvault global` — ADR-0022 D5 (binding) + ADR-0023 D4 (pool management).\n//\n// dotvault global keys org's global key pool inventory + description\n// dotvault global set KEY=V [KEY2=V2...] -E <env> add/update pool key values (ADR-0023)\n// dotvault global delete KEY [...] -E <env> remove keys from the pool (ADR-0023)\n// dotvault global describe KEY \"text\" -E <env> set/clear a pool key's description (ADR-0023)\n// dotvault global use <KEY> [--as <NAME>] bind KEY to this project (optional output rename)\n// dotvault global drop <KEY> unbind KEY from this project\n// dotvault global status this project's current bindings\n//\n// `pull` itself needs no CLI change — server-side merge already applies the\n// binding filter (ADR-0022 D4); any CLI >= 0.10 talking to a server with the\n// D4 change picks up bound keys automatically.\n//\n// Two different scopes, two different resolve() helpers:\n// - `keys`/`set`/`delete`/`describe` operate on the org-wide `_global` pool\n// itself (ADR-0023 D1/D3) — no project. Auth resolves the org from the\n// bearer: a service token self-encodes its org; a Cognito (keychain)\n// session has no org claim, so `--org <id>` is required in that case and\n// sent as `X-Org-Context` (server 400s with an actionable message if\n// omitted on the Cognito path).\n// - `use`/`drop`/`status` operate on THIS project's bindings into that pool\n// (ADR-0022, unchanged) — org is resolved from the project as before.\n//\n// Auth precedence (both scopes), same as `dotvault pull` (PRD-0006 E4):\n// 1. DOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) service token, CI / Lambda / SDK.\n// 2. keychain IdToken (interactive user; refreshed once on 401).\n\nimport {\n AuthExpiredError,\n AuthRequiredError,\n GLOBAL_ALL_ENV,\n type EnvNameOrCustom,\n type GlobalBindingsPatchResponse,\n type GlobalBindingsResponse,\n type GlobalKeysDeleteResponse,\n type GlobalKeysResponse,\n type GlobalKeysSetResponse,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens } from '../keychain.js';\n\nexport interface GlobalCommandOptions {\n project?: string;\n cwd?: string;\n /** Test seam — injected HttpClient. Production callers omit. */\n http?: HttpClient;\n}\n\nexport interface GlobalUseOptions extends GlobalCommandOptions {\n key: string;\n alias?: string;\n}\n\nexport interface GlobalDropOptions extends GlobalCommandOptions {\n key: string;\n}\n\n/** Options shared by the pool-level commands (keys/set/delete/describe) —\n * ADR-0023: no project anchor, optional `--org` for the Cognito path. */\nexport interface GlobalPoolOptions {\n orgId?: string;\n cwd?: string;\n /** Test seam — injected HttpClient. Production callers omit. */\n http?: HttpClient;\n}\n\nexport interface GlobalSetOptions extends GlobalPoolOptions {\n env?: string;\n keys?: Record<string, string>;\n descriptions?: Record<string, string>;\n}\n\nexport interface GlobalDeleteOptions extends GlobalPoolOptions {\n env?: string;\n keys: string[];\n}\n\nexport interface GlobalDescribeOptions extends GlobalPoolOptions {\n env?: string;\n key: string;\n text: string;\n}\n\nexport async function globalKeysCommand(opts: GlobalPoolOptions = {}): Promise<GlobalKeysResponse> {\n const { http, orgId, authedFetch } = await resolvePool(opts);\n return authedFetch((bearer) => http.envGlobalKeys(bearer, undefined, { orgId }));\n}\n\nexport async function globalSetCommand(opts: GlobalSetOptions): Promise<GlobalKeysSetResponse> {\n const { http, orgId, env, authedFetch } = await resolvePoolWithEnv(opts);\n const body = {\n ...(opts.keys !== undefined ? { keys: opts.keys } : {}),\n ...(opts.descriptions !== undefined ? { descriptions: opts.descriptions } : {}),\n };\n return authedFetch((bearer) => http.envGlobalKeysSet(bearer, { env }, body, { orgId }));\n}\n\nexport async function globalDeleteCommand(\n opts: GlobalDeleteOptions,\n): Promise<GlobalKeysDeleteResponse> {\n const { http, orgId, env, authedFetch } = await resolvePoolWithEnv(opts);\n return authedFetch((bearer) =>\n http.envGlobalKeysDelete(bearer, { env }, { keys: opts.keys }, { orgId }),\n );\n}\n\n/** `env-sync global describe KEY TEXT -E <env>` — set or clear (TEXT === '')\n * a pool key's description (ADR-0020). Description-only: never touches the\n * value. */\nexport async function globalDescribeCommand(\n opts: GlobalDescribeOptions,\n): Promise<GlobalKeysSetResponse> {\n const { http, orgId, env, authedFetch } = await resolvePoolWithEnv(opts);\n return authedFetch((bearer) =>\n http.envGlobalKeysSet(bearer, { env }, { descriptions: { [opts.key]: opts.text } }, { orgId }),\n );\n}\n\nexport async function globalStatusCommand(\n opts: GlobalCommandOptions = {},\n): Promise<GlobalBindingsResponse> {\n const { http, project, authedFetch } = await resolve(opts);\n return authedFetch((bearer) => http.envGlobalBindingsGet(bearer, { project }));\n}\n\nexport async function globalUseCommand(\n opts: GlobalUseOptions,\n): Promise<GlobalBindingsPatchResponse> {\n const { http, project, authedFetch } = await resolve(opts);\n const entry = opts.alias !== undefined ? { key: opts.key, alias: opts.alias } : { key: opts.key };\n return authedFetch((bearer) =>\n http.envGlobalBindingsPatch(bearer, { project }, { add: [entry] }),\n );\n}\n\nexport async function globalDropCommand(\n opts: GlobalDropOptions,\n): Promise<GlobalBindingsPatchResponse> {\n const { http, project, authedFetch } = await resolve(opts);\n return authedFetch((bearer) =>\n http.envGlobalBindingsPatch(bearer, { project }, { remove: [opts.key] }),\n );\n}\n\nasync function resolve(opts: GlobalCommandOptions): Promise<{\n http: HttpClient;\n project: string;\n authedFetch: <T>(call: (bearer: string) => Promise<T>) => Promise<T>;\n}> {\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n return { http, project, authedFetch };\n}\n\nasync function resolvePool(opts: GlobalPoolOptions): Promise<{\n http: HttpClient;\n orgId?: string;\n authedFetch: <T>(call: (bearer: string) => Promise<T>) => Promise<T>;\n}> {\n const cfg = await loadProjectConfig(opts.cwd);\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n return { http, orgId: opts.orgId, authedFetch };\n}\n\n// ADR-0024 D2 — the pool's `-E` is deliberately NOT resolved the same way as\n// a project command's (config.ts's resolveEnv, which falls back through\n// APP_ENV / project-config.json's defaultEnv): those fallbacks describe\n// \"which env is this project working in\" and are the wrong default for an\n// org-level pool command. Omitting `-E` here means \"the common value\",\n// full stop — so an omitted flag defaults straight to GLOBAL_ALL_ENV.\nasync function resolvePoolWithEnv(opts: GlobalPoolOptions & { env?: string }): Promise<{\n http: HttpClient;\n orgId?: string;\n env: EnvNameOrCustom;\n authedFetch: <T>(call: (bearer: string) => Promise<T>) => Promise<T>;\n}> {\n const cfg = await loadProjectConfig(opts.cwd);\n const env = opts.env ?? GLOBAL_ALL_ENV;\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n return { http, orgId: opts.orgId, env, authedFetch };\n}\n\n// Same pattern as commands/pull.ts buildAuthedFetch: DOTVAULT_TOKEN (or legacy\n// ENV_SYNC_TOKEN) service token (not refreshable) takes precedence; otherwise\n// the keychain IdToken, refreshed once on a 401/expired response.\nasync function buildAuthedFetch(\n http: HttpClient,\n): Promise<<T>(call: (bearer: string) => Promise<T>) => Promise<T>> {\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return (call) => call(serviceToken);\n }\n\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return async <T>(call: (bearer: string) => Promise<T>): Promise<T> => {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n };\n}\n","// `dotvault list` — show the (env, file) inventory the caller can pull for\n// this project. Reads project-config.json for the project name (or accepts an\n// override). Output is the structured ListResult that the bin renders as a\n// human table.\n//\n// Auth: same precedence as `dotvault pull` / write commands (PRD-0006 E4).\n// 1. DOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) service token, CI / Lambda / SDK\n// 2. keychain IdToken (interactive user; refreshable on 401)\n\nimport { AuthExpiredError, AuthRequiredError, type FileMeta } from '@earthlink/env-sync-shared';\nimport { loadProjectConfig } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens, type TokenSet } from '../keychain.js';\n\nexport interface ListOptions {\n project?: string;\n cwd?: string;\n /** Test seam — injected HttpClient. Production callers omit. */\n http?: HttpClient;\n}\n\nexport interface ListResult {\n project: string;\n files: FileMeta[];\n}\n\nexport async function listCommand(opts: ListOptions = {}): Promise<ListResult> {\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n const res = await http.envList(serviceToken, { project });\n return { project: res.project, files: res.files };\n }\n\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n const res = await fetchWithRefresh(http, tokens, email, (idToken) =>\n http.envList(idToken, { project }),\n );\n return { project: res.project, files: res.files };\n}\n\nasync function fetchWithRefresh<T>(\n http: HttpClient,\n tokens: TokenSet,\n email: string,\n call: (idToken: string) => Promise<T>,\n): Promise<T> {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n}\n","// Minimal TTY prompts for email and password. No dependency on inquirer to\n// keep the bin small and the install free of native rebuilds beyond keytar.\n// Password input disables tty echo, then restores it (even on error).\n\nimport { createInterface } from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\n\nexport async function promptText(label: string): Promise<string> {\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n const answer = await rl.question(label);\n return answer.trim();\n } finally {\n rl.close();\n }\n}\n\nexport async function promptPassword(label: string): Promise<string> {\n return new Promise((resolve, reject) => {\n stdout.write(label);\n const wasRaw = stdin.isTTY ? stdin.isRaw : false;\n if (stdin.isTTY) stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding('utf8');\n\n let buf = '';\n const onData = (chunk: string): void => {\n for (const ch of chunk) {\n if (ch === '\\n' || ch === '\\r' || ch === '\u0004') {\n cleanup();\n stdout.write('\\n');\n resolve(buf);\n return;\n }\n if (ch === '\u0003') {\n cleanup();\n stdout.write('\\n');\n reject(new Error('Aborted'));\n return;\n }\n if (ch === '' || ch === '\\b') {\n buf = buf.slice(0, -1);\n continue;\n }\n buf += ch;\n }\n };\n\n const cleanup = (): void => {\n stdin.off('data', onData);\n if (stdin.isTTY) stdin.setRawMode(wasRaw);\n stdin.pause();\n };\n\n stdin.on('data', onData);\n });\n}\n","// `env-sync login` — prompt for credentials, exchange for Cognito tokens via\n// the Lambda proxy, persist to OS keychain.\n// Returns the email and token expiry so callers can log it. The password\n// buffer is not retained anywhere after the HTTP call.\n\nimport {\n InvalidMfaCodeError,\n isAuthChallenge,\n type AuthLoginResponse,\n} from '@earthlink/env-sync-shared';\nimport { resolveApiUrl } from '../config.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { saveTokens } from '../keychain.js';\nimport { promptPassword, promptText } from '../prompt.js';\n\nconst MFA_MAX_ATTEMPTS = 3;\n\nexport interface LoginOptions {\n email?: string;\n cwd?: string;\n /** Test seam: inject an HttpClient. */\n http?: HttpClient;\n /** Test seam: supply the TOTP code instead of prompting. */\n mfaCode?: string;\n}\n\nexport interface LoginResult {\n email: string;\n expiresAt: number;\n mfa: boolean;\n}\n\nexport async function loginCommand(opts: LoginOptions = {}): Promise<LoginResult> {\n // login is machine-scoped (keychain) — it must not require a project\n // context. resolveApiUrl works with or without project-config.json.\n const apiUrl = await resolveApiUrl(opts.cwd);\n const email = opts.email ?? (await promptText('Email: '));\n const password = await promptPassword('Password: ');\n\n const http = opts.http ?? createHttpClient(apiUrl);\n\n const result = await http.login({ email, password });\n\n // PRD-0006 E17a: TOTP MFA challenge — prompt for the code (with retry).\n let tokens: AuthLoginResponse;\n let usedMfa = false;\n if (isAuthChallenge(result)) {\n usedMfa = true;\n tokens = await answerMfa(http, result.session, email, opts.mfaCode);\n } else {\n tokens = result;\n }\n\n const expiresAt = Math.floor(Date.now() / 1000) + tokens.expiresIn;\n await saveTokens(email, {\n idToken: tokens.idToken,\n refreshToken: tokens.refreshToken,\n expiresAt,\n });\n return { email, expiresAt, mfa: usedMfa };\n}\n\nasync function answerMfa(\n http: HttpClient,\n session: string,\n email: string,\n presetCode: string | undefined,\n): Promise<AuthLoginResponse> {\n for (let attempt = 1; attempt <= MFA_MAX_ATTEMPTS; attempt += 1) {\n const code = presetCode ?? (await promptText('MFA code: '));\n try {\n return await http.mfaRespond({ email, session, code });\n } catch (err) {\n // A wrong code is retryable within the same session; an expired session\n // (MfaSessionExpiredError) or any other error propagates immediately.\n if (\n err instanceof InvalidMfaCodeError &&\n presetCode === undefined &&\n attempt < MFA_MAX_ATTEMPTS\n ) {\n process.stderr.write('Invalid MFA code, try again.\\n');\n continue;\n }\n throw err;\n }\n }\n throw new InvalidMfaCodeError('Too many invalid MFA attempts.');\n}\n","// `env-sync logout` — purge tokens for the current keychain user. Idempotent:\n// returns null if no user was logged in.\n\nimport { deleteTokens, getCurrentUser } from '../keychain.js';\n\nexport async function logoutCommand(): Promise<string | null> {\n const email = await getCurrentUser();\n if (email === null) return null;\n await deleteTokens(email);\n return email;\n}\n","// `dotvault pull` — fetch env from the Lambda proxy and write into one or\n// more local files. Two modes:\n//\n// 1. multi-file (default): no `--file` flag. Server returns every file\n// declared for the project; CLI writes them all atomically (each file's\n// marker block is rewritten in-place; content outside the markers is\n// preserved).\n// 2. single-file: `--file <name>` (or the deprecated `--target <path>`).\n// Server returns just that file's merged keys.\n//\n// Auto-refreshes IdToken once on 401 if a RefreshToken is on hand; a second\n// 401 surfaces as AuthExpiredError.\n\nimport { writeFileSync } from 'node:fs';\nimport { resolve, basename } from 'node:path';\nimport {\n AuthExpiredError,\n AuthRequiredError,\n fileNameToSlug,\n slugToFileName,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig, resolveEnv } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { rewriteMarkers, rewriteMarkersMulti } from '../env-writer.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens } from '../keychain.js';\n\n/** Coarse stages a caller can render as progress feedback. Each fires once,\n * in order, before the corresponding network/disk work starts. */\nexport type PullStage = 'authenticating' | 'fetching' | 'writing';\n\nexport interface PullOptions {\n project?: string;\n env?: string;\n /** Server-side file slug or filename. When present, single-file mode. */\n file?: string;\n /** Deprecated alias for `file`. Accepted for one minor version to ease\n * the schema 2.6.0 → 2.7.0 migration. The CLI converts it to `file`\n * internally; the entry-point command surfaces a stderr warning. */\n target?: string;\n cwd?: string;\n /** Optional progress callback for CLI-side rendering (spinner/bar). Pure\n * logic never depends on it — tests can omit it entirely. */\n onProgress?: (stage: PullStage) => void;\n /** Test seam — injected HttpClient. Production callers omit. */\n http?: HttpClient;\n}\n\nexport interface PulledFile {\n file: string;\n writtenKeys: string[];\n target: string;\n hadExistingMarkers: boolean;\n}\n\nexport interface PullSummary {\n filesSynced: number;\n /** Files declared in project-config.json's `envSync.files` that the\n * server did not return for this env (e.g. not yet registered\n * server-side). Always 0 in single-file mode — an explicit `--file`\n * is a deliberate scope, not an exclusion. */\n filesExcluded: number;\n totalKeys: number;\n}\n\nexport interface PullResult {\n project: string;\n env: string;\n files: PulledFile[];\n summary: PullSummary;\n}\n\nexport async function pullCommand(opts: PullOptions = {}): Promise<PullResult> {\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const env = resolveEnv(opts.env, process.env.APP_ENV, cfg.envSync.defaultEnv);\n const cwd = opts.cwd ?? process.cwd();\n\n // --target is the legacy alias. When the user passed --target but not\n // --file, treat the basename of --target as the file slug.\n const explicitFile = opts.file ?? (opts.target !== undefined ? basename(opts.target) : undefined);\n\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n opts.onProgress?.('authenticating');\n const authedFetch = await buildAuthedFetch(http);\n\n if (explicitFile !== undefined) {\n const fileName = slugToFileName(fileNameToSlug(explicitFile));\n opts.onProgress?.('fetching');\n const response = await authedFetch((bearer) =>\n http.envPull(bearer, { project, env, file: fileName }),\n );\n const target = opts.target !== undefined ? resolve(cwd, opts.target) : resolve(cwd, fileName);\n opts.onProgress?.('writing');\n const result = await rewriteMarkers(target, response.keys);\n return {\n project: response.project,\n env: response.env,\n files: [\n {\n file: response.file,\n writtenKeys: result.writtenKeys,\n target,\n hadExistingMarkers: result.hadExistingMarkers,\n },\n ],\n summary: { filesSynced: 1, filesExcluded: 0, totalKeys: result.writtenKeys.length },\n };\n }\n\n // Multi-file mode.\n opts.onProgress?.('fetching');\n const response = await authedFetch((bearer) => http.envPullAll(bearer, { project, env }));\n const requests = response.files.map((f) => ({\n target: resolve(cwd, f.file),\n keys: f.keys,\n }));\n opts.onProgress?.('writing');\n const writes = await rewriteMarkersMulti(requests);\n\n // E18: also materialize whole-file secrets at their dest path (persistent\n // sync mode). Best-effort — never fails the env pull.\n try {\n const fileResp = await authedFetch((bearer) =>\n http.envFilesGet(bearer, { project, env }),\n ).catch(() => null);\n for (const f of fileResp?.files ?? []) {\n writeFileSync(resolve(cwd, f.destPath), f.content, { mode: 0o600 });\n }\n } catch {\n /* best-effort file materialization */\n }\n\n const files = response.files.map((f, i) => ({\n file: f.file,\n writtenKeys: writes[i]!.writtenKeys,\n target: writes[i]!.target,\n hadExistingMarkers: writes[i]!.hadExistingMarkers,\n }));\n\n const declaredSlugs = new Set(cfg.envSync.files.map((f) => fileNameToSlug(f)));\n const syncedSlugs = new Set(files.map((f) => fileNameToSlug(f.file)));\n const filesExcluded = [...declaredSlugs].filter((slug) => !syncedSlugs.has(slug)).length;\n const totalKeys = files.reduce((sum, f) => sum + f.writtenKeys.length, 0);\n\n return {\n project: response.project,\n env: response.env,\n files,\n summary: { filesSynced: files.length, filesExcluded, totalKeys },\n };\n}\n\n/** Build an authenticated-fetch wrapper. With DOTVAULT_TOKEN (or legacy\n * ENV_SYNC_TOKEN) set (CI/Lambda), the service token is sent directly (no\n * keychain, no refresh). Otherwise the keychain IdToken is used, refreshed\n * once on a 401. */\nasync function buildAuthedFetch(\n http: HttpClient,\n): Promise<<T>(call: (bearer: string) => Promise<T>) => Promise<T>> {\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return (call) => call(serviceToken);\n }\n\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return async <T>(call: (bearer: string) => Promise<T>): Promise<T> => {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n };\n}\n","// Rewrite key=value blocks bounded by env-sync markers inside one or more\n// target files. Content outside the markers is preserved verbatim. Writes\n// go through a temp file + rename so a crash mid-write cannot leave any\n// target half-written; for the multi-file path we stage every temp file\n// before renaming any of them so a hard failure aborts cleanly with no\n// targets touched. chmod 600 so secrets are not world-readable.\n// No .bak — old values must not linger on disk after rotation.\n\nimport { chmod, readFile, rename, unlink, writeFile } from 'node:fs/promises';\nimport { dirname, basename, join } from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport const MARKER_BEGIN = '# BEGIN: eln-bootstrap-envsync (managed by env-sync)';\nexport const MARKER_END = '# END: eln-bootstrap-envsync';\n\nexport interface RewriteResult {\n writtenKeys: string[];\n hadExistingMarkers: boolean;\n targetExisted: boolean;\n}\n\nexport async function rewriteMarkers(\n target: string,\n keys: Record<string, string>,\n): Promise<RewriteResult> {\n const prepared = await prepareRewrite(target, keys);\n await writeTemp(prepared);\n await commitTemp(prepared);\n return prepared.result;\n}\n\nexport interface MultiFileTarget {\n /** Resolved filesystem path the file should land at after rewrite. */\n target: string;\n /** Key/value pairs to render between the markers. */\n keys: Record<string, string>;\n}\n\nexport interface MultiFileResult {\n target: string;\n writtenKeys: string[];\n hadExistingMarkers: boolean;\n targetExisted: boolean;\n}\n\n/** Atomic-ish multi-file rewrite. Stages all temp files first; if any temp\n * write fails, every staged temp is unlinked and no target is renamed. If\n * any rename fails mid-loop the remaining temps are still cleaned up but\n * earlier renames stand — true cross-file atomicity is impossible without\n * a filesystem with directory-level fsync semantics we can rely on. The\n * practical guarantee is: either every file is updated or none are. */\nexport async function rewriteMarkersMulti(\n files: readonly MultiFileTarget[],\n): Promise<MultiFileResult[]> {\n const prepared: PreparedRewrite[] = [];\n try {\n for (const f of files) {\n prepared.push(await prepareRewrite(f.target, f.keys));\n }\n for (const p of prepared) {\n await writeTemp(p);\n }\n } catch (err) {\n await Promise.allSettled(prepared.map((p) => unlink(p.tmp).catch(() => undefined)));\n throw err;\n }\n\n const results: MultiFileResult[] = [];\n for (const p of prepared) {\n await commitTemp(p);\n results.push({\n target: p.target,\n writtenKeys: p.result.writtenKeys,\n hadExistingMarkers: p.result.hadExistingMarkers,\n targetExisted: p.result.targetExisted,\n });\n }\n return results;\n}\n\ninterface PreparedRewrite {\n target: string;\n tmp: string;\n content: string;\n result: RewriteResult;\n}\n\nasync function prepareRewrite(\n target: string,\n keys: Record<string, string>,\n): Promise<PreparedRewrite> {\n let existing = '';\n let targetExisted = true;\n try {\n existing = await readFile(target, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n targetExisted = false;\n } else {\n throw err;\n }\n }\n\n const { outside, hadExistingMarkers } = stripMarkerBlock(existing);\n const block = renderBlock(keys);\n const next = composeFile(outside, block);\n\n const dir = dirname(target);\n const tmpName = `.${basename(target)}.${randomBytes(6).toString('hex')}.tmp`;\n const tmp = join(dir, tmpName);\n\n return {\n target,\n tmp,\n content: next,\n result: {\n writtenKeys: Object.keys(keys),\n hadExistingMarkers,\n targetExisted,\n },\n };\n}\n\nasync function writeTemp(p: PreparedRewrite): Promise<void> {\n await writeFile(p.tmp, p.content, { mode: 0o600 });\n}\n\nasync function commitTemp(p: PreparedRewrite): Promise<void> {\n await rename(p.tmp, p.target);\n await chmod(p.target, 0o600);\n}\n\nfunction stripMarkerBlock(content: string): { outside: string; hadExistingMarkers: boolean } {\n const beginIdx = content.indexOf(MARKER_BEGIN);\n if (beginIdx === -1) {\n return { outside: content, hadExistingMarkers: false };\n }\n const endIdx = content.indexOf(MARKER_END, beginIdx);\n if (endIdx === -1) {\n return { outside: content, hadExistingMarkers: false };\n }\n const afterEnd = content.indexOf('\\n', endIdx);\n const tail = afterEnd === -1 ? '' : content.slice(afterEnd + 1);\n const head = content.slice(0, beginIdx);\n const trimmedHead = head.replace(/\\n+$/, '');\n const outside = trimmedHead.length === 0 ? tail : tail.length === 0 ? trimmedHead : `${trimmedHead}\\n${tail}`;\n return { outside, hadExistingMarkers: true };\n}\n\nfunction renderBlock(keys: Record<string, string>): string {\n const lines: string[] = [MARKER_BEGIN];\n for (const [k, v] of Object.entries(keys)) {\n lines.push(`${k}=${v}`);\n }\n lines.push(MARKER_END);\n return lines.join('\\n');\n}\n\nfunction composeFile(outside: string, block: string): string {\n if (outside.length === 0) return `${block}\\n`;\n const trimmed = outside.replace(/\\n+$/, '');\n return `${trimmed}\\n\\n${block}\\n`;\n}\n","// `dotvault run -- <command> [args...]` — PRD-0006 E1 / ADR-0011 F1.\n//\n// Process-injection mode (the documented default for local dev and CI/Lambda\n// shells): fetch the project's env for the resolved environment, inject the\n// merged keys into a child process's environment, exec the command, forward\n// stdio, and propagate the child's exit code. NOTHING is written to disk —\n// this is the security difference from `pull`, which remains for tools that\n// need a real .env file.\n//\n// Multi-file projects: every file's keys are merged into one flat env map\n// (later files in the server's returned order win on key collision; the\n// server has already merged `_shared` into each file). Pass --file to inject\n// only one file's keys. Pulled keys override inherited process env on conflict\n// (parity with `pull`'s precedence).\n//\n// Auth + token refresh mirror `pull`: try the current IdToken, refresh once on\n// 401, persist, retry.\n\nimport { spawn as nodeSpawn } from 'node:child_process';\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join, resolve } from 'node:path';\nimport {\n AuthExpiredError,\n AuthRequiredError,\n EnvSyncError,\n fileNameToSlug,\n slugToFileName,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig, resolveEnv } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens } from '../keychain.js';\n\n/** Minimal slice of child_process.spawn we depend on, so tests can inject a\n * fake without constructing a real ChildProcess. */\nexport interface SpawnedChild {\n on(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): void;\n on(event: 'error', listener: (err: Error) => void): void;\n}\nexport type SpawnLike = (\n command: string,\n args: string[],\n options: { env: NodeJS.ProcessEnv; stdio: 'inherit' },\n) => SpawnedChild;\n\nexport interface RunOptions {\n project?: string;\n env?: string;\n /** Inject only this file's keys. When absent, all files are merged. */\n file?: string;\n cwd?: string;\n /** Executable to run. */\n command: string;\n /** Arguments passed to the executable. */\n args?: string[];\n // ---- test seams ----\n http?: HttpClient;\n spawn?: SpawnLike;\n /** Base environment the child inherits before pulled keys are merged on top.\n * Defaults to process.env. */\n baseEnv?: NodeJS.ProcessEnv;\n}\n\nexport interface RunResult {\n project: string;\n env: string;\n command: string;\n /** Keys that were injected into the child process env. */\n injectedKeys: string[];\n exitCode: number;\n}\n\nexport async function runCommand(opts: RunOptions): Promise<RunResult> {\n if (opts.command === undefined || opts.command.length === 0) {\n throw new EnvSyncError(\n 'BAD_REQUEST',\n 'run requires a command, e.g. env-sync run -- npm start',\n 1,\n );\n }\n\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const env = resolveEnv(opts.env, process.env.APP_ENV, cfg.envSync.defaultEnv);\n\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n\n // Gather the keys to inject.\n let merged: Record<string, string> = {};\n if (opts.file !== undefined) {\n const fileName = slugToFileName(fileNameToSlug(opts.file));\n const response = await authedFetch((bearer) =>\n http.envPull(bearer, { project, env, file: fileName }),\n );\n merged = { ...response.keys };\n } else {\n const response = await authedFetch((bearer) => http.envPullAll(bearer, { project, env }));\n // Later files win on collision; deterministic by server order.\n for (const f of response.files) {\n merged = { ...merged, ...f.keys };\n }\n }\n\n const baseEnv = opts.baseEnv ?? process.env;\n // Pulled keys override inherited env on conflict (parity with pull).\n const childEnv: NodeJS.ProcessEnv = { ...baseEnv, ...merged };\n\n // E18: materialize file secrets ephemerally for the child, then clean up.\n // Files with a pointer env → written to a temp dir + the env points the tool\n // at them (no persistent on-disk plaintext). Files without a pointer must\n // live at their dest path → written there, deleted on exit (ephemeral in time).\n const cleanup: string[] = [];\n let tmpDir: string | undefined;\n const cwd = opts.cwd ?? process.cwd();\n try {\n const fileResp = await authedFetch((bearer) =>\n http.envFilesGet(bearer, { project, env }),\n ).catch(() => null);\n for (const f of fileResp?.files ?? []) {\n if (f.pointerEnv !== undefined) {\n tmpDir ??= mkdtempSync(join(tmpdir(), 'env-sync-files-'));\n const p = join(tmpDir, basename(f.name));\n writeFileSync(p, f.content, { mode: 0o600 });\n childEnv[f.pointerEnv] = p;\n } else {\n const p = resolve(cwd, f.destPath);\n writeFileSync(p, f.content, { mode: 0o600 });\n cleanup.push(p);\n }\n }\n } catch {\n // best-effort: file materialization failure must not block the run\n }\n\n const spawnImpl = opts.spawn ?? defaultSpawn;\n let exitCode: number;\n try {\n exitCode = await runChild(spawnImpl, opts.command, opts.args ?? [], childEnv);\n } finally {\n for (const p of cleanup) rmSync(p, { force: true });\n if (tmpDir !== undefined) rmSync(tmpDir, { recursive: true, force: true });\n }\n\n return {\n project,\n env,\n command: opts.command,\n injectedKeys: Object.keys(merged),\n exitCode,\n };\n}\n\nconst defaultSpawn: SpawnLike = (command, args, options) =>\n nodeSpawn(command, args, options) as unknown as SpawnedChild;\n\nfunction runChild(\n spawn: SpawnLike,\n command: string,\n args: string[],\n env: NodeJS.ProcessEnv,\n): Promise<number> {\n return new Promise<number>((resolveP, rejectP) => {\n const child = spawn(command, args, { env, stdio: 'inherit' });\n child.on('error', (err: Error) => {\n rejectP(new EnvSyncError('SPAWN_FAILED', `Failed to run '${command}': ${err.message}`, 127));\n });\n child.on('exit', (code: number | null) => {\n // code === null means the child was killed by a signal; we lack the\n // numeric signal portably here, so surface a generic non-zero code.\n resolveP(code ?? 1);\n });\n });\n}\n\n/** Build an authenticated-fetch wrapper. With DOTVAULT_TOKEN (or legacy\n * ENV_SYNC_TOKEN) set (CI/Lambda), the service token is sent directly (no\n * keychain, no refresh). Otherwise the keychain IdToken is used with\n * refresh-on-401. */\nasync function buildAuthedFetch(\n http: HttpClient,\n): Promise<<T>(call: (bearer: string) => Promise<T>) => Promise<T>> {\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return (call) => call(serviceToken);\n }\n\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return async <T>(call: (bearer: string) => Promise<T>): Promise<T> => {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n };\n}\n","// `dotvault push <file>` + `dotvault files` — PRD-0006 E18 arbitrary file sync.\n//\n// push: upload a file AS-IS (zero config). The server records destPath (=name)\n// and the pointer env var (from the known-tool table) automatically. Override\n// only if needed via --as / --pointer.\n//\n// files: list the registered files for the project/env.\n\nimport { readFile } from 'node:fs/promises';\nimport { basename, resolve } from 'node:path';\nimport {\n AuthExpiredError,\n AuthRequiredError,\n ValidationError,\n type EnvNameOrCustom,\n type FileMetaDTO,\n type FilePutResponse,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig, resolveEnv } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens, type TokenSet } from '../keychain.js';\n\ninterface CommonOptions {\n project?: string;\n env?: string;\n cwd?: string;\n http?: HttpClient;\n}\n\ninterface ResolvedAuth {\n project: string;\n env: EnvNameOrCustom;\n http: HttpClient;\n bearer: string;\n refreshable?: { email: string; tokens: TokenSet };\n}\n\nasync function resolveAuth(opts: CommonOptions): Promise<ResolvedAuth> {\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const env = resolveEnv(opts.env, process.env.APP_ENV, cfg.envSync.defaultEnv);\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return { project, env, http, bearer: serviceToken };\n }\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n return { project, env, http, bearer: tokens.idToken, refreshable: { email, tokens } };\n}\n\nasync function withAuth<T>(ctx: ResolvedAuth, call: (bearer: string) => Promise<T>): Promise<T> {\n try {\n return await call(ctx.bearer);\n } catch (err) {\n if (\n ctx.refreshable === undefined ||\n (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError))\n ) {\n throw err;\n }\n const { email, tokens } = ctx.refreshable;\n const refreshed = await ctx.http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n}\n\nexport async function pushCommand(\n opts: CommonOptions & { path: string; as?: string; pointer?: string },\n): Promise<FilePutResponse> {\n const cwd = opts.cwd ?? process.cwd();\n let content: string;\n try {\n content = await readFile(resolve(cwd, opts.path), 'utf8');\n } catch (err) {\n throw new ValidationError(`Could not read ${opts.path}: ${(err as Error).message}`);\n }\n // Logical name = the path as given (so dest defaults to the same relative path),\n // or just the basename when an absolute path was passed.\n const name = opts.as ?? (opts.path.startsWith('/') ? basename(opts.path) : opts.path);\n const ctx = await resolveAuth(opts);\n return withAuth(ctx, (bearer) =>\n ctx.http.envFilesPut(\n bearer,\n { project: ctx.project, env: ctx.env },\n { name, content, destPath: opts.as, pointerEnv: opts.pointer },\n ),\n );\n}\n\nexport async function filesCommand(opts: CommonOptions): Promise<FileMetaDTO[]> {\n const ctx = await resolveAuth(opts);\n const res = await withAuth(ctx, (bearer) =>\n ctx.http.envFilesGet(bearer, { project: ctx.project, env: ctx.env }),\n );\n // Map content response to metadata (CLI listing shows names, not content).\n return res.files.map((f) => ({\n name: f.name,\n destPath: f.destPath,\n pointerEnv: f.pointerEnv,\n version: 0,\n valueSha256: '',\n createdAt: '',\n createdBy: '',\n }));\n}\n","// `env-sync scan` — detect committed secrets (PRD-0006 E17b).\n//\n// A local, dependency-free secret scanner. `scanText` is pure (regex rules over\n// text) and fully unit-testable; `scanPaths` walks a directory tree, skipping\n// VCS/build/dependency dirs and binary files. Matches are redacted in output so\n// the scanner never echoes a full secret.\n\nimport { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\nexport interface ScanRule {\n id: string;\n description: string;\n regex: RegExp;\n}\n\nexport interface Finding {\n rule: string;\n description: string;\n file: string;\n line: number;\n /** Redacted excerpt (never the full secret). */\n excerpt: string;\n}\n\n// Conservative, high-signal rules (gitleaks-style). Each regex is global so a\n// line with multiple hits yields multiple findings.\nexport const RULES: ScanRule[] = [\n { id: 'aws-access-key-id', description: 'AWS Access Key ID', regex: /AKIA[0-9A-Z]{16}/g },\n {\n id: 'aws-secret-access-key',\n description: 'Possible AWS Secret Access Key',\n regex: /aws.{0,20}['\"][0-9a-zA-Z/+]{40}['\"]/gi,\n },\n {\n id: 'private-key',\n description: 'Private key block',\n regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/g,\n },\n { id: 'github-pat', description: 'GitHub personal access token', regex: /ghp_[0-9A-Za-z]{36}/g },\n {\n id: 'github-fine-grained-pat',\n description: 'GitHub fine-grained token',\n regex: /github_pat_[0-9A-Za-z_]{60,}/g,\n },\n { id: 'slack-token', description: 'Slack token', regex: /xox[baprs]-[0-9A-Za-z-]{10,}/g },\n { id: 'stripe-secret-key', description: 'Stripe secret key', regex: /sk_live_[0-9A-Za-z]{24,}/g },\n { id: 'google-api-key', description: 'Google API key', regex: /AIza[0-9A-Za-z_-]{35}/g },\n {\n id: 'dotvault-service-token',\n description: 'dotvault service token',\n regex: /est_[0-9a-f]{32}\\.[A-Za-z0-9_-]{20,}/g,\n },\n {\n id: 'generic-assignment',\n description: 'Generic secret assignment',\n regex: /(?:secret|token|password|passwd|api[_-]?key)[\"']?\\s*[:=]\\s*[\"'][^\"'\\s]{16,}[\"']/gi,\n },\n];\n\nconst SKIP_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n '.next',\n 'coverage',\n 'cdk.out',\n '.turbo',\n]);\n\nfunction redact(match: string): string {\n if (match.length <= 8) return '*'.repeat(match.length);\n return `${match.slice(0, 4)}...${match.slice(-2)} (${match.length} chars)`;\n}\n\n/** Pure scan of a blob of text. Returns one finding per rule match per line. */\nexport function scanText(content: string, file = '<text>'): Finding[] {\n const findings: Finding[] = [];\n const lines = content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i]!;\n for (const rule of RULES) {\n rule.regex.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = rule.regex.exec(line)) !== null) {\n findings.push({\n rule: rule.id,\n description: rule.description,\n file,\n line: i + 1,\n excerpt: redact(m[0]),\n });\n if (m.index === rule.regex.lastIndex) rule.regex.lastIndex += 1; // avoid zero-width loop\n }\n }\n }\n return findings;\n}\n\n/** A NUL byte in the first 8KB marks a binary file we should skip. */\nfunction looksBinary(buf: string): boolean {\n const limit = Math.min(buf.length, 8192);\n for (let i = 0; i < limit; i += 1) {\n if (buf.charCodeAt(i) === 0) return true;\n }\n return false;\n}\n\nconst MAX_FILE_BYTES = 5 * 1024 * 1024;\n\n/** Recursively scan files under the given paths (files or dirs). */\nexport function scanPaths(paths: string[], root = process.cwd()): Finding[] {\n const findings: Finding[] = [];\n const visit = (p: string): void => {\n let st;\n try {\n st = statSync(p);\n } catch {\n return;\n }\n if (st.isDirectory()) {\n for (const entry of readdirSync(p)) {\n if (SKIP_DIRS.has(entry)) continue;\n visit(join(p, entry));\n }\n return;\n }\n if (!st.isFile() || st.size > MAX_FILE_BYTES) return;\n let content: string;\n try {\n content = readFileSync(p, 'utf8');\n } catch {\n return;\n }\n if (looksBinary(content)) return;\n findings.push(...scanText(content, relative(root, p) || p));\n };\n for (const p of paths) visit(p);\n return findings;\n}\n","// `dotvault set | delete | import | versions | rollback` — PRD-0006 E2 + E3.\n//\n// Authoring + version commands. All resolve project/env/file like `pull`,\n// authenticate via the OS keychain, and refresh the IdToken once on 401.\n// Authorization (role) and plan/capability gating are enforced server-side;\n// the CLI only surfaces the resulting errors.\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport {\n AuthExpiredError,\n AuthRequiredError,\n ValidationError,\n fileNameToSlug,\n slugToFileName,\n type EnvNameOrCustom,\n type EnvDeleteResponse,\n type EnvRollbackResponse,\n type EnvSetResponse,\n type EnvVersionsResponse,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig, resolveEnv } from '../config.js';\nimport { resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens, type TokenSet } from '../keychain.js';\n\ninterface CommonOptions {\n project?: string;\n env?: string;\n file?: string;\n cwd?: string;\n http?: HttpClient;\n}\n\ninterface ResolvedContext {\n project: string;\n env: EnvNameOrCustom;\n file: string;\n http: HttpClient;\n /** The bearer to send. For a user this is the IdToken; for CI it is the\n * DOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) service token. */\n bearer: string;\n /** Present only for interactive (keychain) auth — enables refresh-on-401.\n * Absent when authenticating with a service token. */\n refreshable?: { email: string; tokens: TokenSet };\n}\n\nasync function resolveContext(opts: CommonOptions): Promise<ResolvedContext> {\n const cfg = await loadProjectConfig(opts.cwd);\n const project = opts.project ?? cfg.name;\n const env = resolveEnv(opts.env, process.env.APP_ENV, cfg.envSync.defaultEnv);\n const fileInput = opts.file ?? cfg.envSync.files[0]!;\n const file = slugToFileName(fileNameToSlug(fileInput));\n const http = opts.http ?? createHttpClient(cfg.proxy.apiUrl);\n\n // PRD-0006 E4: non-interactive (CI/Lambda) auth via a service token.\n const serviceToken = resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return { project, env, file, http, bearer: serviceToken };\n }\n\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return { project, env, file, http, bearer: tokens.idToken, refreshable: { email, tokens } };\n}\n\n/** Parse `KEY=VALUE` CLI args into a map. Throws on a malformed pair. */\nexport function parsePairs(pairs: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const pair of pairs) {\n const eq = pair.indexOf('=');\n if (eq <= 0) {\n throw new ValidationError(`Invalid KEY=VALUE pair: ${JSON.stringify(pair)}`);\n }\n out[pair.slice(0, eq)] = pair.slice(eq + 1);\n }\n return out;\n}\n\n/** Minimal .env parser for `import` — KEY=VALUE, # comments, optional quotes\n * and `export ` prefix. */\nexport function parseEnvFile(text: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (line.length === 0 || line.startsWith('#')) continue;\n const body = line.startsWith('export ') ? line.slice(7) : line;\n const eq = body.indexOf('=');\n if (eq <= 0) continue;\n const key = body.slice(0, eq).trim();\n let val = body.slice(eq + 1).trim();\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\n val = val.slice(1, -1);\n }\n out[key] = val;\n }\n return out;\n}\n\nexport async function setCommand(\n opts: CommonOptions & { pairs: string[] },\n): Promise<EnvSetResponse> {\n const keys = parsePairs(opts.pairs);\n if (Object.keys(keys).length === 0) {\n throw new ValidationError('set requires at least one KEY=VALUE');\n }\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envKeysPut(idToken, { project: ctx.project, env: ctx.env, file: ctx.file }, { keys }),\n );\n}\n\nexport async function deleteCommand(\n opts: CommonOptions & { keys: string[] },\n): Promise<EnvDeleteResponse> {\n if (opts.keys.length === 0) throw new ValidationError('delete requires at least one KEY');\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envKeysDelete(\n idToken,\n { project: ctx.project, env: ctx.env, file: ctx.file },\n { keys: opts.keys },\n ),\n );\n}\n\nexport async function importCommand(\n opts: CommonOptions & { path: string },\n): Promise<EnvSetResponse> {\n const cwd = opts.cwd ?? process.cwd();\n let text: string;\n try {\n text = await readFile(resolve(cwd, opts.path), 'utf8');\n } catch (err) {\n throw new ValidationError(`Could not read ${opts.path}: ${(err as Error).message}`);\n }\n const keys = parseEnvFile(text);\n if (Object.keys(keys).length === 0) {\n throw new ValidationError(`No KEY=VALUE lines found in ${opts.path}`);\n }\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envKeysPut(idToken, { project: ctx.project, env: ctx.env, file: ctx.file }, { keys }),\n );\n}\n\n/** `env-sync describe KEY TEXT` — set or clear (TEXT === '') a key's\n * description (ADR-0020). Description-only: never touches the value. */\nexport async function describeCommand(\n opts: CommonOptions & { key: string; text: string },\n): Promise<EnvSetResponse> {\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envKeysPut(\n idToken,\n { project: ctx.project, env: ctx.env, file: ctx.file },\n { descriptions: { [opts.key]: opts.text } },\n ),\n );\n}\n\nexport async function versionsCommand(\n opts: CommonOptions & { key: string },\n): Promise<EnvVersionsResponse> {\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envVersions(idToken, {\n project: ctx.project,\n env: ctx.env,\n file: ctx.file,\n key: opts.key,\n }),\n );\n}\n\nexport async function rollbackCommand(\n opts: CommonOptions & { key: string; toVersion: number },\n): Promise<EnvRollbackResponse> {\n if (!Number.isInteger(opts.toVersion) || opts.toVersion < 1) {\n throw new ValidationError('rollback --to must be a positive integer version');\n }\n const ctx = await resolveContext(opts);\n return fetchWithRefresh(ctx, (idToken) =>\n ctx.http.envRollback(\n idToken,\n { project: ctx.project, env: ctx.env, file: ctx.file },\n { key: opts.key, toVersion: opts.toVersion },\n ),\n );\n}\n\nasync function fetchWithRefresh<T>(\n ctx: ResolvedContext,\n call: (bearer: string) => Promise<T>,\n): Promise<T> {\n try {\n return await call(ctx.bearer);\n } catch (err) {\n // Service tokens cannot be refreshed; any auth error propagates.\n if (\n ctx.refreshable === undefined ||\n (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError))\n ) {\n throw err;\n }\n const { email, tokens } = ctx.refreshable;\n const refreshed = await ctx.http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n}\n","// `dotvault whoami` — report the active identity for the next API call.\n//\n// Precedence matches pull/list/write (PRD-0006 E4):\n// 1. DOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) CI/Lambda service token —\n// reported as `service`\n// 2. keychain IdToken (interactive user) — reported as `user`\n//\n// Service-token mode does NOT call the API to look up org/role: that would\n// turn `whoami` into a network operation, which CI users frequently invoke\n// in tight loops for debugging. Only metadata derivable from the token\n// string itself (its prefix) is reported.\n\nimport { resolveServiceToken } from '../env-vars.js';\nimport { getCurrentUser, loadTokens } from '../keychain.js';\n\nexport type WhoamiResult =\n | {\n kind: 'user';\n email: string;\n expiresAt: number;\n expiresInSeconds: number;\n }\n | {\n kind: 'service';\n /** First 12 chars of the token, fingerprint-style. NEVER the full\n * secret — `whoami` is safe to paste into a bug report. */\n tokenPrefix: string;\n };\n\nexport async function whoamiCommand(\n env: NodeJS.ProcessEnv = process.env,\n): Promise<WhoamiResult | null> {\n const serviceToken = resolveServiceToken(env);\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return {\n kind: 'service',\n tokenPrefix: serviceToken.slice(0, 12),\n };\n }\n\n const email = await getCurrentUser();\n if (email === null) return null;\n const tokens = await loadTokens(email);\n if (tokens === null) return null;\n const now = Math.floor(Date.now() / 1000);\n return {\n kind: 'user',\n email,\n expiresAt: tokens.expiresAt,\n expiresInSeconds: Math.max(0, tokens.expiresAt - now),\n };\n}\n","// `env-sync init` — scaffold a project-config.json in the current working\n// directory with sensible defaults. Refuses to overwrite unless --force is set.\n//\n// The generated file uses the canonical schema 2.7.0 shape that loadProjectConfig\n// expects: name / setup.bootstrap.proxy.apiUrl / setup.envSync.{enabled,files,defaultEnv}\n\nimport { writeFile, access } from 'node:fs/promises';\nimport { resolve, basename } from 'node:path';\nimport { constants } from 'node:fs';\nimport { ValidationError } from '@earthlink/env-sync-shared';\n\nimport { DEFAULT_API_URL } from '../config.js';\n\nconst CONFIG_FILENAME = 'project-config.json';\n\nexport interface InitOptions {\n /** Override project name (default: basename of cwd). */\n name?: string;\n /** Override API base URL (default: https://api.dotvault.io/v1). */\n api?: string;\n /** Overwrite existing project-config.json without error. */\n force?: boolean;\n /** Working directory to write into (default: process.cwd()). Test seam. */\n cwd?: string;\n}\n\nexport interface InitResult {\n /** Absolute path of the written file. */\n path: string;\n /** Project name written into the file. */\n project: string;\n}\n\nexport async function initCommand(opts: InitOptions = {}): Promise<InitResult> {\n const cwd = opts.cwd ?? process.cwd();\n const path = resolve(cwd, CONFIG_FILENAME);\n const project = opts.name ?? basename(cwd);\n const apiUrl = opts.api ?? DEFAULT_API_URL;\n\n // Check for existing file unless --force was given.\n const exists = await fileExists(path);\n if (exists && !opts.force) {\n throw new ValidationError(`${CONFIG_FILENAME} already exists. Use --force to overwrite.`);\n }\n\n const config = buildConfig(project, apiUrl);\n await writeFile(path, JSON.stringify(config, null, 2) + '\\n', 'utf8');\n\n return { path, project };\n}\n\nfunction buildConfig(name: string, apiUrl: string): object {\n return {\n name,\n setup: {\n bootstrap: {\n proxy: {\n apiUrl,\n },\n },\n envSync: {\n enabled: true,\n files: ['.env'],\n defaultEnv: 'development',\n },\n },\n };\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","// `dotvault project` — create projects without the admin web console\n// (ADR-0018). This is the piece that lets Claude Code onboard a repo unattended.\n//\n// project create --name <name> [--org <id>]\n//\n// Credential precedence (first that is set wins):\n// 1. DOTVAULT_ADMIN_TOKEN (or legacy ENV_SYNC_ADMIN_TOKEN) — a provisioner\n// service token (headless; preferred)\n// 2. DOTVAULT_TOKEN (or legacy ENV_SYNC_TOKEN) — any service token (falls\n// back for convenience)\n// 3. OS keychain idToken — an interactive `dotvault login` session\n//\n// With a provisioner token the org is taken from the token, so `--org` is\n// optional: `dotvault project create --name myapp` is enough.\n\nimport {\n AuthExpiredError,\n AuthRequiredError,\n type ProjectCreateRequest,\n type ProjectCreateResponse,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig } from '../config.js';\nimport { resolveAdminServiceToken, resolveServiceToken } from '../env-vars.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens } from '../keychain.js';\n\nexport interface ProjectCreateOptions {\n name: string;\n orgId?: string;\n cwd?: string;\n}\n\nexport async function projectCreateCommand(\n opts: ProjectCreateOptions,\n): Promise<ProjectCreateResponse> {\n const cfg = await loadProjectConfig(opts.cwd);\n const http = createHttpClient(cfg.proxy.apiUrl);\n const body: ProjectCreateRequest = {\n name: opts.name,\n ...(opts.orgId !== undefined ? { owning_org_id: opts.orgId } : {}),\n };\n\n const serviceToken = resolveAdminServiceToken() ?? resolveServiceToken();\n if (serviceToken !== undefined && serviceToken.length > 0) {\n return http.adminProjectsCreate(serviceToken, body);\n }\n\n const authedFetch = await buildAuthedFetch(http);\n return authedFetch((bearer) => http.adminProjectsCreate(bearer, body));\n}\n\n// Interactive fallback: use the keychain idToken, refreshing once on 401.\n// (Same shape as commands/token.ts buildAuthedFetch.)\nasync function buildAuthedFetch(\n http: HttpClient,\n): Promise<<T>(call: (bearer: string) => Promise<T>) => Promise<T>> {\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return async <T>(call: (bearer: string) => Promise<T>): Promise<T> => {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n };\n}\n","// `env-sync token` — manage service tokens (PRD-0006 E4).\n//\n// token list --org <id>\n// token create --org <id> --name <name> --role <viewer|member>\n// [--project <id>] [--ttl <seconds>]\n// token revoke --org <id> --id <token_id>\n//\n// Service tokens are minted at admin web → org → Service Tokens. This CLI is\n// a thin wrapper around the same admin API; the resulting `est_…` token is\n// shown ONCE (server only stores its hash).\n\nimport {\n AuthExpiredError,\n AuthRequiredError,\n type ServiceTokenCreateRequest,\n type ServiceTokenCreateResponse,\n type ServiceTokenMetaDTO,\n} from '@earthlink/env-sync-shared';\nimport { loadProjectConfig } from '../config.js';\nimport { createHttpClient, type HttpClient } from '../http.js';\nimport { getCurrentUser, loadTokens, saveTokens } from '../keychain.js';\n\nexport interface TokenListOptions {\n orgId: string;\n cwd?: string;\n}\n\nexport interface TokenCreateOptions {\n orgId: string;\n name: string;\n role: 'viewer' | 'member' | 'provisioner';\n projectId?: string;\n ttlSeconds?: number;\n cwd?: string;\n}\n\nexport interface TokenRevokeOptions {\n orgId: string;\n tokenId: string;\n cwd?: string;\n}\n\nexport async function tokenListCommand(\n opts: TokenListOptions,\n): Promise<{ tokens: ServiceTokenMetaDTO[] }> {\n const cfg = await loadProjectConfig(opts.cwd);\n const http = createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n return authedFetch((bearer) => http.adminTokensList(bearer, { orgId: opts.orgId }));\n}\n\nexport async function tokenCreateCommand(\n opts: TokenCreateOptions,\n): Promise<ServiceTokenCreateResponse> {\n const cfg = await loadProjectConfig(opts.cwd);\n const http = createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n const body: ServiceTokenCreateRequest = {\n name: opts.name,\n role: opts.role,\n ...(opts.projectId !== undefined ? { projectId: opts.projectId } : {}),\n ...(opts.ttlSeconds !== undefined ? { ttlSeconds: opts.ttlSeconds } : {}),\n };\n return authedFetch((bearer) => http.adminTokensCreate(bearer, { orgId: opts.orgId }, body));\n}\n\nexport async function tokenRevokeCommand(opts: TokenRevokeOptions): Promise<void> {\n const cfg = await loadProjectConfig(opts.cwd);\n const http = createHttpClient(cfg.proxy.apiUrl);\n const authedFetch = await buildAuthedFetch(http);\n await authedFetch((bearer) =>\n http.adminTokensRevoke(bearer, { orgId: opts.orgId, tokenId: opts.tokenId }),\n );\n}\n\n// Same pattern as commands/pull.ts buildAuthedFetch. Service tokens cannot\n// mint other service tokens, so this path only accepts a user IdToken\n// (refreshed once on 401).\nasync function buildAuthedFetch(\n http: HttpClient,\n): Promise<<T>(call: (bearer: string) => Promise<T>) => Promise<T>> {\n const email = await getCurrentUser();\n if (email === null) throw new AuthRequiredError();\n const tokens = await loadTokens(email);\n if (tokens === null) throw new AuthRequiredError();\n\n return async <T>(call: (bearer: string) => Promise<T>): Promise<T> => {\n try {\n return await call(tokens.idToken);\n } catch (err) {\n if (!(err instanceof AuthRequiredError) && !(err instanceof AuthExpiredError)) {\n throw err;\n }\n const refreshed = await http.refresh({ refreshToken: tokens.refreshToken });\n const expiresAt = Math.floor(Date.now() / 1000) + refreshed.expiresIn;\n await saveTokens(email, { ...tokens, idToken: refreshed.idToken, expiresAt });\n return await call(refreshed.idToken);\n }\n };\n}\n"],"mappings":"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","names":["basename","resolve","res","resolve","resolve","basename","readFile","basename","buildAuthedFetch","response","resolve","writeFileSync","basename","join","resolve","buildAuthedFetch","join","basename","writeFileSync","resolve","readFile","basename","resolve","readFile","resolve","basename","join","readFile","resolve","fetchWithRefresh","readFile","resolve","writeFile","resolve","basename","resolve","basename","writeFile","buildAuthedFetch","buildAuthedFetch","require","basename"]}
|