issue-flow 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/agent-TB6W7PT7.js +30 -0
  2. package/dist/{analyze-O2PYDIFK.js → analyze-6M3KEOX7.js} +22 -22
  3. package/dist/{apply-SSU6QCD4.js → apply-ADB3ZK7W.js} +14 -14
  4. package/dist/{bench-ODFPAGW6.js → bench-FM7I7EIV.js} +23 -23
  5. package/dist/{chunk-BMHGRYL6.js → chunk-2SUFAE6X.js} +67 -24
  6. package/dist/chunk-2SUFAE6X.js.map +1 -0
  7. package/dist/{chunk-QRCGW2ZO.js → chunk-32JSYXEK.js} +8 -8
  8. package/dist/chunk-3R27MJ5R.js +25 -0
  9. package/dist/chunk-3R27MJ5R.js.map +1 -0
  10. package/dist/{chunk-MGCOQU6N.js → chunk-6YQT3SSM.js} +4 -4
  11. package/dist/chunk-6YQT3SSM.js.map +1 -0
  12. package/dist/{chunk-A35HE4V7.js → chunk-7F7LGMVO.js} +3 -3
  13. package/dist/{chunk-RPXDBX6R.js → chunk-A4H7P7T7.js} +102 -102
  14. package/dist/chunk-A4H7P7T7.js.map +1 -0
  15. package/dist/{chunk-2ZAM45PZ.js → chunk-ANI2NTR4.js} +9 -9
  16. package/dist/{chunk-ZPIVCM7Q.js → chunk-B3TSS7BT.js} +3 -3
  17. package/dist/chunk-C5TL7T4V.js +27 -0
  18. package/dist/chunk-C5TL7T4V.js.map +1 -0
  19. package/dist/chunk-D6ZBGJ3L.js +321 -0
  20. package/dist/chunk-D6ZBGJ3L.js.map +1 -0
  21. package/dist/{chunk-ZXPASFHG.js → chunk-DGRTJD5R.js} +3 -3
  22. package/dist/{chunk-6QYMSNVA.js → chunk-DUS5ZNKL.js} +476 -362
  23. package/dist/chunk-DUS5ZNKL.js.map +1 -0
  24. package/dist/{chunk-VR34TXHF.js → chunk-DV7HUC4Z.js} +7 -7
  25. package/dist/{chunk-6SRE4KD7.js → chunk-E6KXCV3T.js} +4 -4
  26. package/dist/{chunk-HGSYD57B.js → chunk-HJBF4WD2.js} +1656 -1070
  27. package/dist/chunk-HJBF4WD2.js.map +1 -0
  28. package/dist/{chunk-PCN7ZQND.js → chunk-HLAPOUEM.js} +8 -8
  29. package/dist/{chunk-WM3Y7Q4A.js → chunk-HY5HLFDU.js} +630 -571
  30. package/dist/chunk-HY5HLFDU.js.map +1 -0
  31. package/dist/{chunk-XDKGA6UX.js → chunk-ICM463EO.js} +64 -14
  32. package/dist/chunk-ICM463EO.js.map +1 -0
  33. package/dist/{chunk-MEFY4B7T.js → chunk-ISZ54SVE.js} +9 -9
  34. package/dist/{chunk-ARWNYXFL.js → chunk-KZ5EY5XX.js} +12 -12
  35. package/dist/{chunk-ZFIXEYUJ.js → chunk-KZXQWC7U.js} +32 -20
  36. package/dist/chunk-KZXQWC7U.js.map +1 -0
  37. package/dist/{chunk-KAHQ6F5C.js → chunk-LPWPFIIB.js} +11 -11
  38. package/dist/{chunk-FK4IDY6P.js → chunk-MI5TREN3.js} +9 -9
  39. package/dist/{chunk-UNQYMR3H.js → chunk-PPZ3K4YM.js} +2 -2
  40. package/dist/{chunk-F4OK7KEP.js → chunk-QMIQR7EE.js} +10 -10
  41. package/dist/{chunk-AYYMW33T.js → chunk-QPGEFLMY.js} +2 -2
  42. package/dist/chunk-RCZJQUTC.js +196 -0
  43. package/dist/chunk-RCZJQUTC.js.map +1 -0
  44. package/dist/{chunk-MROS3SKL.js → chunk-RNFUVKC3.js} +3 -3
  45. package/dist/{chunk-RWEXK55D.js → chunk-RYOUZ6EK.js} +2 -2
  46. package/dist/{chunk-6E2PEBFT.js → chunk-SGTTR4XW.js} +10 -10
  47. package/dist/{chunk-XQHFC62U.js → chunk-SOM4QA6C.js} +3 -3
  48. package/dist/{chunk-5ZKBIXET.js → chunk-UK4E2FUA.js} +132 -34
  49. package/dist/chunk-UK4E2FUA.js.map +1 -0
  50. package/dist/{chunk-6FXOU2KR.js → chunk-UWDCIFTP.js} +7 -7
  51. package/dist/{chunk-XG2NYDRA.js → chunk-VE3IYNDN.js} +3 -3
  52. package/dist/{chunk-3BWZO4YI.js → chunk-WCCZJL7W.js} +2 -2
  53. package/dist/{chunk-NVZMBXTE.js → chunk-XZUEFTUP.js} +6 -6
  54. package/dist/{chunk-TBDP6QPJ.js → chunk-YII4U7ZD.js} +10 -10
  55. package/dist/{chunk-TBDP6QPJ.js.map → chunk-YII4U7ZD.js.map} +1 -1
  56. package/dist/{chunk-4RXYFWP7.js → chunk-YUNBOUQH.js} +6 -6
  57. package/dist/{chunk-GSZCQUCY.js → chunk-YVPZUN6X.js} +2 -2
  58. package/dist/{chunk-XRLRKTQA.js → chunk-Z5O2XBWA.js} +14 -14
  59. package/dist/cli.js +61 -52
  60. package/dist/cli.js.map +1 -1
  61. package/dist/{config-UMP6DBJB.js → config-KGZUPAUP.js} +13 -13
  62. package/dist/{conventions-DKH7AE4T.js → conventions-RYN7OXJN.js} +15 -15
  63. package/dist/{diagnostics-GOGCLTRS.js → diagnostics-HTCWF7F4.js} +7 -7
  64. package/dist/execute-QL3ZQIAP.js +37 -0
  65. package/dist/{generate-AGBT7EHX.js → generate-CX6KNHZS.js} +22 -22
  66. package/dist/{git-AC542GU2.js → git-A2IP32PQ.js} +2 -2
  67. package/dist/init-PDVQDRS6.js +24 -0
  68. package/dist/{operations-JQYK2EMT.js → operations-CAKIT2BO.js} +15 -15
  69. package/dist/{permissions-6HL52K54.js → permissions-G4XCAESF.js} +4 -4
  70. package/dist/plan-PRORGS3L.js +34 -0
  71. package/dist/{policy-IMRXGG7X.js → policy-WX6O2JID.js} +14 -14
  72. package/dist/pr-27RMQI5F.js +39 -0
  73. package/dist/pr-review-VNESMAMT.js +32 -0
  74. package/dist/prd-ZNC4T5BS.js +33 -0
  75. package/dist/{ps-KUUZ6TUL.js → ps-76L6ZAZL.js} +12 -12
  76. package/dist/{recorder-BJ2KIAWT.js → recorder-N7U66HCO.js} +7 -7
  77. package/dist/{registry-SB7XTMGE.js → registry-XLHHYLTR.js} +5 -5
  78. package/dist/{resume-QNLQSCR5.js → resume-VLWIE264.js} +40 -38
  79. package/dist/{resume-QNLQSCR5.js.map → resume-VLWIE264.js.map} +1 -1
  80. package/dist/review-7CREJDKB.js +35 -0
  81. package/dist/routing-VCDYHSXA.js +33 -0
  82. package/dist/run-3MPORLF5.js +56 -0
  83. package/dist/{session-publisher-T7EI3CIP.js → session-publisher-KAJQRHNZ.js} +3 -2
  84. package/dist/{state-manager-ZEPWTCA6.js → state-manager-UPHO2EA2.js} +4 -4
  85. package/dist/state-manager-UPHO2EA2.js.map +1 -0
  86. package/dist/{usage-QL563I7F.js → usage-U7QNGCPK.js} +12 -12
  87. package/dist/{web-PPSMNTQ6.js → web-HUNDHCJ4.js} +21 -18
  88. package/dist/{web-PPSMNTQ6.js.map → web-HUNDHCJ4.js.map} +1 -1
  89. package/package.json +6 -5
  90. package/web/AGENTS.md +15 -11
  91. package/web/public/app.css +51 -0
  92. package/web/public/app.js +325 -56
  93. package/web/public/index.html +6 -2
  94. package/dist/agent-AT64RXTA.js +0 -30
  95. package/dist/chunk-5ZKBIXET.js.map +0 -1
  96. package/dist/chunk-6QYMSNVA.js.map +0 -1
  97. package/dist/chunk-7Z4Y3VKM.js +0 -26
  98. package/dist/chunk-7Z4Y3VKM.js.map +0 -1
  99. package/dist/chunk-BMHGRYL6.js.map +0 -1
  100. package/dist/chunk-HGSYD57B.js.map +0 -1
  101. package/dist/chunk-MGCOQU6N.js.map +0 -1
  102. package/dist/chunk-RPXDBX6R.js.map +0 -1
  103. package/dist/chunk-WM3Y7Q4A.js.map +0 -1
  104. package/dist/chunk-XDKGA6UX.js.map +0 -1
  105. package/dist/chunk-XLVGPXNL.js +0 -180
  106. package/dist/chunk-XLVGPXNL.js.map +0 -1
  107. package/dist/chunk-ZFIXEYUJ.js.map +0 -1
  108. package/dist/execute-E3BRMDAQ.js +0 -35
  109. package/dist/init-LLBVJNPE.js +0 -24
  110. package/dist/plan-HSLWDJEZ.js +0 -34
  111. package/dist/pr-6TCZXG6K.js +0 -39
  112. package/dist/pr-review-6MWJO2NP.js +0 -32
  113. package/dist/prd-D6YDYAFX.js +0 -33
  114. package/dist/review-3KJ4BH2V.js +0 -35
  115. package/dist/routing-TN7GLMGU.js +0 -94
  116. package/dist/routing-TN7GLMGU.js.map +0 -1
  117. package/dist/run-5EHIFF2V.js +0 -54
  118. /package/dist/{agent-AT64RXTA.js.map → agent-TB6W7PT7.js.map} +0 -0
  119. /package/dist/{analyze-O2PYDIFK.js.map → analyze-6M3KEOX7.js.map} +0 -0
  120. /package/dist/{apply-SSU6QCD4.js.map → apply-ADB3ZK7W.js.map} +0 -0
  121. /package/dist/{bench-ODFPAGW6.js.map → bench-FM7I7EIV.js.map} +0 -0
  122. /package/dist/{chunk-QRCGW2ZO.js.map → chunk-32JSYXEK.js.map} +0 -0
  123. /package/dist/{chunk-A35HE4V7.js.map → chunk-7F7LGMVO.js.map} +0 -0
  124. /package/dist/{chunk-2ZAM45PZ.js.map → chunk-ANI2NTR4.js.map} +0 -0
  125. /package/dist/{chunk-ZPIVCM7Q.js.map → chunk-B3TSS7BT.js.map} +0 -0
  126. /package/dist/{chunk-ZXPASFHG.js.map → chunk-DGRTJD5R.js.map} +0 -0
  127. /package/dist/{chunk-VR34TXHF.js.map → chunk-DV7HUC4Z.js.map} +0 -0
  128. /package/dist/{chunk-6SRE4KD7.js.map → chunk-E6KXCV3T.js.map} +0 -0
  129. /package/dist/{chunk-PCN7ZQND.js.map → chunk-HLAPOUEM.js.map} +0 -0
  130. /package/dist/{chunk-MEFY4B7T.js.map → chunk-ISZ54SVE.js.map} +0 -0
  131. /package/dist/{chunk-ARWNYXFL.js.map → chunk-KZ5EY5XX.js.map} +0 -0
  132. /package/dist/{chunk-KAHQ6F5C.js.map → chunk-LPWPFIIB.js.map} +0 -0
  133. /package/dist/{chunk-FK4IDY6P.js.map → chunk-MI5TREN3.js.map} +0 -0
  134. /package/dist/{chunk-UNQYMR3H.js.map → chunk-PPZ3K4YM.js.map} +0 -0
  135. /package/dist/{chunk-F4OK7KEP.js.map → chunk-QMIQR7EE.js.map} +0 -0
  136. /package/dist/{chunk-AYYMW33T.js.map → chunk-QPGEFLMY.js.map} +0 -0
  137. /package/dist/{chunk-MROS3SKL.js.map → chunk-RNFUVKC3.js.map} +0 -0
  138. /package/dist/{chunk-RWEXK55D.js.map → chunk-RYOUZ6EK.js.map} +0 -0
  139. /package/dist/{chunk-6E2PEBFT.js.map → chunk-SGTTR4XW.js.map} +0 -0
  140. /package/dist/{chunk-XQHFC62U.js.map → chunk-SOM4QA6C.js.map} +0 -0
  141. /package/dist/{chunk-6FXOU2KR.js.map → chunk-UWDCIFTP.js.map} +0 -0
  142. /package/dist/{chunk-XG2NYDRA.js.map → chunk-VE3IYNDN.js.map} +0 -0
  143. /package/dist/{chunk-3BWZO4YI.js.map → chunk-WCCZJL7W.js.map} +0 -0
  144. /package/dist/{chunk-NVZMBXTE.js.map → chunk-XZUEFTUP.js.map} +0 -0
  145. /package/dist/{chunk-4RXYFWP7.js.map → chunk-YUNBOUQH.js.map} +0 -0
  146. /package/dist/{chunk-GSZCQUCY.js.map → chunk-YVPZUN6X.js.map} +0 -0
  147. /package/dist/{chunk-XRLRKTQA.js.map → chunk-Z5O2XBWA.js.map} +0 -0
  148. /package/dist/{config-UMP6DBJB.js.map → config-KGZUPAUP.js.map} +0 -0
  149. /package/dist/{conventions-DKH7AE4T.js.map → conventions-RYN7OXJN.js.map} +0 -0
  150. /package/dist/{diagnostics-GOGCLTRS.js.map → diagnostics-HTCWF7F4.js.map} +0 -0
  151. /package/dist/{execute-E3BRMDAQ.js.map → execute-QL3ZQIAP.js.map} +0 -0
  152. /package/dist/{generate-AGBT7EHX.js.map → generate-CX6KNHZS.js.map} +0 -0
  153. /package/dist/{git-AC542GU2.js.map → git-A2IP32PQ.js.map} +0 -0
  154. /package/dist/{init-LLBVJNPE.js.map → init-PDVQDRS6.js.map} +0 -0
  155. /package/dist/{operations-JQYK2EMT.js.map → operations-CAKIT2BO.js.map} +0 -0
  156. /package/dist/{permissions-6HL52K54.js.map → permissions-G4XCAESF.js.map} +0 -0
  157. /package/dist/{plan-HSLWDJEZ.js.map → plan-PRORGS3L.js.map} +0 -0
  158. /package/dist/{policy-IMRXGG7X.js.map → policy-WX6O2JID.js.map} +0 -0
  159. /package/dist/{pr-6TCZXG6K.js.map → pr-27RMQI5F.js.map} +0 -0
  160. /package/dist/{pr-review-6MWJO2NP.js.map → pr-review-VNESMAMT.js.map} +0 -0
  161. /package/dist/{prd-D6YDYAFX.js.map → prd-ZNC4T5BS.js.map} +0 -0
  162. /package/dist/{ps-KUUZ6TUL.js.map → ps-76L6ZAZL.js.map} +0 -0
  163. /package/dist/{recorder-BJ2KIAWT.js.map → recorder-N7U66HCO.js.map} +0 -0
  164. /package/dist/{registry-SB7XTMGE.js.map → registry-XLHHYLTR.js.map} +0 -0
  165. /package/dist/{review-3KJ4BH2V.js.map → review-7CREJDKB.js.map} +0 -0
  166. /package/dist/{run-5EHIFF2V.js.map → routing-VCDYHSXA.js.map} +0 -0
  167. /package/dist/{session-publisher-T7EI3CIP.js.map → run-3MPORLF5.js.map} +0 -0
  168. /package/dist/{state-manager-ZEPWTCA6.js.map → session-publisher-KAJQRHNZ.js.map} +0 -0
  169. /package/dist/{usage-QL563I7F.js.map → usage-U7QNGCPK.js.map} +0 -0
