@rulemetric/cli 0.5.2 → 0.5.4

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 (178) hide show
  1. package/bin/dev.js +7 -0
  2. package/dist/base-command.js +4 -4
  3. package/dist/{chunk-7DRLX3DN.js → chunk-3POYC5NA.js} +3 -3
  4. package/dist/{chunk-TJ2M5QVL.js → chunk-3QH73QOQ.js} +2 -2
  5. package/dist/{chunk-AOIY5RT6.js → chunk-4LHEN2FS.js} +17 -17
  6. package/dist/{chunk-LJ5OT5XN.js → chunk-7K4ILWS7.js} +6 -6
  7. package/dist/{chunk-5ZOLDIZQ.js → chunk-BCIUSUEV.js} +5 -5
  8. package/dist/{chunk-TDTHAOXO.js → chunk-DR5WLIOU.js} +2 -2
  9. package/dist/{chunk-K3BFZ7KG.js → chunk-E3BIT53W.js} +1 -1
  10. package/dist/chunk-E3BIT53W.js.map +7 -0
  11. package/dist/{chunk-4QGATD5Y.js → chunk-F5N6CLJJ.js} +1 -1
  12. package/dist/{chunk-4QGATD5Y.js.map → chunk-F5N6CLJJ.js.map} +2 -2
  13. package/dist/{chunk-7XDWLJJP.js → chunk-H3C6EGR2.js} +5 -5
  14. package/dist/{chunk-PHIAFGQ2.js → chunk-IATQXFJA.js} +7 -7
  15. package/dist/{chunk-IVOCDHWA.js → chunk-IPOO4IGF.js} +3 -3
  16. package/dist/{chunk-AUUHXCJU.js → chunk-JEJ3J5J6.js} +2 -2
  17. package/dist/{chunk-OAQG5WBV.js → chunk-LAKZUE35.js} +2 -2
  18. package/dist/{chunk-346TGPVR.js → chunk-LTT2YMYY.js} +2 -2
  19. package/dist/{chunk-CCSR73HF.js → chunk-N5A2IQAK.js} +2 -2
  20. package/dist/{chunk-IKEI4KNV.js → chunk-OTOWLUOJ.js} +4 -4
  21. package/dist/{chunk-YQFCUKNI.js → chunk-QNSVCSHG.js} +373 -414
  22. package/dist/chunk-QNSVCSHG.js.map +7 -0
  23. package/dist/{chunk-OKCFYPIQ.js → chunk-RCMXTLQF.js} +2 -2
  24. package/dist/{chunk-CGUV6TUA.js → chunk-RUCSRN7F.js} +2 -2
  25. package/dist/{chunk-4UJATBTG.js → chunk-SLL3OBKN.js} +4 -4
  26. package/dist/{chunk-CB43W53J.js → chunk-SZ7VDCD6.js} +3 -3
  27. package/dist/{chunk-N52AHNBH.js → chunk-W4MZXKZ2.js} +6 -2
  28. package/dist/chunk-W4MZXKZ2.js.map +7 -0
  29. package/dist/{chunk-DUR54APY.js → chunk-WLFX4PYR.js} +6 -6
  30. package/dist/{chunk-FUS5C4SB.js → chunk-Y4BJXXYV.js} +2 -2
  31. package/dist/{chunk-KHJUQFIK.js → chunk-YSEQWCN4.js} +2 -2
  32. package/dist/{chunk-CWFVBGX2.js → chunk-ZRLYHBPN.js} +4 -2
  33. package/dist/chunk-ZRLYHBPN.js.map +7 -0
  34. package/dist/{chunk-46LMTDRE.js → chunk-ZSGKRCKD.js} +7 -4
  35. package/dist/chunk-ZSGKRCKD.js.map +7 -0
  36. package/dist/commands/antigravity/backfill.js +5 -5
  37. package/dist/commands/auth/create-key.js +7 -5
  38. package/dist/commands/auth/create-key.js.map +2 -2
  39. package/dist/commands/auth/login.js +4 -4
  40. package/dist/commands/auth/logout.js +4 -4
  41. package/dist/commands/auth/revoke-key.js +4 -4
  42. package/dist/commands/auth/status.js +4 -4
  43. package/dist/commands/catalog/index.js +4 -4
  44. package/dist/commands/catalog/recommend.js +4 -4
  45. package/dist/commands/convert.js +6 -5
  46. package/dist/commands/convert.js.map +2 -2
  47. package/dist/commands/converters.js +4 -4
  48. package/dist/commands/crons/list.js +4 -4
  49. package/dist/commands/crons/run.js +4 -4
  50. package/dist/commands/dashboard.js +4 -4
  51. package/dist/commands/eval-targets/create.js +4 -4
  52. package/dist/commands/eval-targets/list.js +4 -4
  53. package/dist/commands/evals/agent.js +25 -28
  54. package/dist/commands/evals/agent.js.map +4 -4
  55. package/dist/commands/evals/benchmark.js +5 -5
  56. package/dist/commands/evals/compare.js +4 -4
  57. package/dist/commands/evals/create.js +4 -4
  58. package/dist/commands/evals/optimize-description.js +4 -4
  59. package/dist/commands/evals/optimize.js +4 -4
  60. package/dist/commands/evals/run.js +4 -4
  61. package/dist/commands/gateway/ensure.js +4 -4
  62. package/dist/commands/hooks/install.js +4 -4
  63. package/dist/commands/hooks/run.js +4 -4
  64. package/dist/commands/hooks/uninstall.js +4 -4
  65. package/dist/commands/import.js +4 -4
  66. package/dist/commands/instructions/create.js +4 -4
  67. package/dist/commands/instructions/delete.js +4 -4
  68. package/dist/commands/instructions/fork.js +4 -4
  69. package/dist/commands/instructions/get.js +4 -4
  70. package/dist/commands/instructions/list.js +4 -4
  71. package/dist/commands/instructions/promote.js +4 -4
  72. package/dist/commands/instructions/pull.js +4 -4
  73. package/dist/commands/instructions/upstream.js +4 -4
  74. package/dist/commands/instructions/versions.js +4 -4
  75. package/dist/commands/launcher.js +4 -4
  76. package/dist/commands/org/current.js +9 -9
  77. package/dist/commands/org/list.js +6 -6
  78. package/dist/commands/org/switch.js +7 -7
  79. package/dist/commands/packs/add-instruction.js +4 -4
  80. package/dist/commands/packs/apply.js +4 -4
  81. package/dist/commands/packs/create.js +4 -4
  82. package/dist/commands/packs/fork.js +4 -4
  83. package/dist/commands/packs/get.js +4 -4
  84. package/dist/commands/packs/list.js +4 -4
  85. package/dist/commands/packs/remove-instruction.js +4 -4
  86. package/dist/commands/proxy/env.js +4 -4
  87. package/dist/commands/proxy/logs.js +4 -4
  88. package/dist/commands/proxy/restart.js +4 -4
  89. package/dist/commands/proxy/setup.js +4 -4
  90. package/dist/commands/proxy/start.js +4 -4
  91. package/dist/commands/proxy/status.js +4 -4
  92. package/dist/commands/proxy/stop.js +4 -4
  93. package/dist/commands/research/backfill.js +7 -7
  94. package/dist/commands/research/tail-transcript.js +7 -7
  95. package/dist/commands/service/install.js +9 -4
  96. package/dist/commands/service/install.js.map +2 -2
  97. package/dist/commands/service/status.js +4 -4
  98. package/dist/commands/service/uninstall.js +4 -4
  99. package/dist/commands/sessions/analyze.js +4 -4
  100. package/dist/commands/sessions/end.js +4 -4
  101. package/dist/commands/sessions/import.js +4 -4
  102. package/dist/commands/sessions/list.js +4 -4
  103. package/dist/commands/sessions/start.js +6 -6
  104. package/dist/commands/setup.js +5 -5
  105. package/dist/commands/skills/export-approved.js +4 -4
  106. package/dist/commands/skills/install.js +4 -4
  107. package/dist/commands/skills/list.js +4 -4
  108. package/dist/commands/skills/publish.js +4 -4
  109. package/dist/commands/skills/search.js +4 -4
  110. package/dist/commands/skills/update.js +4 -4
  111. package/dist/commands/suggestions/accept.js +4 -4
  112. package/dist/commands/suggestions/dismiss.js +4 -4
  113. package/dist/commands/suggestions/list.js +4 -4
  114. package/dist/commands/suggestions/refresh.js +4 -4
  115. package/dist/dashboard/Dashboard.js +17 -15
  116. package/dist/dashboard/Dashboard.js.map +1 -1
  117. package/dist/dashboard/data.js +4 -2
  118. package/dist/dashboard/launcher/LauncherOverlay.js +6 -4
  119. package/dist/dashboard/launcher/api.js +3 -1
  120. package/dist/dashboard/launcher/useLaunchJobs.js +4 -2
  121. package/dist/{dist-NEECHU47.js → dist-UNYP5PJR.js} +2 -2
  122. package/dist/lib/active-org-refresh.js +3 -3
  123. package/dist/lib/agent-loop.js +19 -19
  124. package/dist/lib/antigravity-transcript.js +2 -2
  125. package/dist/lib/api-client.js +3 -1
  126. package/dist/lib/eval-benchmark.js +2 -2
  127. package/dist/lib/eval-conversation-handler.js +2 -2
  128. package/dist/lib/handlers/cron-suggest-instructions.js +4 -4
  129. package/dist/lib/handlers/process-announcement.js +3 -3
  130. package/dist/lib/handlers/process-changelog.js +3 -3
  131. package/dist/lib/handlers/process-conversation.js +3 -3
  132. package/dist/lib/handlers/process-eval.js +2 -2
  133. package/dist/lib/handlers/process-insights.js +2 -2
  134. package/dist/lib/handlers/process-launch.js +4 -4
  135. package/dist/lib/handlers/process-run-cleanup.js +4 -4
  136. package/dist/lib/handlers/process-session-goal.js +2 -2
  137. package/dist/lib/manual-tasks.js +7 -7
  138. package/dist/lib/research-client.js +2 -2
  139. package/dist/lib/setup-steps.js +2 -2
  140. package/dist/lib/terminal-target-heartbeat.js +2 -2
  141. package/dist/lib/worktree.js +2 -2
  142. package/oclif.manifest.json +1 -40
  143. package/package.json +7 -7
  144. package/dist/chunk-46LMTDRE.js.map +0 -7
  145. package/dist/chunk-CWFVBGX2.js.map +0 -7
  146. package/dist/chunk-K3BFZ7KG.js.map +0 -7
  147. package/dist/chunk-N52AHNBH.js.map +0 -7
  148. package/dist/chunk-YQFCUKNI.js.map +0 -7
  149. package/dist/commands/signals/report.js +0 -43
  150. package/dist/commands/signals/report.js.map +0 -7
  151. package/dist/lib/handlers/cron-close-stale-sessions.js +0 -19
  152. package/dist/lib/handlers/cron-close-stale-sessions.js.map +0 -7
  153. package/dist/lib/handlers/cron-data-integrity-audit.js +0 -22
  154. package/dist/lib/handlers/cron-data-integrity-audit.js.map +0 -7
  155. package/dist/lib/provider-aggregator.js +0 -59
  156. package/dist/lib/provider-aggregator.js.map +0 -7
  157. /package/dist/{chunk-7DRLX3DN.js.map → chunk-3POYC5NA.js.map} +0 -0
  158. /package/dist/{chunk-TJ2M5QVL.js.map → chunk-3QH73QOQ.js.map} +0 -0
  159. /package/dist/{chunk-AOIY5RT6.js.map → chunk-4LHEN2FS.js.map} +0 -0
  160. /package/dist/{chunk-LJ5OT5XN.js.map → chunk-7K4ILWS7.js.map} +0 -0
  161. /package/dist/{chunk-5ZOLDIZQ.js.map → chunk-BCIUSUEV.js.map} +0 -0
  162. /package/dist/{chunk-TDTHAOXO.js.map → chunk-DR5WLIOU.js.map} +0 -0
  163. /package/dist/{chunk-7XDWLJJP.js.map → chunk-H3C6EGR2.js.map} +0 -0
  164. /package/dist/{chunk-PHIAFGQ2.js.map → chunk-IATQXFJA.js.map} +0 -0
  165. /package/dist/{chunk-IVOCDHWA.js.map → chunk-IPOO4IGF.js.map} +0 -0
  166. /package/dist/{chunk-AUUHXCJU.js.map → chunk-JEJ3J5J6.js.map} +0 -0
  167. /package/dist/{chunk-OAQG5WBV.js.map → chunk-LAKZUE35.js.map} +0 -0
  168. /package/dist/{chunk-346TGPVR.js.map → chunk-LTT2YMYY.js.map} +0 -0
  169. /package/dist/{chunk-CCSR73HF.js.map → chunk-N5A2IQAK.js.map} +0 -0
  170. /package/dist/{chunk-IKEI4KNV.js.map → chunk-OTOWLUOJ.js.map} +0 -0
  171. /package/dist/{chunk-OKCFYPIQ.js.map → chunk-RCMXTLQF.js.map} +0 -0
  172. /package/dist/{chunk-CGUV6TUA.js.map → chunk-RUCSRN7F.js.map} +0 -0
  173. /package/dist/{chunk-4UJATBTG.js.map → chunk-SLL3OBKN.js.map} +0 -0
  174. /package/dist/{chunk-CB43W53J.js.map → chunk-SZ7VDCD6.js.map} +0 -0
  175. /package/dist/{chunk-DUR54APY.js.map → chunk-WLFX4PYR.js.map} +0 -0
  176. /package/dist/{chunk-FUS5C4SB.js.map → chunk-Y4BJXXYV.js.map} +0 -0
  177. /package/dist/{chunk-KHJUQFIK.js.map → chunk-YSEQWCN4.js.map} +0 -0
  178. /package/dist/{dist-NEECHU47.js.map → dist-UNYP5PJR.js.map} +0 -0
