@blackbox_ai/blackbox-cli 0.8.6 → 1.0.2

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 (233) hide show
  1. package/README.md +20 -0
  2. package/dist/assets/notification.mp3 +0 -0
  3. package/dist/package.json +2 -2
  4. package/dist/src/commands/configure/ConfigureUI.d.ts +1 -1
  5. package/dist/src/commands/configure/ConfigureUI.js +91 -22
  6. package/dist/src/commands/configure/ConfigureUI.js.map +1 -1
  7. package/dist/src/commands/configure.js +57 -16
  8. package/dist/src/commands/configure.js.map +1 -1
  9. package/dist/src/commands/shortcut.d.ts +10 -0
  10. package/dist/src/commands/shortcut.js +72 -0
  11. package/dist/src/commands/shortcut.js.map +1 -0
  12. package/dist/src/commands/voice.js +39 -34
  13. package/dist/src/commands/voice.js.map +1 -1
  14. package/dist/src/config/config.js +8 -5
  15. package/dist/src/config/config.js.map +1 -1
  16. package/dist/src/config/modelFetcher.d.ts +4 -0
  17. package/dist/src/config/modelFetcher.js +68 -22
  18. package/dist/src/config/modelFetcher.js.map +1 -1
  19. package/dist/src/config/settings.d.ts +2 -0
  20. package/dist/src/config/settings.js +48 -3
  21. package/dist/src/config/settings.js.map +1 -1
  22. package/dist/src/config/settingsSchema.d.ts +64 -6
  23. package/dist/src/config/settingsSchema.js +62 -6
  24. package/dist/src/config/settingsSchema.js.map +1 -1
  25. package/dist/src/gemini.js +31 -20
  26. package/dist/src/gemini.js.map +1 -1
  27. package/dist/src/generated/git-commit.d.ts +2 -2
  28. package/dist/src/generated/git-commit.js +2 -2
  29. package/dist/src/services/BuiltinCommandLoader.js +4 -2
  30. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  31. package/dist/src/services/agentExecutor.d.ts +57 -0
  32. package/dist/src/services/agentExecutor.js +149 -0
  33. package/dist/src/services/agentExecutor.js.map +1 -0
  34. package/dist/src/services/voiceRecordingService.d.ts +13 -1
  35. package/dist/src/services/voiceRecordingService.js +38 -5
  36. package/dist/src/services/voiceRecordingService.js.map +1 -1
  37. package/dist/src/ui/App.d.ts +1 -1
  38. package/dist/src/ui/App.js +292 -26
  39. package/dist/src/ui/App.js.map +1 -1
  40. package/dist/src/ui/colors.js +3 -0
  41. package/dist/src/ui/colors.js.map +1 -1
  42. package/dist/src/ui/commands/agentCommand.d.ts +7 -0
  43. package/dist/src/ui/commands/agentCommand.js +181 -0
  44. package/dist/src/ui/commands/agentCommand.js.map +1 -0
  45. package/dist/src/ui/commands/modelCommand.js +15 -2
  46. package/dist/src/ui/commands/modelCommand.js.map +1 -1
  47. package/dist/src/ui/commands/quitCommand.js +5 -0
  48. package/dist/src/ui/commands/quitCommand.js.map +1 -1
  49. package/dist/src/ui/commands/subAgentsCommand.d.ts +7 -0
  50. package/dist/src/ui/commands/subAgentsCommand.js +32 -0
  51. package/dist/src/ui/commands/subAgentsCommand.js.map +1 -0
  52. package/dist/src/ui/commands/types.d.ts +24 -3
  53. package/dist/src/ui/commands/types.js.map +1 -1
  54. package/dist/src/ui/commands/voiceCommand.js +70 -34
  55. package/dist/src/ui/commands/voiceCommand.js.map +1 -1
  56. package/dist/src/ui/commands/voiceCommand.test.d.ts +6 -0
  57. package/dist/src/ui/commands/voiceCommand.test.js +131 -0
  58. package/dist/src/ui/commands/voiceCommand.test.js.map +1 -0
  59. package/dist/src/ui/components/AgentModelSelector.d.ts +17 -0
  60. package/dist/src/ui/components/AgentModelSelector.js +41 -0
  61. package/dist/src/ui/components/AgentModelSelector.js.map +1 -0
  62. package/dist/src/ui/components/AgentSetDialog.d.ts +15 -0
  63. package/dist/src/ui/components/AgentSetDialog.js +52 -0
  64. package/dist/src/ui/components/AgentSetDialog.js.map +1 -0
  65. package/dist/src/ui/components/ApiKeyInputDialog.d.ts +17 -0
  66. package/dist/src/ui/components/ApiKeyInputDialog.js +44 -0
  67. package/dist/src/ui/components/ApiKeyInputDialog.js.map +1 -0
  68. package/dist/src/ui/components/AsciiArt.d.ts +3 -3
  69. package/dist/src/ui/components/AsciiArt.js +18 -18
  70. package/dist/src/ui/components/AsciiArt.js.map +1 -1
  71. package/dist/src/ui/components/AuthDialog.js +50 -7
  72. package/dist/src/ui/components/AuthDialog.js.map +1 -1
  73. package/dist/src/ui/components/Footer.d.ts +8 -0
  74. package/dist/src/ui/components/Footer.js +17 -4
  75. package/dist/src/ui/components/Footer.js.map +1 -1
  76. package/dist/src/ui/components/GenericProviderKeyPrompt.js +1 -1
  77. package/dist/src/ui/components/GenericProviderKeyPrompt.js.map +1 -1
  78. package/dist/src/ui/components/Header.js +6 -10
  79. package/dist/src/ui/components/Header.js.map +1 -1
  80. package/dist/src/ui/components/HistoryBrowserDialog.js +2 -1
  81. package/dist/src/ui/components/HistoryBrowserDialog.js.map +1 -1
  82. package/dist/src/ui/components/InputPrompt.js +3 -1
  83. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  84. package/dist/src/ui/components/MemoryUsageDisplay.js +41 -8
  85. package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
  86. package/dist/src/ui/components/SettingsDialog.js +4 -3
  87. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  88. package/dist/src/ui/components/StatsDisplay.js +1 -1
  89. package/dist/src/ui/components/StatsDisplay.js.map +1 -1
  90. package/dist/src/ui/components/SuggestionsDisplay.js +3 -2
  91. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  92. package/dist/src/ui/components/Tips.js +1 -1
  93. package/dist/src/ui/components/Tips.js.map +1 -1
  94. package/dist/src/ui/components/agents/SingleAgentDialog.d.ts +23 -0
  95. package/dist/src/ui/components/agents/SingleAgentDialog.js +222 -0
  96. package/dist/src/ui/components/agents/SingleAgentDialog.js.map +1 -0
  97. package/dist/src/ui/components/messages/DiffRenderer.js +1 -9
  98. package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
  99. package/dist/src/ui/components/messages/ErrorMessage.js +2 -1
  100. package/dist/src/ui/components/messages/ErrorMessage.js.map +1 -1
  101. package/dist/src/ui/components/messages/InfoMessage.js +2 -1
  102. package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
  103. package/dist/src/ui/components/messages/ToolGroupMessage.js +4 -1
  104. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  105. package/dist/src/ui/components/messages/ToolMessage.js +4 -4
  106. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  107. package/dist/src/ui/components/messages/UserMessage.js +1 -2
  108. package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
  109. package/dist/src/ui/components/multiagent/MultiAgentConfigDialog.js +1 -19
  110. package/dist/src/ui/components/multiagent/MultiAgentConfigDialog.js.map +1 -1
  111. package/dist/src/ui/components/shared/RadioButtonSelect.js +14 -4
  112. package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
  113. package/dist/src/ui/contexts/SessionContext.d.ts +18 -0
  114. package/dist/src/ui/contexts/SessionContext.js +25 -1
  115. package/dist/src/ui/contexts/SessionContext.js.map +1 -1
  116. package/dist/src/ui/hooks/shellCommandProcessor.d.ts +1 -1
  117. package/dist/src/ui/hooks/shellCommandProcessor.js +13 -2
  118. package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
  119. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -2
  120. package/dist/src/ui/hooks/slashCommandProcessor.js +65 -29
  121. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  122. package/dist/src/ui/hooks/useAdaptiveStream.d.ts +2 -1
  123. package/dist/src/ui/hooks/useAdaptiveStream.js +2 -2
  124. package/dist/src/ui/hooks/useAdaptiveStream.js.map +1 -1
  125. package/dist/src/ui/hooks/useAgentCommandProcessor.d.ts +26 -0
  126. package/dist/src/ui/hooks/useAgentCommandProcessor.js +967 -0
  127. package/dist/src/ui/hooks/useAgentCommandProcessor.js.map +1 -0
  128. package/dist/src/ui/hooks/useAuthCommand.d.ts +2 -1
  129. package/dist/src/ui/hooks/useAuthCommand.js +22 -2
  130. package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
  131. package/dist/src/ui/hooks/useDialogClose.d.ts +2 -0
  132. package/dist/src/ui/hooks/useDialogClose.js +5 -0
  133. package/dist/src/ui/hooks/useDialogClose.js.map +1 -1
  134. package/dist/src/ui/hooks/useEncryptedStream.d.ts +2 -1
  135. package/dist/src/ui/hooks/useEncryptedStream.js +31 -3
  136. package/dist/src/ui/hooks/useEncryptedStream.js.map +1 -1
  137. package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -1
  138. package/dist/src/ui/hooks/useGeminiStream.js +292 -22
  139. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  140. package/dist/src/ui/hooks/useInputBoxColor.d.ts +13 -0
  141. package/dist/src/ui/hooks/useInputBoxColor.js +62 -0
  142. package/dist/src/ui/hooks/useInputBoxColor.js.map +1 -0
  143. package/dist/src/ui/hooks/useMessageQueue.d.ts +7 -1
  144. package/dist/src/ui/hooks/useMessageQueue.js +9 -3
  145. package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
  146. package/dist/src/ui/hooks/useSingleAgentCommand.d.ts +10 -0
  147. package/dist/src/ui/hooks/useSingleAgentCommand.js +21 -0
  148. package/dist/src/ui/hooks/useSingleAgentCommand.js.map +1 -0
  149. package/dist/src/ui/themes/ansi-light.js +1 -0
  150. package/dist/src/ui/themes/ansi-light.js.map +1 -1
  151. package/dist/src/ui/themes/ansi.js +1 -0
  152. package/dist/src/ui/themes/ansi.js.map +1 -1
  153. package/dist/src/ui/themes/atom-one-dark.js +14 -13
  154. package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
  155. package/dist/src/ui/themes/ayu-light.js +14 -13
  156. package/dist/src/ui/themes/ayu-light.js.map +1 -1
  157. package/dist/src/ui/themes/ayu.js +14 -13
  158. package/dist/src/ui/themes/ayu.js.map +1 -1
  159. package/dist/src/ui/themes/blackbox-dark.js +36 -31
  160. package/dist/src/ui/themes/blackbox-dark.js.map +1 -1
  161. package/dist/src/ui/themes/blackbox-light.js +41 -39
  162. package/dist/src/ui/themes/blackbox-light.js.map +1 -1
  163. package/dist/src/ui/themes/default-light.js +20 -20
  164. package/dist/src/ui/themes/default-light.js.map +1 -1
  165. package/dist/src/ui/themes/default.js +27 -27
  166. package/dist/src/ui/themes/default.js.map +1 -1
  167. package/dist/src/ui/themes/dracula.js +14 -13
  168. package/dist/src/ui/themes/dracula.js.map +1 -1
  169. package/dist/src/ui/themes/github-dark.js +14 -13
  170. package/dist/src/ui/themes/github-dark.js.map +1 -1
  171. package/dist/src/ui/themes/github-light.js +14 -13
  172. package/dist/src/ui/themes/github-light.js.map +1 -1
  173. package/dist/src/ui/themes/googlecode.js +1 -0
  174. package/dist/src/ui/themes/googlecode.js.map +1 -1
  175. package/dist/src/ui/themes/no-color.js +2 -0
  176. package/dist/src/ui/themes/no-color.js.map +1 -1
  177. package/dist/src/ui/themes/semantic-tokens.d.ts +1 -0
  178. package/dist/src/ui/themes/semantic-tokens.js +3 -0
  179. package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
  180. package/dist/src/ui/themes/shades-of-purple.js +1 -0
  181. package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
  182. package/dist/src/ui/themes/theme.d.ts +2 -0
  183. package/dist/src/ui/themes/theme.js +35 -28
  184. package/dist/src/ui/themes/theme.js.map +1 -1
  185. package/dist/src/ui/themes/xcode.js +1 -0
  186. package/dist/src/ui/themes/xcode.js.map +1 -1
  187. package/dist/src/ui/types.d.ts +5 -0
  188. package/dist/src/ui/utils/agentConversationUtils.d.ts +28 -0
  189. package/dist/src/ui/utils/agentConversationUtils.js +71 -0
  190. package/dist/src/ui/utils/agentConversationUtils.js.map +1 -0
  191. package/dist/src/ui/utils/colorBlend.d.ts +33 -0
  192. package/dist/src/ui/utils/colorBlend.js +61 -0
  193. package/dist/src/ui/utils/colorBlend.js.map +1 -0
  194. package/dist/src/ui/utils/commandUtils.d.ts +2 -1
  195. package/dist/src/ui/utils/commandUtils.js +14 -1
  196. package/dist/src/ui/utils/commandUtils.js.map +1 -1
  197. package/dist/src/ui/utils/commandUtils.test.js +25 -0
  198. package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
  199. package/dist/src/ui/utils/terminalBackgroundDetector.d.ts +35 -0
  200. package/dist/src/ui/utils/terminalBackgroundDetector.js +200 -0
  201. package/dist/src/ui/utils/terminalBackgroundDetector.js.map +1 -0
  202. package/dist/src/utils/agentCommandBuilder.d.ts +48 -0
  203. package/dist/src/utils/agentCommandBuilder.js +328 -0
  204. package/dist/src/utils/agentCommandBuilder.js.map +1 -0
  205. package/dist/src/utils/apiKeyUtils.d.ts +47 -0
  206. package/dist/src/utils/apiKeyUtils.js +177 -0
  207. package/dist/src/utils/apiKeyUtils.js.map +1 -0
  208. package/dist/src/utils/backgroundUpdateCheck.js +104 -7
  209. package/dist/src/utils/backgroundUpdateCheck.js.map +1 -1
  210. package/dist/src/utils/memoryManager.d.ts +85 -0
  211. package/dist/src/utils/memoryManager.js +258 -0
  212. package/dist/src/utils/memoryManager.js.map +1 -0
  213. package/dist/src/utils/memoryMonitor.d.ts +89 -0
  214. package/dist/src/utils/memoryMonitor.js +238 -0
  215. package/dist/src/utils/memoryMonitor.js.map +1 -0
  216. package/dist/src/utils/memoryWrapper.d.ts +18 -0
  217. package/dist/src/utils/memoryWrapper.js +62 -0
  218. package/dist/src/utils/memoryWrapper.js.map +1 -0
  219. package/dist/src/utils/preLaunchUpdateCheck.js +17 -7
  220. package/dist/src/utils/preLaunchUpdateCheck.js.map +1 -1
  221. package/dist/src/utils/shellShortcut.d.ts +45 -0
  222. package/dist/src/utils/shellShortcut.js +221 -0
  223. package/dist/src/utils/shellShortcut.js.map +1 -0
  224. package/dist/src/utils/soundNotification.d.ts +15 -0
  225. package/dist/src/utils/soundNotification.js +138 -0
  226. package/dist/src/utils/soundNotification.js.map +1 -0
  227. package/dist/src/utils/userStartupWarnings.js +0 -20
  228. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  229. package/dist/src/utils/versionStorage.d.ts +20 -0
  230. package/dist/src/utils/versionStorage.js +62 -0
  231. package/dist/src/utils/versionStorage.js.map +1 -1
  232. package/dist/tsconfig.tsbuildinfo +1 -1
  233. package/package.json +2 -2
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ // Cache for terminal background RGB to avoid re-detection
7
+ let cachedTerminalBgRgb = undefined;
8
+ /**
9
+ * Gets the cached terminal background RGB, or null if not yet detected.
10
+ * @returns Cached RGB tuple or null
11
+ */
12
+ export function getCachedTerminalBackgroundRgb() {
13
+ return cachedTerminalBgRgb ?? null;
14
+ }
15
+ /**
16
+ * Sets the cached terminal background RGB.
17
+ * @param rgb RGB tuple or null
18
+ */
19
+ export function setCachedTerminalBackgroundRgb(rgb) {
20
+ cachedTerminalBgRgb = rgb;
21
+ }
22
+ /**
23
+ * Detects if the terminal has a light or dark background.
24
+ * Uses OSC 11 escape sequence to query the terminal background color.
25
+ * This implementation writes directly to the TTY file descriptor to avoid
26
+ * any buffering or interference with stdin/stdout streams.
27
+ * @returns Promise that resolves to 'light' or 'dark', or null if detection fails
28
+ */
29
+ export async function detectTerminalBackground() {
30
+ // Check if we're in a TTY
31
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
32
+ return null;
33
+ }
34
+ return new Promise((resolve) => {
35
+ const timeout = setTimeout(() => {
36
+ cleanup();
37
+ resolve(null);
38
+ }, 100); // 100ms timeout
39
+ let response = '';
40
+ let resolved = false;
41
+ const stdinTTY = process.stdin;
42
+ const originalRawMode = stdinTTY.isRaw;
43
+ const onData = (data) => {
44
+ const chunk = data.toString();
45
+ response += chunk;
46
+ // OSC 11 response format: ESC ] 11 ; rgb:RRRR/GGGG/BBBB ESC \
47
+ // or: ESC ] 11 ; rgb:RR/GG/BB ESC \
48
+ // eslint-disable-next-line no-control-regex
49
+ const match = response.match(/\x1b\]11;rgb:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i);
50
+ if (match && !resolved) {
51
+ resolved = true;
52
+ clearTimeout(timeout);
53
+ // Parse RGB values (they can be 2 or 4 hex digits)
54
+ const r = parseInt(match[1].substring(0, 2), 16);
55
+ const g = parseInt(match[2].substring(0, 2), 16);
56
+ const b = parseInt(match[3].substring(0, 2), 16);
57
+ // Calculate relative luminance using the formula from WCAG
58
+ // https://www.w3.org/TR/WCAG20/#relativeluminancedef
59
+ const luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
60
+ const result = luminance > 0.5 ? 'light' : 'dark';
61
+ // Clean up immediately and resolve
62
+ cleanup();
63
+ resolve(result);
64
+ }
65
+ };
66
+ const cleanup = () => {
67
+ if (!process.stdin.isTTY) {
68
+ return;
69
+ }
70
+ try {
71
+ process.stdin.removeListener('data', onData);
72
+ // Immediately restore original raw mode state
73
+ process.stdin.setRawMode(originalRawMode);
74
+ // Don't pause - let the normal input system handle stdin
75
+ // The input system will set up its own listeners
76
+ }
77
+ catch (_err) {
78
+ // Ignore errors during cleanup
79
+ }
80
+ };
81
+ try {
82
+ // Set up stdin to receive the response
83
+ // Only modify stdin if it's in a valid state
84
+ if (process.stdin.isTTY && !process.stdin.destroyed) {
85
+ const wasPaused = process.stdin.isPaused();
86
+ process.stdin.setRawMode(true);
87
+ if (wasPaused) {
88
+ process.stdin.resume();
89
+ }
90
+ process.stdin.on('data', onData);
91
+ // Query the terminal background color using OSC 11
92
+ // Write directly to stdout to avoid any buffering issues
93
+ process.stdout.write('\x1b]11;?\x1b\\');
94
+ }
95
+ else {
96
+ cleanup();
97
+ resolve(null);
98
+ }
99
+ }
100
+ catch (_err) {
101
+ cleanup();
102
+ resolve(null);
103
+ }
104
+ });
105
+ }
106
+ /**
107
+ * Gets the actual RGB terminal background color.
108
+ * Uses OSC 11 escape sequence to query the terminal background color.
109
+ * @returns Promise that resolves to RGB tuple [r, g, b] or null if detection fails
110
+ */
111
+ export async function getTerminalBackgroundRgb() {
112
+ // Check if we're in a TTY
113
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
114
+ return null;
115
+ }
116
+ return new Promise((resolve) => {
117
+ const timeout = setTimeout(() => {
118
+ cleanup();
119
+ resolve(null);
120
+ }, 100); // 100ms timeout
121
+ let response = '';
122
+ let resolved = false;
123
+ const stdinTTY = process.stdin;
124
+ const originalRawMode = stdinTTY.isRaw;
125
+ const onData = (data) => {
126
+ const chunk = data.toString();
127
+ response += chunk;
128
+ // OSC 11 response format: ESC ] 11 ; rgb:RRRR/GGGG/BBBB ESC \
129
+ // or: ESC ] 11 ; rgb:RR/GG/BB ESC \
130
+ // Some terminals may send the response multiple times or with variations
131
+ // eslint-disable-next-line no-control-regex
132
+ const match = response.match(/\x1b\]11;rgb:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i);
133
+ if (match && !resolved) {
134
+ resolved = true;
135
+ clearTimeout(timeout);
136
+ // Parse RGB values (they can be 2 or 4 hex digits)
137
+ const r = parseInt(match[1].substring(0, 2), 16);
138
+ const g = parseInt(match[2].substring(0, 2), 16);
139
+ const b = parseInt(match[3].substring(0, 2), 16);
140
+ // Cache the result
141
+ cachedTerminalBgRgb = [r, g, b];
142
+ // Clean up immediately and resolve
143
+ cleanup();
144
+ resolve([r, g, b]);
145
+ }
146
+ };
147
+ const cleanup = () => {
148
+ if (!process.stdin.isTTY) {
149
+ return;
150
+ }
151
+ try {
152
+ process.stdin.removeListener('data', onData);
153
+ // Immediately restore original raw mode state
154
+ process.stdin.setRawMode(originalRawMode);
155
+ // Don't pause - let the normal input system handle stdin
156
+ // The input system will set up its own listeners
157
+ }
158
+ catch (_err) {
159
+ // Ignore errors during cleanup
160
+ }
161
+ };
162
+ try {
163
+ // Set up stdin to receive the response
164
+ // Only modify stdin if it's in a valid state
165
+ if (process.stdin.isTTY && !process.stdin.destroyed) {
166
+ const wasPaused = process.stdin.isPaused();
167
+ process.stdin.setRawMode(true);
168
+ if (wasPaused) {
169
+ process.stdin.resume();
170
+ }
171
+ process.stdin.on('data', onData);
172
+ // Query the terminal background color using OSC 11
173
+ // Write directly to stdout to avoid any buffering issues
174
+ process.stdout.write('\x1b]11;?\x1b\\');
175
+ }
176
+ else {
177
+ cleanup();
178
+ resolve(null);
179
+ }
180
+ }
181
+ catch (_err) {
182
+ cleanup();
183
+ resolve(null);
184
+ }
185
+ });
186
+ }
187
+ /**
188
+ * Gets the default theme name based on terminal background detection.
189
+ * Falls back to 'Blackbox Dark' if detection fails.
190
+ * @returns Promise that resolves to the theme name
191
+ */
192
+ export async function getDefaultThemeForTerminal() {
193
+ const background = await detectTerminalBackground();
194
+ if (background === 'light') {
195
+ return 'Blackbox Light';
196
+ }
197
+ // Default to dark theme if detection fails or background is dark
198
+ return 'Blackbox Dark';
199
+ }
200
+ //# sourceMappingURL=terminalBackgroundDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminalBackgroundDetector.js","sourceRoot":"","sources":["../../../../src/ui/utils/terminalBackgroundDetector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,0DAA0D;AAC1D,IAAI,mBAAmB,GAAgD,SAAS,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,8BAA8B;IAC5C,OAAO,mBAAmB,IAAI,IAAI,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAAC,GAAoC;IACjF,mBAAmB,GAAG,GAAG,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAEzB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAmB,CAAC;QAC7C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,KAAK,CAAC;YAElB,8DAA8D;YAC9D,oCAAoC;YACpC,4CAA4C;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAEpF,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBAEtB,mDAAmD;gBACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,2DAA2D;gBAC3D,qDAAqD;gBACrD,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAE/D,MAAM,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;gBAElD,mCAAmC;gBACnC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,8CAA8C;gBAC9C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBAC1C,yDAAyD;gBACzD,iDAAiD;YACnD,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,+BAA+B;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,uCAAuC;YACvC,6CAA6C;YAC7C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,mDAAmD;gBACnD,yDAAyD;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,IAAI,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAEzB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAmB,CAAC;QAC7C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,KAAK,CAAC;YAElB,8DAA8D;YAC9D,oCAAoC;YACpC,yEAAyE;YACzE,4CAA4C;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAEpF,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBAEtB,mDAAmD;gBACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,mBAAmB;gBACnB,mBAAmB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAEhC,mCAAmC;gBACnC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,8CAA8C;gBAC9C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBAC1C,yDAAyD;gBACzD,iDAAiD;YACnD,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,+BAA+B;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,uCAAuC;YACvC,6CAA6C;YAC7C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,mDAAmD;gBACnD,yDAAyD;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,IAAI,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,MAAM,UAAU,GAAG,MAAM,wBAAwB,EAAE,CAAC;IAEpD,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,iEAAiE;IACjE,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Blackbox
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { LoadedSettings } from '../config/settings.js';
7
+ export type AgentType = 'blackbox' | 'claude' | 'codex' | 'gemini';
8
+ /**
9
+ * Determines if an agent should use direct client integration vs CLI execution.
10
+ * Blackbox agent uses the existing Gemini client directly to reuse streaming, tools, and UI components.
11
+ * Other agents use CLI execution for their specific implementations.
12
+ */
13
+ export declare function shouldUseDirectClient(agentType: AgentType): boolean;
14
+ /**
15
+ * Options for building agent commands with multi-turn support
16
+ */
17
+ export interface AgentCommandOptions {
18
+ /** Session ID for multi-turn conversations (used by Claude CLI --resume) */
19
+ sessionId?: string;
20
+ /** Whether this is the first message in the session */
21
+ isFirstMessage?: boolean;
22
+ /** Past messages/conversation history to prepend to the instruction (for multi-turn) */
23
+ pastMessages?: string;
24
+ }
25
+ /**
26
+ * Builds the CLI command for the specified agent type.
27
+ * This is the single source of truth for agent command generation,
28
+ * used by both single agent and multi-agent systems.
29
+ *
30
+ * Note: For blackbox agent in single agent mode, direct client integration is preferred
31
+ * over CLI execution to reuse existing streaming and tool infrastructure.
32
+ */
33
+ export declare function buildAgentCommand(agentType: AgentType, model: string, task: string, options?: AgentCommandOptions, settings?: LoadedSettings): string;
34
+ /**
35
+ * Builds the enhanced Claude command with jq parsing for readable output.
36
+ * Used specifically in multi-agent scenarios for better output formatting.
37
+ */
38
+ export declare function buildClaudeCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
39
+ /**
40
+ * Builds the enhanced Codex command with jq parsing for readable output.
41
+ * Used specifically in multi-agent scenarios for better output formatting.
42
+ */
43
+ export declare function buildCodexCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
44
+ /**
45
+ * Builds the enhanced Gemini command with jq parsing for readable output.
46
+ * Used specifically in multi-agent scenarios for better output formatting.
47
+ */
48
+ export declare function buildGeminiCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
@@ -0,0 +1,328 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Blackbox
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { resolveOpenAIModel } from '@blackbox_ai/blackbox-cli-core';
7
+ import { getEffectiveApiKey } from './apiKeyUtils.js';
8
+ /**
9
+ * Determines if an agent should use direct client integration vs CLI execution.
10
+ * Blackbox agent uses the existing Gemini client directly to reuse streaming, tools, and UI components.
11
+ * Other agents use CLI execution for their specific implementations.
12
+ */
13
+ export function shouldUseDirectClient(agentType) {
14
+ return agentType === 'blackbox';
15
+ }
16
+ /**
17
+ * Builds the CLI command for the specified agent type.
18
+ * This is the single source of truth for agent command generation,
19
+ * used by both single agent and multi-agent systems.
20
+ *
21
+ * Note: For blackbox agent in single agent mode, direct client integration is preferred
22
+ * over CLI execution to reuse existing streaming and tool infrastructure.
23
+ */
24
+ export function buildAgentCommand(agentType, model, task, options, settings) {
25
+ // Escape single quotes in the task for shell safety
26
+ const escapedTask = task.replace(/'/g, "'\\''");
27
+ switch (agentType) {
28
+ case 'blackbox': {
29
+ // For multi-turn support: prepend past messages to the instruction
30
+ // This follows the remote-code approach which is simpler and more reliable
31
+ let finalInstruction = escapedTask;
32
+ if (options?.pastMessages) {
33
+ // Escape the past messages for shell safety
34
+ const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
35
+ finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
36
+ }
37
+ return `blackbox -p '${finalInstruction}' -y`;
38
+ }
39
+ case 'claude': {
40
+ const blackboxApiKey = getEffectiveApiKey('claude', settings);
41
+ if (!blackboxApiKey) {
42
+ throw new Error('BLACKBOX_API_KEY is required for Claude Code agent. Please run "/agent configure" to set up your API key.');
43
+ }
44
+ // For multi-turn support: prepend past messages to the instruction
45
+ // This follows the remote-code approach which is simpler and more reliable
46
+ let finalInstruction = escapedTask;
47
+ if (options?.pastMessages) {
48
+ // Escape the past messages for shell safety
49
+ const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
50
+ finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
51
+ }
52
+ return `ANTHROPIC_API_KEY="${blackboxApiKey}" ANTHROPIC_BASE_URL="https://api.blackbox.ai" claude --model "${model}" -p --output-format=stream-json --include-partial-messages --dangerously-skip-permissions --verbose '${finalInstruction}'`;
53
+ }
54
+ case 'codex': {
55
+ // Get effective API keys from both environment and settings
56
+ const blackboxApiKey = getEffectiveApiKey('blackbox', settings);
57
+ const openaiApiKey = getEffectiveApiKey('codex', settings);
58
+ // Resolve model to use Blackbox provider if available
59
+ const apiKeys = {
60
+ blackbox_api_key: blackboxApiKey,
61
+ openai_api_key: openaiApiKey
62
+ };
63
+ const resolved = resolveOpenAIModel(model, apiKeys);
64
+ if (!resolved.userApiKey) {
65
+ throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY is required for Codex agent. Please run "/agent configure" to set up your API key.');
66
+ }
67
+ // For multi-turn support: prepend past messages to the instruction
68
+ // This follows the remote-code approach which is simpler and more reliable
69
+ let finalInstruction = escapedTask;
70
+ if (options?.pastMessages) {
71
+ // Escape the past messages for shell safety
72
+ const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
73
+ finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
74
+ }
75
+ // Check if using Blackbox provider
76
+ if (resolved.selectedModel.startsWith('blackboxai/')) {
77
+ // Use the full Blackbox model name (e.g., blackboxai/openai/gpt-5.1)
78
+ const blackboxModel = resolved.selectedModel;
79
+ // Create config.toml for Blackbox provider
80
+ const configToml = `model = "${blackboxModel}"
81
+ model_provider = "blackbox-ai-gateway"
82
+
83
+ [shell_environment_policy]
84
+ ignore_default_excludes = true
85
+ inherit = "all"
86
+
87
+ [model_providers.blackbox-ai-gateway]
88
+ name = "BlackBox AI Gateway"
89
+ base_url = "https://api.blackbox.ai/v1"
90
+ env_key = "BLACKBOX_API_KEY"
91
+ wire_api = "chat"
92
+
93
+ [debug]
94
+ log_requests = true`;
95
+ // Use Blackbox provider with custom configuration
96
+ return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
97
+ ${configToml}
98
+ EOF
99
+ BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${finalInstruction}'`;
100
+ }
101
+ else {
102
+ // Create config.toml for OpenAI provider
103
+ const configToml = `model = "${resolved.selectedModel}"
104
+ model_provider = "openai"
105
+
106
+ [shell_environment_policy]
107
+ ignore_default_excludes = true
108
+ inherit = "all"
109
+
110
+ [model_providers.openai]
111
+ name = "OpenAI"
112
+ base_url = "https://api.openai.com/v1"
113
+ env_key = "OPENAI_API_KEY"
114
+ wire_api = "responses"
115
+
116
+ [debug]
117
+ log_requests = true`;
118
+ // Use original OpenAI provider with custom configuration
119
+ return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
120
+ ${configToml}
121
+ EOF
122
+ OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${finalInstruction}'`;
123
+ }
124
+ }
125
+ case 'gemini': {
126
+ const geminiApiKey = getEffectiveApiKey('gemini', settings);
127
+ if (!geminiApiKey) {
128
+ throw new Error('GEMINI_API_KEY is required for Gemini agent. Please run "/agent configure" to set up your API key.');
129
+ }
130
+ // For multi-turn support: prepend past messages to the instruction
131
+ // This follows the remote-code approach which is simpler and more reliable
132
+ let finalInstruction = escapedTask;
133
+ if (options?.pastMessages) {
134
+ // Escape the past messages for shell safety
135
+ const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
136
+ finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
137
+ }
138
+ return `GEMINI_API_KEY="${geminiApiKey}" gemini --model "${model}" --yolo '${finalInstruction}' --output-format stream-json`;
139
+ }
140
+ default:
141
+ throw new Error(`Unsupported agent type: ${agentType}`);
142
+ }
143
+ }
144
+ /**
145
+ * Builds the enhanced Claude command with jq parsing for readable output.
146
+ * Used specifically in multi-agent scenarios for better output formatting.
147
+ */
148
+ export function buildClaudeCommandWithJqParsing(model, task, outputFile, settings) {
149
+ const blackboxApiKey = getEffectiveApiKey('claude', settings);
150
+ if (!blackboxApiKey) {
151
+ throw new Error('BLACKBOX_API_KEY is required for Claude Code agent. Please run "/agent configure" to set up your API key.');
152
+ }
153
+ const escapedTask = task.replace(/'/g, "'\\''");
154
+ return `ANTHROPIC_API_KEY="${blackboxApiKey}" ANTHROPIC_BASE_URL="https://api.blackbox.ai" claude --model "${model}" -p --output-format=stream-json --dangerously-skip-permissions --verbose '${escapedTask}' 2>&1 | jq -r '
155
+ if .type == "assistant" and .message.content then
156
+ .message.content[] |
157
+ if .type == "text" then .text
158
+ elif .type == "tool_use" then
159
+ "+-------------------------------------------------------------+\\n" +
160
+ "| šŸ”§ TOOL USE: \\(.name)\\n" +
161
+ "+-------------------------------------------------------------+\\n" +
162
+ "| Input:\\n" +
163
+ ((.input | @json | split("\\n")) | map("| " + .) | join("\\n")) + "\\n" +
164
+ "+-------------------------------------------------------------+\\n"
165
+ else empty
166
+ end
167
+ elif .type == "user" and .message.content then
168
+ .message.content[] |
169
+ if .type == "tool_result" then
170
+ "\\n" +
171
+ ((.content | split("\\n")) as $lines |
172
+ if ($lines | length) > 10 then
173
+ ($lines[:10] | join("\\n")) + "\\n" +
174
+ "\\n... (\\($lines | length - 10) more lines hidden) ...\\n"
175
+ else
176
+ $lines | join("\\n")
177
+ end) +
178
+ "\\n"
179
+ else empty
180
+ end
181
+ else empty
182
+ end
183
+ ' > ${outputFile} 2>&1`;
184
+ }
185
+ /**
186
+ * Builds the enhanced Codex command with jq parsing for readable output.
187
+ * Used specifically in multi-agent scenarios for better output formatting.
188
+ */
189
+ export function buildCodexCommandWithJqParsing(model, task, outputFile, settings) {
190
+ // Get effective API keys from both environment and settings
191
+ const blackboxApiKey = getEffectiveApiKey('blackbox', settings);
192
+ const openaiApiKey = getEffectiveApiKey('codex', settings);
193
+ // Resolve model to use Blackbox provider if available
194
+ const apiKeys = {
195
+ blackbox_api_key: blackboxApiKey,
196
+ openai_api_key: openaiApiKey
197
+ };
198
+ const resolved = resolveOpenAIModel(model, apiKeys);
199
+ if (!resolved.userApiKey) {
200
+ throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY is required for Codex agent. Please run "/agent configure" to set up your API key.');
201
+ }
202
+ const escapedTask = task.replace(/'/g, "'\\''");
203
+ // Check if using Blackbox provider
204
+ if (resolved.selectedModel.startsWith('blackboxai/')) {
205
+ const blackboxModel = resolved.selectedModel;
206
+ // Create config.toml for Blackbox provider
207
+ const configToml = `model = "${blackboxModel}"
208
+ model_provider = "blackbox-ai-gateway"
209
+
210
+ [shell_environment_policy]
211
+ ignore_default_excludes = true
212
+ inherit = "all"
213
+
214
+ [model_providers.blackbox-ai-gateway]
215
+ name = "BlackBox AI Gateway"
216
+ base_url = "https://api.blackbox.ai/v1"
217
+ env_key = "BLACKBOX_API_KEY"
218
+ wire_api = "chat"
219
+
220
+ [debug]
221
+ log_requests = true`;
222
+ return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
223
+ ${configToml}
224
+ EOF
225
+ BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
226
+ if .type == "item.completed" and .item.type == "agent_message" then
227
+ .item.text
228
+ elif .type == "item.started" and .item.type == "command_execution" then
229
+ "\\nšŸ”§ EXECUTING: " + .item.command + "\\n"
230
+ elif .type == "item.completed" and .item.type == "command_execution" then
231
+ if .item.exit_code == 0 then
232
+ ((.item.aggregated_output | split("\\n")) as $lines |
233
+ if ($lines | length) > 20 then
234
+ ($lines[:20] | join("\\n")) + "\\n" +
235
+ "\\n... (\\($lines | length - 20) more lines hidden) ...\\n"
236
+ else
237
+ $lines | join("\\n")
238
+ end) + "\\n"
239
+ else
240
+ "āŒ Command failed with exit code: " + (.item.exit_code | tostring) + "\\n" + .item.aggregated_output + "\\n"
241
+ end
242
+ elif .type == "turn.started" then
243
+ "šŸš€ Starting Codex execution...\\n"
244
+ elif .type == "turn.completed" then
245
+ "āœ… Codex execution completed.\\n"
246
+ else empty
247
+ end
248
+ ' > ${outputFile} 2>&1`;
249
+ }
250
+ else {
251
+ // Create config.toml for OpenAI provider
252
+ const configToml = `model = "${resolved.selectedModel}"
253
+ model_provider = "openai"
254
+
255
+ [shell_environment_policy]
256
+ ignore_default_excludes = true
257
+ inherit = "all"
258
+
259
+ [model_providers.openai]
260
+ name = "OpenAI"
261
+ base_url = "https://api.openai.com/v1"
262
+ env_key = "OPENAI_API_KEY"
263
+ wire_api = "responses"
264
+
265
+ [debug]
266
+ log_requests = true`;
267
+ return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
268
+ ${configToml}
269
+ EOF
270
+ OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
271
+ if .type == "item.completed" and .item.type == "agent_message" then
272
+ .item.text
273
+ elif .type == "item.started" and .item.type == "command_execution" then
274
+ "\\nšŸ”§ EXECUTING: " + .item.command + "\\n"
275
+ elif .type == "item.completed" and .item.type == "command_execution" then
276
+ if .item.exit_code == 0 then
277
+ ((.item.aggregated_output | split("\\n")) as $lines |
278
+ if ($lines | length) > 20 then
279
+ ($lines[:20] | join("\\n")) + "\\n" +
280
+ "\\n... (\\($lines | length - 20) more lines hidden) ...\\n"
281
+ else
282
+ $lines | join("\\n")
283
+ end) + "\\n"
284
+ else
285
+ "āŒ Command failed with exit code: " + (.item.exit_code | tostring) + "\\n" + .item.aggregated_output + "\\n"
286
+ end
287
+ elif .type == "turn.started" then
288
+ "šŸš€ Starting Codex execution...\\n"
289
+ elif .type == "turn.completed" then
290
+ "āœ… Codex execution completed.\\n"
291
+ else empty
292
+ end
293
+ ' > ${outputFile} 2>&1`;
294
+ }
295
+ }
296
+ /**
297
+ * Builds the enhanced Gemini command with jq parsing for readable output.
298
+ * Used specifically in multi-agent scenarios for better output formatting.
299
+ */
300
+ export function buildGeminiCommandWithJqParsing(model, task, outputFile, settings) {
301
+ const geminiApiKey = getEffectiveApiKey('gemini', settings);
302
+ if (!geminiApiKey) {
303
+ throw new Error('GEMINI_API_KEY is required for Gemini agent. Please run "/agent configure" to set up your API key.');
304
+ }
305
+ const escapedTask = task.replace(/'/g, "'\\''");
306
+ return `GEMINI_API_KEY="${geminiApiKey}" gemini --model "${model}" --yolo '${escapedTask}' --output-format stream-json | jq -r '
307
+ def hr(n): ("─" * n);
308
+
309
+ def box(title; body):
310
+ "\\nā”Œ" + hr(78) + "┐\\n" +
311
+ "│ " + (title | ascii_upcase) + (" " * (77 - (title|length))) + "│\\n" +
312
+ "ā”œ" + hr(78) + "┤\\n" +
313
+ (body
314
+ | split("\\n")
315
+ | map("│ " + . + (" " * (77 - (. | length))))
316
+ | join("\\n")
317
+ ) +
318
+ "\\nā””" + hr(78) + "ā”˜";
319
+
320
+ if .type == "message" and .role == "assistant" then
321
+ box("assistant"; .content)
322
+ elif .type == "tool_use" then
323
+ box("tool call: " + .tool_name; "INPUT:\\n" + (.parameters | tojson))
324
+ elif .type == "tool_result" then
325
+ box("tool result"; "STATUS: " + .status + (if .output != null and .output != "" then "\\nOUTPUT:\\n" + .output else "" end))
326
+ else empty end' > ${outputFile} 2>&1`;
327
+ }
328
+ //# sourceMappingURL=agentCommandBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentCommandBuilder.js","sourceRoot":"","sources":["../../../src/utils/agentCommandBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Blackbox
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { AgentType } from '@blackbox_ai/blackbox-cli-core';
7
+ import type { LoadedSettings } from '../config/settings.js';
8
+ export interface ApiKeyInfo {
9
+ envVarName: string;
10
+ settingsPath: string;
11
+ displayName: string;
12
+ placeholder: string;
13
+ validator: (key: string) => boolean;
14
+ description: string;
15
+ }
16
+ /**
17
+ * Mapping of agent types to their API key requirements
18
+ */
19
+ export declare const AGENT_API_KEY_MAP: Record<AgentType, ApiKeyInfo>;
20
+ /**
21
+ * Check if an API key is available for the given agent type
22
+ * Checks both environment variables and settings
23
+ */
24
+ export declare function hasApiKeyForAgent(agentType: AgentType, settings?: LoadedSettings): boolean;
25
+ /**
26
+ * Get API key from settings for the given agent type
27
+ */
28
+ export declare function getApiKeyFromSettings(agentType: AgentType, settings: LoadedSettings): string | undefined;
29
+ /**
30
+ * Get the effective API key for an agent (env var takes precedence over settings)
31
+ */
32
+ export declare function getEffectiveApiKey(agentType: AgentType, settings?: LoadedSettings): string | undefined;
33
+ /**
34
+ * Save API key to settings for the given agent type
35
+ */
36
+ export declare function saveApiKeyToSettings(agentType: AgentType, apiKey: string, settings: LoadedSettings): void;
37
+ /**
38
+ * Get missing API key info for agents that don't have keys
39
+ */
40
+ export declare function getMissingApiKeyInfo(agentTypes: AgentType[], settings?: LoadedSettings): ApiKeyInfo[];
41
+ /**
42
+ * Validate API key format for a specific agent type
43
+ */
44
+ export declare function validateApiKey(agentType: AgentType, apiKey: string): {
45
+ valid: boolean;
46
+ error?: string;
47
+ };