aemeathcli 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +620 -609
  3. package/dist/{App-YAHJUWCX.js → App-NT6MRKQJ.js} +675 -169
  4. package/dist/App-NT6MRKQJ.js.map +1 -0
  5. package/dist/agent-store/architect.md +32 -32
  6. package/dist/agent-store/debugger.md +32 -32
  7. package/dist/agent-store/developer.md +29 -29
  8. package/dist/agent-store/documenter.md +30 -30
  9. package/dist/agent-store/researcher.md +31 -31
  10. package/dist/agent-store/reviewer.md +28 -28
  11. package/dist/agent-store/supervisor.md +37 -37
  12. package/dist/agent-store/tester.md +30 -30
  13. package/dist/api-key-fallback-RJLPM3KH.js +11 -0
  14. package/dist/{api-key-fallback-UN3TJEOO.js.map → api-key-fallback-RJLPM3KH.js.map} +1 -1
  15. package/dist/auth-status-JQJOKUPF.js +13 -0
  16. package/dist/{auth-status-EIM5A5KL.js.map → auth-status-JQJOKUPF.js.map} +1 -1
  17. package/dist/{chunk-P66WDACW.js → chunk-2KMA5RBC.js} +18 -42
  18. package/dist/chunk-2KMA5RBC.js.map +1 -0
  19. package/dist/{chunk-2GKOK6T7.js → chunk-2Y7TR6BS.js} +2 -2
  20. package/dist/chunk-2Y7TR6BS.js.map +1 -0
  21. package/dist/{chunk-ONQ4WCUI.js → chunk-2ZYK5IJG.js} +6 -6
  22. package/dist/chunk-2ZYK5IJG.js.map +1 -0
  23. package/dist/{chunk-OCJPQFOR.js → chunk-36RXCZOV.js} +4 -4
  24. package/dist/chunk-36RXCZOV.js.map +1 -0
  25. package/dist/{chunk-H2SYKIMI.js → chunk-7EBLXPL4.js} +10 -10
  26. package/dist/chunk-7EBLXPL4.js.map +1 -0
  27. package/dist/{chunk-IARA5XYP.js → chunk-BIMQL4AG.js} +4 -4
  28. package/dist/chunk-BIMQL4AG.js.map +1 -0
  29. package/dist/{chunk-BY4DAKUU.js → chunk-D275MCIH.js} +2 -2
  30. package/dist/chunk-D275MCIH.js.map +1 -0
  31. package/dist/{chunk-SOQFMNQC.js → chunk-FFS4T7BZ.js} +5 -5
  32. package/dist/chunk-FFS4T7BZ.js.map +1 -0
  33. package/dist/{chunk-LDVY5ELP.js → chunk-GXAJGP2T.js} +5 -5
  34. package/dist/chunk-GXAJGP2T.js.map +1 -0
  35. package/dist/{chunk-62HSGYQD.js → chunk-HCIHOHLX.js} +2 -2
  36. package/dist/chunk-HCIHOHLX.js.map +1 -0
  37. package/dist/{chunk-6GUD7QIM.js → chunk-HESQLCLU.js} +4 -4
  38. package/dist/chunk-HESQLCLU.js.map +1 -0
  39. package/dist/{chunk-HEKFAKVH.js → chunk-IR5HLBMH.js} +2 -2
  40. package/dist/chunk-IR5HLBMH.js.map +1 -0
  41. package/dist/{chunk-2LF7ALGR.js → chunk-K2FCMRXH.js} +4 -4
  42. package/dist/chunk-K2FCMRXH.js.map +1 -0
  43. package/dist/{chunk-2NWNIKBK.js → chunk-KIC7UI5U.js} +4 -4
  44. package/dist/chunk-KIC7UI5U.js.map +1 -0
  45. package/dist/{chunk-YPFOE2QJ.js → chunk-KMOAJRDE.js} +5 -5
  46. package/dist/chunk-KMOAJRDE.js.map +1 -0
  47. package/dist/{chunk-RP2TAL3J.js → chunk-LQBALETG.js} +2 -2
  48. package/dist/chunk-LQBALETG.js.map +1 -0
  49. package/dist/{chunk-CC7MGWYY.js → chunk-M3FPQSRU.js} +2 -2
  50. package/dist/chunk-M3FPQSRU.js.map +1 -0
  51. package/dist/{chunk-3TSPZRGM.js → chunk-NQEUK763.js} +3 -3
  52. package/dist/chunk-NQEUK763.js.map +1 -0
  53. package/dist/{chunk-VBLLDY4R.js → chunk-OPWAFS6Y.js} +2 -2
  54. package/dist/chunk-OPWAFS6Y.js.map +1 -0
  55. package/dist/{chunk-RYOB3TLZ.js → chunk-PS4WEFW6.js} +6 -6
  56. package/dist/chunk-PS4WEFW6.js.map +1 -0
  57. package/dist/{chunk-LCYH4T6N.js → chunk-QK7TKNHV.js} +6 -6
  58. package/dist/chunk-QK7TKNHV.js.map +1 -0
  59. package/dist/{chunk-QCRK4QEL.js → chunk-RADJSEG5.js} +3 -3
  60. package/dist/chunk-RADJSEG5.js.map +1 -0
  61. package/dist/{chunk-AQ23TYSQ.js → chunk-SNWPI6XJ.js} +4 -4
  62. package/dist/chunk-SNWPI6XJ.js.map +1 -0
  63. package/dist/{chunk-TDFTX32B.js → chunk-UM7MSLOV.js} +4 -4
  64. package/dist/chunk-UM7MSLOV.js.map +1 -0
  65. package/dist/{chunk-FIC7AK4Q.js → chunk-VNZ3YTQD.js} +5 -5
  66. package/dist/chunk-VNZ3YTQD.js.map +1 -0
  67. package/dist/{chunk-5XFSV6PF.js → chunk-WXIN65UG.js} +6 -6
  68. package/dist/chunk-WXIN65UG.js.map +1 -0
  69. package/dist/{chunk-WC72BRHR.js → chunk-XEXWX7C7.js} +3 -3
  70. package/dist/chunk-XEXWX7C7.js.map +1 -0
  71. package/dist/{chunk-VJNQJALF.js → chunk-YCCYXDW7.js} +4 -4
  72. package/dist/chunk-YCCYXDW7.js.map +1 -0
  73. package/dist/{chunk-ROJPFPJ7.js → chunk-YL5XFHR3.js} +2 -2
  74. package/dist/chunk-YL5XFHR3.js.map +1 -0
  75. package/dist/{chunk-GU33WKPG.js → chunk-YPQ2MLAV.js} +5 -5
  76. package/dist/chunk-YPQ2MLAV.js.map +1 -0
  77. package/dist/{chunk-WAYSJMPS.js → chunk-ZCOVMVK4.js} +2 -2
  78. package/dist/chunk-ZCOVMVK4.js.map +1 -0
  79. package/dist/{chunk-473JN6M5.js → chunk-ZGOHARPV.js} +2 -2
  80. package/dist/chunk-ZGOHARPV.js.map +1 -0
  81. package/dist/{claude-login-IS5WTBMP.js → claude-login-AIFIWTYF.js} +10 -10
  82. package/dist/claude-login-AIFIWTYF.js.map +1 -0
  83. package/dist/cli.js +30 -30
  84. package/dist/cli.js.map +1 -1
  85. package/dist/{codex-login-GMPF64MR.js → codex-login-LW5X7GAM.js} +10 -10
  86. package/dist/codex-login-LW5X7GAM.js.map +1 -0
  87. package/dist/config-store-NF56VHFU.js +7 -0
  88. package/dist/{config-store-POB6I37G.js.map → config-store-NF56VHFU.js.map} +1 -1
  89. package/dist/conversation-store-7GRDQZD2.js +4 -0
  90. package/dist/{conversation-store-PRBHWQMJ.js.map → conversation-store-7GRDQZD2.js.map} +1 -1
  91. package/dist/detect-providers-QICJ5U3R.js +4 -0
  92. package/dist/{detect-providers-C4SVQHFF.js.map → detect-providers-QICJ5U3R.js.map} +1 -1
  93. package/dist/executor-FTABX2AW.js +4 -0
  94. package/dist/{executor-RUX7VK3T.js.map → executor-FTABX2AW.js.map} +1 -1
  95. package/dist/{first-run-GDEVRFPO.js → first-run-ADROZVYF.js} +13 -13
  96. package/dist/first-run-ADROZVYF.js.map +1 -0
  97. package/dist/{gemini-login-KE224MSW.js → gemini-login-TST454MX.js} +10 -10
  98. package/dist/gemini-login-TST454MX.js.map +1 -0
  99. package/dist/index.d.ts +2 -56
  100. package/dist/index.js +30 -34
  101. package/dist/index.js.map +1 -1
  102. package/dist/{input-history-MIOO3FIW.js → input-history-BEICE7PT.js} +3 -3
  103. package/dist/input-history-BEICE7PT.js.map +1 -0
  104. package/dist/kimi-adapter-7FYOAKOI.js +6 -0
  105. package/dist/{kimi-adapter-UODMNX6K.js.map → kimi-adapter-7FYOAKOI.js.map} +1 -1
  106. package/dist/{kimi-login-DNT5YBKX.js → kimi-login-3IGVOBJI.js} +10 -10
  107. package/dist/kimi-login-3IGVOBJI.js.map +1 -0
  108. package/dist/logger-KGHUQ4VE.js +3 -0
  109. package/dist/{logger-PLPDWACQ.js.map → logger-KGHUQ4VE.js.map} +1 -1
  110. package/dist/model-discovery-AAJDHRFO.js +6 -0
  111. package/dist/{model-discovery-O64ZWPX5.js.map → model-discovery-AAJDHRFO.js.map} +1 -1
  112. package/dist/native-cli-adapters-CLONTZOA.js +8 -0
  113. package/dist/{native-cli-adapters-JMZX2C2C.js.map → native-cli-adapters-CLONTZOA.js.map} +1 -1
  114. package/dist/ollama-adapter-2N5OQIEV.js +5 -0
  115. package/dist/{ollama-adapter-GE67BNSS.js.map → ollama-adapter-2N5OQIEV.js.map} +1 -1
  116. package/dist/{pathResolver-A6IXQQFE.js → pathResolver-UVAB2FCW.js} +3 -3
  117. package/dist/{pathResolver-A6IXQQFE.js.map → pathResolver-UVAB2FCW.js.map} +1 -1
  118. package/dist/{profile-loader-TNAXBLDX.js → profile-loader-EMLV4J7S.js} +4 -4
  119. package/dist/profile-loader-EMLV4J7S.js.map +1 -0
  120. package/dist/registry-LRURZVUL.js +5 -0
  121. package/dist/{registry-3NHVCXCZ.js.map → registry-LRURZVUL.js.map} +1 -1
  122. package/dist/registry-MVNSXCEF.js +6 -0
  123. package/dist/{registry-7CQ3NCAD.js.map → registry-MVNSXCEF.js.map} +1 -1
  124. package/dist/server-manager-THGZBBZB.js +5 -0
  125. package/dist/{server-manager-DES23IBQ.js.map → server-manager-THGZBBZB.js.map} +1 -1
  126. package/dist/session-manager-X3DXT53M.js +12 -0
  127. package/dist/{session-manager-EHD7GWM2.js.map → session-manager-X3DXT53M.js.map} +1 -1
  128. package/dist/skills/built-in/code-review/SKILL.md +85 -85
  129. package/dist/skills/built-in/commit/SKILL.md +83 -83
  130. package/dist/skills/built-in/debug/SKILL.md +119 -119
  131. package/dist/skills/built-in/plan/SKILL.md +123 -123
  132. package/dist/skills/built-in/refactor/SKILL.md +132 -132
  133. package/dist/skills/built-in/test/SKILL.md +128 -128
  134. package/dist/sqlite-store-7OECRTXM.js +5 -0
  135. package/dist/{sqlite-store-7ZIVOUNI.js.map → sqlite-store-7OECRTXM.js.map} +1 -1
  136. package/dist/team-manager-2VSMALAA.js +11 -0
  137. package/dist/{team-manager-6DCNLGTC.js.map → team-manager-2VSMALAA.js.map} +1 -1
  138. package/dist/team-state-HZNVMQHT.js +3 -0
  139. package/dist/{team-state-R2D7DT5M.js.map → team-state-HZNVMQHT.js.map} +1 -1
  140. package/dist/tmux-manager-57QCUVHU.js +6 -0
  141. package/dist/{tmux-manager-WBKHUHDT.js.map → tmux-manager-57QCUVHU.js.map} +1 -1
  142. package/dist/tools-KWFSYT56.js +6 -0
  143. package/dist/{tools-I6XCTEZY.js.map → tools-KWFSYT56.js.map} +1 -1
  144. package/package.json +89 -93
  145. package/dist/App-YAHJUWCX.js.map +0 -1
  146. package/dist/api-key-fallback-UN3TJEOO.js +0 -11
  147. package/dist/auth-status-EIM5A5KL.js +0 -13
  148. package/dist/chunk-25UNNEHN.js +0 -140
  149. package/dist/chunk-25UNNEHN.js.map +0 -1
  150. package/dist/chunk-2GKOK6T7.js.map +0 -1
  151. package/dist/chunk-2LF7ALGR.js.map +0 -1
  152. package/dist/chunk-2NWNIKBK.js.map +0 -1
  153. package/dist/chunk-3TSPZRGM.js.map +0 -1
  154. package/dist/chunk-473JN6M5.js.map +0 -1
  155. package/dist/chunk-5XFSV6PF.js.map +0 -1
  156. package/dist/chunk-62HSGYQD.js.map +0 -1
  157. package/dist/chunk-6GUD7QIM.js.map +0 -1
  158. package/dist/chunk-AQ23TYSQ.js.map +0 -1
  159. package/dist/chunk-BY4DAKUU.js.map +0 -1
  160. package/dist/chunk-CC7MGWYY.js.map +0 -1
  161. package/dist/chunk-CTFZTARK.js +0 -155
  162. package/dist/chunk-CTFZTARK.js.map +0 -1
  163. package/dist/chunk-FIC7AK4Q.js.map +0 -1
  164. package/dist/chunk-GU33WKPG.js.map +0 -1
  165. package/dist/chunk-H2SYKIMI.js.map +0 -1
  166. package/dist/chunk-HEKFAKVH.js.map +0 -1
  167. package/dist/chunk-IARA5XYP.js.map +0 -1
  168. package/dist/chunk-LCYH4T6N.js.map +0 -1
  169. package/dist/chunk-LDVY5ELP.js.map +0 -1
  170. package/dist/chunk-OCJPQFOR.js.map +0 -1
  171. package/dist/chunk-ODBY7S4X.js +0 -141
  172. package/dist/chunk-ODBY7S4X.js.map +0 -1
  173. package/dist/chunk-ONQ4WCUI.js.map +0 -1
  174. package/dist/chunk-P5TKZM3T.js +0 -159
  175. package/dist/chunk-P5TKZM3T.js.map +0 -1
  176. package/dist/chunk-P66WDACW.js.map +0 -1
  177. package/dist/chunk-QCRK4QEL.js.map +0 -1
  178. package/dist/chunk-ROJPFPJ7.js.map +0 -1
  179. package/dist/chunk-RP2TAL3J.js.map +0 -1
  180. package/dist/chunk-RYOB3TLZ.js.map +0 -1
  181. package/dist/chunk-SOQFMNQC.js.map +0 -1
  182. package/dist/chunk-TDFTX32B.js.map +0 -1
  183. package/dist/chunk-VBLLDY4R.js.map +0 -1
  184. package/dist/chunk-VJNQJALF.js.map +0 -1
  185. package/dist/chunk-WAYSJMPS.js.map +0 -1
  186. package/dist/chunk-WC72BRHR.js.map +0 -1
  187. package/dist/chunk-YPFOE2QJ.js.map +0 -1
  188. package/dist/claude-adapter-6P4SJH7P.js +0 -7
  189. package/dist/claude-adapter-6P4SJH7P.js.map +0 -1
  190. package/dist/claude-login-IS5WTBMP.js.map +0 -1
  191. package/dist/codex-login-GMPF64MR.js.map +0 -1
  192. package/dist/config-store-POB6I37G.js +0 -7
  193. package/dist/conversation-store-PRBHWQMJ.js +0 -4
  194. package/dist/detect-providers-C4SVQHFF.js +0 -4
  195. package/dist/executor-RUX7VK3T.js +0 -4
  196. package/dist/first-run-GDEVRFPO.js.map +0 -1
  197. package/dist/gemini-adapter-MV3U4QFH.js +0 -7
  198. package/dist/gemini-adapter-MV3U4QFH.js.map +0 -1
  199. package/dist/gemini-login-KE224MSW.js.map +0 -1
  200. package/dist/input-history-MIOO3FIW.js.map +0 -1
  201. package/dist/kimi-adapter-UODMNX6K.js +0 -6
  202. package/dist/kimi-login-DNT5YBKX.js.map +0 -1
  203. package/dist/logger-PLPDWACQ.js +0 -3
  204. package/dist/model-discovery-O64ZWPX5.js +0 -6
  205. package/dist/native-cli-adapters-JMZX2C2C.js +0 -8
  206. package/dist/ollama-adapter-GE67BNSS.js +0 -5
  207. package/dist/openai-adapter-SHPLK77L.js +0 -7
  208. package/dist/openai-adapter-SHPLK77L.js.map +0 -1
  209. package/dist/profile-loader-TNAXBLDX.js.map +0 -1
  210. package/dist/registry-3NHVCXCZ.js +0 -6
  211. package/dist/registry-7CQ3NCAD.js +0 -5
  212. package/dist/server-manager-DES23IBQ.js +0 -5
  213. package/dist/session-manager-EHD7GWM2.js +0 -12
  214. package/dist/sqlite-store-7ZIVOUNI.js +0 -5
  215. package/dist/team-manager-6DCNLGTC.js +0 -11
  216. package/dist/team-state-R2D7DT5M.js +0 -3
  217. package/dist/tmux-manager-WBKHUHDT.js +0 -6
  218. package/dist/tools-I6XCTEZY.js +0 -6
