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,384 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/terminal.ts
4
+ function isColorEnabled() {
5
+ if (process.env.NO_COLOR !== void 0) return false;
6
+ if (process.env.FORCE_COLOR !== void 0) return true;
7
+ if (process.stdout.isTTY === true) return true;
8
+ if (isAiCli()) return true;
9
+ return false;
10
+ }
11
+ function isAiCli() {
12
+ if (process.env.CLAUDECODE !== void 0) return true;
13
+ if (process.env.CURSOR_CHANNEL !== void 0) return true;
14
+ if (process.env.CODY_AUTH !== void 0) return true;
15
+ if (process.env.GITHUB_COPILOT_CLI !== void 0) return true;
16
+ if (process.env.AIDER_MODEL !== void 0) return true;
17
+ if (process.env.CONTINUE_GLOBAL_DIR !== void 0) return true;
18
+ return false;
19
+ }
20
+ var COLOR_ENABLED = isColorEnabled();
21
+ var ESC = COLOR_ENABLED ? "\x1B[" : "";
22
+ var RESET = COLOR_ENABLED ? "\x1B[0m" : "";
23
+ function supportsTrueColor() {
24
+ if (!COLOR_ENABLED) return false;
25
+ const colorterm = process.env.COLORTERM;
26
+ if (colorterm === "truecolor" || colorterm === "24bit") return true;
27
+ const term = process.env.TERM || "";
28
+ if (term.includes("256color") || term.includes("truecolor")) return true;
29
+ if (process.env.TERM_PROGRAM === "iTerm.app") return true;
30
+ if (process.env.TERM_PROGRAM === "vscode") return true;
31
+ if (process.env.WT_SESSION) return true;
32
+ return false;
33
+ }
34
+ var USE_TRUE_COLOR = supportsTrueColor();
35
+ var rgb = (r, g, b) => COLOR_ENABLED ? `\x1B[38;2;${r};${g};${b}m` : "";
36
+ var bgRgb = (r, g, b) => COLOR_ENABLED ? `\x1B[48;2;${r};${g};${b}m` : "";
37
+ function isLightBackground() {
38
+ const theme = process.env.SQUADS_THEME?.toLowerCase();
39
+ if (theme === "light") return true;
40
+ if (theme === "dark") return false;
41
+ const colorfgbg = process.env.COLORFGBG;
42
+ if (colorfgbg) {
43
+ const parts = colorfgbg.split(";");
44
+ const bg = parseInt(parts[parts.length - 1], 10);
45
+ if (!isNaN(bg) && (bg === 15 || bg === 7)) return true;
46
+ }
47
+ return false;
48
+ }
49
+ var USE_LIGHT_MODE = isLightBackground();
50
+ var noColors = {
51
+ purple: "",
52
+ pink: "",
53
+ cyan: "",
54
+ green: "",
55
+ yellow: "",
56
+ red: "",
57
+ gray: "",
58
+ dim: "",
59
+ white: ""
60
+ };
61
+ var ansiDark = {
62
+ purple: "\x1B[35m",
63
+ // magenta
64
+ pink: "\x1B[95m",
65
+ // bright magenta
66
+ cyan: "\x1B[36m",
67
+ // cyan
68
+ green: "\x1B[32m",
69
+ // green
70
+ yellow: "\x1B[33m",
71
+ // yellow
72
+ red: "\x1B[31m",
73
+ // red
74
+ gray: "\x1B[90m",
75
+ // bright black (gray)
76
+ dim: "\x1B[90m",
77
+ // bright black (gray)
78
+ white: "\x1B[97m"
79
+ // bright white
80
+ };
81
+ var ansiLight = {
82
+ purple: "\x1B[35m",
83
+ // magenta (same, works on light)
84
+ pink: "\x1B[35m",
85
+ // magenta (bright is too light)
86
+ cyan: "\x1B[36m",
87
+ // cyan
88
+ green: "\x1B[32m",
89
+ // green
90
+ yellow: "\x1B[33m",
91
+ // yellow
92
+ red: "\x1B[31m",
93
+ // red
94
+ gray: "\x1B[90m",
95
+ // bright black (gray)
96
+ dim: "\x1B[90m",
97
+ // bright black (gray)
98
+ white: "\x1B[30m"
99
+ // black for light backgrounds
100
+ };
101
+ var darkPalette = {
102
+ purple: rgb(168, 85, 247),
103
+ // #a855f7
104
+ pink: rgb(236, 72, 153),
105
+ // #ec4899
106
+ cyan: rgb(6, 182, 212),
107
+ // #06b6d4
108
+ green: rgb(16, 185, 129),
109
+ // #10b981
110
+ yellow: rgb(234, 179, 8),
111
+ // #eab308
112
+ red: rgb(239, 68, 68),
113
+ // #ef4444
114
+ gray: rgb(107, 114, 128),
115
+ // #6b7280
116
+ dim: rgb(75, 85, 99),
117
+ // #4b5563
118
+ white: rgb(255, 255, 255)
119
+ };
120
+ var lightPalette = {
121
+ purple: rgb(124, 58, 237),
122
+ // #7c3aed (purple-600)
123
+ pink: rgb(219, 39, 119),
124
+ // #db2777 (pink-600)
125
+ cyan: rgb(8, 145, 178),
126
+ // #0891b2 (cyan-600)
127
+ green: rgb(22, 163, 74),
128
+ // #16a34a (green-600)
129
+ yellow: rgb(202, 138, 4),
130
+ // #ca8a04 (yellow-600)
131
+ red: rgb(220, 38, 38),
132
+ // #dc2626 (red-600)
133
+ gray: rgb(75, 85, 99),
134
+ // #4b5563 (gray-600)
135
+ dim: rgb(107, 114, 128),
136
+ // #6b7280 (gray-500)
137
+ white: rgb(0, 0, 0)
138
+ // black for light backgrounds
139
+ };
140
+ var colors = !COLOR_ENABLED ? noColors : USE_TRUE_COLOR ? USE_LIGHT_MODE ? lightPalette : darkPalette : USE_LIGHT_MODE ? ansiLight : ansiDark;
141
+ var bold = COLOR_ENABLED ? "\x1B[1m" : "";
142
+ var dim = COLOR_ENABLED ? "\x1B[2m" : "";
143
+ var cursor = COLOR_ENABLED ? {
144
+ hide: "\x1B[?25l",
145
+ show: "\x1B[?25h",
146
+ up: (n = 1) => `\x1B[${n}A`,
147
+ down: (n = 1) => `\x1B[${n}B`,
148
+ left: (n = 1) => `\x1B[${n}D`,
149
+ right: (n = 1) => `\x1B[${n}C`,
150
+ to: (x, y) => `\x1B[${y};${x}H`,
151
+ save: "\x1B[s",
152
+ restore: "\x1B[u"
153
+ } : {
154
+ hide: "",
155
+ show: "",
156
+ up: (_n = 1) => "",
157
+ down: (_n = 1) => "",
158
+ left: (_n = 1) => "",
159
+ right: (_n = 1) => "",
160
+ to: (_x, _y) => "",
161
+ save: "",
162
+ restore: ""
163
+ };
164
+ var clear = COLOR_ENABLED ? {
165
+ line: "\x1B[2K",
166
+ toEnd: "\x1B[0K",
167
+ screen: "\x1B[2J\x1B[0;0H"
168
+ } : {
169
+ line: "",
170
+ toEnd: "",
171
+ screen: ""
172
+ };
173
+ function supportsUnicode() {
174
+ if (process.platform === "win32") {
175
+ if (process.env.WT_SESSION) return true;
176
+ if (process.env.ConEmuTask) return true;
177
+ if (process.env.LANG?.includes("UTF") || process.env.LC_ALL?.includes("UTF")) return true;
178
+ return false;
179
+ }
180
+ if (process.env.SQUADS_ASCII !== void 0) return false;
181
+ return true;
182
+ }
183
+ var USE_UNICODE = supportsUnicode();
184
+ function gradient(text) {
185
+ if (!COLOR_ENABLED) return text;
186
+ const stops = [
187
+ [168, 85, 247],
188
+ // purple
189
+ [192, 132, 252],
190
+ // purple-light
191
+ [232, 121, 249],
192
+ // pink
193
+ [244, 114, 182],
194
+ // pink-light
195
+ [251, 113, 133]
196
+ // rose
197
+ ];
198
+ let result = "";
199
+ for (let i = 0; i < text.length; i++) {
200
+ const t = i / Math.max(text.length - 1, 1);
201
+ const stopIndex = t * (stops.length - 1);
202
+ const lower = Math.floor(stopIndex);
203
+ const upper = Math.min(lower + 1, stops.length - 1);
204
+ const blend = stopIndex - lower;
205
+ const r = Math.round(stops[lower][0] + (stops[upper][0] - stops[lower][0]) * blend);
206
+ const g = Math.round(stops[lower][1] + (stops[upper][1] - stops[lower][1]) * blend);
207
+ const b = Math.round(stops[lower][2] + (stops[upper][2] - stops[lower][2]) * blend);
208
+ result += rgb(r, g, b) + text[i];
209
+ }
210
+ return result + RESET;
211
+ }
212
+ var BAR_FILLED = USE_UNICODE ? "\u2501" : "=";
213
+ var BAR_EMPTY = USE_UNICODE ? "\u2501" : "-";
214
+ function progressBar(percent, width = 20) {
215
+ const clampedPercent = Math.max(0, Math.min(100, percent || 0));
216
+ const filled = Math.round(clampedPercent / 100 * width);
217
+ const empty = Math.max(0, width - filled);
218
+ let bar = "";
219
+ for (let i = 0; i < filled; i++) {
220
+ const t = i / Math.max(filled - 1, 1);
221
+ const r = Math.round(16 + (168 - 16) * t);
222
+ const g = Math.round(185 + (85 - 185) * t);
223
+ const b = Math.round(129 + (247 - 129) * t);
224
+ bar += rgb(r, g, b) + BAR_FILLED;
225
+ }
226
+ bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;
227
+ return bar;
228
+ }
229
+ var box = USE_UNICODE ? {
230
+ topLeft: "\u250C",
231
+ topRight: "\u2510",
232
+ bottomLeft: "\u2514",
233
+ bottomRight: "\u2518",
234
+ horizontal: "\u2500",
235
+ vertical: "\u2502",
236
+ teeRight: "\u251C",
237
+ teeLeft: "\u2524"
238
+ } : {
239
+ topLeft: "+",
240
+ topRight: "+",
241
+ bottomLeft: "+",
242
+ bottomRight: "+",
243
+ horizontal: "-",
244
+ vertical: "|",
245
+ teeRight: "+",
246
+ teeLeft: "+"
247
+ };
248
+ function padEnd(str, len) {
249
+ const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
250
+ const pad = Math.max(0, len - visible.length);
251
+ return str + " ".repeat(pad);
252
+ }
253
+ function truncate(str, len) {
254
+ const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
255
+ if (visible.length <= len) return str;
256
+ let result = "";
257
+ let count = 0;
258
+ let i = 0;
259
+ while (i < str.length && count < len - 1) {
260
+ if (str[i] === "\x1B") {
261
+ const end = str.indexOf("m", i);
262
+ if (end !== -1) {
263
+ result += str.slice(i, end + 1);
264
+ i = end + 1;
265
+ continue;
266
+ }
267
+ }
268
+ result += str[i];
269
+ count++;
270
+ i++;
271
+ }
272
+ return result + colors.dim + "\u2026" + RESET;
273
+ }
274
+ var spinnerFrames = USE_UNICODE ? ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"] : ["-", "\\", "|", "/"];
275
+ var icons = USE_UNICODE ? {
276
+ success: `${colors.green}\u25CF${RESET}`,
277
+ warning: `${colors.yellow}\u25CB${RESET}`,
278
+ error: `${colors.red}\u25CF${RESET}`,
279
+ pending: `${colors.dim}\u25CB${RESET}`,
280
+ active: `${colors.green}\u25CF${RESET}`,
281
+ running: `${colors.yellow}\u25C6${RESET}`,
282
+ progress: `${colors.cyan}\u25C6${RESET}`,
283
+ empty: `${colors.dim}\u25C7${RESET}`,
284
+ // Privacy indicators
285
+ internal: `${colors.purple}\u{1F512}${RESET}`,
286
+ publicOk: `${colors.green}\u{1F310}${RESET}`,
287
+ caution: `${colors.yellow}\u26A0\uFE0F${RESET}`
288
+ } : {
289
+ success: `${colors.green}*${RESET}`,
290
+ warning: `${colors.yellow}!${RESET}`,
291
+ error: `${colors.red}x${RESET}`,
292
+ pending: `${colors.dim}o${RESET}`,
293
+ active: `${colors.green}*${RESET}`,
294
+ running: `${colors.yellow}>${RESET}`,
295
+ progress: `${colors.cyan}>${RESET}`,
296
+ empty: `${colors.dim}.${RESET}`,
297
+ // Privacy indicators (ASCII)
298
+ internal: `${colors.purple}[INTERNAL]${RESET}`,
299
+ publicOk: `${colors.green}[PUBLIC]${RESET}`,
300
+ caution: `${colors.yellow}[CAUTION]${RESET}`
301
+ };
302
+ function privacyHeader(level = "internal") {
303
+ const headers = {
304
+ internal: ` ${icons.internal} ${colors.purple}INTERNAL ONLY${RESET} ${colors.dim}\u2014 not for external sharing${RESET}`,
305
+ public: ` ${icons.publicOk} ${colors.green}PUBLIC OK${RESET} ${colors.dim}\u2014 safe to share externally${RESET}`,
306
+ caution: ` ${icons.caution} ${colors.yellow}CAUTION${RESET} ${colors.dim}\u2014 review before sharing${RESET}`
307
+ };
308
+ return headers[level] + "\n " + colors.dim + "\u2500".repeat(50) + RESET;
309
+ }
310
+ function stripAnsi(str) {
311
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
312
+ }
313
+ function write(str) {
314
+ process.stdout.write(str);
315
+ }
316
+ function writeLine(str = "") {
317
+ process.stdout.write(str + "\n");
318
+ }
319
+ var SPARKLINE_BLOCKS = USE_UNICODE ? ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"] : ["_", ".", "-", "=", "+", "#", "#", "#"];
320
+ function sparkline(values, _width) {
321
+ if (values.length === 0) return "";
322
+ const max = Math.max(...values, 1);
323
+ let result = "";
324
+ for (const val of values) {
325
+ const normalized = val / max;
326
+ const blockIndex = Math.min(Math.floor(normalized * SPARKLINE_BLOCKS.length), SPARKLINE_BLOCKS.length - 1);
327
+ if (normalized === 0) {
328
+ result += colors.dim + SPARKLINE_BLOCKS[0];
329
+ } else if (normalized < 0.5) {
330
+ result += colors.cyan + SPARKLINE_BLOCKS[blockIndex];
331
+ } else {
332
+ result += colors.green + SPARKLINE_BLOCKS[blockIndex];
333
+ }
334
+ }
335
+ return result + RESET;
336
+ }
337
+ function barChart(value, max, width = 20, label) {
338
+ const safeValue = Math.max(0, value || 0);
339
+ const safeMax = Math.max(1, max || 1);
340
+ const ratio = Math.min(1, safeValue / safeMax);
341
+ const filled = Math.round(ratio * width);
342
+ const empty = width - filled;
343
+ let bar = "";
344
+ for (let i = 0; i < filled; i++) {
345
+ const t = i / Math.max(filled - 1, 1);
346
+ const r = Math.round(16 + (6 - 16) * t);
347
+ const g = Math.round(185 + (182 - 185) * t);
348
+ const b = Math.round(129 + (212 - 129) * t);
349
+ bar += rgb(r, g, b) + BAR_FILLED;
350
+ }
351
+ bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;
352
+ if (label) {
353
+ return `${bar} ${label}`;
354
+ }
355
+ return bar;
356
+ }
357
+
358
+ export {
359
+ isColorEnabled,
360
+ isAiCli,
361
+ ESC,
362
+ RESET,
363
+ rgb,
364
+ bgRgb,
365
+ colors,
366
+ bold,
367
+ dim,
368
+ cursor,
369
+ clear,
370
+ gradient,
371
+ progressBar,
372
+ box,
373
+ padEnd,
374
+ truncate,
375
+ spinnerFrames,
376
+ icons,
377
+ privacyHeader,
378
+ stripAnsi,
379
+ write,
380
+ writeLine,
381
+ sparkline,
382
+ barChart
383
+ };
384
+ //# sourceMappingURL=chunk-M5FXNY6Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/terminal.ts"],"sourcesContent":["// Terminal utilities - Bun-style approach\n// Raw ANSI for performance, no heavy deps\n\n// Check if we should use colors (TTY detection)\n// Evaluated once at module load — must be before any ANSI constant definitions\nexport function isColorEnabled(): boolean {\n // NO_COLOR environment variable (standard: https://no-color.org/)\n if (process.env.NO_COLOR !== undefined) return false;\n // Force color via environment variable\n if (process.env.FORCE_COLOR !== undefined) return true;\n // TTY check first — piped output (squads | grep) never gets colors\n if (process.stdout.isTTY === true) return true;\n // AI coding assistants that may not expose a TTY but support ANSI rendering\n // Only reached when isTTY is undefined (not explicitly a terminal)\n if (isAiCli()) return true;\n return false;\n}\n\n// Check if running under an AI coding assistant\n// Only include env vars that are EXCLUSIVELY set by the tool's terminal session,\n// not general API keys (e.g. GEMINI_API_KEY, CODEIUM_API_KEY) which users set globally\n// and cause false positives when piping output.\nexport function isAiCli(): boolean {\n // Claude Code\n if (process.env.CLAUDECODE !== undefined) return true;\n // Cursor\n if (process.env.CURSOR_CHANNEL !== undefined) return true;\n // Sourcegraph Cody\n if (process.env.CODY_AUTH !== undefined) return true;\n // Copilot CLI\n if (process.env.GITHUB_COPILOT_CLI !== undefined) return true;\n // Aider\n if (process.env.AIDER_MODEL !== undefined) return true;\n // Continue.dev\n if (process.env.CONTINUE_GLOBAL_DIR !== undefined) return true;\n return false;\n}\n\n// Master color toggle — when false, all ANSI codes become empty strings\nconst COLOR_ENABLED = isColorEnabled();\n\n// ANSI escape codes (empty when piped/NO_COLOR)\nexport const ESC = COLOR_ENABLED ? '\\x1b[' : '';\nexport const RESET = COLOR_ENABLED ? '\\x1b[0m' : '';\n\n// Detect true color support\nfunction supportsTrueColor(): boolean {\n if (!COLOR_ENABLED) return false;\n const colorterm = process.env.COLORTERM;\n if (colorterm === 'truecolor' || colorterm === '24bit') return true;\n const term = process.env.TERM || '';\n if (term.includes('256color') || term.includes('truecolor')) return true;\n // iTerm2, VS Code, modern terminals\n if (process.env.TERM_PROGRAM === 'iTerm.app') return true;\n if (process.env.TERM_PROGRAM === 'vscode') return true;\n if (process.env.WT_SESSION) return true; // Windows Terminal\n return false;\n}\n\nconst USE_TRUE_COLOR = supportsTrueColor();\n\n// Colors - use 24-bit RGB if supported, fallback to basic ANSI\n// Returns empty string when colors are disabled (piped output, NO_COLOR)\nexport const rgb = (r: number, g: number, b: number) => COLOR_ENABLED ? `\\x1b[38;2;${r};${g};${b}m` : '';\nexport const bgRgb = (r: number, g: number, b: number) => COLOR_ENABLED ? `\\x1b[48;2;${r};${g};${b}m` : '';\n\n// Detect light terminal background\n// Uses COLORFGBG env var (format: \"fg;bg\" where bg > 7 = light)\n// or SQUADS_THEME env var for explicit override\nfunction isLightBackground(): boolean {\n const theme = process.env.SQUADS_THEME?.toLowerCase();\n if (theme === 'light') return true;\n if (theme === 'dark') return false;\n\n // COLORFGBG is set by some terminals (xterm, rxvt, etc.)\n // Format: \"foreground;background\" where numbers are ANSI color indices\n // Light backgrounds typically use indices > 7 (white = 15, light gray = 7)\n const colorfgbg = process.env.COLORFGBG;\n if (colorfgbg) {\n const parts = colorfgbg.split(';');\n const bg = parseInt(parts[parts.length - 1], 10);\n if (!isNaN(bg) && (bg === 15 || bg === 7)) return true;\n }\n\n return false;\n}\n\nconst USE_LIGHT_MODE = isLightBackground();\n\n// Empty palette for when colors are disabled\nconst noColors = {\n purple: '', pink: '', cyan: '', green: '', yellow: '',\n red: '', gray: '', dim: '', white: '',\n};\n\n// Basic ANSI color codes (work everywhere)\nconst ansiDark = {\n purple: '\\x1b[35m', // magenta\n pink: '\\x1b[95m', // bright magenta\n cyan: '\\x1b[36m', // cyan\n green: '\\x1b[32m', // green\n yellow: '\\x1b[33m', // yellow\n red: '\\x1b[31m', // red\n gray: '\\x1b[90m', // bright black (gray)\n dim: '\\x1b[90m', // bright black (gray)\n white: '\\x1b[97m', // bright white\n};\n\nconst ansiLight = {\n purple: '\\x1b[35m', // magenta (same, works on light)\n pink: '\\x1b[35m', // magenta (bright is too light)\n cyan: '\\x1b[36m', // cyan\n green: '\\x1b[32m', // green\n yellow: '\\x1b[33m', // yellow\n red: '\\x1b[31m', // red\n gray: '\\x1b[90m', // bright black (gray)\n dim: '\\x1b[90m', // bright black (gray)\n white: '\\x1b[30m', // black for light backgrounds\n};\n\n// Dark mode palette (original - for dark backgrounds)\nconst darkPalette = {\n purple: rgb(168, 85, 247), // #a855f7\n pink: rgb(236, 72, 153), // #ec4899\n cyan: rgb(6, 182, 212), // #06b6d4\n green: rgb(16, 185, 129), // #10b981\n yellow: rgb(234, 179, 8), // #eab308\n red: rgb(239, 68, 68), // #ef4444\n gray: rgb(107, 114, 128), // #6b7280\n dim: rgb(75, 85, 99), // #4b5563\n white: rgb(255, 255, 255),\n};\n\n// Light mode palette (darker colors for contrast on light backgrounds)\nconst lightPalette = {\n purple: rgb(124, 58, 237), // #7c3aed (purple-600)\n pink: rgb(219, 39, 119), // #db2777 (pink-600)\n cyan: rgb(8, 145, 178), // #0891b2 (cyan-600)\n green: rgb(22, 163, 74), // #16a34a (green-600)\n yellow: rgb(202, 138, 4), // #ca8a04 (yellow-600)\n red: rgb(220, 38, 38), // #dc2626 (red-600)\n gray: rgb(75, 85, 99), // #4b5563 (gray-600)\n dim: rgb(107, 114, 128), // #6b7280 (gray-500)\n white: rgb(0, 0, 0), // black for light backgrounds\n};\n\n// Named colors (our brand palette) - with theme and fallback support\n// Returns empty strings when colors are disabled (piped output, NO_COLOR)\nexport const colors = !COLOR_ENABLED\n ? noColors\n : USE_TRUE_COLOR\n ? (USE_LIGHT_MODE ? lightPalette : darkPalette)\n : (USE_LIGHT_MODE ? ansiLight : ansiDark);\n\n// Styles (empty when colors disabled)\nexport const bold = COLOR_ENABLED ? '\\x1b[1m' : '';\nexport const dim = COLOR_ENABLED ? '\\x1b[2m' : '';\n\n// Cursor control (no-op when piped)\nexport const cursor = COLOR_ENABLED ? {\n hide: '\\x1b[?25l',\n show: '\\x1b[?25h',\n up: (n = 1) => `\\x1b[${n}A`,\n down: (n = 1) => `\\x1b[${n}B`,\n left: (n = 1) => `\\x1b[${n}D`,\n right: (n = 1) => `\\x1b[${n}C`,\n to: (x: number, y: number) => `\\x1b[${y};${x}H`,\n save: '\\x1b[s',\n restore: '\\x1b[u',\n} : {\n hide: '',\n show: '',\n up: (_n = 1) => '',\n down: (_n = 1) => '',\n left: (_n = 1) => '',\n right: (_n = 1) => '',\n to: (_x: number, _y: number) => '',\n save: '',\n restore: '',\n};\n\n// Clear (no-op when piped)\nexport const clear = COLOR_ENABLED ? {\n line: '\\x1b[2K',\n toEnd: '\\x1b[0K',\n screen: '\\x1b[2J\\x1b[0;0H',\n} : {\n line: '',\n toEnd: '',\n screen: '',\n};\n\n// Check if terminal supports Unicode\nfunction supportsUnicode(): boolean {\n // Windows CMD typically doesn't support Unicode well\n if (process.platform === 'win32') {\n // Windows Terminal supports Unicode\n if (process.env.WT_SESSION) return true;\n // ConEmu supports Unicode\n if (process.env.ConEmuTask) return true;\n // Fallback: check for UTF-8 codepage\n if (process.env.LANG?.includes('UTF') || process.env.LC_ALL?.includes('UTF')) return true;\n return false;\n }\n // Most modern terminals on macOS/Linux support Unicode\n // But AI CLIs might not render them well in their output\n // Force ASCII for known problematic environments\n if (process.env.SQUADS_ASCII !== undefined) return false;\n return true;\n}\n\nconst USE_UNICODE = supportsUnicode();\n\n// Gradient text (purple → pink → cyan)\nexport function gradient(text: string): string {\n if (!COLOR_ENABLED) return text;\n\n const stops = [\n [168, 85, 247], // purple\n [192, 132, 252], // purple-light\n [232, 121, 249], // pink\n [244, 114, 182], // pink-light\n [251, 113, 133], // rose\n ];\n\n let result = '';\n for (let i = 0; i < text.length; i++) {\n const t = i / Math.max(text.length - 1, 1);\n const stopIndex = t * (stops.length - 1);\n const lower = Math.floor(stopIndex);\n const upper = Math.min(lower + 1, stops.length - 1);\n const blend = stopIndex - lower;\n\n const r = Math.round(stops[lower][0] + (stops[upper][0] - stops[lower][0]) * blend);\n const g = Math.round(stops[lower][1] + (stops[upper][1] - stops[lower][1]) * blend);\n const b = Math.round(stops[lower][2] + (stops[upper][2] - stops[lower][2]) * blend);\n\n result += rgb(r, g, b) + text[i];\n }\n return result + RESET;\n}\n\n// Progress bar characters\nconst BAR_FILLED = USE_UNICODE ? '━' : '=';\nconst BAR_EMPTY = USE_UNICODE ? '━' : '-';\n\n// Progress bar with gradient fill\nexport function progressBar(percent: number, width = 20): string {\n // Clamp values to prevent negative repeat counts\n const clampedPercent = Math.max(0, Math.min(100, percent || 0));\n const filled = Math.round((clampedPercent / 100) * width);\n const empty = Math.max(0, width - filled);\n\n let bar = '';\n for (let i = 0; i < filled; i++) {\n const t = i / Math.max(filled - 1, 1);\n const r = Math.round(16 + (168 - 16) * t);\n const g = Math.round(185 + (85 - 185) * t);\n const b = Math.round(129 + (247 - 129) * t);\n bar += rgb(r, g, b) + BAR_FILLED;\n }\n\n bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;\n return bar;\n}\n\n// Box drawing - with ASCII fallback\nexport const box = USE_UNICODE ? {\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n horizontal: '─',\n vertical: '│',\n teeRight: '├',\n teeLeft: '┤',\n} : {\n topLeft: '+',\n topRight: '+',\n bottomLeft: '+',\n bottomRight: '+',\n horizontal: '-',\n vertical: '|',\n teeRight: '+',\n teeLeft: '+',\n};\n\n// Format helpers\nexport function padEnd(str: string, len: number): string {\n // Strip ANSI codes for length calculation\n const visible = str.replace(/\\x1b\\[[0-9;]*m/g, '');\n const pad = Math.max(0, len - visible.length);\n return str + ' '.repeat(pad);\n}\n\nexport function truncate(str: string, len: number): string {\n const visible = str.replace(/\\x1b\\[[0-9;]*m/g, '');\n if (visible.length <= len) return str;\n\n // Simple truncation (won't handle mid-ANSI truncation perfectly)\n let result = '';\n let count = 0;\n let i = 0;\n\n while (i < str.length && count < len - 1) {\n if (str[i] === '\\x1b') {\n const end = str.indexOf('m', i);\n if (end !== -1) {\n result += str.slice(i, end + 1);\n i = end + 1;\n continue;\n }\n }\n result += str[i];\n count++;\n i++;\n }\n\n return result + colors.dim + '…' + RESET;\n}\n\n// Spinner frames - with ASCII fallback\nexport const spinnerFrames = USE_UNICODE\n ? ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\n : ['-', '\\\\', '|', '/'];\n\n// Status icons - with ASCII fallback\nexport const icons = USE_UNICODE ? {\n success: `${colors.green}●${RESET}`,\n warning: `${colors.yellow}○${RESET}`,\n error: `${colors.red}●${RESET}`,\n pending: `${colors.dim}○${RESET}`,\n active: `${colors.green}●${RESET}`,\n running: `${colors.yellow}◆${RESET}`,\n progress: `${colors.cyan}◆${RESET}`,\n empty: `${colors.dim}◇${RESET}`,\n // Privacy indicators\n internal: `${colors.purple}🔒${RESET}`,\n publicOk: `${colors.green}🌐${RESET}`,\n caution: `${colors.yellow}⚠️${RESET}`,\n} : {\n success: `${colors.green}*${RESET}`,\n warning: `${colors.yellow}!${RESET}`,\n error: `${colors.red}x${RESET}`,\n pending: `${colors.dim}o${RESET}`,\n active: `${colors.green}*${RESET}`,\n running: `${colors.yellow}>${RESET}`,\n progress: `${colors.cyan}>${RESET}`,\n empty: `${colors.dim}.${RESET}`,\n // Privacy indicators (ASCII)\n internal: `${colors.purple}[INTERNAL]${RESET}`,\n publicOk: `${colors.green}[PUBLIC]${RESET}`,\n caution: `${colors.yellow}[CAUTION]${RESET}`,\n};\n\n// Privacy level type\nexport type PrivacyLevel = 'internal' | 'public' | 'caution';\n\n// Privacy header - shows trust indicator at top of output\nexport function privacyHeader(level: PrivacyLevel = 'internal'): string {\n const headers = {\n internal: ` ${icons.internal} ${colors.purple}INTERNAL ONLY${RESET} ${colors.dim}— not for external sharing${RESET}`,\n public: ` ${icons.publicOk} ${colors.green}PUBLIC OK${RESET} ${colors.dim}— safe to share externally${RESET}`,\n caution: ` ${icons.caution} ${colors.yellow}CAUTION${RESET} ${colors.dim}— review before sharing${RESET}`,\n };\n return headers[level] + '\\n ' + colors.dim + '─'.repeat(50) + RESET;\n}\n\n// Strip ANSI escape codes from a string\nexport function stripAnsi(str: string): string {\n return str.replace(/\\x1b\\[[0-9;]*m/g, '');\n}\n\n// Write without newline\nexport function write(str: string): void {\n process.stdout.write(str);\n}\n\n// Write line\nexport function writeLine(str = ''): void {\n process.stdout.write(str + '\\n');\n}\n\n// Sparkline characters - Unicode blocks vs ASCII\nconst SPARKLINE_BLOCKS = USE_UNICODE\n ? ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█']\n : ['_', '.', '-', '=', '+', '#', '#', '#'];\n\n// Sparkline chart using block characters\nexport function sparkline(values: number[], _width?: number): string {\n if (values.length === 0) return '';\n\n const max = Math.max(...values, 1);\n\n let result = '';\n for (const val of values) {\n const normalized = val / max;\n const blockIndex = Math.min(Math.floor(normalized * SPARKLINE_BLOCKS.length), SPARKLINE_BLOCKS.length - 1);\n\n // Color gradient from dim to cyan to green based on value\n if (normalized === 0) {\n result += colors.dim + SPARKLINE_BLOCKS[0];\n } else if (normalized < 0.5) {\n result += colors.cyan + SPARKLINE_BLOCKS[blockIndex];\n } else {\n result += colors.green + SPARKLINE_BLOCKS[blockIndex];\n }\n }\n\n return result + RESET;\n}\n\n// Bar chart (horizontal)\nexport function barChart(value: number, max: number, width: number = 20, label?: string): string {\n // Guard against invalid inputs to prevent crashes\n const safeValue = Math.max(0, value || 0);\n const safeMax = Math.max(1, max || 1); // Prevent division by zero\n const ratio = Math.min(1, safeValue / safeMax); // Clamp ratio to 0-1\n const filled = Math.round(ratio * width);\n const empty = width - filled;\n\n let bar = '';\n for (let i = 0; i < filled; i++) {\n const t = i / Math.max(filled - 1, 1);\n // Green to cyan gradient\n const r = Math.round(16 + (6 - 16) * t);\n const g = Math.round(185 + (182 - 185) * t);\n const b = Math.round(129 + (212 - 129) * t);\n bar += rgb(r, g, b) + BAR_FILLED;\n }\n\n bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;\n\n if (label) {\n return `${bar} ${label}`;\n }\n return bar;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/llm-clis.ts
4
+ import { execSync } from "child_process";
5
+ function commandExists(command) {
6
+ try {
7
+ execSync(`which ${command}`, { stdio: "pipe" });
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+ var LLM_CLIS = {
14
+ anthropic: {
15
+ provider: "anthropic",
16
+ displayName: "Anthropic",
17
+ command: "claude",
18
+ install: "npm i -g @anthropic-ai/claude-code",
19
+ buildArgs: (prompt) => ["--print", prompt]
20
+ },
21
+ google: {
22
+ provider: "google",
23
+ displayName: "Google",
24
+ command: "gemini",
25
+ install: "npm i -g @google/gemini-cli",
26
+ buildArgs: (prompt) => ["--yolo", "--prompt", prompt]
27
+ },
28
+ openai: {
29
+ provider: "openai",
30
+ displayName: "OpenAI",
31
+ command: "codex",
32
+ install: "npm i -g @openai/codex",
33
+ buildArgs: (prompt) => ["exec", prompt]
34
+ },
35
+ mistral: {
36
+ provider: "mistral",
37
+ displayName: "Mistral",
38
+ command: "vibe",
39
+ install: "curl -LsSf https://mistral.ai/vibe/install.sh | bash",
40
+ buildArgs: (prompt) => ["--prompt", prompt, "--auto-approve"]
41
+ },
42
+ xai: {
43
+ provider: "xai",
44
+ displayName: "xAI",
45
+ command: "grok",
46
+ install: "bun add -g @vibe-kit/grok-cli",
47
+ buildArgs: (prompt) => ["--prompt", prompt]
48
+ },
49
+ aider: {
50
+ provider: "aider",
51
+ displayName: "Aider (Multi)",
52
+ command: "aider",
53
+ install: "pip install aider-install && aider-install",
54
+ buildArgs: (prompt) => ["--message", prompt, "--yes"]
55
+ },
56
+ ollama: {
57
+ provider: "ollama",
58
+ displayName: "Ollama (Local)",
59
+ command: "ollama",
60
+ install: "brew install ollama",
61
+ buildArgs: (prompt, opts) => ["run", opts?.model || "llama3.1", prompt]
62
+ }
63
+ };
64
+ function getAllCLIStatus() {
65
+ return Object.values(LLM_CLIS).map((cli) => ({
66
+ provider: cli.provider,
67
+ displayName: cli.displayName,
68
+ command: cli.command,
69
+ available: commandExists(cli.command),
70
+ install: cli.install
71
+ }));
72
+ }
73
+ function getCLIConfig(provider) {
74
+ return LLM_CLIS[provider];
75
+ }
76
+ function isProviderCLIAvailable(provider) {
77
+ const config = LLM_CLIS[provider];
78
+ if (!config) return false;
79
+ return commandExists(config.command);
80
+ }
81
+
82
+ export {
83
+ getAllCLIStatus,
84
+ getCLIConfig,
85
+ isProviderCLIAvailable
86
+ };
87
+ //# sourceMappingURL=chunk-QHNUMM4V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/llm-clis.ts"],"sourcesContent":["/**\n * Multi-LLM CLI Support\n *\n * Enables squads to use different LLM providers by delegating to their native CLIs.\n * Unix-style composition: each provider maintains their own CLI, we orchestrate.\n *\n * @see specs/multi-llm.md\n */\n\nimport { execSync } from 'child_process';\n\nexport interface CLIConfig {\n /** Provider identifier (matches provider field in SQUAD.md/agent.md) */\n provider: string;\n\n /** Display name for UI */\n displayName: string;\n\n /** CLI command name */\n command: string;\n\n /** Install instructions */\n install: string;\n\n /** Build non-interactive args for execution */\n buildArgs: (prompt: string, options?: RunOptions) => string[];\n}\n\nexport interface RunOptions {\n /** Model override (for providers that support it) */\n model?: string;\n\n /** Working directory */\n cwd?: string;\n\n /** Dry run - just show what would execute */\n dryRun?: boolean;\n}\n\n/**\n * Check if a command exists in PATH\n */\nexport function commandExists(command: string): boolean {\n try {\n execSync(`which ${command}`, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * LLM CLI registry\n * Maps provider IDs to their CLI configurations\n */\nexport const LLM_CLIS: Record<string, CLIConfig> = {\n anthropic: {\n provider: 'anthropic',\n displayName: 'Anthropic',\n command: 'claude',\n install: 'npm i -g @anthropic-ai/claude-code',\n buildArgs: (prompt) => ['--print', prompt],\n },\n\n google: {\n provider: 'google',\n displayName: 'Google',\n command: 'gemini',\n install: 'npm i -g @google/gemini-cli',\n buildArgs: (prompt) => ['--yolo', '--prompt', prompt],\n },\n\n openai: {\n provider: 'openai',\n displayName: 'OpenAI',\n command: 'codex',\n install: 'npm i -g @openai/codex',\n buildArgs: (prompt) => ['exec', prompt],\n },\n\n mistral: {\n provider: 'mistral',\n displayName: 'Mistral',\n command: 'vibe',\n install: 'curl -LsSf https://mistral.ai/vibe/install.sh | bash',\n buildArgs: (prompt) => ['--prompt', prompt, '--auto-approve'],\n },\n\n xai: {\n provider: 'xai',\n displayName: 'xAI',\n command: 'grok',\n install: 'bun add -g @vibe-kit/grok-cli',\n buildArgs: (prompt) => ['--prompt', prompt],\n },\n\n aider: {\n provider: 'aider',\n displayName: 'Aider (Multi)',\n command: 'aider',\n install: 'pip install aider-install && aider-install',\n buildArgs: (prompt) => ['--message', prompt, '--yes'],\n },\n\n ollama: {\n provider: 'ollama',\n displayName: 'Ollama (Local)',\n command: 'ollama',\n install: 'brew install ollama',\n buildArgs: (prompt, opts) => ['run', opts?.model || 'llama3.1', prompt],\n },\n};\n\nexport interface CLIStatus {\n provider: string;\n displayName: string;\n command: string;\n available: boolean;\n install: string;\n}\n\n/**\n * Get status of all LLM CLIs\n */\nexport function getAllCLIStatus(): CLIStatus[] {\n return Object.values(LLM_CLIS).map((cli) => ({\n provider: cli.provider,\n displayName: cli.displayName,\n command: cli.command,\n available: commandExists(cli.command),\n install: cli.install,\n }));\n}\n\n/**\n * Get CLI config for a provider\n */\nexport function getCLIConfig(provider: string): CLIConfig | undefined {\n return LLM_CLIS[provider];\n}\n\n/**\n * Check if a provider's CLI is available\n */\nexport function isProviderCLIAvailable(provider: string): boolean {\n const config = LLM_CLIS[provider];\n if (!config) return false;\n return commandExists(config.command);\n}\n"],"mappings":";;;AASA,SAAS,gBAAgB;AAiClB,SAAS,cAAc,SAA0B;AACtD,MAAI;AACF,aAAS,SAAS,OAAO,IAAI,EAAE,OAAO,OAAO,CAAC;AAC9C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,IAAM,WAAsC;AAAA,EACjD,WAAW;AAAA,IACT,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,WAAW,MAAM;AAAA,EAC3C;AAAA,EAEA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,UAAU,YAAY,MAAM;AAAA,EACtD;AAAA,EAEA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,QAAQ,MAAM;AAAA,EACxC;AAAA,EAEA,SAAS;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,YAAY,QAAQ,gBAAgB;AAAA,EAC9D;AAAA,EAEA,KAAK;AAAA,IACH,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,YAAY,MAAM;AAAA,EAC5C;AAAA,EAEA,OAAO;AAAA,IACL,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,WAAW,CAAC,aAAa,QAAQ,OAAO;AAAA,EACtD;AAAA,EAEA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,QAAQ,SAAS,CAAC,OAAO,MAAM,SAAS,YAAY,MAAM;AAAA,EACxE;AACF;AAaO,SAAS,kBAA+B;AAC7C,SAAO,OAAO,OAAO,QAAQ,EAAE,IAAI,CAAC,SAAS;AAAA,IAC3C,UAAU,IAAI;AAAA,IACd,aAAa,IAAI;AAAA,IACjB,SAAS,IAAI;AAAA,IACb,WAAW,cAAc,IAAI,OAAO;AAAA,IACpC,SAAS,IAAI;AAAA,EACf,EAAE;AACJ;AAKO,SAAS,aAAa,UAAyC;AACpE,SAAO,SAAS,QAAQ;AAC1B;AAKO,SAAS,uBAAuB,UAA2B;AAChE,QAAM,SAAS,SAAS,QAAQ;AAChC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,cAAc,OAAO,OAAO;AACrC;","names":[]}