@@ -0,0 +1,321 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ANTIGRAVITY_CAPABILITIES,
4
+ CLAUDE_CAPABILITIES,
5
+ CODEX_CAPABILITIES,
6
+ CURSOR_CAPABILITIES
7
+ } from "./chunk-ICM463EO.js";
8
+
9
+ // src/routing/models.ts
10
+ var MODEL_CATALOG_VERSION = "1";
11
+ var MODEL_CATALOG = {
12
+ "claude-code": [
13
+ { id: "haiku", tier: "fast", relativeCost: 1, relativeLatency: 1 },
14
+ { id: "sonnet", tier: "mid", relativeCost: 3.5, relativeLatency: 1.5 },
15
+ { id: "opus", tier: "strong", relativeCost: 8, relativeLatency: 2.2 }
16
+ ],
17
+ "codex-cli": [
18
+ { id: "gpt-5.6-luna", tier: "fast", relativeCost: 1, relativeLatency: 1 },
19
+ { id: "gpt-5.6-terra", tier: "mid", relativeCost: 3, relativeLatency: 1.45 },
20
+ { id: "gpt-5.6-sol", tier: "strong", relativeCost: 7, relativeLatency: 2.1 }
21
+ ],
22
+ "cursor-cli": [
23
+ { id: "auto-fast", tier: "fast", relativeCost: 1, relativeLatency: 1 },
24
+ { id: "auto", tier: "mid", relativeCost: 3, relativeLatency: 1.5 },
25
+ { id: "auto-strong", tier: "strong", relativeCost: 7, relativeLatency: 2.1 }
26
+ ],
27
+ "antigravity-cli": [
28
+ { id: "gemini-3.5-flash-low", tier: "fast", relativeCost: 1, relativeLatency: 1 },
29
+ { id: "gemini-3.5-flash-medium", tier: "mid", relativeCost: 2.5, relativeLatency: 1.4 },
30
+ { id: "gemini-3.5-pro-high", tier: "strong", relativeCost: 6, relativeLatency: 2 }
31
+ ]
32
+ };
33
+ var DEFAULT_ONLY = [
34
+ { id: null, tier: "mid", relativeCost: 1, relativeLatency: 1 }
35
+ ];
36
+ function modelsFor(harness, capabilities) {
37
+ if (!capabilities.modelSelection) return DEFAULT_ONLY;
38
+ return MODEL_CATALOG[harness] ?? DEFAULT_ONLY;
39
+ }
40
+ function modelForTier(harness, tier) {
41
+ return MODEL_CATALOG[harness]?.find((entry) => entry.tier === tier) ?? null;
42
+ }
43
+
44
+ // src/routing/policy.ts
45
+ var RECOMMENDED_POLICY_VERSION = "1";
46
+ var RECOMMENDED_POLICY = {
47
+ analyze: { tier: "fast", preferHarness: "codex-cli" },
48
+ generate: { tier: "mid", preferHarness: "claude-code" },
49
+ prd: { tier: "mid", preferHarness: "claude-code" },
50
+ plan: { tier: "fast", preferHarness: "codex-cli" },
51
+ execute: { tier: "strong", preferHarness: "claude-code" },
52
+ review: { tier: "strong", preferHarness: "codex-cli" },
53
+ pr: { tier: "fast", preferHarness: "codex-cli" },
54
+ "pr-review": { tier: "strong", preferHarness: "codex-cli" }
55
+ };
56
+ var PROVIDERS = {
57
+ "claude-code": "claude",
58
+ "codex-cli": "codex",
59
+ "cursor-cli": "cursor",
60
+ "antigravity-cli": "antigravity"
61
+ };
62
+ function recommendedFor(phase) {
63
+ return RECOMMENDED_POLICY[phase];
64
+ }
65
+ function recommendedTarget(phase) {
66
+ const entry = recommendedFor(phase);
67
+ if (entry.preferHarness === void 0) return null;
68
+ const model = modelForTier(entry.preferHarness, entry.tier);
69
+ const provider = PROVIDERS[entry.preferHarness];
70
+ if (model === null || provider === void 0) return null;
71
+ return { harness: entry.preferHarness, provider, model: model.id, tier: entry.tier };
72
+ }
73
+
74
+ // src/routing/priors.ts
75
+ var PRIORS_VERSION = "2";
76
+ function tiers(mid) {
77
+ return { fast: Math.max(0, mid - 0.25), mid, strong: Math.min(1, mid + 0.12) };
78
+ }
79
+ function harnesses(values) {
80
+ return Object.fromEntries(Object.entries(values).map(([harness, mid]) => [harness, tiers(mid)]));
81
+ }
82
+ var PRIORS = {
83
+ bugfix: harnesses({
84
+ "claude-code": 0.7,
85
+ "codex-cli": 0.95,
86
+ "cursor-cli": 0.65,
87
+ "antigravity-cli": 0.6
88
+ }),
89
+ feature: harnesses({
90
+ "claude-code": 0.85,
91
+ "codex-cli": 0.8,
92
+ "cursor-cli": 0.7,
93
+ "antigravity-cli": 0.65
94
+ }),
95
+ refactor: harnesses({
96
+ "claude-code": 0.75,
97
+ "codex-cli": 0.9,
98
+ "cursor-cli": 0.65,
99
+ "antigravity-cli": 0.6
100
+ }),
101
+ docs: harnesses({
102
+ "claude-code": 0.8,
103
+ "codex-cli": 0.7,
104
+ "cursor-cli": 0.75,
105
+ "antigravity-cli": 0.7
106
+ }),
107
+ test: harnesses({
108
+ "claude-code": 0.7,
109
+ "codex-cli": 0.9,
110
+ "cursor-cli": 0.65,
111
+ "antigravity-cli": 0.6
112
+ }),
113
+ infra: harnesses({
114
+ "claude-code": 0.8,
115
+ "codex-cli": 0.75,
116
+ "cursor-cli": 0.6,
117
+ "antigravity-cli": 0.55
118
+ }),
119
+ analysis: harnesses({
120
+ "claude-code": 0.95,
121
+ "codex-cli": 0.6,
122
+ "cursor-cli": 0.7,
123
+ "antigravity-cli": 0.65
124
+ })
125
+ };
126
+ function priorFor(taskClass, harness, tier) {
127
+ return PRIORS[taskClass][harness]?.[tier] ?? 0.5;
128
+ }
129
+
130
+ // src/routing/analyze.ts
131
+ var RISK_PATHS = [/auth/i, /migrat/i, /infra/i, /\.github\//i, /permission/i, /secret/i];
132
+ function analyzeTask(signals = {}) {
133
+ const hay = [
134
+ signals.title ?? "",
135
+ signals.body ?? "",
136
+ ...signals.labels ?? [],
137
+ ...signals.paths ?? []
138
+ ].join(" ").toLowerCase();
139
+ const taskClass = classify(hay, signals);
140
+ const risk = RISK_PATHS.some(
141
+ (pattern) => (signals.paths ?? []).some((path) => pattern.test(path))
142
+ ) ? "high" : /security|auth|migrat/.test(hay) ? "high" : /refactor|large|epic/.test(hay) ? "medium" : "low";
143
+ return { taskClass, risk };
144
+ }
145
+ function classify(hay, signals) {
146
+ if (/\bdocs?\b|readme|changelog/.test(hay)) return "docs";
147
+ if (/\btest|spec|coverage/.test(hay)) return "test";
148
+ if (/\bcie?|deploy|infra|workflow|docker/.test(hay)) return "infra";
149
+ if (/\banaly[sz]e|investigat|research/.test(hay)) return "analysis";
150
+ if (/\bbug|fix|regres+ion|crash/.test(hay)) return "bugfix";
151
+ if (/\brefactor|cleanup|extract/.test(hay)) return "refactor";
152
+ if (/\bfeat|feature|add |implement/.test(hay)) return "feature";
153
+ if ((signals.labels ?? []).some((label) => /bug/i.test(label))) return "bugfix";
154
+ if ((signals.labels ?? []).some((label) => /enhancement|feature/i.test(label))) return "feature";
155
+ return "feature";
156
+ }
157
+
158
+ // src/routing/capabilities.ts
159
+ function filterEligible(input) {
160
+ const reasons = [];
161
+ if (input.requiresExtraDirectories && input.capabilities.extraDirectories === "none") {
162
+ reasons.push("MISSING_CAPABILITY:extraDirectories");
163
+ }
164
+ return { eligible: reasons.length === 0, reasonCodes: reasons };
165
+ }
166
+
167
+ // src/routing/score.ts
168
+ var DELTA = 0.2;
169
+ var MIN_SAMPLE_SIZE = 8;
170
+ var PROFILE_WEIGHTS = {
171
+ economy: { quality: 0.5, cost: 0.4, latency: 0.1 },
172
+ balanced: { quality: 0.6, cost: 0.25, latency: 0.15 },
173
+ quality: { quality: 0.85, cost: 0.05, latency: 0.1 },
174
+ speed: { quality: 0.45, cost: 0.1, latency: 0.45 }
175
+ };
176
+ function clampLearned(value) {
177
+ return Math.max(-DELTA, Math.min(DELTA, value));
178
+ }
179
+ function scoreCandidates(inputs) {
180
+ const profile = inputs[0]?.profile ?? "balanced";
181
+ const scored = inputs.map((input) => {
182
+ const prior = priorFor(input.taskClass, input.harness, input.tier);
183
+ const samples = input.samples ?? 0;
184
+ const rawLearned = samples >= MIN_SAMPLE_SIZE ? input.learned ?? 0 : 0;
185
+ const learned = clampLearned(rawLearned);
186
+ const weights = PROFILE_WEIGHTS[profile];
187
+ const costScore = 1 / input.relativeCost;
188
+ const latencyScore = 1 / input.relativeLatency;
189
+ const score = input.eligible ? (prior + learned) * weights.quality + costScore * weights.cost + latencyScore * weights.latency : 0;
190
+ const reasonCodes = [...input.reasonCodes];
191
+ if (input.eligible && samples === 0) reasonCodes.push("COLD_START");
192
+ if (input.eligible && learned > 0) reasonCodes.push("HIGH_HISTORICAL_SUCCESS");
193
+ return {
194
+ harness: input.harness,
195
+ provider: input.provider,
196
+ model: input.model ?? null,
197
+ tier: input.tier,
198
+ relativeCost: input.relativeCost,
199
+ relativeLatency: input.relativeLatency,
200
+ eligible: input.eligible,
201
+ prior,
202
+ learned,
203
+ samples,
204
+ score,
205
+ reasonCodes
206
+ };
207
+ });
208
+ return scored.sort((a, b) => {
209
+ if (b.score !== a.score) return b.score - a.score;
210
+ return a.harness.localeCompare(b.harness);
211
+ });
212
+ }
213
+ function pickSelected(candidates) {
214
+ const eligible = candidates.filter((candidate) => candidate.eligible);
215
+ if (eligible.length === 0) {
216
+ throw new Error(
217
+ `No eligible routing candidate: ${candidates.map((c) => `${c.harness} (${c.reasonCodes.join(",")})`).join("; ")}`
218
+ );
219
+ }
220
+ return eligible[0];
221
+ }
222
+
223
+ // src/routing/decide.ts
224
+ var CAPS = {
225
+ "claude-code": CLAUDE_CAPABILITIES,
226
+ "codex-cli": CODEX_CAPABILITIES,
227
+ "cursor-cli": CURSOR_CAPABILITIES,
228
+ "antigravity-cli": ANTIGRAVITY_CAPABILITIES
229
+ };
230
+ var PROVIDER = {
231
+ "claude-code": "claude",
232
+ "codex-cli": "codex",
233
+ "cursor-cli": "cursor",
234
+ "antigravity-cli": "antigravity"
235
+ };
236
+ function decideRouting(input) {
237
+ if (input.mode === "off") return null;
238
+ const analyzed = analyzeTask(input.signals ?? {});
239
+ const profile = input.profile ?? "balanced";
240
+ const policyVersion = `${PRIORS_VERSION}:${MODEL_CATALOG_VERSION}:${input.policy === "recommended" ? RECOMMENDED_POLICY_VERSION : "adaptive"}`;
241
+ if (input.skipScore) {
242
+ return {
243
+ policyVersion,
244
+ profile,
245
+ taskClass: analyzed.taskClass,
246
+ risk: analyzed.risk,
247
+ mode: input.mode,
248
+ candidates: [],
249
+ selected: {
250
+ harness: input.actualHarness,
251
+ provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,
252
+ model: input.actualModel ?? null
253
+ },
254
+ actual: {
255
+ harness: input.actualHarness,
256
+ provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,
257
+ model: input.actualModel ?? null
258
+ },
259
+ reasonCodes: ["EXPLICIT_CONFIG"]
260
+ };
261
+ }
262
+ const scored = scoreCandidates(
263
+ Object.keys(CAPS).flatMap((harness) => {
264
+ const eligibility = filterEligible({
265
+ harness,
266
+ capabilities: CAPS[harness],
267
+ phase: input.phase,
268
+ requiresExtraDirectories: input.requiresExtraDirectories === true
269
+ });
270
+ const recommendation = input.policy === "recommended" ? recommendedFor(input.phase) : null;
271
+ return modelsFor(harness, CAPS[harness]).map((model) => ({
272
+ harness,
273
+ provider: PROVIDER[harness] ?? harness,
274
+ model: model.id,
275
+ tier: model.tier,
276
+ relativeCost: model.relativeCost,
277
+ relativeLatency: model.relativeLatency,
278
+ eligible: eligibility.eligible && (recommendation === null || model.tier === recommendation.tier && (recommendation.preferHarness === void 0 || recommendation.preferHarness === harness)),
279
+ reasonCodes: [
280
+ ...eligibility.reasonCodes,
281
+ ...recommendation !== null && model.tier === recommendation.tier && (recommendation.preferHarness === void 0 || recommendation.preferHarness === harness) ? ["RECOMMENDED_POLICY"] : [],
282
+ ...model.tier === "fast" && analyzed.risk !== "high" ? ["CHEAPER_TIER_SUFFICIENT"] : [],
283
+ ...model.tier === "strong" && (analyzed.risk === "high" || profile === "quality") ? ["STRONGER_TIER_FOR_RISK"] : []
284
+ ],
285
+ taskClass: analyzed.taskClass,
286
+ profile
287
+ }));
288
+ })
289
+ );
290
+ const selected = pickSelected(scored);
291
+ return {
292
+ policyVersion,
293
+ profile,
294
+ taskClass: analyzed.taskClass,
295
+ risk: analyzed.risk,
296
+ mode: input.mode,
297
+ candidates: scored,
298
+ selected: {
299
+ harness: selected.harness,
300
+ provider: selected.provider,
301
+ model: selected.model ?? null,
302
+ tier: selected.tier
303
+ },
304
+ actual: {
305
+ harness: input.actualHarness,
306
+ provider: input.actualProvider ?? PROVIDER[input.actualHarness] ?? input.actualHarness,
307
+ model: input.actualModel ?? null
308
+ },
309
+ reasonCodes: selected.reasonCodes.includes("COLD_START") ? ["HIGH_PRIOR", ...selected.reasonCodes] : selected.reasonCodes
310
+ };
311
+ }
312
+
313
+ export {
314
+ MODEL_CATALOG_VERSION,
315
+ MODEL_CATALOG,
316
+ RECOMMENDED_POLICY_VERSION,
317
+ recommendedTarget,
318
+ PRIORS_VERSION,
319
+ decideRouting
320
+ };
321
+ //# sourceMappingURL=chunk-D6ZBGJ3L.js.map
@@ -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 = '1';\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};\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 = '1';\n\nexport interface RecommendedPolicyEntry {\n tier: ModelTier;\n preferHarness?: 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: { tier: 'fast', preferHarness: 'codex-cli' },\n generate: { tier: 'mid', preferHarness: 'claude-code' },\n prd: { tier: 'mid', preferHarness: 'claude-code' },\n plan: { tier: 'fast', preferHarness: 'codex-cli' },\n execute: { tier: 'strong', preferHarness: 'claude-code' },\n review: { tier: 'strong', preferHarness: 'codex-cli' },\n pr: { tier: 'fast', preferHarness: 'codex-cli' },\n 'pr-review': { tier: 'strong', preferHarness: 'codex-cli' },\n};\n\nconst PROVIDERS: Record<string, AgentProviderId> = {\n 'claude-code': 'claude',\n 'codex-cli': 'codex',\n 'cursor-cli': 'cursor',\n 'antigravity-cli': 'antigravity',\n};\n\nexport function recommendedFor(phase: AgentPhase): RecommendedPolicyEntry {\n return RECOMMENDED_POLICY[phase];\n}\n\nexport function recommendedTarget(phase: AgentPhase): ExecutionTarget | null {\n const entry = recommendedFor(phase);\n if (entry.preferHarness === undefined) return null;\n const model = modelForTier(entry.preferHarness, entry.tier);\n const provider = PROVIDERS[entry.preferHarness];\n if (model === null || provider === undefined) return null;\n return { harness: entry.preferHarness, provider, model: model.id, tier: entry.tier };\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 = '2';\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 */\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 }),\n feature: harnesses({\n 'claude-code': 0.85,\n 'codex-cli': 0.8,\n 'cursor-cli': 0.7,\n 'antigravity-cli': 0.65,\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 }),\n docs: harnesses({\n 'claude-code': 0.8,\n 'codex-cli': 0.7,\n 'cursor-cli': 0.75,\n 'antigravity-cli': 0.7,\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 }),\n infra: harnesses({\n 'claude-code': 0.8,\n 'codex-cli': 0.75,\n 'cursor-cli': 0.6,\n 'antigravity-cli': 0.55,\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 }),\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 { AgentCapabilities, AgentPhase } from '../agents/types.js';\n\nexport interface EligibilityInput {\n harness: string;\n capabilities: AgentCapabilities;\n phase: AgentPhase;\n requiresExtraDirectories: 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 */\nexport function filterEligible(input: EligibilityInput): Eligibility {\n const reasons: string[] = [];\n if (input.requiresExtraDirectories && input.capabilities.extraDirectories === 'none') {\n reasons.push('MISSING_CAPABILITY:extraDirectories');\n }\n return { eligible: reasons.length === 0, 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}\n\nexport function clampLearned(value: number): number {\n return Math.max(-DELTA, Math.min(DELTA, value));\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 score = input.eligible\n ? (prior + learned) * weights.quality +\n costScore * weights.cost +\n latencyScore * weights.latency\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 { AgentPhase } from '../agents/types.js';\nimport {\n ANTIGRAVITY_CAPABILITIES,\n CLAUDE_CAPABILITIES,\n CODEX_CAPABILITIES,\n CURSOR_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 { 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} 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};\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}): 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'}`;\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 scored = scoreCandidates(\n (Object.keys(CAPS) as (keyof typeof CAPS)[]).flatMap((harness) => {\n const eligibility = filterEligible({\n harness,\n capabilities: CAPS[harness],\n phase: input.phase,\n requiresExtraDirectories: input.requiresExtraDirectories === true,\n });\n const recommendation = input.policy === 'recommended' ? recommendedFor(input.phase) : null;\n return modelsFor(harness, CAPS[harness]).map((model) => ({\n harness,\n provider: PROVIDER[harness] ?? harness,\n model: model.id,\n tier: model.tier,\n relativeCost: model.relativeCost,\n relativeLatency: model.relativeLatency,\n eligible:\n eligibility.eligible &&\n (recommendation === null ||\n (model.tier === recommendation.tier &&\n (recommendation.preferHarness === undefined ||\n recommendation.preferHarness === harness))),\n reasonCodes: [\n ...eligibility.reasonCodes,\n ...(recommendation !== null &&\n model.tier === recommendation.tier &&\n (recommendation.preferHarness === undefined || recommendation.preferHarness === harness)\n ? ['RECOMMENDED_POLICY']\n : []),\n ...(model.tier === 'fast' && analyzed.risk !== 'high' ? ['CHEAPER_TIER_SUFFICIENT'] : []),\n ...(model.tier === 'strong' && (analyzed.risk === 'high' || profile === 'quality')\n ? ['STRONGER_TIER_FOR_RISK']\n : []),\n ],\n taskClass: analyzed.taskClass,\n profile,\n }));\n }),\n );\n const selected = pickSelected(scored);\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":"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","names":[]}
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-HAKDLR6N.js";
5
5
  import {
6
6
  getProjectRoot
7
- } from "./chunk-GSZCQUCY.js";
7
+ } from "./chunk-YVPZUN6X.js";
8
8
  import {
9
9
  writeFileAtomic
10
- } from "./chunk-7Z4Y3VKM.js";
10
+ } from "./chunk-3R27MJ5R.js";
11
11
 
12
12
  // src/agents/permissions.ts
13
13
  import { mkdir, readFile } from "fs/promises";
@@ -74,4 +74,4 @@ export {
74
74
  ensureCursorStorageGrant,
75
75
  cursorStorageGranted
76
76
  };
77
- //# sourceMappingURL=chunk-ZXPASFHG.js.map
77
+ //# sourceMappingURL=chunk-DGRTJD5R.js.map