@@ -1,49 +1,28 @@
1
- import { getCliProviderEntry, getCliProviderForModelProvider } from './chunk-RP2TAL3J.js';
2
- import { getActiveTeamName, getActiveTeamManager, getActiveTmuxCleanup, setActiveTmuxCleanup, setActiveTeamManager, setActiveTeamName } from './chunk-WAYSJMPS.js';
3
- import { CostTracker } from './chunk-ONQ4WCUI.js';
4
- import { getEventBus } from './chunk-ROJPFPJ7.js';
5
- import { createModelRouter } from './chunk-GU33WKPG.js';
6
- import { formatCost, formatTokenCount } from './chunk-VJNQJALF.js';
7
- import './chunk-VBLLDY4R.js';
8
- import { DEFAULT_CONFIG, PACKAGE_VERSION } from './chunk-2GKOK6T7.js';
9
- import './chunk-473JN6M5.js';
10
- import { getThinkingConfigForModel, SUPPORTED_MODELS, PROVIDER_MODEL_ORDER } from './chunk-62HSGYQD.js';
11
- import './chunk-HEKFAKVH.js';
12
- import './chunk-BY4DAKUU.js';
1
+ import { getCliProviderEntry, getCliProviderForModelProvider } from './chunk-LQBALETG.js';
2
+ import { getActiveTeamName, getActiveTeamManager, getActiveTmuxCleanup, setActiveTmuxCleanup, setActiveTeamManager, setActiveTeamName } from './chunk-ZCOVMVK4.js';
3
+ import { CostTracker } from './chunk-2ZYK5IJG.js';
4
+ import { getEventBus } from './chunk-YL5XFHR3.js';
5
+ import { createModelRouter } from './chunk-YPQ2MLAV.js';
6
+ import { formatCost, formatTokenCount } from './chunk-YCCYXDW7.js';
7
+ import './chunk-OPWAFS6Y.js';
8
+ import './chunk-ZGOHARPV.js';
9
+ import { getThinkingConfigForModel, SUPPORTED_MODELS, PROVIDER_MODEL_ORDER } from './chunk-HCIHOHLX.js';
10
+ import { DEFAULT_CONFIG, PACKAGE_VERSION } from './chunk-2Y7TR6BS.js';
11
+ import './chunk-IR5HLBMH.js';
12
+ import './chunk-D275MCIH.js';
13
13
  import React11, { useRef, useState, useCallback, useEffect, useMemo, startTransition } from 'react';
14
- import { Box, Text, render, useInput } from 'ink';
14
+ import { Box, Text, render, useInput, useStdout } from 'ink';
15
15
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
16
16
  import { randomUUID } from 'crypto';
17
17
 
18
18
  // src/ui/theme.ts
