@lexq/cli 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/auth.ts","../src/lib/config.ts","../src/lib/api-client.ts","../src/lib/output.ts","../src/commands/status.ts","../src/commands/groups.ts","../src/commands/versions.ts","../src/commands/rules.ts","../src/commands/facts.ts","../src/commands/deploy.ts","../src/commands/analytics.ts","../src/commands/history.ts","../src/commands/integrations.ts","../src/commands/logs.ts","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { registerAuthCommands } from './commands/auth';\nimport { registerStatusCommand } from './commands/status';\nimport { registerGroupCommands } from './commands/groups';\nimport { registerVersionCommands } from './commands/versions';\nimport { registerRuleCommands } from './commands/rules';\nimport { registerFactCommands } from './commands/facts';\nimport { registerDeployCommands } from './commands/deploy';\nimport { registerAnalyticsCommands } from './commands/analytics';\nimport { registerHistoryCommands } from './commands/history';\nimport { registerIntegrationCommands } from './commands/integrations';\nimport { registerLogCommands } from './commands/logs';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction getVersion(): string {\n try {\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n return pkg.version;\n } catch {\n return '0.0.0';\n }\n}\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name('lexq')\n .description('LexQ CLI — manage policies, simulate rules, and deploy from the terminal.')\n .version(getVersion(), '-V, --version')\n .option('--format <format>', 'Output format: json or table', 'json')\n .option('--api-key <key>', 'Override stored API key')\n .option('--base-url <url>', 'Override API base URL')\n .option('--dry-run', 'Preview the HTTP request without executing')\n .option('--verbose', 'Show request/response details')\n .option('--no-color', 'Disable colored output');\n\n // M1: Auth & Infrastructure\n registerAuthCommands(program);\n registerStatusCommand(program);\n\n // M1+: Policy Groups (CRUD + A/B Test)\n registerGroupCommands(program);\n\n // M2: Versions, Rules, Facts\n registerVersionCommands(program);\n registerRuleCommands(program);\n registerFactCommands(program);\n\n // M3: Deployment & Analytics\n registerDeployCommands(program);\n registerAnalyticsCommands(program);\n\n // M3+: Execution History, Integrations, Failure Logs\n registerHistoryCommands(program);\n registerIntegrationCommands(program);\n registerLogCommands(program);\n\n return program;\n}","import { type Command } from 'commander';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { saveConfig, deleteConfig, loadConfig, getConfigPath } from '@/lib/config';\nimport { apiRequest } from '@/lib/api-client';\nimport { printJson, printError } from '@/lib/output';\nimport type { WhoAmIResponse } from '@/types/auth';\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command('auth').description('Manage authentication');\n\n // ── login ──\n auth\n .command('login')\n .description('Authenticate with your LexQ API key')\n .action(async () => {\n try {\n const rl = createInterface({ input: stdin, output: stdout });\n const apiKey = await rl.question('Enter your API Key: ');\n rl.close();\n\n if (!apiKey.trim()) {\n console.error('API key cannot be empty.');\n process.exit(1);\n }\n\n saveConfig({ apiKey: apiKey.trim() });\n console.log(`✓ API key saved to ${getConfigPath()}`);\n console.log(' Run \"lexq auth whoami\" to verify.');\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── logout ──\n auth\n .command('logout')\n .description('Remove stored credentials')\n .action(() => {\n deleteConfig();\n console.log('✓ Credentials removed.');\n });\n\n // ── whoami ──\n auth\n .command('whoami')\n .description('Show current authentication info')\n .action(async () => {\n try {\n const config = loadConfig();\n if (!config.apiKey) {\n console.error('Not authenticated. Run \"lexq auth login\" first.');\n process.exit(1);\n }\n\n const info = await apiRequest<WhoAmIResponse>(\n 'GET',\n 'whoami',\n { apiKey: config.apiKey, baseUrl: config.baseUrl }\n );\n\n const masked = config.apiKey.length > 8\n ? config.apiKey.substring(0, 4) + '****' + config.apiKey.substring(config.apiKey.length - 4)\n : '****';\n\n printJson({\n ...info,\n apiKey: masked,\n baseUrl: config.baseUrl,\n });\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport interface LexqConfig {\n apiKey?: string;\n baseUrl: string;\n format: 'json' | 'table';\n}\n\nconst CONFIG_DIR = join(homedir(), '.lexq');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\nconst DEFAULT_CONFIG: LexqConfig = {\n baseUrl: 'https://api.lexq.io/api/v1/partners',\n format: 'json',\n};\n\nexport function loadConfig(): LexqConfig {\n if (!existsSync(CONFIG_FILE)) return { ...DEFAULT_CONFIG };\n\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(config: Partial<LexqConfig>): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n\n const current = loadConfig();\n const merged = { ...current, ...config };\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf-8');\n}\n\nexport function deleteConfig(): void {\n if (existsSync(CONFIG_FILE)) {\n unlinkSync(CONFIG_FILE);\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}","import { loadConfig } from './config';\nimport type { ApiResponse } from '@/types/api';\n\nexport interface ApiClientOptions {\n apiKey?: string;\n baseUrl?: string;\n dryRun?: boolean;\n verbose?: boolean;\n}\n\nexport class ApiError extends Error {\n constructor(\n public readonly statusCode: number,\n public readonly errorCode: string | null,\n message: string\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function apiRequest<T>(\n method: string,\n path: string,\n options: ApiClientOptions & { body?: unknown; params?: Record<string, string> } = {}\n): Promise<T> {\n const config = loadConfig();\n const baseUrl = options.baseUrl ?? config.baseUrl;\n const apiKey = options.apiKey ?? config.apiKey;\n\n if (!apiKey) {\n throw new ApiError(401, 'AUTH', 'Not authenticated. Run \"lexq auth login\" first.');\n }\n\n // Build URL with query params\n const url = new URL(path, baseUrl.endsWith('/') ? baseUrl : baseUrl + '/');\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined && value !== '') {\n url.searchParams.set(key, value);\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'X-API-KEY': apiKey,\n 'Accept': 'application/json',\n };\n\n if (options.body) {\n headers['Content-Type'] = 'application/json';\n }\n\n // Dry-run: print request and exit\n if (options.dryRun) {\n const masked = apiKey.length > 8\n ? apiKey.substring(0, 4) + '****' + apiKey.substring(apiKey.length - 4)\n : '****';\n\n console.log(`${method} ${url.toString()}`);\n console.log('Headers:');\n console.log(` X-API-KEY: ${masked}`);\n console.log(` Content-Type: application/json`);\n if (options.body) {\n console.log('Body:');\n console.log(` ${JSON.stringify(options.body, null, 2)}`);\n }\n console.log('\\n(Use without --dry-run to execute)');\n process.exit(0);\n }\n\n if (options.verbose) {\n console.error(`→ ${method} ${url.toString()}`);\n }\n\n const startTime = Date.now();\n\n const response = await fetch(url.toString(), {\n method,\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n if (options.verbose) {\n console.error(`← ${response.status} ${response.statusText} (${Date.now() - startTime}ms)`);\n }\n\n // Handle blob responses (export endpoints)\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('text/csv') || contentType.includes('application/octet-stream')) {\n return response as unknown as T;\n }\n\n // No-content responses (DELETE 204 등)\n if (response.status === 204 || contentType === '') {\n return undefined as T;\n }\n\n const json = (await response.json()) as ApiResponse<T>;\n\n if (!response.ok || json.result !== 'SUCCESS') {\n throw new ApiError(\n response.status,\n json.errorCode,\n json.message ?? `Request failed with status ${response.status}`\n );\n }\n\n return json.data;\n}","import Table from 'cli-table3';\n\nexport type OutputFormat = 'json' | 'table';\n\nexport function printJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function printTable(\n headers: string[],\n rows: string[][],\n options?: { truncate?: number }\n): void {\n const table = new Table({\n head: headers,\n style: { head: ['cyan'] },\n wordWrap: true,\n });\n\n for (const row of rows) {\n if (options?.truncate) {\n table.push(\n row.map((cell) =>\n cell.length > options.truncate! ? cell.substring(0, options.truncate!) + '…' : cell\n )\n );\n } else {\n table.push(row);\n }\n }\n\n console.log(table.toString());\n}\n\nexport function printError(error: unknown): void {\n if (error instanceof Error && 'errorCode' in error) {\n const apiErr = error as Error & { errorCode: string | null; statusCode: number };\n const output = {\n error: apiErr.errorCode ?? 'UNKNOWN',\n message: apiErr.message,\n status: apiErr.statusCode,\n };\n console.error(JSON.stringify(output, null, 2));\n } else if (error instanceof Error) {\n console.error(JSON.stringify({ error: 'CLI_ERROR', message: error.message }, null, 2));\n } else {\n console.error(JSON.stringify({ error: 'UNKNOWN', message: String(error) }, null, 2));\n }\n}","import { type Command } from 'commander';\nimport { loadConfig } from '@/lib/config';\nimport { printJson, printError } from '@/lib/output';\n\nexport function registerStatusCommand(program: Command): void {\n program\n .command('status')\n .description('Check LexQ API server status')\n .action(async () => {\n const config = loadConfig();\n const baseUrl = config.baseUrl.replace(/\\/v1\\/partners\\/?$/, '');\n\n try {\n const start = Date.now();\n const response = await fetch(`${baseUrl}/health`);\n const latency = Date.now() - start;\n\n printJson({\n status: response.ok ? 'ok' : 'degraded',\n httpStatus: response.status,\n latencyMs: latency,\n endpoint: `${baseUrl}/health`,\n });\n } catch {\n printError(new Error(`Cannot reach LexQ API at ${baseUrl}/health`));\n process.exit(1);\n }\n });\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type {\n PolicyGroupSummary,\n PolicyGroupDetail,\n CreatePolicyGroupRequest,\n UpdatePolicyGroupRequest,\n StartAbTestRequest,\n AdjustTrafficRateRequest,\n} from '@/types/groups';\n\nexport function registerGroupCommands(program: Command): void {\n const groups = program.command('groups').description('Manage policy groups');\n\n // ── list ──\n groups\n .command('list')\n .description('List all policy groups')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const data = await apiRequest<PageResponse<PolicyGroupSummary>>(\n 'GET',\n 'policy-groups',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: { page: opts.page, size: opts.size },\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Name', 'Status', 'Priority', 'Version', 'Updated'],\n data.content.map((g) => [\n g.id,\n g.name,\n g.status,\n String(g.priority),\n g.currentVersionName ?? '–',\n g.updatedAt.substring(0, 10),\n ]),\n { truncate: 24 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n groups\n .command('get')\n .description('Get a policy group by ID')\n .requiredOption('--id <groupId>', 'Policy group ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<PolicyGroupDetail>(\n 'GET',\n `policy-groups/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── create ──\n groups\n .command('create')\n .description('Create a new policy group')\n .requiredOption('--json <body>', 'Request body as JSON string')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = JSON.parse(opts.json) as CreatePolicyGroupRequest;\n const data = await apiRequest<PolicyGroupDetail>(\n 'POST',\n 'policy-groups',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── update ──\n groups\n .command('update')\n .description('Update a policy group')\n .requiredOption('--id <groupId>', 'Policy group ID')\n .requiredOption('--json <body>', 'Request body as JSON string')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = JSON.parse(opts.json) as UpdatePolicyGroupRequest;\n const data = await apiRequest<PolicyGroupDetail>(\n 'PUT',\n `policy-groups/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── delete ──\n groups\n .command('delete')\n .description('Delete a policy group')\n .requiredOption('--id <groupId>', 'Policy group ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Delete group ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `policy-groups/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Group ${opts.id} deleted.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ══════════════════════════════════════════════════\n // A/B Test\n // ══════════════════════════════════════════════════\n\n const abTest = groups.command('ab-test').description('A/B test management');\n\n // ── start ──\n abTest\n .command('start')\n .description('Start an A/B test')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Challenger version ID')\n .requiredOption('--traffic-rate <rate>', 'Traffic rate for challenger (1-99)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body: StartAbTestRequest = {\n testVersionId: opts.versionId,\n trafficRate: Number(opts.trafficRate),\n };\n const data = await apiRequest<PolicyGroupDetail>(\n 'POST',\n `policy-groups/${opts.groupId}/ab-test`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── stop ──\n abTest\n .command('stop')\n .description('Stop an A/B test')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Stop A/B test for group ${opts.groupId}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n const data = await apiRequest<unknown>(\n 'DELETE',\n `policy-groups/${opts.groupId}/ab-test`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── adjust ──\n abTest\n .command('adjust')\n .description('Adjust A/B test traffic rate')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--traffic-rate <rate>', 'New traffic rate (1-99)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body: AdjustTrafficRateRequest = {\n trafficRate: Number(opts.trafficRate),\n };\n const data = await apiRequest<unknown>(\n 'PATCH',\n `policy-groups/${opts.groupId}/ab-test/traffic-rate`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { PolicyVersionSummary } from '@/types/versions';\n\nexport function registerVersionCommands(program: Command): void {\n const versions = program.command('versions').description('Manage policy versions');\n\n // ── list ──\n versions\n .command('list')\n .description('List versions for a policy group')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const data = await apiRequest<PageResponse<PolicyVersionSummary>>(\n 'GET',\n `policy-groups/${opts.groupId}/versions`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: { page: opts.page, size: opts.size },\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'v#', 'Status', 'Commit', 'Hash', 'Created'],\n data.content.map((v) => [\n v.id,\n `v${v.versionNo}`,\n v.status,\n v.commitMessage ?? '–',\n v.snapshotHash ? v.snapshotHash.substring(0, 8) : '–',\n v.createdAt.substring(0, 10),\n ]),\n { truncate: 24 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n versions\n .command('get')\n .description('Get a policy version by ID')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--id <versionId>', 'Policy version ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<PolicyVersionSummary>(\n 'GET',\n `policy-groups/${opts.groupId}/versions/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── create ──\n versions\n .command('create')\n .description('Create a new draft version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .option('--commit-message <message>', 'Commit message')\n .option('--effective-from <date>', 'Effective from (ISO datetime)')\n .option('--effective-to <date>', 'Effective to (ISO datetime)')\n .option('--json <body>', 'Full request body as JSON (overrides other options)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = opts.json\n ? JSON.parse(opts.json)\n : buildCreateBody(opts);\n\n const data = await apiRequest<PolicyVersionSummary>(\n 'POST',\n `policy-groups/${opts.groupId}/versions`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── update ──\n versions\n .command('update')\n .description('Update a draft version metadata')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--id <versionId>', 'Policy version ID')\n .option('--commit-message <message>', 'Commit message')\n .option('--effective-from <date>', 'Effective from (ISO datetime)')\n .option('--effective-to <date>', 'Effective to (ISO datetime)')\n .option('--json <body>', 'Full request body as JSON (overrides other options)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = opts.json\n ? JSON.parse(opts.json)\n : buildUpdateBody(opts);\n\n const data = await apiRequest<PolicyVersionSummary>(\n 'PUT',\n `policy-groups/${opts.groupId}/versions/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── delete ──\n versions\n .command('delete')\n .description('Delete a policy version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--id <versionId>', 'Policy version ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Delete version ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `policy-groups/${opts.groupId}/versions/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Version ${opts.id} deleted.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── clone ──\n versions\n .command('clone')\n .description('Clone (duplicate) a policy version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--id <versionId>', 'Source version ID to clone')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<PolicyVersionSummary>(\n 'POST',\n `policy-groups/${opts.groupId}/versions/${opts.id}/clone`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}\n\n// ── Helpers ──\n\nfunction buildCreateBody(opts: Record<string, string | undefined>): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (opts.commitMessage) body.commitMessage = opts.commitMessage;\n if (opts.effectiveFrom) body.effectiveFrom = opts.effectiveFrom;\n if (opts.effectiveTo) body.effectiveTo = opts.effectiveTo;\n return body;\n}\n\nfunction buildUpdateBody(opts: Record<string, string | undefined>): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (opts.commitMessage) body.commitMessage = opts.commitMessage;\n if (opts.effectiveFrom) body.effectiveFrom = opts.effectiveFrom;\n if (opts.effectiveTo) body.effectiveTo = opts.effectiveTo;\n return body;\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type {\n PolicyRuleSummary,\n PolicyRuleDetail,\n CreateRuleRequest,\n UpdateRuleRequest,\n ReorderRulesRequest,\n} from '@/types/rules';\n\nexport function registerRuleCommands(program: Command): void {\n const rules = program.command('rules').description('Manage policy rules');\n\n // ── list ──\n rules\n .command('list')\n .description('List rules for a policy version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const data = await apiRequest<PageResponse<PolicyRuleSummary>>(\n 'GET',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: { page: opts.page, size: opts.size },\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Name', 'Priority', 'Conditions', 'Actions', 'Enabled'],\n data.content.map((r) => [\n r.id,\n r.name,\n String(r.priority),\n String(r.totalConditionCount),\n String(r.totalActionCount),\n r.isEnabled ? '✓' : '✗',\n ]),\n { truncate: 24 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n rules\n .command('get')\n .description('Get a rule by ID')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--id <ruleId>', 'Rule ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<PolicyRuleDetail>(\n 'GET',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── create ──\n rules\n .command('create')\n .description('Create a new rule')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--json <body>', 'Request body as JSON string')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = JSON.parse(opts.json) as CreateRuleRequest;\n const data = await apiRequest<PolicyRuleDetail>(\n 'POST',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── update ──\n rules\n .command('update')\n .description('Update a rule')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--id <ruleId>', 'Rule ID')\n .requiredOption('--json <body>', 'Request body as JSON string')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = JSON.parse(opts.json) as UpdateRuleRequest;\n const data = await apiRequest<PolicyRuleDetail>(\n 'PUT',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── delete ──\n rules\n .command('delete')\n .description('Delete a rule')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--id <ruleId>', 'Rule ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Delete rule ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Rule ${opts.id} deleted.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── reorder ──\n rules\n .command('reorder')\n .description('Reorder rules by priority (drag & drop equivalent)')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--rule-ids <ids>', 'Comma-separated rule IDs in desired order')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const ruleIds = (opts.ruleIds as string).split(',').map((id: string) => id.trim());\n\n const body: ReorderRulesRequest = {\n rules: ruleIds.map((ruleId, index) => ({\n ruleId,\n priority: index,\n })),\n };\n\n await apiRequest<void>(\n 'PATCH',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules/reorder`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n console.log(`✓ ${ruleIds.length} rules reordered.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── toggle ──\n rules\n .command('toggle')\n .description('Enable or disable a rule')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .requiredOption('--id <ruleId>', 'Rule ID')\n .requiredOption('--enabled <boolean>', 'true or false')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const isEnabled = opts.enabled === 'true';\n\n await apiRequest<void>(\n 'PATCH',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/rules/${opts.id}/enabled`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { isEnabled },\n }\n );\n console.log(`✓ Rule ${opts.id} ${isEnabled ? 'enabled' : 'disabled'}.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { FactSchemaResponse } from '@/types/facts';\n\nexport function registerFactCommands(program: Command): void {\n const facts = program.command('facts').description('Manage fact definitions (schema)');\n\n // ── list ──\n facts\n .command('list')\n .description('List fact definitions')\n .option('--keyword <keyword>', 'Filter by keyword')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.keyword) params.keyword = opts.keyword;\n\n const data = await apiRequest<PageResponse<FactSchemaResponse>>(\n 'GET',\n 'schema/facts',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Key', 'Name', 'Type', 'System', 'Required'],\n data.content.map((f) => [\n f.id,\n f.key,\n f.name,\n f.type,\n f.isSystem ? '✓' : '–',\n f.isRequired ? '✓' : '–',\n ]),\n { truncate: 28 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── create ──\n facts\n .command('create')\n .description('Create a new fact definition')\n .option('--key <key>', 'Fact key (lowercase, underscores)')\n .option('--name <name>', 'Display name')\n .option('--type <type>', 'Value type: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER')\n .option('--description <desc>', 'Description')\n .option('--required', 'Mark as required', false)\n .option('--json <body>', 'Full request body as JSON (overrides other options)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = opts.json\n ? JSON.parse(opts.json)\n : buildCreateBody(opts);\n\n const data = await apiRequest<FactSchemaResponse>(\n 'POST',\n 'schema/facts',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── update ──\n facts\n .command('update')\n .description('Update a fact definition')\n .requiredOption('--id <factId>', 'Fact definition ID')\n .option('--name <name>', 'Display name')\n .option('--description <desc>', 'Description')\n .option('--required', 'Mark as required')\n .option('--no-required', 'Mark as not required')\n .option('--json <body>', 'Full request body as JSON (overrides other options)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = opts.json\n ? JSON.parse(opts.json)\n : buildUpdateBody(opts);\n\n const data = await apiRequest<FactSchemaResponse>(\n 'PUT',\n `schema/facts/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── delete ──\n facts\n .command('delete')\n .description('Delete a fact definition')\n .requiredOption('--id <factId>', 'Fact definition ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Delete fact ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `schema/facts/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Fact ${opts.id} deleted.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── action-metadata ──\n facts\n .command('action-metadata')\n .description('Get action runtime fact metadata')\n .action(async () => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<unknown>(\n 'GET',\n 'schema/action-metadata',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}\n\n// ── Helpers ──\n\nfunction buildCreateBody(opts: Record<string, string | boolean | undefined>): Record<string, unknown> {\n if (!opts.key || !opts.name || !opts.type) {\n throw new Error('--key, --name, and --type are required (or use --json).');\n }\n const body: Record<string, unknown> = {\n key: opts.key,\n name: opts.name,\n type: opts.type,\n isRequired: opts.required === true,\n };\n if (opts.description) body.description = opts.description;\n return body;\n}\n\nfunction buildUpdateBody(opts: Record<string, string | boolean | undefined>): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (opts.name) body.name = opts.name;\n if (opts.description !== undefined) body.description = opts.description;\n if (typeof opts.required === 'boolean') body.isRequired = opts.required;\n return body;\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { DeploymentSummary, DeploymentDetail, DeploymentStatus } from '@/types/deploy';\n\nexport function registerDeployCommands(program: Command): void {\n const deploy = program.command('deploy').description('Deployment lifecycle and history');\n\n // ── publish ──\n deploy\n .command('publish')\n .description('Publish a DRAFT version (DRAFT → ACTIVE)')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Version ID to publish')\n .option('--memo <memo>', 'Deployment memo')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n await apiRequest<void>(\n 'POST',\n `policy-groups/${opts.groupId}/versions/${opts.versionId}/publish`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { memo: opts.memo ?? '' },\n }\n );\n console.log(`✓ Version ${opts.versionId} published.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── live ──\n deploy\n .command('live')\n .description('Deploy an ACTIVE version to live traffic')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Version ID to deploy')\n .option('--memo <memo>', 'Deployment memo')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n await apiRequest<void>(\n 'POST',\n `policy-groups/${opts.groupId}/deploy`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { versionId: opts.versionId, memo: opts.memo ?? '' },\n }\n );\n console.log(`✓ Version ${opts.versionId} deployed to live.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── rollback ──\n deploy\n .command('rollback')\n .description('Rollback to the previous deployed version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .option('--memo <memo>', 'Rollback reason')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Rollback group ${opts.groupId}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'POST',\n `policy-groups/${opts.groupId}/rollback`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { memo: opts.memo ?? '' },\n }\n );\n console.log(`✓ Group ${opts.groupId} rolled back.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── undeploy ──\n deploy\n .command('undeploy')\n .description('Remove the live version from a group')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .option('--memo <memo>', 'Undeploy reason')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Undeploy group ${opts.groupId}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'POST',\n `policy-groups/${opts.groupId}/undeploy`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { memo: opts.memo ?? '' },\n }\n );\n console.log(`✓ Group ${opts.groupId} undeployed.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── history ──\n deploy\n .command('history')\n .description('List deployment history')\n .option('--group-id <groupId>', 'Filter by policy group')\n .option('--types <types>', 'Filter by types (comma-separated: PUBLISH,DEPLOY,ROLLBACK,UNDEPLOY)')\n .option('--start-date <date>', 'Start date (yyyy-MM-dd)')\n .option('--end-date <date>', 'End date (yyyy-MM-dd)')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.groupId) params.groupId = opts.groupId;\n if (opts.types) params.types = opts.types;\n if (opts.startDate) params.startDate = opts.startDate;\n if (opts.endDate) params.endDate = opts.endDate;\n\n const data = await apiRequest<PageResponse<DeploymentSummary>>(\n 'GET',\n 'deployments',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Type', 'Group', 'Version', 'By', 'At'],\n data.content.map((d) => [\n d.id.substring(0, 8),\n d.deploymentType,\n d.policyGroupName,\n d.versionNo != null ? `v${d.versionNo}` : '–',\n d.deployedByName,\n d.deployedAt.substring(0, 16),\n ]),\n { truncate: 20 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── detail ──\n deploy\n .command('detail')\n .description('Get deployment detail')\n .requiredOption('--id <deploymentId>', 'Deployment ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<DeploymentDetail>(\n 'GET',\n `deployments/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── overview ──\n deploy\n .command('overview')\n .description('Show deployment status overview for all groups')\n .action(async () => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const data = await apiRequest<DeploymentStatus[]>(\n 'GET',\n 'deployments/overview',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['Group', 'Name', 'Status', 'Current Version', 'Last Deploy'],\n data.map((d) => [\n d.groupId.substring(0, 8),\n d.groupName,\n d.groupStatus,\n d.currentVersionName ?? '–',\n d.lastDeployedAt?.substring(0, 16) ?? '–',\n ])\n );\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── deployable ──\n deploy\n .command('deployable')\n .description('List deployable (ACTIVE) versions for a group')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<unknown[]>(\n 'GET',\n `deployments/groups/${opts.groupId}/deployable-versions`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── diff ──\n deploy\n .command('diff')\n .description('Compare snapshot diff between two versions')\n .requiredOption('--base <versionId>', 'Base version ID')\n .requiredOption('--target <versionId>', 'Target version ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<unknown>(\n 'GET',\n 'deployments/diff',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: {\n baseVersionId: opts.base,\n targetVersionId: opts.target,\n },\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { readFileSync } from 'node:fs';\nimport { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type {\n DryRunResponse,\n RequirementsResponse,\n SimulationHistoryResponse,\n SimulationResponse,\n} from '@/types/analytics';\n\nexport function registerAnalyticsCommands(program: Command): void {\n const analytics = program.command('analytics').description('Dry run, simulation, and requirements');\n\n // ══════════════════════════════════════════════════\n // Dry Run\n // ══════════════════════════════════════════════════\n\n analytics\n .command('dry-run')\n .description('Execute a single dry run against a version')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .option('--json <body>', 'Request body as JSON string')\n .option('--file <path>', 'Read request body from a JSON file')\n .option('--debug', 'Include debug traces', false)\n .option('--mock', 'Mock external calls', false)\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = resolveBody(opts);\n\n if (!body.facts) {\n throw new Error('Request body must include \"facts\". Use --json or --file.');\n }\n\n body.includeDebugInfo = opts.debug;\n body.mockExternalCalls = opts.mock;\n\n const data = await apiRequest<DryRunResponse>(\n 'POST',\n `analytics/dry-run/versions/${opts.versionId}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ══════════════════════════════════════════════════\n // Dry Run Compare\n // ══════════════════════════════════════════════════\n\n analytics\n .command('dry-run-compare')\n .description('Compare dry run results between two versions')\n .option('--json <body>', 'Request body as JSON string')\n .option('--file <path>', 'Read request body from a JSON file')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = resolveBody(opts);\n\n if (!body.facts || !body.versionIdA || !body.versionIdB) {\n throw new Error('Request body must include \"facts\", \"versionIdA\", \"versionIdB\". Use --json or --file.');\n }\n\n const data = await apiRequest<unknown>(\n 'POST',\n 'analytics/dry-run/compare',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ══════════════════════════════════════════════════\n // Requirements\n // ══════════════════════════════════════════════════\n\n analytics\n .command('requirements')\n .description('Analyze required input facts for a version')\n .requiredOption('--group-id <groupId>', 'Policy group ID')\n .requiredOption('--version-id <versionId>', 'Policy version ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const data = await apiRequest<RequirementsResponse>(\n 'GET',\n `analytics/groups/${opts.groupId}/versions/${opts.versionId}/requirements`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['Key', 'Type', 'Name', 'Required', 'Used By'],\n data.requiredFacts.map((f) => [\n f.key,\n f.type ?? '–',\n f.displayName ?? '–',\n f.required ? '✓' : '–',\n f.usedBy.join(', ') || '–',\n ])\n );\n console.log('\\nExample request:');\n console.log(JSON.stringify(data.exampleRequest, null, 2));\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ══════════════════════════════════════════════════\n // Simulation\n // ══════════════════════════════════════════════════\n\n const sim = analytics.command('simulation').description('Manage batch simulations');\n\n // ── start ──\n sim\n .command('start')\n .description('Start a new batch simulation')\n .requiredOption('--json <body>', 'Simulation request body as JSON')\n .option('--file <path>', 'Read request body from a JSON file')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = resolveBody(opts);\n\n const data = await apiRequest<SimulationResponse>(\n 'POST',\n 'analytics/simulations',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n console.log(`✓ Simulation started: ${data.simulationId} (${data.status})`);\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── status ──\n sim\n .command('status')\n .description('Get simulation status and results')\n .requiredOption('--id <simulationId>', 'Simulation ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<SimulationResponse>(\n 'GET',\n `analytics/simulations/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── list ──\n sim\n .command('list')\n .description('List simulation history')\n .option('--status <status>', 'Filter by status (PENDING, RUNNING, COMPLETED, FAILED, CANCELLED)')\n .option('--from <date>', 'Start date (yyyy-MM-dd)')\n .option('--to <date>', 'End date (yyyy-MM-dd)')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.status) params.status = opts.status;\n if (opts.from) params.from = opts.from;\n if (opts.to) params.to = opts.to;\n\n const data = await apiRequest<PageResponse<SimulationHistoryResponse>>(\n 'GET',\n 'analytics/simulations',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Group', 'Target', 'Status', 'Match', 'Records', 'Created'],\n data.content.map((s) => [\n s.simulationId.substring(0, 8),\n s.policyGroupName,\n s.targetVersionName ?? '–',\n s.status,\n `${(s.matchRate * 100).toFixed(1)}%`,\n String(s.totalRecords),\n s.createdAt.substring(0, 16),\n ]),\n { truncate: 20 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── cancel ──\n sim\n .command('cancel')\n .description('Cancel a running simulation')\n .requiredOption('--id <simulationId>', 'Simulation ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Cancel simulation ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `analytics/simulations/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Simulation ${opts.id} cancelled.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── export ──\n sim\n .command('export')\n .description('Export simulation results')\n .requiredOption('--id <simulationId>', 'Simulation ID')\n .option('--format <fmt>', 'Export format: csv or json', 'json')\n .option('--output <path>', 'Output file path')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const exportFormat = opts.format === 'csv' ? 'csv' : 'json';\n\n const response = await apiRequest<unknown>(\n 'GET',\n `analytics/simulations/${opts.id}/export`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: { format: exportFormat },\n }\n );\n\n if (opts.output) {\n const { writeFileSync } = await import('node:fs');\n const text = typeof response === 'string'\n ? response\n : JSON.stringify(response, null, 2);\n writeFileSync(opts.output, text, 'utf-8');\n console.log(`✓ Exported to ${opts.output}`);\n } else {\n printJson(response);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}\n\n// ── Helpers ──\n\nfunction resolveBody(opts: Record<string, string | boolean | undefined>): Record<string, unknown> {\n if (opts.file) {\n const raw = readFileSync(opts.file as string, 'utf-8');\n return JSON.parse(raw);\n }\n if (opts.json) {\n return JSON.parse(opts.json as string);\n }\n return {};\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { ExecutionHistorySummary, ExecutionHistoryDetail, ExecutionStatsResponse } from '@/types/history';\n\nexport function registerHistoryCommands(program: Command): void {\n const history = program.command('history').description('Execution history');\n\n // ── list ──\n history\n .command('list')\n .description('List execution history')\n .option('--trace-id <traceId>', 'Filter by trace ID')\n .option('--group-id <groupId>', 'Filter by policy group')\n .option('--version-id <versionId>', 'Filter by version')\n .option('--status <status>', 'Filter by status (SUCCESS, NO_MATCH, ERROR, TIMEOUT)')\n .option('--start-date <date>', 'Start date (yyyy-MM-dd)')\n .option('--end-date <date>', 'End date (yyyy-MM-dd)')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.traceId) params.traceId = opts.traceId;\n if (opts.groupId) params.policyGroupId = opts.groupId;\n if (opts.versionId) params.versionId = opts.versionId;\n if (opts.status) params.status = opts.status;\n if (opts.startDate) params.startDate = opts.startDate;\n if (opts.endDate) params.endDate = opts.endDate;\n\n const data = await apiRequest<PageResponse<ExecutionHistorySummary>>(\n 'GET',\n 'execution/history',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['Trace', 'Group', 'Version', 'Status', 'Matched', 'Latency', 'At'],\n data.content.map((h) => [\n h.traceId.substring(0, 12),\n h.policyGroupName ?? '–',\n h.policyVersionNo != null ? `v${h.policyVersionNo}` : '–',\n h.status,\n h.isMatched ? '✓' : '✗',\n `${h.latencyMs}ms`,\n h.createdAt.substring(0, 16),\n ]),\n { truncate: 20 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n history\n .command('get')\n .description('Get execution detail')\n .requiredOption('--id <executionId>', 'Execution history ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<ExecutionHistoryDetail>(\n 'GET',\n `execution/history/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── stats ──\n history\n .command('stats')\n .description('Get execution statistics')\n .option('--group-id <groupId>', 'Filter by policy group')\n .option('--start-date <date>', 'Start date (yyyy-MM-dd)')\n .option('--end-date <date>', 'End date (yyyy-MM-dd)')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {};\n if (opts.groupId) params.policyGroupId = opts.groupId;\n if (opts.startDate) params.startDate = opts.startDate;\n if (opts.endDate) params.endDate = opts.endDate;\n\n const data = await apiRequest<ExecutionStatsResponse>(\n 'GET',\n 'execution/history/stats',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['Total', 'Success', 'No Match', 'Failures', 'Success Rate', 'Avg Latency'],\n [[\n String(data.totalExecutions),\n String(data.successCount),\n String(data.noMatchCount),\n String(data.failureCount),\n `${data.successRate}%`,\n `${data.avgLatencyMs}ms`,\n ]]\n );\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { IntegrationResponse, IntegrationConfigSpecs } from '@/types/integrations';\n\nexport function registerIntegrationCommands(program: Command): void {\n const integrations = program.command('integrations').description('Manage external integrations');\n\n // ── list ──\n integrations\n .command('list')\n .description('List integrations')\n .option('--type <type>', 'Filter by type (COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK)')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.type) params.type = opts.type;\n\n const data = await apiRequest<PageResponse<IntegrationResponse>>(\n 'GET',\n 'integrations',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Name', 'Type', 'URL', 'Active'],\n data.content.map((i) => [\n i.id.substring(0, 8),\n i.name,\n i.type,\n i.baseUrl,\n i.isActive ? '✓' : '✗',\n ]),\n { truncate: 28 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n integrations\n .command('get')\n .description('Get integration detail')\n .requiredOption('--id <integrationId>', 'Integration ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<IntegrationResponse>(\n 'GET',\n `integrations/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── save ──\n integrations\n .command('save')\n .description('Create or update an integration')\n .requiredOption('--json <body>', 'Request body as JSON string')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const body = JSON.parse(opts.json);\n const data = await apiRequest<IntegrationResponse>(\n 'POST',\n 'integrations',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── delete ──\n integrations\n .command('delete')\n .description('Delete an integration')\n .requiredOption('--id <integrationId>', 'Integration ID')\n .option('--force', 'Skip confirmation prompt')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n\n if (!opts.force) {\n const { createInterface } = await import('node:readline/promises');\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Delete integration ${opts.id}? [y/N] `);\n rl.close();\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n\n await apiRequest<void>(\n 'DELETE',\n `integrations/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n console.log(`✓ Integration ${opts.id} deleted.`);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── config-spec ──\n integrations\n .command('config-spec')\n .description('Get integration configuration field specs')\n .action(async () => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<IntegrationConfigSpecs>(\n 'GET',\n 'integrations/config-spec',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { type Command } from 'commander';\nimport { apiRequest } from '@/lib/api-client';\nimport type { PageResponse } from '@/types/api';\nimport { printJson, printTable, printError, type OutputFormat } from '@/lib/output';\nimport type { FailureLogResponse, BulkActionResponse } from '@/types/logs';\n\nexport function registerLogCommands(program: Command): void {\n const logs = program.command('logs').description('Failure logs');\n\n // ── list ──\n logs\n .command('list')\n .description('List failure logs')\n .option('--category <category>', 'Filter by category (INTEGRATION, INTERNAL)')\n .option('--task-type <taskType>', 'Filter by task type (COUPON_ISSUE, POINT_EARN, NOTIFICATION_SEND, WEBHOOK_EXECUTE)')\n .option('--status <status>', 'Filter by status (PENDING, RESOLVED, IGNORED)')\n .option('--keyword <keyword>', 'Search keyword')\n .option('--start-date <date>', 'Start date (yyyy-MM-dd)')\n .option('--end-date <date>', 'End date (yyyy-MM-dd)')\n .option('--page <number>', 'Page number', '0')\n .option('--size <number>', 'Page size', '20')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const format: OutputFormat = globalOpts.format ?? 'json';\n\n const params: Record<string, string> = {\n page: opts.page,\n size: opts.size,\n };\n if (opts.category) params.category = opts.category;\n if (opts.taskType) params.taskType = opts.taskType;\n if (opts.status) params.status = opts.status;\n if (opts.keyword) params.searchKeyword = opts.keyword;\n if (opts.startDate) params.startDate = opts.startDate;\n if (opts.endDate) params.endDate = opts.endDate;\n\n const data = await apiRequest<PageResponse<FailureLogResponse>>(\n 'GET',\n 'failure-logs',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params,\n }\n );\n\n if (format === 'table') {\n printTable(\n ['ID', 'Category', 'Task', 'Status', 'Retries', 'Error', 'Created'],\n data.content.map((l) => [\n l.id.substring(0, 8),\n l.category,\n l.taskType,\n l.status,\n String(l.retryCount),\n l.errorMessage?.substring(0, 24) ?? '–',\n l.createdAt.substring(0, 16),\n ]),\n { truncate: 24 }\n );\n console.log(`\\n${data.totalElements} total · page ${data.pageNo + 1}/${data.totalPages}`);\n } else {\n printJson(data);\n }\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── get ──\n logs\n .command('get')\n .description('Get failure log detail')\n .requiredOption('--id <logId>', 'Log ID')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<FailureLogResponse>(\n 'GET',\n `failure-logs/${opts.id}`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── action ──\n logs\n .command('action')\n .description('Process a failure log action (RETRY, IGNORE, RESOLVE)')\n .requiredOption('--id <logId>', 'Log ID')\n .requiredOption('--action <action>', 'Action: RETRY, IGNORE, or RESOLVE')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const data = await apiRequest<FailureLogResponse>(\n 'POST',\n `failure-logs/${opts.id}/actions`,\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n params: { action: opts.action },\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n\n // ── bulk-action ──\n logs\n .command('bulk-action')\n .description('Bulk process failure logs')\n .requiredOption('--ids <logIds>', 'Comma-separated log IDs')\n .requiredOption('--action <action>', 'Action: RETRY, IGNORE, or RESOLVE')\n .action(async (opts) => {\n try {\n const globalOpts = program.opts();\n const logIds = (opts.ids as string).split(',').map((id: string) => id.trim());\n\n const data = await apiRequest<BulkActionResponse>(\n 'POST',\n 'failure-logs/bulk-actions',\n {\n apiKey: globalOpts.apiKey,\n baseUrl: globalOpts.baseUrl,\n dryRun: globalOpts.dryRun,\n verbose: globalOpts.verbose,\n body: { logIds, action: opts.action },\n }\n );\n printJson(data);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n });\n}","import { createCli } from './cli';\nimport { printError } from './lib/output';\n\nasync function main(): Promise<void> {\n const program = createCli();\n\n try {\n await program.parseAsync(process.argv);\n } catch (error) {\n printError(error);\n process.exit(1);\n }\n}\n\nmain();"],"mappings":"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","names":["readFileSync","join","createInterface","createInterface","createInterface","buildCreateBody","buildUpdateBody","createInterface","createInterface","readFileSync","createInterface","writeFileSync","readFileSync","createInterface","readFileSync","join"]}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@lexq/cli",
3
+ "version": "0.1.0",
4
+ "description": "LexQ CLI — manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.",
5
+ "type": "module",
6
+ "bin": {
7
+ "lexq": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "schemas",
12
+ "skills",
13
+ "AGENTS.md",
14
+ "CONTEXT.md"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "keywords": [
20
+ "lexq",
21
+ "rule-engine",
22
+ "policy-engine",
23
+ "cli",
24
+ "ai-agent",
25
+ "agent-skills",
26
+ "simulation",
27
+ "business-rules"
28
+ ],
29
+ "author": "LexQ, LLC",
30
+ "license": "Apache-2.0",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/sanghyunp-dev/lexq-cli.git"
34
+ },
35
+ "homepage": "https://lexq.io",
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ },
39
+ "dependencies": {
40
+ "commander": "^13.1.0",
41
+ "ora": "^8.2.0",
42
+ "cli-table3": "^0.6.5"
43
+ },
44
+ "devDependencies": {
45
+ "tsup": "^8.4.0",
46
+ "typescript": "^5.7.0",
47
+ "@types/node": "^22.12.0",
48
+ "eslint": "^9.20.0",
49
+ "@eslint/js": "^9.20.0",
50
+ "typescript-eslint": "^8.24.0"
51
+ },
52
+ "scripts": {
53
+ "dev": "tsup --watch",
54
+ "build": "tsup",
55
+ "lint": "eslint src/",
56
+ "typecheck": "tsc --noEmit",
57
+ "start": "node dist/index.js"
58
+ }
59
+ }
@@ -0,0 +1,211 @@
1
+ # LexQ CLI — Execution & Monitoring
2
+
3
+ > **Prerequisite:** Read `lexq-shared/SKILL.md` first.
4
+
5
+ ## Overview
6
+
7
+ Once policies are deployed, the engine evaluates incoming facts against live rules. This skill covers **observing** production behavior: execution history, statistics, failure logs, and integrations.
8
+
9
+ ## 1. Execution History
10
+
11
+ ### List Executions
12
+
13
+ ```bash
14
+ lexq history list --page 0 --size 20
15
+ ```
16
+
17
+ Filter options:
18
+
19
+ | Flag | Description | Example |
20
+ |---|---|---|
21
+ | `--trace-id <id>` | Filter by trace ID | `--trace-id abc123` |
22
+ | `--group-id <id>` | Filter by policy group | `--group-id <gid>` |
23
+ | `--version-id <id>` | Filter by version | `--version-id <vid>` |
24
+ | `--status <status>` | Filter by status | `--status SUCCESS` |
25
+ | `--start-date <date>` | Start date (ISO) | `--start-date 2025-01-01` |
26
+ | `--end-date <date>` | End date (ISO) | `--end-date 2025-01-31` |
27
+
28
+ ### Execution Statuses
29
+
30
+ | Status | Meaning |
31
+ |---|---|
32
+ | `SUCCESS` | At least one rule matched and actions executed |
33
+ | `NO_MATCH` | No rules matched the input facts |
34
+ | `ERROR` | Engine error during evaluation |
35
+ | `TIMEOUT` | Execution exceeded time limit |
36
+
37
+ ### Get Execution Detail
38
+
39
+ ```bash
40
+ lexq history get --id <executionId>
41
+ ```
42
+
43
+ Returns full detail including `requestFacts`, `resultTraces`, and `decisionTraces`.
44
+
45
+ ### Execution Statistics
46
+
47
+ ```bash
48
+ lexq history stats
49
+ ```
50
+
51
+ Returns KPI summary:
52
+
53
+ ```json
54
+ {
55
+ "totalExecutions": 150000,
56
+ "successCount": 142500,
57
+ "noMatchCount": 5000,
58
+ "failureCount": 2500,
59
+ "successRate": 0.95,
60
+ "avgLatencyMs": 8.5
61
+ }
62
+ ```
63
+
64
+ Use stats to monitor:
65
+ - **Success rate** — should be close to 1.0 for well-configured policies
66
+ - **Average latency** — should be single-digit ms under normal load
67
+ - **No-match count** — high values may indicate missing rules or incomplete fact definitions
68
+
69
+ ## 2. Failure Logs
70
+
71
+ System failure logs capture errors from background tasks (batch jobs, webhook calls, scheduled operations).
72
+
73
+ ### List Failure Logs
74
+
75
+ ```bash
76
+ lexq logs list --page 0 --size 20
77
+ ```
78
+
79
+ Filter options:
80
+
81
+ | Flag | Description | Values |
82
+ |---|---|---|
83
+ | `--category <cat>` | Task category | `INTEGRATION`, `INTERNAL` |
84
+ | `--task-type <type>` | Task type | `COUPON_ISSUE`, `POINT_EARN`, `NOTIFICATION_SEND`, `WEBHOOK_EXECUTE` |
85
+ | `--status <status>` | Log status | `PENDING`, `RESOLVED`, `IGNORED` |
86
+ | `--keyword <kw>` | Search in refId, refSubId, errorMessage | any string |
87
+ | `--start-date <date>` | Start date (ISO) | `2025-01-01` |
88
+ | `--end-date <date>` | End date (ISO) | `2025-01-31` |
89
+
90
+ ### Get Failure Log Detail
91
+
92
+ ```bash
93
+ lexq logs get --id <logId>
94
+ ```
95
+
96
+ ### Retry Failed Log
97
+
98
+ ```bash
99
+ lexq logs action --id <logId> --action RETRY
100
+ ```
101
+
102
+ ### Resolve (Mark as Handled)
103
+
104
+ ```bash
105
+ lexq logs action --id <logId> --action RESOLVE
106
+ ```
107
+
108
+ ### Ignore (Skip Retries)
109
+
110
+ ```bash
111
+ lexq logs action --id <logId> --action IGNORE
112
+ ```
113
+
114
+ ### Bulk Operations
115
+
116
+ ```bash
117
+ lexq logs bulk-action --ids "id1,id2,id3" --action RETRY
118
+ lexq logs bulk-action --ids "id1,id2,id3" --action RESOLVE
119
+ ```
120
+
121
+ ## 3. Integrations
122
+
123
+ Integrations connect LexQ actions to external systems (webhooks, CRM, notification services).
124
+
125
+ ### List Integrations
126
+
127
+ ```bash
128
+ lexq integrations list --page 0 --size 10
129
+ ```
130
+
131
+ ### Get Integration
132
+
133
+ ```bash
134
+ lexq integrations get --id <integrationId>
135
+ ```
136
+
137
+ ### Get Config Spec
138
+
139
+ Shows available integration types and their required configuration fields:
140
+
141
+ ```bash
142
+ lexq integrations config-spec
143
+ ```
144
+
145
+ ### Save (Create or Update)
146
+
147
+ ```bash
148
+ lexq integrations save --json '{
149
+ "type": "WEBHOOK",
150
+ "name": "Order Webhook",
151
+ "baseUrl": "https://api.example.com/webhook",
152
+ "isActive": true
153
+ }'
154
+ ```
155
+
156
+ Integration types: `COUPON`, `POINT`, `NOTIFICATION`, `CRM`, `MESSENGER`, `WEBHOOK`
157
+
158
+ ### Delete Integration
159
+
160
+ ```bash
161
+ lexq integrations delete --id <integrationId>
162
+ lexq integrations delete --id <integrationId> --force
163
+ ```
164
+
165
+ ## 4. Deployment Monitoring
166
+
167
+ ### Deployment Overview
168
+
169
+ See all groups' deployment status at a glance:
170
+
171
+ ```bash
172
+ lexq deploy overview
173
+ ```
174
+
175
+ Returns an array with each group's current version, last deployment type, and deployer.
176
+
177
+ ### Deployment History
178
+
179
+ ```bash
180
+ lexq deploy history --page 0 --size 20
181
+ lexq deploy history --group-id <gid>
182
+ lexq deploy history --types DEPLOY,ROLLBACK --start-date 2025-01-01
183
+ ```
184
+
185
+ ### Deployment Detail
186
+
187
+ ```bash
188
+ lexq deploy detail --id <deploymentId>
189
+ ```
190
+
191
+ Includes snapshot hash verification (`hashValid` field) to detect if a version was modified after deployment.
192
+
193
+ ## Agent Monitoring Workflow
194
+
195
+ ```bash
196
+ # 1. Check overall health
197
+ lexq history stats
198
+
199
+ # 2. If failure rate is high, investigate
200
+ lexq history list --status ERROR --page 0 --size 10
201
+
202
+ # 3. Check for system failures
203
+ lexq logs list --status PENDING --page 0 --size 10
204
+
205
+ # 4. Retry or resolve failures
206
+ lexq logs action --id <logId> --action RETRY
207
+ lexq logs action --id <logId> --action RESOLVE
208
+
209
+ # 5. Verify deployment integrity
210
+ lexq deploy overview
211
+ ```