@@ -3459,45 +3459,6 @@
3459
3459
  "start.js"
3460
3460
  ]
3461
3461
  },
3462
- "signals:report": {
3463
- "aliases": [],
3464
- "args": {},
3465
- "description": "Report filesystem-detected languages for the current project to the server.",
3466
- "flags": {
3467
- "api-url": {
3468
- "description": "Override API base URL",
3469
- "env": "RULEMETRIC_API_URL",
3470
- "hidden": true,
3471
- "name": "api-url",
3472
- "hasDynamicHelp": false,
3473
- "multiple": false,
3474
- "type": "option"
3475
- },
3476
- "cwd": {
3477
- "description": "Project path to inspect (defaults to process.cwd())",
3478
- "name": "cwd",
3479
- "hasDynamicHelp": false,
3480
- "multiple": false,
3481
- "type": "option"
3482
- }
3483
- },
3484
- "hasDynamicHelp": false,
3485
- "hidden": true,
3486
- "hiddenAliases": [],
3487
- "id": "signals:report",
3488
- "pluginAlias": "@rulemetric/cli",
3489
- "pluginName": "@rulemetric/cli",
3490
- "pluginType": "core",
3491
- "strict": true,
3492
- "enableJsonFlag": false,
3493
- "isESM": true,
3494
- "relativePath": [
3495
- "dist",
3496
- "commands",
3497
- "signals",
3498
- "report.js"
3499
- ]
3500
- },
3501
3462
  "skills:export-approved": {
3502
3463
  "aliases": [],
3503
3464
  "args": {},
@@ -4054,5 +4015,5 @@
4054
4015
  ]