19
19
  var BRAND_COLOR = "#F0C5DA";
20
20
  var colors = {
21
- text: {
22
- primary: "#F9F5F5",
23
- secondary: "#d3acb3",
24
- muted: "#9e8085",
25
- accent: "#F0C5DA",
26
- response: "#F9F5F5"
27
- },
28
- border: {
29
- dim: "#6b5459",
30
- active: "#d3acb3"},
31
- syntax: {
32
- keyword: "#F0C5DA",
33
- string: "#EDD6DC"},
34
- status: {
35
- success: "#F0C5DA",
36
- error: "#f87171",
37
- warning: "#EDD6DC",
38
- info: "#F0C5DA",
39
- active: "#F0C5DA"
40
- },
41
- role: {
42
- user: "#F0C5DA",
43
- assistant: "#F9F5F5",
44
- system: "#EDD6DC",
45
- tool: "#d3acb3"
46
- }
21
+ text: { primary: "#F9F5F5", secondary: "#d3acb3", muted: "#9e8085", accent: "#F0C5DA", response: "#F9F5F5" },
22
+ border: { dim: "#6b5459", active: "#d3acb3"},
23
+ syntax: { keyword: "#F0C5DA", string: "#EDD6DC"},
24
+ status: { success: "#F0C5DA", error: "#f87171", warning: "#EDD6DC", info: "#F0C5DA", active: "#F0C5DA" },
25
+ role: { user: "#F0C5DA", assistant: "#F9F5F5", system: "#EDD6DC", tool: "#d3acb3" }
47
26
  };
48
27
  function parseBlocks(raw) {
49
28
  const blocks = [];
@@ -180,12 +159,24 @@ function InlineMarkdown({
180
159
  }
181
160
  const linkMatch = remaining.match(/^\[([^\]]+)\]\(([^)]+)\)/);
182
161
  if (linkMatch) {
162
+ const linkLabel = linkMatch[1] ?? "";
163
+ const linkUrl = linkMatch[2] ?? "";
164
+ const isLocalPath = linkUrl.startsWith("/") || linkUrl.startsWith("./") || linkUrl.startsWith("../");
165
+ const displayText = isLocalPath ? linkUrl : linkLabel;
183
166
  segments.push(
184
- /* @__PURE__ */ jsx(Text, { color: colors.status.info, underline: true, children: linkMatch[1] }, key++)
167
+ /* @__PURE__ */ jsx(Text, { color: colors.status.info, underline: true, children: displayText }, key++)
185
168
  );
186
169
  remaining = remaining.slice(linkMatch[0].length);
187
170
  continue;
188
171
  }
