squads-cli 0.2.0 → 0.2.1

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 (223) hide show
  1. package/README.md +521 -288
  2. package/dist/auth-YW3UPFSB.js +23 -0
  3. package/dist/auth-YW3UPFSB.js.map +1 -0
  4. package/dist/autonomy-PSVZVX7A.js +105 -0
  5. package/dist/autonomy-PSVZVX7A.js.map +1 -0
  6. package/dist/chunk-67RO2HKR.js +174 -0
  7. package/dist/chunk-67RO2HKR.js.map +1 -0
  8. package/dist/chunk-7OCVIDC7.js +12 -0
  9. package/dist/chunk-7OCVIDC7.js.map +1 -0
  10. package/dist/chunk-BODLDQY7.js +452 -0
  11. package/dist/chunk-BODLDQY7.js.map +1 -0
  12. package/dist/chunk-EHQJHRIW.js +103 -0
  13. package/dist/chunk-EHQJHRIW.js.map +1 -0
  14. package/dist/chunk-FFFCFZ6A.js +121 -0
  15. package/dist/chunk-FFFCFZ6A.js.map +1 -0
  16. package/dist/chunk-FIWT2NMM.js +165 -0
  17. package/dist/chunk-FIWT2NMM.js.map +1 -0
  18. package/dist/chunk-HF4WR7RA.js +154 -0
  19. package/dist/chunk-HF4WR7RA.js.map +1 -0
  20. package/dist/chunk-J6QF4ZQX.js +230 -0
  21. package/dist/chunk-J6QF4ZQX.js.map +1 -0
  22. package/dist/chunk-LOA3KWYJ.js +294 -0
  23. package/dist/chunk-LOA3KWYJ.js.map +1 -0
  24. package/dist/chunk-M5FXNY6Y.js +384 -0
  25. package/dist/chunk-M5FXNY6Y.js.map +1 -0
  26. package/dist/chunk-QHNUMM4V.js +87 -0
  27. package/dist/chunk-QHNUMM4V.js.map +1 -0
  28. package/dist/chunk-QJ7C7CMB.js +223 -0
  29. package/dist/chunk-QJ7C7CMB.js.map +1 -0
  30. package/dist/chunk-RM6BWILN.js +74 -0
  31. package/dist/chunk-RM6BWILN.js.map +1 -0
  32. package/dist/chunk-TYFTF53O.js +613 -0
  33. package/dist/chunk-TYFTF53O.js.map +1 -0
  34. package/dist/chunk-TZXD6WFN.js +420 -0
  35. package/dist/chunk-TZXD6WFN.js.map +1 -0
  36. package/dist/chunk-WVOIY5GW.js +621 -0
  37. package/dist/chunk-WVOIY5GW.js.map +1 -0
  38. package/dist/chunk-Z2UKDBNL.js +162 -0
  39. package/dist/chunk-Z2UKDBNL.js.map +1 -0
  40. package/dist/chunk-ZTQ7ISUR.js +338 -0
  41. package/dist/chunk-ZTQ7ISUR.js.map +1 -0
  42. package/dist/cli.js +2483 -5902
  43. package/dist/cli.js.map +1 -1
  44. package/dist/context-GWPF4SEY.js +291 -0
  45. package/dist/context-GWPF4SEY.js.map +1 -0
  46. package/dist/context-feed-AJGVAR6H.js +394 -0
  47. package/dist/context-feed-AJGVAR6H.js.map +1 -0
  48. package/dist/cost-XBCDJ7XC.js +275 -0
  49. package/dist/cost-XBCDJ7XC.js.map +1 -0
  50. package/dist/create-BLFGG6PF.js +286 -0
  51. package/dist/create-BLFGG6PF.js.map +1 -0
  52. package/dist/dashboard-LGT2B2BL.js +951 -0
  53. package/dist/dashboard-LGT2B2BL.js.map +1 -0
  54. package/dist/dashboard-RMK2BOD2.js +794 -0
  55. package/dist/dashboard-RMK2BOD2.js.map +1 -0
  56. package/dist/doctor-XPUIIBHJ.js +374 -0
  57. package/dist/doctor-XPUIIBHJ.js.map +1 -0
  58. package/dist/env-config-SQEI3Y7Y.js +21 -0
  59. package/dist/env-config-SQEI3Y7Y.js.map +1 -0
  60. package/dist/exec-OUXM7JBF.js +223 -0
  61. package/dist/exec-OUXM7JBF.js.map +1 -0
  62. package/dist/feedback-KNAOG5QK.js +229 -0
  63. package/dist/feedback-KNAOG5QK.js.map +1 -0
  64. package/dist/github-UQTM5KMS.js +23 -0
  65. package/dist/github-UQTM5KMS.js.map +1 -0
  66. package/dist/goal-BVHV5573.js +168 -0
  67. package/dist/goal-BVHV5573.js.map +1 -0
  68. package/dist/health-4UXN44PF.js +218 -0
  69. package/dist/health-4UXN44PF.js.map +1 -0
  70. package/dist/history-ILH3SWHB.js +232 -0
  71. package/dist/history-ILH3SWHB.js.map +1 -0
  72. package/dist/index.d.ts +736 -8
  73. package/dist/index.js +1312 -6
  74. package/dist/index.js.map +1 -1
  75. package/dist/init-XQZ7BOGT.js +812 -0
  76. package/dist/init-XQZ7BOGT.js.map +1 -0
  77. package/dist/kpi-RQIU7WGK.js +413 -0
  78. package/dist/kpi-RQIU7WGK.js.map +1 -0
  79. package/dist/learn-OIFUVZAS.js +269 -0
  80. package/dist/learn-OIFUVZAS.js.map +1 -0
  81. package/dist/login-DXZANWZY.js +155 -0
  82. package/dist/login-DXZANWZY.js.map +1 -0
  83. package/dist/memory-T3ACCS7E.js +560 -0
  84. package/dist/memory-T3ACCS7E.js.map +1 -0
  85. package/dist/memory-VNF2VFRB.js +23 -0
  86. package/dist/memory-VNF2VFRB.js.map +1 -0
  87. package/dist/progress-DAUZMT3N.js +202 -0
  88. package/dist/progress-DAUZMT3N.js.map +1 -0
  89. package/dist/providers-3P5D2XL5.js +65 -0
  90. package/dist/providers-3P5D2XL5.js.map +1 -0
  91. package/dist/results-UECWGLTB.js +224 -0
  92. package/dist/results-UECWGLTB.js.map +1 -0
  93. package/dist/run-I6KAXU6U.js +4049 -0
  94. package/dist/run-I6KAXU6U.js.map +1 -0
  95. package/dist/session-HBU6KZOD.js +64 -0
  96. package/dist/session-HBU6KZOD.js.map +1 -0
  97. package/dist/sessions-CK25VGPL.js +333 -0
  98. package/dist/sessions-CK25VGPL.js.map +1 -0
  99. package/dist/squad-parser-DCG65BJS.js +35 -0
  100. package/dist/squad-parser-DCG65BJS.js.map +1 -0
  101. package/dist/stats-G6NAU5BD.js +334 -0
  102. package/dist/stats-G6NAU5BD.js.map +1 -0
  103. package/dist/status-AQNLDZVN.js +352 -0
  104. package/dist/status-AQNLDZVN.js.map +1 -0
  105. package/dist/sync-ZI3MHA4G.js +836 -0
  106. package/dist/sync-ZI3MHA4G.js.map +1 -0
  107. package/dist/templates/core/AGENTS.md.template +51 -0
  108. package/dist/templates/core/BUSINESS_BRIEF.md.template +29 -0
  109. package/dist/templates/core/CLAUDE.md.template +48 -0
  110. package/dist/templates/core/provider.yaml.template +5 -0
  111. package/dist/templates/first-squad/SQUAD.md.template +23 -0
  112. package/dist/templates/first-squad/lead.md.template +44 -0
  113. package/dist/templates/memory/getting-started/state.md.template +19 -0
  114. package/dist/templates/seed/BUSINESS_BRIEF.md.template +27 -0
  115. package/dist/templates/seed/CLAUDE.md.template +119 -0
  116. package/dist/templates/seed/README.md.template +42 -0
  117. package/dist/templates/seed/config/SYSTEM.md +52 -0
  118. package/dist/templates/seed/config/provider.yaml +4 -0
  119. package/dist/templates/seed/hooks/settings.json.template +31 -0
  120. package/dist/templates/seed/memory/company/directives.md +37 -0
  121. package/dist/templates/seed/memory/company/manager/state.md +16 -0
  122. package/dist/templates/seed/memory/engineering/issue-solver/state.md +12 -0
  123. package/dist/templates/seed/memory/intelligence/intel-lead/state.md +9 -0
  124. package/dist/templates/seed/memory/marketing/content-drafter/state.md +12 -0
  125. package/dist/templates/seed/memory/operations/ops-lead/state.md +12 -0
  126. package/dist/templates/seed/memory/product/lead/state.md +14 -0
  127. package/dist/templates/seed/memory/research/lead/state.md +14 -0
  128. package/dist/templates/seed/skills/gh/SKILL.md +57 -0
  129. package/dist/templates/seed/skills/squads-cli/SKILL.md +84 -0
  130. package/dist/templates/seed/squads/company/SQUAD.md +51 -0
  131. package/dist/templates/seed/squads/company/company-critic.md +49 -0
  132. package/dist/templates/seed/squads/company/company-eval.md +49 -0
  133. package/dist/templates/seed/squads/company/event-dispatcher.md +43 -0
  134. package/dist/templates/seed/squads/company/goal-tracker.md +43 -0
  135. package/dist/templates/seed/squads/company/manager.md +54 -0
  136. package/dist/templates/seed/squads/engineering/SQUAD.md +48 -0
  137. package/dist/templates/seed/squads/engineering/code-reviewer.md +57 -0
  138. package/dist/templates/seed/squads/engineering/issue-solver.md +58 -0
  139. package/dist/templates/seed/squads/engineering/test-writer.md +50 -0
  140. package/dist/templates/seed/squads/intelligence/SQUAD.md +38 -0
  141. package/dist/templates/seed/squads/intelligence/intel-critic.md +36 -0
  142. package/dist/templates/seed/squads/intelligence/intel-eval.md +31 -0
  143. package/dist/templates/seed/squads/intelligence/intel-lead.md +71 -0
  144. package/dist/templates/seed/squads/marketing/SQUAD.md +47 -0
  145. package/dist/templates/seed/squads/marketing/content-drafter.md +71 -0
  146. package/dist/templates/seed/squads/marketing/growth-analyst.md +49 -0
  147. package/dist/templates/seed/squads/marketing/social-poster.md +44 -0
  148. package/dist/templates/seed/squads/operations/SQUAD.md +45 -0
  149. package/dist/templates/seed/squads/operations/finance-tracker.md +47 -0
  150. package/dist/templates/seed/squads/operations/goal-tracker.md +48 -0
  151. package/dist/templates/seed/squads/operations/ops-lead.md +58 -0
  152. package/dist/templates/seed/squads/product/SQUAD.md +41 -0
  153. package/dist/templates/seed/squads/product/lead.md +56 -0
  154. package/dist/templates/seed/squads/product/scanner.md +50 -0
  155. package/dist/templates/seed/squads/product/worker.md +55 -0
  156. package/dist/templates/seed/squads/research/SQUAD.md +38 -0
  157. package/dist/templates/seed/squads/research/analyst.md +50 -0
  158. package/dist/templates/seed/squads/research/lead.md +52 -0
  159. package/dist/templates/seed/squads/research/synthesizer.md +59 -0
  160. package/dist/templates/skills/squads-learn/SKILL.md +86 -0
  161. package/dist/templates/skills/squads-workflow/instruction.md +70 -0
  162. package/dist/terminal-FBQFQTKZ.js +55 -0
  163. package/dist/terminal-FBQFQTKZ.js.map +1 -0
  164. package/dist/update-D7CGIZ3M.js +18 -0
  165. package/dist/update-D7CGIZ3M.js.map +1 -0
  166. package/dist/update-STU276HR.js +83 -0
  167. package/dist/update-STU276HR.js.map +1 -0
  168. package/package.json +31 -13
  169. package/templates/core/AGENTS.md.template +51 -0
  170. package/templates/core/BUSINESS_BRIEF.md.template +29 -0
  171. package/templates/core/CLAUDE.md.template +48 -0
  172. package/templates/core/provider.yaml.template +5 -0
  173. package/templates/first-squad/SQUAD.md.template +23 -0
  174. package/templates/first-squad/lead.md.template +44 -0
  175. package/templates/memory/getting-started/state.md.template +19 -0
  176. package/templates/seed/BUSINESS_BRIEF.md.template +27 -0
  177. package/templates/seed/CLAUDE.md.template +119 -0
  178. package/templates/seed/README.md.template +42 -0
  179. package/templates/seed/config/SYSTEM.md +52 -0
  180. package/templates/seed/config/provider.yaml +4 -0
  181. package/templates/seed/hooks/settings.json.template +31 -0
  182. package/templates/seed/memory/company/directives.md +37 -0
  183. package/templates/seed/memory/company/manager/state.md +16 -0
  184. package/templates/seed/memory/engineering/issue-solver/state.md +12 -0
  185. package/templates/seed/memory/intelligence/intel-lead/state.md +9 -0
  186. package/templates/seed/memory/marketing/content-drafter/state.md +12 -0
  187. package/templates/seed/memory/operations/ops-lead/state.md +12 -0
  188. package/templates/seed/memory/product/lead/state.md +14 -0
  189. package/templates/seed/memory/research/lead/state.md +14 -0
  190. package/templates/seed/skills/gh/SKILL.md +57 -0
  191. package/templates/seed/skills/squads-cli/SKILL.md +84 -0
  192. package/templates/seed/squads/company/SQUAD.md +51 -0
  193. package/templates/seed/squads/company/company-critic.md +49 -0
  194. package/templates/seed/squads/company/company-eval.md +49 -0
  195. package/templates/seed/squads/company/event-dispatcher.md +43 -0
  196. package/templates/seed/squads/company/goal-tracker.md +43 -0
  197. package/templates/seed/squads/company/manager.md +54 -0
  198. package/templates/seed/squads/engineering/SQUAD.md +48 -0
  199. package/templates/seed/squads/engineering/code-reviewer.md +57 -0
  200. package/templates/seed/squads/engineering/issue-solver.md +58 -0
  201. package/templates/seed/squads/engineering/test-writer.md +50 -0
  202. package/templates/seed/squads/intelligence/SQUAD.md +38 -0
  203. package/templates/seed/squads/intelligence/intel-critic.md +36 -0
  204. package/templates/seed/squads/intelligence/intel-eval.md +31 -0
  205. package/templates/seed/squads/intelligence/intel-lead.md +71 -0
  206. package/templates/seed/squads/marketing/SQUAD.md +47 -0
  207. package/templates/seed/squads/marketing/content-drafter.md +71 -0
  208. package/templates/seed/squads/marketing/growth-analyst.md +49 -0
  209. package/templates/seed/squads/marketing/social-poster.md +44 -0
  210. package/templates/seed/squads/operations/SQUAD.md +45 -0
  211. package/templates/seed/squads/operations/finance-tracker.md +47 -0
  212. package/templates/seed/squads/operations/goal-tracker.md +48 -0
  213. package/templates/seed/squads/operations/ops-lead.md +58 -0
  214. package/templates/seed/squads/product/SQUAD.md +41 -0
  215. package/templates/seed/squads/product/lead.md +56 -0
  216. package/templates/seed/squads/product/scanner.md +50 -0
  217. package/templates/seed/squads/product/worker.md +55 -0
  218. package/templates/seed/squads/research/SQUAD.md +38 -0
  219. package/templates/seed/squads/research/analyst.md +50 -0
  220. package/templates/seed/squads/research/lead.md +52 -0
  221. package/templates/seed/squads/research/synthesizer.md +59 -0
  222. package/templates/skills/squads-learn/SKILL.md +86 -0
  223. package/templates/skills/squads-workflow/instruction.md +70 -0
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ RESET,
4
+ colors,
5
+ writeLine
6
+ } from "./chunk-M5FXNY6Y.js";
7
+ import {
8
+ __require
9
+ } from "./chunk-7OCVIDC7.js";
10
+
11
+ // src/lib/update.ts
12
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
13
+ import { join, dirname } from "path";
14
+ import { homedir } from "os";
15
+ import { execSync } from "child_process";
16
+ import { fileURLToPath } from "url";
17
+ function getPackageVersion() {
18
+ try {
19
+ const __filename2 = fileURLToPath(import.meta.url);
20
+ const __dirname2 = dirname(__filename2);
21
+ const possiblePaths = [
22
+ join(__dirname2, "..", "..", "package.json"),
23
+ // From dist/lib/
24
+ join(__dirname2, "..", "package.json"),
25
+ // From dist/
26
+ join(__dirname2, "package.json")
27
+ // Same dir
28
+ ];
29
+ for (const pkgPath of possiblePaths) {
30
+ if (existsSync(pkgPath)) {
31
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
32
+ return pkg.version || "0.0.0";
33
+ }
34
+ }
35
+ } catch {
36
+ }
37
+ return "0.0.0";
38
+ }
39
+ var CURRENT_VERSION = getPackageVersion();
40
+ var CACHE_DIR = join(homedir(), ".squads");
41
+ var CACHE_FILE = join(CACHE_DIR, "update-check.json");
42
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
43
+ function isNewerVersion(v1, v2) {
44
+ const parts1 = v1.replace(/^v/, "").split(".").map(Number);
45
+ const parts2 = v2.replace(/^v/, "").split(".").map(Number);
46
+ for (let i = 0; i < 3; i++) {
47
+ const p1 = parts1[i] || 0;
48
+ const p2 = parts2[i] || 0;
49
+ if (p2 > p1) return true;
50
+ if (p2 < p1) return false;
51
+ }
52
+ return false;
53
+ }
54
+ function readCache() {
55
+ try {
56
+ if (!existsSync(CACHE_FILE)) return null;
57
+ const data = JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
58
+ return data;
59
+ } catch {
60
+ return null;
61
+ }
62
+ }
63
+ function writeCache(latestVersion) {
64
+ try {
65
+ if (!existsSync(CACHE_DIR)) {
66
+ mkdirSync(CACHE_DIR, { recursive: true });
67
+ }
68
+ const cache = {
69
+ latestVersion,
70
+ checkedAt: Date.now()
71
+ };
72
+ writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
73
+ } catch {
74
+ }
75
+ }
76
+ function fetchLatestVersion() {
77
+ try {
78
+ const result = execSync("npm view squads-cli version 2>/dev/null", {
79
+ encoding: "utf-8",
80
+ timeout: 5e3
81
+ }).trim();
82
+ return result || null;
83
+ } catch {
84
+ return null;
85
+ }
86
+ }
87
+ function checkForUpdate() {
88
+ const result = {
89
+ currentVersion: CURRENT_VERSION,
90
+ latestVersion: CURRENT_VERSION,
91
+ updateAvailable: false
92
+ };
93
+ const cache = readCache();
94
+ const now = Date.now();
95
+ if (cache) {
96
+ result.latestVersion = cache.latestVersion;
97
+ result.updateAvailable = isNewerVersion(CURRENT_VERSION, cache.latestVersion);
98
+ if (now - cache.checkedAt >= CACHE_TTL_MS) {
99
+ triggerBackgroundRefresh();
100
+ }
101
+ return result;
102
+ }
103
+ triggerBackgroundRefresh();
104
+ return result;
105
+ }
106
+ function triggerBackgroundRefresh() {
107
+ try {
108
+ const { spawn } = __require("child_process");
109
+ const child = spawn("npm", ["view", "squads-cli", "version"], {
110
+ detached: true,
111
+ stdio: ["ignore", "pipe", "ignore"],
112
+ shell: true
113
+ });
114
+ let output = "";
115
+ child.stdout?.on("data", (data) => {
116
+ output += data.toString();
117
+ });
118
+ child.on("close", () => {
119
+ const version = output.trim();
120
+ if (version && /^\d+\.\d+\.\d+/.test(version)) {
121
+ writeCache(version);
122
+ }
123
+ });
124
+ child.unref();
125
+ } catch {
126
+ }
127
+ }
128
+ function getCurrentVersion() {
129
+ return CURRENT_VERSION;
130
+ }
131
+ function performUpdate() {
132
+ try {
133
+ execSync("npm update -g squads-cli", {
134
+ encoding: "utf-8",
135
+ stdio: "inherit",
136
+ timeout: 12e4
137
+ // 2 minutes
138
+ });
139
+ try {
140
+ unlinkSync(CACHE_FILE);
141
+ } catch {
142
+ }
143
+ return { success: true };
144
+ } catch (err) {
145
+ return {
146
+ success: false,
147
+ error: err instanceof Error ? err.message : "Unknown error"
148
+ };
149
+ }
150
+ }
151
+ function refreshVersionCache() {
152
+ const latestVersion = fetchLatestVersion();
153
+ if (latestVersion) {
154
+ writeCache(latestVersion);
155
+ return {
156
+ currentVersion: CURRENT_VERSION,
157
+ latestVersion,
158
+ updateAvailable: isNewerVersion(CURRENT_VERSION, latestVersion)
159
+ };
160
+ }
161
+ return checkForUpdate();
162
+ }
163
+ var AUTO_UPDATE_CACHE_FILE = join(CACHE_DIR, "auto-update.json");
164
+ var AUTO_UPDATE_COOLDOWN_MS = 60 * 60 * 1e3;
165
+ function readAutoUpdateCache() {
166
+ try {
167
+ if (!existsSync(AUTO_UPDATE_CACHE_FILE)) return null;
168
+ return JSON.parse(readFileSync(AUTO_UPDATE_CACHE_FILE, "utf-8"));
169
+ } catch {
170
+ return null;
171
+ }
172
+ }
173
+ function writeAutoUpdateCache(cache) {
174
+ try {
175
+ if (!existsSync(CACHE_DIR)) {
176
+ mkdirSync(CACHE_DIR, { recursive: true });
177
+ }
178
+ writeFileSync(AUTO_UPDATE_CACHE_FILE, JSON.stringify(cache, null, 2));
179
+ } catch {
180
+ }
181
+ }
182
+ async function autoUpdateOnStartup(silent = false) {
183
+ if (process.env.CI || process.env.SQUADS_NO_AUTO_UPDATE) return;
184
+ const autoCache = readAutoUpdateCache();
185
+ const now = Date.now();
186
+ if (autoCache && now - autoCache.lastAttempt < AUTO_UPDATE_COOLDOWN_MS) {
187
+ return;
188
+ }
189
+ const info = checkForUpdate();
190
+ if (!info.updateAvailable) return;
191
+ writeAutoUpdateCache({ lastAttempt: now, lastSuccess: autoCache?.lastSuccess });
192
+ try {
193
+ const { spawn } = await import("child_process");
194
+ const child = spawn("npm", ["update", "-g", "squads-cli"], {
195
+ detached: true,
196
+ stdio: silent ? "ignore" : ["ignore", "pipe", "pipe"],
197
+ shell: true
198
+ });
199
+ if (!silent && child.stdout) {
200
+ await new Promise((resolve) => {
201
+ child.on("close", (code) => {
202
+ if (code === 0) {
203
+ writeLine(`
204
+ ${colors.green}\u2713${RESET} Update successful! v${info.latestVersion} will be used on your next run.
205
+ `);
206
+ writeAutoUpdateCache({ lastAttempt: now, lastSuccess: now });
207
+ try {
208
+ unlinkSync(CACHE_FILE);
209
+ } catch {
210
+ }
211
+ }
212
+ resolve();
213
+ });
214
+ setTimeout(() => resolve(), 3e4);
215
+ });
216
+ } else {
217
+ child.unref();
218
+ }
219
+ } catch {
220
+ }
221
+ }
222
+
223
+ export {
224
+ checkForUpdate,
225
+ getCurrentVersion,
226
+ performUpdate,
227
+ refreshVersionCache,
228
+ autoUpdateOnStartup
229
+ };
230
+ //# sourceMappingURL=chunk-J6QF4ZQX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/update.ts"],"sourcesContent":["/**\n * Update checker for squads-cli\n * Checks npm registry for newer versions and caches result\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { execSync } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport { colors as termColors, RESET as termReset, writeLine } from './terminal.js';\n\n// Get current version from package.json\nfunction getPackageVersion(): string {\n try {\n // Try to find package.json relative to this module\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // Look up from dist/lib to find package.json\n const possiblePaths = [\n join(__dirname, '..', '..', 'package.json'), // From dist/lib/\n join(__dirname, '..', 'package.json'), // From dist/\n join(__dirname, 'package.json'), // Same dir\n ];\n\n for (const pkgPath of possiblePaths) {\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version || '0.0.0';\n }\n }\n } catch {\n // Ignore errors\n }\n return '0.0.0';\n}\n\nconst CURRENT_VERSION = getPackageVersion();\n\n// Cache settings\nconst CACHE_DIR = join(homedir(), '.squads');\nconst CACHE_FILE = join(CACHE_DIR, 'update-check.json');\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface UpdateCache {\n latestVersion: string;\n checkedAt: number;\n}\n\nexport interface UpdateInfo {\n currentVersion: string;\n latestVersion: string;\n updateAvailable: boolean;\n}\n\n/**\n * Compare semantic versions\n * Returns true if v2 > v1\n */\nfunction isNewerVersion(v1: string, v2: string): boolean {\n const parts1 = v1.replace(/^v/, '').split('.').map(Number);\n const parts2 = v2.replace(/^v/, '').split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n if (p2 > p1) return true;\n if (p2 < p1) return false;\n }\n return false;\n}\n\n/**\n * Read cached update info\n */\nfunction readCache(): UpdateCache | null {\n try {\n if (!existsSync(CACHE_FILE)) return null;\n const data = JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));\n return data as UpdateCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Write update info to cache\n */\nfunction writeCache(latestVersion: string): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n const cache: UpdateCache = {\n latestVersion,\n checkedAt: Date.now(),\n };\n writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));\n } catch {\n // Ignore cache write errors\n }\n}\n\n/**\n * Fetch latest version from npm registry\n */\nfunction fetchLatestVersion(): string | null {\n try {\n const result = execSync('npm view squads-cli version 2>/dev/null', {\n encoding: 'utf-8',\n timeout: 5000,\n }).trim();\n return result || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check for updates (uses cache to avoid frequent npm calls)\n * Non-blocking: returns cached data immediately, triggers background refresh if stale\n */\nexport function checkForUpdate(): UpdateInfo {\n const result: UpdateInfo = {\n currentVersion: CURRENT_VERSION,\n latestVersion: CURRENT_VERSION,\n updateAvailable: false,\n };\n\n // Check cache first\n const cache = readCache();\n const now = Date.now();\n\n if (cache) {\n // Always use cached value immediately for fast response\n result.latestVersion = cache.latestVersion;\n result.updateAvailable = isNewerVersion(CURRENT_VERSION, cache.latestVersion);\n\n // If cache is stale, trigger background refresh (non-blocking)\n if ((now - cache.checkedAt) >= CACHE_TTL_MS) {\n // Fire and forget - don't await\n triggerBackgroundRefresh();\n }\n return result;\n }\n\n // No cache at all - trigger background refresh and return defaults\n triggerBackgroundRefresh();\n return result;\n}\n\n/**\n * Trigger a background version check that doesn't block the CLI\n * Uses spawn to run npm in a detached process\n */\nfunction triggerBackgroundRefresh(): void {\n try {\n // Use spawn with detached: true to run in background\n // This won't block the main process\n const { spawn } = require('child_process') as typeof import('child_process');\n const child = spawn('npm', ['view', 'squads-cli', 'version'], {\n detached: true,\n stdio: ['ignore', 'pipe', 'ignore'],\n shell: true,\n });\n\n // Collect output\n let output = '';\n child.stdout?.on('data', (data: Buffer) => {\n output += data.toString();\n });\n\n child.on('close', () => {\n const version = output.trim();\n if (version && /^\\d+\\.\\d+\\.\\d+/.test(version)) {\n writeCache(version);\n }\n });\n\n // Unref to allow main process to exit\n child.unref();\n } catch {\n // Ignore errors - background refresh is best effort\n }\n}\n\n/**\n * Get current version\n */\nexport function getCurrentVersion(): string {\n return CURRENT_VERSION;\n}\n\n/**\n * Perform the actual update via npm\n * Returns true if successful\n */\nexport function performUpdate(): { success: boolean; error?: string } {\n try {\n execSync('npm update -g squads-cli', {\n encoding: 'utf-8',\n stdio: 'inherit',\n timeout: 120000, // 2 minutes\n });\n // Clear cache so next check fetches fresh\n try {\n unlinkSync(CACHE_FILE);\n } catch {\n // Ignore\n }\n return { success: true };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n };\n }\n}\n\n/**\n * Force refresh the version cache (bypass TTL)\n */\nexport function refreshVersionCache(): UpdateInfo {\n const latestVersion = fetchLatestVersion();\n if (latestVersion) {\n writeCache(latestVersion);\n return {\n currentVersion: CURRENT_VERSION,\n latestVersion,\n updateAvailable: isNewerVersion(CURRENT_VERSION, latestVersion),\n };\n }\n return checkForUpdate();\n}\n\n// Auto-update settings\nconst AUTO_UPDATE_CACHE_FILE = join(CACHE_DIR, 'auto-update.json');\nconst AUTO_UPDATE_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour cooldown between auto-update attempts\n\ninterface AutoUpdateCache {\n lastAttempt: number;\n lastSuccess?: number;\n}\n\nfunction readAutoUpdateCache(): AutoUpdateCache | null {\n try {\n if (!existsSync(AUTO_UPDATE_CACHE_FILE)) return null;\n return JSON.parse(readFileSync(AUTO_UPDATE_CACHE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeAutoUpdateCache(cache: AutoUpdateCache): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n writeFileSync(AUTO_UPDATE_CACHE_FILE, JSON.stringify(cache, null, 2));\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Seamless auto-update on CLI startup (like Gemini CLI)\n * Checks for updates and auto-installs without prompting.\n * Shows a message on success: \"Update successful! The new version will be used on your next run.\"\n *\n * @param silent - If true, don't show any output (for background checks)\n * @returns Promise that resolves when check/update is complete\n */\nexport async function autoUpdateOnStartup(silent = false): Promise<void> {\n // Skip in CI or if auto-update disabled\n if (process.env.CI || process.env.SQUADS_NO_AUTO_UPDATE) return;\n\n // Check cooldown - don't spam npm\n const autoCache = readAutoUpdateCache();\n const now = Date.now();\n if (autoCache && (now - autoCache.lastAttempt) < AUTO_UPDATE_COOLDOWN_MS) {\n return; // Too soon since last attempt\n }\n\n // Check if update is available\n const info = checkForUpdate();\n if (!info.updateAvailable) return;\n\n // Write attempt timestamp before trying\n writeAutoUpdateCache({ lastAttempt: now, lastSuccess: autoCache?.lastSuccess });\n\n // Perform update silently in background using spawn\n try {\n const { spawn } = await import('child_process');\n\n // Run npm update in background\n const child = spawn('npm', ['update', '-g', 'squads-cli'], {\n detached: true,\n stdio: silent ? 'ignore' : ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n if (!silent && child.stdout) {\n // Wait for completion and check result\n await new Promise<void>((resolve) => {\n child.on('close', (code) => {\n if (code === 0) {\n // Success - show Gemini-style message\n writeLine(`\\n ${termColors.green}✓${termReset} Update successful! v${info.latestVersion} will be used on your next run.\\n`);\n writeAutoUpdateCache({ lastAttempt: now, lastSuccess: now });\n // Clear version cache so next startup detects new version\n try { unlinkSync(CACHE_FILE); } catch { /* ignore */ }\n }\n resolve();\n });\n\n // Timeout after 30 seconds\n setTimeout(() => resolve(), 30000);\n });\n } else {\n // Silent mode - just fire and forget\n child.unref();\n }\n } catch {\n // Ignore errors - auto-update is best effort\n }\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
@@ -0,0 +1,294 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/providers.ts
4
+ var PROVIDERS = {
5
+ anthropic: {
6
+ name: "anthropic",
7
+ displayName: "Anthropic",
8
+ envVars: ["ANTHROPIC_API_KEY"],
9
+ modelPatterns: [/^claude/i],
10
+ defaultPricing: { input: 3, output: 15 },
11
+ models: {
12
+ "claude-opus-4-5": { input: 15, output: 75 },
13
+ "claude-opus-4-5-20251101": { input: 15, output: 75 },
14
+ "claude-sonnet-4": { input: 3, output: 15 },
15
+ "claude-sonnet-4-20250514": { input: 3, output: 15 },
16
+ "claude-3-5-sonnet": { input: 3, output: 15 },
17
+ "claude-3-5-sonnet-20241022": { input: 3, output: 15 },
18
+ "claude-3-5-sonnet-20240620": { input: 3, output: 15 },
19
+ "claude-haiku-3-5": { input: 0.8, output: 4 },
20
+ "claude-3-5-haiku": { input: 0.8, output: 4 },
21
+ "claude-3-5-haiku-20241022": { input: 0.8, output: 4 },
22
+ "claude-3-opus": { input: 15, output: 75 },
23
+ "claude-3-sonnet": { input: 3, output: 15 },
24
+ "claude-3-haiku": { input: 0.25, output: 1.25 }
25
+ }
26
+ },
27
+ openai: {
28
+ name: "openai",
29
+ displayName: "OpenAI",
30
+ envVars: ["OPENAI_API_KEY"],
31
+ modelPatterns: [/^gpt-/i, /^o1/i, /^o3/i],
32
+ defaultPricing: { input: 2.5, output: 10 },
33
+ models: {
34
+ "gpt-4o": { input: 2.5, output: 10 },
35
+ "gpt-4o-2024-11-20": { input: 2.5, output: 10 },
36
+ "gpt-4o-2024-08-06": { input: 2.5, output: 10 },
37
+ "gpt-4o-mini": { input: 0.15, output: 0.6 },
38
+ "gpt-4o-mini-2024-07-18": { input: 0.15, output: 0.6 },
39
+ "gpt-4-turbo": { input: 10, output: 30 },
40
+ "gpt-4-turbo-2024-04-09": { input: 10, output: 30 },
41
+ "gpt-4": { input: 30, output: 60 },
42
+ "gpt-4-32k": { input: 60, output: 120 },
43
+ "gpt-3.5-turbo": { input: 0.5, output: 1.5 },
44
+ "gpt-3.5-turbo-0125": { input: 0.5, output: 1.5 },
45
+ o1: { input: 15, output: 60 },
46
+ "o1-2024-12-17": { input: 15, output: 60 },
47
+ "o1-preview": { input: 15, output: 60 },
48
+ "o1-mini": { input: 3, output: 12 },
49
+ "o1-mini-2024-09-12": { input: 3, output: 12 },
50
+ "o3-mini": { input: 1.1, output: 4.4 }
51
+ }
52
+ },
53
+ google: {
54
+ name: "google",
55
+ displayName: "Google",
56
+ envVars: ["GEMINI_API_KEY", "GOOGLE_API_KEY"],
57
+ modelPatterns: [/^gemini/i],
58
+ defaultPricing: { input: 0.1, output: 0.4 },
59
+ models: {
60
+ "gemini-2.0-flash": { input: 0.1, output: 0.4 },
61
+ "gemini-2.0-flash-exp": { input: 0.1, output: 0.4 },
62
+ "gemini-1.5-pro": { input: 1.25, output: 5 },
63
+ "gemini-1.5-pro-002": { input: 1.25, output: 5 },
64
+ "gemini-1.5-flash": { input: 0.075, output: 0.3 },
65
+ "gemini-1.5-flash-002": { input: 0.075, output: 0.3 },
66
+ "gemini-1.0-pro": { input: 0.5, output: 1.5 }
67
+ }
68
+ },
69
+ mistral: {
70
+ name: "mistral",
71
+ displayName: "Mistral",
72
+ envVars: ["MISTRAL_API_KEY"],
73
+ modelPatterns: [/^mistral/i, /^mixtral/i, /^codestral/i],
74
+ defaultPricing: { input: 2, output: 6 },
75
+ models: {
76
+ "mistral-large": { input: 2, output: 6 },
77
+ "mistral-large-2411": { input: 2, output: 6 },
78
+ "mistral-medium": { input: 2.7, output: 8.1 },
79
+ "mistral-small": { input: 0.2, output: 0.6 },
80
+ "mistral-small-2409": { input: 0.2, output: 0.6 },
81
+ "mixtral-8x7b": { input: 0.7, output: 0.7 },
82
+ "mixtral-8x22b": { input: 2, output: 6 },
83
+ codestral: { input: 0.2, output: 0.6 },
84
+ "codestral-2405": { input: 0.2, output: 0.6 }
85
+ }
86
+ },
87
+ groq: {
88
+ name: "groq",
89
+ displayName: "Groq",
90
+ envVars: ["GROQ_API_KEY"],
91
+ modelPatterns: [/^llama/i],
92
+ // llama models on Groq
93
+ defaultPricing: { input: 0.59, output: 0.79 },
94
+ models: {
95
+ "llama-3.3-70b-versatile": { input: 0.59, output: 0.79 },
96
+ "llama-3.3-70b-specdec": { input: 0.59, output: 0.99 },
97
+ "llama-3.1-70b-versatile": { input: 0.59, output: 0.79 },
98
+ "llama-3.1-8b-instant": { input: 0.05, output: 0.08 },
99
+ "llama-3-70b-8192": { input: 0.59, output: 0.79 },
100
+ "llama-3-8b-8192": { input: 0.05, output: 0.08 },
101
+ "mixtral-8x7b-32768": { input: 0.24, output: 0.24 },
102
+ "gemma2-9b-it": { input: 0.2, output: 0.2 }
103
+ }
104
+ },
105
+ aws_bedrock: {
106
+ name: "aws_bedrock",
107
+ displayName: "AWS Bedrock",
108
+ envVars: ["AWS_ACCESS_KEY_ID"],
109
+ modelPatterns: [/^anthropic\./i, /^amazon\./i, /^meta\./i, /^mistral\./i],
110
+ defaultPricing: { input: 3, output: 15 },
111
+ models: {
112
+ "anthropic.claude-3-5-sonnet-20241022-v2:0": { input: 3, output: 15 },
113
+ "anthropic.claude-3-5-sonnet-20240620-v1:0": { input: 3, output: 15 },
114
+ "anthropic.claude-3-5-haiku-20241022-v1:0": { input: 0.8, output: 4 },
115
+ "anthropic.claude-3-opus-20240229-v1:0": { input: 15, output: 75 },
116
+ "anthropic.claude-3-sonnet-20240229-v1:0": { input: 3, output: 15 },
117
+ "anthropic.claude-3-haiku-20240307-v1:0": { input: 0.25, output: 1.25 },
118
+ "amazon.titan-text-premier-v1:0": { input: 0.5, output: 1.5 },
119
+ "amazon.titan-text-express-v1": { input: 0.2, output: 0.6 },
120
+ "amazon.titan-text-lite-v1": { input: 0.15, output: 0.2 },
121
+ "meta.llama3-70b-instruct-v1:0": { input: 2.65, output: 3.5 },
122
+ "meta.llama3-8b-instruct-v1:0": { input: 0.3, output: 0.6 },
123
+ "meta.llama3-1-405b-instruct-v1:0": { input: 5.32, output: 16 },
124
+ "mistral.mistral-large-2407-v1:0": { input: 4, output: 12 }
125
+ }
126
+ },
127
+ azure: {
128
+ name: "azure",
129
+ displayName: "Azure OpenAI",
130
+ envVars: ["AZURE_OPENAI_API_KEY"],
131
+ modelPatterns: [],
132
+ // Detected via endpoint, not model name
133
+ defaultPricing: { input: 2.5, output: 10 },
134
+ models: {
135
+ // Same pricing as OpenAI (regional variations possible)
136
+ "gpt-4o": { input: 2.5, output: 10 },
137
+ "gpt-4o-mini": { input: 0.15, output: 0.6 },
138
+ "gpt-4-turbo": { input: 10, output: 30 },
139
+ "gpt-4": { input: 30, output: 60 },
140
+ "gpt-35-turbo": { input: 0.5, output: 1.5 }
141
+ // Azure uses different name
142
+ }
143
+ }
144
+ };
145
+ function detectProviderFromModel(model) {
146
+ const modelLower = model.toLowerCase();
147
+ if (modelLower.includes("anthropic.") || modelLower.includes("amazon.") || modelLower.includes("meta.") || modelLower.includes("mistral.")) {
148
+ return "aws_bedrock";
149
+ }
150
+ if (modelLower.startsWith("claude")) {
151
+ return "anthropic";
152
+ }
153
+ if (modelLower.startsWith("gpt-") || modelLower.startsWith("o1") || modelLower.startsWith("o3")) {
154
+ if (process.env.AZURE_OPENAI_ENDPOINT || process.env.AZURE_OPENAI_API_KEY) {
155
+ return "azure";
156
+ }
157
+ return "openai";
158
+ }
159
+ if (modelLower.startsWith("gemini")) {
160
+ return "google";
161
+ }
162
+ if (modelLower.startsWith("mistral") || modelLower.startsWith("mixtral") || modelLower.startsWith("codestral")) {
163
+ if (process.env.GROQ_API_KEY && !process.env.MISTRAL_API_KEY) {
164
+ return "groq";
165
+ }
166
+ return "mistral";
167
+ }
168
+ if (modelLower.startsWith("llama") || modelLower.startsWith("gemma")) {
169
+ return "groq";
170
+ }
171
+ return "unknown";
172
+ }
173
+ function detectProvidersFromEnv() {
174
+ const detected = [];
175
+ if (process.env.ANTHROPIC_API_KEY) {
176
+ const tier = parseInt(process.env.ANTHROPIC_TIER || "0", 10);
177
+ const budgetSet = process.env.ANTHROPIC_BUDGET_DAILY || process.env.SQUADS_DAILY_BUDGET;
178
+ const explicitPlan = process.env.SQUADS_PLAN_TYPE?.toLowerCase();
179
+ let plan = "Max";
180
+ let confidence = "inferred";
181
+ let reason = "API key detected";
182
+ if (explicitPlan === "usage") {
183
+ plan = "Usage";
184
+ confidence = "explicit";
185
+ reason = "SQUADS_PLAN_TYPE=usage";
186
+ } else if (explicitPlan === "max") {
187
+ plan = "Max";
188
+ confidence = "explicit";
189
+ reason = "SQUADS_PLAN_TYPE=max";
190
+ } else if (budgetSet) {
191
+ plan = "Usage";
192
+ reason = `Budget set ($${budgetSet}/day)`;
193
+ } else if (tier >= 4) {
194
+ plan = "Max";
195
+ reason = `Tier ${tier} (high usage)`;
196
+ } else if (tier >= 1 && tier <= 2) {
197
+ plan = "Usage";
198
+ reason = `Tier ${tier} (new user)`;
199
+ }
200
+ detected.push({ provider: "anthropic", plan, confidence, reason });
201
+ }
202
+ if (process.env.OPENAI_API_KEY) {
203
+ const orgId = process.env.OPENAI_ORG_ID;
204
+ detected.push({
205
+ provider: "openai",
206
+ plan: orgId ? "Team/Enterprise" : "Personal",
207
+ confidence: "inferred",
208
+ reason: orgId ? "Org ID set" : "API key only"
209
+ });
210
+ }
211
+ if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {
212
+ detected.push({
213
+ provider: "google",
214
+ plan: "Pay-as-you-go",
215
+ confidence: "inferred",
216
+ reason: "API key detected"
217
+ });
218
+ }
219
+ if (process.env.AWS_ACCESS_KEY_ID) {
220
+ detected.push({
221
+ provider: "aws_bedrock",
222
+ plan: "On-demand",
223
+ confidence: "inferred",
224
+ reason: "AWS credentials detected"
225
+ });
226
+ }
227
+ if (process.env.AZURE_OPENAI_API_KEY) {
228
+ detected.push({
229
+ provider: "azure",
230
+ plan: process.env.AZURE_OPENAI_DEPLOYMENT ? "PTU" : "Pay-as-you-go",
231
+ confidence: "inferred",
232
+ reason: process.env.AZURE_OPENAI_DEPLOYMENT ? "Deployment detected" : "API key only"
233
+ });
234
+ }
235
+ if (process.env.MISTRAL_API_KEY) {
236
+ detected.push({
237
+ provider: "mistral",
238
+ plan: "Pay-per-token",
239
+ confidence: "inferred",
240
+ reason: "API key detected"
241
+ });
242
+ }
243
+ if (process.env.GROQ_API_KEY) {
244
+ detected.push({
245
+ provider: "groq",
246
+ plan: "Developer",
247
+ confidence: "inferred",
248
+ reason: "API key detected"
249
+ });
250
+ }
251
+ return detected;
252
+ }
253
+ function getModelPricing(provider, model) {
254
+ if (provider === "unknown") {
255
+ return { input: 3, output: 15 };
256
+ }
257
+ const config = PROVIDERS[provider];
258
+ const modelLower = model.toLowerCase();
259
+ if (config.models[model]) {
260
+ return config.models[model];
261
+ }
262
+ const matchedModel = Object.keys(config.models).find(
263
+ (m) => m.toLowerCase() === modelLower
264
+ );
265
+ if (matchedModel) {
266
+ return config.models[matchedModel];
267
+ }
268
+ const partialMatch = Object.keys(config.models).find(
269
+ (m) => modelLower.includes(m.toLowerCase()) || m.toLowerCase().includes(modelLower)
270
+ );
271
+ if (partialMatch) {
272
+ return config.models[partialMatch];
273
+ }
274
+ return config.defaultPricing;
275
+ }
276
+ function calcCost(provider, model, inputTokens, outputTokens, cachedTokens = 0) {
277
+ const pricing = getModelPricing(provider, model);
278
+ const inputCost = inputTokens / 1e6 * pricing.input;
279
+ const outputCost = outputTokens / 1e6 * pricing.output;
280
+ const cachedCost = pricing.cached ? cachedTokens / 1e6 * pricing.cached : 0;
281
+ return inputCost + outputCost + cachedCost;
282
+ }
283
+ function getProviderDisplayName(provider) {
284
+ if (provider === "unknown") return "Unknown";
285
+ return PROVIDERS[provider].displayName;
286
+ }
287
+
288
+ export {
289
+ detectProviderFromModel,
290
+ detectProvidersFromEnv,
291
+ calcCost,
292
+ getProviderDisplayName
293
+ };
294
+ //# sourceMappingURL=chunk-LOA3KWYJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/providers.ts"],"sourcesContent":["/**\n * Multi-provider LLM detection and cost tracking\n *\n * Supports: Anthropic, OpenAI, Google, AWS Bedrock, Azure, Mistral, Groq\n */\n\n// Provider types\nexport type ProviderName =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'aws_bedrock'\n | 'azure'\n | 'mistral'\n | 'groq'\n | 'unknown';\n\nexport interface ProviderDetection {\n provider: ProviderName;\n plan?: string;\n confidence: 'explicit' | 'inferred';\n reason: string;\n}\n\nexport interface ModelPricing {\n input: number; // per 1M tokens\n output: number; // per 1M tokens\n cached?: number; // per 1M cached tokens (if supported)\n}\n\nexport interface ProviderConfig {\n name: ProviderName;\n displayName: string;\n models: Record<string, ModelPricing>;\n defaultPricing: ModelPricing;\n envVars: string[]; // API key env vars to check\n modelPatterns: RegExp[]; // Model name patterns\n}\n\n// Pricing data per 1M tokens (Jan 2025)\nexport const PROVIDERS: Record<Exclude<ProviderName, 'unknown'>, ProviderConfig> = {\n anthropic: {\n name: 'anthropic',\n displayName: 'Anthropic',\n envVars: ['ANTHROPIC_API_KEY'],\n modelPatterns: [/^claude/i],\n defaultPricing: { input: 3.0, output: 15.0 },\n models: {\n 'claude-opus-4-5': { input: 15.0, output: 75.0 },\n 'claude-opus-4-5-20251101': { input: 15.0, output: 75.0 },\n 'claude-sonnet-4': { input: 3.0, output: 15.0 },\n 'claude-sonnet-4-20250514': { input: 3.0, output: 15.0 },\n 'claude-3-5-sonnet': { input: 3.0, output: 15.0 },\n 'claude-3-5-sonnet-20241022': { input: 3.0, output: 15.0 },\n 'claude-3-5-sonnet-20240620': { input: 3.0, output: 15.0 },\n 'claude-haiku-3-5': { input: 0.8, output: 4.0 },\n 'claude-3-5-haiku': { input: 0.8, output: 4.0 },\n 'claude-3-5-haiku-20241022': { input: 0.8, output: 4.0 },\n 'claude-3-opus': { input: 15.0, output: 75.0 },\n 'claude-3-sonnet': { input: 3.0, output: 15.0 },\n 'claude-3-haiku': { input: 0.25, output: 1.25 },\n },\n },\n\n openai: {\n name: 'openai',\n displayName: 'OpenAI',\n envVars: ['OPENAI_API_KEY'],\n modelPatterns: [/^gpt-/i, /^o1/i, /^o3/i],\n defaultPricing: { input: 2.5, output: 10.0 },\n models: {\n 'gpt-4o': { input: 2.5, output: 10.0 },\n 'gpt-4o-2024-11-20': { input: 2.5, output: 10.0 },\n 'gpt-4o-2024-08-06': { input: 2.5, output: 10.0 },\n 'gpt-4o-mini': { input: 0.15, output: 0.6 },\n 'gpt-4o-mini-2024-07-18': { input: 0.15, output: 0.6 },\n 'gpt-4-turbo': { input: 10.0, output: 30.0 },\n 'gpt-4-turbo-2024-04-09': { input: 10.0, output: 30.0 },\n 'gpt-4': { input: 30.0, output: 60.0 },\n 'gpt-4-32k': { input: 60.0, output: 120.0 },\n 'gpt-3.5-turbo': { input: 0.5, output: 1.5 },\n 'gpt-3.5-turbo-0125': { input: 0.5, output: 1.5 },\n o1: { input: 15.0, output: 60.0 },\n 'o1-2024-12-17': { input: 15.0, output: 60.0 },\n 'o1-preview': { input: 15.0, output: 60.0 },\n 'o1-mini': { input: 3.0, output: 12.0 },\n 'o1-mini-2024-09-12': { input: 3.0, output: 12.0 },\n 'o3-mini': { input: 1.1, output: 4.4 },\n },\n },\n\n google: {\n name: 'google',\n displayName: 'Google',\n envVars: ['GEMINI_API_KEY', 'GOOGLE_API_KEY'],\n modelPatterns: [/^gemini/i],\n defaultPricing: { input: 0.1, output: 0.4 },\n models: {\n 'gemini-2.0-flash': { input: 0.1, output: 0.4 },\n 'gemini-2.0-flash-exp': { input: 0.1, output: 0.4 },\n 'gemini-1.5-pro': { input: 1.25, output: 5.0 },\n 'gemini-1.5-pro-002': { input: 1.25, output: 5.0 },\n 'gemini-1.5-flash': { input: 0.075, output: 0.3 },\n 'gemini-1.5-flash-002': { input: 0.075, output: 0.3 },\n 'gemini-1.0-pro': { input: 0.5, output: 1.5 },\n },\n },\n\n mistral: {\n name: 'mistral',\n displayName: 'Mistral',\n envVars: ['MISTRAL_API_KEY'],\n modelPatterns: [/^mistral/i, /^mixtral/i, /^codestral/i],\n defaultPricing: { input: 2.0, output: 6.0 },\n models: {\n 'mistral-large': { input: 2.0, output: 6.0 },\n 'mistral-large-2411': { input: 2.0, output: 6.0 },\n 'mistral-medium': { input: 2.7, output: 8.1 },\n 'mistral-small': { input: 0.2, output: 0.6 },\n 'mistral-small-2409': { input: 0.2, output: 0.6 },\n 'mixtral-8x7b': { input: 0.7, output: 0.7 },\n 'mixtral-8x22b': { input: 2.0, output: 6.0 },\n codestral: { input: 0.2, output: 0.6 },\n 'codestral-2405': { input: 0.2, output: 0.6 },\n },\n },\n\n groq: {\n name: 'groq',\n displayName: 'Groq',\n envVars: ['GROQ_API_KEY'],\n modelPatterns: [/^llama/i], // llama models on Groq\n defaultPricing: { input: 0.59, output: 0.79 },\n models: {\n 'llama-3.3-70b-versatile': { input: 0.59, output: 0.79 },\n 'llama-3.3-70b-specdec': { input: 0.59, output: 0.99 },\n 'llama-3.1-70b-versatile': { input: 0.59, output: 0.79 },\n 'llama-3.1-8b-instant': { input: 0.05, output: 0.08 },\n 'llama-3-70b-8192': { input: 0.59, output: 0.79 },\n 'llama-3-8b-8192': { input: 0.05, output: 0.08 },\n 'mixtral-8x7b-32768': { input: 0.24, output: 0.24 },\n 'gemma2-9b-it': { input: 0.2, output: 0.2 },\n },\n },\n\n aws_bedrock: {\n name: 'aws_bedrock',\n displayName: 'AWS Bedrock',\n envVars: ['AWS_ACCESS_KEY_ID'],\n modelPatterns: [/^anthropic\\./i, /^amazon\\./i, /^meta\\./i, /^mistral\\./i],\n defaultPricing: { input: 3.0, output: 15.0 },\n models: {\n 'anthropic.claude-3-5-sonnet-20241022-v2:0': { input: 3.0, output: 15.0 },\n 'anthropic.claude-3-5-sonnet-20240620-v1:0': { input: 3.0, output: 15.0 },\n 'anthropic.claude-3-5-haiku-20241022-v1:0': { input: 0.8, output: 4.0 },\n 'anthropic.claude-3-opus-20240229-v1:0': { input: 15.0, output: 75.0 },\n 'anthropic.claude-3-sonnet-20240229-v1:0': { input: 3.0, output: 15.0 },\n 'anthropic.claude-3-haiku-20240307-v1:0': { input: 0.25, output: 1.25 },\n 'amazon.titan-text-premier-v1:0': { input: 0.5, output: 1.5 },\n 'amazon.titan-text-express-v1': { input: 0.2, output: 0.6 },\n 'amazon.titan-text-lite-v1': { input: 0.15, output: 0.2 },\n 'meta.llama3-70b-instruct-v1:0': { input: 2.65, output: 3.5 },\n 'meta.llama3-8b-instruct-v1:0': { input: 0.3, output: 0.6 },\n 'meta.llama3-1-405b-instruct-v1:0': { input: 5.32, output: 16.0 },\n 'mistral.mistral-large-2407-v1:0': { input: 4.0, output: 12.0 },\n },\n },\n\n azure: {\n name: 'azure',\n displayName: 'Azure OpenAI',\n envVars: ['AZURE_OPENAI_API_KEY'],\n modelPatterns: [], // Detected via endpoint, not model name\n defaultPricing: { input: 2.5, output: 10.0 },\n models: {\n // Same pricing as OpenAI (regional variations possible)\n 'gpt-4o': { input: 2.5, output: 10.0 },\n 'gpt-4o-mini': { input: 0.15, output: 0.6 },\n 'gpt-4-turbo': { input: 10.0, output: 30.0 },\n 'gpt-4': { input: 30.0, output: 60.0 },\n 'gpt-35-turbo': { input: 0.5, output: 1.5 }, // Azure uses different name\n },\n },\n};\n\n/**\n * Detect the LLM provider from a model name string.\n * Supports Anthropic, OpenAI, Google, Mistral, Groq, AWS Bedrock, and Azure.\n * @param model - Model identifier (e.g., 'claude-3-5-sonnet', 'gpt-4o')\n * @returns Provider name or 'unknown' if unrecognized\n */\nexport function detectProviderFromModel(model: string): ProviderName {\n const modelLower = model.toLowerCase();\n\n // AWS Bedrock - check first (model IDs include provider prefix)\n if (\n modelLower.includes('anthropic.') ||\n modelLower.includes('amazon.') ||\n modelLower.includes('meta.') ||\n modelLower.includes('mistral.')\n ) {\n return 'aws_bedrock';\n }\n\n // Anthropic\n if (modelLower.startsWith('claude')) {\n return 'anthropic';\n }\n\n // OpenAI\n if (\n modelLower.startsWith('gpt-') ||\n modelLower.startsWith('o1') ||\n modelLower.startsWith('o3')\n ) {\n // Check for Azure (endpoint-based detection takes priority)\n if (process.env.AZURE_OPENAI_ENDPOINT || process.env.AZURE_OPENAI_API_KEY) {\n return 'azure';\n }\n return 'openai';\n }\n\n // Google\n if (modelLower.startsWith('gemini')) {\n return 'google';\n }\n\n // Mistral vs Groq (both can run mistral/mixtral models)\n if (modelLower.startsWith('mistral') || modelLower.startsWith('mixtral') || modelLower.startsWith('codestral')) {\n // If Groq API key is set and not Mistral key, assume Groq\n if (process.env.GROQ_API_KEY && !process.env.MISTRAL_API_KEY) {\n return 'groq';\n }\n return 'mistral';\n }\n\n // Groq (llama models, gemma)\n if (modelLower.startsWith('llama') || modelLower.startsWith('gemma')) {\n return 'groq';\n }\n\n return 'unknown';\n}\n\n/**\n * Detect all LLM providers configured via environment variables.\n * Checks for API keys and infers plan type based on tier/budget settings.\n * @returns Array of detected providers with their configuration details\n */\nexport function detectProvidersFromEnv(): ProviderDetection[] {\n const detected: ProviderDetection[] = [];\n\n // Anthropic\n if (process.env.ANTHROPIC_API_KEY) {\n const tier = parseInt(process.env.ANTHROPIC_TIER || '0', 10);\n const budgetSet = process.env.ANTHROPIC_BUDGET_DAILY || process.env.SQUADS_DAILY_BUDGET;\n const explicitPlan = process.env.SQUADS_PLAN_TYPE?.toLowerCase();\n\n let plan = 'Max';\n let confidence: 'explicit' | 'inferred' = 'inferred';\n let reason = 'API key detected';\n\n if (explicitPlan === 'usage') {\n plan = 'Usage';\n confidence = 'explicit';\n reason = 'SQUADS_PLAN_TYPE=usage';\n } else if (explicitPlan === 'max') {\n plan = 'Max';\n confidence = 'explicit';\n reason = 'SQUADS_PLAN_TYPE=max';\n } else if (budgetSet) {\n plan = 'Usage';\n reason = `Budget set ($${budgetSet}/day)`;\n } else if (tier >= 4) {\n plan = 'Max';\n reason = `Tier ${tier} (high usage)`;\n } else if (tier >= 1 && tier <= 2) {\n plan = 'Usage';\n reason = `Tier ${tier} (new user)`;\n }\n\n detected.push({ provider: 'anthropic', plan, confidence, reason });\n }\n\n // OpenAI\n if (process.env.OPENAI_API_KEY) {\n const orgId = process.env.OPENAI_ORG_ID;\n detected.push({\n provider: 'openai',\n plan: orgId ? 'Team/Enterprise' : 'Personal',\n confidence: 'inferred',\n reason: orgId ? 'Org ID set' : 'API key only',\n });\n }\n\n // Google\n if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {\n detected.push({\n provider: 'google',\n plan: 'Pay-as-you-go',\n confidence: 'inferred',\n reason: 'API key detected',\n });\n }\n\n // AWS Bedrock\n if (process.env.AWS_ACCESS_KEY_ID) {\n detected.push({\n provider: 'aws_bedrock',\n plan: 'On-demand',\n confidence: 'inferred',\n reason: 'AWS credentials detected',\n });\n }\n\n // Azure OpenAI\n if (process.env.AZURE_OPENAI_API_KEY) {\n detected.push({\n provider: 'azure',\n plan: process.env.AZURE_OPENAI_DEPLOYMENT ? 'PTU' : 'Pay-as-you-go',\n confidence: 'inferred',\n reason: process.env.AZURE_OPENAI_DEPLOYMENT ? 'Deployment detected' : 'API key only',\n });\n }\n\n // Mistral\n if (process.env.MISTRAL_API_KEY) {\n detected.push({\n provider: 'mistral',\n plan: 'Pay-per-token',\n confidence: 'inferred',\n reason: 'API key detected',\n });\n }\n\n // Groq\n if (process.env.GROQ_API_KEY) {\n detected.push({\n provider: 'groq',\n plan: 'Developer',\n confidence: 'inferred',\n reason: 'API key detected',\n });\n }\n\n return detected;\n}\n\n/**\n * Get pricing information for a specific model.\n * Attempts exact match first, then case-insensitive, then partial match.\n * @param provider - Provider name\n * @param model - Model identifier\n * @returns Pricing in dollars per 1M tokens (input/output/cached)\n */\nexport function getModelPricing(provider: ProviderName, model: string): ModelPricing {\n if (provider === 'unknown') {\n // Fallback to Anthropic Sonnet pricing for unknown models\n return { input: 3.0, output: 15.0 };\n }\n\n const config = PROVIDERS[provider];\n const modelLower = model.toLowerCase();\n\n // Exact match first\n if (config.models[model]) {\n return config.models[model];\n }\n\n // Case-insensitive match\n const matchedModel = Object.keys(config.models).find(\n (m) => m.toLowerCase() === modelLower\n );\n if (matchedModel) {\n return config.models[matchedModel];\n }\n\n // Partial match (for versioned models)\n const partialMatch = Object.keys(config.models).find(\n (m) => modelLower.includes(m.toLowerCase()) || m.toLowerCase().includes(modelLower)\n );\n if (partialMatch) {\n return config.models[partialMatch];\n }\n\n return config.defaultPricing;\n}\n\n/**\n * Calculate cost for token usage based on provider pricing.\n * @param provider - Provider name\n * @param model - Model identifier\n * @param inputTokens - Number of input tokens\n * @param outputTokens - Number of output tokens\n * @param cachedTokens - Number of cached tokens (for providers that support it)\n * @returns Total cost in dollars\n */\nexport function calcCost(\n provider: ProviderName,\n model: string,\n inputTokens: number,\n outputTokens: number,\n cachedTokens = 0\n): number {\n const pricing = getModelPricing(provider, model);\n\n // Per 1M tokens pricing\n const inputCost = (inputTokens / 1_000_000) * pricing.input;\n const outputCost = (outputTokens / 1_000_000) * pricing.output;\n const cachedCost = pricing.cached\n ? (cachedTokens / 1_000_000) * pricing.cached\n : 0;\n\n return inputCost + outputCost + cachedCost;\n}\n\n/**\n * Get human-readable display name for a provider.\n * @param provider - Provider name\n * @returns Display name (e.g., 'Anthropic', 'OpenAI', 'AWS Bedrock')\n */\nexport function getProviderDisplayName(provider: ProviderName): string {\n if (provider === 'unknown') return 'Unknown';\n return PROVIDERS[provider].displayName;\n}\n\n/**\n * Check if a provider has its API key configured in environment variables.\n * @param provider - Provider name\n * @returns true if any of the provider's API key env vars are set\n */\nexport function isProviderConfigured(provider: ProviderName): boolean {\n if (provider === 'unknown') return false;\n const config = PROVIDERS[provider];\n return config.envVars.some((envVar) => !!process.env[envVar]);\n}\n"],"mappings":";;;AAwCO,IAAM,YAAsE;AAAA,EACjF,WAAW;AAAA,IACT,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,mBAAmB;AAAA,IAC7B,eAAe,CAAC,UAAU;AAAA,IAC1B,gBAAgB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,IAC3C,QAAQ;AAAA,MACN,mBAAmB,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC/C,4BAA4B,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MACxD,mBAAmB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MAC9C,4BAA4B,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACvD,qBAAqB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MAChD,8BAA8B,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACzD,8BAA8B,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACzD,oBAAoB,EAAE,OAAO,KAAK,QAAQ,EAAI;AAAA,MAC9C,oBAAoB,EAAE,OAAO,KAAK,QAAQ,EAAI;AAAA,MAC9C,6BAA6B,EAAE,OAAO,KAAK,QAAQ,EAAI;AAAA,MACvD,iBAAiB,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC7C,mBAAmB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MAC9C,kBAAkB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,gBAAgB;AAAA,IAC1B,eAAe,CAAC,UAAU,QAAQ,MAAM;AAAA,IACxC,gBAAgB,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,IAC3C,QAAQ;AAAA,MACN,UAAU,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,MACrC,qBAAqB,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,MAChD,qBAAqB,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,MAChD,eAAe,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MAC1C,0BAA0B,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MACrD,eAAe,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC3C,0BAA0B,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MACtD,SAAS,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MACrC,aAAa,EAAE,OAAO,IAAM,QAAQ,IAAM;AAAA,MAC1C,iBAAiB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC3C,sBAAsB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAChD,IAAI,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAChC,iBAAiB,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC7C,cAAc,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC1C,WAAW,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACtC,sBAAsB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACjD,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,kBAAkB,gBAAgB;AAAA,IAC5C,eAAe,CAAC,UAAU;AAAA,IAC1B,gBAAgB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IAC1C,QAAQ;AAAA,MACN,oBAAoB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC9C,wBAAwB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAClD,kBAAkB,EAAE,OAAO,MAAM,QAAQ,EAAI;AAAA,MAC7C,sBAAsB,EAAE,OAAO,MAAM,QAAQ,EAAI;AAAA,MACjD,oBAAoB,EAAE,OAAO,OAAO,QAAQ,IAAI;AAAA,MAChD,wBAAwB,EAAE,OAAO,OAAO,QAAQ,IAAI;AAAA,MACpD,kBAAkB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,iBAAiB;AAAA,IAC3B,eAAe,CAAC,aAAa,aAAa,aAAa;AAAA,IACvD,gBAAgB,EAAE,OAAO,GAAK,QAAQ,EAAI;AAAA,IAC1C,QAAQ;AAAA,MACN,iBAAiB,EAAE,OAAO,GAAK,QAAQ,EAAI;AAAA,MAC3C,sBAAsB,EAAE,OAAO,GAAK,QAAQ,EAAI;AAAA,MAChD,kBAAkB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC5C,iBAAiB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC3C,sBAAsB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAChD,gBAAgB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC1C,iBAAiB,EAAE,OAAO,GAAK,QAAQ,EAAI;AAAA,MAC3C,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MACrC,kBAAkB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,cAAc;AAAA,IACxB,eAAe,CAAC,SAAS;AAAA;AAAA,IACzB,gBAAgB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC5C,QAAQ;AAAA,MACN,2BAA2B,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACvD,yBAAyB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACrD,2BAA2B,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACvD,wBAAwB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACpD,oBAAoB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MAChD,mBAAmB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MAC/C,sBAAsB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MAClD,gBAAgB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,mBAAmB;AAAA,IAC7B,eAAe,CAAC,iBAAiB,cAAc,YAAY,aAAa;AAAA,IACxE,gBAAgB,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,IAC3C,QAAQ;AAAA,MACN,6CAA6C,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACxE,6CAA6C,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACxE,4CAA4C,EAAE,OAAO,KAAK,QAAQ,EAAI;AAAA,MACtE,yCAAyC,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MACrE,2CAA2C,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,MACtE,0CAA0C,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACtE,kCAAkC,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC5D,gCAAgC,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC1D,6BAA6B,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MACxD,iCAAiC,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MAC5D,gCAAgC,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC1D,oCAAoC,EAAE,OAAO,MAAM,QAAQ,GAAK;AAAA,MAChE,mCAAmC,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,sBAAsB;AAAA,IAChC,eAAe,CAAC;AAAA;AAAA,IAChB,gBAAgB,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,IAC3C,QAAQ;AAAA;AAAA,MAEN,UAAU,EAAE,OAAO,KAAK,QAAQ,GAAK;AAAA,MACrC,eAAe,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MAC1C,eAAe,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MAC3C,SAAS,EAAE,OAAO,IAAM,QAAQ,GAAK;AAAA,MACrC,gBAAgB,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA;AAAA,IAC5C;AAAA,EACF;AACF;AAQO,SAAS,wBAAwB,OAA6B;AACnE,QAAM,aAAa,MAAM,YAAY;AAGrC,MACE,WAAW,SAAS,YAAY,KAChC,WAAW,SAAS,SAAS,KAC7B,WAAW,SAAS,OAAO,KAC3B,WAAW,SAAS,UAAU,GAC9B;AACA,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,WAAW,QAAQ,GAAG;AACnC,WAAO;AAAA,EACT;AAGA,MACE,WAAW,WAAW,MAAM,KAC5B,WAAW,WAAW,IAAI,KAC1B,WAAW,WAAW,IAAI,GAC1B;AAEA,QAAI,QAAQ,IAAI,yBAAyB,QAAQ,IAAI,sBAAsB;AACzE,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,WAAW,QAAQ,GAAG;AACnC,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,WAAW,SAAS,KAAK,WAAW,WAAW,SAAS,KAAK,WAAW,WAAW,WAAW,GAAG;AAE9G,QAAI,QAAQ,IAAI,gBAAgB,CAAC,QAAQ,IAAI,iBAAiB;AAC5D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,WAAW,OAAO,KAAK,WAAW,WAAW,OAAO,GAAG;AACpE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAOO,SAAS,yBAA8C;AAC5D,QAAM,WAAgC,CAAC;AAGvC,MAAI,QAAQ,IAAI,mBAAmB;AACjC,UAAM,OAAO,SAAS,QAAQ,IAAI,kBAAkB,KAAK,EAAE;AAC3D,UAAM,YAAY,QAAQ,IAAI,0BAA0B,QAAQ,IAAI;AACpE,UAAM,eAAe,QAAQ,IAAI,kBAAkB,YAAY;AAE/D,QAAI,OAAO;AACX,QAAI,aAAsC;AAC1C,QAAI,SAAS;AAEb,QAAI,iBAAiB,SAAS;AAC5B,aAAO;AACP,mBAAa;AACb,eAAS;AAAA,IACX,WAAW,iBAAiB,OAAO;AACjC,aAAO;AACP,mBAAa;AACb,eAAS;AAAA,IACX,WAAW,WAAW;AACpB,aAAO;AACP,eAAS,gBAAgB,SAAS;AAAA,IACpC,WAAW,QAAQ,GAAG;AACpB,aAAO;AACP,eAAS,QAAQ,IAAI;AAAA,IACvB,WAAW,QAAQ,KAAK,QAAQ,GAAG;AACjC,aAAO;AACP,eAAS,QAAQ,IAAI;AAAA,IACvB;AAEA,aAAS,KAAK,EAAE,UAAU,aAAa,MAAM,YAAY,OAAO,CAAC;AAAA,EACnE;AAGA,MAAI,QAAQ,IAAI,gBAAgB;AAC9B,UAAM,QAAQ,QAAQ,IAAI;AAC1B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,QAAQ,oBAAoB;AAAA,MAClC,YAAY;AAAA,MACZ,QAAQ,QAAQ,eAAe;AAAA,IACjC,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,gBAAgB;AAC5D,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,mBAAmB;AACjC,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,sBAAsB;AACpC,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,QAAQ,IAAI,0BAA0B,QAAQ;AAAA,MACpD,YAAY;AAAA,MACZ,QAAQ,QAAQ,IAAI,0BAA0B,wBAAwB;AAAA,IACxE,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,iBAAiB;AAC/B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,cAAc;AAC5B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AASO,SAAS,gBAAgB,UAAwB,OAA6B;AACnF,MAAI,aAAa,WAAW;AAE1B,WAAO,EAAE,OAAO,GAAK,QAAQ,GAAK;AAAA,EACpC;AAEA,QAAM,SAAS,UAAU,QAAQ;AACjC,QAAM,aAAa,MAAM,YAAY;AAGrC,MAAI,OAAO,OAAO,KAAK,GAAG;AACxB,WAAO,OAAO,OAAO,KAAK;AAAA,EAC5B;AAGA,QAAM,eAAe,OAAO,KAAK,OAAO,MAAM,EAAE;AAAA,IAC9C,CAAC,MAAM,EAAE,YAAY,MAAM;AAAA,EAC7B;AACA,MAAI,cAAc;AAChB,WAAO,OAAO,OAAO,YAAY;AAAA,EACnC;AAGA,QAAM,eAAe,OAAO,KAAK,OAAO,MAAM,EAAE;AAAA,IAC9C,CAAC,MAAM,WAAW,SAAS,EAAE,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,UAAU;AAAA,EACpF;AACA,MAAI,cAAc;AAChB,WAAO,OAAO,OAAO,YAAY;AAAA,EACnC;AAEA,SAAO,OAAO;AAChB;AAWO,SAAS,SACd,UACA,OACA,aACA,cACA,eAAe,GACP;AACR,QAAM,UAAU,gBAAgB,UAAU,KAAK;AAG/C,QAAM,YAAa,cAAc,MAAa,QAAQ;AACtD,QAAM,aAAc,eAAe,MAAa,QAAQ;AACxD,QAAM,aAAa,QAAQ,SACtB,eAAe,MAAa,QAAQ,SACrC;AAEJ,SAAO,YAAY,aAAa;AAClC;AAOO,SAAS,uBAAuB,UAAgC;AACrE,MAAI,aAAa,UAAW,QAAO;AACnC,SAAO,UAAU,QAAQ,EAAE;AAC7B;","names":[]}