@x12i/ai-tools 1.0.2 → 1.0.3

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 (66) hide show
  1. package/README.md +114 -12
  2. package/dist/{AiModelsCatalogClient-CSVlKql5.d.cts → AiModelsCatalogClient-CNeqFiFs.d.cts} +2 -1
  3. package/dist/{AiModelsCatalogClient-B-dNLXX0.d.ts → AiModelsCatalogClient-nwFoEaqL.d.ts} +2 -1
  4. package/dist/aliases/index.d.cts +4 -3
  5. package/dist/aliases/index.d.ts +4 -3
  6. package/dist/catalog/index.cjs +30 -0
  7. package/dist/catalog/index.cjs.map +1 -0
  8. package/dist/catalog/index.d.cts +100 -0
  9. package/dist/catalog/index.d.ts +100 -0
  10. package/dist/catalog/index.js +30 -0
  11. package/dist/catalog/index.js.map +1 -0
  12. package/dist/catalox/index.cjs +2 -2
  13. package/dist/catalox/index.d.cts +7 -19
  14. package/dist/catalox/index.d.ts +7 -19
  15. package/dist/catalox/index.js +1 -1
  16. package/dist/chunk-C3H7RTFR.cjs +1 -0
  17. package/dist/chunk-C3H7RTFR.cjs.map +1 -0
  18. package/dist/{chunk-ONA73BU6.cjs → chunk-DKHGWHXP.cjs} +21 -12
  19. package/dist/chunk-DKHGWHXP.cjs.map +1 -0
  20. package/dist/{chunk-HHNHWYTP.cjs → chunk-FGP3QXWL.cjs} +94 -36
  21. package/dist/chunk-FGP3QXWL.cjs.map +1 -0
  22. package/dist/chunk-HS74X2OJ.cjs +172 -0
  23. package/dist/chunk-HS74X2OJ.cjs.map +1 -0
  24. package/dist/chunk-HYGXZY25.js +163 -0
  25. package/dist/chunk-HYGXZY25.js.map +1 -0
  26. package/dist/chunk-M5TMA73F.js +1 -0
  27. package/dist/chunk-M5TMA73F.js.map +1 -0
  28. package/dist/chunk-MX3AMQFC.js +172 -0
  29. package/dist/chunk-MX3AMQFC.js.map +1 -0
  30. package/dist/{chunk-MLRHYOCD.js → chunk-VRFVF5RH.js} +21 -12
  31. package/dist/chunk-VRFVF5RH.js.map +1 -0
  32. package/dist/cli/index.cjs +133 -30
  33. package/dist/cli/index.cjs.map +1 -1
  34. package/dist/cli/index.js +134 -31
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cost/index.d.cts +4 -3
  37. package/dist/cost/index.d.ts +4 -3
  38. package/dist/index.cjs +17 -6
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +10 -16
  41. package/dist/index.d.ts +10 -16
  42. package/dist/index.js +22 -11
  43. package/dist/{modelNameResolver-Bn8QnkSj.d.ts → modelNameResolver-D9V_GfUK.d.cts} +3 -27
  44. package/dist/{modelNameResolver-bZD-eBSJ.d.cts → modelNameResolver-DqFt7g6W.d.ts} +3 -27
  45. package/dist/models/index.d.cts +3 -2
  46. package/dist/models/index.d.ts +3 -2
  47. package/dist/sync/index.cjs +3 -3
  48. package/dist/sync/index.d.cts +6 -3
  49. package/dist/sync/index.d.ts +6 -3
  50. package/dist/sync/index.js +2 -2
  51. package/dist/syncAiModelsCatalog-CnXRLm2c.d.cts +32 -0
  52. package/dist/syncAiModelsCatalog-DpkN_w7S.d.ts +32 -0
  53. package/dist/types-BYXnCvKx.d.cts +137 -0
  54. package/dist/types-BYXnCvKx.d.ts +137 -0
  55. package/dist/types-CX6QFNNy.d.cts +144 -0
  56. package/dist/types-CuiPDcVs.d.ts +144 -0
  57. package/dist/upsertAiModelRecord-C831wOIF.d.ts +35 -0
  58. package/dist/upsertAiModelRecord-CjY-sny0.d.cts +35 -0
  59. package/package.json +8 -1
  60. package/dist/chunk-HHNHWYTP.cjs.map +0 -1
  61. package/dist/chunk-ML2FRR4L.js +0 -105
  62. package/dist/chunk-ML2FRR4L.js.map +0 -1
  63. package/dist/chunk-MLRHYOCD.js.map +0 -1
  64. package/dist/chunk-ONA73BU6.cjs.map +0 -1
  65. package/dist/types-DdGB3YaA.d.cts +0 -278
  66. package/dist/types-DdGB3YaA.d.ts +0 -278
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/cli/index.cjs","../../src/cli/index.ts","../../src/cli/commands/alias.ts","../../src/cli/catalox.ts","../../src/cli/env.ts","../../src/cli/commands/catalog.ts","../../src/cli/commands/cost.ts","../../src/cli/commands/models.ts","../../src/cli/commands/sync.ts"],"names":["program"],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { registerAliasCommand } from \"./commands/alias.js\";\nimport { registerCatalogCommand } from \"./commands/catalog.js\";\nimport { registerCostCommand } from \"./commands/cost.js\";\nimport { registerModelsCommand } from \"./commands/models.js\";\nimport { registerSyncCommand } from \"./commands/sync.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"ai-tools\")\n .description(\"@x12i/ai-tools — AI model catalog, cost calculation, and utilities\")\n .version(\"1.0.0\");\n\nregisterSyncCommand(program);\nregisterCatalogCommand(program);\nregisterModelsCommand(program);\nregisterCostCommand(program);\nregisterAliasCommand(program);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { AliasResolver } from \"../../aliases/AliasResolver.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction registry(path?: string) {\n return new AliasRegistry(path ? { aliasesPath: path } : {});\n}\n\nfunction resolver(path?: string) {\n return new AliasResolver({\n registry: registry(path),\n catalogClient: new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: envAppId(),\n catalogId: envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n }),\n });\n}\n\nexport function registerAliasCommand(program: Command): void {\n const alias = program.command(\"alias\").description(\"Manage project-local model aliases\");\n\n alias\n .command(\"init\")\n .description(\"Create an empty ai-tools/aliases.json\")\n .option(\"--path <path>\", \"Custom path\")\n .option(\"--force\", \"Overwrite if already exists\")\n .action((opts: { path?: string; force?: boolean }) => {\n const reg = registry(opts.path);\n if (reg.exists() && !opts.force) {\n console.log(`Aliases file already exists at ${reg.path}`);\n return;\n }\n if (opts.force && reg.exists()) {\n fs.unlinkSync(reg.path);\n }\n reg.init();\n console.log(`✔ Created ${reg.path}`);\n console.log(\n \" Tip: commit this file to your repository so aliases are consistent across environments.\",\n );\n });\n\n alias\n .command(\"set\")\n .description(\"Create or update an alias\")\n .argument(\"<name>\", \"Alias name\")\n .argument(\"<modelId>\", \"Model ID\")\n .option(\"--provider <p>\", \"Provider routing\", \"openrouter\")\n .option(\"--description <d>\", \"Human-readable note\")\n .option(\"--tag <t>\", \"Tag (repeatable)\", (v: string, prev: string[]) => [...prev, v], [] as string[])\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(\n (\n name: string,\n modelId: string,\n opts: { provider: string; description?: string; tag: string[]; path?: string },\n ) => {\n const reg = registry(opts.path);\n if (!reg.exists()) reg.init();\n reg.set(name, {\n modelId,\n provider: opts.provider,\n description: opts.description,\n tags: opts.tag.length ? opts.tag : undefined,\n });\n console.log(`✔ alias \"${name}\" → ${modelId} (via ${opts.provider})`);\n console.log(` Updated ${reg.path}`);\n },\n );\n\n alias\n .command(\"get\")\n .description(\"Show one alias (with catalog resolution when available)\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (name: string, opts: { path?: string }) => {\n const ref = await resolver(opts.path).getModel(name);\n console.log(`Alias: ${ref.alias}`);\n console.log(`Model ID: ${ref.modelId}`);\n console.log(`Provider: ${ref.provider}`);\n if (ref.modelRecord) {\n console.log(`Name: ${ref.name}`);\n console.log(`Context: ${ref.modelRecord.contextLength.toLocaleString()} tokens`);\n console.log(`Status: ${ref.modelRecord.status} ✔`);\n } else {\n console.log(`Catalog: ✘ not found in ai-models catalog (local/custom model)`);\n }\n if (ref.entry.description) console.log(`Description: ${ref.entry.description}`);\n if (ref.entry.tags?.length) console.log(`Tags: ${ref.entry.tags.join(\", \")}`);\n });\n\n alias\n .command(\"list\")\n .description(\"List all aliases\")\n .option(\"--tag <t>\", \"Filter by tag\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--check\", \"Validate each alias against the catalog\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { tag?: string; json?: boolean; check?: boolean; path?: string }) => {\n const reg = registry(opts.path);\n const rows = reg.list(opts.tag ? { tag: opts.tag } : undefined);\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (opts.check) {\n const report = await resolver(opts.path).validate();\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"STATUS\");\n console.log(\"─\".repeat(60));\n for (const e of report.entries) {\n const status =\n e.status === \"ok\" ? \"✔ resolved\" : e.status === \"unknown\" ? \"✘ not in catalog\" : \"✗ broken\";\n console.log(e.name.padEnd(14), e.modelId.padEnd(32), status);\n }\n return;\n }\n\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"PROVIDER\".padEnd(12), \"DESCRIPTION\");\n console.log(\"─\".repeat(90));\n for (const row of rows) {\n console.log(\n row.name.padEnd(14),\n row.modelId.padEnd(32),\n row.provider.padEnd(12),\n (row.description ?? \"\").slice(0, 40),\n );\n }\n });\n\n alias\n .command(\"remove\")\n .description(\"Remove an alias\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--yes\", \"Skip confirmation\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((name: string, opts: { yes?: boolean; path?: string }) => {\n if (!opts.yes) {\n console.log(`Remove alias \"${name}\"? Use --yes to confirm.`);\n process.exit(1);\n }\n const removed = registry(opts.path).remove(name);\n if (removed) console.log(`✔ Removed alias \"${name}\"`);\n else {\n console.error(`Alias not found: ${name}`);\n process.exit(1);\n }\n });\n\n alias\n .command(\"rename\")\n .description(\"Rename an alias\")\n .argument(\"<from>\", \"Current name\")\n .argument(\"<to>\", \"New name\")\n .option(\"--force\", \"Overwrite destination if it exists\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((from: string, to: string, opts: { force?: boolean; path?: string }) => {\n registry(opts.path).rename(from, to, { force: opts.force });\n console.log(`✔ Renamed \"${from}\" → \"${to}\"`);\n });\n\n alias\n .command(\"check\")\n .description(\"Validate all aliases against the catalog (CI-friendly)\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { path?: string }) => {\n const report = await resolver(opts.path).validate();\n console.log(`Checking ${report.total} aliases against ai-models catalog…\\n`);\n\n for (const e of report.entries) {\n const icon = e.status === \"ok\" ? \"✔\" : e.status === \"unknown\" ? \"⚠\" : \"✗\";\n const extra = e.resolvedName ? ` (${e.resolvedName})` : e.issue ? ` (${e.issue})` : \"\";\n console.log(` ${icon} ${e.name.padEnd(12)} → ${e.modelId.padEnd(28)}${extra}`);\n }\n\n console.log(\n `\\n${report.total} total · ${report.ok} ok · ${report.unknown} unknown · ${report.broken} broken`,\n );\n\n if (report.broken > 0) process.exit(1);\n });\n}\n","import { createCataloxFromEnv } from \"@x12i/catalox/firebase\";\nimport type { Catalox } from \"@x12i/catalox\";\nimport type { Firestore } from \"firebase-admin/firestore\";\n\ntype CataloxBundle = {\n catalox: Catalox;\n firestore: Firestore;\n};\n\nlet cached: CataloxBundle | null = null;\n\nexport function getCataloxBundle(): CataloxBundle {\n if (!cached) {\n cached = createCataloxFromEnv();\n }\n return cached;\n}\n\nexport function getCatalox(): Catalox {\n return getCataloxBundle().catalox;\n}\n\nexport function getFirestore(): Firestore {\n return getCataloxBundle().firestore;\n}\n","import { config } from \"dotenv\";\n\nconfig();\n\nexport function envAppId(): string {\n return process.env.AI_TOOLS_APP_ID ?? \"ai-tools\";\n}\n\nexport function envCatalogId(): string {\n return process.env.AI_TOOLS_CATALOG_ID ?? \"ai-models\";\n}\n\nexport function envCacheTtlMs(): number {\n const raw = process.env.AI_TOOLS_CACHE_TTL_MS;\n return raw ? Number.parseInt(raw, 10) : 60 * 60 * 1000;\n}\n","import type { Command } from \"commander\";\nimport { ensureAiModelsCatalog } from \"../../catalog/ensureAiModelsCatalog.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\n\nexport function registerCatalogCommand(program: Command): void {\n const catalog = program.command(\"catalog\").description(\"Catalog bootstrap commands\");\n\n catalog\n .command(\"ensure\")\n .description(\"Create catalog, descriptor, and app binding if missing\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: { app?: string; catalog?: string }) => {\n await ensureAiModelsCatalog(getCatalox(), {\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n });\n console.log(\"✔ ai-models catalog ensured\");\n });\n}\n","import type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { CostCalculator } from \"../../cost/CostCalculator.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction formatUsd(n: number): string {\n return `$${n.toFixed(6)}`;\n}\n\nexport function registerCostCommand(program: Command): void {\n program\n .command(\"cost\")\n .description(\"Estimate cost from catalog pricing\")\n .requiredOption(\"--model <id>\", \"Model ID or alias\")\n .requiredOption(\"--prompt-tokens <n>\", \"Prompt token count\", (v) => Number.parseInt(v, 10))\n .requiredOption(\n \"--completion-tokens <n>\",\n \"Completion token count\",\n (v) => Number.parseInt(v, 10),\n )\n .option(\"--cached-tokens <n>\", \"Cached token count\", (v) => Number.parseInt(v, 10))\n .option(\"--reasoning-tokens <n>\", \"Reasoning token count\", (v) => Number.parseInt(v, 10))\n .option(\"--provider <id>\", \"Provider for OpenRouter delta logic\", \"openrouter\")\n .option(\"--json\", \"Output raw AiCostResult JSON\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n promptTokens: number;\n completionTokens: number;\n cachedTokens?: number;\n reasoningTokens?: number;\n provider: string;\n json?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const catalogClient = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n\n const calculator = new CostCalculator(catalogClient, {\n aliasRegistry: new AliasRegistry(),\n });\n\n const result = await calculator.calculate({\n tokens: {\n prompt: opts.promptTokens,\n completion: opts.completionTokens,\n total: opts.promptTokens + opts.completionTokens,\n cached: opts.cachedTokens,\n reasoning: opts.reasoningTokens,\n },\n provider: opts.provider,\n modelUsed: opts.model,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const b = result.breakdown;\n console.log(`Model: ${result.resolvedModelId}`);\n console.log(\n `Prompt: ${opts.promptTokens.toLocaleString()} tokens → ${formatUsd(b?.promptCostUsd ?? 0)}`,\n );\n console.log(\n `Completion: ${opts.completionTokens.toLocaleString()} tokens → ${formatUsd(b?.completionCostUsd ?? 0)}`,\n );\n console.log(\n `Request fee: → ${formatUsd(b?.requestFlatCostUsd ?? 0)}`,\n );\n console.log(\"─\".repeat(38));\n console.log(`Total: → ${formatUsd(result.cost)}`);\n console.log(\n `Via OpenRouter: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`,\n );\n });\n}\n","import type { Command } from \"commander\";\nimport { AiModelsService } from \"../../models/AiModelsService.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction service(opts: { app?: string; catalog?: string }) {\n return new AiModelsService({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n}\n\nexport function registerModelsCommand(program: Command): void {\n const models = program.command(\"models\").description(\"Inspect ai-models catalog\");\n\n models\n .command(\"list\")\n .description(\"List models with optional filters\")\n .option(\"--provider <id>\", \"Filter by providerId (e.g. openai, anthropic)\")\n .option(\"--output-modality <m>\", \"Filter by output modality (text, image, audio, …)\")\n .option(\"--input-modality <m>\", \"Filter by input modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter (e.g. tools)\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--search <q>\", \"Search name, id, description\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--limit <n>\", \"Max rows\", \"50\")\n .option(\"--offset <n>\", \"Skip rows\", \"0\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n inputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n search?: string;\n json?: boolean;\n limit?: string;\n offset?: string;\n app?: string;\n catalog?: string;\n }) => {\n const { models: rows, total } = await service(opts).listModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n inputModality: opts.inputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n search: opts.search,\n limit: Number.parseInt(opts.limit ?? \"50\", 10),\n offset: Number.parseInt(opts.offset ?? \"0\", 10),\n });\n\n if (opts.json) {\n console.log(JSON.stringify({ total, models: rows }, null, 2));\n return;\n }\n\n console.log(\n \"MODEL ID\".padEnd(42),\n \"PROVIDER\".padEnd(14),\n \"OUTPUT\".padEnd(10),\n \"R\".padEnd(3),\n \"NAME\",\n );\n console.log(\"─\".repeat(104));\n for (const m of rows) {\n console.log(\n m.modelId.padEnd(42),\n m.providerId.padEnd(14),\n m.primaryOutputModality.padEnd(10),\n (m.supportsReasoning ? \"yes\" : \"no\").padEnd(3),\n m.name.slice(0, 40),\n );\n }\n console.log(`\\n${rows.length} shown · ${total} matching`);\n });\n\n models\n .command(\"get\")\n .description(\"Get full model info (OpenRouter mirror) by ID or alias\")\n .argument(\"<modelId>\", \"Model ID or alias\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (modelId: string, opts: { app?: string; catalog?: string }) => {\n const model = await service(opts).getModelInfo(modelId);\n if (!model) {\n console.error(`Model not found: ${modelId}`);\n process.exit(1);\n }\n console.log(JSON.stringify(model, null, 2));\n });\n\n models\n .command(\"resolve\")\n .description(\"Resolve provider + model to canonical id (smart resolver)\")\n .requiredOption(\"--model <m>\", \"Model string (required)\")\n .option(\"--provider <p>\", \"Provider hint (openrouter, openai, …)\")\n .option(\"--threshold <n>\", \"Confidence threshold 0–1\", \"0.6\")\n .option(\"--json\", \"Output raw ModelResolutionResult JSON\")\n .option(\"--verbose\", \"Show strategy trail\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n provider?: string;\n threshold?: string;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const { AiModelsCatalogClient } = await import(\"../../catalox/AiModelsCatalogClient.js\");\n const client = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n const threshold = Number.parseFloat(opts.threshold ?? \"0.6\");\n const result = await client.resolveModel(\n { model: opts.model, provider: opts.provider },\n { confidenceThreshold: threshold },\n );\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n if (!result.found) process.exit(1);\n return;\n }\n\n const providerLabel = opts.provider ?? \"unspecified\";\n console.log(`Input: provider=\"${providerLabel}\" model=\"${opts.model}\"`);\n\n if (opts.verbose) {\n console.log(`Normalised: model=\"${result.found ? result.normalisedInput : opts.model}\"`);\n const strategies = result.found ? result.resolvedVia : result.attemptedStrategies;\n console.log(\"\\nStrategy trail:\");\n for (const s of strategies) {\n console.log(` • ${s}`);\n }\n console.log();\n }\n\n if (!result.found) {\n console.log(\"Result: NOT FOUND\");\n console.log(`Reason: ${result.reason}`);\n if (result.bestRejectedCandidate) {\n console.log(\n `Candidate: ${result.bestRejectedCandidate.modelId} (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)})`,\n );\n } else {\n console.log(\"Candidate: none\");\n }\n console.log('Tip: Run \"ai-tools sync\" or add an alias with \"ai-tools alias set\".');\n process.exit(1);\n return;\n }\n\n console.log(`Resolved: ${result.modelId}`);\n console.log(`Name: ${result.record?.name ?? \"(local / no catalog record)\"}`);\n console.log(`Strategy: ${result.resolvedVia.join(\" → \")}`);\n console.log(`Confidence: ${result.confidence.toFixed(2)}`);\n console.log(`Via OR: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`);\n });\n\n models\n .command(\"count\")\n .description(\"Count models matching filters\")\n .option(\"--provider <id>\", \"Filter by providerId\")\n .option(\"--output-modality <m>\", \"Filter by output modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const n = await service(opts).countModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n });\n console.log(n);\n });\n}\n","import type { Command } from \"commander\";\nimport { syncAiModelsCatalog } from \"../../sync/syncAiModelsCatalog.js\";\nimport { getCatalox, getFirestore } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\n\nexport function registerSyncCommand(program: Command): void {\n program\n .command(\"sync\")\n .description(\"Fetch OpenRouter models (public API, no key required) and upsert into the ai-models catalog\")\n .option(\"--dry-run\", \"Print what would be written without touching Firestore\")\n .option(\"--verbose\", \"Print each model ID as it is upserted\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--force-cache\", \"Invalidate nx-cache before running\")\n .action(async (opts: {\n dryRun?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n forceCache?: boolean;\n }) => {\n const result = await syncAiModelsCatalog({\n catalox: getCatalox(),\n firestore: getFirestore(),\n openRouterApiKey: process.env.OPENROUTER_API_KEY,\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n dryRun: opts.dryRun,\n verbose: opts.verbose,\n forceCache: opts.forceCache,\n });\n\n console.log(\"\\nSync complete\");\n console.log(` Fetched: ${result.fetched}`);\n console.log(` Upserted: ${result.upserted}`);\n console.log(` Skipped: ${result.skipped}`);\n console.log(` Errors: ${result.errors.length}`);\n console.log(` Duration: ${result.durationMs}ms`);\n\n if (result.errors.length > 0) {\n for (const e of result.errors.slice(0, 10)) {\n console.error(` ✗ ${e.modelId}: ${e.error}`);\n }\n process.exit(1);\n }\n });\n}\n"]}
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/cli/index.cjs","../../src/cli/index.ts","../../src/cli/commands/alias.ts","../../src/cli/catalox.ts","../../src/cli/env.ts","../../src/cli/report.ts","../../src/cli/commands/catalog.ts","../../src/cli/commands/cost.ts","../../src/cli/commands/models.ts","../../src/cli/commands/sync.ts"],"names":["program"],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { registerAliasCommand } from \"./commands/alias.js\";\nimport { registerCatalogCommand } from \"./commands/catalog.js\";\nimport { registerCostCommand } from \"./commands/cost.js\";\nimport { registerModelsCommand } from \"./commands/models.js\";\nimport { registerSyncCommand } from \"./commands/sync.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"ai-tools\")\n .description(\"@x12i/ai-tools — AI model catalog, cost calculation, and utilities\")\n .version(\"1.0.0\");\n\nregisterSyncCommand(program);\nregisterCatalogCommand(program);\nregisterModelsCommand(program);\nregisterCostCommand(program);\nregisterAliasCommand(program);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { AliasResolver } from \"../../aliases/AliasResolver.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction registry(path?: string) {\n return new AliasRegistry(path ? { aliasesPath: path } : {});\n}\n\nfunction resolver(path?: string) {\n return new AliasResolver({\n registry: registry(path),\n catalogClient: new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: envAppId(),\n catalogId: envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n }),\n });\n}\n\nexport function registerAliasCommand(program: Command): void {\n const alias = program.command(\"alias\").description(\"Manage project-local model aliases\");\n\n alias\n .command(\"init\")\n .description(\"Create an empty ai-tools/aliases.json\")\n .option(\"--path <path>\", \"Custom path\")\n .option(\"--force\", \"Overwrite if already exists\")\n .action((opts: { path?: string; force?: boolean }) => {\n const reg = registry(opts.path);\n if (reg.exists() && !opts.force) {\n console.log(`Aliases file already exists at ${reg.path}`);\n return;\n }\n if (opts.force && reg.exists()) {\n fs.unlinkSync(reg.path);\n }\n reg.init();\n console.log(`✔ Created ${reg.path}`);\n console.log(\n \" Tip: commit this file to your repository so aliases are consistent across environments.\",\n );\n });\n\n alias\n .command(\"set\")\n .description(\"Create or update an alias\")\n .argument(\"<name>\", \"Alias name\")\n .argument(\"<modelId>\", \"Model ID\")\n .option(\"--provider <p>\", \"Provider routing\", \"openrouter\")\n .option(\"--description <d>\", \"Human-readable note\")\n .option(\"--tag <t>\", \"Tag (repeatable)\", (v: string, prev: string[]) => [...prev, v], [] as string[])\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(\n (\n name: string,\n modelId: string,\n opts: { provider: string; description?: string; tag: string[]; path?: string },\n ) => {\n const reg = registry(opts.path);\n if (!reg.exists()) reg.init();\n reg.set(name, {\n modelId,\n provider: opts.provider,\n description: opts.description,\n tags: opts.tag.length ? opts.tag : undefined,\n });\n console.log(`✔ alias \"${name}\" → ${modelId} (via ${opts.provider})`);\n console.log(` Updated ${reg.path}`);\n },\n );\n\n alias\n .command(\"get\")\n .description(\"Show one alias (with catalog resolution when available)\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (name: string, opts: { path?: string }) => {\n const ref = await resolver(opts.path).getModel(name);\n console.log(`Alias: ${ref.alias}`);\n console.log(`Model ID: ${ref.modelId}`);\n console.log(`Provider: ${ref.provider}`);\n if (ref.modelRecord) {\n console.log(`Name: ${ref.name}`);\n console.log(`Context: ${ref.modelRecord.contextLength.toLocaleString()} tokens`);\n console.log(`Status: ${ref.modelRecord.status} ✔`);\n } else {\n console.log(`Catalog: ✘ not found in ai-models catalog (local/custom model)`);\n }\n if (ref.entry.description) console.log(`Description: ${ref.entry.description}`);\n if (ref.entry.tags?.length) console.log(`Tags: ${ref.entry.tags.join(\", \")}`);\n });\n\n alias\n .command(\"list\")\n .description(\"List all aliases\")\n .option(\"--tag <t>\", \"Filter by tag\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--check\", \"Validate each alias against the catalog\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { tag?: string; json?: boolean; check?: boolean; path?: string }) => {\n const reg = registry(opts.path);\n const rows = reg.list(opts.tag ? { tag: opts.tag } : undefined);\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (opts.check) {\n const report = await resolver(opts.path).validate();\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"STATUS\");\n console.log(\"─\".repeat(60));\n for (const e of report.entries) {\n const status =\n e.status === \"ok\" ? \"✔ resolved\" : e.status === \"unknown\" ? \"✘ not in catalog\" : \"✗ broken\";\n console.log(e.name.padEnd(14), e.modelId.padEnd(32), status);\n }\n return;\n }\n\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"PROVIDER\".padEnd(12), \"DESCRIPTION\");\n console.log(\"─\".repeat(90));\n for (const row of rows) {\n console.log(\n row.name.padEnd(14),\n row.modelId.padEnd(32),\n row.provider.padEnd(12),\n (row.description ?? \"\").slice(0, 40),\n );\n }\n });\n\n alias\n .command(\"remove\")\n .description(\"Remove an alias\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--yes\", \"Skip confirmation\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((name: string, opts: { yes?: boolean; path?: string }) => {\n if (!opts.yes) {\n console.log(`Remove alias \"${name}\"? Use --yes to confirm.`);\n process.exit(1);\n }\n const removed = registry(opts.path).remove(name);\n if (removed) console.log(`✔ Removed alias \"${name}\"`);\n else {\n console.error(`Alias not found: ${name}`);\n process.exit(1);\n }\n });\n\n alias\n .command(\"rename\")\n .description(\"Rename an alias\")\n .argument(\"<from>\", \"Current name\")\n .argument(\"<to>\", \"New name\")\n .option(\"--force\", \"Overwrite destination if it exists\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((from: string, to: string, opts: { force?: boolean; path?: string }) => {\n registry(opts.path).rename(from, to, { force: opts.force });\n console.log(`✔ Renamed \"${from}\" → \"${to}\"`);\n });\n\n alias\n .command(\"check\")\n .description(\"Validate all aliases against the catalog (CI-friendly)\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { path?: string }) => {\n const report = await resolver(opts.path).validate();\n console.log(`Checking ${report.total} aliases against ai-models catalog…\\n`);\n\n for (const e of report.entries) {\n const icon = e.status === \"ok\" ? \"✔\" : e.status === \"unknown\" ? \"⚠\" : \"✗\";\n const extra = e.resolvedName ? ` (${e.resolvedName})` : e.issue ? ` (${e.issue})` : \"\";\n console.log(` ${icon} ${e.name.padEnd(12)} → ${e.modelId.padEnd(28)}${extra}`);\n }\n\n console.log(\n `\\n${report.total} total · ${report.ok} ok · ${report.unknown} unknown · ${report.broken} broken`,\n );\n\n if (report.broken > 0) process.exit(1);\n });\n}\n","import { createCataloxFromEnv } from \"@x12i/catalox/firebase\";\nimport type { Catalox } from \"@x12i/catalox\";\nimport type { Firestore } from \"firebase-admin/firestore\";\n\ntype CataloxBundle = {\n catalox: Catalox;\n firestore: Firestore;\n};\n\nlet cached: CataloxBundle | null = null;\n\nexport function getCataloxBundle(): CataloxBundle {\n if (!cached) {\n cached = createCataloxFromEnv();\n }\n return cached;\n}\n\nexport function getCatalox(): Catalox {\n return getCataloxBundle().catalox;\n}\n\nexport function getFirestore(): Firestore {\n return getCataloxBundle().firestore;\n}\n","import { config } from \"dotenv\";\n\nconfig();\n\nexport function envAppId(): string {\n return process.env.AI_TOOLS_APP_ID ?? \"ai-tools\";\n}\n\nexport function envCatalogId(): string {\n return process.env.AI_TOOLS_CATALOG_ID ?? \"ai-models\";\n}\n\nexport function envCacheTtlMs(): number {\n const raw = process.env.AI_TOOLS_CACHE_TTL_MS;\n return raw ? Number.parseInt(raw, 10) : 60 * 60 * 1000;\n}\n","export function emitJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function emitHuman(lines: string[]): void {\n for (const line of lines) {\n console.log(line);\n }\n}\n\nexport function formatSyncJobReport(result: {\n ok: boolean;\n sync: {\n fetched: number;\n upserted: number;\n skipped: number;\n errors: Array<{ modelId: string; error: string }>;\n durationMs: number;\n };\n verify?: {\n ok: boolean;\n openRouterCount: number;\n cataloxCount: number;\n missingInCatalox: string[];\n extraInCatalox: string[];\n durationMs: number;\n };\n prune?: { pruned: number; scanned: number };\n}): string[] {\n const lines = [\n \"\",\n result.ok ? \"✔ Catalog sync job succeeded\" : \"✗ Catalog sync job failed\",\n \"\",\n \"Sync\",\n ` Fetched: ${result.sync.fetched}`,\n ` Upserted: ${result.sync.upserted}`,\n ` Skipped: ${result.sync.skipped}`,\n ` Errors: ${result.sync.errors.length}`,\n ` Duration: ${result.sync.durationMs}ms`,\n ];\n\n if (result.verify) {\n lines.push(\n \"\",\n \"Verify\",\n ` Status: ${result.verify.ok ? \"ok\" : \"FAILED\"}`,\n ` OpenRouter: ${result.verify.openRouterCount}`,\n ` Catalox: ${result.verify.cataloxCount}`,\n ` Missing: ${result.verify.missingInCatalox.length}`,\n ` Extra: ${result.verify.extraInCatalox.length}`,\n ` Duration: ${result.verify.durationMs}ms`,\n );\n if (result.verify.missingInCatalox.length > 0) {\n lines.push(` Sample missing: ${result.verify.missingInCatalox.join(\", \")}`);\n }\n if (result.verify.extraInCatalox.length > 0) {\n lines.push(` Sample extra: ${result.verify.extraInCatalox.join(\", \")}`);\n }\n }\n\n if (result.prune) {\n lines.push(\"\", \"Prune\", ` Scanned: ${result.prune.scanned}`, ` Removed: ${result.prune.pruned}`);\n }\n\n return lines;\n}\n","import type { Command } from \"commander\";\nimport { ensureAiModelsCatalog } from \"../../catalog/ensureAiModelsCatalog.js\";\nimport { verifyAiModelsCatalog } from \"../../catalog/verifyAiModelsCatalog.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\nimport { emitHuman, emitJson } from \"../report.js\";\n\nexport function registerCatalogCommand(program: Command): void {\n const catalog = program.command(\"catalog\").description(\"Catalog bootstrap and health commands\");\n\n catalog\n .command(\"ensure\")\n .description(\"Create catalog, descriptor, and app binding if missing\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .action(async (opts: { app?: string; catalog?: string; json?: boolean }) => {\n const appId = opts.app ?? envAppId();\n const catalogId = opts.catalog ?? envCatalogId();\n await ensureAiModelsCatalog(getCatalox(), { appId, catalogId });\n if (opts.json) {\n emitJson({ ok: true, appId, catalogId, action: \"ensure\" });\n } else {\n console.log(\"✔ ai-models catalog ensured\");\n }\n });\n\n catalog\n .command(\"verify\")\n .description(\"Health check: compare Catalox ai-models against the live OpenRouter catalog\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .action(async (opts: { app?: string; catalog?: string; json?: boolean }) => {\n const report = await verifyAiModelsCatalog({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n });\n\n if (opts.json) {\n emitJson(report);\n } else {\n emitHuman([\n report.ok ? \"✔ Catalog verification passed\" : \"✗ Catalog verification FAILED\",\n ` OpenRouter models: ${report.openRouterCount}`,\n ` Catalox models: ${report.cataloxCount}`,\n ` Missing in Catalox: ${report.missingInCatalox.length}`,\n ` Extra in Catalox: ${report.extraInCatalox.length}`,\n ` Duration: ${report.durationMs}ms`,\n ]);\n if (report.missingInCatalox.length > 0) {\n console.log(` Sample missing: ${report.missingInCatalox.join(\", \")}`);\n }\n if (report.extraInCatalox.length > 0) {\n console.log(` Sample extra: ${report.extraInCatalox.join(\", \")}`);\n }\n }\n\n if (!report.ok) {\n process.exit(1);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { CostCalculator } from \"../../cost/CostCalculator.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction formatUsd(n: number): string {\n return `$${n.toFixed(6)}`;\n}\n\nexport function registerCostCommand(program: Command): void {\n program\n .command(\"cost\")\n .description(\"Estimate cost from catalog pricing\")\n .requiredOption(\"--model <id>\", \"Model ID or alias\")\n .requiredOption(\"--prompt-tokens <n>\", \"Prompt token count\", (v) => Number.parseInt(v, 10))\n .requiredOption(\n \"--completion-tokens <n>\",\n \"Completion token count\",\n (v) => Number.parseInt(v, 10),\n )\n .option(\"--cached-tokens <n>\", \"Cached token count\", (v) => Number.parseInt(v, 10))\n .option(\"--reasoning-tokens <n>\", \"Reasoning token count\", (v) => Number.parseInt(v, 10))\n .option(\"--provider <id>\", \"Provider for OpenRouter delta logic\", \"openrouter\")\n .option(\"--json\", \"Output raw AiCostResult JSON\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n promptTokens: number;\n completionTokens: number;\n cachedTokens?: number;\n reasoningTokens?: number;\n provider: string;\n json?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const catalogClient = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n\n const calculator = new CostCalculator(catalogClient, {\n aliasRegistry: new AliasRegistry(),\n });\n\n const result = await calculator.calculate({\n tokens: {\n prompt: opts.promptTokens,\n completion: opts.completionTokens,\n total: opts.promptTokens + opts.completionTokens,\n cached: opts.cachedTokens,\n reasoning: opts.reasoningTokens,\n },\n provider: opts.provider,\n modelUsed: opts.model,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const b = result.breakdown;\n console.log(`Model: ${result.resolvedModelId}`);\n console.log(\n `Prompt: ${opts.promptTokens.toLocaleString()} tokens → ${formatUsd(b?.promptCostUsd ?? 0)}`,\n );\n console.log(\n `Completion: ${opts.completionTokens.toLocaleString()} tokens → ${formatUsd(b?.completionCostUsd ?? 0)}`,\n );\n console.log(\n `Request fee: → ${formatUsd(b?.requestFlatCostUsd ?? 0)}`,\n );\n console.log(\"─\".repeat(38));\n console.log(`Total: → ${formatUsd(result.cost)}`);\n console.log(\n `Via OpenRouter: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`,\n );\n });\n}\n","import type { Command } from \"commander\";\nimport { AiModelsService } from \"../../models/AiModelsService.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction service(opts: { app?: string; catalog?: string }) {\n return new AiModelsService({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n}\n\nexport function registerModelsCommand(program: Command): void {\n const models = program.command(\"models\").description(\"Inspect ai-models catalog\");\n\n models\n .command(\"list\")\n .description(\"List models with optional filters\")\n .option(\"--provider <id>\", \"Filter by providerId (e.g. openai, anthropic)\")\n .option(\"--output-modality <m>\", \"Filter by output modality (text, image, audio, …)\")\n .option(\"--input-modality <m>\", \"Filter by input modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter (e.g. tools)\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--search <q>\", \"Search name, id, description\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--limit <n>\", \"Max rows\", \"50\")\n .option(\"--offset <n>\", \"Skip rows\", \"0\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n inputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n search?: string;\n json?: boolean;\n limit?: string;\n offset?: string;\n app?: string;\n catalog?: string;\n }) => {\n const { models: rows, total } = await service(opts).listModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n inputModality: opts.inputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n search: opts.search,\n limit: Number.parseInt(opts.limit ?? \"50\", 10),\n offset: Number.parseInt(opts.offset ?? \"0\", 10),\n });\n\n if (opts.json) {\n console.log(JSON.stringify({ total, models: rows }, null, 2));\n return;\n }\n\n console.log(\n \"MODEL ID\".padEnd(42),\n \"PROVIDER\".padEnd(14),\n \"OUTPUT\".padEnd(10),\n \"R\".padEnd(3),\n \"NAME\",\n );\n console.log(\"─\".repeat(104));\n for (const m of rows) {\n console.log(\n m.modelId.padEnd(42),\n m.providerId.padEnd(14),\n m.primaryOutputModality.padEnd(10),\n (m.supportsReasoning ? \"yes\" : \"no\").padEnd(3),\n m.name.slice(0, 40),\n );\n }\n console.log(`\\n${rows.length} shown · ${total} matching`);\n });\n\n models\n .command(\"get\")\n .description(\"Get full model info (OpenRouter mirror) by ID or alias\")\n .argument(\"<modelId>\", \"Model ID or alias\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (modelId: string, opts: { app?: string; catalog?: string }) => {\n const model = await service(opts).getModelInfo(modelId);\n if (!model) {\n console.error(`Model not found: ${modelId}`);\n process.exit(1);\n }\n console.log(JSON.stringify(model, null, 2));\n });\n\n models\n .command(\"resolve\")\n .description(\"Resolve provider + model to canonical id (smart resolver)\")\n .requiredOption(\"--model <m>\", \"Model string (required)\")\n .option(\"--provider <p>\", \"Provider hint (openrouter, openai, …)\")\n .option(\"--threshold <n>\", \"Confidence threshold 0–1\", \"0.6\")\n .option(\"--json\", \"Output raw ModelResolutionResult JSON\")\n .option(\"--verbose\", \"Show strategy trail\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n provider?: string;\n threshold?: string;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const { AiModelsCatalogClient } = await import(\"../../catalox/AiModelsCatalogClient.js\");\n const client = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n const threshold = Number.parseFloat(opts.threshold ?? \"0.6\");\n const result = await client.resolveModel(\n { model: opts.model, provider: opts.provider },\n { confidenceThreshold: threshold },\n );\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n if (!result.found) process.exit(1);\n return;\n }\n\n const providerLabel = opts.provider ?? \"unspecified\";\n console.log(`Input: provider=\"${providerLabel}\" model=\"${opts.model}\"`);\n\n if (opts.verbose) {\n console.log(`Normalised: model=\"${result.found ? result.normalisedInput : opts.model}\"`);\n const strategies = result.found ? result.resolvedVia : result.attemptedStrategies;\n console.log(\"\\nStrategy trail:\");\n for (const s of strategies) {\n console.log(` • ${s}`);\n }\n console.log();\n }\n\n if (!result.found) {\n console.log(\"Result: NOT FOUND\");\n console.log(`Reason: ${result.reason}`);\n if (result.bestRejectedCandidate) {\n console.log(\n `Candidate: ${result.bestRejectedCandidate.modelId} (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)})`,\n );\n } else {\n console.log(\"Candidate: none\");\n }\n console.log('Tip: Run \"ai-tools sync\" or add an alias with \"ai-tools alias set\".');\n process.exit(1);\n return;\n }\n\n console.log(`Resolved: ${result.modelId}`);\n console.log(`Name: ${result.record?.name ?? \"(local / no catalog record)\"}`);\n console.log(`Strategy: ${result.resolvedVia.join(\" → \")}`);\n console.log(`Confidence: ${result.confidence.toFixed(2)}`);\n console.log(`Via OR: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`);\n });\n\n models\n .command(\"count\")\n .description(\"Count models matching filters\")\n .option(\"--provider <id>\", \"Filter by providerId\")\n .option(\"--output-modality <m>\", \"Filter by output modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const n = await service(opts).countModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n });\n console.log(n);\n });\n}\n","import type { Command } from \"commander\";\nimport { runAiModelsCatalogSync, CatalogSyncJobError } from \"../../catalog/runAiModelsCatalogSync.js\";\nimport { getCatalox, getFirestore } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\nimport { emitHuman, emitJson, formatSyncJobReport } from \"../report.js\";\n\nexport function registerSyncCommand(program: Command): void {\n program\n .command(\"sync\")\n .description(\n \"Production sync: fetch OpenRouter models, upsert into Catalox/Firestore, verify completeness\",\n )\n .option(\"--dry-run\", \"Fetch and validate without writing to Firestore\")\n .option(\"--no-verify\", \"Skip post-sync verification (not recommended in production)\")\n .option(\"--prune-stale\", \"Remove catalog rows no longer on OpenRouter\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .option(\"--verbose\", \"Log fetch URL and upsert progress\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--force-cache\", \"Invalidate nx-cache before running\")\n .action(\n async (opts: {\n dryRun?: boolean;\n verify?: boolean;\n pruneStale?: boolean;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n forceCache?: boolean;\n }) => {\n const verifyAfter = opts.verify !== false;\n\n try {\n const result = await runAiModelsCatalogSync({\n catalox: getCatalox(),\n firestore: getFirestore(),\n openRouterApiKey: process.env.OPENROUTER_API_KEY,\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n dryRun: opts.dryRun,\n verbose: opts.verbose,\n forceCache: opts.forceCache,\n verifyAfter,\n pruneStale: opts.pruneStale,\n onProgress: opts.verbose\n ? ({ completed, total, phase }) => {\n console.log(`[sync] ${phase} ${completed}/${total}`);\n }\n : undefined,\n });\n\n if (opts.json) {\n emitJson(result);\n } else {\n emitHuman(formatSyncJobReport(result));\n }\n\n if (!result.ok) {\n process.exit(1);\n }\n } catch (error) {\n if (error instanceof CatalogSyncJobError) {\n const payload = {\n ok: false,\n sync: error.sync,\n verify: error.verify,\n };\n if (opts.json) {\n emitJson(payload);\n } else {\n emitHuman(formatSyncJobReport(payload));\n }\n process.exit(1);\n }\n throw error;\n }\n },\n );\n}\n"]}
package/dist/cli/index.js CHANGED
@@ -2,11 +2,6 @@
2
2
  import {
3
3
  CostCalculator
4
4
  } from "../chunk-YHO57D2V.js";
