issue-flow 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -97
- package/dist/agent-4DHRKZ2Z.js +32 -0
- package/dist/{analyze-Q4ONIWRZ.js → analyze-UEJ2R3H5.js} +42 -41
- package/dist/analyze-UEJ2R3H5.js.map +1 -0
- package/dist/{apply-EEFPY2W4.js → apply-QDYNQMUX.js} +22 -24
- package/dist/apply-QDYNQMUX.js.map +1 -0
- package/dist/artifacts-AMJQJFFV.js +82 -0
- package/dist/artifacts-AMJQJFFV.js.map +1 -0
- package/dist/{bench-WWWXLTFH.js → bench-RNRXVEFK.js} +42 -42
- package/dist/{chunk-RYOUZ6EK.js → chunk-23VHVVKW.js} +3 -3
- package/dist/chunk-2EYLOS5I.js +99 -0
- package/dist/chunk-2EYLOS5I.js.map +1 -0
- package/dist/{chunk-C5TL7T4V.js → chunk-2YM2VH6R.js} +2 -2
- package/dist/{chunk-XUEMATVY.js → chunk-37O2FMAN.js} +28 -25
- package/dist/chunk-37O2FMAN.js.map +1 -0
- package/dist/chunk-44RF3VFG.js +717 -0
- package/dist/chunk-44RF3VFG.js.map +1 -0
- package/dist/chunk-6AOZCWN2.js +21 -0
- package/dist/chunk-6AOZCWN2.js.map +1 -0
- package/dist/chunk-7MJGYPHF.js +1571 -0
- package/dist/chunk-7MJGYPHF.js.map +1 -0
- package/dist/{chunk-SA6HXL4Y.js → chunk-7WBUEBD5.js} +9 -9
- package/dist/chunk-7WBUEBD5.js.map +1 -0
- package/dist/chunk-7ZZUSMBJ.js +35 -0
- package/dist/chunk-7ZZUSMBJ.js.map +1 -0
- package/dist/{chunk-QJ44VG5G.js → chunk-ADH6RJNX.js} +3 -3
- package/dist/{chunk-34OCSKOB.js → chunk-AKL5UPR6.js} +159 -114
- package/dist/chunk-AKL5UPR6.js.map +1 -0
- package/dist/{chunk-7F7LGMVO.js → chunk-BTBJ5UOO.js} +12 -12
- package/dist/{chunk-7F7LGMVO.js.map → chunk-BTBJ5UOO.js.map} +1 -1
- package/dist/{chunk-HOAHMERN.js → chunk-CLZ6RRZL.js} +21 -21
- package/dist/chunk-DBLXLKGU.js +1201 -0
- package/dist/chunk-DBLXLKGU.js.map +1 -0
- package/dist/{chunk-DUS5ZNKL.js → chunk-DIMDAYZS.js} +7 -6
- package/dist/chunk-DZ3DZ3EN.js +278 -0
- package/dist/chunk-DZ3DZ3EN.js.map +1 -0
- package/dist/{chunk-CRGIQFUQ.js → chunk-E2H3JV2E.js} +3 -1
- package/dist/chunk-E2H3JV2E.js.map +1 -0
- package/dist/{chunk-45WZ6GMI.js → chunk-EORDSKWZ.js} +17 -17
- package/dist/chunk-EORDSKWZ.js.map +1 -0
- package/dist/{chunk-LTH6XYZ3.js → chunk-EYKPWHT7.js} +40 -30
- package/dist/chunk-EYKPWHT7.js.map +1 -0
- package/dist/{chunk-OODXFCQV.js → chunk-FU2FQ4JE.js} +14 -16
- package/dist/{chunk-OODXFCQV.js.map → chunk-FU2FQ4JE.js.map} +1 -1
- package/dist/{chunk-V7QOIQYC.js → chunk-G442RDFX.js} +9 -23
- package/dist/{chunk-V7QOIQYC.js.map → chunk-G442RDFX.js.map} +1 -1
- package/dist/{chunk-QPGEFLMY.js → chunk-I64N6RL6.js} +7 -7
- package/dist/{chunk-KRAGAUKD.js → chunk-JBYXJOJJ.js} +201 -64
- package/dist/chunk-JBYXJOJJ.js.map +1 -0
- package/dist/{chunk-SOM4QA6C.js → chunk-JCR5C5A7.js} +93 -18
- package/dist/chunk-JCR5C5A7.js.map +1 -0
- package/dist/{chunk-RNFUVKC3.js → chunk-K5NM26NV.js} +30 -13
- package/dist/chunk-K5NM26NV.js.map +1 -0
- package/dist/{chunk-YVPZUN6X.js → chunk-KUA6KBBD.js} +335 -38
- package/dist/chunk-KUA6KBBD.js.map +1 -0
- package/dist/{chunk-KMCS76ZW.js → chunk-KUL64XUF.js} +44 -12
- package/dist/chunk-KUL64XUF.js.map +1 -0
- package/dist/{chunk-HAKDLR6N.js → chunk-MAJ6QDRL.js} +65 -78
- package/dist/chunk-MAJ6QDRL.js.map +1 -0
- package/dist/{chunk-DGRTJD5R.js → chunk-MML2G7IC.js} +7 -7
- package/dist/chunk-NP47HRX2.js +136 -0
- package/dist/chunk-NP47HRX2.js.map +1 -0
- package/dist/{chunk-3R27MJ5R.js → chunk-PFWHHYEO.js} +3 -3
- package/dist/{chunk-ECU7YO7S.js → chunk-PM5YWJYO.js} +22 -6
- package/dist/chunk-PM5YWJYO.js.map +1 -0
- package/dist/{chunk-E4I6MMHD.js → chunk-PXPTIXJF.js} +154 -101
- package/dist/chunk-PXPTIXJF.js.map +1 -0
- package/dist/{chunk-CWSQVHVV.js → chunk-QJHZ3HYJ.js} +248 -102
- package/dist/chunk-QJHZ3HYJ.js.map +1 -0
- package/dist/{chunk-LI35PIIS.js → chunk-RDPK7LYK.js} +20 -117
- package/dist/chunk-RDPK7LYK.js.map +1 -0
- package/dist/{chunk-PMLE7KAQ.js → chunk-RMIBLFG3.js} +30 -14
- package/dist/chunk-RMIBLFG3.js.map +1 -0
- package/dist/{chunk-62GVVZQO.js → chunk-T736DSZI.js} +32 -316
- package/dist/chunk-T736DSZI.js.map +1 -0
- package/dist/{chunk-TZYINKCC.js → chunk-UDUUUFQF.js} +57 -29
- package/dist/chunk-UDUUUFQF.js.map +1 -0
- package/dist/{chunk-NEWNXZ65.js → chunk-V7GETODQ.js} +36 -28
- package/dist/{chunk-NEWNXZ65.js.map → chunk-V7GETODQ.js.map} +1 -1
- package/dist/{chunk-PPZ3K4YM.js → chunk-VHQMMY2D.js} +2 -2
- package/dist/{chunk-ZVZMWNCG.js → chunk-VJ3PF6B7.js} +50 -16
- package/dist/chunk-VJ3PF6B7.js.map +1 -0
- package/dist/{chunk-L6HSKTQE.js → chunk-W7LZLJAF.js} +4 -4
- package/dist/{chunk-6K2LCFG6.js → chunk-WB4FA2EH.js} +70 -81
- package/dist/chunk-WB4FA2EH.js.map +1 -0
- package/dist/{chunk-LGHND47K.js → chunk-WQSGL5LX.js} +22 -16
- package/dist/chunk-WQSGL5LX.js.map +1 -0
- package/dist/{chunk-ICM463EO.js → chunk-XNK5UN2D.js} +5 -649
- package/dist/chunk-XNK5UN2D.js.map +1 -0
- package/dist/{chunk-7UMMFOL2.js → chunk-Y2KOWABB.js} +39 -24
- package/dist/chunk-Y2KOWABB.js.map +1 -0
- package/dist/{chunk-QF7VEL3M.js → chunk-YC24E66P.js} +568 -158
- package/dist/chunk-YC24E66P.js.map +1 -0
- package/dist/{chunk-EG2MGDP5.js → chunk-Z6RCKCVB.js} +52 -46
- package/dist/chunk-Z6RCKCVB.js.map +1 -0
- package/dist/{chunk-YUNBOUQH.js → chunk-ZPGNVBWY.js} +8 -8
- package/dist/cli.js +132 -62
- package/dist/cli.js.map +1 -1
- package/dist/compat-OJG76J4I.js +24 -0
- package/dist/{config-LEBZZCJP.js → config-6YTWPDBK.js} +20 -17
- package/dist/{contract-JH2WBIO6.js → contract-HWLFFL3F.js} +2 -2
- package/dist/{conventions-XOT6YW5L.js → conventions-5UPOTU42.js} +20 -16
- package/dist/{conventions-XOT6YW5L.js.map → conventions-5UPOTU42.js.map} +1 -1
- package/dist/db-QAZG4LQD.js +264 -0
- package/dist/db-QAZG4LQD.js.map +1 -0
- package/dist/diagnostics-YEFB42E5.js +25 -0
- package/dist/execute-QCT64D37.js +38 -0
- package/dist/{generate-JGW5JSKB.js → generate-QATMDKOK.js} +46 -43
- package/dist/generate-QATMDKOK.js.map +1 -0
- package/dist/{git-A2IP32PQ.js → git-XGOECXWG.js} +2 -3
- package/dist/history-NBPUZVGQ.js +101 -0
- package/dist/history-NBPUZVGQ.js.map +1 -0
- package/dist/init-4LB2YKWP.js +28 -0
- package/dist/{operations-O4FORFIH.js → operations-RUQP2Y2F.js} +78 -52
- package/dist/operations-RUQP2Y2F.js.map +1 -0
- package/dist/{permissions-G4XCAESF.js → permissions-QZPUUBSO.js} +5 -6
- package/dist/plan-2NMSHTMD.js +38 -0
- package/dist/{policy-U5NBFAO5.js → policy-RKKFF5A2.js} +17 -15
- package/dist/{policy-U5NBFAO5.js.map → policy-RKKFF5A2.js.map} +1 -1
- package/dist/pr-QKFO5HI3.js +42 -0
- package/dist/pr-review-H2BFD6F2.js +33 -0
- package/dist/prd-ET6XKYRS.js +37 -0
- package/dist/{ps-76L6ZAZL.js → ps-UIKSOUAQ.js} +26 -15
- package/dist/ps-UIKSOUAQ.js.map +1 -0
- package/dist/{recorder-2BAKPBRA.js → recorder-LOU3PTIE.js} +11 -7
- package/dist/registry-HV7M6MAH.js +17 -0
- package/dist/repository-RCRR6RDE.js +80 -0
- package/dist/resume-BWJZGBLZ.js +278 -0
- package/dist/resume-BWJZGBLZ.js.map +1 -0
- package/dist/review-2MTZLNSS.js +38 -0
- package/dist/routing-RM5ABHHD.js +35 -0
- package/dist/run-XMACQBRJ.js +61 -0
- package/dist/{session-publisher-KAJQRHNZ.js → session-publisher-Q5TNEZPX.js} +3 -3
- package/dist/session-publisher-Q5TNEZPX.js.map +1 -0
- package/dist/{state-manager-UPHO2EA2.js → state-manager-SRN4VJSX.js} +9 -4
- package/dist/state-manager-SRN4VJSX.js.map +1 -0
- package/dist/{usage-KTMYXAPF.js → usage-JOODVE5O.js} +69 -63
- package/dist/usage-JOODVE5O.js.map +1 -0
- package/dist/web-TLMWJ2BM.js +205 -0
- package/dist/web-TLMWJ2BM.js.map +1 -0
- package/package.json +22 -8
- package/prompts/analyze.md +16 -19
- package/prompts/execute.md +73 -144
- package/prompts/generate.md +23 -10
- package/prompts/plan.md +32 -60
- package/prompts/pr-review.md +58 -40
- package/prompts/pr.md +50 -16
- package/prompts/prd.md +26 -19
- package/prompts/review.md +41 -18
- package/web/public/app.js +111 -112
- package/dist/agent-HMZTXCRT.js +0 -30
- package/dist/analyze-Q4ONIWRZ.js.map +0 -1
- package/dist/apply-EEFPY2W4.js.map +0 -1
- package/dist/chunk-34OCSKOB.js.map +0 -1
- package/dist/chunk-45WZ6GMI.js.map +0 -1
- package/dist/chunk-62GVVZQO.js.map +0 -1
- package/dist/chunk-6K2LCFG6.js.map +0 -1
- package/dist/chunk-7UMMFOL2.js.map +0 -1
- package/dist/chunk-CRGIQFUQ.js.map +0 -1
- package/dist/chunk-CWSQVHVV.js.map +0 -1
- package/dist/chunk-E4I6MMHD.js.map +0 -1
- package/dist/chunk-ECU7YO7S.js.map +0 -1
- package/dist/chunk-EG2MGDP5.js.map +0 -1
- package/dist/chunk-HAKDLR6N.js.map +0 -1
- package/dist/chunk-ICM463EO.js.map +0 -1
- package/dist/chunk-KMCS76ZW.js.map +0 -1
- package/dist/chunk-KRAGAUKD.js.map +0 -1
- package/dist/chunk-LGHND47K.js.map +0 -1
- package/dist/chunk-LI35PIIS.js.map +0 -1
- package/dist/chunk-LTH6XYZ3.js.map +0 -1
- package/dist/chunk-PMLE7KAQ.js.map +0 -1
- package/dist/chunk-QF7VEL3M.js.map +0 -1
- package/dist/chunk-RNFUVKC3.js.map +0 -1
- package/dist/chunk-SA6HXL4Y.js.map +0 -1
- package/dist/chunk-SOM4QA6C.js.map +0 -1
- package/dist/chunk-TZYINKCC.js.map +0 -1
- package/dist/chunk-WCCZJL7W.js +0 -141
- package/dist/chunk-WCCZJL7W.js.map +0 -1
- package/dist/chunk-XEYH6ZZI.js +0 -289
- package/dist/chunk-XEYH6ZZI.js.map +0 -1
- package/dist/chunk-XUEMATVY.js.map +0 -1
- package/dist/chunk-XZUEFTUP.js +0 -243
- package/dist/chunk-XZUEFTUP.js.map +0 -1
- package/dist/chunk-YVPZUN6X.js.map +0 -1
- package/dist/chunk-ZVZMWNCG.js.map +0 -1
- package/dist/diagnostics-HTCWF7F4.js +0 -23
- package/dist/execute-LELOSR5T.js +0 -37
- package/dist/generate-JGW5JSKB.js.map +0 -1
- package/dist/init-TO6MUXO4.js +0 -26
- package/dist/operations-O4FORFIH.js.map +0 -1
- package/dist/plan-OXAT344Q.js +0 -34
- package/dist/pr-UZHNKKZC.js +0 -39
- package/dist/pr-review-Q4ACAWDM.js +0 -32
- package/dist/prd-6CYEMLDY.js +0 -33
- package/dist/ps-76L6ZAZL.js.map +0 -1
- package/dist/registry-XLHHYLTR.js +0 -15
- package/dist/resume-URCU6CIJ.js +0 -244
- package/dist/resume-URCU6CIJ.js.map +0 -1
- package/dist/review-LVZT2TMW.js +0 -35
- package/dist/routing-EK6RBZM4.js +0 -33
- package/dist/run-2RXJCJKT.js +0 -56
- package/dist/usage-KTMYXAPF.js.map +0 -1
- package/dist/web-B5UPHHR5.js +0 -172
- package/dist/web-B5UPHHR5.js.map +0 -1
- /package/dist/{agent-HMZTXCRT.js.map → agent-4DHRKZ2Z.js.map} +0 -0
- /package/dist/{bench-WWWXLTFH.js.map → bench-RNRXVEFK.js.map} +0 -0
- /package/dist/{chunk-RYOUZ6EK.js.map → chunk-23VHVVKW.js.map} +0 -0
- /package/dist/{chunk-C5TL7T4V.js.map → chunk-2YM2VH6R.js.map} +0 -0
- /package/dist/{chunk-QJ44VG5G.js.map → chunk-ADH6RJNX.js.map} +0 -0
- /package/dist/{chunk-HOAHMERN.js.map → chunk-CLZ6RRZL.js.map} +0 -0
- /package/dist/{chunk-DUS5ZNKL.js.map → chunk-DIMDAYZS.js.map} +0 -0
- /package/dist/{chunk-QPGEFLMY.js.map → chunk-I64N6RL6.js.map} +0 -0
- /package/dist/{chunk-DGRTJD5R.js.map → chunk-MML2G7IC.js.map} +0 -0
- /package/dist/{chunk-3R27MJ5R.js.map → chunk-PFWHHYEO.js.map} +0 -0
- /package/dist/{chunk-PPZ3K4YM.js.map → chunk-VHQMMY2D.js.map} +0 -0
- /package/dist/{chunk-L6HSKTQE.js.map → chunk-W7LZLJAF.js.map} +0 -0
- /package/dist/{chunk-YUNBOUQH.js.map → chunk-ZPGNVBWY.js.map} +0 -0
- /package/dist/{config-LEBZZCJP.js.map → compat-OJG76J4I.js.map} +0 -0
- /package/dist/{contract-JH2WBIO6.js.map → config-6YTWPDBK.js.map} +0 -0
- /package/dist/{diagnostics-HTCWF7F4.js.map → contract-HWLFFL3F.js.map} +0 -0
- /package/dist/{execute-LELOSR5T.js.map → diagnostics-YEFB42E5.js.map} +0 -0
- /package/dist/{git-A2IP32PQ.js.map → execute-QCT64D37.js.map} +0 -0
- /package/dist/{init-TO6MUXO4.js.map → git-XGOECXWG.js.map} +0 -0
- /package/dist/{permissions-G4XCAESF.js.map → init-4LB2YKWP.js.map} +0 -0
- /package/dist/{plan-OXAT344Q.js.map → permissions-QZPUUBSO.js.map} +0 -0
- /package/dist/{pr-UZHNKKZC.js.map → plan-2NMSHTMD.js.map} +0 -0
- /package/dist/{pr-review-Q4ACAWDM.js.map → pr-QKFO5HI3.js.map} +0 -0
- /package/dist/{prd-6CYEMLDY.js.map → pr-review-H2BFD6F2.js.map} +0 -0
- /package/dist/{recorder-2BAKPBRA.js.map → prd-ET6XKYRS.js.map} +0 -0
- /package/dist/{registry-XLHHYLTR.js.map → recorder-LOU3PTIE.js.map} +0 -0
- /package/dist/{review-LVZT2TMW.js.map → registry-HV7M6MAH.js.map} +0 -0
- /package/dist/{routing-EK6RBZM4.js.map → repository-RCRR6RDE.js.map} +0 -0
- /package/dist/{run-2RXJCJKT.js.map → review-2MTZLNSS.js.map} +0 -0
- /package/dist/{session-publisher-KAJQRHNZ.js.map → routing-RM5ABHHD.js.map} +0 -0
- /package/dist/{state-manager-UPHO2EA2.js.map → run-XMACQBRJ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/routing/models.ts","../src/routing/policy.ts","../src/routing/priors.ts","../src/routing/analyze.ts","../src/routing/capabilities.ts","../src/routing/score.ts","../src/routing/decide.ts"],"sourcesContent":["import type { AgentCapabilities } from '../agents/types.js';\n\nexport const MODEL_CATALOG_VERSION = '3';\n\nexport type ModelTier = 'fast' | 'mid' | 'strong';\n\nexport interface ModelEntry {\n id: string | null;\n tier: ModelTier;\n relativeCost: number;\n relativeLatency: number;\n}\n\n/**\n * Deliberately hand-maintained. Harnesses do not expose a stable price/tier API,\n * so relative values are more durable than USD prices and keep the router pure.\n */\nexport const MODEL_CATALOG: Record<string, readonly ModelEntry[]> = {\n 'claude-code': [\n { id: 'haiku', tier: 'fast', relativeCost: 1, relativeLatency: 1 },\n { id: 'sonnet', tier: 'mid', relativeCost: 3.5, relativeLatency: 1.5 },\n { id: 'opus', tier: 'strong', relativeCost: 8, relativeLatency: 2.2 },\n ],\n 'codex-cli': [\n { id: 'gpt-5.6-luna', tier: 'fast', relativeCost: 1, relativeLatency: 1 },\n { id: 'gpt-5.6-terra', tier: 'mid', relativeCost: 3, relativeLatency: 1.45 },\n { id: 'gpt-5.6-sol', tier: 'strong', relativeCost: 7, relativeLatency: 2.1 },\n ],\n 'cursor-cli': [\n { id: 'auto-fast', tier: 'fast', relativeCost: 1, relativeLatency: 1 },\n { id: 'auto', tier: 'mid', relativeCost: 3, relativeLatency: 1.5 },\n { id: 'auto-strong', tier: 'strong', relativeCost: 7, relativeLatency: 2.1 },\n ],\n 'antigravity-cli': [\n { id: 'gemini-3.5-flash-low', tier: 'fast', relativeCost: 1, relativeLatency: 1 },\n { id: 'gemini-3.5-flash-medium', tier: 'mid', relativeCost: 2.5, relativeLatency: 1.4 },\n { id: 'gemini-3.5-pro-high', tier: 'strong', relativeCost: 6, relativeLatency: 2 },\n ],\n // OpenCode Go: relative cost tracks 5h quota intensity, kept in the 1–8\n // band so preferredTier still wins over raw request-count ratios.\n 'opencode-cli': [\n { id: 'opencode-go/mimo-v2.5', tier: 'fast', relativeCost: 1, relativeLatency: 1 },\n { id: 'opencode-go/qwen3.8-flash', tier: 'mid', relativeCost: 2.5, relativeLatency: 1.3 },\n { id: 'opencode-go/gpt-5.6-luna', tier: 'strong', relativeCost: 5, relativeLatency: 1.8 },\n ],\n};\n\nconst DEFAULT_ONLY: readonly ModelEntry[] = [\n { id: null, tier: 'mid', relativeCost: 1, relativeLatency: 1 },\n];\n\nexport function modelsFor(harness: string, capabilities: AgentCapabilities): readonly ModelEntry[] {\n if (!capabilities.modelSelection) return DEFAULT_ONLY;\n return MODEL_CATALOG[harness] ?? DEFAULT_ONLY;\n}\n\nexport function modelForTier(harness: string, tier: ModelTier): ModelEntry | null {\n return MODEL_CATALOG[harness]?.find((entry) => entry.tier === tier) ?? null;\n}\n","import type { AgentPhase, AgentProviderId } from '../agents/types.js';\nimport { type ModelTier, modelForTier } from './models.js';\nimport type { ExecutionTarget } from './types.js';\n\nexport const RECOMMENDED_POLICY_VERSION = '2';\n\nexport type OptimizeFor = 'cost-speed' | 'time-to-correct' | 'quality' | 'balanced';\n\n/**\n * Phase objectives for the opinionated policy. Affinity is a soft prior /\n * tie-break — never an eligibility filter that eliminates other harnesses.\n */\nexport interface RecommendedPolicyEntry {\n preferredTier: ModelTier;\n optimizeFor: OptimizeFor;\n escalateTo?: ModelTier;\n independentFrom?: AgentPhase;\n /** When true (default), conditional providers may win if no ready peer exists. */\n allowConditional?: boolean;\n /** Soft harness affinity for scoring — not a hard pin. */\n affinityHarness?: string;\n}\n\n/** The token-economy guidance from docs/agents.md, made executable and reviewable. */\nexport const RECOMMENDED_POLICY: Record<AgentPhase, RecommendedPolicyEntry> = {\n analyze: {\n preferredTier: 'fast',\n optimizeFor: 'cost-speed',\n affinityHarness: 'codex-cli',\n },\n generate: {\n preferredTier: 'mid',\n optimizeFor: 'balanced',\n affinityHarness: 'claude-code',\n },\n prd: {\n preferredTier: 'mid',\n optimizeFor: 'balanced',\n affinityHarness: 'claude-code',\n },\n plan: {\n preferredTier: 'fast',\n optimizeFor: 'cost-speed',\n affinityHarness: 'codex-cli',\n },\n execute: {\n preferredTier: 'mid',\n escalateTo: 'strong',\n optimizeFor: 'time-to-correct',\n affinityHarness: 'claude-code',\n },\n review: {\n preferredTier: 'strong',\n optimizeFor: 'quality',\n independentFrom: 'execute',\n affinityHarness: 'codex-cli',\n },\n pr: {\n preferredTier: 'fast',\n optimizeFor: 'cost-speed',\n affinityHarness: 'codex-cli',\n },\n 'pr-review': {\n preferredTier: 'strong',\n optimizeFor: 'quality',\n affinityHarness: 'codex-cli',\n },\n};\n\nconst PROVIDERS: Record<string, AgentProviderId> = {\n 'claude-code': 'claude',\n 'codex-cli': 'codex',\n 'cursor-cli': 'cursor',\n 'antigravity-cli': 'antigravity',\n 'opencode-cli': 'opencode',\n};\n\nexport function recommendedFor(phase: AgentPhase): RecommendedPolicyEntry {\n return RECOMMENDED_POLICY[phase];\n}\n\n/**\n * Illustrative affinity target for `routing explain`. The live decision may\n * pick a different harness when readiness or score says so.\n */\nexport function recommendedTarget(phase: AgentPhase): ExecutionTarget | null {\n const entry = recommendedFor(phase);\n const harness = entry.affinityHarness;\n if (harness === undefined) return null;\n const model = modelForTier(harness, entry.preferredTier);\n const provider = PROVIDERS[harness];\n if (model === null || provider === undefined) return null;\n return { harness, provider, model: model.id, tier: entry.preferredTier };\n}\n","import type { ModelTier } from './models.js';\nimport type { TaskClass } from './types.js';\n\n/** Bump when a cell's provenance changes. */\nexport const PRIORS_VERSION = '3';\n\n/**\n * Cold-start priors. Provenance: author judgement on 2026-08-30 from the\n * #79 baseline and the #76 capability matrix — not measured affinity.\n * `opencode-cli` stays conservative: intra-OpenCode model choice lives in\n * `opencode-go.ts`, not in these harness priors.\n */\ntype HarnessPriors = Record<string, Record<ModelTier, number>>;\n\nfunction tiers(mid: number): Record<ModelTier, number> {\n return { fast: Math.max(0, mid - 0.25), mid, strong: Math.min(1, mid + 0.12) };\n}\n\nfunction harnesses(values: Record<string, number>): HarnessPriors {\n return Object.fromEntries(Object.entries(values).map(([harness, mid]) => [harness, tiers(mid)]));\n}\n\nexport const PRIORS: Record<TaskClass, HarnessPriors> = {\n bugfix: harnesses({\n 'claude-code': 0.7,\n 'codex-cli': 0.95,\n 'cursor-cli': 0.65,\n 'antigravity-cli': 0.6,\n 'opencode-cli': 0.55,\n }),\n feature: harnesses({\n 'claude-code': 0.85,\n 'codex-cli': 0.8,\n 'cursor-cli': 0.7,\n 'antigravity-cli': 0.65,\n 'opencode-cli': 0.6,\n }),\n refactor: harnesses({\n 'claude-code': 0.75,\n 'codex-cli': 0.9,\n 'cursor-cli': 0.65,\n 'antigravity-cli': 0.6,\n 'opencode-cli': 0.55,\n }),\n docs: harnesses({\n 'claude-code': 0.8,\n 'codex-cli': 0.7,\n 'cursor-cli': 0.75,\n 'antigravity-cli': 0.7,\n 'opencode-cli': 0.65,\n }),\n test: harnesses({\n 'claude-code': 0.7,\n 'codex-cli': 0.9,\n 'cursor-cli': 0.65,\n 'antigravity-cli': 0.6,\n 'opencode-cli': 0.55,\n }),\n infra: harnesses({\n 'claude-code': 0.8,\n 'codex-cli': 0.75,\n 'cursor-cli': 0.6,\n 'antigravity-cli': 0.55,\n 'opencode-cli': 0.5,\n }),\n analysis: harnesses({\n 'claude-code': 0.95,\n 'codex-cli': 0.6,\n 'cursor-cli': 0.7,\n 'antigravity-cli': 0.65,\n 'opencode-cli': 0.6,\n }),\n};\n\nexport function priorFor(taskClass: TaskClass, harness: string, tier: ModelTier): number {\n return PRIORS[taskClass][harness]?.[tier] ?? 0.5;\n}\n","import type { RiskLevel, TaskClass, TaskSignals } from './types.js';\n\nconst RISK_PATHS = [/auth/i, /migrat/i, /infra/i, /\\.github\\//i, /permission/i, /secret/i];\n\nexport interface AnalyzedTask {\n taskClass: TaskClass;\n risk: RiskLevel;\n}\n\n/** Deterministic. No model, no I/O. Every class is reachable. */\nexport function analyzeTask(signals: TaskSignals = {}): AnalyzedTask {\n const hay = [\n signals.title ?? '',\n signals.body ?? '',\n ...(signals.labels ?? []),\n ...(signals.paths ?? []),\n ]\n .join(' ')\n .toLowerCase();\n\n const taskClass = classify(hay, signals);\n const risk = RISK_PATHS.some((pattern) =>\n (signals.paths ?? []).some((path) => pattern.test(path)),\n )\n ? 'high'\n : /security|auth|migrat/.test(hay)\n ? 'high'\n : /refactor|large|epic/.test(hay)\n ? 'medium'\n : 'low';\n\n return { taskClass, risk };\n}\n\nfunction classify(hay: string, signals: TaskSignals): TaskClass {\n if (/\\bdocs?\\b|readme|changelog/.test(hay)) return 'docs';\n if (/\\btest|spec|coverage/.test(hay)) return 'test';\n if (/\\bcie?|deploy|infra|workflow|docker/.test(hay)) return 'infra';\n if (/\\banaly[sz]e|investigat|research/.test(hay)) return 'analysis';\n if (/\\bbug|fix|regres+ion|crash/.test(hay)) return 'bugfix';\n if (/\\brefactor|cleanup|extract/.test(hay)) return 'refactor';\n if (/\\bfeat|feature|add |implement/.test(hay)) return 'feature';\n if ((signals.labels ?? []).some((label) => /bug/i.test(label))) return 'bugfix';\n if ((signals.labels ?? []).some((label) => /enhancement|feature/i.test(label))) return 'feature';\n return 'feature';\n}\n","import type { ProviderReadiness } from '../agents/availability.js';\nimport type { AgentCapabilities, AgentPhase } from '../agents/types.js';\n\nexport interface EligibilityInput {\n harness: string;\n capabilities: AgentCapabilities;\n phase: AgentPhase;\n requiresExtraDirectories: boolean;\n readiness?: ProviderReadiness | null;\n /** Default true. When false, conditional/unverified providers are ineligible. */\n allowConditional?: boolean;\n}\n\nexport interface Eligibility {\n eligible: boolean;\n reasonCodes: string[];\n}\n\n/**\n * Restriction missing (`toolAllowlist`) is ignored. Enablement missing\n * (`extraDirectories`) is ineligible when the phase needs addDirs.\n * Readiness is injected by the caller — this module stays pure.\n */\nexport function filterEligible(input: EligibilityInput): Eligibility {\n const reasons: string[] = [];\n let eligible = true;\n\n if (input.requiresExtraDirectories && input.capabilities.extraDirectories === 'none') {\n reasons.push('MISSING_CAPABILITY:extraDirectories');\n reasons.push('CAPABILITY_MISMATCH');\n eligible = false;\n }\n\n const readiness = input.readiness;\n if (readiness !== undefined && readiness !== null) {\n if (!readiness.installed) {\n reasons.push('PROVIDER_NOT_INSTALLED');\n eligible = false;\n } else if (\n readiness.cooldownUntil !== null &&\n Date.parse(readiness.cooldownUntil) > Date.parse(readiness.observedAt)\n ) {\n reasons.push('PROVIDER_COOLDOWN');\n eligible = false;\n } else if (readiness.authentication === 'failed') {\n reasons.push('AUTHENTICATION_FAILED');\n reasons.push('PROVIDER_UNAVAILABLE');\n eligible = false;\n } else if (readiness.state === 'unavailable') {\n reasons.push('PROVIDER_UNAVAILABLE');\n eligible = false;\n } else if (readiness.authentication === 'unverified' || readiness.state === 'conditional') {\n reasons.push('AUTHENTICATION_UNVERIFIED');\n reasons.push('READINESS_CONDITIONAL');\n if (input.allowConditional === false) {\n reasons.push('PROVIDER_UNAVAILABLE');\n eligible = false;\n }\n } else {\n reasons.push('READINESS_CONFIRMED');\n }\n\n const modelAccess = readiness.models[0]?.access;\n if (modelAccess === 'denied') {\n reasons.push('MODEL_NOT_ACCESSIBLE');\n eligible = false;\n } else if (modelAccess === 'unverified') {\n reasons.push('MODEL_ACCESS_UNVERIFIED');\n }\n }\n\n return { eligible, reasonCodes: reasons };\n}\n","import type { ModelTier } from './models.js';\nimport { priorFor } from './priors.js';\nimport type { Candidate, RoutingProfile, TaskClass } from './types.js';\n\nexport const DELTA = 0.2;\nexport const MIN_SAMPLE_SIZE = 8;\n\nexport const PROFILE_WEIGHTS: Record<\n RoutingProfile,\n { quality: number; cost: number; latency: number }\n> = {\n economy: { quality: 0.5, cost: 0.4, latency: 0.1 },\n balanced: { quality: 0.6, cost: 0.25, latency: 0.15 },\n quality: { quality: 0.85, cost: 0.05, latency: 0.1 },\n speed: { quality: 0.45, cost: 0.1, latency: 0.45 },\n};\n\nexport interface ScoreInput {\n harness: string;\n provider: string;\n model?: string | null;\n tier: ModelTier;\n relativeCost: number;\n relativeLatency: number;\n eligible: boolean;\n reasonCodes: string[];\n taskClass: TaskClass;\n learned?: number;\n samples?: number;\n profile?: RoutingProfile;\n /** Observed cost status from #78; catalog-relative cost is always available. */\n costStatus?: 'reported' | 'estimated' | 'unknown';\n readinessState?: 'ready' | 'conditional' | 'unavailable' | null;\n preferredTierMatch?: boolean;\n affinityMatch?: boolean;\n}\n\nexport function clampLearned(value: number): number {\n return Math.max(-DELTA, Math.min(DELTA, value));\n}\n\nfunction readinessMultiplier(state: ScoreInput['readinessState']): number {\n if (state === 'ready') return 1;\n if (state === 'conditional') return 0.72;\n if (state === 'unavailable') return 0;\n return 1;\n}\n\nexport function scoreCandidates(inputs: readonly ScoreInput[]): Candidate[] {\n const profile = inputs[0]?.profile ?? 'balanced';\n const scored: Candidate[] = inputs.map((input) => {\n const prior = priorFor(input.taskClass, input.harness, input.tier);\n const samples = input.samples ?? 0;\n const rawLearned = samples >= MIN_SAMPLE_SIZE ? (input.learned ?? 0) : 0;\n const learned = clampLearned(rawLearned);\n const weights = PROFILE_WEIGHTS[profile];\n // This is catalog-relative ordering, not observed USD. An unknown reported\n // cost still contributes no measured-cost signal; the declared tier order\n // remains available to economy/balanced profiles.\n const costScore = 1 / input.relativeCost;\n const latencyScore = 1 / input.relativeLatency;\n const preferenceBonus =\n (input.preferredTierMatch === true ? 0.12 : 0) + (input.affinityMatch === true ? 0.08 : 0);\n const score = input.eligible\n ? ((prior + learned) * weights.quality +\n costScore * weights.cost +\n latencyScore * weights.latency +\n preferenceBonus) *\n readinessMultiplier(input.readinessState)\n : 0;\n const reasonCodes = [...input.reasonCodes];\n if (input.eligible && samples === 0) reasonCodes.push('COLD_START');\n if (input.eligible && learned > 0) reasonCodes.push('HIGH_HISTORICAL_SUCCESS');\n return {\n harness: input.harness,\n provider: input.provider,\n model: input.model ?? null,\n tier: input.tier,\n relativeCost: input.relativeCost,\n relativeLatency: input.relativeLatency,\n eligible: input.eligible,\n prior,\n learned,\n samples,\n score,\n reasonCodes,\n };\n });\n\n return scored.sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n return a.harness.localeCompare(b.harness);\n });\n}\n\nexport function pickSelected(candidates: readonly Candidate[]): Candidate {\n const eligible = candidates.filter((candidate) => candidate.eligible);\n if (eligible.length === 0) {\n throw new Error(\n `No eligible routing candidate: ${candidates.map((c) => `${c.harness} (${c.reasonCodes.join(',')})`).join('; ')}`,\n );\n }\n return eligible[0] as Candidate;\n}\n","import type { ReadinessSnapshot } from '../agents/availability.js';\nimport type { AgentPhase } from '../agents/types.js';\nimport {\n ANTIGRAVITY_CAPABILITIES,\n CLAUDE_CAPABILITIES,\n CODEX_CAPABILITIES,\n CURSOR_CAPABILITIES,\n OPENCODE_CAPABILITIES,\n} from '../agents/types.js';\nimport { analyzeTask } from './analyze.js';\nimport { filterEligible } from './capabilities.js';\nimport { MODEL_CATALOG_VERSION, modelsFor } from './models.js';\nimport { OPENCODE_GO_POLICY_VERSION, resolveOpenCodeGoModel } from './opencode-go.js';\nimport { RECOMMENDED_POLICY_VERSION, recommendedFor } from './policy.js';\nimport { PRIORS_VERSION } from './priors.js';\nimport { pickSelected, scoreCandidates } from './score.js';\nimport type { RoutingDecision, RoutingMode, RoutingProfile, TaskSignals } from './types.js';\n\nconst CAPS = {\n 'claude-code': CLAUDE_CAPABILITIES,\n 'codex-cli': CODEX_CAPABILITIES,\n 'cursor-cli': CURSOR_CAPABILITIES,\n 'antigravity-cli': ANTIGRAVITY_CAPABILITIES,\n 'opencode-cli': OPENCODE_CAPABILITIES,\n} as const;\n\nconst PROVIDER: Record<string, string> = {\n 'claude-code': 'claude',\n 'codex-cli': 'codex',\n 'cursor-cli': 'cursor',\n 'antigravity-cli': 'antigravity',\n 'opencode-cli': 'opencode',\n};\n\nexport function decideRouting(input: {\n signals?: TaskSignals;\n phase: AgentPhase;\n actualHarness: string;\n actualProvider?: string;\n actualModel?: string | null;\n mode: RoutingMode;\n profile?: RoutingProfile;\n requiresExtraDirectories?: boolean;\n skipScore?: boolean;\n policy?: 'recommended';\n /** Injected inventory — router stays pure (no probes). */\n readiness?: ReadinessSnapshot | null;\n correctionCycle?: number;\n}): RoutingDecision | null {\n if (input.mode === 'off') return null;\n const analyzed = analyzeTask(input.signals ?? {});\n const profile = input.profile ?? 'balanced';\n const policyVersion = `${PRIORS_VERSION}:${MODEL_CATALOG_VERSION}:${input.policy === 'recommended' ? RECOMMENDED_POLICY_VERSION : 'adaptive'}:${OPENCODE_GO_POLICY_VERSION}`;\n\n if (input.skipScore) {\n return {\n policyVersion,\n profile,\n taskClass: analyzed.taskClass,\n risk: analyzed.risk,\n mode: input.mode,\n candidates: [],\n selected: {\n harness: input.actualHarness,\n provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,\n model: input.actualModel ?? null,\n },\n actual: {\n harness: input.actualHarness,\n provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,\n model: input.actualModel ?? null,\n },\n reasonCodes: ['EXPLICIT_CONFIG'],\n };\n }\n\n const recommendation = input.policy === 'recommended' ? recommendedFor(input.phase) : null;\n const allowConditional = recommendation?.allowConditional !== false;\n\n const scored = scoreCandidates(\n (Object.keys(CAPS) as (keyof typeof CAPS)[]).flatMap((harness) => {\n const providerId = PROVIDER[harness] as\n | 'claude'\n | 'codex'\n | 'cursor'\n | 'antigravity'\n | 'opencode';\n const readiness =\n input.readiness === undefined || input.readiness === null\n ? null\n : (input.readiness.providers[providerId] ?? null);\n const eligibility = filterEligible({\n harness,\n capabilities: CAPS[harness],\n phase: input.phase,\n requiresExtraDirectories: input.requiresExtraDirectories === true,\n readiness,\n allowConditional,\n });\n return modelsFor(harness, CAPS[harness]).map((model) => {\n const reasonCodes = [...eligibility.reasonCodes];\n const preferredTierMatch =\n recommendation !== null && model.tier === recommendation.preferredTier;\n const affinityMatch = recommendation !== null && recommendation.affinityHarness === harness;\n if (preferredTierMatch) reasonCodes.push('RECOMMENDED_POLICY');\n if (affinityMatch) reasonCodes.push('HARNESS_AFFINITY');\n if (model.tier === 'fast' && analyzed.risk !== 'high') {\n reasonCodes.push('CHEAPER_TIER_SUFFICIENT');\n }\n if (model.tier === 'strong' && (analyzed.risk === 'high' || profile === 'quality')) {\n reasonCodes.push('STRONGER_TIER_FOR_RISK');\n }\n return {\n harness,\n provider: providerId,\n model: model.id,\n tier: model.tier,\n relativeCost: model.relativeCost,\n relativeLatency: model.relativeLatency,\n eligible: eligibility.eligible,\n reasonCodes,\n taskClass: analyzed.taskClass,\n profile,\n readinessState: readiness?.state ?? null,\n preferredTierMatch,\n affinityMatch,\n };\n });\n }),\n );\n const selected = pickSelected(scored);\n if (selected.harness === 'opencode-cli') {\n const go = resolveOpenCodeGoModel({\n phase: input.phase,\n taskClass: analyzed.taskClass,\n risk: analyzed.risk,\n profile,\n correctionCycle: input.correctionCycle,\n });\n selected.model = go.model;\n selected.reasonCodes.push(...go.reasonCodes);\n }\n return {\n policyVersion,\n profile,\n taskClass: analyzed.taskClass,\n risk: analyzed.risk,\n mode: input.mode,\n candidates: scored,\n selected: {\n harness: selected.harness,\n provider: selected.provider,\n model: selected.model ?? null,\n tier: selected.tier,\n },\n actual: {\n harness: input.actualHarness,\n provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,\n model: input.actualModel ?? null,\n },\n reasonCodes: selected.reasonCodes.includes('COLD_START')\n ? ['HIGH_PRIOR', ...selected.reasonCodes]\n : selected.reasonCodes,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAEO,IAAM,wBAAwB;AAe9B,IAAM,gBAAuD;AAAA,EAClE,eAAe;AAAA,IACb,EAAE,IAAI,SAAS,MAAM,QAAQ,cAAc,GAAG,iBAAiB,EAAE;AAAA,IACjE,EAAE,IAAI,UAAU,MAAM,OAAO,cAAc,KAAK,iBAAiB,IAAI;AAAA,IACrE,EAAE,IAAI,QAAQ,MAAM,UAAU,cAAc,GAAG,iBAAiB,IAAI;AAAA,EACtE;AAAA,EACA,aAAa;AAAA,IACX,EAAE,IAAI,gBAAgB,MAAM,QAAQ,cAAc,GAAG,iBAAiB,EAAE;AAAA,IACxE,EAAE,IAAI,iBAAiB,MAAM,OAAO,cAAc,GAAG,iBAAiB,KAAK;AAAA,IAC3E,EAAE,IAAI,eAAe,MAAM,UAAU,cAAc,GAAG,iBAAiB,IAAI;AAAA,EAC7E;AAAA,EACA,cAAc;AAAA,IACZ,EAAE,IAAI,aAAa,MAAM,QAAQ,cAAc,GAAG,iBAAiB,EAAE;AAAA,IACrE,EAAE,IAAI,QAAQ,MAAM,OAAO,cAAc,GAAG,iBAAiB,IAAI;AAAA,IACjE,EAAE,IAAI,eAAe,MAAM,UAAU,cAAc,GAAG,iBAAiB,IAAI;AAAA,EAC7E;AAAA,EACA,mBAAmB;AAAA,IACjB,EAAE,IAAI,wBAAwB,MAAM,QAAQ,cAAc,GAAG,iBAAiB,EAAE;AAAA,IAChF,EAAE,IAAI,2BAA2B,MAAM,OAAO,cAAc,KAAK,iBAAiB,IAAI;AAAA,IACtF,EAAE,IAAI,uBAAuB,MAAM,UAAU,cAAc,GAAG,iBAAiB,EAAE;AAAA,EACnF;AAAA;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,EAAE,IAAI,yBAAyB,MAAM,QAAQ,cAAc,GAAG,iBAAiB,EAAE;AAAA,IACjF,EAAE,IAAI,6BAA6B,MAAM,OAAO,cAAc,KAAK,iBAAiB,IAAI;AAAA,IACxF,EAAE,IAAI,4BAA4B,MAAM,UAAU,cAAc,GAAG,iBAAiB,IAAI;AAAA,EAC1F;AACF;AAEA,IAAM,eAAsC;AAAA,EAC1C,EAAE,IAAI,MAAM,MAAM,OAAO,cAAc,GAAG,iBAAiB,EAAE;AAC/D;AAEO,SAAS,UAAU,SAAiB,cAAwD;AACjG,MAAI,CAAC,aAAa,eAAgB,QAAO;AACzC,SAAO,cAAc,OAAO,KAAK;AACnC;AAEO,SAAS,aAAa,SAAiB,MAAoC;AAChF,SAAO,cAAc,OAAO,GAAG,KAAK,CAAC,UAAU,MAAM,SAAS,IAAI,KAAK;AACzE;;;ACtDO,IAAM,6BAA6B;AAoBnC,IAAM,qBAAiE;AAAA,EAC5E,SAAS;AAAA,IACP,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,UAAU;AAAA,IACR,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,KAAK;AAAA,IACH,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,MAAM;AAAA,IACJ,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,SAAS;AAAA,IACP,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,QAAQ;AAAA,IACN,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB;AAAA,EACA,IAAI;AAAA,IACF,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA,EACA,aAAa;AAAA,IACX,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AACF;AAEA,IAAM,YAA6C;AAAA,EACjD,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;AAEO,SAAS,eAAe,OAA2C;AACxE,SAAO,mBAAmB,KAAK;AACjC;AAMO,SAAS,kBAAkB,OAA2C;AAC3E,QAAM,QAAQ,eAAe,KAAK;AAClC,QAAM,UAAU,MAAM;AACtB,MAAI,YAAY,OAAW,QAAO;AAClC,QAAM,QAAQ,aAAa,SAAS,MAAM,aAAa;AACvD,QAAM,WAAW,UAAU,OAAO;AAClC,MAAI,UAAU,QAAQ,aAAa,OAAW,QAAO;AACrD,SAAO,EAAE,SAAS,UAAU,OAAO,MAAM,IAAI,MAAM,MAAM,cAAc;AACzE;;;ACzFO,IAAM,iBAAiB;AAU9B,SAAS,MAAM,KAAwC;AACrD,SAAO,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,GAAG,KAAK,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,EAAE;AAC/E;AAEA,SAAS,UAAU,QAA+C;AAChE,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC;AACjG;AAEO,IAAM,SAA2C;AAAA,EACtD,QAAQ,UAAU;AAAA,IAChB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,SAAS,UAAU;AAAA,IACjB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,UAAU,UAAU;AAAA,IAClB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,MAAM,UAAU;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,MAAM,UAAU;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,OAAO,UAAU;AAAA,IACf,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,UAAU,UAAU;AAAA,IAClB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB,CAAC;AACH;AAEO,SAAS,SAAS,WAAsB,SAAiB,MAAyB;AACvF,SAAO,OAAO,SAAS,EAAE,OAAO,IAAI,IAAI,KAAK;AAC/C;;;AC1EA,IAAM,aAAa,CAAC,SAAS,WAAW,UAAU,eAAe,eAAe,SAAS;AAQlF,SAAS,YAAY,UAAuB,CAAC,GAAiB;AACnE,QAAM,MAAM;AAAA,IACV,QAAQ,SAAS;AAAA,IACjB,QAAQ,QAAQ;AAAA,IAChB,GAAI,QAAQ,UAAU,CAAC;AAAA,IACvB,GAAI,QAAQ,SAAS,CAAC;AAAA,EACxB,EACG,KAAK,GAAG,EACR,YAAY;AAEf,QAAM,YAAY,SAAS,KAAK,OAAO;AACvC,QAAM,OAAO,WAAW;AAAA,IAAK,CAAC,aAC3B,QAAQ,SAAS,CAAC,GAAG,KAAK,CAAC,SAAS,QAAQ,KAAK,IAAI,CAAC;AAAA,EACzD,IACI,SACA,uBAAuB,KAAK,GAAG,IAC7B,SACA,sBAAsB,KAAK,GAAG,IAC5B,WACA;AAER,SAAO,EAAE,WAAW,KAAK;AAC3B;AAEA,SAAS,SAAS,KAAa,SAAiC;AAC9D,MAAI,6BAA6B,KAAK,GAAG,EAAG,QAAO;AACnD,MAAI,uBAAuB,KAAK,GAAG,EAAG,QAAO;AAC7C,MAAI,sCAAsC,KAAK,GAAG,EAAG,QAAO;AAC5D,MAAI,mCAAmC,KAAK,GAAG,EAAG,QAAO;AACzD,MAAI,6BAA6B,KAAK,GAAG,EAAG,QAAO;AACnD,MAAI,6BAA6B,KAAK,GAAG,EAAG,QAAO;AACnD,MAAI,gCAAgC,KAAK,GAAG,EAAG,QAAO;AACtD,OAAK,QAAQ,UAAU,CAAC,GAAG,KAAK,CAAC,UAAU,OAAO,KAAK,KAAK,CAAC,EAAG,QAAO;AACvE,OAAK,QAAQ,UAAU,CAAC,GAAG,KAAK,CAAC,UAAU,uBAAuB,KAAK,KAAK,CAAC,EAAG,QAAO;AACvF,SAAO;AACT;;;ACtBO,SAAS,eAAe,OAAsC;AACnE,QAAM,UAAoB,CAAC;AAC3B,MAAI,WAAW;AAEf,MAAI,MAAM,4BAA4B,MAAM,aAAa,qBAAqB,QAAQ;AACpF,YAAQ,KAAK,qCAAqC;AAClD,YAAQ,KAAK,qBAAqB;AAClC,eAAW;AAAA,EACb;AAEA,QAAM,YAAY,MAAM;AACxB,MAAI,cAAc,UAAa,cAAc,MAAM;AACjD,QAAI,CAAC,UAAU,WAAW;AACxB,cAAQ,KAAK,wBAAwB;AACrC,iBAAW;AAAA,IACb,WACE,UAAU,kBAAkB,QAC5B,KAAK,MAAM,UAAU,aAAa,IAAI,KAAK,MAAM,UAAU,UAAU,GACrE;AACA,cAAQ,KAAK,mBAAmB;AAChC,iBAAW;AAAA,IACb,WAAW,UAAU,mBAAmB,UAAU;AAChD,cAAQ,KAAK,uBAAuB;AACpC,cAAQ,KAAK,sBAAsB;AACnC,iBAAW;AAAA,IACb,WAAW,UAAU,UAAU,eAAe;AAC5C,cAAQ,KAAK,sBAAsB;AACnC,iBAAW;AAAA,IACb,WAAW,UAAU,mBAAmB,gBAAgB,UAAU,UAAU,eAAe;AACzF,cAAQ,KAAK,2BAA2B;AACxC,cAAQ,KAAK,uBAAuB;AACpC,UAAI,MAAM,qBAAqB,OAAO;AACpC,gBAAQ,KAAK,sBAAsB;AACnC,mBAAW;AAAA,MACb;AAAA,IACF,OAAO;AACL,cAAQ,KAAK,qBAAqB;AAAA,IACpC;AAEA,UAAM,cAAc,UAAU,OAAO,CAAC,GAAG;AACzC,QAAI,gBAAgB,UAAU;AAC5B,cAAQ,KAAK,sBAAsB;AACnC,iBAAW;AAAA,IACb,WAAW,gBAAgB,cAAc;AACvC,cAAQ,KAAK,yBAAyB;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,aAAa,QAAQ;AAC1C;;;ACpEO,IAAM,QAAQ;AACd,IAAM,kBAAkB;AAExB,IAAM,kBAGT;AAAA,EACF,SAAS,EAAE,SAAS,KAAK,MAAM,KAAK,SAAS,IAAI;AAAA,EACjD,UAAU,EAAE,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK;AAAA,EACpD,SAAS,EAAE,SAAS,MAAM,MAAM,MAAM,SAAS,IAAI;AAAA,EACnD,OAAO,EAAE,SAAS,MAAM,MAAM,KAAK,SAAS,KAAK;AACnD;AAsBO,SAAS,aAAa,OAAuB;AAClD,SAAO,KAAK,IAAI,CAAC,OAAO,KAAK,IAAI,OAAO,KAAK,CAAC;AAChD;AAEA,SAAS,oBAAoB,OAA6C;AACxE,MAAI,UAAU,QAAS,QAAO;AAC9B,MAAI,UAAU,cAAe,QAAO;AACpC,MAAI,UAAU,cAAe,QAAO;AACpC,SAAO;AACT;AAEO,SAAS,gBAAgB,QAA4C;AAC1E,QAAM,UAAU,OAAO,CAAC,GAAG,WAAW;AACtC,QAAM,SAAsB,OAAO,IAAI,CAAC,UAAU;AAChD,UAAM,QAAQ,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,IAAI;AACjE,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,aAAa,WAAW,kBAAmB,MAAM,WAAW,IAAK;AACvE,UAAM,UAAU,aAAa,UAAU;AACvC,UAAM,UAAU,gBAAgB,OAAO;AAIvC,UAAM,YAAY,IAAI,MAAM;AAC5B,UAAM,eAAe,IAAI,MAAM;AAC/B,UAAM,mBACH,MAAM,uBAAuB,OAAO,OAAO,MAAM,MAAM,kBAAkB,OAAO,OAAO;AAC1F,UAAM,QAAQ,MAAM,aACd,QAAQ,WAAW,QAAQ,UAC3B,YAAY,QAAQ,OACpB,eAAe,QAAQ,UACvB,mBACF,oBAAoB,MAAM,cAAc,IACxC;AACJ,UAAM,cAAc,CAAC,GAAG,MAAM,WAAW;AACzC,QAAI,MAAM,YAAY,YAAY,EAAG,aAAY,KAAK,YAAY;AAClE,QAAI,MAAM,YAAY,UAAU,EAAG,aAAY,KAAK,yBAAyB;AAC7E,WAAO;AAAA,MACL,SAAS,MAAM;AAAA,MACf,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM,SAAS;AAAA,MACtB,MAAM,MAAM;AAAA,MACZ,cAAc,MAAM;AAAA,MACpB,iBAAiB,MAAM;AAAA,MACvB,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,OAAO,KAAK,CAAC,GAAG,MAAM;AAC3B,QAAI,EAAE,UAAU,EAAE,MAAO,QAAO,EAAE,QAAQ,EAAE;AAC5C,WAAO,EAAE,QAAQ,cAAc,EAAE,OAAO;AAAA,EAC1C,CAAC;AACH;AAEO,SAAS,aAAa,YAA6C;AACxE,QAAM,WAAW,WAAW,OAAO,CAAC,cAAc,UAAU,QAAQ;AACpE,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI;AAAA,MACR,kCAAkC,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,KAAK,EAAE,YAAY,KAAK,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IACjH;AAAA,EACF;AACA,SAAO,SAAS,CAAC;AACnB;;;ACrFA,IAAM,OAAO;AAAA,EACX,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;AAEA,IAAM,WAAmC;AAAA,EACvC,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;AAEO,SAAS,cAAc,OAcH;AACzB,MAAI,MAAM,SAAS,MAAO,QAAO;AACjC,QAAM,WAAW,YAAY,MAAM,WAAW,CAAC,CAAC;AAChD,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,gBAAgB,GAAG,cAAc,IAAI,qBAAqB,IAAI,MAAM,WAAW,gBAAgB,6BAA6B,UAAU,IAAI,0BAA0B;AAE1K,MAAI,MAAM,WAAW;AACnB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW,SAAS;AAAA,MACpB,MAAM,SAAS;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,YAAY,CAAC;AAAA,MACb,UAAU;AAAA,QACR,SAAS,MAAM;AAAA,QACf,UAAU,MAAM,kBAAkB,SAAS,MAAM,aAAa,KAAK,MAAM;AAAA,QACzE,OAAO,MAAM,eAAe;AAAA,MAC9B;AAAA,MACA,QAAQ;AAAA,QACN,SAAS,MAAM;AAAA,QACf,UAAU,MAAM,kBAAkB,SAAS,MAAM,aAAa,KAAK,MAAM;AAAA,QACzE,OAAO,MAAM,eAAe;AAAA,MAC9B;AAAA,MACA,aAAa,CAAC,iBAAiB;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM,WAAW,gBAAgB,eAAe,MAAM,KAAK,IAAI;AACtF,QAAM,mBAAmB,gBAAgB,qBAAqB;AAE9D,QAAM,SAAS;AAAA,IACZ,OAAO,KAAK,IAAI,EAA4B,QAAQ,CAAC,YAAY;AAChE,YAAM,aAAa,SAAS,OAAO;AAMnC,YAAM,YACJ,MAAM,cAAc,UAAa,MAAM,cAAc,OACjD,OACC,MAAM,UAAU,UAAU,UAAU,KAAK;AAChD,YAAM,cAAc,eAAe;AAAA,QACjC;AAAA,QACA,cAAc,KAAK,OAAO;AAAA,QAC1B,OAAO,MAAM;AAAA,QACb,0BAA0B,MAAM,6BAA6B;AAAA,QAC7D;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,UAAU,SAAS,KAAK,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU;AACtD,cAAM,cAAc,CAAC,GAAG,YAAY,WAAW;AAC/C,cAAM,qBACJ,mBAAmB,QAAQ,MAAM,SAAS,eAAe;AAC3D,cAAM,gBAAgB,mBAAmB,QAAQ,eAAe,oBAAoB;AACpF,YAAI,mBAAoB,aAAY,KAAK,oBAAoB;AAC7D,YAAI,cAAe,aAAY,KAAK,kBAAkB;AACtD,YAAI,MAAM,SAAS,UAAU,SAAS,SAAS,QAAQ;AACrD,sBAAY,KAAK,yBAAyB;AAAA,QAC5C;AACA,YAAI,MAAM,SAAS,aAAa,SAAS,SAAS,UAAU,YAAY,YAAY;AAClF,sBAAY,KAAK,wBAAwB;AAAA,QAC3C;AACA,eAAO;AAAA,UACL;AAAA,UACA,UAAU;AAAA,UACV,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,cAAc,MAAM;AAAA,UACpB,iBAAiB,MAAM;AAAA,UACvB,UAAU,YAAY;AAAA,UACtB;AAAA,UACA,WAAW,SAAS;AAAA,UACpB;AAAA,UACA,gBAAgB,WAAW,SAAS;AAAA,UACpC;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,QAAM,WAAW,aAAa,MAAM;AACpC,MAAI,SAAS,YAAY,gBAAgB;AACvC,UAAM,KAAK,uBAAuB;AAAA,MAChC,OAAO,MAAM;AAAA,MACb,WAAW,SAAS;AAAA,MACpB,MAAM,SAAS;AAAA,MACf;AAAA,MACA,iBAAiB,MAAM;AAAA,IACzB,CAAC;AACD,aAAS,QAAQ,GAAG;AACpB,aAAS,YAAY,KAAK,GAAG,GAAG,WAAW;AAAA,EAC7C;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW,SAAS;AAAA,IACpB,MAAM,SAAS;AAAA,IACf,MAAM,MAAM;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACR,SAAS,SAAS;AAAA,MAClB,UAAU,SAAS;AAAA,MACnB,OAAO,SAAS,SAAS;AAAA,MACzB,MAAM,SAAS;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,MACN,SAAS,MAAM;AAAA,MACf,UAAU,MAAM,kBAAkB,SAAS,MAAM,aAAa,KAAK,MAAM;AAAA,MACzE,OAAO,MAAM,eAAe;AAAA,IAC9B;AAAA,IACA,aAAa,SAAS,YAAY,SAAS,YAAY,IACnD,CAAC,cAAc,GAAG,SAAS,WAAW,IACtC,SAAS;AAAA,EACf;AACF;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/verify/contract.ts
|
|
4
|
-
import { existsSync } from "fs";
|
|
5
|
-
import { readFile } from "fs/promises";
|
|
6
|
-
import { join } from "path";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
7
7
|
var DISCOVERABLE = ["typecheck", "lint", "test"];
|
|
8
8
|
async function discoverFromMakefile(cwd) {
|
|
9
9
|
const makePath = join(cwd, "Makefile");
|
|
@@ -74,4 +74,4 @@ async function discoverFromPackage(cwd) {
|
|
|
74
74
|
export {
|
|
75
75
|
resolveContract
|
|
76
76
|
};
|
|
77
|
-
//# sourceMappingURL=chunk-
|
|
77
|
+
//# sourceMappingURL=chunk-W7LZLJAF.js.map
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
redactFailureMessage
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
isoNow,
|
|
7
|
-
loadTaskPlan,
|
|
8
|
-
saveTaskPlan
|
|
9
|
-
} from "./chunk-SOM4QA6C.js";
|
|
10
|
-
import {
|
|
11
|
-
classify
|
|
12
|
-
} from "./chunk-XEYH6ZZI.js";
|
|
4
|
+
} from "./chunk-VHQMMY2D.js";
|
|
13
5
|
import {
|
|
14
6
|
getTelemetrySessionId,
|
|
15
7
|
setTelemetrySessionId
|
|
16
8
|
} from "./chunk-P3LRUNC6.js";
|
|
9
|
+
import {
|
|
10
|
+
isoNow
|
|
11
|
+
} from "./chunk-JCR5C5A7.js";
|
|
12
|
+
import {
|
|
13
|
+
ensurePlanRepository,
|
|
14
|
+
getPlanRepository,
|
|
15
|
+
loadExecution,
|
|
16
|
+
saveExecution
|
|
17
|
+
} from "./chunk-7MJGYPHF.js";
|
|
18
|
+
import {
|
|
19
|
+
classify
|
|
20
|
+
} from "./chunk-KUA6KBBD.js";
|
|
17
21
|
|
|
18
22
|
// src/telemetry/recorder.ts
|
|
19
|
-
import { randomUUID } from "crypto";
|
|
20
|
-
import { hostname } from "os";
|
|
23
|
+
import { randomUUID } from "node:crypto";
|
|
24
|
+
import { hostname } from "node:os";
|
|
21
25
|
|
|
22
26
|
// src/telemetry/pricing.ts
|
|
23
27
|
var PRICING_TABLE_VERSION = "2026-08-30";
|
|
@@ -137,22 +141,13 @@ function resetTelemetryState() {
|
|
|
137
141
|
async function resolveConfig(ctx) {
|
|
138
142
|
if (ctx.config !== void 0) return ctx.config;
|
|
139
143
|
try {
|
|
140
|
-
const { loadTelemetryConfig } = await import("./config-
|
|
144
|
+
const { loadTelemetryConfig } = await import("./config-6YTWPDBK.js");
|
|
141
145
|
ctx.config = await loadTelemetryConfig();
|
|
142
146
|
return ctx.config;
|
|
143
147
|
} catch {
|
|
144
148
|
return DEFAULT_TELEMETRY_CONFIG;
|
|
145
149
|
}
|
|
146
150
|
}
|
|
147
|
-
function cap(records, max) {
|
|
148
|
-
if (records.length <= max) return records;
|
|
149
|
-
discardedCount += records.length - max;
|
|
150
|
-
return records.slice(records.length - max);
|
|
151
|
-
}
|
|
152
|
-
async function mutate(tasksPath, update) {
|
|
153
|
-
const plan = await loadTaskPlan(tasksPath);
|
|
154
|
-
await saveTaskPlan(tasksPath, update(plan));
|
|
155
|
-
}
|
|
156
151
|
function usageFromClaude(usage) {
|
|
157
152
|
if (usage === void 0 || usage === null) return null;
|
|
158
153
|
const next = { source: "provider" };
|
|
@@ -200,11 +195,10 @@ async function beginExecution(input) {
|
|
|
200
195
|
...input.routingDecision === void 0 || input.routingDecision === null ? {} : { routingDecision: input.routingDecision }
|
|
201
196
|
};
|
|
202
197
|
try {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
})
|
|
207
|
-
const { getSessionPublisher } = await import("./session-publisher-KAJQRHNZ.js");
|
|
198
|
+
const repository = getPlanRepository(ctx.tasksPath) ?? await ensurePlanRepository(ctx.tasksPath);
|
|
199
|
+
if (repository === null) return null;
|
|
200
|
+
await saveExecution(repository, record);
|
|
201
|
+
const { getSessionPublisher } = await import("./session-publisher-Q5TNEZPX.js");
|
|
208
202
|
getSessionPublisher().publish({
|
|
209
203
|
type: "execution:update",
|
|
210
204
|
at: record.startedAt,
|
|
@@ -231,15 +225,13 @@ async function attachVerdict(verdict) {
|
|
|
231
225
|
const ctx = context;
|
|
232
226
|
if (ctx === null || verdict == null) return;
|
|
233
227
|
try {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return { ...plan, executions: records };
|
|
242
|
-
});
|
|
228
|
+
const repository = getPlanRepository(ctx.tasksPath);
|
|
229
|
+
if (repository === void 0) return;
|
|
230
|
+
const plan = await import("./repository-RCRR6RDE.js").then(
|
|
231
|
+
({ loadStoredPlan }) => loadStoredPlan(repository)
|
|
232
|
+
);
|
|
233
|
+
const current = plan.executions?.at(-1);
|
|
234
|
+
if (current !== void 0) await saveExecution(repository, { ...current, verdict });
|
|
243
235
|
} catch {
|
|
244
236
|
}
|
|
245
237
|
}
|
|
@@ -269,53 +261,50 @@ async function endExecution(input) {
|
|
|
269
261
|
};
|
|
270
262
|
const completed = { value: null };
|
|
271
263
|
try {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
...current,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
264
|
+
const repository = getPlanRepository(ctx.tasksPath);
|
|
265
|
+
if (repository === void 0) return;
|
|
266
|
+
const current = await loadExecution(repository, input.id);
|
|
267
|
+
if (current === null) return;
|
|
268
|
+
const started = Date.parse(current.startedAt);
|
|
269
|
+
const finishedAt = isoNow();
|
|
270
|
+
const modelResolved = input.modelResolved ?? current.agent.model.resolved;
|
|
271
|
+
const modelKey = modelResolved ?? current.agent.model.requested;
|
|
272
|
+
const record = {
|
|
273
|
+
...current,
|
|
274
|
+
agent: {
|
|
275
|
+
...current.agent,
|
|
276
|
+
harnessVersion: input.harnessVersion ?? current.agent.harnessVersion,
|
|
277
|
+
providerSessionId: input.providerSessionId ?? current.agent.providerSessionId,
|
|
278
|
+
model: {
|
|
279
|
+
...current.agent.model,
|
|
280
|
+
resolved: modelResolved,
|
|
281
|
+
source: input.modelSource ?? (modelResolved ? current.agent.model.source === "unavailable" ? "provider" : current.agent.model.source : current.agent.model.source)
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
finishedAt,
|
|
285
|
+
durationMs: Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,
|
|
286
|
+
...timingFromUsage(
|
|
287
|
+
Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,
|
|
288
|
+
input.usage
|
|
289
|
+
),
|
|
290
|
+
usage,
|
|
291
|
+
cost: resolveCost({
|
|
292
|
+
reportedUsd: input.reportedUsd ?? input.usage?.costUsd,
|
|
300
293
|
usage,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
};
|
|
314
|
-
completed.value = records[index] ?? null;
|
|
315
|
-
return { ...plan, executions: records };
|
|
316
|
-
});
|
|
294
|
+
modelKey,
|
|
295
|
+
estimate: cfg.pricing.estimate,
|
|
296
|
+
overrides: cfg.pricing.overrides
|
|
297
|
+
}),
|
|
298
|
+
status,
|
|
299
|
+
failure,
|
|
300
|
+
owner: null,
|
|
301
|
+
...input.storyIds === void 0 ? {} : { storyIds: input.storyIds },
|
|
302
|
+
...input.stopReason === void 0 ? {} : { stopReason: input.stopReason }
|
|
303
|
+
};
|
|
304
|
+
completed.value = record;
|
|
305
|
+
await saveExecution(repository, record);
|
|
317
306
|
if (completed.value !== null) {
|
|
318
|
-
const { getSessionPublisher } = await import("./session-publisher-
|
|
307
|
+
const { getSessionPublisher } = await import("./session-publisher-Q5TNEZPX.js");
|
|
319
308
|
getSessionPublisher().publish({
|
|
320
309
|
type: "execution:update",
|
|
321
310
|
at: completed.value.finishedAt ?? isoNow(),
|
|
@@ -359,4 +348,4 @@ export {
|
|
|
359
348
|
endExecution,
|
|
360
349
|
recordInvocation
|
|
361
350
|
};
|
|
362
|
-
//# sourceMappingURL=chunk-
|
|
351
|
+
//# sourceMappingURL=chunk-WB4FA2EH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/telemetry/recorder.ts","../src/telemetry/pricing.ts","../src/telemetry/types.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport type { ClaudeUsage } from '../core/metrics.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { classify } from '../resilience/errors.js';\nimport {\n ensurePlanRepository,\n getPlanRepository,\n loadExecution,\n saveExecution,\n} from '../storage/db/repository.js';\nimport { resolveCost } from './pricing.js';\nimport { redactFailureMessage } from './redact.js';\nimport { getTelemetrySessionId, setTelemetrySessionId } from './session-id.js';\nimport {\n DEFAULT_TELEMETRY_CONFIG,\n type ExecutionPurpose,\n type ExecutionRecord,\n type ExecutionStatus,\n type ExecutionTrigger,\n type NormalizedUsage,\n type StopReason,\n type TelemetryConfig,\n} from './types.js';\n\nexport interface TelemetryContext {\n tasksPath: string;\n sessionId?: string | null;\n config?: TelemetryConfig;\n}\n\nlet context: TelemetryContext | null = null;\nlet discardedCount = 0;\n\nexport function bindTelemetry(next: TelemetryContext | null): void {\n context = next;\n}\n\nexport function getTelemetryContext(): TelemetryContext | null {\n return context;\n}\n\nexport function discardedExecutionCount(): number {\n return discardedCount;\n}\n\nexport function resetTelemetryState(): void {\n context = null;\n discardedCount = 0;\n setTelemetrySessionId(null);\n}\n\nasync function resolveConfig(ctx: TelemetryContext): Promise<TelemetryConfig> {\n if (ctx.config !== undefined) return ctx.config;\n try {\n const { loadTelemetryConfig } = await import('../config.js');\n ctx.config = await loadTelemetryConfig();\n return ctx.config;\n } catch {\n return DEFAULT_TELEMETRY_CONFIG;\n }\n}\n\nexport function usageFromClaude(usage: ClaudeUsage | null | undefined): NormalizedUsage | null {\n if (usage === undefined || usage === null) return null;\n const next: NormalizedUsage = { source: 'provider' };\n if (usage.inputTokens !== undefined) next.inputTokens = usage.inputTokens;\n if (usage.outputTokens !== undefined) next.outputTokens = usage.outputTokens;\n if (usage.cacheReadTokens !== undefined) next.cacheReadTokens = usage.cacheReadTokens;\n if (usage.cacheCreationTokens !== undefined) next.cacheCreationTokens = usage.cacheCreationTokens;\n return next;\n}\n\nexport interface BeginExecutionInput {\n purpose: ExecutionPurpose;\n attempt?: number;\n trigger?: ExecutionTrigger;\n triggerReason?: ExecutionRecord['triggerReason'];\n harness: string;\n provider?: string | null;\n harnessVersion?: string | null;\n modelRequested?: string | null;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n iteration?: number;\n correctionCycle?: number;\n storyIds?: string[];\n routingDecision?: ExecutionRecord['routingDecision'];\n}\n\nexport async function beginExecution(input: BeginExecutionInput): Promise<string | null> {\n const ctx = context;\n if (ctx === null) return null;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return null;\n\n const id = randomUUID();\n const record: ExecutionRecord = {\n id,\n sessionId: ctx.sessionId ?? getTelemetrySessionId(),\n purpose: input.purpose,\n attempt: input.attempt ?? 1,\n trigger: input.trigger ?? 'initial',\n triggerReason: input.triggerReason ?? null,\n agent: {\n harness: input.harness,\n provider: input.provider ?? null,\n harnessVersion: input.harnessVersion ?? null,\n model: {\n requested: input.modelRequested ?? null,\n resolved: input.modelResolved ?? null,\n source: input.modelSource ?? (input.modelResolved ? 'provider' : 'unavailable'),\n },\n providerSessionId: null,\n },\n startedAt: isoNow(),\n finishedAt: null,\n durationMs: null,\n usage: null,\n cost: { status: 'unknown', reason: 'not_reported' },\n status: 'running',\n failure: null,\n owner: { pid: process.pid, host: hostname() },\n ...(input.iteration === undefined ? {} : { iteration: input.iteration }),\n ...(input.correctionCycle === undefined ? {} : { correctionCycle: input.correctionCycle }),\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.routingDecision === undefined || input.routingDecision === null\n ? {}\n : { routingDecision: input.routingDecision }),\n };\n\n try {\n const repository =\n getPlanRepository(ctx.tasksPath) ?? (await ensurePlanRepository(ctx.tasksPath));\n if (repository === null) return null;\n await saveExecution(repository, record as unknown as { id: string } & Record<string, unknown>);\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: record.startedAt,\n execution: record,\n });\n return id;\n } catch {\n return null;\n }\n}\n\n/** Wall clock vs CLI envelope: startup the harness does not report. */\nexport function timingFromUsage(\n wallClockMs: number | null,\n usage: ClaudeUsage | null | undefined,\n): Pick<\n ExecutionRecord,\n 'cliDurationMs' | 'harnessStartupMs' | 'apiDurationMs' | 'ttftMs' | 'numTurns'\n> {\n const cli = usage?.cliDurationMs;\n const cliDurationMs = cli === undefined ? null : cli;\n const harnessStartupMs =\n wallClockMs !== null && cli !== undefined ? Math.max(0, wallClockMs - cli) : null;\n return {\n cliDurationMs,\n harnessStartupMs,\n apiDurationMs: usage?.apiDurationMs ?? null,\n ttftMs: usage?.ttftMs ?? null,\n numTurns: usage?.numTurns ?? null,\n };\n}\n\nexport async function attachVerdict(verdict: ExecutionRecord['verdict']): Promise<void> {\n const ctx = context;\n if (ctx === null || verdict == null) return;\n try {\n const repository = getPlanRepository(ctx.tasksPath);\n if (repository === undefined) return;\n const plan = await import('../storage/db/repository.js').then(({ loadStoredPlan }) =>\n loadStoredPlan(repository),\n );\n const current = plan.executions?.at(-1);\n if (current !== undefined) await saveExecution(repository, { ...current, verdict });\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport interface EndExecutionInput {\n id: string;\n status?: ExecutionStatus;\n usage?: ClaudeUsage | null;\n reportedUsd?: number | null;\n error?: string | null;\n exitCode?: number | null;\n storyIds?: string[];\n cancelled?: boolean;\n timedOut?: boolean;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n harnessVersion?: string | null;\n providerSessionId?: string | null;\n stopReason?: StopReason | null;\n}\n\nexport async function endExecution(input: EndExecutionInput): Promise<void> {\n const ctx = context;\n if (ctx === null) return;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return;\n\n const usage = usageFromClaude(input.usage);\n const timedOut = input.timedOut === true || /\\btimed out\\b/i.test(input.error ?? '');\n const cancelled = input.cancelled === true;\n let status: ExecutionStatus = input.status ?? 'completed';\n if (input.status === undefined) {\n if (cancelled) status = 'cancelled';\n else if (timedOut) status = 'timeout';\n else if (input.error) status = 'failed';\n }\n\n const failure =\n status === 'completed'\n ? null\n : {\n kind: classify({\n source: 'agent',\n stdout: input.error ?? '',\n exitCode: input.exitCode,\n timedOut,\n }).kind,\n message: redactFailureMessage(input.error ?? status),\n exitCode: input.exitCode ?? null,\n };\n\n const completed: { value: ExecutionRecord | null } = { value: null };\n try {\n const repository = getPlanRepository(ctx.tasksPath);\n if (repository === undefined) return;\n const current = (await loadExecution(repository, input.id)) as ExecutionRecord | null;\n if (current === null) return;\n const started = Date.parse(current.startedAt);\n const finishedAt = isoNow();\n const modelResolved = input.modelResolved ?? current.agent.model.resolved;\n const modelKey = modelResolved ?? current.agent.model.requested;\n const record: ExecutionRecord = {\n ...current,\n agent: {\n ...current.agent,\n harnessVersion: input.harnessVersion ?? current.agent.harnessVersion,\n providerSessionId: input.providerSessionId ?? current.agent.providerSessionId,\n model: {\n ...current.agent.model,\n resolved: modelResolved,\n source:\n input.modelSource ??\n (modelResolved\n ? current.agent.model.source === 'unavailable'\n ? 'provider'\n : current.agent.model.source\n : current.agent.model.source),\n },\n },\n finishedAt,\n durationMs: Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n ...timingFromUsage(\n Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n input.usage,\n ),\n usage,\n cost: resolveCost({\n reportedUsd: input.reportedUsd ?? input.usage?.costUsd,\n usage,\n modelKey,\n estimate: cfg.pricing.estimate,\n overrides: cfg.pricing.overrides,\n }),\n status,\n failure,\n owner: null,\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.stopReason === undefined ? {} : { stopReason: input.stopReason }),\n };\n completed.value = record;\n await saveExecution(repository, record as unknown as { id: string } & Record<string, unknown>);\n if (completed.value !== null) {\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: completed.value.finishedAt ?? isoNow(),\n execution: completed.value,\n });\n }\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport async function recordInvocation<T>(\n input: BeginExecutionInput,\n invoke: () => Promise<T>,\n finish: (result: T) => EndExecutionInput,\n): Promise<T> {\n const id = await beginExecution(input);\n try {\n const result = await invoke();\n if (id !== null) {\n await endExecution({ ...finish(result), id });\n }\n return result;\n } catch (err) {\n if (id !== null) {\n await endExecution({\n id,\n status: 'failed',\n error: err instanceof Error ? err.message : String(err),\n });\n }\n throw err;\n }\n}\n","import { isoNow } from '../core/state-manager.js';\nimport type { CostRecord, NormalizedUsage, PricingSnapshot, TelemetryConfig } from './types.js';\n\nexport const PRICING_TABLE_VERSION = '2026-08-30';\n\ninterface PricingRow {\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n}\n\n/** Microdollars-per-million would be more precise; dollars keep the snapshot readable. */\nconst TABLE: Record<string, PricingRow> = {\n 'claude-sonnet-4': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-sonnet-4-5': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-opus-4': {\n inputPerMillion: 15,\n outputPerMillion: 75,\n cacheReadPerMillion: 1.5,\n cacheWritePerMillion: 18.75,\n },\n 'gpt-5': { inputPerMillion: 1.25, outputPerMillion: 10 },\n 'gpt-5.1': { inputPerMillion: 1.25, outputPerMillion: 10 },\n};\n\n/** Aliases a harness accepts in place of a model id. */\nconst ALIASES: Record<string, string> = {\n sonnet: 'claude-sonnet-4-5',\n opus: 'claude-opus-4',\n};\n\n/**\n * Map a resolved model id onto a table key.\n *\n * What reaches here is whatever the harness reported: a dated snapshot\n * (`claude-sonnet-4-5-20250929`), a vendor-prefixed id\n * (`anthropic/claude-sonnet-4-5`) or a configured alias (`sonnet`). An exact\n * lookup misses all three, and the estimate silently degrades to `unknown`.\n * An override is always honoured under the key the user wrote.\n */\nexport function normalizeModelKey(modelKey: string): string {\n const lower = modelKey.trim().toLowerCase();\n const withoutVendor = lower.slice(lower.lastIndexOf('/') + 1);\n const withoutSnapshot = withoutVendor.replace(/-\\d{8}$/, '').replace(/-latest$/, '');\n return ALIASES[withoutSnapshot] ?? withoutSnapshot;\n}\n\nfunction rowFor(\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'],\n): PricingRow | null {\n const normalized = normalizeModelKey(modelKey);\n const override = overrides[modelKey] ?? overrides[normalized];\n const base = TABLE[modelKey] ?? TABLE[normalized];\n if (override === undefined && base === undefined) return null;\n return {\n inputPerMillion: override?.inputPerMillion ?? base?.inputPerMillion ?? 0,\n outputPerMillion: override?.outputPerMillion ?? base?.outputPerMillion ?? 0,\n cacheReadPerMillion: override?.cacheReadPerMillion ?? base?.cacheReadPerMillion,\n cacheWritePerMillion: override?.cacheWritePerMillion ?? base?.cacheWritePerMillion,\n };\n}\n\nfunction dollars(tokens: number | undefined, perMillion: number | undefined): number {\n if (tokens === undefined || perMillion === undefined) return 0;\n return (tokens * perMillion) / 1_000_000;\n}\n\nexport function resolveCost(options: {\n reportedUsd?: number | null;\n usage: NormalizedUsage | null;\n modelKey: string | null;\n estimate: boolean;\n overrides?: TelemetryConfig['pricing']['overrides'];\n}): CostRecord {\n if (options.reportedUsd !== undefined && options.reportedUsd !== null) {\n return { status: 'reported', amount: options.reportedUsd, currency: 'USD' };\n }\n if (!options.estimate) {\n return { status: 'unknown', reason: 'not_reported' };\n }\n if (options.modelKey === null || options.modelKey === '') {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n const row = rowFor(options.modelKey, options.overrides ?? {});\n if (row === null) {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n if (options.usage === null || options.usage.source === 'unavailable') {\n return { status: 'unknown', reason: 'not_reported' };\n }\n const amount =\n dollars(options.usage.inputTokens, row.inputPerMillion) +\n dollars(options.usage.outputTokens, row.outputPerMillion) +\n dollars(options.usage.cacheReadTokens, row.cacheReadPerMillion) +\n dollars(options.usage.cacheCreationTokens, row.cacheWritePerMillion);\n const pricing: PricingSnapshot = {\n tableVersion: PRICING_TABLE_VERSION,\n modelKey: options.modelKey,\n inputPerMillion: row.inputPerMillion,\n outputPerMillion: row.outputPerMillion,\n capturedAt: isoNow(),\n ...(row.cacheReadPerMillion === undefined\n ? {}\n : { cacheReadPerMillion: row.cacheReadPerMillion }),\n ...(row.cacheWritePerMillion === undefined\n ? {}\n : { cacheWritePerMillion: row.cacheWritePerMillion }),\n };\n return { status: 'estimated', amount, currency: 'USD', pricing };\n}\n\nexport function estimateCost(\n usage: NormalizedUsage,\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'] = {},\n): CostRecord {\n return resolveCost({ usage, modelKey, estimate: true, overrides });\n}\n","import type { FailureKind } from '../resilience/errors.js';\n\nexport const EXECUTION_PURPOSES = [\n 'analyze',\n 'generate',\n 'prd',\n 'plan',\n 'execute',\n 'review',\n 'pr',\n 'pr-review',\n 'verify',\n] as const;\n\nexport type ExecutionPurpose = (typeof EXECUTION_PURPOSES)[number];\n\nexport type ExecutionTrigger = 'initial' | 'retry' | 'fallback' | 'correction' | 'escalation';\n\nexport type ExecutionStatus =\n | 'running'\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'interrupted';\n\nexport type StopReason =\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'max_attempts'\n | 'max_cost'\n | 'max_duration';\n\nexport type VerdictStatus = 'passed' | 'failed' | 'unverified';\n\nexport interface NormalizedUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n reasoningTokens?: number;\n details?: Record<string, number>;\n source: 'provider' | 'unavailable';\n}\n\nexport interface PricingSnapshot {\n tableVersion: string;\n modelKey: string;\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n capturedAt: string;\n}\n\nexport type CostRecord =\n | { status: 'reported'; amount: number; currency: 'USD' }\n | { status: 'estimated'; amount: number; currency: 'USD'; pricing: PricingSnapshot }\n | {\n status: 'unknown';\n reason: 'not_reported' | 'no_pricing' | 'unknown_model' | 'subscription' | 'zero_rated';\n };\n\nexport interface ExecutionAgent {\n harness: string;\n provider: string | null;\n harnessVersion?: string | null;\n model: {\n requested: string | null;\n resolved: string | null;\n source: 'provider' | 'config' | 'routing' | 'unavailable';\n };\n providerSessionId: string | null;\n}\n\nexport interface ExecutionOwner {\n pid: number;\n host: string;\n}\n\nexport interface ExecutionVerdict {\n status: VerdictStatus;\n level?: string | null;\n independence?: string | null;\n}\n\nexport interface RoutingDecision {\n selected: string | { harness: string; provider: string; model?: string | null; tier?: string };\n actual?: string | { harness: string; provider: string; model?: string | null; tier?: string };\n candidates?: unknown[];\n reasonCodes?: string[];\n [key: string]: unknown;\n}\n\nexport interface ExecutionRecord {\n id: string;\n sessionId: string | null;\n purpose: ExecutionPurpose;\n attempt: number;\n trigger: ExecutionTrigger;\n triggerReason: FailureKind | null;\n agent: ExecutionAgent;\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n /** Envelope duration when the CLI reports it. */\n cliDurationMs?: number | null;\n /** wallClock − cliDuration: startup the CLI does not see. */\n harnessStartupMs?: number | null;\n /** Envelope `duration_api_ms` when reported. */\n apiDurationMs?: number | null;\n /** Time to first output, when reported. */\n ttftMs?: number | null;\n numTurns?: number | null;\n usage: NormalizedUsage | null;\n cost: CostRecord;\n status: ExecutionStatus;\n failure: {\n kind: FailureKind;\n message: string;\n exitCode: number | null;\n } | null;\n stopReason?: StopReason | null;\n iteration?: number;\n /** Correction cycle active when this invocation started; 0 is the initial pass. */\n correctionCycle?: number;\n storyIds?: string[];\n owner?: ExecutionOwner | null;\n routingDecision?: RoutingDecision | null;\n verdict?: ExecutionVerdict | null;\n}\n\nexport interface CostTotals {\n reported: number;\n estimated: number;\n unknownExecutions: number;\n}\n\nexport interface ExecutionSummary {\n count: number;\n discarded: number;\n byStatus: Partial<Record<ExecutionStatus, number>>;\n usage: {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n reasoningTokens: number;\n };\n totalCost: CostTotals;\n}\n\nexport interface TelemetryConfig {\n enabled: boolean;\n maxExecutions: number;\n pricing: {\n estimate: boolean;\n overrides: Record<string, Partial<PricingSnapshot>>;\n };\n}\n\nexport const DEFAULT_TELEMETRY_CONFIG: TelemetryConfig = {\n enabled: true,\n maxExecutions: 500,\n pricing: { estimate: false, overrides: {} },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
loadPolicyConfig,
|
|
4
4
|
mergeConfigLayers
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YC24E66P.js";
|
|
6
6
|
import {
|
|
7
7
|
printWarning
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DBLXLKGU.js";
|
|
9
9
|
import {
|
|
10
10
|
getProjectRoot,
|
|
11
11
|
run
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KUA6KBBD.js";
|
|
13
13
|
|
|
14
14
|
// src/conventions/git/types.ts
|
|
15
15
|
var CHANGE_TYPES = [
|
|
@@ -40,7 +40,13 @@ var DEFAULT_LABEL_TYPE_MAP = {
|
|
|
40
40
|
architecture: "feat",
|
|
41
41
|
investigation: "chore"
|
|
42
42
|
};
|
|
43
|
-
var FORBIDDEN_PROVIDER_NAMES = [
|
|
43
|
+
var FORBIDDEN_PROVIDER_NAMES = [
|
|
44
|
+
"claude",
|
|
45
|
+
"codex",
|
|
46
|
+
"cursor",
|
|
47
|
+
"antigravity",
|
|
48
|
+
"opencode"
|
|
49
|
+
];
|
|
44
50
|
function isChangeType(value) {
|
|
45
51
|
return CHANGE_TYPES.includes(value);
|
|
46
52
|
}
|
|
@@ -351,14 +357,14 @@ function issueReferenceLines(input) {
|
|
|
351
357
|
}
|
|
352
358
|
|
|
353
359
|
// src/policy/resolve.ts
|
|
354
|
-
import { isAbsolute, normalize, sep as sep2 } from "path";
|
|
360
|
+
import { isAbsolute, normalize, sep as sep2 } from "node:path";
|
|
355
361
|
|
|
356
362
|
// src/policy/discovery.ts
|
|
357
|
-
import { readdir, readFile, stat } from "fs/promises";
|
|
358
|
-
import { join, relative, sep } from "path";
|
|
363
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
364
|
+
import { join, relative, sep } from "node:path";
|
|
359
365
|
|
|
360
366
|
// src/policy/parsers/docs.ts
|
|
361
|
-
import { posix } from "path";
|
|
367
|
+
import { posix } from "node:path";
|
|
362
368
|
function classifyDocument(fileName) {
|
|
363
369
|
switch (fileName.toLowerCase()) {
|
|
364
370
|
case "agents.md":
|
|
@@ -543,7 +549,7 @@ function parseIssueTypes(payload) {
|
|
|
543
549
|
}
|
|
544
550
|
|
|
545
551
|
// src/policy/parsers/templates.ts
|
|
546
|
-
import { basename, extname } from "path";
|
|
552
|
+
import { basename, extname } from "node:path";
|
|
547
553
|
|
|
548
554
|
// src/policy/parsers/issue-forms.ts
|
|
549
555
|
function emptyTemplateMetadata() {
|
|
@@ -1417,14 +1423,14 @@ async function resolvePolicy(root, scope, options) {
|
|
|
1417
1423
|
discoverGitConventions(root)
|
|
1418
1424
|
]
|
|
1419
1425
|
);
|
|
1420
|
-
const wantsOrgTemplates = toggles.issueTemplates && templateDiscovery.templates.length === 0;
|
|
1426
|
+
const wantsOrgTemplates = options.remote !== false && toggles.issueTemplates && templateDiscovery.templates.length === 0;
|
|
1421
1427
|
const [baseBranch, slug] = await Promise.all([
|
|
1422
|
-
discoverBaseBranch(root, options.exec),
|
|
1423
|
-
toggles.issueTypes || wantsOrgTemplates ? discoverGitHubSlug(root, options.exec) : Promise.resolve(null)
|
|
1428
|
+
options.remote === false ? Promise.resolve({ baseBranch: null, sources: [] }) : discoverBaseBranch(root, options.exec),
|
|
1429
|
+
options.remote !== false && toggles.issueTypes || wantsOrgTemplates ? discoverGitHubSlug(root, options.exec) : Promise.resolve(null)
|
|
1424
1430
|
]);
|
|
1425
1431
|
const [labels, issueTypes, orgTemplates, orgForms] = await Promise.all([
|
|
1426
|
-
toggles.labels ? discoverLabels(root, options.exec) : Promise.resolve({ labels: [], sources: [disabledSource("labels")] }),
|
|
1427
|
-
toggles.issueTypes ? discoverIssueTypes(root, slug?.owner ?? null, options.exec) : Promise.resolve({ types: [], sources: [disabledSource("issue-types")] }),
|
|
1432
|
+
options.remote !== false && toggles.labels ? discoverLabels(root, options.exec) : Promise.resolve({ labels: [], sources: [disabledSource("labels")] }),
|
|
1433
|
+
options.remote !== false && toggles.issueTypes ? discoverIssueTypes(root, slug?.owner ?? null, options.exec) : Promise.resolve({ types: [], sources: [disabledSource("issue-types")] }),
|
|
1428
1434
|
wantsOrgTemplates ? discoverOrganizationTemplates(root, slug, options.exec) : Promise.resolve({ templates: [], sources: [] }),
|
|
1429
1435
|
// Two calls, because GitHub answers the two kinds of organization default
|
|
1430
1436
|
// through different surfaces: `issueTemplates` covers markdown templates and
|
|
@@ -1533,7 +1539,7 @@ async function loadRepositoryPolicy(options = {}) {
|
|
|
1533
1539
|
if (options.cache === false) {
|
|
1534
1540
|
return resolvePolicy(root, scope, options);
|
|
1535
1541
|
}
|
|
1536
|
-
const key = `${root}\0${scope ?? ""}`;
|
|
1542
|
+
const key = `${root}\0${scope ?? ""}\0${options.remote !== false}`;
|
|
1537
1543
|
const cached = cache.get(key);
|
|
1538
1544
|
if (cached !== void 0) {
|
|
1539
1545
|
return cached;
|
|
@@ -1559,4 +1565,4 @@ export {
|
|
|
1559
1565
|
issueReferenceLines,
|
|
1560
1566
|
loadRepositoryPolicy
|
|
1561
1567
|
};
|
|
1562
|
-
//# sourceMappingURL=chunk-
|
|
1568
|
+
//# sourceMappingURL=chunk-WQSGL5LX.js.map
|