aicodeman 1.20.1 → 1.22.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 (286) hide show
  1. package/README.md +19 -15
  2. package/README.zh-CN.md +6 -20
  3. package/dist/cli-style.d.ts +115 -0
  4. package/dist/cli-style.d.ts.map +1 -0
  5. package/dist/cli-style.js +245 -0
  6. package/dist/cli-style.js.map +1 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +237 -186
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config/dependency-registry.d.ts.map +1 -1
  11. package/dist/config/dependency-registry.js +24 -0
  12. package/dist/config/dependency-registry.js.map +1 -1
  13. package/dist/config/instance.d.ts +9 -0
  14. package/dist/config/instance.d.ts.map +1 -1
  15. package/dist/config/instance.js +14 -0
  16. package/dist/config/instance.js.map +1 -1
  17. package/dist/cron/cron-service.d.ts +2 -1
  18. package/dist/cron/cron-service.d.ts.map +1 -1
  19. package/dist/cron/cron-service.js +3 -2
  20. package/dist/cron/cron-service.js.map +1 -1
  21. package/dist/docker-hosts.d.ts.map +1 -1
  22. package/dist/docker-hosts.js +11 -0
  23. package/dist/docker-hosts.js.map +1 -1
  24. package/dist/mux-interface.d.ts +3 -1
  25. package/dist/mux-interface.d.ts.map +1 -1
  26. package/dist/remote-hosts.d.ts.map +1 -1
  27. package/dist/remote-hosts.js +1 -0
  28. package/dist/remote-hosts.js.map +1 -1
  29. package/dist/session.d.ts +9 -3
  30. package/dist/session.d.ts.map +1 -1
  31. package/dist/session.js +29 -4
  32. package/dist/session.js.map +1 -1
  33. package/dist/state-store.d.ts +22 -0
  34. package/dist/state-store.d.ts.map +1 -1
  35. package/dist/state-store.js +45 -13
  36. package/dist/state-store.js.map +1 -1
  37. package/dist/tab-layout-legacy-order.d.ts +12 -0
  38. package/dist/tab-layout-legacy-order.d.ts.map +1 -0
  39. package/dist/tab-layout-legacy-order.js +58 -0
  40. package/dist/tab-layout-legacy-order.js.map +1 -0
  41. package/dist/tab-layout-persistence.d.ts +43 -0
  42. package/dist/tab-layout-persistence.d.ts.map +1 -0
  43. package/dist/tab-layout-persistence.js +100 -0
  44. package/dist/tab-layout-persistence.js.map +1 -0
  45. package/dist/tab-layout-service.d.ts +96 -0
  46. package/dist/tab-layout-service.d.ts.map +1 -0
  47. package/dist/tab-layout-service.js +535 -0
  48. package/dist/tab-layout-service.js.map +1 -0
  49. package/dist/tab-layout.d.ts +83 -0
  50. package/dist/tab-layout.d.ts.map +1 -0
  51. package/dist/tab-layout.js +457 -0
  52. package/dist/tab-layout.js.map +1 -0
  53. package/dist/tmux-manager.d.ts +2 -1
  54. package/dist/tmux-manager.d.ts.map +1 -1
  55. package/dist/tmux-manager.js +60 -10
  56. package/dist/tmux-manager.js.map +1 -1
  57. package/dist/tui/tui-ansi.d.ts +71 -0
  58. package/dist/tui/tui-ansi.d.ts.map +1 -0
  59. package/dist/tui/tui-ansi.js +576 -0
  60. package/dist/tui/tui-ansi.js.map +1 -0
  61. package/dist/tui/tui-app.d.ts +424 -0
  62. package/dist/tui/tui-app.d.ts.map +1 -0
  63. package/dist/tui/tui-app.js +2424 -0
  64. package/dist/tui/tui-app.js.map +1 -0
  65. package/dist/tui/tui-approvals.d.ts +71 -0
  66. package/dist/tui/tui-approvals.d.ts.map +1 -0
  67. package/dist/tui/tui-approvals.js +114 -0
  68. package/dist/tui/tui-approvals.js.map +1 -0
  69. package/dist/tui/tui-client.d.ts +581 -0
  70. package/dist/tui/tui-client.d.ts.map +1 -0
  71. package/dist/tui/tui-client.js +1359 -0
  72. package/dist/tui/tui-client.js.map +1 -0
  73. package/dist/tui/tui-composer.d.ts +83 -0
  74. package/dist/tui/tui-composer.d.ts.map +1 -0
  75. package/dist/tui/tui-composer.js +174 -0
  76. package/dist/tui/tui-composer.js.map +1 -0
  77. package/dist/tui/tui-digest.d.ts +27 -0
  78. package/dist/tui/tui-digest.d.ts.map +1 -0
  79. package/dist/tui/tui-digest.js +79 -0
  80. package/dist/tui/tui-digest.js.map +1 -0
  81. package/dist/tui/tui-keys.d.ts +57 -0
  82. package/dist/tui/tui-keys.d.ts.map +1 -0
  83. package/dist/tui/tui-keys.js +204 -0
  84. package/dist/tui/tui-keys.js.map +1 -0
  85. package/dist/tui/tui-layout.d.ts +70 -0
  86. package/dist/tui/tui-layout.d.ts.map +1 -0
  87. package/dist/tui/tui-layout.js +87 -0
  88. package/dist/tui/tui-layout.js.map +1 -0
  89. package/dist/tui/tui-model.d.ts +178 -0
  90. package/dist/tui/tui-model.d.ts.map +1 -0
  91. package/dist/tui/tui-model.js +502 -0
  92. package/dist/tui/tui-model.js.map +1 -0
  93. package/dist/tui/tui-render.d.ts +150 -0
  94. package/dist/tui/tui-render.d.ts.map +1 -0
  95. package/dist/tui/tui-render.js +784 -0
  96. package/dist/tui/tui-render.js.map +1 -0
  97. package/dist/tui/tui-sse.d.ts +79 -0
  98. package/dist/tui/tui-sse.d.ts.map +1 -0
  99. package/dist/tui/tui-sse.js +200 -0
  100. package/dist/tui/tui-sse.js.map +1 -0
  101. package/dist/tui/tui-types.d.ts +190 -0
  102. package/dist/tui/tui-types.d.ts.map +1 -0
  103. package/dist/tui/tui-types.js +16 -0
  104. package/dist/tui/tui-types.js.map +1 -0
  105. package/dist/types/app-state.d.ts +3 -0
  106. package/dist/types/app-state.d.ts.map +1 -1
  107. package/dist/types/app-state.js.map +1 -1
  108. package/dist/types/session.d.ts +30 -4
  109. package/dist/types/session.d.ts.map +1 -1
  110. package/dist/types/session.js +2 -1
  111. package/dist/types/session.js.map +1 -1
  112. package/dist/utils/cli-executable-resolver.d.ts +2 -2
  113. package/dist/utils/cli-executable-resolver.js +2 -2
  114. package/dist/utils/dependency-report.d.ts +21 -3
  115. package/dist/utils/dependency-report.d.ts.map +1 -1
  116. package/dist/utils/dependency-report.js +29 -10
  117. package/dist/utils/dependency-report.js.map +1 -1
  118. package/dist/utils/grok-cli-resolver.d.ts +61 -0
  119. package/dist/utils/grok-cli-resolver.d.ts.map +1 -0
  120. package/dist/utils/grok-cli-resolver.js +130 -0
  121. package/dist/utils/grok-cli-resolver.js.map +1 -0
  122. package/dist/utils/index.d.ts +1 -0
  123. package/dist/utils/index.d.ts.map +1 -1
  124. package/dist/utils/index.js +1 -0
  125. package/dist/utils/index.js.map +1 -1
  126. package/dist/web/ports/index.d.ts +1 -0
  127. package/dist/web/ports/index.d.ts.map +1 -1
  128. package/dist/web/ports/session-port.d.ts +1 -1
  129. package/dist/web/ports/session-port.d.ts.map +1 -1
  130. package/dist/web/ports/tab-layout-port.d.ts +7 -0
  131. package/dist/web/ports/tab-layout-port.d.ts.map +1 -0
  132. package/dist/web/ports/tab-layout-port.js +2 -0
  133. package/dist/web/ports/tab-layout-port.js.map +1 -0
  134. package/dist/web/public/admin-ui.js.gz +0 -0
  135. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  136. package/dist/web/public/app.84bf8955.js +36 -0
  137. package/dist/web/public/app.84bf8955.js.br +0 -0
  138. package/dist/web/public/app.84bf8955.js.gz +0 -0
  139. package/dist/web/public/approvals-ui.js.gz +0 -0
  140. package/dist/web/public/{constants.5abbd823.js → constants.189c7bff.js} +82 -8
  141. package/dist/web/public/constants.189c7bff.js.br +0 -0
  142. package/dist/web/public/constants.189c7bff.js.gz +0 -0
  143. package/dist/web/public/cron-ui.js.gz +0 -0
  144. package/dist/web/public/entrance-animations.js.gz +0 -0
  145. package/dist/web/public/home-sessions.js +5 -2
  146. package/dist/web/public/home-sessions.js.br +0 -0
  147. package/dist/web/public/home-sessions.js.gz +0 -0
  148. package/dist/web/public/i18n.34016b89.js +1 -0
  149. package/dist/web/public/i18n.34016b89.js.br +0 -0
  150. package/dist/web/public/i18n.34016b89.js.gz +0 -0
  151. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  152. package/dist/web/public/index.html +74 -13
  153. package/dist/web/public/index.html.br +0 -0
  154. package/dist/web/public/index.html.gz +0 -0
  155. package/dist/web/public/input-cjk.87f14251.js.gz +0 -0
  156. package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
  157. package/dist/web/public/mobile-handlers.0f83a608.js.gz +0 -0
  158. package/dist/web/public/mobile-overview.js +1 -0
  159. package/dist/web/public/mobile-overview.js.br +0 -0
  160. package/dist/web/public/mobile-overview.js.gz +0 -0
  161. package/dist/web/public/mobile.983f064e.css +1 -0
  162. package/dist/web/public/mobile.983f064e.css.br +0 -0
  163. package/dist/web/public/mobile.983f064e.css.gz +0 -0
  164. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  165. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  166. package/dist/web/public/{panels-ui.5e97a36e.js → panels-ui.7c667123.js} +77 -77
  167. package/dist/web/public/panels-ui.7c667123.js.br +0 -0
  168. package/dist/web/public/panels-ui.7c667123.js.gz +0 -0
  169. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  170. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  171. package/dist/web/public/readmymind-ui.js.gz +0 -0
  172. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  173. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  174. package/dist/web/public/session-lineage.js +15 -5
  175. package/dist/web/public/session-lineage.js.br +0 -0
  176. package/dist/web/public/session-lineage.js.gz +0 -0
  177. package/dist/web/public/session-ui.acd79900.js +68 -0
  178. package/dist/web/public/session-ui.acd79900.js.br +0 -0
  179. package/dist/web/public/session-ui.acd79900.js.gz +0 -0
  180. package/dist/web/public/settings-ui.115a2d1e.js +67 -0
  181. package/dist/web/public/settings-ui.115a2d1e.js.br +0 -0
  182. package/dist/web/public/settings-ui.115a2d1e.js.gz +0 -0
  183. package/dist/web/public/styles.64369ebd.css +1 -0
  184. package/dist/web/public/styles.64369ebd.css.br +0 -0
  185. package/dist/web/public/styles.64369ebd.css.gz +0 -0
  186. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  187. package/dist/web/public/sw.js.gz +0 -0
  188. package/dist/web/public/tab-rail-resize.f3465ce1.js +1 -0
  189. package/dist/web/public/tab-rail-resize.f3465ce1.js.br +0 -0
  190. package/dist/web/public/tab-rail-resize.f3465ce1.js.gz +0 -0
  191. package/dist/web/public/{terminal-ui.f70d681f.js → terminal-ui.ef68a666.js} +1 -1
  192. package/dist/web/public/terminal-ui.ef68a666.js.br +0 -0
  193. package/dist/web/public/terminal-ui.ef68a666.js.gz +0 -0
  194. package/dist/web/public/ultracode-panel.js.gz +0 -0
  195. package/dist/web/public/ultracode-windows.js.gz +0 -0
  196. package/dist/web/public/upload.html.gz +0 -0
  197. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  198. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  199. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  200. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  201. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  202. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  203. package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
  204. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
  205. package/dist/web/public/vendor/xterm.css.gz +0 -0
  206. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  207. package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
  208. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  209. package/dist/web/public/webview-tabs.js.gz +0 -0
  210. package/dist/web/response-viewer-transcript.js +1 -1
  211. package/dist/web/response-viewer-transcript.js.map +1 -1
  212. package/dist/web/routes/index.d.ts +1 -0
  213. package/dist/web/routes/index.d.ts.map +1 -1
  214. package/dist/web/routes/index.js +1 -0
  215. package/dist/web/routes/index.js.map +1 -1
  216. package/dist/web/routes/ralph-routes.js +1 -1
  217. package/dist/web/routes/ralph-routes.js.map +1 -1
  218. package/dist/web/routes/session-routes.d.ts +9 -4
  219. package/dist/web/routes/session-routes.d.ts.map +1 -1
  220. package/dist/web/routes/session-routes.js +68 -27
  221. package/dist/web/routes/session-routes.js.map +1 -1
  222. package/dist/web/routes/system-routes.d.ts +2 -2
  223. package/dist/web/routes/system-routes.d.ts.map +1 -1
  224. package/dist/web/routes/system-routes.js +15 -2
  225. package/dist/web/routes/system-routes.js.map +1 -1
  226. package/dist/web/routes/tab-layout-routes.d.ts +6 -0
  227. package/dist/web/routes/tab-layout-routes.d.ts.map +1 -0
  228. package/dist/web/routes/tab-layout-routes.js +45 -0
  229. package/dist/web/routes/tab-layout-routes.js.map +1 -0
  230. package/dist/web/routes/webview-routes.d.ts +2 -2
  231. package/dist/web/routes/webview-routes.d.ts.map +1 -1
  232. package/dist/web/routes/webview-routes.js +29 -1
  233. package/dist/web/routes/webview-routes.js.map +1 -1
  234. package/dist/web/schemas.d.ts +25 -1
  235. package/dist/web/schemas.d.ts.map +1 -1
  236. package/dist/web/schemas.js +47 -5
  237. package/dist/web/schemas.js.map +1 -1
  238. package/dist/web/server.d.ts +5 -0
  239. package/dist/web/server.d.ts.map +1 -1
  240. package/dist/web/server.js +101 -36
  241. package/dist/web/server.js.map +1 -1
  242. package/dist/web/session-order-sse.d.ts +7 -0
  243. package/dist/web/session-order-sse.d.ts.map +1 -0
  244. package/dist/web/session-order-sse.js +10 -0
  245. package/dist/web/session-order-sse.js.map +1 -0
  246. package/dist/web/sse-events.d.ts +5 -2
  247. package/dist/web/sse-events.d.ts.map +1 -1
  248. package/dist/web/sse-events.js +5 -2
  249. package/dist/web/sse-events.js.map +1 -1
  250. package/dist/web/sse-stream-manager.d.ts +9 -0
  251. package/dist/web/sse-stream-manager.d.ts.map +1 -1
  252. package/dist/web/sse-stream-manager.js +86 -27
  253. package/dist/web/sse-stream-manager.js.map +1 -1
  254. package/dist/web/tab-layout-sse.d.ts +4 -0
  255. package/dist/web/tab-layout-sse.d.ts.map +1 -0
  256. package/dist/web/tab-layout-sse.js +4 -0
  257. package/dist/web/tab-layout-sse.js.map +1 -0
  258. package/package.json +2 -1
  259. package/skills/codeman/reference/endpoints.md +12 -11
  260. package/skills/codeman/reference/messaging.md +2 -2
  261. package/skills/codeman/reference/recipes.md +1 -1
  262. package/skills/codeman/reference/verbs.md +3 -3
  263. package/dist/web/public/app.202140a2.js +0 -35
  264. package/dist/web/public/app.202140a2.js.br +0 -0
  265. package/dist/web/public/app.202140a2.js.gz +0 -0
  266. package/dist/web/public/constants.5abbd823.js.br +0 -0
  267. package/dist/web/public/constants.5abbd823.js.gz +0 -0
  268. package/dist/web/public/i18n.196a992e.js +0 -1
  269. package/dist/web/public/i18n.196a992e.js.br +0 -0
  270. package/dist/web/public/i18n.196a992e.js.gz +0 -0
  271. package/dist/web/public/mobile.49aeb17e.css +0 -1
  272. package/dist/web/public/mobile.49aeb17e.css.br +0 -0
  273. package/dist/web/public/mobile.49aeb17e.css.gz +0 -0
  274. package/dist/web/public/panels-ui.5e97a36e.js.br +0 -0
  275. package/dist/web/public/panels-ui.5e97a36e.js.gz +0 -0
  276. package/dist/web/public/session-ui.71a0ce9a.js +0 -68
  277. package/dist/web/public/session-ui.71a0ce9a.js.br +0 -0
  278. package/dist/web/public/session-ui.71a0ce9a.js.gz +0 -0
  279. package/dist/web/public/settings-ui.1a62e935.js +0 -67
  280. package/dist/web/public/settings-ui.1a62e935.js.br +0 -0
  281. package/dist/web/public/settings-ui.1a62e935.js.gz +0 -0
  282. package/dist/web/public/styles.68f9e118.css +0 -1
  283. package/dist/web/public/styles.68f9e118.css.br +0 -0
  284. package/dist/web/public/styles.68f9e118.css.gz +0 -0
  285. package/dist/web/public/terminal-ui.f70d681f.js.br +0 -0
  286. package/dist/web/public/terminal-ui.f70d681f.js.gz +0 -0
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <h2 align="center">Mission control for AI coding agents</h2>
6
6
 