4055
4016
  }
4056
4017
  },
4057
- "version": "0.5.2"
4018
+ "version": "0.5.4"
4058
4019
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulemetric/cli",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -70,9 +70,9 @@
70
70
  "postgres": "^3.4.0",
71
71
  "react": "^19.0.0",
72
72
  "zod": "^3.24.0",
73
- "@rulemetric/hooks": "0.5.2",
74
- "@rulemetric/proxy": "0.5.2",
75
- "@rulemetric/skills-registry": "0.5.2"
73
+ "@rulemetric/hooks": "0.5.4",
74
+ "@rulemetric/skills-registry": "0.5.4",
75
+ "@rulemetric/proxy": "0.5.4"
76
76
  },
77
77
  "//deps": "Worker (`evals agent`) runtime deps: the @opentelemetry/* set, @sentry/node, and postgres are STATIC top-level imports loaded at worker startup (via bundled @rulemetric/{telemetry,db}) — they MUST be runtime deps or a clean `npm i -g` crashes with ModuleLoadError. `better-sqlite3` is optionalDependencies (below): it's a native module, lazy `require()`'d inside a try/catch (packages/session providers cursor/opencode) so a missing binary degrades gracefully — making it a hard dep would break `npm i -g` on platforms without prebuilt binaries. `resend` stays a devDep: lazy `await import('resend')` guarded by RESEND_API_KEY, which end-user workers never set (provider falls back to noop). Classification verified via import-graph scan of dist/commands/evals/agent.js + per-importer static/lazy check.",
78
78
  "optionalDependencies": {
@@ -92,11 +92,11 @@
92
92
  "vitest": "^3.2.0",
93
93
  "@rulemetric/api": "0.0.1",
94
94
  "@rulemetric/core": "0.0.1",
95
+ "@rulemetric/db": "0.0.1",
96
+ "@rulemetric/email": "0.0.1",
95
97
  "@rulemetric/session": "0.2.1",
96
98
  "@rulemetric/telemetry": "0.0.1",
97
- "@rulemetric/db": "0.0.1",
98
- "@rulemetric/typescript-config": "0.0.0",
99
- "@rulemetric/email": "0.0.1"
99
+ "@rulemetric/typescript-config": "0.0.0"
100
100
  },