5
- import {
6
- ensureAiModelsCatalog,
7
- syncAiModelsCatalog
8
- } from "../chunk-MLRHYOCD.js";
9
- import "../chunk-ML2FRR4L.js";
10
5
  import {
11
6
  AliasRegistry,
12
7
  AliasResolver
@@ -14,6 +9,15 @@ import {
14
9
  import {
15
10
  AiModelsService
16
11
  } from "../chunk-4NAY6HRP.js";
12
+ import {
13
+ CatalogSyncJobError,
14
+ runAiModelsCatalogSync,
15
+ verifyAiModelsCatalog
16
+ } from "../chunk-MX3AMQFC.js";
17
+ import {
18
+ ensureAiModelsCatalog
19
+ } from "../chunk-VRFVF5RH.js";
20
+ import "../chunk-HYGXZY25.js";
17
21
  import "../chunk-6QGDZTGH.js";
18
22
  import {
19
23
  AiModelsCatalogClient
@@ -179,15 +183,91 @@ ${report.total} total \xB7 ${report.ok} ok \xB7 ${report.unknown} unknown \
179
183
  });
180
184
  }
181
185
 
186
+ // src/cli/report.ts
187
+ function emitJson(data) {
188
+ console.log(JSON.stringify(data, null, 2));
189
+ }
190
+ function emitHuman(lines) {
191
+ for (const line of lines) {
192
+ console.log(line);
193
+ }
194
+ }
195
+ function formatSyncJobReport(result) {
196
+ const lines = [
197
+ "",
198
+ result.ok ? "\u2714 Catalog sync job succeeded" : "\u2717 Catalog sync job failed",
199
+ "",
200
+ "Sync",
201
+ ` Fetched: ${result.sync.fetched}`,
202
+ ` Upserted: ${result.sync.upserted}`,
203
+ ` Skipped: ${result.sync.skipped}`,
204
+ ` Errors: ${result.sync.errors.length}`,
205
+ ` Duration: ${result.sync.durationMs}ms`
206
+ ];
207
+ if (result.verify) {
208
+ lines.push(
209
+ "",
210
+ "Verify",
211
+ ` Status: ${result.verify.ok ? "ok" : "FAILED"}`,
212
+ ` OpenRouter: ${result.verify.openRouterCount}`,
213
+ ` Catalox: ${result.verify.cataloxCount}`,
214
+ ` Missing: ${result.verify.missingInCatalox.length}`,
215
+ ` Extra: ${result.verify.extraInCatalox.length}`,
216
+ ` Duration: ${result.verify.durationMs}ms`
217
+ );
218
+ if (result.verify.missingInCatalox.length > 0) {
219
+ lines.push(` Sample missing: ${result.verify.missingInCatalox.join(", ")}`);
220
+ }
221
+ if (result.verify.extraInCatalox.length > 0) {
222
+ lines.push(` Sample extra: ${result.verify.extraInCatalox.join(", ")}`);
223
+ }
224
+ }
225
+ if (result.prune) {
226
+ lines.push("", "Prune", ` Scanned: ${result.prune.scanned}`, ` Removed: ${result.prune.pruned}`);
227
+ }
228
+ return lines;
229
+ }
230
+
182
231
  // src/cli/commands/catalog.ts