172
+ const bareUrlMatch = remaining.match(/^(https?:\/\/[^\s)>\]]+)/);
173
+ if (bareUrlMatch) {
174
+ segments.push(
175
+ /* @__PURE__ */ jsx(Text, { color: colors.status.info, underline: true, children: bareUrlMatch[1] }, key++)
176
+ );
177
+ remaining = remaining.slice(bareUrlMatch[0].length);
178
+ continue;
179
+ }
189
180
  const nextSpecial = remaining.search(/[[*`~]/);
190
181
  if (nextSpecial === -1) {
191
182
  segments.push(/* @__PURE__ */ jsx(Text, { children: remaining }, key++));
@@ -367,6 +358,96 @@ function useAnimationTick(intervalMs, enabled = true) {
367
358
  }, [enabled, intervalMs]);
368
359
  return tick;
369
360
  }
361
+
362
+ // src/ui/shimmer.ts
363
+ var DEFAULT_PERIOD_MS = 2e3;
364
+ var BAND_WIDTH = 10;
365
+ var MAX_INTENSITY = 0.9;
366
+ var trueColorCached;
367
+ function supportsTrueColor() {
368
+ if (trueColorCached === void 0) {
369
+ const ct = process.env["COLORTERM"] ?? "";
370
+ trueColorCached = ct === "truecolor" || ct === "24bit";
371
+ }
372
+ return trueColorCached;
373
+ }
374
+ function parseHex(hex) {
375
+ let raw = hex.startsWith("#") ? hex.slice(1) : hex;
376
+ if (raw.length === 3) {
377
+ const c0 = raw[0] ?? "f";
378
+ const c1 = raw[1] ?? "f";
379
+ const c2 = raw[2] ?? "f";
380
+ raw = c0 + c0 + c1 + c1 + c2 + c2;
381
+ }
382
+ if (raw.length !== 6) return [255, 255, 255];
383
+ const n = parseInt(raw, 16);
384
+ if (Number.isNaN(n)) return [255, 255, 255];
385
+ return [n >> 16 & 255, n >> 8 & 255, n & 255];
386
+ }
387
+ function toHex(r, g, b) {
388
+ const c = (v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, "0");
389
+ return "#" + c(r) + c(g) + c(b);
390
+ }
391
+ function blendChannel(base, intensity) {
392
+ return base + (255 - base) * intensity;
393
+ }
394
+ function shimmerIntensity(charIndex, totalLength, periodMs = DEFAULT_PERIOD_MS) {
395
+ const totalWidth = totalLength + BAND_WIDTH;
396
+ const progress = Date.now() % periodMs / periodMs;
397
+ const bandCenter = progress * totalWidth;
398
+ const distance = Math.abs(charIndex - bandCenter) / (totalWidth / 2);
399
+ return Math.max(0, Math.cos(distance * (Math.PI / 2))) * MAX_INTENSITY;
400
+ }
401
+ function shimmerText(text, baseColor) {
402
+ const len = text.length;
403
+ const trueColor = supportsTrueColor();
404
+ const [br, bg, bb] = parseHex(baseColor);
405
+ const result = [];
406
+ for (let i = 0; i < len; i++) {
407
+ const intensity = shimmerIntensity(i, len);
408
+ if (trueColor) {
409
+ const color = toHex(
410
+ blendChannel(br, intensity),
411
+ blendChannel(bg, intensity),
412
+ blendChannel(bb, intensity)
413
+ );
414
+ const ch = text[i] ?? " ";
415
+ result.push({ char: ch, intensity, color, bold: false, dim: false });
416
+ } else {
417
+ const bold = intensity > 0.6;
418
+ const dim = intensity <= 0.1;
419
+ const ch = text[i] ?? " ";
420
+ result.push({ char: ch, intensity, color: baseColor, bold, dim });
421
+ }
422
+ }
423
+ return result;
424
+ }
425
+ function shimmerToInkSpans(text, baseColor) {
426
+ const chars = shimmerText(text, baseColor);
427
+ if (chars.length === 0) return [];
428
+ const spans = [];
429
+ const first = chars[0];
430
+ if (first === void 0) return [];
431
+ let curText = first.char;
432
+ let curColor = first.color;
433
+ let curBold = first.bold;
434
+ let curDim = first.dim;
435
+ for (let i = 1; i < chars.length; i++) {
436
+ const ch = chars[i];
437
+ if (ch === void 0) continue;
438
+ if (ch.color === curColor && ch.bold === curBold && ch.dim === curDim) {
439
+ curText += ch.char;
440
+ } else {
441
+ spans.push({ text: curText, color: curColor, bold: curBold, dim: curDim });
442
+ curText = ch.char;
443
+ curColor = ch.color;
444
+ curBold = ch.bold;
445
+ curDim = ch.dim;
446
+ }
447
+ }
448
+ spans.push({ text: curText, color: curColor, bold: curBold, dim: curDim });
449
+ return spans;
450
+ }
370
451
  var SPINNER_VARIANTS = {
371
452
  dots: {
372
453
  frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
@@ -389,11 +470,13 @@ var SPINNER_VARIANTS = {
389
470
  interval: 120
390
471
  }
391
472
  };
473
+ var SHIMMER_INTERVAL_MS = 32;
392
474
  function GradientSpinner({
393
475
  label,
394
476
  labelColor = "#888888",
395
477
  variant = "dots",
396
- speed
478
+ speed,
479
+ shimmer = false
397
480
  }) {
398
481
  const spinnerDef = SPINNER_VARIANTS[variant] ?? SPINNER_VARIANTS["dots"];
399
482
  if (!spinnerDef) {
@@ -401,10 +484,27 @@ function GradientSpinner({
401
484
  }
402
485
  const interval = speed ?? spinnerDef.interval;
403
486
  const tick = useAnimationTick(interval);
487
+ useAnimationTick(SHIMMER_INTERVAL_MS, shimmer && label !== void 0 && label.length > 0);
404
488
  const frame = tick % spinnerDef.frames.length;
489
+ const shimmerSpans = useMemo(() => {
490
+ if (!shimmer || !label) return null;
491
+ return shimmerToInkSpans(label, labelColor);
492
+ }, [shimmer, label, labelColor, tick]);
405
493
  return /* @__PURE__ */ jsxs(Text, { children: [
406
494
  /* @__PURE__ */ jsx(Text, { color: BRAND_COLOR, children: spinnerDef.frames[frame] }),
407
- label ? /* @__PURE__ */ jsxs(Text, { color: labelColor, children: [
495
+ label ? shimmerSpans ? /* @__PURE__ */ jsxs(Text, { children: [
496
+ " ",
497
+ shimmerSpans.map((span, i) => /* @__PURE__ */ jsx(
498
+ Text,
499
+ {
500
+ color: span.color,
501
+ bold: span.bold,
502
+ dimColor: span.dim,
503
+ children: span.text
504
+ },
505
+ i
506
+ ))
507
+ ] }) : /* @__PURE__ */ jsxs(Text, { color: labelColor, children: [
408
508
  " ",
409
509
  label
410
510
  ] }) : null
@@ -428,31 +528,62 @@ function StatusIcon({
428
528
  }
429
529
  function formatDuration(ms) {
430
530
  if (ms < 1e3) return `${ms}ms`;
431
- return `${(ms / 1e3).toFixed(1)}s`;
531
+ const totalSec = Math.floor(ms / 1e3);
532
+ if (totalSec < 60) {
533
+ const frac = ms % 1e3;
534
+ return frac >= 100 ? `${(ms / 1e3).toFixed(1)}s` : `${totalSec}s`;
535
+ }
536
+ const minutes = Math.floor(totalSec / 60);
537
+ const seconds = totalSec % 60;
538
+ if (minutes < 60) {
539
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
540
+ }
541
+ const hours = Math.floor(minutes / 60);
542
+ const remainMin = minutes % 60;
543
+ return seconds > 0 ? `${hours}h ${remainMin}m ${seconds}s` : `${hours}h ${remainMin}m`;
432
544
  }
545
+ var TOOL_ICONS = {
546
+ read: "\u{1F4C4}",
547
+ write: "\u270F\uFE0F",
548
+ edit: "\u{1F4DD}",
549
+ glob: "\u{1F50D}",
550
+ grep: "\u{1F50E}",
551
+ bash: "\u26A1",
552
+ web_search: "\u{1F310}",
553
+ webSearch: "\u{1F310}",
554
+ web_fetch: "\u{1F4E1}",
555
+ webFetch: "\u{1F4E1}"
556
+ };
433
557
  function getToolIcon(name) {
434
- switch (name) {
435
- case "read":
436
- return "\u{1F4C4}";
437
- case "write":
438
- return "\u270F\uFE0F";
439
- case "edit":
440
- return "\u{1F4DD}";
441
- case "glob":
442
- return "\u{1F50D}";
443
- case "grep":
444
- return "\u{1F50E}";
445
- case "bash":
446
- return "\u26A1";
447
- case "web_search":
448
- case "webSearch":
449
- return "\u{1F310}";
450
- case "web_fetch":
451
- case "webFetch":
452
- return "\u{1F4E1}";
453
- default:
454
- return "\u2699";
558
+ return TOOL_ICONS[name] ?? "\u2699";
559
+ }
560
+ var HEAD_LINES = 5;
561
+ var TAIL_LINES = 2;
562
+ function formatOutputLines(raw) {
563
+ const allLines = raw.split("\n");
564
+ if (allLines.length > 0 && allLines[allLines.length - 1] === "") {
565
+ allLines.pop();
566
+ }
567
+ const total = allLines.length;
568
+ if (total <= HEAD_LINES + TAIL_LINES) {
569
+ return allLines.map((line, i) => {
570
+ const prefix = i === 0 ? " \u2514 " : " ";
571
+ return `${prefix}${line}`;
572
+ });
455
573
  }
574
+ const head = allLines.slice(0, HEAD_LINES);
575
+ const tail = allLines.slice(total - TAIL_LINES);
576
+ const omitted = total - HEAD_LINES - TAIL_LINES;
577
+ const result = [];
578
+ head.forEach((line, i) => {
579
+ const prefix = i === 0 ? " \u2514 " : " ";
580
+ result.push(`${prefix}${line}`);
581
+ });
582
+ result.push(` \u2026 +${omitted} lines`);
583
+ tail.forEach((line) => {
584
+ result.push(` ${line}`);
585
+ });
586
+ return result;
456
587
  }
457
588
  function ToolCallDisplay({
458
589
  toolName,
@@ -463,7 +594,6 @@ function ToolCallDisplay({
463
594
  duration,
464
595
  isCollapsed = true
465
596
  }) {
466
- const borderColor = status === "error" ? colors.status.error : status === "executing" ? colors.status.active : colors.border.dim;
467
597
  const icon = getToolIcon(toolName);
468
598
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 0, children: [
469
599
  /* @__PURE__ */ jsxs(Box, { children: [
@@ -485,28 +615,16 @@ function ToolCallDisplay({
485
615
  ")"
486
616
  ] }) : null
487
617
  ] }),
488
- !isCollapsed && output ? /* @__PURE__ */ jsx(
489
- Box,
618
+ !isCollapsed && output ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: formatOutputLines(output).map((line, i) => /* @__PURE__ */ jsx(
619
+ Text,
490
620
  {
491
- flexDirection: "column",
492
- marginLeft: 2,
493
- borderStyle: "single",
494
- borderLeft: true,
495
- borderRight: false,
496
- borderTop: false,
497
- borderBottom: false,
498
- borderColor,
499
- paddingLeft: 1,
500
- children: /* @__PURE__ */ jsx(
501
- Text,
502
- {
503
- wrap: "wrap",
504
- color: isError ? colors.status.error : colors.text.secondary,
505
- children: output.length > 2e3 ? output.slice(0, 2e3) + "\n\u2026 (truncated)" : output
506
- }
507
- )
508
- }
509
- ) : null
621
+ wrap: "truncate",
622
+ dimColor: true,
623
+ color: isError ? colors.status.error : colors.text.secondary,
624
+ children: line
625
+ },
626
+ i
627
+ )) }) : null
510
628
  ] });
511
629
  }
512
630
  function getRoleColor(role) {
@@ -966,6 +1084,10 @@ function InputBar({
966
1084
  const isAutocompleteActiveRef = useRef(false);
967
1085
  const previousHistoryIndexRef = useRef(void 0);
968
1086
  const historyCacheRef = useRef({});
1087
+ const lastInputTimeRef = useRef(0);
1088
+ const pasteBufferRef = useRef("");
1089
+ const pasteTimeoutRef = useRef(null);
1090
+ const isPastingRef = useRef(false);
969
1091
  const setInputWithCursor = useCallback(
970
1092
  (nextInput, cursorPosition = "end") => {
971
1093
  const nextCursor = cursorPosition === "start" ? 0 : cursorPosition === "end" ? codePointLength(nextInput) : clampCursorOffset(nextInput, cursorPosition);
@@ -1032,6 +1154,17 @@ function InputBar({
1032
1154
  });
1033
1155
  }
1034
1156
  }, [initialHistory]);
1157
+ useEffect(() => {
1158
+ process.stdout.write("\x1B[?2004h");
1159
+ return () => {
1160
+ process.stdout.write("\x1B[?2004l");
1161
+ };
1162
+ }, []);
1163
+ useEffect(() => {
1164
+ return () => {
1165
+ if (pasteTimeoutRef.current) clearTimeout(pasteTimeoutRef.current);
1166
+ };
1167
+ }, []);
1035
1168
  useEffect(() => {
1036
1169
  inputRef.current = input;
1037
1170
  cursorOffsetRef.current = cursorOffset;
@@ -1178,6 +1311,24 @@ function InputBar({
1178
1311
  }
1179
1312
  if (key.ctrl && inputChar === "l") return;
1180
1313
  if (!key.ctrl && !key.meta && inputChar) {
1314
+ const now = Date.now();
1315
+ const timeSinceLastInput = now - lastInputTimeRef.current;
1316
+ lastInputTimeRef.current = now;
1317
+ if (timeSinceLastInput < 5) {
1318
+ isPastingRef.current = true;
1319
+ pasteBufferRef.current += inputChar;
1320
+ if (pasteTimeoutRef.current) clearTimeout(pasteTimeoutRef.current);
1321
+ pasteTimeoutRef.current = setTimeout(() => {
1322
+ const pasteText = pasteBufferRef.current;
1323
+ pasteBufferRef.current = "";
1324
+ isPastingRef.current = false;
1325
+ if (pasteText) {
1326
+ const result2 = insertTextAtCursor(inputRef.current, cursorOffsetRef.current, pasteText);
1327
+ setInputWithCursor(result2.text, result2.cursorOffset);
1328
+ }
1329
+ }, 10);
1330
+ return;
1331
+ }
1181
1332
  const result = insertTextAtCursor(currentInput, currentCursorOffset, inputChar);
1182
1333
  setInputWithCursor(result.text, result.cursorOffset);
1183
1334
  }
@@ -1238,6 +1389,12 @@ function StatusBar({
1238
1389
  gitBranch,
1239
1390
  gitChanges
1240
1391
  }) {
1392
+ const { stdout } = useStdout();
1393
+ const width = stdout.columns ?? 120;
1394
+ const showRole = width > 100 && !!role;
1395
+ const showGit = width > 60 && !!gitBranch;
1396
+ const showTokens = width > 45;
1397
+ const showCost = width > 45;
1241
1398
  return /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: colors.border.dim, paddingX: 1, children: [
1242
1399
  /* @__PURE__ */ jsxs(Text, { color: BRAND_COLOR, bold: true, children: [
1243
1400
  "\u25C6",
@@ -1246,18 +1403,22 @@ function StatusBar({
1246
1403
  /* @__PURE__ */ jsx(Text, { color: colors.status.active, bold: true, children: "Aemeath Agent Swarm" }),
1247
1404
  /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1248
1405
  /* @__PURE__ */ jsx(Text, { color: colors.status.warning, bold: true, children: shortModelLabel(model) }),
1249
- role ? /* @__PURE__ */ jsxs(Fragment, { children: [
1406
+ showRole ? /* @__PURE__ */ jsxs(Fragment, { children: [
1250
1407
  /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1251
1408
  /* @__PURE__ */ jsx(Text, { color: colors.role.tool, children: role })
1252
1409
  ] }) : null,
1253
- /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1254
- /* @__PURE__ */ jsxs(Text, { color: colors.text.secondary, children: [
1255
- tokenCount,
1256
- " tok"
1257
- ] }),
1258
- /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1259
- /* @__PURE__ */ jsx(Text, { color: colors.status.success, children: cost }),
1260
- gitBranch ? /* @__PURE__ */ jsxs(Fragment, { children: [
1410
+ showTokens ? /* @__PURE__ */ jsxs(Fragment, { children: [
1411
+ /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1412
+ /* @__PURE__ */ jsxs(Text, { color: colors.text.secondary, children: [
1413
+ tokenCount,
1414
+ " tok"
1415
+ ] })
1416
+ ] }) : null,
1417
+ showCost ? /* @__PURE__ */ jsxs(Fragment, { children: [
1418
+ /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1419
+ /* @__PURE__ */ jsx(Text, { color: colors.status.success, children: cost })
1420
+ ] }) : null,
1421
+ showGit ? /* @__PURE__ */ jsxs(Fragment, { children: [
1261
1422
  /* @__PURE__ */ jsx(Text, { color: colors.text.muted, children: SEP }),
1262
1423
  /* @__PURE__ */ jsxs(Text, { color: colors.status.info, children: [
1263
1424
  "\u2387",
@@ -1278,26 +1439,49 @@ var THINKING_PHRASES = [
1278
1439
  "Evaluating"
1279
1440
  ];
1280
1441
  var PHRASE_CYCLE_MS = 2500;
1442
+ function formatElapsed(ms) {
1443
+ const totalSecs = Math.floor(ms / 1e3);
1444
+ if (totalSecs < 1) return "0s";
1445
+ if (totalSecs < 60) return `${totalSecs}s`;
1446
+ const mins = Math.floor(totalSecs / 60);
1447
+ const secs = totalSecs % 60;
1448
+ if (mins < 60) return `${mins}m ${String(secs).padStart(2, "0")}s`;
1449
+ const hrs = Math.floor(mins / 60);
1450
+ const remMins = mins % 60;
1451
+ return `${hrs}h ${String(remMins).padStart(2, "0")}m ${String(secs).padStart(2, "0")}s`;
1452
+ }
1281
1453
  function ThinkingIndicator({
1282
1454
  activity,
1283
1455
  isStreaming,
1284
1456
  modelName,
1285
- startTime
1457
+ startTime,
1458
+ isPaused = false,
1459
+ details,
1460
+ maxDetailLines = 3
1286
1461
  }) {
1287
1462
  const tick = useAnimationTick(1e3);
1288
- const elapsed = startTime === void 0 ? 0 : Math.max(0, Date.now() - startTime);
1463
+ const pausedAccumRef = useRef(0);
1464
+ const pauseStartRef = useRef(void 0);
1465
+ if (isPaused && pauseStartRef.current === void 0) {
1466
+ pauseStartRef.current = Date.now();
1467
+ } else if (!isPaused && pauseStartRef.current !== void 0) {
1468
+ pausedAccumRef.current += Date.now() - pauseStartRef.current;
1469
+ pauseStartRef.current = void 0;
1470
+ }
1471
+ const now = isPaused ? pauseStartRef.current ?? Date.now() : Date.now();
1472
+ const rawElapsed = startTime === void 0 ? 0 : Math.max(0, now - startTime);
1473
+ const elapsed = Math.max(0, rawElapsed - pausedAccumRef.current);
1289
1474
  const phraseIndex = Math.floor(elapsed / PHRASE_CYCLE_MS) % THINKING_PHRASES.length;
1290
1475
  const elapsedStr = useMemo(() => {
1291
- const secs = Math.floor(elapsed / 1e3);
1292
- if (secs < 1) return "";
1293
- if (secs < 60) return `${secs}s`;
1294
- const mins = Math.floor(secs / 60);
1295
- return `${mins}m${secs % 60}s`;
1476
+ if (elapsed < 1e3) return "";
1477
+ return formatElapsed(elapsed);
1296
1478
  }, [elapsed]);
1297
1479
  const dotCount = tick % 4;
1298
1480
  const dots = ".".repeat(dotCount);
1299
1481
  const phrase = THINKING_PHRASES[phraseIndex] ?? "Thinking";
1300
- const displayText = activity ? activity : isStreaming ? "Streaming response" : `${phrase}${dots}`;
1482
+ const displayText = isPaused ? "Rate limited \u2014 waiting" : activity ? activity : isStreaming ? "Streaming response" : `${phrase}${dots}`;
1483
+ const visibleDetails = details ? details.slice(0, maxDetailLines) : void 0;
1484
+ const hiddenDetailCount = details ? Math.max(0, details.length - maxDetailLines) : 0;
1301
1485
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
1302
1486
  modelName ? /* @__PURE__ */ jsxs(Box, { children: [
1303
1487
  /* @__PURE__ */ jsxs(Text, { color: colors.role.assistant, bold: true, children: [
@@ -1310,21 +1494,35 @@ function ThinkingIndicator({
1310
1494
  /* @__PURE__ */ jsx(
1311
1495
  GradientSpinner,
1312
1496
  {
1313
- variant: activity ? "braille" : "dots",
1497
+ variant: isPaused ? "pulse" : activity ? "braille" : "dots",
1314
1498
  label: displayText,
1315
- labelColor: activity ? colors.text.secondary : colors.text.muted
1499
+ labelColor: isPaused ? colors.status.warning : activity ? colors.text.secondary : colors.text.muted
1316
1500
  }
1317
1501
  ),
1318
1502
  elapsedStr ? /* @__PURE__ */ jsxs(Text, { color: colors.text.muted, children: [
1319
- " (",
1503
+ " ",
1504
+ "(",
1320
1505
  elapsedStr,
1321
- ")"
1322
- ] }) : null
1506
+ " ",
1507
+ "\u2022",
1508
+ " esc to interrupt)"
1509
+ ] }) : /* @__PURE__ */ jsxs(Text, { color: colors.text.muted, children: [
1510
+ " ",
1511
+ "(esc to interrupt)"
1512
+ ] })
1323
1513
  ] }),
1324
- /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: colors.text.muted, dimColor: true, children: [
1325
- " ",
1326
- "esc to cancel"
1327
- ] }) })
1514
+ visibleDetails && visibleDetails.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
1515
+ visibleDetails.map((detail, i) => /* @__PURE__ */ jsxs(Text, { color: colors.text.muted, dimColor: true, wrap: "truncate", children: [
1516
+ " \u2514 ",
1517
+ detail
1518
+ ] }, i)),
1519
+ hiddenDetailCount > 0 ? /* @__PURE__ */ jsxs(Text, { color: colors.text.muted, dimColor: true, children: [
1520
+ " ",
1521
+ "(+",
1522
+ hiddenDetailCount,
1523
+ " more)"
1524
+ ] }) : null
1525
+ ] }) : null
1328
1526
  ] });
1329
1527
  }
1330
1528
  var MASCOT_LINES = [
@@ -1764,6 +1962,111 @@ function useModel(config, initialModel, initialRole) {
1764
1962
  router
1765
1963
  };
1766
1964
  }
1965
+
1966
+ // src/ui/streaming-controller.ts
1967
+ var StreamingController = class {
1968
+ buffer;
1969
+ committed;
1970
+ lineCounter;
1971
+ headerEmitted;
1972
+ /** Index into `committed` marking where the last drain ended. */
1973
+ drainCursor;
1974
+ constructor() {
1975
+ this.buffer = "";
1976
+ this.committed = [];
1977
+ this.lineCounter = 0;
1978
+ this.headerEmitted = false;
1979
+ this.drainCursor = 0;
1980
+ }
1981
+ /**
1982
+ * Feed a text chunk into the controller.
1983
+ *
1984
+ * Lines terminated by `\n` are committed immediately.
1985
+ * Any trailing text without a newline stays in the buffer.
1986
+ *
1987
+ * @returns Newly committed lines from this chunk.
1988
+ */
1989
+ push(chunk) {
1990
+ this.buffer += chunk;
1991
+ const newLines = [];
1992
+ let newlineIdx = this.buffer.indexOf("\n");
1993
+ while (newlineIdx !== -1) {
1994
+ const lineText = this.buffer.slice(0, newlineIdx);
1995
+ this.buffer = this.buffer.slice(newlineIdx + 1);
1996
+ this.lineCounter += 1;
1997
+ const committed = {
1998
+ text: lineText,
1999
+ lineNumber: this.lineCounter
2000
+ };
2001
+ this.committed.push(committed);
2002
+ newLines.push(committed);
2003
+ newlineIdx = this.buffer.indexOf("\n");
2004
+ }
2005
+ if (newLines.length > 0) {
2006
+ this.headerEmitted = true;
2007
+ }
2008
+ return newLines;
2009
+ }
2010
+ /**
2011
+ * Flush the remaining buffer as a final committed line.
2012
+ *
2013
+ * Call this when the stream ends to commit any trailing
2014
+ * partial line that never received a terminating newline.
2015
+ *
2016
+ * @returns The flushed line, or `null` if the buffer was empty.
2017
+ */
2018
+ flush() {
2019
+ if (this.buffer.length === 0) {
2020
+ return null;
2021
+ }
2022
+ this.lineCounter += 1;
2023
+ const committed = {
2024
+ text: this.buffer,
2025
+ lineNumber: this.lineCounter
2026
+ };
2027
+ this.committed.push(committed);
2028
+ this.buffer = "";
2029
+ this.headerEmitted = true;
2030
+ return committed;
2031
+ }
2032
+ /** Get an immutable snapshot of the current controller state. */
2033
+ getState() {
2034
+ return {
2035
+ committedLines: [...this.committed],
2036
+ pendingLine: this.buffer,
2037
+ hasEmittedHeader: this.headerEmitted,
2038
+ totalLines: this.lineCounter
2039
+ };
2040
+ }
2041
+ /** Get only the pending (incomplete) line text. */
2042
+ getPendingLine() {
2043
+ return this.buffer;
2044
+ }
2045
+ /** Reset the controller to its initial state. */
2046
+ reset() {
2047
+ this.buffer = "";
2048
+ this.committed = [];
2049
+ this.lineCounter = 0;
2050
+ this.headerEmitted = false;
2051
+ this.drainCursor = 0;
2052
+ }
2053
+ /**
2054
+ * Get committed lines since the last call to this method.
2055
+ *
2056
+ * Useful for incremental rendering — each call returns only
2057
+ * the lines that were committed after the previous drain.
2058
+ */
2059
+ drainNewLines() {
2060
+ const newLines = this.committed.slice(this.drainCursor);
2061
+ this.drainCursor = this.committed.length;
2062
+ return newLines;
2063
+ }
2064
+ };
2065
+ function createStreamingController() {
2066
+ return new StreamingController();
2067
+ }
2068
+
2069
+ // src/ui/hooks/useStream.ts
1767
2070
  function formatToolActivity(toolCall) {
1768
2071
  const args = toolCall.arguments;
1769
2072
  switch (toolCall.name) {
@@ -1809,25 +2112,32 @@ function useStream() {
1809
2112
  const [state, setState] = useState({
1810
2113
  isStreaming: false,
1811
2114
  content: "",
2115
+ pendingLine: "",
1812
2116
  usage: void 0,
1813
2117
  error: void 0,
1814
2118
  activity: void 0,
1815
2119
  toolCalls: [],
1816
- startTime: void 0
2120
+ startTime: void 0,
2121
+ isPaused: false
1817
2122
  });
1818
2123
  const cancelRef = useRef(false);
2124
+ const streamingCtrlRef = useRef(null);
1819
2125
  const isCancelled = () => cancelRef.current;
1820
2126
  const startStream = useCallback(
1821
2127
  async (stream) => {
1822
2128
  cancelRef.current = false;
2129
+ const ctrl = createStreamingController();
2130
+ streamingCtrlRef.current = ctrl;
1823
2131
  setState({
1824
2132
  isStreaming: true,
1825
2133
  content: "",
2134
+ pendingLine: "",
1826
2135
  usage: void 0,
1827
2136
  error: void 0,
1828
2137
  activity: void 0,
1829
2138
  toolCalls: [],
1830
- startTime: Date.now()
2139
+ startTime: Date.now(),
2140
+ isPaused: false
1831
2141
  });
1832
2142
  try {
1833
2143
  for await (const chunk of stream) {
@@ -1836,9 +2146,12 @@ function useStream() {
1836
2146
  case "text":
1837
2147
  if (chunk.content !== void 0) {
1838
2148
  const text = chunk.content;
2149
+ ctrl.push(text);
2150
+ const ctrlState = ctrl.getState();
1839
2151
  setState((prev) => ({
1840
2152
  ...prev,
1841
- content: prev.content + text,
2153
+ content: ctrlState.committedLines.map((l) => l.text).join("\n"),
2154
+ pendingLine: ctrlState.pendingLine,
1842
2155
  activity: void 0
1843
2156
  }));
1844
2157
  }
@@ -1894,12 +2207,17 @@ function useStream() {
1894
2207
  )
1895
2208
  }));
1896
2209
  return;
1897
- case "done":
2210
+ case "done": {
2211
+ ctrl.flush();
2212
+ const finalState = ctrl.getState();
1898
2213
  setState((prev) => ({
1899
2214
  ...prev,
1900
2215
  isStreaming: false,
2216
+ content: finalState.committedLines.map((l) => l.text).join("\n"),
2217
+ pendingLine: "",
1901
2218
  usage: chunk.usage ?? prev.usage,
1902
2219
  activity: void 0,
2220
+ isPaused: false,
1903
2221
  toolCalls: prev.toolCalls.map(
1904
2222
  (tc) => tc.status === "executing" ? {
1905
2223
  ...tc,
@@ -1909,12 +2227,18 @@ function useStream() {
1909
2227
  )
1910
2228
  }));
1911
2229
  return;
2230
+ }
1912
2231
  }
1913
2232
  }
2233
+ ctrl.flush();
2234
+ const endState = ctrl.getState();
1914
2235
  setState((prev) => ({
1915
2236
  ...prev,
1916
2237
  isStreaming: false,
2238
+ content: endState.committedLines.map((l) => l.text).join("\n"),
2239
+ pendingLine: "",
1917
2240
  activity: void 0,
2241
+ isPaused: false,
1918
2242
  toolCalls: prev.toolCalls.map(
1919
2243
  (tc) => tc.status === "executing" ? {
1920
2244
  ...tc,
@@ -1928,7 +2252,8 @@ function useStream() {
1928
2252
  ...prev,
1929
2253
  isStreaming: false,
1930
2254
  error: error instanceof Error ? error.message : String(error),
1931
- activity: void 0
2255
+ activity: void 0,
2256
+ isPaused: false
1932
2257
  }));
1933
2258
  }
1934
2259
  },
@@ -1936,28 +2261,52 @@ function useStream() {
1936
2261
  );
1937
2262
  const cancelStream = useCallback(() => {
1938
2263
  cancelRef.current = true;
1939
- setState((prev) => ({
1940
- ...prev,
1941
- isStreaming: false,
1942
- toolCalls: prev.toolCalls.map(
1943
- (tc) => tc.status === "executing" ? {
1944
- ...tc,
1945
- status: "cancelled",
1946
- endTime: Date.now()
1947
- } : tc
1948
- )
1949
- }));
2264
+ const ctrl = streamingCtrlRef.current;
2265
+ if (ctrl) {
2266
+ ctrl.flush();
2267
+ const finalState = ctrl.getState();
2268
+ setState((prev) => ({
2269
+ ...prev,
2270
+ isStreaming: false,
2271
+ content: finalState.committedLines.map((l) => l.text).join("\n"),
2272
+ pendingLine: "",
2273
+ isPaused: false,
2274
+ toolCalls: prev.toolCalls.map(
2275
+ (tc) => tc.status === "executing" ? {
2276
+ ...tc,
2277
+ status: "cancelled",
2278
+ endTime: Date.now()
2279
+ } : tc
2280
+ )
2281
+ }));
2282
+ } else {
2283
+ setState((prev) => ({
2284
+ ...prev,
2285
+ isStreaming: false,
2286
+ isPaused: false,
2287
+ toolCalls: prev.toolCalls.map(
2288
+ (tc) => tc.status === "executing" ? {
2289
+ ...tc,
2290
+ status: "cancelled",
2291
+ endTime: Date.now()
2292
+ } : tc
2293
+ )
2294
+ }));
2295
+ }
1950
2296
  }, []);
1951
2297
  const reset = useCallback(() => {
1952
2298
  cancelRef.current = true;
2299
+ streamingCtrlRef.current = null;
1953
2300
  setState({
1954
2301
  isStreaming: false,
1955
2302
  content: "",
2303
+ pendingLine: "",
1956
2304
  usage: void 0,
1957
2305
  error: void 0,
1958
2306
  activity: void 0,
1959
2307
  toolCalls: [],
1960
- startTime: void 0
2308
+ startTime: void 0,
2309
+ isPaused: false
1961
2310
  });
1962
2311
  }, []);
1963
2312
  return { state, startStream, cancelStream, reset };
@@ -2484,7 +2833,7 @@ async function handleTeamCommand(args, ctx) {
2484
2833
  }
2485
2834
  if (subcommand === "list") {
2486
2835
  try {
2487
- const { TeamManager } = await import('./team-manager-6DCNLGTC.js');
2836
+ const { TeamManager } = await import('./team-manager-2VSMALAA.js');
2488
2837
  const manager = new TeamManager();
2489
2838
  const teams = manager.listTeams();
2490
2839
  if (teams.length === 0) {
@@ -2510,7 +2859,7 @@ async function handleMcpCommand(args, ctx) {
2510
2859
  const subcommand = args[0];
2511
2860
  if (subcommand === "list") {
2512
2861
  try {
2513
- const { MCPServerManager } = await import('./server-manager-DES23IBQ.js');
2862
+ const { MCPServerManager } = await import('./server-manager-THGZBBZB.js');
2514
2863
  const manager = new MCPServerManager();
2515
2864
  const connected = manager.getConnectedServers();
2516
2865
  if (connected.length === 0) {
@@ -2561,8 +2910,8 @@ async function handleSkillCommand(args, ctx) {
2561
2910
  const subcommand = args[0];
2562
2911
  if (subcommand === "list") {
2563
2912
  try {
2564
- const { SkillRegistry } = await import('./registry-7CQ3NCAD.js');
2565
- const { findProjectRoot } = await import('./pathResolver-A6IXQQFE.js');
2913
+ const { SkillRegistry } = await import('./registry-LRURZVUL.js');
2914
+ const { findProjectRoot } = await import('./pathResolver-UVAB2FCW.js');
2566
2915
  const registry = new SkillRegistry();
2567
2916
  await registry.initialize(findProjectRoot());
2568
2917
  const skills = registry.listAll();
@@ -2597,9 +2946,9 @@ async function handleSkillInvocation(input, setMessages) {
2597
2946
  { id: v4Id(), role: "user", content: input, createdAt: /* @__PURE__ */ new Date() }
2598
2947
  ]);
2599
2948
  try {
2600
- const { SkillRegistry } = await import('./registry-7CQ3NCAD.js');
2601
- const { SkillExecutor } = await import('./executor-RUX7VK3T.js');
2602
- const { findProjectRoot } = await import('./pathResolver-A6IXQQFE.js');
2949
+ const { SkillRegistry } = await import('./registry-LRURZVUL.js');
2950
+ const { SkillExecutor } = await import('./executor-FTABX2AW.js');
2951
+ const { findProjectRoot } = await import('./pathResolver-UVAB2FCW.js');
2603
2952
  const registry = new SkillRegistry();
2604
2953
  await registry.initialize(findProjectRoot());
2605
2954
  const executor = new SkillExecutor(registry);
@@ -2634,7 +2983,7 @@ async function handleLoginSlashCommand(args, ctx) {
2634
2983
  const subcommand = args[0];
2635
2984
  if (subcommand === "status") {
2636
2985
  try {
2637
- const { getAuthStatusRecords, formatCompactAuthStatusLine } = await import('./auth-status-EIM5A5KL.js');
2986
+ const { getAuthStatusRecords, formatCompactAuthStatusLine } = await import('./auth-status-JQJOKUPF.js');
2638
2987
  const records = await getAuthStatusRecords();
2639
2988
  const lines = records.map((record) => formatCompactAuthStatusLine(record));
2640
2989
  addSystemMessage(ctx, lines.join("\n"));
@@ -2665,19 +3014,19 @@ async function handleLoginSlashCommand(args, ctx) {
2665
3014
  async function loadLoginModuleForSlash(provider) {
2666
3015
  switch (provider) {
2667
3016
  case "claude": {
2668
- const mod = await import('./claude-login-IS5WTBMP.js');
3017
+ const mod = await import('./claude-login-AIFIWTYF.js');
2669
3018
  return new mod.ClaudeLogin();
2670
3019
  }
2671
3020
  case "codex": {
2672
- const mod = await import('./codex-login-GMPF64MR.js');
3021
+ const mod = await import('./codex-login-LW5X7GAM.js');
2673
3022
  return new mod.CodexLogin();
2674
3023
  }
2675
3024
  case "gemini": {
2676
- const mod = await import('./gemini-login-KE224MSW.js');
3025
+ const mod = await import('./gemini-login-TST454MX.js');
2677
3026
  return new mod.GeminiLogin();
2678
3027
  }
2679
3028
  case "kimi": {
2680
- const mod = await import('./kimi-login-DNT5YBKX.js');
3029
+ const mod = await import('./kimi-login-3IGVOBJI.js');
2681
3030
  return new mod.KimiLogin();
2682
3031
  }
2683
3032
  default:
@@ -2691,7 +3040,7 @@ async function handleConfigSlashCommand(args, ctx) {
2691
3040
  if (subcommand === "get") {
2692
3041
  const key = args[1];
2693
3042
  try {
2694
- const { ConfigStore } = await import('./config-store-POB6I37G.js');
3043
+ const { ConfigStore } = await import('./config-store-NF56VHFU.js');
2695
3044
  const store = new ConfigStore();
2696
3045
  const cfg = store.loadGlobal();
2697
3046
  if (!key) {
@@ -2718,7 +3067,7 @@ async function handleConfigSlashCommand(args, ctx) {
2718
3067
  return;
2719
3068
  }
2720
3069
  try {
2721
- const { ConfigStore } = await import('./config-store-POB6I37G.js');
3070
+ const { ConfigStore } = await import('./config-store-NF56VHFU.js');
2722
3071
  const store = new ConfigStore();
2723
3072
  const cfg = store.loadGlobal();
2724
3073
  let parsedValue;
@@ -2763,8 +3112,8 @@ function setNestedConfigValue(obj, path, value) {
2763
3112
  // src/ui/commands/history-commands.ts
2764
3113
  async function handleHistoryCommand(ctx) {
2765
3114
  try {
2766
- const { SqliteStore } = await import('./sqlite-store-7ZIVOUNI.js');
2767
- const { ConversationStore } = await import('./conversation-store-PRBHWQMJ.js');
3115
+ const { SqliteStore } = await import('./sqlite-store-7OECRTXM.js');
3116
+ const { ConversationStore } = await import('./conversation-store-7GRDQZD2.js');
2768
3117
  const db = new SqliteStore();
2769
3118
  db.open();
2770
3119
  const store = new ConversationStore(db);
@@ -2797,8 +3146,8 @@ async function handleResumeCommand(arg, ctx) {
2797
3146
  return;
2798
3147
  }
2799
3148
  try {
2800
- const { SqliteStore } = await import('./sqlite-store-7ZIVOUNI.js');
2801
- const { ConversationStore } = await import('./conversation-store-PRBHWQMJ.js');
3149
+ const { SqliteStore } = await import('./sqlite-store-7OECRTXM.js');
3150
+ const { ConversationStore } = await import('./conversation-store-7GRDQZD2.js');
2802
3151
  const db = new SqliteStore();
2803
3152
  db.open();
2804
3153
  const store = new ConversationStore(db);
@@ -2952,7 +3301,7 @@ Valid roles: ${validRoles.join(", ")}`);
2952
3301
  break;
2953
3302
  case "/quit":
2954
3303
  case "/exit": {
2955
- const { getActiveTeamManager: getActiveTeamManager2, getActiveTeamName: getActiveTeamName2, getActiveTmuxCleanup: getActiveTmuxCleanup2 } = await import('./team-state-R2D7DT5M.js');
3304
+ const { getActiveTeamManager: getActiveTeamManager2, getActiveTeamName: getActiveTeamName2, getActiveTmuxCleanup: getActiveTmuxCleanup2 } = await import('./team-state-HZNVMQHT.js');
2956
3305
  const teamCleanup = getActiveTmuxCleanup2();
2957
3306
  if (teamCleanup) {
2958
3307
  try {
@@ -2980,8 +3329,8 @@ Valid roles: ${validRoles.join(", ")}`);
2980
3329
  var convDbRef;
2981
3330
  async function persistMessages(projectRoot, userMsg, assistantMsg, model, provider) {
2982
3331
  try {
2983
- const { SqliteStore } = await import('./sqlite-store-7ZIVOUNI.js');
2984
- const { ConversationStore } = await import('./conversation-store-PRBHWQMJ.js');
3332
+ const { SqliteStore } = await import('./sqlite-store-7OECRTXM.js');
3333
+ const { ConversationStore } = await import('./conversation-store-7GRDQZD2.js');
2985
3334
  if (!convDbRef) {
2986
3335
  const db = new SqliteStore();
2987
3336
  db.open();
@@ -3003,7 +3352,7 @@ async function persistMessages(projectRoot, userMsg, assistantMsg, model, provid
3003
3352
  content: assistantMsg.content
3004
3353
  });
3005
3354
  } catch (error) {
3006
- const { logger } = await import('./logger-PLPDWACQ.js');
3355
+ const { logger } = await import('./logger-KGHUQ4VE.js');
3007
3356
  const msg = error instanceof Error ? error.message : String(error);
3008
3357
  logger.warn({ error: msg }, "Conversation persistence failed");
3009
3358
  }
@@ -3220,7 +3569,7 @@ async function handlePromptBasedTeamCreation(input, setMessages, panel, getRegis
3220
3569
  ]);
3221
3570
  try {
3222
3571
  const registry = await getRegistry();
3223
- const { detectInstalledProviders } = await import('./detect-providers-C4SVQHFF.js');
3572
+ const { detectInstalledProviders } = await import('./detect-providers-QICJ5U3R.js');
3224
3573
  const installedClis = detectInstalledProviders();
3225
3574
  const prioritizedMasterProviders = resolveMasterProviderPriority(swarmConfig, installedClis);
3226
3575
  const availableModels = getAvailableModelsForProviders(installedClis);
@@ -3424,6 +3773,40 @@ The sponsoring lead agent must use ${primaryMasterLabel} when possible.`;
3424
3773
  leadCoordinationTask
3425
3774
  );
3426
3775
  }
3776
+ const isGhostty = process.platform === "darwin" && process.env["TERM_PROGRAM"] === "ghostty";
3777
+ if (isGhostty) {
3778
+ return await launchGhostty(
3779
+ agentSpecs,
3780
+ leadSpec,
3781
+ workerCommands,
3782
+ teamName,
3783
+ tempDir,
3784
+ boardDir,
3785
+ fs,
3786
+ path,
3787
+ execaPane,
3788
+ setMessages,
3789
+ formatAgentLines,
3790
+ leadCoordinationTask
3791
+ );
3792
+ }
3793
+ const isTerminalApp = process.platform === "darwin" && process.env["TERM_PROGRAM"] === "Apple_Terminal";
3794
+ if (isTerminalApp) {
3795
+ return await launchTerminalApp(
3796
+ agentSpecs,
3797
+ leadSpec,
3798
+ workerCommands,
3799
+ teamName,
3800
+ tempDir,
3801
+ boardDir,
3802
+ fs,
3803
+ path,
3804
+ execaPane,
3805
+ setMessages,
3806
+ formatAgentLines,
3807
+ leadCoordinationTask
3808
+ );
3809
+ }
3427
3810
  if (isWindowsTerminal) {
3428
3811
  return await launchWindowsTerminal(
3429
3812
  agentSpecs,
@@ -3440,7 +3823,7 @@ The sponsoring lead agent must use ${primaryMasterLabel} when possible.`;
3440
3823
  projectRoot
3441
3824
  );
3442
3825
  }
3443
- const { TmuxManager } = await import('./tmux-manager-WBKHUHDT.js');
3826
+ const { TmuxManager } = await import('./tmux-manager-57QCUVHU.js');
3444
3827
  const tmux = new TmuxManager();
3445
3828
  const tmuxAvailable = await tmux.isAvailable();
3446
3829
  if (tmuxAvailable) {
@@ -3545,6 +3928,129 @@ ${agentLines.join("\n")}
3545
3928
  );
3546
3929
  return leadCoordinationTask;
3547
3930
  }
3931
+ async function launchGhostty(agentSpecs, leadSpec, workerCommands, teamName, tempDir, boardDir, fs, path, execaPane, setMessages, formatAgentLines, leadCoordinationTask) {
3932
+ sysMsg(setMessages, `Designed ${agentSpecs.length}-agent team. Creating Ghostty split panes...`);
3933
+ const asEscape = (s) => s.replace(/\\/gu, "\\\\").replace(/"/gu, '\\"');
3934
+ const scriptLines = [];
3935
+ scriptLines.push('tell application "Ghostty" to activate');
3936
+ scriptLines.push("delay 0.5");
3937
+ scriptLines.push('tell application "System Events"');
3938
+ for (const [i, agent] of workerCommands.entries()) {
3939
+ if (i === 0) {
3940
+ scriptLines.push(' keystroke "d" using {command down}');
3941
+ } else {
3942
+ scriptLines.push(' keystroke "d" using {command down, shift down}');
3943
+ }
3944
+ scriptLines.push(" delay 1.0");
3945
+ const escapedCmd = asEscape(agent.command);
3946
+ scriptLines.push(` keystroke "${escapedCmd}"`);
3947
+ scriptLines.push(" delay 0.2");
3948
+ scriptLines.push(" keystroke return");
3949
+ scriptLines.push(" delay 0.5");
3950
+ }
3951
+ if (workerCommands.length > 0) {
3952
+ for (let i = 0; i < workerCommands.length; i++) {
3953
+ scriptLines.push(" key code 123 using {command down, option down}");
3954
+ scriptLines.push(" delay 0.2");
3955
+ }
3956
+ }
3957
+ scriptLines.push("end tell");
3958
+ const scriptFile = path.join(tempDir, "create-panes.applescript");
3959
+ fs.writeFileSync(scriptFile, scriptLines.join("\n"), "utf-8");
3960
+ try {
3961
+ await execaPane("osascript", [scriptFile]);
3962
+ } catch (scriptErr) {
3963
+ const errMsg = scriptErr instanceof Error ? scriptErr.message : String(scriptErr);
3964
+ sysMsg(
3965
+ setMessages,
3966
+ `Failed to create Ghostty panes: ${errMsg.slice(0, 200)}
3967
+ Ensure macOS accessibility permissions are granted and Ghostty uses default split keybindings (Cmd+D = new_split:right, Cmd+Shift+D = new_split:down).`
3968
+ );
3969
+ return;
3970
+ }
3971
+ setActiveTeamName(teamName);
3972
+ setActiveTeamManager(void 0);
3973
+ setActiveTmuxCleanup(async () => {
3974
+ try {
3975
+ const { execFileSync } = await import('child_process');
3976
+ execFileSync("pkill", ["-f", tempDir], { stdio: "ignore" });
3977
+ } catch {
3978
+ }
3979
+ try {
3980
+ fs.rmSync(tempDir, { recursive: true, force: true });
3981
+ fs.rmSync(boardDir, { recursive: true, force: true });
3982
+ } catch {
3983
+ }
3984
+ });
3985
+ const agentLines = formatAgentLines(leadSpec.name);
3986
+ sysMsg(
3987
+ setMessages,
3988
+ `Team "${teamName}" \u2014 ${agentSpecs.length} agents active.
3989
+ ${workerCommands.length} worker panes in Ghostty + lead coordinating here.
3990
+ ${agentLines.join("\n")}
3991
+ Keybindings:
3992
+ Cmd+Opt+Arrows Switch pane
3993
+ Cmd+Shift+Enter Zoom pane
3994
+ Cmd+Ctrl+= Equalize splits
3995
+ /team stop to shut down all agents.`
3996
+ );
3997
+ return leadCoordinationTask;
3998
+ }
3999
+ async function launchTerminalApp(agentSpecs, leadSpec, workerCommands, teamName, tempDir, boardDir, fs, path, execaPane, setMessages, formatAgentLines, leadCoordinationTask) {
4000
+ sysMsg(setMessages, `Designed ${agentSpecs.length}-agent team. Creating Terminal.app split panes...`);
4001
+ const asEscape = (s) => s.replace(/\\/gu, "\\\\").replace(/"/gu, '\\"');
4002
+ const scriptLines = [];
4003
+ scriptLines.push('tell application "Terminal" to activate');
4004
+ scriptLines.push("delay 0.5");
4005
+ scriptLines.push('tell application "System Events"');
4006
+ for (const agent of workerCommands) {
4007
+ scriptLines.push(' keystroke "d" using {command down}');
4008
+ scriptLines.push(" delay 1.0");
4009
+ const escapedCmd = asEscape(agent.command);
4010
+ scriptLines.push(` keystroke "${escapedCmd}"`);
4011
+ scriptLines.push(" delay 0.2");
4012
+ scriptLines.push(" keystroke return");
4013
+ scriptLines.push(" delay 0.5");
4014
+ }
4015
+ scriptLines.push("end tell");
4016
+ const scriptFile = path.join(tempDir, "create-panes.applescript");
4017
+ fs.writeFileSync(scriptFile, scriptLines.join("\n"), "utf-8");
4018
+ try {
4019
+ await execaPane("osascript", [scriptFile]);
4020
+ } catch (scriptErr) {
4021
+ const errMsg = scriptErr instanceof Error ? scriptErr.message : String(scriptErr);
4022
+ sysMsg(
4023
+ setMessages,
4024
+ `Failed to create Terminal.app panes: ${errMsg.slice(0, 200)}
4025
+ Ensure macOS accessibility permissions are granted for Terminal.app.`
4026
+ );
4027
+ return;
4028
+ }
4029
+ setActiveTeamName(teamName);
4030
+ setActiveTeamManager(void 0);
4031
+ setActiveTmuxCleanup(async () => {
4032
+ try {
4033
+ const { execFileSync } = await import('child_process');
4034
+ execFileSync("pkill", ["-f", tempDir], { stdio: "ignore" });
4035
+ } catch {
4036
+ }
4037
+ try {
4038
+ fs.rmSync(tempDir, { recursive: true, force: true });
4039
+ fs.rmSync(boardDir, { recursive: true, force: true });
4040
+ } catch {
4041
+ }
4042
+ });
4043
+ const agentLines = formatAgentLines(leadSpec.name);
4044
+ sysMsg(
4045
+ setMessages,
4046
+ `Team "${teamName}" \u2014 ${agentSpecs.length} agents active.
4047
+ ${workerCommands.length} worker panes in Terminal.app + lead coordinating here.
4048
+ ${agentLines.join("\n")}
4049
+ Click the lead pane to switch back. Shift+Cmd+D to close a split pane.
4050
+ /team stop to shut down all agents.`
4051
+ );
4052
+ return leadCoordinationTask;
4053
+ }
3548
4054
  async function launchWindowsTerminal(agentSpecs, leadSpec, workerCommands, teamName, tempDir, boardDir, fs, execaPane, setMessages, formatAgentLines, leadCoordinationTask, projectRoot) {
3549
4055
  sysMsg(setMessages, `Designed ${agentSpecs.length}-agent team. Creating Windows Terminal split panes...`);
3550
4056
  for (const [i, agent] of workerCommands.entries()) {
@@ -3724,7 +4230,7 @@ Keybindings:
3724
4230
  const provider = modelInfo?.provider ?? "anthropic";
3725
4231
  return { name: spec.name, agentType: spec.agentType, model: spec.model, provider, role: spec.role };
3726
4232
  });
3727
- const { TeamManager: TM } = await import('./team-manager-6DCNLGTC.js');
4233
+ const { TeamManager: TM } = await import('./team-manager-2VSMALAA.js');
3728
4234
  const manager = new TM();
3729
4235
  setActiveTeamManager(manager);
3730
4236
  setActiveTeamName(teamName);
@@ -3868,13 +4374,13 @@ function App({ config, options }) {
3868
4374
  const registryRef = useRef(void 0);
3869
4375
  const getRegistry = useCallback(async () => {
3870
4376
  if (registryRef.current !== void 0) return registryRef.current;
3871
- const { createDefaultRegistry } = await import('./registry-3NHVCXCZ.js');
4377
+ const { createDefaultRegistry } = await import('./registry-MVNSXCEF.js');
3872
4378
  registryRef.current = await createDefaultRegistry();
3873
4379
  return registryRef.current;
3874
4380
  }, []);
3875
4381
  const projectRootRef = useRef(process.cwd());
3876
4382
  useEffect(() => {
3877
- void import('./pathResolver-A6IXQQFE.js').then(({ findProjectRoot }) => {
4383
+ void import('./pathResolver-UVAB2FCW.js').then(({ findProjectRoot }) => {
3878
4384
  projectRootRef.current = findProjectRoot();
3879
4385
  }).catch(() => {
3880
4386
  });
@@ -3882,10 +4388,10 @@ function App({ config, options }) {
3882
4388
  useEffect(() => {
3883
4389
  void (async () => {
3884
4390
  try {
3885
- const { findProjectRoot } = await import('./pathResolver-A6IXQQFE.js');
4391
+ const { findProjectRoot } = await import('./pathResolver-UVAB2FCW.js');
3886
4392
  const root = findProjectRoot();
3887
4393
  projectRootRef.current = root;
3888
- const { loadInputHistory } = await import('./input-history-MIOO3FIW.js');
4394
+ const { loadInputHistory } = await import('./input-history-BEICE7PT.js');
3889
4395
  const history = await loadInputHistory(root);
3890
4396
  if (history.length > 0) setPersistentHistory(history);
3891
4397
  } catch {
@@ -3902,7 +4408,7 @@ function App({ config, options }) {
3902
4408
  }, []);
3903
4409
  useEffect(() => {
3904
4410
  if (options.isAgentPane) return;
3905
- void import('./detect-providers-C4SVQHFF.js').then(({ detectInstalledProviders }) => {
4411
+ void import('./detect-providers-QICJ5U3R.js').then(({ detectInstalledProviders }) => {
3906
4412
  const detected = detectInstalledProviders();
3907
4413
  if (detected.length > 0) setSwarmOnboardingDeferred(false);
3908
4414
  setSwarmConfig((prev) => {
@@ -3915,7 +4421,7 @@ function App({ config, options }) {
3915
4421
  useEffect(() => {
3916
4422
  void (async () => {
3917
4423
  try {
3918
- const { findProjectRoot } = await import('./pathResolver-A6IXQQFE.js');
4424
+ const { findProjectRoot } = await import('./pathResolver-UVAB2FCW.js');
3919
4425
  const projectRoot = findProjectRoot();
3920
4426
  projectRootRef.current = projectRoot;
3921
4427
  const { default: fg } = await import('fast-glob');
@@ -3942,8 +4448,8 @@ function App({ config, options }) {
3942
4448
  useEffect(() => {
3943
4449
  void (async () => {
3944
4450
  try {
3945
- const { SkillRegistry } = await import('./registry-7CQ3NCAD.js');
3946
- const { findProjectRoot } = await import('./pathResolver-A6IXQQFE.js');
4451
+ const { SkillRegistry } = await import('./registry-LRURZVUL.js');
4452
+ const { findProjectRoot } = await import('./pathResolver-UVAB2FCW.js');
3947
4453
  const registry = new SkillRegistry();
3948
4454
  await registry.initialize(findProjectRoot());
3949
4455
  const all = registry.listAll();
@@ -3957,7 +4463,7 @@ function App({ config, options }) {
3957
4463
  useEffect(() => {
3958
4464
  void (async () => {
3959
4465
  try {
3960
- const { discoverModels, getDisplayOrder } = await import('./model-discovery-O64ZWPX5.js');
4466
+ const { discoverModels, getDisplayOrder } = await import('./model-discovery-AAJDHRFO.js');
3961
4467
  await discoverModels();
3962
4468
  setModelDisplayOrder(getDisplayOrder());
3963
4469
  } catch {
@@ -4021,7 +4527,7 @@ function App({ config, options }) {
4021
4527
  return;
4022
4528
  }
4023
4529
  const userMessage = { id: v4Id(), role: "user", content: input, createdAt: /* @__PURE__ */ new Date() };
4024
- import('./input-history-MIOO3FIW.js').then(({ appendInputHistory }) => appendInputHistory(projectRootRef.current, input)).catch(() => {
4530
+ import('./input-history-BEICE7PT.js').then(({ appendInputHistory }) => appendInputHistory(projectRootRef.current, input)).catch(() => {
4025
4531
  });
4026
4532
  setMessages((prev) => [...prev, userMessage]);
4027
4533
  setIsProcessing(true);
@@ -4166,7 +4672,7 @@ ${methodLabel}: ${optionLabel}`, createdAt: /* @__PURE__ */ new Date() }]);
4166
4672
  fallbackMasterProviders: swarmConfig.detectedProviders.filter((p) => p !== primaryProvider)
4167
4673
  };
4168
4674
  try {
4169
- const { ConfigStore } = await import('./config-store-POB6I37G.js');
4675
+ const { ConfigStore } = await import('./config-store-NF56VHFU.js');
4170
4676
  const store = new ConfigStore();
4171
4677
  const currentConfig = store.loadGlobal();
4172
4678
  const nextProviders = { ...currentConfig.providers };
@@ -4255,7 +4761,7 @@ ${methodLabel}: ${optionLabel}`, createdAt: /* @__PURE__ */ new Date() }]);
4255
4761
  async function startChatSession(options) {
4256
4762
  let config;
4257
4763
  try {
4258
- const { ConfigStore } = await import('./config-store-POB6I37G.js');
4764
+ const { ConfigStore } = await import('./config-store-NF56VHFU.js');
4259
4765
  const store = new ConfigStore();
4260
4766
  config = store.loadGlobal();
4261
4767
  } catch {
@@ -4265,10 +4771,10 @@ async function startChatSession(options) {
4265
4771
  await waitUntilExit();
4266
4772
  }
4267
4773
  async function runFirstRunSetup() {
4268
- const { runFirstRunSetup: runCliFirstRunSetup } = await import('./first-run-GDEVRFPO.js');
4774
+ const { runFirstRunSetup: runCliFirstRunSetup } = await import('./first-run-ADROZVYF.js');
4269
4775
  await runCliFirstRunSetup();
4270
4776
  }
4271
4777
 
4272
4778
  export { runFirstRunSetup, startChatSession };
4273
- //# sourceMappingURL=App-YAHJUWCX.js.map
4274
- //# sourceMappingURL=App-YAHJUWCX.js.map
4779
+ //# sourceMappingURL=App-NT6MRKQJ.js.map
4780
+ //# sourceMappingURL=App-NT6MRKQJ.js.map