101
101
  "scripts": {
102
102
  "build": "node scripts/build.mjs",
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/dashboard/data.ts"],
4
- "sourcesContent": ["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { discoverAllSessions, ClaudeCodeAdapter } from '@rulemetric/session';\nimport type { LocalStats, ApiInsights } from './types.js';\n\n/** Load auth config from env vars \u2192 ~/.config/rulemetric/env \u2192 .env.local */\nfunction ensureEnv(): void {\n if (process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN) return;\n\n // Try ~/.config/rulemetric/env\n const globalEnv = path.join(os.homedir(), '.config', 'rulemetric', 'env');\n if (loadEnvFile(globalEnv)) return;\n\n // Try .env.local in cwd\n loadEnvFile(path.join(process.cwd(), '.env.local'));\n}\n\nfunction loadEnvFile(filePath: string): boolean {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx < 0) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n const value = trimmed.slice(eqIdx + 1).trim();\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n return !!(process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN);\n } catch {\n return false;\n }\n}\n\n// Load on import\nensureEnv();\n\n/** Read local JSONL files and compute basic stats. */\nexport async function loadLocalStats(providerFilter?: string): Promise<LocalStats> {\n const stats: LocalStats = {\n totalSessions: 0,\n totalCalls: 0,\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCacheReadTokens: 0,\n totalCacheWriteTokens: 0,\n totalCostUSD: 0,\n providers: {},\n };\n\n const sources = await discoverAllSessions(providerFilter);\n stats.providers = {};\n for (const s of sources) {\n stats.providers[s.provider] = (stats.providers[s.provider] || 0) + 1;\n }\n\n // Parse Claude Code sessions from local JSONL files\n const adapter = new ClaudeCodeAdapter();\n const claudeSources = sources.filter(s => s.provider === 'claude');\n\n for (const source of claudeSources) {\n try {\n const files = fs.readdirSync(source.path).filter(f => f.endsWith('.jsonl'));\n stats.totalSessions += files.length;\n\n for (const file of files) {\n const content = fs.readFileSync(path.join(source.path, file), 'utf-8');\n const parsed = adapter.parse(content);\n\n for (const event of parsed.events) {\n if (event.tokenUsage) {\n stats.totalCalls++;\n stats.totalInputTokens += event.tokenUsage.input;\n stats.totalOutputTokens += event.tokenUsage.output;\n stats.totalCacheReadTokens += event.tokenUsage.cacheRead ?? 0;\n stats.totalCacheWriteTokens += event.tokenUsage.cacheWrite ?? 0;\n }\n }\n }\n } catch {\n // Skip unreadable directories\n }\n }\n\n // Estimate cost (Opus pricing as default)\n const inputCostPerM = 15;\n const outputCostPerM = 75;\n stats.totalCostUSD = Math.round((\n (stats.totalInputTokens / 1_000_000) * inputCostPerM +\n (stats.totalOutputTokens / 1_000_000) * outputCostPerM +\n (stats.totalCacheReadTokens / 1_000_000) * (inputCostPerM * 0.1) +\n (stats.totalCacheWriteTokens / 1_000_000) * (inputCostPerM * 1.25)\n ) * 100) / 100;\n\n return stats;\n}\n\n/** Fetch enriched insights from the API. Returns null if API is unreachable. */\nexport async function loadApiInsights(projectPath?: string): Promise<ApiInsights | null> {\n const apiUrl = process.env.RULEMETRIC_API_URL ?? 'http://localhost:3000';\n const apiKey = process.env.RULEMETRIC_API_KEY;\n const accessToken = process.env.RULEMETRIC_ACCESS_TOKEN;\n const token = apiKey ?? accessToken;\n if (!token) return null;\n\n const params = new URLSearchParams();\n if (projectPath) params.set('projectPath', projectPath);\n\n try {\n const resp = await fetch(`${apiUrl}/api/insights/compute?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) return null;\n return await resp.json() as ApiInsights;\n } catch {\n return null;\n }\n}\n\n/** Fetch linked instructions from the API. */\nexport async function loadLinkedInstructions(projectPath?: string): Promise<Array<{ name: string; linkedSessions: number }> | null> {\n const apiUrl = process.env.RULEMETRIC_API_URL ?? 'http://localhost:3000';\n const token = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;\n if (!token) return null;\n\n const params = new URLSearchParams();\n if (projectPath) params.set('projectPath', projectPath);\n\n try {\n const resp = await fetch(`${apiUrl}/api/insights/linked-instructions?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) return null;\n return await resp.json() as Array<{ name: string; linkedSessions: number }>;\n } catch {\n return null;\n }\n}\n"],
5
- "mappings": ";;;;;;AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAKpB,SAAS,YAAkB;AACzB,MAAI,QAAQ,IAAI,sBAAsB,QAAQ,IAAI,wBAAyB;AAG3E,QAAM,YAAiB,UAAQ,WAAQ,GAAG,WAAW,cAAc,KAAK;AACxE,MAAI,YAAY,SAAS,EAAG;AAG5B,cAAiB,UAAK,QAAQ,IAAI,GAAG,YAAY,CAAC;AACpD;AAEA,SAAS,YAAY,UAA2B;AAC9C,MAAI;AACF,UAAM,UAAa,gBAAa,UAAU,OAAO;AACjD,eAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,YAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,UAAI,QAAQ,EAAG;AACf,YAAM,MAAM,QAAQ,MAAM,GAAG,KAAK,EAAE,KAAK;AACzC,YAAM,QAAQ,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK;AAC5C,UAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,gBAAQ,IAAI,GAAG,IAAI;AAAA,MACrB;AAAA,IACF;AACA,WAAO,CAAC,EAAE,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,UAAU;AAGV,eAAsB,eAAe,gBAA8C;AACjF,QAAM,QAAoB;AAAA,IACxB,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,IACvB,cAAc;AAAA,IACd,WAAW,CAAC;AAAA,EACd;AAEA,QAAM,UAAU,MAAM,oBAAoB,cAAc;AACxD,QAAM,YAAY,CAAC;AACnB,aAAW,KAAK,SAAS;AACvB,UAAM,UAAU,EAAE,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,KAAK,KAAK;AAAA,EACrE;AAGA,QAAM,UAAU,IAAI,kBAAkB;AACtC,QAAM,gBAAgB,QAAQ,OAAO,OAAK,EAAE,aAAa,QAAQ;AAEjE,aAAW,UAAU,eAAe;AAClC,QAAI;AACF,YAAM,QAAW,eAAY,OAAO,IAAI,EAAE,OAAO,OAAK,EAAE,SAAS,QAAQ,CAAC;AAC1E,YAAM,iBAAiB,MAAM;AAE7B,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAa,gBAAkB,UAAK,OAAO,MAAM,IAAI,GAAG,OAAO;AACrE,cAAM,SAAS,QAAQ,MAAM,OAAO;AAEpC,mBAAW,SAAS,OAAO,QAAQ;AACjC,cAAI,MAAM,YAAY;AACpB,kBAAM;AACN,kBAAM,oBAAoB,MAAM,WAAW;AAC3C,kBAAM,qBAAqB,MAAM,WAAW;AAC5C,kBAAM,wBAAwB,MAAM,WAAW,aAAa;AAC5D,kBAAM,yBAAyB,MAAM,WAAW,cAAc;AAAA,UAChE;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,QAAM,gBAAgB;AACtB,QAAM,iBAAiB;AACvB,QAAM,eAAe,KAAK,OACvB,MAAM,mBAAmB,MAAa,gBACtC,MAAM,oBAAoB,MAAa,iBACvC,MAAM,uBAAuB,OAAc,gBAAgB,OAC3D,MAAM,wBAAwB,OAAc,gBAAgB,SAC3D,GAAG,IAAI;AAEX,SAAO;AACT;AAGA,eAAsB,gBAAgB,aAAmD;AACvF,QAAM,SAAS,QAAQ,IAAI,sBAAsB;AACjD,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,QAAQ,UAAU;AACxB,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,YAAa,QAAO,IAAI,eAAe,WAAW;AAEtD,MAAI;AACF,UAAM,OAAO,MAAM,MAAM,GAAG,MAAM,yBAAyB,MAAM,IAAI;AAAA,MACnE,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,MAC5C,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,KAAK,GAAI,QAAO;AACrB,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,uBAAuB,aAAuF;AAClI,QAAM,SAAS,QAAQ,IAAI,sBAAsB;AACjD,QAAM,QAAQ,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AAC5D,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,YAAa,QAAO,IAAI,eAAe,WAAW;AAEtD,MAAI;AACF,UAAM,OAAO,MAAM,MAAM,GAAG,MAAM,qCAAqC,MAAM,IAAI;AAAA,MAC/E,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,MAC5C,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,KAAK,GAAI,QAAO;AACrB,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/lib/api-client.ts"],
4
- "sourcesContent": ["import { fileURLToPath } from 'node:url';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { loadToken, loadEnvFileAuth } from './auth.js';\n\n/**\n * Read the CLI's own version. Walks up from this module's location to find\n * `@rulemetric/cli`'s package.json \u2014 robust whether running unbundled from\n * `src/lib/` (dev) or from a bundled chunk at a different `dist/` depth (prod),\n * where a fixed relative `../../package.json` would resolve to the wrong file.\n */\nfunction readCliVersion(): string {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 8; i++) {\n const pj = join(dir, 'package.json');\n if (existsSync(pj)) {\n try {\n const parsed = JSON.parse(readFileSync(pj, 'utf8')) as { name?: string; version?: string };\n if (parsed.name === '@rulemetric/cli' && parsed.version) return parsed.version;\n } catch {\n /* unreadable/parse error \u2014 keep walking up */\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return '0.0.0';\n}\n\nconst version = readCliVersion();\n\nexport class ApiError extends Error {\n constructor(\n public statusCode: number,\n message: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\ninterface ApiOptions {\n method?: string;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\nfunction getBaseUrl(): string {\n // Additive fallback to the env file's URL so a key/token read from that same\n // file (see the auth header below) is sent to the SERVER it belongs to,\n // not the localhost default.\n const url = process.env.RULEMETRIC_API_URL ?? loadEnvFileAuth().apiUrl ?? 'http://localhost:3000';\n\n // Enforce HTTPS for non-localhost URLs\n const parsed = new URL(url);\n if (parsed.protocol === 'http:' && parsed.hostname !== 'localhost' && parsed.hostname !== '127.0.0.1') {\n throw new Error(`API URL must use HTTPS for non-localhost hosts: ${url}`);\n }\n\n return url;\n}\n\nexport async function api<T>(path: string, options: ApiOptions = {}): Promise<T> {\n const baseUrl = getBaseUrl();\n const url = `${baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': `rulemetric-cli/${version}`,\n ...options.headers,\n };\n\n // Auth header resolution, first match wins:\n // 1. process.env.RULEMETRIC_API_KEY \u2014 exported long-lived key\n // 2. env-file RULEMETRIC_API_KEY \u2014 long-lived key on disk (create-key)\n // 3. auth.json OAuth accessToken \u2014 fresh right after `auth login`\n // 4. env-file RULEMETRIC_ACCESS_TOKEN \u2014 token persisted by login\n // The long-lived API key is preferred over the OAuth token because the latter\n // EXPIRES \u2014 auth.json can hold a stale token, so trying it first would 401\n // (\"Session expired\") even when a valid key sits right there in the env file.\n const envAuth = loadEnvFileAuth();\n const bearer =\n process.env.RULEMETRIC_API_KEY ||\n envAuth.apiKey ||\n loadToken()?.accessToken ||\n envAuth.accessToken;\n if (bearer) {\n headers['Authorization'] = `Bearer ${bearer}`;\n }\n\n // Bypass proxy for localhost API calls \u2014 HTTPS_PROXY is for Claude Code \u2192 Anthropic,\n // not for CLI \u2192 local API. Node.js fetch doesn't respect NO_PROXY reliably, so we\n // temporarily unset the proxy env vars for localhost calls.\n const parsed = new URL(url);\n const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n const savedProxy = process.env.HTTPS_PROXY;\n const savedHttpProxy = process.env.HTTP_PROXY;\n if (isLocalhost) {\n delete process.env.HTTPS_PROXY;\n delete process.env.HTTP_PROXY;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: options.method ?? 'GET',\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n } finally {\n // Restore proxy vars so claude -p calls still route through the proxy\n if (isLocalhost) {\n if (savedProxy !== undefined) process.env.HTTPS_PROXY = savedProxy;\n if (savedHttpProxy !== undefined) process.env.HTTP_PROXY = savedHttpProxy;\n }\n }\n\n let responseBody: unknown;\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n responseBody = await response.json();\n } else {\n responseBody = await response.text();\n }\n\n if (!response.ok) {\n // Extract only the error message, not the full response body\n const message =\n responseBody && typeof responseBody === 'object' && 'error' in responseBody\n ? String((responseBody as { error: string }).error)\n : `HTTP ${response.status}`;\n throw new ApiError(response.status, message);\n }\n\n return responseBody as T;\n}\n\nexport const apiGet = <T>(path: string): Promise<T> => api<T>(path);\nexport const apiPost = <T>(path: string, body: unknown): Promise<T> => api<T>(path, { method: 'POST', body });\nexport const apiPut = <T>(path: string, body: unknown): Promise<T> => api<T>(path, { method: 'PUT', body });\nexport const apiPatch = <T>(path: string, body: unknown): Promise<T> => api<T>(path, { method: 'PATCH', body });\nexport const apiDelete = <T>(path: string): Promise<T> => api<T>(path, { method: 'DELETE' });\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/llm/recommend.ts", "../../../packages/core/src/changelog/parse.ts", "../../../packages/core/src/types/instruction.ts", "../../../packages/core/src/types/prompt.ts", "../../../packages/core/src/parser/frontmatter-parser.ts"],
4
- "sourcesContent": ["import type { ProjectContext, InstructionCandidate, Recommendation } from './types.js';\n\nexport type { ProjectContext, InstructionCandidate, Recommendation };\n\nexport function buildRecommendationPrompt(project: ProjectContext, candidates: InstructionCandidate[]): string {\n const candidateList = candidates\n .map((c) => `- ID: ${c.id}\\n Name: ${c.name}\\n Description: ${c.description}\\n Tags: ${c.tags.join(', ')}\\n Preview: ${c.contentPreview}`)\n .join('\\n\\n');\n\n return `You are an expert at matching AI coding instructions to software projects.\n\n## Project\n- Name: ${project.name}\n- Description: ${project.description ?? 'No description'}\n- Languages: ${project.languages.join(', ') || 'Unknown'}\n- Topics: ${project.topics.join(', ') || 'None'}\n- Dependencies: ${project.dependencies.join(', ') || 'None'}\n\n## Available Instructions\n\n${candidateList}\n\n## Task\n\nAnalyze the project and recommend which instructions would be most useful. Consider:\n1. Language and framework alignment\n2. Project purpose and what standards/practices would help\n3. Security, testing, and quality needs based on the project type\n\nReturn your response as JSON in this exact format:\n{\n \"recommendations\": [\n { \"instructionId\": \"<id>\", \"score\": <0.0-1.0>, \"reason\": \"<one sentence explanation>\" }\n ]\n}\n\nOnly include instructions with a relevance score >= 0.5. Order by score descending. Return valid JSON only, no markdown fences.`;\n}\n\nexport function parseRecommendationResponse(response: string): Recommendation[] {\n try {\n // Try to extract JSON from the response (handle markdown fences if present)\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) return [];\n\n const parsed = JSON.parse(jsonMatch[0]);\n if (!parsed.recommendations || !Array.isArray(parsed.recommendations)) return [];\n\n return parsed.recommendations.filter(\n (r: Record<string, unknown>) =>\n typeof r.instructionId === 'string' &&\n typeof r.score === 'number' &&\n typeof r.reason === 'string',\n ) as Recommendation[];\n } catch {\n return [];\n }\n}\n", "// Keep-a-Changelog parser. Pure function, no I/O.\n//\n// Grammar (the strict subset we accept):\n//\n// # Changelog\n// (any prose / front-matter before the first `## [` heading is ignored)\n//\n// ## [Unreleased]\n// ### Added\n// - item one\n// - item two\n//\n// ## [2026.06.05] - 2026-06-05\n// ### Added\n// - \u2026\n// ### Fixed\n// - \u2026\n//\n// Rules:\n// - Version headings MUST match `## [<version>]` with optional ` - <date>`.\n// - `[Unreleased]` is parsed but flagged so callers can skip it.\n// - Section headings MUST be `### <Name>` where Name is one of the\n// KNOWN_SECTIONS set. Unknown sections are dropped silently so a stray\n// `### Notes` doesn't end up in a customer email.\n// - List items are `- `-prefixed lines. Multi-line items (continuation\n// lines indented by 2+ spaces) are joined with a single space.\n// - Anything outside a recognized list is discarded.\n\nexport const KNOWN_SECTIONS = [\n 'Added',\n 'Changed',\n 'Fixed',\n 'Removed',\n 'Deprecated',\n 'Security',\n] as const;\n\nexport type SectionName = (typeof KNOWN_SECTIONS)[number];\n\nexport interface ChangelogEntry {\n /** Verbatim version string from the heading, e.g. \"2026.06.05\" or \"Unreleased\". */\n version: string;\n /** ISO date (YYYY-MM-DD) parsed from the heading. Null for Unreleased or when omitted. */\n date: string | null;\n /** True iff version === \"Unreleased\" (case-insensitive). */\n unreleased: boolean;\n /** Section name \u2192 list of items, preserving heading order. */\n sections: Partial<Record<SectionName, string[]>>;\n}\n\nexport interface ParsedChangelog {\n entries: ChangelogEntry[];\n}\n\nconst VERSION_HEADING = /^##\\s+\\[([^\\]]+)\\](?:\\s*[-\u2013]\\s*(\\d{4}-\\d{2}-\\d{2}))?\\s*$/;\nconst SECTION_HEADING = /^###\\s+(.+?)\\s*$/;\nconst LIST_ITEM = /^[-*]\\s+(.*\\S)\\s*$/;\nconst CONTINUATION = /^ {2,}(\\S.*)$/;\n\nexport function parseChangelog(markdown: string): ParsedChangelog {\n const lines = markdown.split(/\\r?\\n/);\n const entries: ChangelogEntry[] = [];\n let current: ChangelogEntry | null = null;\n let currentSection: SectionName | null = null;\n let lastItems: string[] | null = null;\n\n for (const raw of lines) {\n const versionMatch = raw.match(VERSION_HEADING);\n if (versionMatch) {\n if (current) entries.push(current);\n const version = versionMatch[1].trim();\n current = {\n version,\n date: versionMatch[2] ?? null,\n unreleased: version.toLowerCase() === 'unreleased',\n sections: {},\n };\n currentSection = null;\n lastItems = null;\n continue;\n }\n\n if (!current) continue;\n\n const sectionMatch = raw.match(SECTION_HEADING);\n if (sectionMatch) {\n const name = sectionMatch[1].trim();\n if ((KNOWN_SECTIONS as readonly string[]).includes(name)) {\n currentSection = name as SectionName;\n if (!current.sections[currentSection]) {\n current.sections[currentSection] = [];\n }\n lastItems = current.sections[currentSection]!;\n } else {\n currentSection = null;\n lastItems = null;\n }\n continue;\n }\n\n if (!currentSection || !lastItems) continue;\n\n const itemMatch = raw.match(LIST_ITEM);\n if (itemMatch) {\n lastItems.push(itemMatch[1]);\n continue;\n }\n\n const contMatch = raw.match(CONTINUATION);\n if (contMatch && lastItems.length > 0) {\n lastItems[lastItems.length - 1] += ' ' + contMatch[1].trim();\n continue;\n }\n\n // Blank line or unrelated content \u2014 terminates continuation for the\n // previous item but doesn't close the section.\n }\n\n if (current) entries.push(current);\n return { entries };\n}\n\n/**\n * Filter to entries worth announcing: skip `[Unreleased]` and any entry\n * whose sections are all empty. Caller does dedup against the DB.\n */\nexport function announceableEntries(parsed: ParsedChangelog): ChangelogEntry[] {\n return parsed.entries.filter((e) => {\n if (e.unreleased) return false;\n return Object.values(e.sections).some((items) => items && items.length > 0);\n });\n}\n", "import { z } from 'zod';\n\nexport const INSTRUCTION_SCOPES = ['org', 'team', 'project', 'personal'] as const;\nexport type InstructionScope = (typeof INSTRUCTION_SCOPES)[number];\n\nexport const instructionFrontmatterSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n type: z.literal('instruction').default('instruction'),\n scope: z.enum(INSTRUCTION_SCOPES),\n version: z.string().min(1),\n tags: z.array(z.string()).optional(),\n compatibility: z.array(z.string()).optional(),\n slots: z.record(z.string(), z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type InstructionFrontmatter = z.infer<typeof instructionFrontmatterSchema>;\n\nexport interface Instruction {\n id: string;\n name: string;\n description: string;\n type: 'instruction';\n scope: InstructionScope;\n scopeRef: string | null;\n version: string;\n content: string;\n frontmatter: InstructionFrontmatter;\n slots: Record<string, string> | null;\n tags: string[];\n compatibility: string[];\n createdBy: string;\n createdAt: Date;\n updatedAt: Date;\n archived: boolean;\n}\n\nexport interface CreateInstructionInput {\n name: string;\n description: string;\n scope: InstructionScope;\n scopeRef?: string;\n version: string;\n content: string;\n tags?: string[];\n compatibility?: string[];\n}\n", "import { z } from 'zod';\n\nexport const promptFrontmatterSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n type: z.literal('prompt'),\n version: z.string().min(1),\n tags: z.array(z.string()).optional(),\n variables: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type PromptFrontmatter = z.infer<typeof promptFrontmatterSchema>;\n\nexport interface Prompt {\n id: string;\n name: string;\n description: string;\n type: 'prompt';\n version: string;\n content: string;\n frontmatter: PromptFrontmatter;\n variables: string[];\n tags: string[];\n createdBy: string;\n createdAt: Date;\n updatedAt: Date;\n}\n", "import matter from 'gray-matter';\nimport { z } from 'zod';\nimport { instructionFrontmatterSchema, type InstructionFrontmatter } from '../types/instruction.js';\nimport { promptFrontmatterSchema, type PromptFrontmatter } from '../types/prompt.js';\n\nexport interface ParsedInstruction {\n frontmatter: InstructionFrontmatter;\n content: string;\n slots: Record<string, string> | null;\n}\n\nexport interface ParsedPrompt {\n frontmatter: PromptFrontmatter;\n content: string;\n}\n\nexport type ParseResult =\n | { type: 'instruction'; data: ParsedInstruction }\n | { type: 'prompt'; data: ParsedPrompt };\n\nconst typeDetectorSchema = z.object({\n type: z.enum(['instruction', 'prompt']),\n});\n\nexport function parseInstruction(raw: string): ParsedInstruction {\n const { data, content } = matter(raw);\n const frontmatter = instructionFrontmatterSchema.parse(data);\n const slots = frontmatter.slots ?? null;\n\n return {\n frontmatter,\n content: content.trim(),\n slots,\n };\n}\n\nexport function parsePrompt(raw: string): ParsedPrompt {\n const { data, content } = matter(raw);\n const frontmatter = promptFrontmatterSchema.parse(data);\n\n return {\n frontmatter,\n content: content.trim(),\n };\n}\n\nexport function parse(raw: string): ParseResult {\n const { data } = matter(raw);\n const { type } = typeDetectorSchema.parse(data);\n\n if (type === 'instruction') {\n return { type: 'instruction', data: parseInstruction(raw) };\n }\n\n return { type: 'prompt', data: parsePrompt(raw) };\n}\n"],
5
- "mappings": ";AAIM,SAAU,0BAA0B,SAAyB,YAAkC;AACjG,QAAM,gBAAgB,WACjB,IAAI,CAAC,MAAM,SAAS,EAAE,EAAE;UAAa,EAAE,IAAI;iBAAoB,EAAE,WAAW;UAAa,EAAE,KAAK,KAAK,IAAI,CAAC;aAAgB,EAAE,cAAc,EAAE,EAC5I,KAAK,MAAM;AAEhB,SAAO;;;UAGD,QAAQ,IAAI;iBACL,QAAQ,eAAe,gBAAgB;eACzC,QAAQ,UAAU,KAAK,IAAI,KAAK,SAAS;YAC5C,QAAQ,OAAO,KAAK,IAAI,KAAK,MAAM;kBAC7B,QAAQ,aAAa,KAAK,IAAI,KAAK,MAAM;;;;EAIzD,aAAa;;;;;;;;;;;;;;;;;AAiBf;;;ACTO,IAAM,iBAAiB;EAC5B;EACA;EACA;EACA;EACA;EACA;;AAoBF,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,YAAY;AAClB,IAAM,eAAe;AAEf,SAAU,eAAe,UAAgB;AAC7C,QAAM,QAAQ,SAAS,MAAM,OAAO;AACpC,QAAM,UAA4B,CAAA;AAClC,MAAI,UAAiC;AACrC,MAAI,iBAAqC;AACzC,MAAI,YAA6B;AAEjC,aAAW,OAAO,OAAO;AACvB,UAAM,eAAe,IAAI,MAAM,eAAe;AAC9C,QAAI,cAAc;AAChB,UAAI;AAAS,gBAAQ,KAAK,OAAO;AACjC,YAAM,UAAU,aAAa,CAAC,EAAE,KAAI;AACpC,gBAAU;QACR;QACA,MAAM,aAAa,CAAC,KAAK;QACzB,YAAY,QAAQ,YAAW,MAAO;QACtC,UAAU,CAAA;;AAEZ,uBAAiB;AACjB,kBAAY;AACZ;IACF;AAEA,QAAI,CAAC;AAAS;AAEd,UAAM,eAAe,IAAI,MAAM,eAAe;AAC9C,QAAI,cAAc;AAChB,YAAM,OAAO,aAAa,CAAC,EAAE,KAAI;AACjC,UAAK,eAAqC,SAAS,IAAI,GAAG;AACxD,yBAAiB;AACjB,YAAI,CAAC,QAAQ,SAAS,cAAc,GAAG;AACrC,kBAAQ,SAAS,cAAc,IAAI,CAAA;QACrC;AACA,oBAAY,QAAQ,SAAS,cAAc;MAC7C,OAAO;AACL,yBAAiB;AACjB,oBAAY;MACd;AACA;IACF;AAEA,QAAI,CAAC,kBAAkB,CAAC;AAAW;AAEnC,UAAM,YAAY,IAAI,MAAM,SAAS;AACrC,QAAI,WAAW;AACb,gBAAU,KAAK,UAAU,CAAC,CAAC;AAC3B;IACF;AAEA,UAAM,YAAY,IAAI,MAAM,YAAY;AACxC,QAAI,aAAa,UAAU,SAAS,GAAG;AACrC,gBAAU,UAAU,SAAS,CAAC,KAAK,MAAM,UAAU,CAAC,EAAE,KAAI;AAC1D;IACF;EAIF;AAEA,MAAI;AAAS,YAAQ,KAAK,OAAO;AACjC,SAAO,EAAE,QAAO;AAClB;AAMM,SAAU,oBAAoB,QAAuB;AACzD,SAAO,OAAO,QAAQ,OAAO,CAAC,MAAK;AACjC,QAAI,EAAE;AAAY,aAAO;AACzB,WAAO,OAAO,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,SAAS,MAAM,SAAS,CAAC;EAC5E,CAAC;AACH;;;ACnIA,SAAS,SAAS;AAEX,IAAM,qBAAqB,CAAC,OAAO,QAAQ,WAAW,UAAU;AAGhE,IAAM,+BAA+B,EAAE,OAAO;EACnD,MAAM,EAAE,OAAM,EAAG,IAAI,CAAC;EACtB,aAAa,EAAE,OAAM,EAAG,IAAI,CAAC;EAC7B,MAAM,EAAE,QAAQ,aAAa,EAAE,QAAQ,aAAa;EACpD,OAAO,EAAE,KAAK,kBAAkB;EAChC,SAAS,EAAE,OAAM,EAAG,IAAI,CAAC;EACzB,MAAM,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,SAAQ;EAClC,eAAe,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,SAAQ;EAC3C,OAAO,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,OAAM,CAAE,EAAE,SAAQ;EAChD,UAAU,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,QAAO,CAAE,EAAE,SAAQ;CACrD;;;ACfD,SAAS,KAAAA,UAAS;AAEX,IAAM,0BAA0BA,GAAE,OAAO;EAC9C,MAAMA,GAAE,OAAM,EAAG,IAAI,CAAC;EACtB,aAAaA,GAAE,OAAM,EAAG,IAAI,CAAC;EAC7B,MAAMA,GAAE,QAAQ,QAAQ;EACxB,SAASA,GAAE,OAAM,EAAG,IAAI,CAAC;EACzB,MAAMA,GAAE,MAAMA,GAAE,OAAM,CAAE,EAAE,SAAQ;EAClC,WAAWA,GAAE,MAAMA,GAAE,OAAM,CAAE,EAAE,SAAQ;EACvC,UAAUA,GAAE,OAAOA,GAAE,OAAM,GAAIA,GAAE,QAAO,CAAE,EAAE,SAAQ;CACrD;;;ACVD,OAAO,YAAY;AACnB,SAAS,KAAAC,UAAS;AAmBlB,IAAM,qBAAqBC,GAAE,OAAO;EAClC,MAAMA,GAAE,KAAK,CAAC,eAAe,QAAQ,CAAC;CACvC;",
6
- "names": ["z", "z", "z"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/dashboard/launcher/api.ts"],
4
- "sourcesContent": ["import type { LaunchJob, AvailableLauncher, CreateLaunchPayload } from './types.js';\n\nfunction apiUrl(): string {\n return process.env.RULEMETRIC_API_URL ?? 'http://localhost:3000';\n}\n\nfunction authToken(): string {\n const t = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;\n if (!t) throw new Error('not signed in \u2014 run `rulemetric auth login`');\n return t;\n}\n\nasync function request<T>(path: string, init?: RequestInit): Promise<T> {\n const resp = await fetch(`${apiUrl()}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${authToken()}`,\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(10_000),\n });\n if (!resp.ok) {\n throw new Error(`${resp.status} ${resp.statusText}`);\n }\n return (await resp.json()) as T;\n}\n\nexport function fetchLaunchJobs({ limit }: { limit: number }): Promise<LaunchJob[]> {\n return request<LaunchJob[]>(`/api/launch-jobs?limit=${limit}`);\n}\n\nexport function createLaunchJob(payload: CreateLaunchPayload): Promise<LaunchJob> {\n return request<LaunchJob>('/api/launch-jobs', {\n method: 'POST',\n body: JSON.stringify(payload),\n });\n}\n\nexport function cancelLaunchJob(id: string): Promise<{ ok: true }> {\n return request<{ ok: true }>(`/api/launch-jobs/${id}/cancel`, { method: 'POST' });\n}\n\nexport function listLaunchers(): Promise<AvailableLauncher[]> {\n return request<AvailableLauncher[]>('/api/launchers');\n}\n"],
5
- "mappings": ";AAEA,SAAS,SAAiB;AACxB,SAAO,QAAQ,IAAI,sBAAsB;AAC3C;AAEA,SAAS,YAAoB;AAC3B,QAAM,IAAI,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AACxD,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,kDAA6C;AACrE,SAAO;AACT;AAEA,eAAe,QAAW,MAAc,MAAgC;AACtE,QAAM,OAAO,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI;AAAA,IAC7C,GAAG;AAAA,IACH,SAAS;AAAA,MACP,eAAe,UAAU,UAAU,CAAC;AAAA,MACpC,gBAAgB;AAAA,MAChB,GAAI,MAAM,WAAW,CAAC;AAAA,IACxB;AAAA,IACA,QAAQ,YAAY,QAAQ,GAAM;AAAA,EACpC,CAAC;AACD,MAAI,CAAC,KAAK,IAAI;AACZ,UAAM,IAAI,MAAM,GAAG,KAAK,MAAM,IAAI,KAAK,UAAU,EAAE;AAAA,EACrD;AACA,SAAQ,MAAM,KAAK,KAAK;AAC1B;AAEO,SAAS,gBAAgB,EAAE,MAAM,GAA4C;AAClF,SAAO,QAAqB,0BAA0B,KAAK,EAAE;AAC/D;AAEO,SAAS,gBAAgB,SAAkD;AAChF,SAAO,QAAmB,oBAAoB;AAAA,IAC5C,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,EAC9B,CAAC;AACH;AAEO,SAAS,gBAAgB,IAAmC;AACjE,SAAO,QAAsB,oBAAoB,EAAE,WAAW,EAAE,QAAQ,OAAO,CAAC;AAClF;AAEO,SAAS,gBAA8C;AAC5D,SAAO,QAA6B,gBAAgB;AACtD;",
6
- "names": []
7
- }