7
7
  <p align="center">
8
- <em>Claude Code &bull; OpenCode &bull; Codex &bull; Antigravity &bull; Gemini &bull; Pi &bull; Terminal - One Dashboard &bull; Any Device</em>
8
+ <em>Claude Code &bull; OpenCode &bull; Codex &bull; Antigravity &bull; Gemini &bull; Pi &bull; Grok &bull; Terminal - One Dashboard &bull; Any Device</em>
9
9
  </p>
10
10
 
11
11
  <p align="center">
@@ -27,7 +27,7 @@
27
27
  <img src="docs/images/subagent-demo-20260724.gif" alt="Codeman — parallel subagent visualization" width="900">
28
28
  </p>
29
29
 
30
- **Codeman** is a self-hosted mission control for AI coding agents. It spawns Claude Code, OpenCode, Codex, Antigravity, Gemini, or Pi inside persistent tmux sessions, streams the real terminal to any browser, and keeps agents productive after you walk away: it re-prompts on idle, resumes when a usage limit resets, runs scheduled jobs, and shows every background agent working in real time.
30
+ **Codeman** is a self-hosted mission control for AI coding agents. It spawns Claude Code, OpenCode, Codex, Antigravity, Gemini, Pi, or Grok inside persistent tmux sessions, streams the real terminal to any browser, and keeps agents productive after you walk away: it re-prompts on idle, resumes when a usage limit resets, runs scheduled jobs, and shows every background agent working in real time.
31
31
 