183
232
  function registerCatalogCommand(program2) {
184
- const catalog = program2.command("catalog").description("Catalog bootstrap commands");
185
- catalog.command("ensure").description("Create catalog, descriptor, and app binding if missing").option("--app <appId>", "Override appId").option("--catalog <id>", "Override catalogId").action(async (opts) => {
186
- await ensureAiModelsCatalog(getCatalox(), {
233
+ const catalog = program2.command("catalog").description("Catalog bootstrap and health commands");
234
+ catalog.command("ensure").description("Create catalog, descriptor, and app binding if missing").option("--app <appId>", "Override appId").option("--catalog <id>", "Override catalogId").option("--json", "Machine-readable JSON on stdout").action(async (opts) => {
235
+ const appId = opts.app ?? envAppId();
236
+ const catalogId = opts.catalog ?? envCatalogId();
237
+ await ensureAiModelsCatalog(getCatalox(), { appId, catalogId });
238
+ if (opts.json) {
239
+ emitJson({ ok: true, appId, catalogId, action: "ensure" });
240
+ } else {
241
+ console.log("\u2714 ai-models catalog ensured");
242
+ }
243
+ });
244
+ catalog.command("verify").description("Health check: compare Catalox ai-models against the live OpenRouter catalog").option("--app <appId>", "Override appId").option("--catalog <id>", "Override catalogId").option("--json", "Machine-readable JSON on stdout").action(async (opts) => {
245
+ const report = await verifyAiModelsCatalog({
246
+ catalox: getCatalox(),
187
247
  appId: opts.app ?? envAppId(),
188
248
  catalogId: opts.catalog ?? envCatalogId()
189
249
  });
190
- console.log("\u2714 ai-models catalog ensured");
250
+ if (opts.json) {
251
+ emitJson(report);
252
+ } else {
253
+ emitHuman([
254
+ report.ok ? "\u2714 Catalog verification passed" : "\u2717 Catalog verification FAILED",
255
+ ` OpenRouter models: ${report.openRouterCount}`,
256
+ ` Catalox models: ${report.cataloxCount}`,
257
+ ` Missing in Catalox: ${report.missingInCatalox.length}`,
258
+ ` Extra in Catalox: ${report.extraInCatalox.length}`,
259
+ ` Duration: ${report.durationMs}ms`
260
+ ]);
261
+ if (report.missingInCatalox.length > 0) {
262
+ console.log(` Sample missing: ${report.missingInCatalox.join(", ")}`);
263
+ }
264
+ if (report.extraInCatalox.length > 0) {
265
+ console.log(` Sample extra: ${report.extraInCatalox.join(", ")}`);
266
+ }
267
+ }
268
+ if (!report.ok) {
269
+ process.exit(1);
270
+ }
191
271
  });
192
272
  }
193
273
 
@@ -362,30 +442,53 @@ ${rows.length} shown \xB7 ${total} matching`);
362
442
 
363
443
  // src/cli/commands/sync.ts
364
444
  function registerSyncCommand(program2) {
365
- program2.command("sync").description("Fetch OpenRouter models (public API, no key required) and upsert into the ai-models catalog").option("--dry-run", "Print what would be written without touching Firestore").option("--verbose", "Print each model ID as it is upserted").option("--app <appId>", "Override appId").option("--catalog <id>", "Override catalogId").option("--force-cache", "Invalidate nx-cache before running").action(async (opts) => {
366
- const result = await syncAiModelsCatalog({
367
- catalox: getCatalox(),
368
- firestore: getFirestore(),
369
- openRouterApiKey: process.env.OPENROUTER_API_KEY,
370
- appId: opts.app ?? envAppId(),
371
- catalogId: opts.catalog ?? envCatalogId(),
372
- dryRun: opts.dryRun,
373
- verbose: opts.verbose,
374
- forceCache: opts.forceCache
375
- });
376
- console.log("\nSync complete");
377
- console.log(` Fetched: ${result.fetched}`);
378
- console.log(` Upserted: ${result.upserted}`);
379
- console.log(` Skipped: ${result.skipped}`);
380
- console.log(` Errors: ${result.errors.length}`);
381
- console.log(` Duration: ${result.durationMs}ms`);
382
- if (result.errors.length > 0) {
383
- for (const e of result.errors.slice(0, 10)) {
384
- console.error(` \u2717 ${e.modelId}: ${e.error}`);
445
+ program2.command("sync").description(
446
+ "Production sync: fetch OpenRouter models, upsert into Catalox/Firestore, verify completeness"
447
+ ).option("--dry-run", "Fetch and validate without writing to Firestore").option("--no-verify", "Skip post-sync verification (not recommended in production)").option("--prune-stale", "Remove catalog rows no longer on OpenRouter").option("--json", "Machine-readable JSON on stdout").option("--verbose", "Log fetch URL and upsert progress").option("--app <appId>", "Override appId").option("--catalog <id>", "Override catalogId").option("--force-cache", "Invalidate nx-cache before running").action(
448
+ async (opts) => {
449
+ const verifyAfter = opts.verify !== false;
450
+ try {
451
+ const result = await runAiModelsCatalogSync({
452
+ catalox: getCatalox(),
453
+ firestore: getFirestore(),
454
+ openRouterApiKey: process.env.OPENROUTER_API_KEY,
455
+ appId: opts.app ?? envAppId(),
456
+ catalogId: opts.catalog ?? envCatalogId(),
457
+ dryRun: opts.dryRun,
458
+ verbose: opts.verbose,
459
+ forceCache: opts.forceCache,
460
+ verifyAfter,
461
+ pruneStale: opts.pruneStale,
462
+ onProgress: opts.verbose ? ({ completed, total, phase }) => {
463
+ console.log(`[sync] ${phase} ${completed}/${total}`);
464
+ } : void 0
465
+ });
466
+ if (opts.json) {
467
+ emitJson(result);
468
+ } else {
469
+ emitHuman(formatSyncJobReport(result));
470
+ }
471
+ if (!result.ok) {
472
+ process.exit(1);
473
+ }
474
+ } catch (error) {
475
+ if (error instanceof CatalogSyncJobError) {
476
+ const payload = {
477
+ ok: false,
478
+ sync: error.sync,
479
+ verify: error.verify
480
+ };
481
+ if (opts.json) {
482
+ emitJson(payload);
483
+ } else {
484
+ emitHuman(formatSyncJobReport(payload));
485
+ }
486
+ process.exit(1);
487
+ }
488
+ throw error;
385
489
  }
386
- process.exit(1);
387
490
  }
388
- });
491
+ );
389
492
  }
390
493
 
391
494
  // src/cli/index.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/alias.ts","../../src/cli/catalox.ts","../../src/cli/env.ts","../../src/cli/commands/catalog.ts","../../src/cli/commands/cost.ts","../../src/cli/commands/models.ts","../../src/cli/commands/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { registerAliasCommand } from \"./commands/alias.js\";\nimport { registerCatalogCommand } from \"./commands/catalog.js\";\nimport { registerCostCommand } from \"./commands/cost.js\";\nimport { registerModelsCommand } from \"./commands/models.js\";\nimport { registerSyncCommand } from \"./commands/sync.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"ai-tools\")\n .description(\"@x12i/ai-tools — AI model catalog, cost calculation, and utilities\")\n .version(\"1.0.0\");\n\nregisterSyncCommand(program);\nregisterCatalogCommand(program);\nregisterModelsCommand(program);\nregisterCostCommand(program);\nregisterAliasCommand(program);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { AliasResolver } from \"../../aliases/AliasResolver.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction registry(path?: string) {\n return new AliasRegistry(path ? { aliasesPath: path } : {});\n}\n\nfunction resolver(path?: string) {\n return new AliasResolver({\n registry: registry(path),\n catalogClient: new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: envAppId(),\n catalogId: envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n }),\n });\n}\n\nexport function registerAliasCommand(program: Command): void {\n const alias = program.command(\"alias\").description(\"Manage project-local model aliases\");\n\n alias\n .command(\"init\")\n .description(\"Create an empty ai-tools/aliases.json\")\n .option(\"--path <path>\", \"Custom path\")\n .option(\"--force\", \"Overwrite if already exists\")\n .action((opts: { path?: string; force?: boolean }) => {\n const reg = registry(opts.path);\n if (reg.exists() && !opts.force) {\n console.log(`Aliases file already exists at ${reg.path}`);\n return;\n }\n if (opts.force && reg.exists()) {\n fs.unlinkSync(reg.path);\n }\n reg.init();\n console.log(`✔ Created ${reg.path}`);\n console.log(\n \" Tip: commit this file to your repository so aliases are consistent across environments.\",\n );\n });\n\n alias\n .command(\"set\")\n .description(\"Create or update an alias\")\n .argument(\"<name>\", \"Alias name\")\n .argument(\"<modelId>\", \"Model ID\")\n .option(\"--provider <p>\", \"Provider routing\", \"openrouter\")\n .option(\"--description <d>\", \"Human-readable note\")\n .option(\"--tag <t>\", \"Tag (repeatable)\", (v: string, prev: string[]) => [...prev, v], [] as string[])\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(\n (\n name: string,\n modelId: string,\n opts: { provider: string; description?: string; tag: string[]; path?: string },\n ) => {\n const reg = registry(opts.path);\n if (!reg.exists()) reg.init();\n reg.set(name, {\n modelId,\n provider: opts.provider,\n description: opts.description,\n tags: opts.tag.length ? opts.tag : undefined,\n });\n console.log(`✔ alias \"${name}\" → ${modelId} (via ${opts.provider})`);\n console.log(` Updated ${reg.path}`);\n },\n );\n\n alias\n .command(\"get\")\n .description(\"Show one alias (with catalog resolution when available)\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (name: string, opts: { path?: string }) => {\n const ref = await resolver(opts.path).getModel(name);\n console.log(`Alias: ${ref.alias}`);\n console.log(`Model ID: ${ref.modelId}`);\n console.log(`Provider: ${ref.provider}`);\n if (ref.modelRecord) {\n console.log(`Name: ${ref.name}`);\n console.log(`Context: ${ref.modelRecord.contextLength.toLocaleString()} tokens`);\n console.log(`Status: ${ref.modelRecord.status} ✔`);\n } else {\n console.log(`Catalog: ✘ not found in ai-models catalog (local/custom model)`);\n }\n if (ref.entry.description) console.log(`Description: ${ref.entry.description}`);\n if (ref.entry.tags?.length) console.log(`Tags: ${ref.entry.tags.join(\", \")}`);\n });\n\n alias\n .command(\"list\")\n .description(\"List all aliases\")\n .option(\"--tag <t>\", \"Filter by tag\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--check\", \"Validate each alias against the catalog\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { tag?: string; json?: boolean; check?: boolean; path?: string }) => {\n const reg = registry(opts.path);\n const rows = reg.list(opts.tag ? { tag: opts.tag } : undefined);\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (opts.check) {\n const report = await resolver(opts.path).validate();\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"STATUS\");\n console.log(\"─\".repeat(60));\n for (const e of report.entries) {\n const status =\n e.status === \"ok\" ? \"✔ resolved\" : e.status === \"unknown\" ? \"✘ not in catalog\" : \"✗ broken\";\n console.log(e.name.padEnd(14), e.modelId.padEnd(32), status);\n }\n return;\n }\n\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"PROVIDER\".padEnd(12), \"DESCRIPTION\");\n console.log(\"─\".repeat(90));\n for (const row of rows) {\n console.log(\n row.name.padEnd(14),\n row.modelId.padEnd(32),\n row.provider.padEnd(12),\n (row.description ?? \"\").slice(0, 40),\n );\n }\n });\n\n alias\n .command(\"remove\")\n .description(\"Remove an alias\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--yes\", \"Skip confirmation\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((name: string, opts: { yes?: boolean; path?: string }) => {\n if (!opts.yes) {\n console.log(`Remove alias \"${name}\"? Use --yes to confirm.`);\n process.exit(1);\n }\n const removed = registry(opts.path).remove(name);\n if (removed) console.log(`✔ Removed alias \"${name}\"`);\n else {\n console.error(`Alias not found: ${name}`);\n process.exit(1);\n }\n });\n\n alias\n .command(\"rename\")\n .description(\"Rename an alias\")\n .argument(\"<from>\", \"Current name\")\n .argument(\"<to>\", \"New name\")\n .option(\"--force\", \"Overwrite destination if it exists\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((from: string, to: string, opts: { force?: boolean; path?: string }) => {\n registry(opts.path).rename(from, to, { force: opts.force });\n console.log(`✔ Renamed \"${from}\" → \"${to}\"`);\n });\n\n alias\n .command(\"check\")\n .description(\"Validate all aliases against the catalog (CI-friendly)\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { path?: string }) => {\n const report = await resolver(opts.path).validate();\n console.log(`Checking ${report.total} aliases against ai-models catalog…\\n`);\n\n for (const e of report.entries) {\n const icon = e.status === \"ok\" ? \"✔\" : e.status === \"unknown\" ? \"⚠\" : \"✗\";\n const extra = e.resolvedName ? ` (${e.resolvedName})` : e.issue ? ` (${e.issue})` : \"\";\n console.log(` ${icon} ${e.name.padEnd(12)} → ${e.modelId.padEnd(28)}${extra}`);\n }\n\n console.log(\n `\\n${report.total} total · ${report.ok} ok · ${report.unknown} unknown · ${report.broken} broken`,\n );\n\n if (report.broken > 0) process.exit(1);\n });\n}\n","import { createCataloxFromEnv } from \"@x12i/catalox/firebase\";\nimport type { Catalox } from \"@x12i/catalox\";\nimport type { Firestore } from \"firebase-admin/firestore\";\n\ntype CataloxBundle = {\n catalox: Catalox;\n firestore: Firestore;\n};\n\nlet cached: CataloxBundle | null = null;\n\nexport function getCataloxBundle(): CataloxBundle {\n if (!cached) {\n cached = createCataloxFromEnv();\n }\n return cached;\n}\n\nexport function getCatalox(): Catalox {\n return getCataloxBundle().catalox;\n}\n\nexport function getFirestore(): Firestore {\n return getCataloxBundle().firestore;\n}\n","import { config } from \"dotenv\";\n\nconfig();\n\nexport function envAppId(): string {\n return process.env.AI_TOOLS_APP_ID ?? \"ai-tools\";\n}\n\nexport function envCatalogId(): string {\n return process.env.AI_TOOLS_CATALOG_ID ?? \"ai-models\";\n}\n\nexport function envCacheTtlMs(): number {\n const raw = process.env.AI_TOOLS_CACHE_TTL_MS;\n return raw ? Number.parseInt(raw, 10) : 60 * 60 * 1000;\n}\n","import type { Command } from \"commander\";\nimport { ensureAiModelsCatalog } from \"../../catalog/ensureAiModelsCatalog.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\n\nexport function registerCatalogCommand(program: Command): void {\n const catalog = program.command(\"catalog\").description(\"Catalog bootstrap commands\");\n\n catalog\n .command(\"ensure\")\n .description(\"Create catalog, descriptor, and app binding if missing\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: { app?: string; catalog?: string }) => {\n await ensureAiModelsCatalog(getCatalox(), {\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n });\n console.log(\"✔ ai-models catalog ensured\");\n });\n}\n","import type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { CostCalculator } from \"../../cost/CostCalculator.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction formatUsd(n: number): string {\n return `$${n.toFixed(6)}`;\n}\n\nexport function registerCostCommand(program: Command): void {\n program\n .command(\"cost\")\n .description(\"Estimate cost from catalog pricing\")\n .requiredOption(\"--model <id>\", \"Model ID or alias\")\n .requiredOption(\"--prompt-tokens <n>\", \"Prompt token count\", (v) => Number.parseInt(v, 10))\n .requiredOption(\n \"--completion-tokens <n>\",\n \"Completion token count\",\n (v) => Number.parseInt(v, 10),\n )\n .option(\"--cached-tokens <n>\", \"Cached token count\", (v) => Number.parseInt(v, 10))\n .option(\"--reasoning-tokens <n>\", \"Reasoning token count\", (v) => Number.parseInt(v, 10))\n .option(\"--provider <id>\", \"Provider for OpenRouter delta logic\", \"openrouter\")\n .option(\"--json\", \"Output raw AiCostResult JSON\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n promptTokens: number;\n completionTokens: number;\n cachedTokens?: number;\n reasoningTokens?: number;\n provider: string;\n json?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const catalogClient = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n\n const calculator = new CostCalculator(catalogClient, {\n aliasRegistry: new AliasRegistry(),\n });\n\n const result = await calculator.calculate({\n tokens: {\n prompt: opts.promptTokens,\n completion: opts.completionTokens,\n total: opts.promptTokens + opts.completionTokens,\n cached: opts.cachedTokens,\n reasoning: opts.reasoningTokens,\n },\n provider: opts.provider,\n modelUsed: opts.model,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const b = result.breakdown;\n console.log(`Model: ${result.resolvedModelId}`);\n console.log(\n `Prompt: ${opts.promptTokens.toLocaleString()} tokens → ${formatUsd(b?.promptCostUsd ?? 0)}`,\n );\n console.log(\n `Completion: ${opts.completionTokens.toLocaleString()} tokens → ${formatUsd(b?.completionCostUsd ?? 0)}`,\n );\n console.log(\n `Request fee: → ${formatUsd(b?.requestFlatCostUsd ?? 0)}`,\n );\n console.log(\"─\".repeat(38));\n console.log(`Total: → ${formatUsd(result.cost)}`);\n console.log(\n `Via OpenRouter: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`,\n );\n });\n}\n","import type { Command } from \"commander\";\nimport { AiModelsService } from \"../../models/AiModelsService.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction service(opts: { app?: string; catalog?: string }) {\n return new AiModelsService({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n}\n\nexport function registerModelsCommand(program: Command): void {\n const models = program.command(\"models\").description(\"Inspect ai-models catalog\");\n\n models\n .command(\"list\")\n .description(\"List models with optional filters\")\n .option(\"--provider <id>\", \"Filter by providerId (e.g. openai, anthropic)\")\n .option(\"--output-modality <m>\", \"Filter by output modality (text, image, audio, …)\")\n .option(\"--input-modality <m>\", \"Filter by input modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter (e.g. tools)\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--search <q>\", \"Search name, id, description\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--limit <n>\", \"Max rows\", \"50\")\n .option(\"--offset <n>\", \"Skip rows\", \"0\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n inputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n search?: string;\n json?: boolean;\n limit?: string;\n offset?: string;\n app?: string;\n catalog?: string;\n }) => {\n const { models: rows, total } = await service(opts).listModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n inputModality: opts.inputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n search: opts.search,\n limit: Number.parseInt(opts.limit ?? \"50\", 10),\n offset: Number.parseInt(opts.offset ?? \"0\", 10),\n });\n\n if (opts.json) {\n console.log(JSON.stringify({ total, models: rows }, null, 2));\n return;\n }\n\n console.log(\n \"MODEL ID\".padEnd(42),\n \"PROVIDER\".padEnd(14),\n \"OUTPUT\".padEnd(10),\n \"R\".padEnd(3),\n \"NAME\",\n );\n console.log(\"─\".repeat(104));\n for (const m of rows) {\n console.log(\n m.modelId.padEnd(42),\n m.providerId.padEnd(14),\n m.primaryOutputModality.padEnd(10),\n (m.supportsReasoning ? \"yes\" : \"no\").padEnd(3),\n m.name.slice(0, 40),\n );\n }\n console.log(`\\n${rows.length} shown · ${total} matching`);\n });\n\n models\n .command(\"get\")\n .description(\"Get full model info (OpenRouter mirror) by ID or alias\")\n .argument(\"<modelId>\", \"Model ID or alias\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (modelId: string, opts: { app?: string; catalog?: string }) => {\n const model = await service(opts).getModelInfo(modelId);\n if (!model) {\n console.error(`Model not found: ${modelId}`);\n process.exit(1);\n }\n console.log(JSON.stringify(model, null, 2));\n });\n\n models\n .command(\"resolve\")\n .description(\"Resolve provider + model to canonical id (smart resolver)\")\n .requiredOption(\"--model <m>\", \"Model string (required)\")\n .option(\"--provider <p>\", \"Provider hint (openrouter, openai, …)\")\n .option(\"--threshold <n>\", \"Confidence threshold 0–1\", \"0.6\")\n .option(\"--json\", \"Output raw ModelResolutionResult JSON\")\n .option(\"--verbose\", \"Show strategy trail\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n provider?: string;\n threshold?: string;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const { AiModelsCatalogClient } = await import(\"../../catalox/AiModelsCatalogClient.js\");\n const client = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n const threshold = Number.parseFloat(opts.threshold ?? \"0.6\");\n const result = await client.resolveModel(\n { model: opts.model, provider: opts.provider },\n { confidenceThreshold: threshold },\n );\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n if (!result.found) process.exit(1);\n return;\n }\n\n const providerLabel = opts.provider ?? \"unspecified\";\n console.log(`Input: provider=\"${providerLabel}\" model=\"${opts.model}\"`);\n\n if (opts.verbose) {\n console.log(`Normalised: model=\"${result.found ? result.normalisedInput : opts.model}\"`);\n const strategies = result.found ? result.resolvedVia : result.attemptedStrategies;\n console.log(\"\\nStrategy trail:\");\n for (const s of strategies) {\n console.log(` • ${s}`);\n }\n console.log();\n }\n\n if (!result.found) {\n console.log(\"Result: NOT FOUND\");\n console.log(`Reason: ${result.reason}`);\n if (result.bestRejectedCandidate) {\n console.log(\n `Candidate: ${result.bestRejectedCandidate.modelId} (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)})`,\n );\n } else {\n console.log(\"Candidate: none\");\n }\n console.log('Tip: Run \"ai-tools sync\" or add an alias with \"ai-tools alias set\".');\n process.exit(1);\n return;\n }\n\n console.log(`Resolved: ${result.modelId}`);\n console.log(`Name: ${result.record?.name ?? \"(local / no catalog record)\"}`);\n console.log(`Strategy: ${result.resolvedVia.join(\" → \")}`);\n console.log(`Confidence: ${result.confidence.toFixed(2)}`);\n console.log(`Via OR: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`);\n });\n\n models\n .command(\"count\")\n .description(\"Count models matching filters\")\n .option(\"--provider <id>\", \"Filter by providerId\")\n .option(\"--output-modality <m>\", \"Filter by output modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const n = await service(opts).countModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n });\n console.log(n);\n });\n}\n","import type { Command } from \"commander\";\nimport { syncAiModelsCatalog } from \"../../sync/syncAiModelsCatalog.js\";\nimport { getCatalox, getFirestore } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\n\nexport function registerSyncCommand(program: Command): void {\n program\n .command(\"sync\")\n .description(\"Fetch OpenRouter models (public API, no key required) and upsert into the ai-models catalog\")\n .option(\"--dry-run\", \"Print what would be written without touching Firestore\")\n .option(\"--verbose\", \"Print each model ID as it is upserted\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--force-cache\", \"Invalidate nx-cache before running\")\n .action(async (opts: {\n dryRun?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n forceCache?: boolean;\n }) => {\n const result = await syncAiModelsCatalog({\n catalox: getCatalox(),\n firestore: getFirestore(),\n openRouterApiKey: process.env.OPENROUTER_API_KEY,\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n dryRun: opts.dryRun,\n verbose: opts.verbose,\n forceCache: opts.forceCache,\n });\n\n console.log(\"\\nSync complete\");\n console.log(` Fetched: ${result.fetched}`);\n console.log(` Upserted: ${result.upserted}`);\n console.log(` Skipped: ${result.skipped}`);\n console.log(` Errors: ${result.errors.length}`);\n console.log(` Duration: ${result.durationMs}ms`);\n\n if (result.errors.length > 0) {\n for (const e of result.errors.slice(0, 10)) {\n console.error(` ✗ ${e.modelId}: ${e.error}`);\n }\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["program","program","program","program","AiModelsCatalogClient","program"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/alias.ts","../../src/cli/catalox.ts","../../src/cli/env.ts","../../src/cli/report.ts","../../src/cli/commands/catalog.ts","../../src/cli/commands/cost.ts","../../src/cli/commands/models.ts","../../src/cli/commands/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { registerAliasCommand } from \"./commands/alias.js\";\nimport { registerCatalogCommand } from \"./commands/catalog.js\";\nimport { registerCostCommand } from \"./commands/cost.js\";\nimport { registerModelsCommand } from \"./commands/models.js\";\nimport { registerSyncCommand } from \"./commands/sync.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"ai-tools\")\n .description(\"@x12i/ai-tools — AI model catalog, cost calculation, and utilities\")\n .version(\"1.0.0\");\n\nregisterSyncCommand(program);\nregisterCatalogCommand(program);\nregisterModelsCommand(program);\nregisterCostCommand(program);\nregisterAliasCommand(program);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { AliasResolver } from \"../../aliases/AliasResolver.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction registry(path?: string) {\n return new AliasRegistry(path ? { aliasesPath: path } : {});\n}\n\nfunction resolver(path?: string) {\n return new AliasResolver({\n registry: registry(path),\n catalogClient: new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: envAppId(),\n catalogId: envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n }),\n });\n}\n\nexport function registerAliasCommand(program: Command): void {\n const alias = program.command(\"alias\").description(\"Manage project-local model aliases\");\n\n alias\n .command(\"init\")\n .description(\"Create an empty ai-tools/aliases.json\")\n .option(\"--path <path>\", \"Custom path\")\n .option(\"--force\", \"Overwrite if already exists\")\n .action((opts: { path?: string; force?: boolean }) => {\n const reg = registry(opts.path);\n if (reg.exists() && !opts.force) {\n console.log(`Aliases file already exists at ${reg.path}`);\n return;\n }\n if (opts.force && reg.exists()) {\n fs.unlinkSync(reg.path);\n }\n reg.init();\n console.log(`✔ Created ${reg.path}`);\n console.log(\n \" Tip: commit this file to your repository so aliases are consistent across environments.\",\n );\n });\n\n alias\n .command(\"set\")\n .description(\"Create or update an alias\")\n .argument(\"<name>\", \"Alias name\")\n .argument(\"<modelId>\", \"Model ID\")\n .option(\"--provider <p>\", \"Provider routing\", \"openrouter\")\n .option(\"--description <d>\", \"Human-readable note\")\n .option(\"--tag <t>\", \"Tag (repeatable)\", (v: string, prev: string[]) => [...prev, v], [] as string[])\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(\n (\n name: string,\n modelId: string,\n opts: { provider: string; description?: string; tag: string[]; path?: string },\n ) => {\n const reg = registry(opts.path);\n if (!reg.exists()) reg.init();\n reg.set(name, {\n modelId,\n provider: opts.provider,\n description: opts.description,\n tags: opts.tag.length ? opts.tag : undefined,\n });\n console.log(`✔ alias \"${name}\" → ${modelId} (via ${opts.provider})`);\n console.log(` Updated ${reg.path}`);\n },\n );\n\n alias\n .command(\"get\")\n .description(\"Show one alias (with catalog resolution when available)\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (name: string, opts: { path?: string }) => {\n const ref = await resolver(opts.path).getModel(name);\n console.log(`Alias: ${ref.alias}`);\n console.log(`Model ID: ${ref.modelId}`);\n console.log(`Provider: ${ref.provider}`);\n if (ref.modelRecord) {\n console.log(`Name: ${ref.name}`);\n console.log(`Context: ${ref.modelRecord.contextLength.toLocaleString()} tokens`);\n console.log(`Status: ${ref.modelRecord.status} ✔`);\n } else {\n console.log(`Catalog: ✘ not found in ai-models catalog (local/custom model)`);\n }\n if (ref.entry.description) console.log(`Description: ${ref.entry.description}`);\n if (ref.entry.tags?.length) console.log(`Tags: ${ref.entry.tags.join(\", \")}`);\n });\n\n alias\n .command(\"list\")\n .description(\"List all aliases\")\n .option(\"--tag <t>\", \"Filter by tag\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--check\", \"Validate each alias against the catalog\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { tag?: string; json?: boolean; check?: boolean; path?: string }) => {\n const reg = registry(opts.path);\n const rows = reg.list(opts.tag ? { tag: opts.tag } : undefined);\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (opts.check) {\n const report = await resolver(opts.path).validate();\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"STATUS\");\n console.log(\"─\".repeat(60));\n for (const e of report.entries) {\n const status =\n e.status === \"ok\" ? \"✔ resolved\" : e.status === \"unknown\" ? \"✘ not in catalog\" : \"✗ broken\";\n console.log(e.name.padEnd(14), e.modelId.padEnd(32), status);\n }\n return;\n }\n\n console.log(\"NAME\".padEnd(14), \"MODEL ID\".padEnd(32), \"PROVIDER\".padEnd(12), \"DESCRIPTION\");\n console.log(\"─\".repeat(90));\n for (const row of rows) {\n console.log(\n row.name.padEnd(14),\n row.modelId.padEnd(32),\n row.provider.padEnd(12),\n (row.description ?? \"\").slice(0, 40),\n );\n }\n });\n\n alias\n .command(\"remove\")\n .description(\"Remove an alias\")\n .argument(\"<name>\", \"Alias name\")\n .option(\"--yes\", \"Skip confirmation\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((name: string, opts: { yes?: boolean; path?: string }) => {\n if (!opts.yes) {\n console.log(`Remove alias \"${name}\"? Use --yes to confirm.`);\n process.exit(1);\n }\n const removed = registry(opts.path).remove(name);\n if (removed) console.log(`✔ Removed alias \"${name}\"`);\n else {\n console.error(`Alias not found: ${name}`);\n process.exit(1);\n }\n });\n\n alias\n .command(\"rename\")\n .description(\"Rename an alias\")\n .argument(\"<from>\", \"Current name\")\n .argument(\"<to>\", \"New name\")\n .option(\"--force\", \"Overwrite destination if it exists\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action((from: string, to: string, opts: { force?: boolean; path?: string }) => {\n registry(opts.path).rename(from, to, { force: opts.force });\n console.log(`✔ Renamed \"${from}\" → \"${to}\"`);\n });\n\n alias\n .command(\"check\")\n .description(\"Validate all aliases against the catalog (CI-friendly)\")\n .option(\"--path <path>\", \"Custom aliases path\")\n .action(async (opts: { path?: string }) => {\n const report = await resolver(opts.path).validate();\n console.log(`Checking ${report.total} aliases against ai-models catalog…\\n`);\n\n for (const e of report.entries) {\n const icon = e.status === \"ok\" ? \"✔\" : e.status === \"unknown\" ? \"⚠\" : \"✗\";\n const extra = e.resolvedName ? ` (${e.resolvedName})` : e.issue ? ` (${e.issue})` : \"\";\n console.log(` ${icon} ${e.name.padEnd(12)} → ${e.modelId.padEnd(28)}${extra}`);\n }\n\n console.log(\n `\\n${report.total} total · ${report.ok} ok · ${report.unknown} unknown · ${report.broken} broken`,\n );\n\n if (report.broken > 0) process.exit(1);\n });\n}\n","import { createCataloxFromEnv } from \"@x12i/catalox/firebase\";\nimport type { Catalox } from \"@x12i/catalox\";\nimport type { Firestore } from \"firebase-admin/firestore\";\n\ntype CataloxBundle = {\n catalox: Catalox;\n firestore: Firestore;\n};\n\nlet cached: CataloxBundle | null = null;\n\nexport function getCataloxBundle(): CataloxBundle {\n if (!cached) {\n cached = createCataloxFromEnv();\n }\n return cached;\n}\n\nexport function getCatalox(): Catalox {\n return getCataloxBundle().catalox;\n}\n\nexport function getFirestore(): Firestore {\n return getCataloxBundle().firestore;\n}\n","import { config } from \"dotenv\";\n\nconfig();\n\nexport function envAppId(): string {\n return process.env.AI_TOOLS_APP_ID ?? \"ai-tools\";\n}\n\nexport function envCatalogId(): string {\n return process.env.AI_TOOLS_CATALOG_ID ?? \"ai-models\";\n}\n\nexport function envCacheTtlMs(): number {\n const raw = process.env.AI_TOOLS_CACHE_TTL_MS;\n return raw ? Number.parseInt(raw, 10) : 60 * 60 * 1000;\n}\n","export function emitJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function emitHuman(lines: string[]): void {\n for (const line of lines) {\n console.log(line);\n }\n}\n\nexport function formatSyncJobReport(result: {\n ok: boolean;\n sync: {\n fetched: number;\n upserted: number;\n skipped: number;\n errors: Array<{ modelId: string; error: string }>;\n durationMs: number;\n };\n verify?: {\n ok: boolean;\n openRouterCount: number;\n cataloxCount: number;\n missingInCatalox: string[];\n extraInCatalox: string[];\n durationMs: number;\n };\n prune?: { pruned: number; scanned: number };\n}): string[] {\n const lines = [\n \"\",\n result.ok ? \"✔ Catalog sync job succeeded\" : \"✗ Catalog sync job failed\",\n \"\",\n \"Sync\",\n ` Fetched: ${result.sync.fetched}`,\n ` Upserted: ${result.sync.upserted}`,\n ` Skipped: ${result.sync.skipped}`,\n ` Errors: ${result.sync.errors.length}`,\n ` Duration: ${result.sync.durationMs}ms`,\n ];\n\n if (result.verify) {\n lines.push(\n \"\",\n \"Verify\",\n ` Status: ${result.verify.ok ? \"ok\" : \"FAILED\"}`,\n ` OpenRouter: ${result.verify.openRouterCount}`,\n ` Catalox: ${result.verify.cataloxCount}`,\n ` Missing: ${result.verify.missingInCatalox.length}`,\n ` Extra: ${result.verify.extraInCatalox.length}`,\n ` Duration: ${result.verify.durationMs}ms`,\n );\n if (result.verify.missingInCatalox.length > 0) {\n lines.push(` Sample missing: ${result.verify.missingInCatalox.join(\", \")}`);\n }\n if (result.verify.extraInCatalox.length > 0) {\n lines.push(` Sample extra: ${result.verify.extraInCatalox.join(\", \")}`);\n }\n }\n\n if (result.prune) {\n lines.push(\"\", \"Prune\", ` Scanned: ${result.prune.scanned}`, ` Removed: ${result.prune.pruned}`);\n }\n\n return lines;\n}\n","import type { Command } from \"commander\";\nimport { ensureAiModelsCatalog } from \"../../catalog/ensureAiModelsCatalog.js\";\nimport { verifyAiModelsCatalog } from \"../../catalog/verifyAiModelsCatalog.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\nimport { emitHuman, emitJson } from \"../report.js\";\n\nexport function registerCatalogCommand(program: Command): void {\n const catalog = program.command(\"catalog\").description(\"Catalog bootstrap and health commands\");\n\n catalog\n .command(\"ensure\")\n .description(\"Create catalog, descriptor, and app binding if missing\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .action(async (opts: { app?: string; catalog?: string; json?: boolean }) => {\n const appId = opts.app ?? envAppId();\n const catalogId = opts.catalog ?? envCatalogId();\n await ensureAiModelsCatalog(getCatalox(), { appId, catalogId });\n if (opts.json) {\n emitJson({ ok: true, appId, catalogId, action: \"ensure\" });\n } else {\n console.log(\"✔ ai-models catalog ensured\");\n }\n });\n\n catalog\n .command(\"verify\")\n .description(\"Health check: compare Catalox ai-models against the live OpenRouter catalog\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .action(async (opts: { app?: string; catalog?: string; json?: boolean }) => {\n const report = await verifyAiModelsCatalog({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n });\n\n if (opts.json) {\n emitJson(report);\n } else {\n emitHuman([\n report.ok ? \"✔ Catalog verification passed\" : \"✗ Catalog verification FAILED\",\n ` OpenRouter models: ${report.openRouterCount}`,\n ` Catalox models: ${report.cataloxCount}`,\n ` Missing in Catalox: ${report.missingInCatalox.length}`,\n ` Extra in Catalox: ${report.extraInCatalox.length}`,\n ` Duration: ${report.durationMs}ms`,\n ]);\n if (report.missingInCatalox.length > 0) {\n console.log(` Sample missing: ${report.missingInCatalox.join(\", \")}`);\n }\n if (report.extraInCatalox.length > 0) {\n console.log(` Sample extra: ${report.extraInCatalox.join(\", \")}`);\n }\n }\n\n if (!report.ok) {\n process.exit(1);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { AliasRegistry } from \"../../aliases/AliasRegistry.js\";\nimport { CostCalculator } from \"../../cost/CostCalculator.js\";\nimport { AiModelsCatalogClient } from \"../../catalox/AiModelsCatalogClient.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction formatUsd(n: number): string {\n return `$${n.toFixed(6)}`;\n}\n\nexport function registerCostCommand(program: Command): void {\n program\n .command(\"cost\")\n .description(\"Estimate cost from catalog pricing\")\n .requiredOption(\"--model <id>\", \"Model ID or alias\")\n .requiredOption(\"--prompt-tokens <n>\", \"Prompt token count\", (v) => Number.parseInt(v, 10))\n .requiredOption(\n \"--completion-tokens <n>\",\n \"Completion token count\",\n (v) => Number.parseInt(v, 10),\n )\n .option(\"--cached-tokens <n>\", \"Cached token count\", (v) => Number.parseInt(v, 10))\n .option(\"--reasoning-tokens <n>\", \"Reasoning token count\", (v) => Number.parseInt(v, 10))\n .option(\"--provider <id>\", \"Provider for OpenRouter delta logic\", \"openrouter\")\n .option(\"--json\", \"Output raw AiCostResult JSON\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n promptTokens: number;\n completionTokens: number;\n cachedTokens?: number;\n reasoningTokens?: number;\n provider: string;\n json?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const catalogClient = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n\n const calculator = new CostCalculator(catalogClient, {\n aliasRegistry: new AliasRegistry(),\n });\n\n const result = await calculator.calculate({\n tokens: {\n prompt: opts.promptTokens,\n completion: opts.completionTokens,\n total: opts.promptTokens + opts.completionTokens,\n cached: opts.cachedTokens,\n reasoning: opts.reasoningTokens,\n },\n provider: opts.provider,\n modelUsed: opts.model,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const b = result.breakdown;\n console.log(`Model: ${result.resolvedModelId}`);\n console.log(\n `Prompt: ${opts.promptTokens.toLocaleString()} tokens → ${formatUsd(b?.promptCostUsd ?? 0)}`,\n );\n console.log(\n `Completion: ${opts.completionTokens.toLocaleString()} tokens → ${formatUsd(b?.completionCostUsd ?? 0)}`,\n );\n console.log(\n `Request fee: → ${formatUsd(b?.requestFlatCostUsd ?? 0)}`,\n );\n console.log(\"─\".repeat(38));\n console.log(`Total: → ${formatUsd(result.cost)}`);\n console.log(\n `Via OpenRouter: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`,\n );\n });\n}\n","import type { Command } from \"commander\";\nimport { AiModelsService } from \"../../models/AiModelsService.js\";\nimport { getCatalox } from \"../catalox.js\";\nimport { envAppId, envCacheTtlMs, envCatalogId } from \"../env.js\";\n\nfunction service(opts: { app?: string; catalog?: string }) {\n return new AiModelsService({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n}\n\nexport function registerModelsCommand(program: Command): void {\n const models = program.command(\"models\").description(\"Inspect ai-models catalog\");\n\n models\n .command(\"list\")\n .description(\"List models with optional filters\")\n .option(\"--provider <id>\", \"Filter by providerId (e.g. openai, anthropic)\")\n .option(\"--output-modality <m>\", \"Filter by output modality (text, image, audio, …)\")\n .option(\"--input-modality <m>\", \"Filter by input modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter (e.g. tools)\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--search <q>\", \"Search name, id, description\")\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--limit <n>\", \"Max rows\", \"50\")\n .option(\"--offset <n>\", \"Skip rows\", \"0\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n inputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n search?: string;\n json?: boolean;\n limit?: string;\n offset?: string;\n app?: string;\n catalog?: string;\n }) => {\n const { models: rows, total } = await service(opts).listModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n inputModality: opts.inputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n search: opts.search,\n limit: Number.parseInt(opts.limit ?? \"50\", 10),\n offset: Number.parseInt(opts.offset ?? \"0\", 10),\n });\n\n if (opts.json) {\n console.log(JSON.stringify({ total, models: rows }, null, 2));\n return;\n }\n\n console.log(\n \"MODEL ID\".padEnd(42),\n \"PROVIDER\".padEnd(14),\n \"OUTPUT\".padEnd(10),\n \"R\".padEnd(3),\n \"NAME\",\n );\n console.log(\"─\".repeat(104));\n for (const m of rows) {\n console.log(\n m.modelId.padEnd(42),\n m.providerId.padEnd(14),\n m.primaryOutputModality.padEnd(10),\n (m.supportsReasoning ? \"yes\" : \"no\").padEnd(3),\n m.name.slice(0, 40),\n );\n }\n console.log(`\\n${rows.length} shown · ${total} matching`);\n });\n\n models\n .command(\"get\")\n .description(\"Get full model info (OpenRouter mirror) by ID or alias\")\n .argument(\"<modelId>\", \"Model ID or alias\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (modelId: string, opts: { app?: string; catalog?: string }) => {\n const model = await service(opts).getModelInfo(modelId);\n if (!model) {\n console.error(`Model not found: ${modelId}`);\n process.exit(1);\n }\n console.log(JSON.stringify(model, null, 2));\n });\n\n models\n .command(\"resolve\")\n .description(\"Resolve provider + model to canonical id (smart resolver)\")\n .requiredOption(\"--model <m>\", \"Model string (required)\")\n .option(\"--provider <p>\", \"Provider hint (openrouter, openai, …)\")\n .option(\"--threshold <n>\", \"Confidence threshold 0–1\", \"0.6\")\n .option(\"--json\", \"Output raw ModelResolutionResult JSON\")\n .option(\"--verbose\", \"Show strategy trail\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n model: string;\n provider?: string;\n threshold?: string;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const { AiModelsCatalogClient } = await import(\"../../catalox/AiModelsCatalogClient.js\");\n const client = new AiModelsCatalogClient({\n catalox: getCatalox(),\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n cacheTtlMs: envCacheTtlMs(),\n });\n const threshold = Number.parseFloat(opts.threshold ?? \"0.6\");\n const result = await client.resolveModel(\n { model: opts.model, provider: opts.provider },\n { confidenceThreshold: threshold },\n );\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n if (!result.found) process.exit(1);\n return;\n }\n\n const providerLabel = opts.provider ?? \"unspecified\";\n console.log(`Input: provider=\"${providerLabel}\" model=\"${opts.model}\"`);\n\n if (opts.verbose) {\n console.log(`Normalised: model=\"${result.found ? result.normalisedInput : opts.model}\"`);\n const strategies = result.found ? result.resolvedVia : result.attemptedStrategies;\n console.log(\"\\nStrategy trail:\");\n for (const s of strategies) {\n console.log(` • ${s}`);\n }\n console.log();\n }\n\n if (!result.found) {\n console.log(\"Result: NOT FOUND\");\n console.log(`Reason: ${result.reason}`);\n if (result.bestRejectedCandidate) {\n console.log(\n `Candidate: ${result.bestRejectedCandidate.modelId} (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)})`,\n );\n } else {\n console.log(\"Candidate: none\");\n }\n console.log('Tip: Run \"ai-tools sync\" or add an alias with \"ai-tools alias set\".');\n process.exit(1);\n return;\n }\n\n console.log(`Resolved: ${result.modelId}`);\n console.log(`Name: ${result.record?.name ?? \"(local / no catalog record)\"}`);\n console.log(`Strategy: ${result.resolvedVia.join(\" → \")}`);\n console.log(`Confidence: ${result.confidence.toFixed(2)}`);\n console.log(`Via OR: ${result.routedViaOpenRouter ? \"yes\" : \"no\"}`);\n });\n\n models\n .command(\"count\")\n .description(\"Count models matching filters\")\n .option(\"--provider <id>\", \"Filter by providerId\")\n .option(\"--output-modality <m>\", \"Filter by output modality\")\n .option(\"--parameter <p>\", \"Filter by supported parameter\")\n .option(\"--tools\", \"Only models that support tools\")\n .option(\"--reasoning\", \"Only reasoning / thinking models\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .action(async (opts: {\n provider?: string;\n outputModality?: string;\n parameter?: string;\n tools?: boolean;\n reasoning?: boolean;\n app?: string;\n catalog?: string;\n }) => {\n const n = await service(opts).countModels({\n providerId: opts.provider,\n outputModality: opts.outputModality,\n supportedParameter: opts.parameter,\n supportsTools: opts.tools ? true : undefined,\n supportsReasoning: opts.reasoning ? true : undefined,\n });\n console.log(n);\n });\n}\n","import type { Command } from \"commander\";\nimport { runAiModelsCatalogSync, CatalogSyncJobError } from \"../../catalog/runAiModelsCatalogSync.js\";\nimport { getCatalox, getFirestore } from \"../catalox.js\";\nimport { envAppId, envCatalogId } from \"../env.js\";\nimport { emitHuman, emitJson, formatSyncJobReport } from \"../report.js\";\n\nexport function registerSyncCommand(program: Command): void {\n program\n .command(\"sync\")\n .description(\n \"Production sync: fetch OpenRouter models, upsert into Catalox/Firestore, verify completeness\",\n )\n .option(\"--dry-run\", \"Fetch and validate without writing to Firestore\")\n .option(\"--no-verify\", \"Skip post-sync verification (not recommended in production)\")\n .option(\"--prune-stale\", \"Remove catalog rows no longer on OpenRouter\")\n .option(\"--json\", \"Machine-readable JSON on stdout\")\n .option(\"--verbose\", \"Log fetch URL and upsert progress\")\n .option(\"--app <appId>\", \"Override appId\")\n .option(\"--catalog <id>\", \"Override catalogId\")\n .option(\"--force-cache\", \"Invalidate nx-cache before running\")\n .action(\n async (opts: {\n dryRun?: boolean;\n verify?: boolean;\n pruneStale?: boolean;\n json?: boolean;\n verbose?: boolean;\n app?: string;\n catalog?: string;\n forceCache?: boolean;\n }) => {\n const verifyAfter = opts.verify !== false;\n\n try {\n const result = await runAiModelsCatalogSync({\n catalox: getCatalox(),\n firestore: getFirestore(),\n openRouterApiKey: process.env.OPENROUTER_API_KEY,\n appId: opts.app ?? envAppId(),\n catalogId: opts.catalog ?? envCatalogId(),\n dryRun: opts.dryRun,\n verbose: opts.verbose,\n forceCache: opts.forceCache,\n verifyAfter,\n pruneStale: opts.pruneStale,\n onProgress: opts.verbose\n ? ({ completed, total, phase }) => {\n console.log(`[sync] ${phase} ${completed}/${total}`);\n }\n : undefined,\n });\n\n if (opts.json) {\n emitJson(result);\n } else {\n emitHuman(formatSyncJobReport(result));\n }\n\n if (!result.ok) {\n process.exit(1);\n }\n } catch (error) {\n if (error instanceof CatalogSyncJobError) {\n const payload = {\n ok: false,\n sync: error.sync,\n verify: error.verify,\n };\n if (opts.json) {\n emitJson(payload);\n } else {\n emitHuman(formatSyncJobReport(payload));\n }\n process.exit(1);\n }\n throw error;\n }\n },\n );\n}\n"],"mappings":"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","names":["program","program","program","program","AiModelsCatalogClient","program"]}
@@ -1,6 +1,7 @@
1
- import { A as AiModelPricing, d as AliasRegistry, l as ModelResolverOptions } from '../types-DdGB3YaA.cjs';
2
- export { a as AiModelRecord } from '../types-DdGB3YaA.cjs';
3
- import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-CSVlKql5.cjs';
1
+ import { b as AliasRegistry, h as ModelResolverOptions } from '../types-CX6QFNNy.cjs';
2
+ import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-CNeqFiFs.cjs';
3
+ import { A as AiModelPricing } from '../types-BYXnCvKx.cjs';
4
+ export { a as AiModelRecord } from '../types-BYXnCvKx.cjs';
4
5
  import '@x12i/catalox';
5
6
 
6
7
  type AiUsageInput = {
@@ -1,6 +1,7 @@
1
- import { A as AiModelPricing, d as AliasRegistry, l as ModelResolverOptions } from '../types-DdGB3YaA.js';
2
- export { a as AiModelRecord } from '../types-DdGB3YaA.js';
3
- import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-B-dNLXX0.js';
1
+ import { b as AliasRegistry, h as ModelResolverOptions } from '../types-CuiPDcVs.js';
2
+ import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-nwFoEaqL.js';
3
+ import { A as AiModelPricing } from '../types-BYXnCvKx.js';
4
+ export { a as AiModelRecord } from '../types-BYXnCvKx.js';
4
5
  import '@x12i/catalox';
5
6
 
6
7
  type AiUsageInput = {