@graphorin/cli 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +130 -0
  4. package/dist/bin/graphorin.d.ts +1 -0
  5. package/dist/bin/graphorin.js +606 -0
  6. package/dist/bin/graphorin.js.map +1 -0
  7. package/dist/commands/audit.d.ts +59 -0
  8. package/dist/commands/audit.d.ts.map +1 -0
  9. package/dist/commands/audit.js +156 -0
  10. package/dist/commands/audit.js.map +1 -0
  11. package/dist/commands/auth.d.ts +48 -0
  12. package/dist/commands/auth.d.ts.map +1 -0
  13. package/dist/commands/auth.js +148 -0
  14. package/dist/commands/auth.js.map +1 -0
  15. package/dist/commands/consolidator.d.ts +49 -0
  16. package/dist/commands/consolidator.d.ts.map +1 -0
  17. package/dist/commands/consolidator.js +97 -0
  18. package/dist/commands/consolidator.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +64 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +150 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/guard.d.ts +35 -0
  24. package/dist/commands/guard.d.ts.map +1 -0
  25. package/dist/commands/guard.js +86 -0
  26. package/dist/commands/guard.js.map +1 -0
  27. package/dist/commands/index.d.ts +21 -0
  28. package/dist/commands/index.js +22 -0
  29. package/dist/commands/init.d.ts +46 -0
  30. package/dist/commands/init.d.ts.map +1 -0
  31. package/dist/commands/init.js +131 -0
  32. package/dist/commands/init.js.map +1 -0
  33. package/dist/commands/memory.d.ts +243 -0
  34. package/dist/commands/memory.d.ts.map +1 -0
  35. package/dist/commands/memory.js +471 -0
  36. package/dist/commands/memory.js.map +1 -0
  37. package/dist/commands/migrate-config.d.ts +20 -0
  38. package/dist/commands/migrate-config.d.ts.map +1 -0
  39. package/dist/commands/migrate-config.js +48 -0
  40. package/dist/commands/migrate-config.js.map +1 -0
  41. package/dist/commands/migrate-export.d.ts +26 -0
  42. package/dist/commands/migrate-export.d.ts.map +1 -0
  43. package/dist/commands/migrate-export.js +67 -0
  44. package/dist/commands/migrate-export.js.map +1 -0
  45. package/dist/commands/migrate.d.ts +31 -0
  46. package/dist/commands/migrate.d.ts.map +1 -0
  47. package/dist/commands/migrate.js +59 -0
  48. package/dist/commands/migrate.js.map +1 -0
  49. package/dist/commands/pricing.d.ts +66 -0
  50. package/dist/commands/pricing.d.ts.map +1 -0
  51. package/dist/commands/pricing.js +128 -0
  52. package/dist/commands/pricing.js.map +1 -0
  53. package/dist/commands/secrets.d.ts +96 -0
  54. package/dist/commands/secrets.d.ts.map +1 -0
  55. package/dist/commands/secrets.js +182 -0
  56. package/dist/commands/secrets.js.map +1 -0
  57. package/dist/commands/skills.d.ts +58 -0
  58. package/dist/commands/skills.d.ts.map +1 -0
  59. package/dist/commands/skills.js +181 -0
  60. package/dist/commands/skills.js.map +1 -0
  61. package/dist/commands/start.d.ts +51 -0
  62. package/dist/commands/start.d.ts.map +1 -0
  63. package/dist/commands/start.js +122 -0
  64. package/dist/commands/start.js.map +1 -0
  65. package/dist/commands/storage.d.ts +110 -0
  66. package/dist/commands/storage.d.ts.map +1 -0
  67. package/dist/commands/storage.js +274 -0
  68. package/dist/commands/storage.js.map +1 -0
  69. package/dist/commands/telemetry.d.ts +21 -0
  70. package/dist/commands/telemetry.d.ts.map +1 -0
  71. package/dist/commands/telemetry.js +75 -0
  72. package/dist/commands/telemetry.js.map +1 -0
  73. package/dist/commands/token.d.ts +109 -0
  74. package/dist/commands/token.d.ts.map +1 -0
  75. package/dist/commands/token.js +246 -0
  76. package/dist/commands/token.js.map +1 -0
  77. package/dist/commands/tools-lint.d.ts +103 -0
  78. package/dist/commands/tools-lint.d.ts.map +1 -0
  79. package/dist/commands/tools-lint.js +240 -0
  80. package/dist/commands/tools-lint.js.map +1 -0
  81. package/dist/commands/traces.d.ts +33 -0
  82. package/dist/commands/traces.d.ts.map +1 -0
  83. package/dist/commands/traces.js +103 -0
  84. package/dist/commands/traces.js.map +1 -0
  85. package/dist/commands/triggers.d.ts +49 -0
  86. package/dist/commands/triggers.d.ts.map +1 -0
  87. package/dist/commands/triggers.js +129 -0
  88. package/dist/commands/triggers.js.map +1 -0
  89. package/dist/index.d.ts +46 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +47 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/internal/exit.js +17 -0
  94. package/dist/internal/exit.js.map +1 -0
  95. package/dist/internal/load-config.js +84 -0
  96. package/dist/internal/load-config.js.map +1 -0
  97. package/dist/internal/offline.d.ts +58 -0
  98. package/dist/internal/offline.d.ts.map +1 -0
  99. package/dist/internal/offline.js +72 -0
  100. package/dist/internal/offline.js.map +1 -0
  101. package/dist/internal/output.d.ts +56 -0
  102. package/dist/internal/output.d.ts.map +1 -0
  103. package/dist/internal/output.js +86 -0
  104. package/dist/internal/output.js.map +1 -0
  105. package/dist/internal/prompts.js +49 -0
  106. package/dist/internal/prompts.js.map +1 -0
  107. package/dist/internal/store-context.js +69 -0
  108. package/dist/internal/store-context.js.map +1 -0
  109. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphorin.js","names":[],"sources":["../../src/bin/graphorin.ts"],"sourcesContent":["/**\n * `graphorin` CLI entry point. Built into `dist/bin/graphorin.js`\n * with a shebang prepended by `tsdown`; the `package.json` `bin`\n * field points npm at the compiled file.\n *\n * Phase 14a installs three subcommands grouped by lifecycle phase:\n *\n * Bootstrap:\n * - graphorin init\n *\n * Maintenance:\n * - graphorin migrate\n *\n * Runtime:\n * - graphorin start\n *\n * Phase 15 extends this binary with the full operator surface\n * (`doctor`, `token`, `secrets`, `audit`, `storage`, `memory`,\n * `consolidator`, `triggers`, `auth`, `pricing`, `skills`, `traces`,\n * `migrate-export`, `migrate-config`, `guard`, `telemetry`,\n * `tools lint`).\n *\n * `GRAPHORIN_OFFLINE=1` is honoured by every subcommand — the v0.1\n * surface never makes implicit network calls. Phase 15 commands that\n * do touch the network (e.g. `graphorin pricing refresh`) consult\n * the same flag through the helper in `../internal/offline.ts`.\n *\n * @packageDocumentation\n */\n\nimport process from 'node:process';\n\nimport { Command } from 'commander';\n\nimport {\n runAuditExport,\n runAuditPrune,\n runAuditVerify,\n runAuthList,\n runAuthLogin,\n runAuthRefresh,\n runAuthRevoke,\n runAuthStatus,\n runConsolidatorSetTier,\n runConsolidatorStatus,\n runConsolidatorStop,\n runDoctor,\n runGuardExplain,\n runGuardStatus,\n runInit,\n runMemoryActivity,\n runMemoryInspect,\n runMemoryMigrate,\n runMemoryReview,\n runMemoryStatus,\n runMemoryWhy,\n runMigrate,\n runMigrateConfig,\n runMigrateExport,\n runPricingDiff,\n runPricingLookup,\n runPricingMissing,\n runPricingRefresh,\n runPricingStatus,\n runSecretsDelete,\n runSecretsGet,\n runSecretsList,\n runSecretsRef,\n runSecretsRotate,\n runSecretsSet,\n runSkillsAudit,\n runSkillsInspect,\n runSkillsInstall,\n runSkillsMigrateFrontmatter,\n runStart,\n runStorageCleanupBackups,\n runStorageEncrypt,\n runStorageRekey,\n runStorageStatus,\n runTelemetryDisable,\n runTelemetryEnable,\n runTelemetryInspect,\n runTelemetryStatus,\n runTokenCreate,\n runTokenList,\n runTokenRekey,\n runTokenRevoke,\n runTokenRotate,\n runTokenVerify,\n runToolsLint,\n runTracesPrune,\n runTracesStatus,\n runTriggersDisable,\n runTriggersFire,\n runTriggersList,\n runTriggersPrune,\n runTriggersStatus,\n VERSION,\n} from '../index.js';\nimport { isOfflineMode } from '../internal/offline.js';\n\nasync function main(): Promise<void> {\n const program = new Command();\n program\n .name('graphorin')\n .description(\n [\n 'Operator CLI for the Graphorin framework.',\n '',\n 'Commands grouped by purpose:',\n ' Bootstrap: init, migrate, migrate-config',\n ' Runtime: start',\n ' Diagnostics: doctor, telemetry, traces, guard',\n ' Auth: token, secrets, auth',\n ' Storage: storage, audit, memory, consolidator, triggers, migrate-export',\n ' Catalogue: pricing, skills, tools',\n '',\n 'Honours GRAPHORIN_OFFLINE=1 — the v0.1 surface never makes implicit network calls.',\n ].join('\\n'),\n )\n .version(VERSION);\n\n registerLifecycleCommands(program);\n registerDoctorCommand(program);\n registerTokenCommands(program);\n registerSecretsCommands(program);\n registerStorageCommands(program);\n registerAuditCommands(program);\n registerMemoryCommands(program);\n registerConsolidatorCommands(program);\n registerTriggersCommands(program);\n registerAuthCommands(program);\n registerPricingCommands(program);\n registerSkillsCommands(program);\n registerTracesCommands(program);\n registerMigrateExportCommand(program);\n registerMigrateConfigCommand(program);\n registerGuardCommands(program);\n registerTelemetryCommands(program);\n registerToolsCommands(program);\n\n await program.parseAsync(process.argv);\n}\n\nfunction registerLifecycleCommands(program: Command): void {\n program\n .command('start')\n .description('[Runtime] Start the @graphorin/server daemon.')\n .option('-c, --config <path>', 'Path to the graphorin.config file (TS / JS / JSON).')\n .option('-h, --host <host>', 'Override the configured listen host.')\n .option('-p, --port <port>', 'Override the configured listen port.', (value) =>\n Number.parseInt(value, 10),\n )\n .option(\n '--secrets-source <kind>',\n 'Override secrets.source: auto | keyring | encrypted-file | env (DEC-136).',\n )\n .option('--strict-secrets', 'Refuse to fall back to a different secrets store (DEC-136).')\n .action(\n async (opts: {\n config?: string;\n host?: string;\n port?: number;\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n }) => {\n if (isOfflineMode()) {\n process.stderr.write(\n '[graphorin/cli] GRAPHORIN_OFFLINE=1 — running with no implicit network calls.\\n',\n );\n }\n await runStart({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.host !== undefined ? { host: opts.host } : {}),\n ...(opts.port !== undefined ? { port: opts.port } : {}),\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n });\n },\n );\n\n program\n .command('init')\n .description(\n '[Bootstrap] Generate a fresh graphorin.config.ts and a one-shot bootstrap admin token.',\n )\n .option('-o, --out <path>', 'Output path; defaults to ./graphorin.config.ts.')\n .option('--non-interactive', 'Accept defaults / env vars without prompting.', false)\n .option(\n '--cloud-consent <tier>',\n 'Cloud-upload consent tier: public-only | public-and-internal | all-with-warnings.',\n )\n .option('--encrypted', 'Enable storage encryption opt-in.')\n .option('--no-encrypted', 'Disable storage encryption opt-in.')\n .action(\n async (opts: {\n out?: string;\n nonInteractive?: boolean;\n cloudConsent?: 'public-only' | 'public-and-internal' | 'all-with-warnings';\n encrypted?: boolean;\n }) => {\n if (isOfflineMode()) {\n process.stderr.write(\n '[graphorin/cli] GRAPHORIN_OFFLINE=1 — init never reaches the network.\\n',\n );\n }\n await runInit({\n ...(opts.out !== undefined ? { out: opts.out } : {}),\n ...(opts.nonInteractive !== undefined ? { nonInteractive: opts.nonInteractive } : {}),\n ...(opts.cloudConsent !== undefined ? { cloudConsent: opts.cloudConsent } : {}),\n ...(opts.encrypted !== undefined ? { encrypted: opts.encrypted } : {}),\n });\n },\n );\n\n program\n .command('migrate')\n .description(\n '[Maintenance] Apply pending storage migrations against the configured SQLite store.',\n )\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--target <version>', 'Reserved for the Phase 15 partial-migration runner.')\n .action(async (opts: { config?: string; target?: string }) => {\n if (isOfflineMode()) {\n process.stderr.write(\n '[graphorin/cli] GRAPHORIN_OFFLINE=1 — migrate is a local-only operation.\\n',\n );\n }\n await runMigrate({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.target !== undefined ? { target: opts.target } : {}),\n });\n });\n}\n\nfunction registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('[Diagnostics] Health check (perms + secrets + encryption + systemd).')\n .option('--fix-perms', 'Repair drifted POSIX file modes.')\n .option('--check-perms', 'Run the file-perms check.')\n .option('--check-secrets', 'Run the secrets-store check.')\n .option('--check-encryption', 'Run the audit-encryption check.')\n .option('--check-systemd', 'Run the systemd-hardening check (Linux only).')\n .option('--all', 'Run every check.')\n .option('--json', 'Emit a structured JSON report on stdout.')\n .action(\n async (opts: {\n fixPerms?: boolean;\n checkPerms?: boolean;\n checkSecrets?: boolean;\n checkEncryption?: boolean;\n checkSystemd?: boolean;\n all?: boolean;\n json?: boolean;\n }) => {\n await runDoctor({\n ...(opts.fixPerms !== undefined ? { fixPerms: opts.fixPerms } : {}),\n ...(opts.checkPerms !== undefined ? { checkPerms: opts.checkPerms } : {}),\n ...(opts.checkSecrets !== undefined ? { checkSecrets: opts.checkSecrets } : {}),\n ...(opts.checkEncryption !== undefined ? { checkEncryption: opts.checkEncryption } : {}),\n ...(opts.checkSystemd !== undefined ? { checkSystemd: opts.checkSystemd } : {}),\n ...(opts.all !== undefined ? { all: opts.all } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerTokenCommands(program: Command): void {\n const token = program.command('token').description('[Auth] Manage server auth tokens.');\n token\n .command('create')\n .description('Mint a new token. Prints the raw value once.')\n .requiredOption('--scopes <list>', 'Comma-separated scope list.')\n .option('--label <name>', 'Optional label.')\n .option('--expires-in <duration>', 'Duration string: 30d, 12h, 90m, 45s.')\n .option('--env <env>', 'Token environment: live | test.', 'live')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: {\n scopes: string;\n label?: string;\n expiresIn?: string;\n env?: 'live' | 'test';\n config?: string;\n json?: boolean;\n }) => {\n await runTokenCreate({\n scopes: opts.scopes\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n ...(opts.label !== undefined ? { label: opts.label } : {}),\n ...(opts.expiresIn !== undefined ? { expiresIn: opts.expiresIn } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n token\n .command('list')\n .description('List token metadata.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--include-revoked', 'Include revoked tokens.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; includeRevoked?: boolean; json?: boolean }) => {\n await runTokenList({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.includeRevoked !== undefined ? { includeRevoked: opts.includeRevoked } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n token\n .command('revoke <id>')\n .description('Revoke a single token.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (id: string, opts: { config?: string; json?: boolean }) => {\n await runTokenRevoke({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n token\n .command('rotate <id>')\n .description('Revoke + reissue a token with the same scopes.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--env <env>', 'Token environment: live | test.', 'live')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (id: string, opts: { config?: string; env?: 'live' | 'test'; json?: boolean }) => {\n await runTokenRotate({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n token\n .command('rekey')\n .description('Re-issue every active token (use after a known compromise).')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--env <env>', 'Token environment: live | test.', 'live')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; env?: 'live' | 'test'; json?: boolean }) => {\n await runTokenRekey({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n token\n .command('verify <token>')\n .description('Offline checksum verification — never consults the store.')\n .option('--prefix <prefix>', 'Override the expected token prefix.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((tok: string, opts: { prefix?: string; json?: boolean }) => {\n runTokenVerify({\n token: tok,\n ...(opts.prefix !== undefined ? { prefix: opts.prefix } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerSecretsCommands(program: Command): void {\n const secrets = program\n .command('secrets')\n .description('[Auth] Manage secrets in the configured store.');\n const commonOpts = (cmd: Command): Command =>\n cmd\n .option('--secrets-source <kind>', 'auto | keyring | encrypted-file | env (DEC-136).')\n .option('--strict-secrets', 'Refuse to fall back to a different secrets store.')\n .option('--json', 'Emit a structured JSON document on stdout.');\n commonOpts(secrets.command('list').description('List secret metadata.')).action(\n async (opts: {\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n json?: boolean;\n }) => {\n await runSecretsList({\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n commonOpts(\n secrets\n .command('get <key>')\n .description('Read a secret. Use --reveal to print the bytes.')\n .option('--reveal', 'Print the raw value.'),\n ).action(\n async (\n key: string,\n opts: {\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n json?: boolean;\n reveal?: boolean;\n },\n ) => {\n await runSecretsGet({\n key,\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n ...(opts.reveal !== undefined ? { reveal: opts.reveal } : {}),\n });\n },\n );\n commonOpts(\n secrets\n .command('set <key>')\n .description('Persist a secret. Pass --value <v> or --from-stdin.')\n .option('--value <v>', 'Inline value.')\n .option('--from-stdin', 'Read the value from stdin.'),\n ).action(\n async (\n key: string,\n opts: {\n value?: string;\n fromStdin?: boolean;\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n json?: boolean;\n },\n ) => {\n await runSecretsSet({\n key,\n ...(opts.value !== undefined ? { value: opts.value } : {}),\n ...(opts.fromStdin !== undefined ? { fromStdin: opts.fromStdin } : {}),\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n commonOpts(secrets.command('delete <key>').description('Delete a secret.')).action(\n async (\n key: string,\n opts: {\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n json?: boolean;\n },\n ) => {\n await runSecretsDelete({\n key,\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n commonOpts(\n secrets\n .command('ref <uri>')\n .description('Test resolution of a SecretRef URI.')\n .option('--reveal', 'Include the resolved value in the report.'),\n ).action(async (uri: string, opts: { reveal?: boolean; json?: boolean }) => {\n await runSecretsRef({\n uri,\n ...(opts.reveal !== undefined ? { reveal: opts.reveal } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n commonOpts(\n secrets\n .command('rotate <key>')\n .description('Replace an existing secret with a fresh value.')\n .option('--new-value <v>', 'Inline new value.')\n .option('--from-stdin', 'Read the new value from stdin.'),\n ).action(\n async (\n key: string,\n opts: {\n newValue?: string;\n fromStdin?: boolean;\n secretsSource?: 'auto' | 'keyring' | 'encrypted-file' | 'env';\n strictSecrets?: boolean;\n json?: boolean;\n },\n ) => {\n await runSecretsRotate({\n key,\n ...(opts.newValue !== undefined ? { newValue: opts.newValue } : {}),\n ...(opts.fromStdin !== undefined ? { fromStdin: opts.fromStdin } : {}),\n ...(opts.secretsSource !== undefined ? { secretsSource: opts.secretsSource } : {}),\n ...(opts.strictSecrets !== undefined ? { strictSecrets: opts.strictSecrets } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerStorageCommands(program: Command): void {\n const storage = program\n .command('storage')\n .description('[Storage] SQLite + encryption-at-rest commands.');\n storage\n .command('status')\n .description('Report current store state + cipher peer availability.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runStorageStatus({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n storage\n .command('encrypt')\n .description(\n 'Encrypt the store. Requires the @graphorin/store-sqlite-encrypted sub-pack (Phase 16).',\n )\n .requiredOption('--passphrase-from <ref>', 'SecretRef URI for the new passphrase.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option(\n '--target-path <path>',\n 'Override the encrypted output path. Default <storage>.encrypted.',\n )\n .option(\n '--swap',\n 'Atomically swap the encrypted output into the storage path; original kept under .bak.<ts>.',\n )\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: {\n passphraseFrom: string;\n config?: string;\n targetPath?: string;\n swap?: boolean;\n json?: boolean;\n }) => {\n await runStorageEncrypt({\n passphraseFrom: opts.passphraseFrom,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.targetPath !== undefined ? { targetPath: opts.targetPath } : {}),\n ...(opts.swap === true ? { swap: true } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n storage\n .command('rekey')\n .description('Rekey an already-encrypted store.')\n .requiredOption('--old-passphrase-from <ref>', 'SecretRef URI for the existing passphrase.')\n .requiredOption('--new-passphrase-from <ref>', 'SecretRef URI for the new passphrase.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: {\n oldPassphraseFrom: string;\n newPassphraseFrom: string;\n config?: string;\n json?: boolean;\n }) => {\n await runStorageRekey({\n oldPassphraseFrom: opts.oldPassphraseFrom,\n newPassphraseFrom: opts.newPassphraseFrom,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n storage\n .command('cleanup-backups')\n .description('Drop stale .bak / .tmp.<ts> files left by previous encrypt / rekey runs.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--dry-run', 'Print what would be removed without touching the filesystem.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; dryRun?: boolean; json?: boolean }) => {\n await runStorageCleanupBackups({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.dryRun !== undefined ? { dryRun: opts.dryRun } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerAuditCommands(program: Command): void {\n const audit = program\n .command('audit')\n .description('[Storage] Operate on the encrypted audit log.');\n audit\n .command('verify')\n .description('Replay the chain and report the first broken link (if any).')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runAuditVerify({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n audit\n .command('prune')\n .description('Drop entries older than --before (cutoff is required).')\n .requiredOption('--before <date>', 'ISO date / epoch ms cutoff.')\n .option('--retain <n>', 'Minimum number of entries that must survive.', (v) =>\n Number.parseInt(v, 10),\n )\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { before: string; retain?: number; config?: string; json?: boolean }) => {\n await runAuditPrune({\n before: opts.before,\n ...(opts.retain !== undefined ? { retain: opts.retain } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n audit\n .command('export')\n .description('Stream every audit entry as JSONL into --to.')\n .requiredOption('--to <file>', 'Output path.')\n .option('--from-seq <n>', 'Lower bound (inclusive).', (v) => Number.parseInt(v, 10))\n .option('--to-seq <n>', 'Upper bound (inclusive).', (v) => Number.parseInt(v, 10))\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: {\n to: string;\n fromSeq?: number;\n toSeq?: number;\n config?: string;\n json?: boolean;\n }) => {\n await runAuditExport({\n to: opts.to,\n ...(opts.fromSeq !== undefined ? { fromSeq: opts.fromSeq } : {}),\n ...(opts.toSeq !== undefined ? { toSeq: opts.toSeq } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerMemoryCommands(program: Command): void {\n const memory = program\n .command('memory')\n .description('[Storage] Long-term memory operator commands.');\n memory\n .command('status')\n .description('Report counts + active embedder + migration state.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runMemoryStatus({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n memory\n .command('migrate')\n .description('Embedder swap. Requires --embedders module that exports the factories.')\n .requiredOption('--from <id>', 'Source embedder id.')\n .requiredOption('--to <id>', 'Target embedder id.')\n .requiredOption('--strategy <s>', 'lock-on-first | auto-migrate | multi-active.')\n .option('--embedders <path>', 'Path to a module exporting embedder factories.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .action(\n async (opts: {\n from: string;\n to: string;\n strategy: string;\n embedders?: string;\n config?: string;\n }) => {\n await runMemoryMigrate({\n from: opts.from,\n to: opts.to,\n strategy: opts.strategy as 'lock-on-first' | 'auto-migrate' | 'multi-active',\n ...(opts.embedders !== undefined ? { embeddersModule: opts.embedders } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n });\n },\n );\n memory\n .command('inspect')\n .description('Inspect one fact: supersede chain, quarantine, conflicts, citing insights.')\n .argument('<factId>', 'Id of the fact to inspect.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (factId: string, opts: { config?: string; json?: boolean }) => {\n await runMemoryInspect({\n factId,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n memory\n .command('activity')\n .description('Store-wide consolidator / reflection activity: quarantine, history, conflicts.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--limit <n>', 'Cap on recent history / conflict rows (default 20).')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; limit?: string; json?: boolean }) => {\n const limit = opts.limit !== undefined ? Number.parseInt(opts.limit, 10) : undefined;\n await runMemoryActivity({\n ...(limit !== undefined && Number.isFinite(limit) ? { limit } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n memory\n .command('why')\n .description(\n 'Explain why facts were recalled (ranking signals) from the persisted recall spans.',\n )\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--session <id>', \"Restrict to one session's recall spans.\")\n .option('--limit <n>', 'Cap on the most-recent recall spans (default 5).')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; session?: string; limit?: string; json?: boolean }) => {\n const limit = opts.limit !== undefined ? Number.parseInt(opts.limit, 10) : undefined;\n await runMemoryWhy({\n ...(opts.session !== undefined ? { sessionId: opts.session } : {}),\n ...(limit !== undefined && Number.isFinite(limit) ? { limit } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n memory\n .command('review')\n .description('List quarantined memory by tier, or promote a reviewed item with --promote.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--limit <n>', 'Cap on rows listed per type (default 20).')\n .option('--promote <id>', 'Promote this quarantined memory id out of quarantine.')\n .option('--reason <text>', 'Audit reason recorded with the promotion.')\n .option('--force', 'Override the injection-refusal gate (operator action, after review).')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: {\n config?: string;\n limit?: string;\n promote?: string;\n reason?: string;\n force?: boolean;\n json?: boolean;\n }) => {\n const limit = opts.limit !== undefined ? Number.parseInt(opts.limit, 10) : undefined;\n await runMemoryReview({\n ...(limit !== undefined && Number.isFinite(limit) ? { limit } : {}),\n ...(opts.promote !== undefined ? { promote: opts.promote } : {}),\n ...(opts.reason !== undefined ? { reason: opts.reason } : {}),\n ...(opts.force !== undefined ? { force: opts.force } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerConsolidatorCommands(program: Command): void {\n const c = program\n .command('consolidator')\n .description('[Storage] Inspect and steer the memory consolidator.');\n c.command('status')\n .description('Current tier hint + DLQ size + recent run history.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runConsolidatorStatus({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n c.command('set-tier <tier>')\n .description('Persist a tier hint (free | cheap | standard | full | custom).')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (tier: string, opts: { config?: string; json?: boolean }) => {\n await runConsolidatorSetTier({\n tier: tier as 'free' | 'cheap' | 'standard' | 'full' | 'custom',\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n c.command('stop')\n .description('Persist a pause flag the running daemon honours.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runConsolidatorStop({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerTriggersCommands(program: Command): void {\n const t = program\n .command('triggers')\n .description('[Storage] Operate on the durable trigger registry.');\n t.command('list')\n .description('Every persisted trigger.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runTriggersList({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n t.command('status <id>')\n .description('Single-trigger detail.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (id: string, opts: { config?: string; json?: boolean }) => {\n await runTriggersStatus({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n t.command('fire <id>')\n .description('Operator-fired side-effect (admin only).')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (id: string, opts: { config?: string; json?: boolean }) => {\n await runTriggersFire({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n t.command('disable <id>')\n .description('Flip the disabled column on the registry row.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (id: string, opts: { config?: string; json?: boolean }) => {\n await runTriggersDisable({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n t.command('prune')\n .description('Drop disabled triggers older than --before.')\n .option(\n '--before <date>',\n 'ISO date / epoch ms cutoff. Defaults to 0 (drop every disabled row).',\n )\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { before?: string; config?: string; json?: boolean }) => {\n await runTriggersPrune({\n ...(opts.before !== undefined ? { before: opts.before } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerAuthCommands(program: Command): void {\n const a = program.command('auth').description('[Auth] Outbound OAuth (e.g. for MCP servers).');\n a.command('login')\n .description('Drive an interactive login flow.')\n .requiredOption('--server <url>', 'Authorization server URL.')\n .option('--server-id <id>', 'Override the persisted server identifier.')\n .option('--scope <scope>', 'OAuth scope.')\n .option('--device-flow', 'Use the Device Authorization Grant.')\n .option('--client-id <id>', 'Pre-existing client identifier (skip DCR).')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .action(\n async (opts: {\n server: string;\n serverId?: string;\n scope?: string;\n deviceFlow?: boolean;\n clientId?: string;\n config?: string;\n }) => {\n await runAuthLogin({\n serverUrl: opts.server,\n ...(opts.serverId !== undefined ? { serverId: opts.serverId } : {}),\n ...(opts.scope !== undefined ? { scope: opts.scope } : {}),\n ...(opts.deviceFlow !== undefined ? { deviceFlow: opts.deviceFlow } : {}),\n ...(opts.clientId !== undefined ? { clientId: opts.clientId } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n });\n },\n );\n a.command('list')\n .description('List persisted OAuth sessions.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runAuthList({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n a.command('refresh <id>')\n .description('Refresh a session.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .action(async (id: string, opts: { config?: string }) => {\n await runAuthRefresh({\n id,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n });\n });\n a.command('revoke <id>')\n .description('Revoke a session.')\n .option('--reason <text>', 'Optional reason persisted in the audit log.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .action(async (id: string, opts: { reason?: string; config?: string }) => {\n await runAuthRevoke({\n id,\n ...(opts.reason !== undefined ? { reason: opts.reason } : {}),\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n });\n });\n a.command('status')\n .description('OAuth subsystem snapshot.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runAuthStatus({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerPricingCommands(program: Command): void {\n const p = program.command('pricing').description('[Catalogue] Bundled LLM pricing snapshot.');\n p.command('status')\n .description('Show bundled snapshot version + entry count + digest.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runPricingStatus({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n p.command('refresh')\n .description('Pull a fresh snapshot from --url (network).')\n .requiredOption('--url <url>', 'Snapshot URL.')\n .option('--out <file>', 'Optional path to write the refreshed snapshot to.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { url: string; out?: string; json?: boolean }) => {\n await runPricingRefresh({\n url: opts.url,\n ...(opts.out !== undefined ? { out: opts.out } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n p.command('diff')\n .description('Diff a supplied snapshot against the bundled one.')\n .requiredOption('--snapshot <file>', 'JSON file containing a PricingSnapshot.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { snapshot: string; json?: boolean }) => {\n await runPricingDiff({\n snapshot: opts.snapshot,\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n p.command('lookup')\n .description('Print the per-token price for a single (provider, model) pair.')\n .requiredOption('--provider <name>', 'Provider id.')\n .requiredOption('--model <id>', 'Model id.')\n .option('--region <region>', 'Optional region.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { provider: string; model: string; region?: string; json?: boolean }) => {\n runPricingLookup({\n provider: opts.provider,\n model: opts.model,\n ...(opts.region !== undefined ? { region: opts.region } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n p.command('missing')\n .description('Report (provider, model) pairs absent from the bundled snapshot.')\n .requiredOption('--spans <file>', 'JSON file containing trace spans (array of { attributes }).')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { spans: string; json?: boolean }) => {\n await runPricingMissing({\n spans: opts.spans,\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerSkillsCommands(program: Command): void {\n const s = program\n .command('skills')\n .description('[Catalogue] Manage operator-managed skill packages.');\n s.command('install <source>')\n .description('Install a skill from npm:<name>[@version] or git:<url>.')\n .option('--version <version>', 'npm version pin.')\n .option('--ref <ref>', 'git ref (branch / tag / sha).')\n .option('--trust-level <level>', 'trusted | trusted-with-scripts | untrusted.')\n .option('--cwd <dir>', 'Working directory for npm installs.')\n .option('--dry-run', 'Skip the install; run the policy + audit pipeline only.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (\n source: string,\n opts: {\n version?: string;\n ref?: string;\n trustLevel?: 'trusted' | 'trusted-with-scripts' | 'untrusted';\n cwd?: string;\n dryRun?: boolean;\n json?: boolean;\n },\n ) => {\n await runSkillsInstall({\n source,\n ...(opts.version !== undefined ? { version: opts.version } : {}),\n ...(opts.ref !== undefined ? { ref: opts.ref } : {}),\n ...(opts.trustLevel !== undefined ? { trustLevel: opts.trustLevel } : {}),\n ...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),\n ...(opts.dryRun !== undefined ? { dryRun: opts.dryRun } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n s.command('inspect <name>')\n .description('Print a single recorded installation.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (name: string, opts: { json?: boolean }) => {\n await runSkillsInspect({\n name,\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n s.command('audit')\n .description('Audit every recorded installation in this process.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runSkillsAudit({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n s.command('migrate-frontmatter')\n .description(\n 'Migrate legacy graphorin-* frontmatter fields onto upstream equivalents (DEC-156).',\n )\n .option('--path <dir>', 'Directory to walk. Defaults to cwd.')\n .option('--recursive', 'Walk subdirectories.')\n .option('--apply', 'Actually rewrite files (default: dry-run).')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (opts: { path?: string; recursive?: boolean; apply?: boolean; json?: boolean }) => {\n await runSkillsMigrateFrontmatter({\n ...(opts.path !== undefined ? { path: opts.path } : {}),\n ...(opts.recursive !== undefined ? { recursive: opts.recursive } : {}),\n ...(opts.apply !== undefined ? { apply: opts.apply } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerTracesCommands(program: Command): void {\n const t = program.command('traces').description('[Diagnostics] Operate on the trace cache.');\n t.command('status')\n .description('Count rows + report TTL config.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { config?: string; json?: boolean }) => {\n await runTracesStatus({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n t.command('prune')\n .description('Manual TTL enforcement (cutoff is required).')\n .requiredOption('--before <date>', 'ISO date / epoch ms cutoff.')\n .option('-c, --config <path>', 'Path to the graphorin.config file.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (opts: { before: string; config?: string; json?: boolean }) => {\n await runTracesPrune({\n before: opts.before,\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerMigrateExportCommand(program: Command): void {\n program\n .command('migrate-export <input>')\n .description('[Storage] Migrate a session export file to the current schema (DEC-155).')\n .requiredOption('--to <file>', 'Output path.')\n .option('--to-schema <version>', 'Target schema version.', '1.0')\n .option('--writer <id>', 'Writer identifier surfaced on the meta header.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n async (\n input: string,\n opts: { to: string; toSchema?: string; writer?: string; json?: boolean },\n ) => {\n await runMigrateExport({\n input,\n to: opts.to,\n ...(opts.toSchema !== undefined ? { toSchema: opts.toSchema } : {}),\n ...(opts.writer !== undefined ? { writer: opts.writer } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerMigrateConfigCommand(program: Command): void {\n program\n .command('migrate-config <input>')\n .description('[Bootstrap] Migrate an old config file to the current schema.')\n .option('--out <file>', 'Output path. Defaults to <input>.migrated.json next to the source.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(async (input: string, opts: { out?: string; json?: boolean }) => {\n await runMigrateConfig({\n input,\n ...(opts.out !== undefined ? { out: opts.out } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n });\n}\n\nfunction registerGuardCommands(program: Command): void {\n const g = program\n .command('guard')\n .description('[Diagnostics] Inspect the memory-modification guard.');\n g.command('status')\n .description('Print the four guard tiers and their variants.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runGuardStatus({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n g.command('explain <toolName>')\n .description(\n 'Derive the tier the classifier would assign to a tool with the supplied metadata.',\n )\n .option('--tags <list>', 'Comma-separated tag list.')\n .option('--secrets-allowed <list>', 'Comma-separated secret allowlist.')\n .option('--trust-level <level>', 'built-in | user-defined | trusted | untrusted.')\n .option(\n '--explicit-tier <tier>',\n 'pure | side-effecting-no-memory | memory-aware | unknown | untrusted.',\n )\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action(\n (\n toolName: string,\n opts: {\n tags?: string;\n secretsAllowed?: string;\n trustLevel?: 'built-in' | 'user-defined' | 'trusted' | 'untrusted';\n explicitTier?:\n | 'pure'\n | 'side-effecting-no-memory'\n | 'memory-aware'\n | 'unknown'\n | 'untrusted';\n json?: boolean;\n },\n ) => {\n runGuardExplain({\n toolName,\n ...(opts.tags !== undefined\n ? {\n tags: opts.tags\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n }\n : {}),\n ...(opts.secretsAllowed !== undefined\n ? {\n secretsAllowed: opts.secretsAllowed\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n }\n : {}),\n ...(opts.trustLevel !== undefined ? { trustLevel: opts.trustLevel } : {}),\n ...(opts.explicitTier !== undefined ? { explicitTier: opts.explicitTier } : {}),\n ...(opts.json !== undefined ? { json: opts.json } : {}),\n });\n },\n );\n}\n\nfunction registerTelemetryCommands(program: Command): void {\n const t = program\n .command('telemetry')\n .description('[Diagnostics] Telemetry policy (zero-default per ADR-041).');\n t.command('status')\n .description('Always reports disabled.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runTelemetryStatus({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n t.command('enable')\n .description('Refuses; opt-in collector is on the v0.2+ roadmap.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runTelemetryEnable({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n t.command('disable')\n .description('No-op; telemetry is always disabled.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runTelemetryDisable({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n t.command('inspect')\n .description('Informational summary of the zero-default promise.')\n .option('--json', 'Emit a structured JSON document on stdout.')\n .action((opts: { json?: boolean }) => {\n runTelemetryInspect({ ...(opts.json !== undefined ? { json: opts.json } : {}) });\n });\n}\n\nfunction registerToolsCommands(program: Command): void {\n const tools = program.command('tools').description('[Catalogue] Operate on the tool registry.');\n tools\n .command('lint')\n .description(\n [\n 'Static AST analysis of every tool({...}) registration; per-tool grader + threshold gate (RB-49).',\n '',\n 'Grader rubric (40 + 30 + 30 = 100 points):',\n ' description axis (0..40): 0 if missing/placeholder/<20 chars; 16/24/32/40 by length.',\n ' examples axis (0..30): 0 if none or >5; 12 base + 6 per additional, cap 30; -6 per PII.',\n ' parameter naming (0..30): 30 base; -30/N per ambiguous name; -10/N per numeric suffix.',\n '',\n 'Exit codes (CI-friendly):',\n ' 0 every tool meets or exceeds --threshold.',\n ' 1 at least one tool falls below --threshold.',\n ' 2 invocation could not start (config missing, walker failed).',\n ].join('\\n'),\n )\n .option('-c, --config <path>', 'Optional tsconfig.json whose include overrides the file glob.')\n .option('--threshold <n>', 'Minimum acceptable per-tool score (default 60).', (v) =>\n Number.parseInt(v, 10),\n )\n .option('--format <fmt>', 'text | json (default text).')\n .option('--source <pattern>', 'File glob override (e.g. src/skills/**/tools/*.ts).')\n .action(\n async (opts: {\n config?: string;\n threshold?: number;\n format?: 'text' | 'json';\n source?: string;\n }) => {\n await runToolsLint({\n ...(opts.config !== undefined ? { config: opts.config } : {}),\n ...(opts.threshold !== undefined ? { threshold: opts.threshold } : {}),\n ...(opts.format !== undefined ? { format: opts.format } : {}),\n ...(opts.source !== undefined ? { source: opts.source } : {}),\n });\n },\n );\n}\n\nmain().catch((err) => {\n process.stderr.write(`[graphorin/cli] ${(err as Error).message}\\n`);\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { CommonOutputOptions } from "../internal/output.js";
2
+ import { PruneAuditResult } from "@graphorin/security";
3
+
4
+ //#region src/commands/audit.d.ts
5
+
6
+ /** @stable */
7
+ interface AuditCommonOptions extends CommonOutputOptions {
8
+ readonly config?: string;
9
+ }
10
+ /** @stable */
11
+ interface AuditVerifyResult {
12
+ readonly ok: boolean;
13
+ readonly path: string;
14
+ readonly entries: number;
15
+ readonly broken?: {
16
+ readonly seq: number;
17
+ readonly expected: string;
18
+ readonly actual: string;
19
+ };
20
+ }
21
+ /**
22
+ * `graphorin audit verify` — replay the chain and report the first
23
+ * broken link (if any).
24
+ *
25
+ * @stable
26
+ */
27
+ declare function runAuditVerify(options?: AuditCommonOptions): Promise<AuditVerifyResult>;
28
+ /** @stable */
29
+ interface AuditPruneOptions extends AuditCommonOptions {
30
+ /**
31
+ * ISO-8601 date / `YYYY-MM-DD` / millis-since-epoch. The helper
32
+ * drops entries older than this cutoff.
33
+ */
34
+ readonly before: string;
35
+ /** Minimum number of entries that must survive. Default `1`. */
36
+ readonly retain?: number;
37
+ }
38
+ /** @stable */
39
+ declare function runAuditPrune(options: AuditPruneOptions): Promise<PruneAuditResult>;
40
+ /** @stable */
41
+ interface AuditExportOptions extends AuditCommonOptions {
42
+ readonly to: string;
43
+ readonly fromSeq?: number;
44
+ readonly toSeq?: number;
45
+ }
46
+ /** @stable */
47
+ interface AuditExportResult {
48
+ readonly path: string;
49
+ readonly rows: number;
50
+ }
51
+ /**
52
+ * `graphorin audit export --to <file>` — stream every entry as JSONL.
53
+ *
54
+ * @stable
55
+ */
56
+ declare function runAuditExport(options: AuditExportOptions): Promise<AuditExportResult>;
57
+ //#endregion
58
+ export { AuditCommonOptions, AuditExportOptions, AuditExportResult, AuditPruneOptions, AuditVerifyResult, runAuditExport, runAuditPrune, runAuditVerify };
59
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","names":[],"sources":["../../src/commands/audit.ts"],"sourcesContent":[],"mappings":";;;;;AA6JA;AAA8C,UA/G7B,kBAAA,SAA2B,mBA+GE,CAAA;EAA6B,SAAA,MAAA,CAAA,EAAA,MAAA;;;UA1G1D,iBAAA;;;;;;;;;;;;;;;;iBAaK,cAAA,WAAwB,qBAA0B,QAAQ;;UAoC/D,iBAAA,SAA0B;;;;;;;;;;iBAWrB,aAAA,UAAuB,oBAAoB,QAAQ;;UA6BxD,kBAAA,SAA2B;;;;;;UAO3B,iBAAA;;;;;;;;;iBAUK,cAAA,UAAwB,qBAAqB,QAAQ"}
@@ -0,0 +1,156 @@
1
+ import { brand, defaultPrintSink, emitReport, statusMarker } from "../internal/output.js";
2
+ import { EXIT_CODES } from "../internal/exit.js";
3
+ import { loadConfig } from "../internal/load-config.js";
4
+ import { writeFile } from "node:fs/promises";
5
+ import { dirname, isAbsolute, resolve } from "node:path";
6
+ import process from "node:process";
7
+ import { exportAudit, openAuditDb, pruneAudit, resolveSecret, verifyAuditChain } from "@graphorin/security";
8
+ import { ensureStoreAuditBinding, parseServerConfig } from "@graphorin/server";
9
+
10
+ //#region src/commands/audit.ts
11
+ /**
12
+ * `graphorin audit` — operate on the tamper-evident audit log
13
+ * (`audit.db`).
14
+ *
15
+ * Surface (per Phase 15 § Audit):
16
+ *
17
+ * - `graphorin audit verify` — full hash chain integrity check.
18
+ * - `graphorin audit prune --before <date>` — drop entries older than
19
+ * a cutoff while preserving the surviving suffix's chain integrity.
20
+ * - `graphorin audit export --to <file>` — stream every entry as JSONL.
21
+ *
22
+ * The CLI opens `audit.db` through the framework default binding
23
+ * registered by `@graphorin/server` (`ensureStoreAuditBinding()`); it
24
+ * never re-implements the cipher path.
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ /**
29
+ * `graphorin audit verify` — replay the chain and report the first
30
+ * broken link (if any).
31
+ *
32
+ * @stable
33
+ */
34
+ async function runAuditVerify(options = {}) {
35
+ const ctx = await openAuditContext(options);
36
+ try {
37
+ const result = await verifyAuditChain(ctx.auditDb);
38
+ const out = result.ok ? Object.freeze({
39
+ ok: true,
40
+ path: ctx.auditDb.path,
41
+ entries: result.count
42
+ }) : Object.freeze({
43
+ ok: false,
44
+ path: ctx.auditDb.path,
45
+ entries: 0,
46
+ broken: Object.freeze({
47
+ seq: result.brokenAt,
48
+ expected: result.expected,
49
+ actual: result.actual
50
+ })
51
+ });
52
+ emitReport(options, out, () => {
53
+ const print = options.print ?? defaultPrintSink;
54
+ if (out.ok) {
55
+ print(brand(`audit chain ${statusMarker("ok")} (${out.entries} entries verified, ${out.path})`));
56
+ return;
57
+ }
58
+ print(brand(`audit chain ${statusMarker("fail")} broken at seq ${out.broken?.seq}`));
59
+ print(` expected prevHash=${out.broken?.expected}`);
60
+ print(` actual prevHash=${out.broken?.actual}`);
61
+ process.exitCode = EXIT_CODES.RECOVERABLE_FAILURE;
62
+ });
63
+ return out;
64
+ } finally {
65
+ await ctx.close();
66
+ }
67
+ }
68
+ /** @stable */
69
+ async function runAuditPrune(options) {
70
+ const cutoff = parseCutoff(options.before);
71
+ const ctx = await openAuditContext(options);
72
+ try {
73
+ const result = await pruneAudit(ctx.auditDb, {
74
+ before: cutoff,
75
+ ...options.retain !== void 0 ? { retain: options.retain } : {}
76
+ });
77
+ emitReport(options, result, () => {
78
+ const print = options.print ?? defaultPrintSink;
79
+ if (result.deleted === 0) {
80
+ print(brand(`no audit entries qualified for prune (cutoff=${new Date(cutoff).toISOString()}).`));
81
+ return;
82
+ }
83
+ print(brand(`pruned ${result.deleted} audit entries (cutoff=${new Date(cutoff).toISOString()}, surviving from seq=${result.firstSurvivingSeq ?? "<empty>"})`));
84
+ });
85
+ return result;
86
+ } finally {
87
+ await ctx.close();
88
+ }
89
+ }
90
+ /**
91
+ * `graphorin audit export --to <file>` — stream every entry as JSONL.
92
+ *
93
+ * @stable
94
+ */
95
+ async function runAuditExport(options) {
96
+ const cwd = process.cwd();
97
+ const targetPath = isAbsolute(options.to) ? options.to : resolve(cwd, options.to);
98
+ const ctx = await openAuditContext(options);
99
+ try {
100
+ const lines = [];
101
+ const { rows } = await exportAudit(ctx.auditDb, {
102
+ writer: { write: (line) => void lines.push(line) },
103
+ ...options.fromSeq !== void 0 ? { fromSeq: options.fromSeq } : {},
104
+ ...options.toSeq !== void 0 ? { toSeq: options.toSeq } : {}
105
+ });
106
+ await writeFile(targetPath, lines.join(""), { mode: 384 });
107
+ const out = Object.freeze({
108
+ path: targetPath,
109
+ rows
110
+ });
111
+ emitReport(options, out, () => {
112
+ (options.print ?? defaultPrintSink)(brand(`exported ${rows} audit entries to ${targetPath} (mode 0600).`));
113
+ });
114
+ return out;
115
+ } finally {
116
+ await ctx.close();
117
+ }
118
+ }
119
+ async function openAuditContext(options) {
120
+ const config = parseServerConfig((await loadConfig(options.config)).config);
121
+ if (!config.audit.enabled) throw new Error("[graphorin/cli] this command requires audit.enabled = true in the resolved config.");
122
+ const passphraseRef = config.audit.passphraseRef ?? config.storage.encryption.passphraseRef;
123
+ if (passphraseRef === void 0) throw new Error(`[graphorin/cli] audit.enabled is true but no audit.passphraseRef (or storage.encryption.passphraseRef) is configured. audit.db is mandatory-encrypted by DEC-124.`);
124
+ let passphrase;
125
+ try {
126
+ passphrase = await resolveSecret(passphraseRef);
127
+ } catch (err) {
128
+ throw new Error(`[graphorin/cli] failed to resolve audit passphrase '${passphraseRef}': ${err.message}`, { cause: err });
129
+ }
130
+ const auditPath = config.audit.path ?? deriveAuditPath(config.storage.path);
131
+ ensureStoreAuditBinding();
132
+ const auditDb = await openAuditDb({
133
+ path: auditPath,
134
+ passphrase,
135
+ ...config.audit.cipher !== void 0 ? { cipher: config.audit.cipher } : {}
136
+ });
137
+ return Object.freeze({
138
+ auditDb,
139
+ path: auditPath,
140
+ close: () => auditDb.close()
141
+ });
142
+ }
143
+ function deriveAuditPath(storagePath) {
144
+ return resolve(dirname(storagePath), "audit.db");
145
+ }
146
+ function parseCutoff(input) {
147
+ const numeric = Number(input);
148
+ if (Number.isFinite(numeric) && numeric > 0) return numeric;
149
+ const ms = Date.parse(input);
150
+ if (!Number.isFinite(ms)) throw new Error(`[graphorin/cli] --before '${input}' is not a valid ISO date or epoch-ms value.`);
151
+ return ms;
152
+ }
153
+
154
+ //#endregion
155
+ export { runAuditExport, runAuditPrune, runAuditVerify };
156
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","names":["result: AuditChainVerifyResult","out: AuditVerifyResult","lines: string[]","out: AuditExportResult","passphrase: SecretValue"],"sources":["../../src/commands/audit.ts"],"sourcesContent":["/**\n * `graphorin audit` — operate on the tamper-evident audit log\n * (`audit.db`).\n *\n * Surface (per Phase 15 § Audit):\n *\n * - `graphorin audit verify` — full hash chain integrity check.\n * - `graphorin audit prune --before <date>` — drop entries older than\n * a cutoff while preserving the surviving suffix's chain integrity.\n * - `graphorin audit export --to <file>` — stream every entry as JSONL.\n *\n * The CLI opens `audit.db` through the framework default binding\n * registered by `@graphorin/server` (`ensureStoreAuditBinding()`); it\n * never re-implements the cipher path.\n *\n * @packageDocumentation\n */\n\nimport { writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport process from 'node:process';\n\nimport {\n type AuditChainVerifyResult,\n exportAudit,\n openAuditDb,\n type PruneAuditResult,\n pruneAudit,\n resolveSecret,\n type SecretValue,\n type StoredAuditEntry,\n verifyAuditChain,\n} from '@graphorin/security';\nimport { ensureStoreAuditBinding, parseServerConfig } from '@graphorin/server';\n\nimport { EXIT_CODES } from '../internal/exit.js';\nimport { loadConfig } from '../internal/load-config.js';\nimport {\n brand,\n type CommonOutputOptions,\n defaultPrintSink,\n emitReport,\n statusMarker,\n} from '../internal/output.js';\n\n/** @stable */\nexport interface AuditCommonOptions extends CommonOutputOptions {\n readonly config?: string;\n}\n\n/** @stable */\nexport interface AuditVerifyResult {\n readonly ok: boolean;\n readonly path: string;\n readonly entries: number;\n readonly broken?: { readonly seq: number; readonly expected: string; readonly actual: string };\n}\n\n/**\n * `graphorin audit verify` — replay the chain and report the first\n * broken link (if any).\n *\n * @stable\n */\nexport async function runAuditVerify(options: AuditCommonOptions = {}): Promise<AuditVerifyResult> {\n const ctx = await openAuditContext(options);\n try {\n const result: AuditChainVerifyResult = await verifyAuditChain(ctx.auditDb);\n const out: AuditVerifyResult = result.ok\n ? Object.freeze({ ok: true, path: ctx.auditDb.path, entries: result.count })\n : Object.freeze({\n ok: false,\n path: ctx.auditDb.path,\n entries: 0,\n broken: Object.freeze({\n seq: result.brokenAt,\n expected: result.expected,\n actual: result.actual,\n }),\n });\n emitReport(options, out, () => {\n const print = options.print ?? defaultPrintSink;\n if (out.ok) {\n print(\n brand(`audit chain ${statusMarker('ok')} (${out.entries} entries verified, ${out.path})`),\n );\n return;\n }\n print(brand(`audit chain ${statusMarker('fail')} broken at seq ${out.broken?.seq}`));\n print(` expected prevHash=${out.broken?.expected}`);\n print(` actual prevHash=${out.broken?.actual}`);\n process.exitCode = EXIT_CODES.RECOVERABLE_FAILURE;\n });\n return out;\n } finally {\n await ctx.close();\n }\n}\n\n/** @stable */\nexport interface AuditPruneOptions extends AuditCommonOptions {\n /**\n * ISO-8601 date / `YYYY-MM-DD` / millis-since-epoch. The helper\n * drops entries older than this cutoff.\n */\n readonly before: string;\n /** Minimum number of entries that must survive. Default `1`. */\n readonly retain?: number;\n}\n\n/** @stable */\nexport async function runAuditPrune(options: AuditPruneOptions): Promise<PruneAuditResult> {\n const cutoff = parseCutoff(options.before);\n const ctx = await openAuditContext(options);\n try {\n const result = await pruneAudit(ctx.auditDb, {\n before: cutoff,\n ...(options.retain !== undefined ? { retain: options.retain } : {}),\n });\n emitReport(options, result, () => {\n const print = options.print ?? defaultPrintSink;\n if (result.deleted === 0) {\n print(\n brand(`no audit entries qualified for prune (cutoff=${new Date(cutoff).toISOString()}).`),\n );\n return;\n }\n print(\n brand(\n `pruned ${result.deleted} audit entries (cutoff=${new Date(cutoff).toISOString()}, surviving from seq=${result.firstSurvivingSeq ?? '<empty>'})`,\n ),\n );\n });\n return result;\n } finally {\n await ctx.close();\n }\n}\n\n/** @stable */\nexport interface AuditExportOptions extends AuditCommonOptions {\n readonly to: string;\n readonly fromSeq?: number;\n readonly toSeq?: number;\n}\n\n/** @stable */\nexport interface AuditExportResult {\n readonly path: string;\n readonly rows: number;\n}\n\n/**\n * `graphorin audit export --to <file>` — stream every entry as JSONL.\n *\n * @stable\n */\nexport async function runAuditExport(options: AuditExportOptions): Promise<AuditExportResult> {\n const cwd = process.cwd();\n const targetPath = isAbsolute(options.to) ? options.to : resolve(cwd, options.to);\n const ctx = await openAuditContext(options);\n try {\n const lines: string[] = [];\n const { rows } = await exportAudit(ctx.auditDb, {\n writer: { write: (line: string) => void lines.push(line) },\n ...(options.fromSeq !== undefined ? { fromSeq: options.fromSeq } : {}),\n ...(options.toSeq !== undefined ? { toSeq: options.toSeq } : {}),\n });\n await writeFile(targetPath, lines.join(''), { mode: 0o600 });\n const out: AuditExportResult = Object.freeze({ path: targetPath, rows });\n emitReport(options, out, () => {\n const print = options.print ?? defaultPrintSink;\n print(brand(`exported ${rows} audit entries to ${targetPath} (mode 0600).`));\n });\n return out;\n } finally {\n await ctx.close();\n }\n}\n\ninterface AuditContext {\n readonly auditDb: Awaited<ReturnType<typeof openAuditDb>>;\n readonly path: string;\n readonly close: () => Promise<void>;\n}\n\nasync function openAuditContext(options: AuditCommonOptions): Promise<AuditContext> {\n const loaded = await loadConfig(options.config);\n const config = parseServerConfig(loaded.config);\n if (!config.audit.enabled) {\n throw new Error(\n '[graphorin/cli] this command requires audit.enabled = true in the resolved config.',\n );\n }\n const passphraseRef = config.audit.passphraseRef ?? config.storage.encryption.passphraseRef;\n if (passphraseRef === undefined) {\n throw new Error(\n `[graphorin/cli] audit.enabled is true but no audit.passphraseRef (or storage.encryption.passphraseRef) is configured. audit.db is mandatory-encrypted by DEC-124.`,\n );\n }\n let passphrase: SecretValue;\n try {\n passphrase = await resolveSecret(passphraseRef);\n } catch (err) {\n throw new Error(\n `[graphorin/cli] failed to resolve audit passphrase '${passphraseRef}': ${(err as Error).message}`,\n { cause: err },\n );\n }\n const auditPath = config.audit.path ?? deriveAuditPath(config.storage.path);\n ensureStoreAuditBinding();\n const auditDb = await openAuditDb({\n path: auditPath,\n passphrase,\n ...(config.audit.cipher !== undefined ? { cipher: config.audit.cipher } : {}),\n });\n return Object.freeze({\n auditDb,\n path: auditPath,\n close: () => auditDb.close(),\n });\n}\n\nfunction deriveAuditPath(storagePath: string): string {\n const dir = dirname(storagePath);\n return resolve(dir, 'audit.db');\n}\n\nfunction parseCutoff(input: string): number {\n const numeric = Number(input);\n if (Number.isFinite(numeric) && numeric > 0) return numeric;\n const ms = Date.parse(input);\n if (!Number.isFinite(ms)) {\n throw new Error(\n `[graphorin/cli] --before '${input}' is not a valid ISO date or epoch-ms value.`,\n );\n }\n return ms;\n}\n\n// Internal type-only consumers — keep in scope so tree-shaking\n// preserves the entry point.\nvoid ((_e?: StoredAuditEntry) => undefined);\n"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { CommonOutputOptions } from "../internal/output.js";
2
+ import * as _graphorin_security0 from "@graphorin/security";
3
+ import { LoginInteractiveResult } from "@graphorin/security";
4
+
5
+ //#region src/commands/auth.d.ts
6
+
7
+ /** @stable */
8
+ interface AuthCommonOptions extends CommonOutputOptions {
9
+ readonly config?: string;
10
+ }
11
+ /** @stable */
12
+ interface AuthLoginOptions extends AuthCommonOptions {
13
+ readonly serverUrl: string;
14
+ readonly serverId?: string;
15
+ readonly scope?: string;
16
+ readonly deviceFlow?: boolean;
17
+ /**
18
+ * Optional pre-existing client identifier — skips Dynamic Client
19
+ * Registration when supplied.
20
+ */
21
+ readonly clientId?: string;
22
+ }
23
+ /** @stable */
24
+ declare function runAuthLogin(options: AuthLoginOptions): Promise<LoginInteractiveResult>;
25
+ /** @stable */
26
+ interface AuthListOptions extends AuthCommonOptions {}
27
+ /** @stable */
28
+ declare function runAuthList(options?: AuthListOptions): Promise<readonly _graphorin_security0.OAuthSessionMetadata[]>;
29
+ /** @stable */
30
+ interface AuthRefreshOptions extends AuthCommonOptions {
31
+ readonly id: string;
32
+ }
33
+ /** @stable */
34
+ declare function runAuthRefresh(options: AuthRefreshOptions): Promise<_graphorin_security0.OAuthSession>;
35
+ /** @stable */
36
+ interface AuthRevokeOptions extends AuthCommonOptions {
37
+ readonly id: string;
38
+ readonly reason?: string;
39
+ }
40
+ /** @stable */
41
+ declare function runAuthRevoke(options: AuthRevokeOptions): Promise<{
42
+ readonly ok: true;
43
+ }>;
44
+ /** @stable */
45
+ declare function runAuthStatus(options?: AuthCommonOptions): Promise<_graphorin_security0.OAuthStatusSnapshot>;
46
+ //#endregion
47
+ export { AuthCommonOptions, AuthListOptions, AuthLoginOptions, AuthRefreshOptions, AuthRevokeOptions, runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus };
48
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","names":[],"sources":["../../src/commands/auth.ts"],"sourcesContent":[],"mappings":";;;;;;AAkJA;AAA8C,UA1F7B,iBAAA,SAA0B,mBA0FG,CAAA;EAAkB,SAAA,MAAA,CAAA,EAAA,MAAA;;;AA+B/C,UApHA,gBAAA,SAAyB,iBAoHkB,CAAA;EAMtC,SAAA,SAAa,EAAA,MAAA;EAqBb,SAAA,QAAa,CAAA,EAAA,MAAA;EAAU,SAAA,KAAA,CAAA,EAAA,MAAA;EAAsB,SAAA,UAAA,CAAA,EAAA,OAAA;EAAA;;;;;;;iBAlI7C,YAAA,UAAsB,mBAAmB,QAAQ;;UAoCtD,eAAA,SAAwB;;iBAGnB,WAAA,WAAqB,kBAAoB,iBAAA,oBAAA,CAAA,oBAAA;;UA4B9C,kBAAA,SAA2B;;;;iBAKtB,cAAA,UAAwB,qBAAkB,QAAA,oBAAA,CAAA,YAAA;;UA+B/C,iBAAA,SAA0B;;;;;iBAMrB,aAAA,UAAuB,oBAAoB;;;;iBAqB3C,aAAA,WAAuB,oBAAsB,QAAA,oBAAA,CAAA,mBAAA"}
@@ -0,0 +1,148 @@
1
+ import { brand, defaultPrintSink, emitReport, statusMarker } from "../internal/output.js";
2
+ import { EXIT_CODES } from "../internal/exit.js";
3
+ import { checkOfflineModeBlocked } from "../internal/offline.js";
4
+ import { openStoreContext } from "../internal/store-context.js";
5
+ import { getOAuthStatus, listOAuthSessions, loginInteractive, refreshOAuthSession, revokeOAuthSession } from "@graphorin/security";
6
+ import { createSecretsStore as createSecretsStore$1, getActiveSecretsStore as getActiveSecretsStore$1 } from "@graphorin/security/secrets";
7
+
8
+ //#region src/commands/auth.ts
9
+ /**
10
+ * `graphorin auth` — outbound OAuth subsystem (e.g. for MCP servers).
11
+ *
12
+ * Surface (per Phase 15 § Auth):
13
+ *
14
+ * - `graphorin auth login --server <url> [--device-flow]`
15
+ * - `graphorin auth list`
16
+ * - `graphorin auth refresh <id>`
17
+ * - `graphorin auth revoke <id>`
18
+ * - `graphorin auth status`
19
+ *
20
+ * Honours `GRAPHORIN_OFFLINE=1` — when set, every subcommand short-
21
+ * circuits with an explanatory message and exits `1` so CI pipelines
22
+ * see the failure.
23
+ *
24
+ * @packageDocumentation
25
+ */
26
+ /**
27
+ * Resolve the CLI's secrets store for OAuth token persistence (SPL-1):
28
+ * the already-active store when one exists, else the default auto
29
+ * chain (keyring → encrypted-file → env). Best-effort — a store
30
+ * failure degrades to the in-memory-only pre-SPL-1 behavior instead of
31
+ * blocking the auth command.
32
+ */
33
+ async function resolveAuthSecretsStore() {
34
+ try {
35
+ return getActiveSecretsStore$1() ?? await createSecretsStore$1({});
36
+ } catch {
37
+ return;
38
+ }
39
+ }
40
+ /** @stable */
41
+ async function runAuthLogin(options) {
42
+ if (!checkOfflineModeBlocked("auth login", { ...options.print !== void 0 ? { print: options.print } : {} })) process.exit(EXIT_CODES.RECOVERABLE_FAILURE);
43
+ const ctx = await openStoreContext({ ...options.config !== void 0 ? { config: options.config } : {} });
44
+ try {
45
+ const serverId = options.serverId ?? deriveServerId(options.serverUrl);
46
+ const secretsStore = await resolveAuthSecretsStore();
47
+ const result = await loginInteractive({
48
+ serverId,
49
+ serverUrl: options.serverUrl,
50
+ storage: ctx.store.oauthServers,
51
+ ...secretsStore === void 0 ? {} : { secretsStore },
52
+ ...options.deviceFlow !== void 0 ? { deviceFlow: options.deviceFlow } : {},
53
+ ...options.scope !== void 0 ? { scope: options.scope } : {},
54
+ ...options.clientId !== void 0 ? { clientId: options.clientId } : {}
55
+ });
56
+ emitReport(options, result.status, () => {
57
+ const print = options.print ?? defaultPrintSink;
58
+ print(brand(`oauth login ${statusMarker("ok")} (server=${result.status.serverId})`));
59
+ print(` status: ${result.status.status}`);
60
+ print(` expiresAt: ${result.status.expiresAt ?? "-"}`);
61
+ });
62
+ return result;
63
+ } finally {
64
+ await ctx.close();
65
+ }
66
+ }
67
+ /** @stable */
68
+ async function runAuthList(options = {}) {
69
+ const ctx = await openStoreContext({ ...options.config !== void 0 ? { config: options.config } : {} });
70
+ try {
71
+ const secretsStore = await resolveAuthSecretsStore();
72
+ const list = await listOAuthSessions(ctx.store.oauthServers, { ...secretsStore === void 0 ? {} : { secretsStore } });
73
+ emitReport(options, list, () => {
74
+ const print = options.print ?? defaultPrintSink;
75
+ if (list.length === 0) {
76
+ print(brand("no OAuth sessions persisted."));
77
+ return;
78
+ }
79
+ print(brand(`${list.length} OAuth session(s):`));
80
+ for (const s of list) print(` ${s.status === "expired" ? statusMarker("warn") : statusMarker("ok")} ${s.serverId} (status=${s.status}, scope=${s.scope ?? "-"})`);
81
+ });
82
+ return list;
83
+ } finally {
84
+ await ctx.close();
85
+ }
86
+ }
87
+ /** @stable */
88
+ async function runAuthRefresh(options) {
89
+ if (!checkOfflineModeBlocked("auth refresh", { ...options.print !== void 0 ? { print: options.print } : {} })) process.exit(EXIT_CODES.RECOVERABLE_FAILURE);
90
+ const ctx = await openStoreContext({ ...options.config !== void 0 ? { config: options.config } : {} });
91
+ try {
92
+ const secretsStore = await resolveAuthSecretsStore();
93
+ const session = await refreshOAuthSession(ctx.store.oauthServers, options.id, { ...secretsStore === void 0 ? {} : { secretsStore } });
94
+ emitReport(options, {
95
+ ok: true,
96
+ id: options.id
97
+ }, () => {
98
+ (options.print ?? defaultPrintSink)(brand(`oauth session '${options.id}' refreshed (expiresAt=${new Date(session.expiresAt ?? Date.now()).toISOString()})`));
99
+ });
100
+ return session;
101
+ } finally {
102
+ await ctx.close();
103
+ }
104
+ }
105
+ /** @stable */
106
+ async function runAuthRevoke(options) {
107
+ const ctx = await openStoreContext({ ...options.config !== void 0 ? { config: options.config } : {} });
108
+ try {
109
+ const secretsStore = await resolveAuthSecretsStore();
110
+ await revokeOAuthSession(ctx.store.oauthServers, options.id, {
111
+ ...secretsStore === void 0 ? {} : { secretsStore },
112
+ ...options.reason !== void 0 ? { reason: options.reason } : {}
113
+ });
114
+ emitReport(options, { ok: true }, () => {
115
+ (options.print ?? defaultPrintSink)(brand(`oauth session '${options.id}' revoked.`));
116
+ });
117
+ return { ok: true };
118
+ } finally {
119
+ await ctx.close();
120
+ }
121
+ }
122
+ /** @stable */
123
+ async function runAuthStatus(options = {}) {
124
+ const ctx = await openStoreContext({ ...options.config !== void 0 ? { config: options.config } : {} });
125
+ try {
126
+ const secretsStore = await resolveAuthSecretsStore();
127
+ const status = await getOAuthStatus(ctx.store.oauthServers, { ...secretsStore === void 0 ? {} : { secretsStore } });
128
+ emitReport(options, status, () => {
129
+ const print = options.print ?? defaultPrintSink;
130
+ print(brand(`oauth subsystem status: ${status.sessions.length} session(s), ${status.providers.length} strategy(ies)`));
131
+ if (status.defaultStrategy !== null) print(brand(`default strategy: ${status.defaultStrategy.id}`));
132
+ });
133
+ return status;
134
+ } finally {
135
+ await ctx.close();
136
+ }
137
+ }
138
+ function deriveServerId(serverUrl) {
139
+ try {
140
+ return new URL(serverUrl).host;
141
+ } catch {
142
+ return serverUrl;
143
+ }
144
+ }
145
+
146
+ //#endregion
147
+ export { runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus };
148
+ //# sourceMappingURL=auth.js.map