32
32
  Get started in one line (macOS & Linux, Windows via WSL):
33
33
 
@@ -42,7 +42,7 @@ codeman web
42
42
 
43
43
  The installer asks before every system change, and re-running the same line updates in place. Full details: [Quick Start - Installation](#quick-start---installation).
44
44
 
45
- - **One dashboard, six CLIs** - run [Claude Code, OpenCode, Codex, Antigravity, Gemini, or Pi](#more-features) per session (plus plain shell), locally, [in Docker](#isolated-docker-sessions), or [over SSH](#remote-ssh-sessions)
45
+ - **One dashboard, seven CLIs** - run [Claude Code, OpenCode, Codex, Antigravity, Gemini, Pi, or Grok](#more-features) per session (plus plain shell), locally, [in Docker](#isolated-docker-sessions), or [over SSH](#remote-ssh-sessions)
46
46
  - **Truly phone-friendly** - a [touch-optimized terminal](#mobile-optimized-web-ui) with instant local echo, QR login, swipe navigation, and push notifications
47
47
  - **Runs while you sleep** - [idle detection + respawn cycling](#respawn-controller) and auto-resume when a subscription limit resets, for 24+ hour unattended runs
48
48
  - **See your agents think** - [live floating windows](#live-agent-visualization) for every subagent and teammate, with real-time transcripts
@@ -68,7 +68,7 @@ This installs Node.js and tmux if missing, clones Codeman to `~/.codeman/app`, a
68
68
  - **Re-run to update.** The same one-liner updates a finished install in place: local changes in `~/.codeman/app` are stashed (never discarded), and a running service is restarted and verified. If a first install was interrupted, re-running resumes the full setup instead. `install.sh update` and `install.sh uninstall` also exist.
69
69
  - **CI / headless:** without a terminal attached, steps that would change your system abort with instructions instead of running silently. Set `CODEMAN_NONINTERACTIVE=1` to approve them for automation.
70
70
 
71
- You'll need at least one AI coding CLI installed — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Pi](https://pi.dev) (any combination works; Gemini CLI is enterprise-only since Google's consumer cutover, and Antigravity is its successor). The installer detects whichever of the six is present; if none is found, it offers to install Claude Code or OpenCode, or you can skip and install one yourself later. After install:
71
+ You'll need at least one AI coding CLI installed — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Pi](https://pi.dev), or [Grok Build](https://github.com/xai-org/grok-build) (any combination works; Gemini CLI is enterprise-only since Google's consumer cutover, and Antigravity is its successor). The installer detects whichever of the seven is present; if none is found, it offers to install Claude Code or OpenCode, or you can skip and install one yourself later. After install:
72
72
 
73
73
  ```bash
74
74
  codeman web
@@ -171,7 +171,7 @@ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.codeman.web.plist
171
171
  wsl bash -c "curl -fsSL https://getcodeman.com/install | bash"
172
172
  ```
173
173
 
174
- Codeman requires tmux, so Windows users need [WSL](https://learn.microsoft.com/en-us/windows/wsl/install). If you don't have WSL yet: run `wsl --install` in an admin PowerShell, reboot, open Ubuntu, then install your preferred AI coding CLI inside WSL ([Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Pi](https://pi.dev)). After installing, `http://localhost:3000` is accessible from your Windows browser.
174
+ Codeman requires tmux, so Windows users need [WSL](https://learn.microsoft.com/en-us/windows/wsl/install). If you don't have WSL yet: run `wsl --install` in an admin PowerShell, reboot, open Ubuntu, then install your preferred AI coding CLI inside WSL ([Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Pi](https://pi.dev), or [Grok Build](https://github.com/xai-org/grok-build)). After installing, `http://localhost:3000` is accessible from your Windows browser.
175
175
 
176
176
  </details>
177
177
 
@@ -253,7 +253,7 @@ Click **+ New Session** (or **Quick Start**). A session is one AI CLI running in
253
253
  | Field | What it does |
254
254
  | ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
255
255
  | **Working directory / case** | The folder the agent operates in. A "case" is just a named working dir Codeman remembers. **Add Case** creates one from scratch, links an existing folder, or clones a GitHub repo straight into one (**Clone Repo**). |
256
- | **CLI / run mode** | `Claude` (default), `OpenCode`, `Codex`, `Antigravity`, `Gemini`, `Pi`, or `Terminal` (plain shell). |
256
+ | **CLI / run mode** | `Claude` (default), `OpenCode`, `Codex`, `Antigravity`, `Gemini`, `Pi`, `Grok`, or `Terminal` (plain shell). |
257
257
  | **Model** | Per-session model (App Settings → Models → New Claude sessions). A soft default — `/model` still works in-session. |
258
258
  | **Effort / Ultracode** | Reasoning effort (`low`–`max`) or `ultracode` for dynamic multi-agent workflows. Switchable anytime with `/effort`. |
259
259
 
@@ -285,7 +285,7 @@ Hit start — Codeman spawns the CLI via a real PTY and streams it to your brows
285
285
 
286
286
  - **Phone/tablet** — the UI is fully touch-optimized; scan the desktop **QR code** to log in without typing a password.
287
287
  - **Outside your network** — `./scripts/tunnel.sh start` opens a Cloudflare tunnel (set `CODEMAN_PASSWORD` first).
288
- - **SSH** — the `sc` chooser attaches to any session from a terminal (`sc` interactive, `sc 2` quick-attach, `sc -l` list).
288
+ - **SSH** — `codeman tui` is a full-screen dashboard in the terminal (`codeman tui --list` to list, `codeman tui 2` to attach straight to one).
289
289
 
290
290
  ### 7. Operate & maintain
291
291
 
@@ -437,7 +437,7 @@ PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xt
437
437
  - **Background daemon & service install** — `codeman web -d` runs the server detached with a pidfile, `~/.codeman/web.log`, and verified startup (it polls the server until it answers, so a port clash never reads as success); `codeman service install` writes a systemd user unit (Linux) or LaunchAgent (macOS) with your shell's PATH baked in, so an nvm or Homebrew `node`, `tmux` and `claude` are actually found. Secrets are never written into unit files
438
438
  - **Self-update** — git-clone installs under systemd/launchd update in place from **App Settings → System → Updates**: it detects the latest release, auto-stashes a dirty tree, and streams build progress across the service restart (npm installs report as non-updatable)
439
439
  - **Clone a GitHub repo as a case** — paste a repository URL into **Add Case → Clone Repo** and Codeman clones it into `~/codeman-cases/<name>` and registers it as a normal case, ready to run an agent in. It preflights the URL while you type (tells you whether it can be cloned anonymously and offers the repo's real branches and tags for the optional branch/tag field), fills the case name in from the URL, and lets you pick which CLI the Run button should use. Public repositories over `https://`; Codeman never collects or stores credentials
440
- - **Multi-CLI** — run **Claude Code**, **OpenCode**, **Codex**, **Antigravity**, **Gemini**, or **Pi** per session; env-var prefixes auto-gate (`CLAUDE_CODE_*` vs `OPENCODE_*` vs `CODEX_*` vs `ANTIGRAVITY_*` vs `GEMINI_*`/`GOOGLE_*` vs `PI_*`). See [`docs/opencode-integration.md`](docs/opencode-integration.md) and [`docs/pi-integration.md`](docs/pi-integration.md)
440
+ - **Multi-CLI** — run **Claude Code**, **OpenCode**, **Codex**, **Antigravity**, **Gemini**, **Pi**, or **Grok** per session; env-var prefixes auto-gate (`CLAUDE_CODE_*` vs `OPENCODE_*` vs `CODEX_*` vs `ANTIGRAVITY_*` vs `GEMINI_*`/`GOOGLE_*` vs `PI_*` vs `GROK_*`/`XAI_*`). See [`docs/opencode-integration.md`](docs/opencode-integration.md), [`docs/pi-integration.md`](docs/pi-integration.md) and [`docs/grok-integration.md`](docs/grok-integration.md)
441
441
  - **Docker sessions** — run a case inside an isolated, hardened container. One checkbox on **Create New** spins up a container with sensible defaults and starts the agent inside it; multiple sessions share one per-case container; export a container + its workspace to a portable `.tar.gz` to move it to another machine. See [`docs/docker-cases.md`](docs/docker-cases.md)
442
442
  - **Remote SSH sessions** — point a case at another machine and run the agent there inside a durable remote tmux: survives SSH drops, auto-reconnects, and can discover + attach sessions already running on the host. See [`docs/remote-sessions.md`](docs/remote-sessions.md)
443
443
  - **Effort & Ultracode** — set a per-session default effort (`low`–`max`) or enable **ultracode** (dynamic multi-agent workflows). Soft defaults only — switchable anytime with `/effort` in-session. Extended-thinking budget is configurable too
@@ -658,17 +658,19 @@ These run for **every** request — before auth, even on the default no-password
658
658
 
659
659
  ---
660
660
 
661
- ## SSH Alternative (`sc`)
661
+ ## Terminal UI (`codeman tui`)
662
662
 
663
- If you prefer SSH (Termius, Blink, etc.), the `sc` command is a thumb-friendly session chooser:
663
+ A full-screen dashboard for your sessions, in the terminal. Same states as the web UI, because it is a client of the same server:
664
664
 
665
665
  ```bash
666
- sc # Interactive chooser
667
- sc 2 # Quick attach to session 2
668
- sc -l # List sessions
666
+ codeman tui # the dashboard
667
+ codeman tui --list # numbered session list, then exit (scriptable)
668
+ codeman tui 2 # attach straight to session 2 of that list
669
669
  ```
670
670
 
671
- Single-digit selection (1-9), color-coded status, token counts, auto-refresh. Detach with `Ctrl+A D`.
671
+ Sessions are grouped **NEEDS YOU → WORKING → IDLE → RECENT**, longest-waiting first. `↑↓`/`j`/`k` select, `1`-`9` and `[`/`]` switch between sessions, `Enter` attaches into the tmux pane (**`F1`** to come back). Inside a pane the bar across the top keeps the session strip visible and `Alt+1`-`Alt+9` switch without leaving. `y`/`n`/digit answer a pending permission dialog right from the list, `p` sends a one-line prompt, `n` starts a session and opens straight into it, `x` kills one (`y` confirms), `/` searches, `g` shows the away digest, `?` is help, `q` quits. Below 72 columns it drops the preview pane and becomes a single-column list, so it stays usable in Termius on a phone. With no server running it still starts in attach-only degraded mode.
672
+
673
+ The web UI remains the primary surface; see **[docs/tui.md](docs/tui.md)** for the full guide.
672
674
 
673
675
  ---
674
676
 
@@ -893,7 +895,9 @@ codeman session start -d /path/to/repo # (s) start a session
893
895
  codeman session list # list sessions
894
896
  codeman session logs <id> # tail output
895
897
  codeman task add "fix the failing test" # (t) queue a task
896
- codeman attach <path> # attach a Claude hook context
898
+ codeman attach <path> # show an attachment card for a local file
899
+ codeman tui --list # numbered session list (plain text when piped)
900
+ codeman tui 3 # attach to session 3 of that list
897
901
  ```
898
902
 
899
903
  ### Hooks (events flowing _back_ to Codeman)
package/README.zh-CN.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <h2 align="center">AI 编程智能体的任务控制中心</h2>
6
6
 
7
7
  <p align="center">
8
- <em>Claude Code &bull; OpenCode &bull; Codex &bull; Antigravity &bull; Gemini &bull; Pi &bull; 终端 —— 统一仪表盘 &bull; 任意设备</em>
8
+ <em>Claude Code &bull; OpenCode &bull; Codex &bull; Antigravity &bull; Gemini &bull; Pi &bull; Grok &bull; 终端 —— 统一仪表盘 &bull; 任意设备</em>
9
9
  </p>
10
10
 
11
11
  <p align="center">
@@ -58,7 +58,7 @@ curl -fsSL https://getcodeman.com/install | bash
58
58
  - **重跑即更新。** 再次运行同一条命令即可原地更新已完成的安装:`~/.codeman/app` 中的本地改动会被 stash(绝不丢弃),运行中的服务会自动重启并校验。若首次安装中途失败,重跑会继续完成完整的安装流程。也可以使用 `install.sh update` 与 `install.sh uninstall`。
59
59
  - **CI / 无终端环境:** 没有终端时,涉及系统改动的步骤会带着说明中止,而不是静默执行;在自动化场景设置 `CODEMAN_NONINTERACTIVE=1` 即可批准这些步骤。
60
60
 
61
- 你至少需要安装一个 AI 编程 CLI —— [Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[OpenCode](https://opencode.ai)、[Codex](https://developers.openai.com/codex/cli)、[Antigravity](https://antigravity.google)、[Gemini CLI](https://github.com/google-gemini/gemini-cli)[Pi](https://pi.dev)(任意组合均可;自 Google 面向消费者停售后,Gemini CLI 仅限企业版,Antigravity 是其继任者)。安装器会自动检测这六个中已安装的任意一个;若一个都没有,会提供安装 Claude Code 或 OpenCode 的选项,也可以选择跳过、稍后自行安装。安装完成后:
61
+ 你至少需要安装一个 AI 编程 CLI —— [Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[OpenCode](https://opencode.ai)、[Codex](https://developers.openai.com/codex/cli)、[Antigravity](https://antigravity.google)、[Gemini CLI](https://github.com/google-gemini/gemini-cli)[Pi](https://pi.dev) 或 [Grok Build](https://github.com/xai-org/grok-build)(任意组合均可;自 Google 面向消费者停售后,Gemini CLI 仅限企业版,Antigravity 是其继任者)。安装器会自动检测这七个中已安装的任意一个;若一个都没有,会提供安装 Claude Code 或 OpenCode 的选项,也可以选择跳过、稍后自行安装。安装完成后:
62
62
 
63
63
  ```bash
64
64
  codeman web
@@ -141,7 +141,7 @@ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.codeman.web.plist
141
141
  wsl bash -c "curl -fsSL https://getcodeman.com/install | bash"
142
142
  ```
143
143
 
144
- Codeman 依赖 tmux,因此 Windows 用户需要 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)。如果还没装 WSL:在管理员 PowerShell 中运行 `wsl --install`,重启,打开 Ubuntu,然后在 WSL 内安装你偏好的 AI 编程 CLI([Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[OpenCode](https://opencode.ai)、[Codex](https://developers.openai.com/codex/cli)、[Antigravity](https://antigravity.google)、[Gemini CLI](https://github.com/google-gemini/gemini-cli)[Pi](https://pi.dev))。安装完成后,即可从 Windows 浏览器访问 `http://localhost:3000`。
144
+ Codeman 依赖 tmux,因此 Windows 用户需要 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)。如果还没装 WSL:在管理员 PowerShell 中运行 `wsl --install`,重启,打开 Ubuntu,然后在 WSL 内安装你偏好的 AI 编程 CLI([Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[OpenCode](https://opencode.ai)、[Codex](https://developers.openai.com/codex/cli)、[Antigravity](https://antigravity.google)、[Gemini CLI](https://github.com/google-gemini/gemini-cli)[Pi](https://pi.dev) 或 [Grok Build](https://github.com/xai-org/grok-build))。安装完成后,即可从 Windows 浏览器访问 `http://localhost:3000`。
145
145
 
146
146
  </details>
147
147
 
@@ -221,7 +221,7 @@ codeman web -H 0.0.0.0 # 绑定局域网 —— 必须设置 CODEMAN_
221
221
  | 字段 | 作用 |
222
222
  | ---------------------- | ------------------------------------------------------------------------------------------- |
223
223
  | **工作目录 / case** | 智能体操作的文件夹。「case」就是一个 Codeman 记住的命名工作目录。 |
224
- | **CLI / 运行模式** | `Claude`(默认)、`OpenCode`、`Codex`、`Antigravity`、`Gemini`、`Pi` 或 `Terminal`(普通 shell)。 |
224
+ | **CLI / 运行模式** | `Claude`(默认)、`OpenCode`、`Codex`、`Antigravity`、`Gemini`、`Pi`、`Grok` 或 `Terminal`(普通 shell)。 |
225
225
  | **模型** | 每会话模型(App Settings → Claude Model)。软默认值 —— 会话内 `/model` 依然有效。 |
226
226
  | **Effort / Ultracode** | 推理力度(`low`–`max`),或用 `ultracode` 开启动态多智能体工作流。随时可用 `/effort` 切换。 |
227
227
 
@@ -253,7 +253,7 @@ codeman web -H 0.0.0.0 # 绑定局域网 —— 必须设置 CODEMAN_
253
253
 
254
254
  - **手机/平板** —— UI 完全触控优化;扫描桌面上的**二维码**即可免密码登录。
255
255
  - **网络之外** —— `./scripts/tunnel.sh start` 打开一条 Cloudflare 隧道(先设置 `CODEMAN_PASSWORD`)。
256
- - **SSH** —— `sc` 选择器可从终端附着任意会话(`sc` 交互式,`sc 2` 快速附着,`sc -l` 列表)。
256
+ - **SSH** —— `codeman tui` 是终端里的全屏会话面板(`codeman tui --list` 列出,`codeman tui 2` 直接附着到某个会话)。
257
257
 
258
258
  ### 7. 运维与维护
259
259
 
@@ -394,7 +394,7 @@ PTY 输出 → 16ms 服务端批处理 → DEC 2026 包裹 → SSE → 客户端
394
394
  ## 更多特性
395
395
 
396
396
  - **自更新** —— systemd/launchd 管理下的 git-clone 安装可在 **App Settings → Updates** 中原地更新:它会检测最新发行版,自动暂存(stash)脏工作树,并在服务重启期间流式展示构建进度(npm 安装会被报告为不可更新)
397
- - **多 CLI** —— 每个会话可选 **Claude Code**、**OpenCode**、**Codex**、**Antigravity**、**Gemini** 或 **Pi**;环境变量前缀自动隔离(`CLAUDE_CODE_*`、`OPENCODE_*`、`CODEX_*`、`ANTIGRAVITY_*`、`PI_*` 与 `GEMINI_*`/`GOOGLE_*`)。详见 [`docs/opencode-integration.md`](docs/opencode-integration.md) 与 [`docs/pi-integration.md`](docs/pi-integration.md)
397
+ - **多 CLI** —— 每个会话可选 **Claude Code**、**OpenCode**、**Codex**、**Antigravity**、**Gemini**、**Pi** 或 **Grok**;环境变量前缀自动隔离(`CLAUDE_CODE_*`、`OPENCODE_*`、`CODEX_*`、`ANTIGRAVITY_*`、`PI_*`、`GROK_*`/`XAI_*` 与 `GEMINI_*`/`GOOGLE_*`)。详见 [`docs/opencode-integration.md`](docs/opencode-integration.md)、[`docs/pi-integration.md`](docs/pi-integration.md) 与 [`docs/grok-integration.md`](docs/grok-integration.md)
398
398
  - **Docker 会话** —— 在隔离且加固的容器中运行案例。**Create New** 上勾选一个复选框即可用合理的默认值启动容器并在其中启动智能体;同一案例的多个会话共享一个容器;可将容器连同工作区导出为可移植的 `.tar.gz`,迁移到另一台机器。详见 [`docs/docker-cases.md`](docs/docker-cases.md)
399
399
  - **远程 SSH 会话**:把案例指向另一台机器,让智能体在那里一个持久的远程 tmux 中运行:SSH 断连不中断任务、自动重连,还能发现并附着主机上已在运行的会话。详见 [`docs/remote-sessions.md`](docs/remote-sessions.md)
400
400
  - **Effort 与 Ultracode** —— 设置每会话的默认 effort(`low`–`max`),或启用 **ultracode**(动态多智能体工作流)。这些都只是软默认值 —— 会话中可随时用 `/effort` 切换。扩展思考预算也可配置
@@ -615,20 +615,6 @@ Codeman 默认用 `--dangerously-skip-permissions` 启动会话,因此 Web UI
615
615
 
616
616
  ---
617
617
 
618
- ## SSH 替代方案(`sc`)
619
-
620
- 如果你更喜欢 SSH(Termius、Blink 等),`sc` 命令是一个便于拇指操作的会话选择器:
621
-
622
- ```bash
623
- sc # 交互式选择器
624
- sc 2 # 快速附着到会话 2
625
- sc -l # 列出会话
626
- ```
627
-
628
- 单数字选择(1–9)、颜色编码的状态、token 计数、自动刷新。用 `Ctrl+A D` 分离。
629
-
630
- ---
631
-
632
618
  ## 键盘快捷键
633
619
 
634
620
  > Ctrl 绑定在 macOS 上也接受 Cmd。
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @fileoverview One style vocabulary for everything the `codeman` CLI prints:
3
+ * palette, glyphs, the small block helpers (heading/rule/kv), width-aware table
4
+ * layout, a stderr spinner and a y/N confirm.
5
+ *
6
+ * Color detection is chalk's alone. It already honors NO_COLOR, FORCE_COLOR,
7
+ * TERM=dumb and TTY-ness, and a second detector here would disagree with it on
8
+ * some terminal with no way to tell which one was right.
9
+ *
10
+ * The layout math is pure and exported separately from anything that touches a
11
+ * terminal, which is what lets it be unit-tested with no TTY and reused by
12
+ * `utils/dependency-report.ts` while that file stays color-free.
13
+ *
14
+ * @module cli-style
15
+ */
16
+ import { type ChalkInstance } from 'chalk';
17
+ /** Semantic roles, mirroring the web UI's status language (green fine, yellow waiting, red blocked). */
18
+ export declare const palette: {
19
+ readonly ok: ChalkInstance;
20
+ readonly warn: ChalkInstance;
21
+ readonly err: ChalkInstance;
22
+ readonly info: ChalkInstance;
23
+ readonly muted: ChalkInstance;
24
+ readonly emph: ChalkInstance;
25
+ readonly accent: ChalkInstance;
26
+ };
27
+ /** The glyph vocabulary the CLI already used, in one place. */
28
+ export declare const GLYPH: {
29
+ readonly ok: "✓";
30
+ readonly fail: "✗";
31
+ readonly warn: "⚠";
32
+ readonly idle: "○";
33
+ readonly dot: "●";
34
+ readonly arrow: "→";
35
+ };
36
+ /** Spinner frames (braille, one cell wide in every terminal we support). */
37
+ export declare const SPINNER_FRAMES: readonly ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
38
+ /** What a line is reporting, independent of how it is painted. */
39
+ export type Tone = 'ok' | 'warn' | 'err' | 'idle' | 'info';
40
+ /** Glyph for a tone. Pure, so the mapping is testable without a terminal. */
41
+ export declare function glyphFor(tone: Tone): string;
42
+ /** Paint text in a tone's color. */
43
+ export declare function tint(tone: Tone, text: string): string;
44
+ /** Section heading. The blank line above it is part of the existing block idiom. */
45
+ export declare function heading(text: string): string;
46
+ /** Horizontal rule under a title. */
47
+ export declare function rule(width?: number): string;
48
+ /**
49
+ * Indented `Label: value` line. `pad` aligns the values of a block by padding
50
+ * the label column (including its colon), for blocks whose labels differ in
51
+ * length.
52
+ */
53
+ export declare function kv(label: string, value: string, pad?: number): string;
54
+ /** Printed width of a cell: ANSI sequences take no columns. */
55
+ export declare function displayWidth(text: string): number;
56
+ export type CellAlign = 'left' | 'right';
57
+ /** Pad to `width` columns, measuring by display width so colored cells still align. */
58
+ export declare function padCell(text: string, width: number, align?: CellAlign): string;
59
+ /**
60
+ * Pad AFTER the paint, so the fill stays outside the color run and a trailing
61
+ * empty column can be trimmed away instead of ending in a reset sequence with
62
+ * invisible spaces before it.
63
+ */
64
+ export declare function padStyled(text: string, width: number, paint: (t: string) => string): string;
65
+ /** Widest cell per column. Short rows count as empty cells, never as narrower columns. */
66
+ export declare function columnWidths(rows: readonly (readonly string[])[]): number[];
67
+ export interface TableOptions {
68
+ /** Per-column alignment; missing entries are left-aligned. */
69
+ align?: readonly CellAlign[];
70
+ /** Spaces between columns. */
71
+ gap?: number;
72
+ /** Prefix for every row. */
73
+ indent?: string;
74
+ }
75
+ /**
76
+ * Lay rows out in columns sized to their widest cell. The last cell of a row is
77
+ * never padded, so no line carries trailing whitespace.
78
+ */
79
+ export declare function layoutTable(rows: readonly (readonly string[])[], options?: TableOptions): string[];
80
+ /** `layoutTable()` as one printable block. */
81
+ export declare function table(rows: readonly (readonly string[])[], options?: TableOptions): string;
82
+ /** The slice of a stream a spinner needs; `process.stderr` satisfies it. */
83
+ export interface SpinnerStream {
84
+ isTTY?: boolean;
85
+ write(chunk: string): unknown;
86
+ }
87
+ export interface Spinner {
88
+ start(): Spinner;
89
+ /** Change the text mid-flight. Silent on a non-TTY, which prints once and stops. */
90
+ setText(text: string): void;
91
+ /** Clear the line, restore the cursor and optionally print a final line. */
92
+ stop(finalLine?: string): void;
93
+ }
94
+ export interface SpinnerOptions {
95
+ stream?: SpinnerStream;
96
+ intervalMs?: number;
97
+ }
98
+ /**
99
+ * In-place progress line on stderr, for the calls that block for tens of seconds
100
+ * (daemon start, service install). Only a TTY gets the animation: piped output
101
+ * and journald get the text once, so a log file never fills with `\r` frames.
102
+ */
103
+ export declare function spinner(text: string, options?: SpinnerOptions): Spinner;
104
+ /** Run `work` with a spinner up, stopping it however `work` ends. */
105
+ export declare function withSpinner<T>(text: string, work: () => Promise<T>, options?: SpinnerOptions): Promise<T>;
106
+ /** Is there a human on the other end of both halves of the terminal? */
107
+ export declare function isInteractive(): boolean;
108
+ /**
109
+ * y/N prompt. Answers `false` immediately when stdin is not a TTY (a script
110
+ * piping into the CLI must never hang on an invisible question), so callers
111
+ * that support a `--force` flag can branch on `isInteractive()` to keep printing
112
+ * their "pass --force" hint instead.
113
+ */
114
+ export declare function confirm(question: string): Promise<boolean>;
115
+ //# sourceMappingURL=cli-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-style.d.ts","sourceRoot":"","sources":["../src/cli-style.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * @fileoverview One style vocabulary for everything the `codeman` CLI prints:
3
+ * palette, glyphs, the small block helpers (heading/rule/kv), width-aware table
4
+ * layout, a stderr spinner and a y/N confirm.
5
+ *
6
+ * Color detection is chalk's alone. It already honors NO_COLOR, FORCE_COLOR,
7
+ * TERM=dumb and TTY-ness, and a second detector here would disagree with it on
8
+ * some terminal with no way to tell which one was right.
9
+ *
10
+ * The layout math is pure and exported separately from anything that touches a
11
+ * terminal, which is what lets it be unit-tested with no TTY and reused by
12
+ * `utils/dependency-report.ts` while that file stays color-free.
13
+ *
14
+ * @module cli-style
15
+ */
16
+ import chalk from 'chalk';
17
+ import { createInterface } from 'node:readline';
18
+ // Direct import, not the `utils` barrel: the barrel pulls in node-pty and every
19
+ // CLI resolver, which a style module has no business loading.
20
+ import { stripAnsi } from './utils/regex-patterns.js';
21
+ // ─────────────────────────────────────────────────────────────────────────────
22
+ // Palette and glyphs
23
+ // ─────────────────────────────────────────────────────────────────────────────
24
+ /** Semantic roles, mirroring the web UI's status language (green fine, yellow waiting, red blocked). */
25
+ export const palette = {
26
+ ok: chalk.green,
27
+ warn: chalk.yellow,
28
+ err: chalk.red,
29
+ info: chalk.cyan,
30
+ muted: chalk.gray,
31
+ emph: chalk.bold,
32
+ accent: chalk.magenta,
33
+ };
34
+ /** The glyph vocabulary the CLI already used, in one place. */
35
+ export const GLYPH = {
36
+ ok: '✓',
37
+ fail: '✗',
38
+ warn: '⚠',
39
+ idle: '○',
40
+ dot: '●',
41
+ arrow: '→',
42
+ };
43
+ /** Spinner frames (braille, one cell wide in every terminal we support). */
44
+ export const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
45
+ const TONE_GLYPH = {
46
+ ok: GLYPH.ok,
47
+ warn: GLYPH.warn,
48
+ err: GLYPH.fail,
49
+ idle: GLYPH.idle,
50
+ info: GLYPH.dot,
51
+ };
52
+ const TONE_STYLE = {
53
+ ok: palette.ok,
54
+ warn: palette.warn,
55
+ err: palette.err,
56
+ idle: palette.muted,
57
+ info: palette.info,
58
+ };
59
+ /** Glyph for a tone. Pure, so the mapping is testable without a terminal. */
60
+ export function glyphFor(tone) {
61
+ return TONE_GLYPH[tone];
62
+ }
63
+ /** Paint text in a tone's color. */
64
+ export function tint(tone, text) {
65
+ return TONE_STYLE[tone](text);
66
+ }
67
+ // ─────────────────────────────────────────────────────────────────────────────
68
+ // Blocks
69
+ // ─────────────────────────────────────────────────────────────────────────────
70
+ /** Section heading. The blank line above it is part of the existing block idiom. */
71
+ export function heading(text) {
72
+ return `\n${palette.emph(text)}`;
73
+ }
74
+ /** Horizontal rule under a title. */
75
+ export function rule(width = 40) {
76
+ return palette.muted('─'.repeat(Math.max(0, width)));
77
+ }
78
+ /**
79
+ * Indented `Label: value` line. `pad` aligns the values of a block by padding
80
+ * the label column (including its colon), for blocks whose labels differ in
81
+ * length.
82
+ */
83
+ export function kv(label, value, pad = 0) {
84
+ const key = pad > 0 ? padCell(`${label}:`, pad) : `${label}:`;
85
+ return ` ${key} ${value}`;
86
+ }
87
+ // ─────────────────────────────────────────────────────────────────────────────
88
+ // Width-aware layout (pure)
89
+ // ─────────────────────────────────────────────────────────────────────────────
90
+ /** Printed width of a cell: ANSI sequences take no columns. */
91
+ export function displayWidth(text) {
92
+ return stripAnsi(text).length;
93
+ }
94
+ /** Pad to `width` columns, measuring by display width so colored cells still align. */
95
+ export function padCell(text, width, align = 'left') {
96
+ const fill = ' '.repeat(Math.max(0, width - displayWidth(text)));
97
+ return align === 'right' ? `${fill}${text}` : `${text}${fill}`;
98
+ }
99
+ /**
100
+ * Pad AFTER the paint, so the fill stays outside the color run and a trailing
101
+ * empty column can be trimmed away instead of ending in a reset sequence with
102
+ * invisible spaces before it.
103
+ */
104
+ export function padStyled(text, width, paint) {
105
+ return `${paint(text)}${' '.repeat(Math.max(0, width - displayWidth(text)))}`;
106
+ }
107
+ /** Widest cell per column. Short rows count as empty cells, never as narrower columns. */
108
+ export function columnWidths(rows) {
109
+ const widths = [];
110
+ for (const row of rows) {
111
+ for (let i = 0; i < row.length; i++) {
112
+ widths[i] = Math.max(widths[i] ?? 0, displayWidth(row[i] ?? ''));
113
+ }
114
+ }
115
+ return widths;
116
+ }
117
+ /**
118
+ * Lay rows out in columns sized to their widest cell. The last cell of a row is
119
+ * never padded, so no line carries trailing whitespace.
120
+ */
121
+ export function layoutTable(rows, options = {}) {
122
+ const { align = [], gap = 1, indent = '' } = options;
123
+ const widths = columnWidths(rows);
124
+ const separator = ' '.repeat(Math.max(0, gap));
125
+ return rows.map((row) => {
126
+ const cells = row.map((cell, i) => (i === row.length - 1 ? cell : padCell(cell, widths[i], align[i] ?? 'left')));
127
+ return `${indent}${cells.join(separator)}`;
128
+ });
129
+ }
130
+ /** `layoutTable()` as one printable block. */
131
+ export function table(rows, options = {}) {
132
+ return layoutTable(rows, options).join('\n');
133
+ }
134
+ // ─────────────────────────────────────────────────────────────────────────────
135
+ // Spinner
136
+ // ─────────────────────────────────────────────────────────────────────────────
137
+ const HIDE_CURSOR = '\x1b[?25l';
138
+ const SHOW_CURSOR = '\x1b[?25h';
139
+ const CLEAR_LINE = '\x1b[K';
140
+ /**
141
+ * In-place progress line on stderr, for the calls that block for tens of seconds
142
+ * (daemon start, service install). Only a TTY gets the animation: piped output
143
+ * and journald get the text once, so a log file never fills with `\r` frames.
144
+ */
145
+ export function spinner(text, options = {}) {
146
+ const stream = options.stream ?? process.stderr;
147
+ const intervalMs = options.intervalMs ?? 90;
148
+ const animated = Boolean(stream.isTTY);
149
+ let label = text;
150
+ let frame = 0;
151
+ let timer = null;
152
+ let started = false;
153
+ let stopped = false;
154
+ const restoreCursor = () => {
155
+ if (animated)
156
+ stream.write(SHOW_CURSOR);
157
+ };
158
+ const render = () => {
159
+ stream.write(`\r${palette.info(SPINNER_FRAMES[frame % SPINNER_FRAMES.length])} ${label}${CLEAR_LINE}`);
160
+ frame++;
161
+ };
162
+ const handle = {
163
+ start() {
164
+ if (started || stopped)
165
+ return handle;
166
+ started = true;
167
+ if (!animated) {
168
+ stream.write(`${label}\n`);
169
+ return handle;
170
+ }
171
+ stream.write(HIDE_CURSOR);
172
+ // A hidden cursor left behind by a Ctrl+C outlives the process, so the
173
+ // exit hook is not optional.
174
+ process.once('exit', restoreCursor);
175
+ render();
176
+ // Unref'd: a spinner must never be the reason the process stays alive.
177
+ timer = setInterval(render, intervalMs);
178
+ timer.unref();
179
+ return handle;
180
+ },
181
+ setText(next) {
182
+ label = next;
183
+ if (animated && started && !stopped)
184
+ render();
185
+ },
186
+ stop(finalLine) {
187
+ if (stopped)
188
+ return;
189
+ stopped = true;
190
+ if (timer) {
191
+ clearInterval(timer);
192
+ timer = null;
193
+ }
194
+ if (animated && started) {
195
+ stream.write(`\r${CLEAR_LINE}`);
196
+ restoreCursor();
197
+ process.off('exit', restoreCursor);
198
+ }
199
+ if (finalLine && animated)
200
+ stream.write(`${finalLine}\n`);
201
+ },
202
+ };
203
+ return handle;
204
+ }
205
+ /** Run `work` with a spinner up, stopping it however `work` ends. */
206
+ export async function withSpinner(text, work, options) {
207
+ const handle = spinner(text, options).start();
208
+ try {
209
+ return await work();
210
+ }
211
+ finally {
212
+ handle.stop();
213
+ }
214
+ }
215
+ // ─────────────────────────────────────────────────────────────────────────────
216
+ // Confirm
217
+ // ─────────────────────────────────────────────────────────────────────────────
218
+ /** Is there a human on the other end of both halves of the terminal? */
219
+ export function isInteractive() {
220
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
221
+ }
222
+ /**
223
+ * y/N prompt. Answers `false` immediately when stdin is not a TTY (a script
224
+ * piping into the CLI must never hang on an invisible question), so callers
225
+ * that support a `--force` flag can branch on `isInteractive()` to keep printing
226
+ * their "pass --force" hint instead.
227
+ */
228
+ export async function confirm(question) {
229
+ if (!isInteractive())
230
+ return false;
231
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
232
+ try {
233
+ const answer = await new Promise((resolve) => {
234
+ rl.once('SIGINT', () => resolve(''));
235
+ rl.question(`${question} ${palette.muted('[y/N]')} `, resolve);
236
+ });
237
+ return /^y(es)?$/i.test(answer.trim());
238
+ }
239
+ finally {
240
+ rl.close();
241
+ // readline resumes stdin; a still-flowing stdin keeps the process alive.
242
+ process.stdin.pause();
243
+ }
244
+ }
245
+ //# sourceMappingURL=cli-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-style.js","sourceRoot":"","sources":["../src/cli-style.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAgG9B;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAO5F;AAmhCD,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAgG9B;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAO5F;AAklCD,OAAO,EAAE,OAAO,EAAE,CAAC"}