aicodeman 1.22.0 → 1.23.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 (199) hide show
  1. package/dist/config/dependency-registry.d.ts.map +1 -1
  2. package/dist/config/dependency-registry.js +27 -0
  3. package/dist/config/dependency-registry.js.map +1 -1
  4. package/dist/cron/cron-service.d.ts +3 -2
  5. package/dist/cron/cron-service.d.ts.map +1 -1
  6. package/dist/cron/cron-service.js +17 -3
  7. package/dist/cron/cron-service.js.map +1 -1
  8. package/dist/deepseek-status-shim.d.ts +77 -0
  9. package/dist/deepseek-status-shim.d.ts.map +1 -0
  10. package/dist/deepseek-status-shim.js +268 -0
  11. package/dist/deepseek-status-shim.js.map +1 -0
  12. package/dist/deepseek-transcript.d.ts +188 -0
  13. package/dist/deepseek-transcript.d.ts.map +1 -0
  14. package/dist/deepseek-transcript.js +633 -0
  15. package/dist/deepseek-transcript.js.map +1 -0
  16. package/dist/deepseek-web-server.d.ts +60 -0
  17. package/dist/deepseek-web-server.d.ts.map +1 -0
  18. package/dist/deepseek-web-server.js +249 -0
  19. package/dist/deepseek-web-server.js.map +1 -0
  20. package/dist/docker-hosts.d.ts.map +1 -1
  21. package/dist/docker-hosts.js +12 -0
  22. package/dist/docker-hosts.js.map +1 -1
  23. package/dist/mux-interface.d.ts +3 -1
  24. package/dist/mux-interface.d.ts.map +1 -1
  25. package/dist/remote-hosts.d.ts.map +1 -1
  26. package/dist/remote-hosts.js +4 -0
  27. package/dist/remote-hosts.js.map +1 -1
  28. package/dist/session.d.ts +27 -1
  29. package/dist/session.d.ts.map +1 -1
  30. package/dist/session.js +47 -2
  31. package/dist/session.js.map +1 -1
  32. package/dist/tmux-manager.d.ts +23 -1
  33. package/dist/tmux-manager.d.ts.map +1 -1
  34. package/dist/tmux-manager.js +134 -5
  35. package/dist/tmux-manager.js.map +1 -1
  36. package/dist/tui/tui-app.d.ts.map +1 -1
  37. package/dist/tui/tui-app.js +1 -0
  38. package/dist/tui/tui-app.js.map +1 -1
  39. package/dist/tui/tui-client.d.ts +1 -1
  40. package/dist/tui/tui-client.d.ts.map +1 -1
  41. package/dist/types/api.d.ts +1 -1
  42. package/dist/types/api.d.ts.map +1 -1
  43. package/dist/types/api.js.map +1 -1
  44. package/dist/types/session.d.ts +61 -4
  45. package/dist/types/session.d.ts.map +1 -1
  46. package/dist/types/session.js +2 -1
  47. package/dist/types/session.js.map +1 -1
  48. package/dist/types/webview.d.ts +15 -0
  49. package/dist/types/webview.d.ts.map +1 -1
  50. package/dist/utils/deepseek-cli-resolver.d.ts +144 -0
  51. package/dist/utils/deepseek-cli-resolver.d.ts.map +1 -0
  52. package/dist/utils/deepseek-cli-resolver.js +339 -0
  53. package/dist/utils/deepseek-cli-resolver.js.map +1 -0
  54. package/dist/utils/index.d.ts +2 -0
  55. package/dist/utils/index.d.ts.map +1 -1
  56. package/dist/utils/index.js +1 -0
  57. package/dist/utils/index.js.map +1 -1
  58. package/dist/web/public/admin-ui.js.gz +0 -0
  59. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  60. package/dist/web/public/app.360ece48.js +36 -0
  61. package/dist/web/public/app.360ece48.js.br +0 -0
  62. package/dist/web/public/app.360ece48.js.gz +0 -0
  63. package/dist/web/public/approvals-ui.js.gz +0 -0
  64. package/dist/web/public/{constants.189c7bff.js → constants.f4ea0a19.js} +8 -1
  65. package/dist/web/public/constants.f4ea0a19.js.br +0 -0
  66. package/dist/web/public/constants.f4ea0a19.js.gz +0 -0
  67. package/dist/web/public/cron-ui.js.gz +0 -0
  68. package/dist/web/public/entrance-animations.js.gz +0 -0
  69. package/dist/web/public/home-sessions.js +1 -0
  70. package/dist/web/public/home-sessions.js.br +0 -0
  71. package/dist/web/public/home-sessions.js.gz +0 -0
  72. package/dist/web/public/i18n.9ae15b51.js +1 -0
  73. package/dist/web/public/i18n.9ae15b51.js.br +0 -0
  74. package/dist/web/public/i18n.9ae15b51.js.gz +0 -0
  75. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  76. package/dist/web/public/index.html +46 -13
  77. package/dist/web/public/index.html.br +0 -0
  78. package/dist/web/public/index.html.gz +0 -0
  79. package/dist/web/public/input-cjk.87f14251.js.gz +0 -0
  80. package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
  81. package/dist/web/public/mobile-handlers.0f83a608.js.gz +0 -0
  82. package/dist/web/public/mobile-overview.js +6 -0
  83. package/dist/web/public/mobile-overview.js.br +0 -0
  84. package/dist/web/public/mobile-overview.js.gz +0 -0
  85. package/dist/web/public/mobile.cab92e3f.css +1 -0
  86. package/dist/web/public/mobile.cab92e3f.css.br +0 -0
  87. package/dist/web/public/mobile.cab92e3f.css.gz +0 -0
  88. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  89. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  90. package/dist/web/public/{panels-ui.7c667123.js → panels-ui.50200a8d.js} +1 -1
  91. package/dist/web/public/panels-ui.50200a8d.js.br +0 -0
  92. package/dist/web/public/panels-ui.50200a8d.js.gz +0 -0
  93. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  94. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  95. package/dist/web/public/readmymind-ui.js.gz +0 -0
  96. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  97. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  98. package/dist/web/public/session-lineage.js.gz +0 -0
  99. package/dist/web/public/session-ui.103656d3.js +68 -0
  100. package/dist/web/public/session-ui.103656d3.js.br +0 -0
  101. package/dist/web/public/session-ui.103656d3.js.gz +0 -0
  102. package/dist/web/public/settings-ui.45f311a7.js +67 -0
  103. package/dist/web/public/settings-ui.45f311a7.js.br +0 -0
  104. package/dist/web/public/settings-ui.45f311a7.js.gz +0 -0
  105. package/dist/web/public/styles.1938fd02.css +1 -0
  106. package/dist/web/public/styles.1938fd02.css.br +0 -0
  107. package/dist/web/public/styles.1938fd02.css.gz +0 -0
  108. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  109. package/dist/web/public/sw.js.gz +0 -0
  110. package/dist/web/public/tab-rail-resize.42c24949.js +1 -0
  111. package/dist/web/public/tab-rail-resize.42c24949.js.br +0 -0
  112. package/dist/web/public/tab-rail-resize.42c24949.js.gz +0 -0
  113. package/dist/web/public/terminal-ui.ef68a666.js.gz +0 -0
  114. package/dist/web/public/ultracode-panel.js.gz +0 -0
  115. package/dist/web/public/ultracode-windows.js.gz +0 -0
  116. package/dist/web/public/upload.html.gz +0 -0
  117. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  118. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  119. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  120. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  121. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  122. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  123. package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
  124. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
  125. package/dist/web/public/vendor/xterm.css.gz +0 -0
  126. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  127. package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
  128. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  129. package/dist/web/public/webview-tabs.js +4 -1
  130. package/dist/web/public/webview-tabs.js.br +0 -0
  131. package/dist/web/public/webview-tabs.js.gz +0 -0
  132. package/dist/web/response-viewer-transcript.js +1 -1
  133. package/dist/web/response-viewer-transcript.js.map +1 -1
  134. package/dist/web/routes/approval-routes.d.ts.map +1 -1
  135. package/dist/web/routes/approval-routes.js +12 -2
  136. package/dist/web/routes/approval-routes.js.map +1 -1
  137. package/dist/web/routes/hook-event-routes.d.ts.map +1 -1
  138. package/dist/web/routes/hook-event-routes.js +51 -7
  139. package/dist/web/routes/hook-event-routes.js.map +1 -1
  140. package/dist/web/routes/readmymind-routes.d.ts.map +1 -1
  141. package/dist/web/routes/readmymind-routes.js +5 -2
  142. package/dist/web/routes/readmymind-routes.js.map +1 -1
  143. package/dist/web/routes/session-routes.d.ts +30 -2
  144. package/dist/web/routes/session-routes.d.ts.map +1 -1
  145. package/dist/web/routes/session-routes.js +158 -16
  146. package/dist/web/routes/session-routes.js.map +1 -1
  147. package/dist/web/routes/system-routes.d.ts.map +1 -1
  148. package/dist/web/routes/system-routes.js +203 -2
  149. package/dist/web/routes/system-routes.js.map +1 -1
  150. package/dist/web/routes/webview-routes.d.ts.map +1 -1
  151. package/dist/web/routes/webview-routes.js +1 -0
  152. package/dist/web/routes/webview-routes.js.map +1 -1
  153. package/dist/web/schemas.d.ts +68 -0
  154. package/dist/web/schemas.d.ts.map +1 -1
  155. package/dist/web/schemas.js +107 -4
  156. package/dist/web/schemas.js.map +1 -1
  157. package/dist/web/server.d.ts.map +1 -1
  158. package/dist/web/server.js +21 -3
  159. package/dist/web/server.js.map +1 -1
  160. package/dist/web/session-wait-registry.d.ts +63 -7
  161. package/dist/web/session-wait-registry.d.ts.map +1 -1
  162. package/dist/web/session-wait-registry.js +67 -9
  163. package/dist/web/session-wait-registry.js.map +1 -1
  164. package/dist/web/sse-events.d.ts +11 -2
  165. package/dist/web/sse-events.d.ts.map +1 -1
  166. package/dist/web/sse-events.js +11 -2
  167. package/dist/web/sse-events.js.map +1 -1
  168. package/package.json +2 -1
  169. package/skills/codeman/SKILL.md +121 -34
  170. package/skills/codeman/preamble.sh +81 -26
  171. package/skills/codeman/reference/endpoints.md +18 -10
  172. package/skills/codeman/reference/messaging.md +2 -2
  173. package/skills/codeman/reference/recipes.md +53 -0
  174. package/skills/codeman/reference/verbs.md +39 -8
  175. package/dist/web/public/app.84bf8955.js +0 -36
  176. package/dist/web/public/app.84bf8955.js.br +0 -0
  177. package/dist/web/public/app.84bf8955.js.gz +0 -0
  178. package/dist/web/public/constants.189c7bff.js.br +0 -0
  179. package/dist/web/public/constants.189c7bff.js.gz +0 -0
  180. package/dist/web/public/i18n.34016b89.js +0 -1
  181. package/dist/web/public/i18n.34016b89.js.br +0 -0
  182. package/dist/web/public/i18n.34016b89.js.gz +0 -0
  183. package/dist/web/public/mobile.983f064e.css +0 -1
  184. package/dist/web/public/mobile.983f064e.css.br +0 -0
  185. package/dist/web/public/mobile.983f064e.css.gz +0 -0
  186. package/dist/web/public/panels-ui.7c667123.js.br +0 -0
  187. package/dist/web/public/panels-ui.7c667123.js.gz +0 -0
  188. package/dist/web/public/session-ui.acd79900.js +0 -68
  189. package/dist/web/public/session-ui.acd79900.js.br +0 -0
  190. package/dist/web/public/session-ui.acd79900.js.gz +0 -0
  191. package/dist/web/public/settings-ui.115a2d1e.js +0 -67
  192. package/dist/web/public/settings-ui.115a2d1e.js.br +0 -0
  193. package/dist/web/public/settings-ui.115a2d1e.js.gz +0 -0
  194. package/dist/web/public/styles.64369ebd.css +0 -1
  195. package/dist/web/public/styles.64369ebd.css.br +0 -0
  196. package/dist/web/public/styles.64369ebd.css.gz +0 -0
  197. package/dist/web/public/tab-rail-resize.f3465ce1.js +0 -1
  198. package/dist/web/public/tab-rail-resize.f3465ce1.js.br +0 -0
  199. package/dist/web/public/tab-rail-resize.f3465ce1.js.gz +0 -0
@@ -8,7 +8,7 @@
8
8
  * - SessionConfig — creation-time config (id, workingDir, createdAt)
9
9
  * - SessionOutput — captured stdout/stderr/exitCode
10
10
  * - SessionStatus — 'idle' | 'busy' | 'stopped' | 'error'
11
- * - SessionMode — 'claude' | 'shell' | 'opencode' | 'codex' | 'gemini' | 'antigravity' | 'pi' | 'grok' (which CLI backend)
11
+ * - SessionMode — 'claude' | 'shell' | 'opencode' | 'codex' | 'gemini' | 'antigravity' | 'pi' | 'grok' | 'deepseek' (which CLI backend)
12
12
  * - ClaudeMode — CLI permission mode ('dangerously-skip-permissions' | 'auto' | 'normal' | 'allowedTools')
13
13
  * - SessionColor — visual differentiation color
14
14
  * - OpenCodeConfig — OpenCode-specific settings (model, autoAllowTools, continueSession)
@@ -17,6 +17,7 @@
17
17
  * - AntigravityConfig — Antigravity CLI (agy) settings (model, dangerouslySkipPermissions, resumeConversationId)
18
18
  * - PiConfig — Pi CLI (pi.dev) settings (model, provider, thinking, resume/continue, project trust)
19
19
  * - GrokConfig — Grok Build CLI (xAI `grok`) settings (model, alwaysApprove, resume/continue)
20
+ * - DeepSeekConfig — DeepSeek Harness (`dsh`) settings (profile, permissionMode, resume, status bridge)
20
21
  *
21
22
  * Cross-domain relationships:
22
23
  * - SessionState.respawnConfig embeds RespawnConfig (respawn domain)
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/types/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgPH;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAU,CAAC;AAK7F,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,OAAO,KAAK,KAAK,SAAS,IAAK,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACrF,CAAC;AAuSD;;GAEG"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/types/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAyPH;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAU,CAAC;AAK7F,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,OAAO,KAAK,KAAK,SAAS,IAAK,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACrF,CAAC;AAgWD;;GAEG"}
@@ -30,6 +30,15 @@
30
30
  */
31
31
  export type WebviewEmbedMode = 'proxy' | 'direct';
32
32
  /** A saved dashboard, persisted to `~/.codeman/webviews.json`. */
33
+ /**
34
+ * Dashboards Codeman creates and maintains on the user's behalf.
35
+ *
36
+ * A managed record is hidden from the saved-dashboard list, because the shortcut
37
+ * that maintains it is already a menu entry of its own: listing both showed the
38
+ * same dashboard twice, once as "DeepSeek web UI..." and once as the row it had
39
+ * just written.
40
+ */
41
+ export type WebviewManagedKind = 'deepseek-web';
33
42
  export interface Webview {
34
43
  id: string;
35
44
  /** Display name shown on the tab. */
@@ -47,6 +56,12 @@ export interface Webview {
47
56
  * cookies/localStorage, only for dashboards the user fully trusts.
48
57
  */
49
58
  trusted: boolean;
59
+ /**
60
+ * Set when Codeman owns this record rather than the user (see
61
+ * `WebviewManagedKind`). Managed rows are maintained by the shortcut that
62
+ * created them, including repointing the URL when the port changes.
63
+ */
64
+ managed?: WebviewManagedKind;
50
65
  /** Multi-user owner (username). Undefined in single-user mode. */
51
66
  owner?: string;
52
67
  createdAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"webview.d.ts","sourceRoot":"","sources":["../../src/types/webview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElD,kEAAkE;AAClE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,EAAE,gBAAgB,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,eAAe,EAAE,gBAAgB,CAAC;IAClC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"webview.d.ts","sourceRoot":"","sources":["../../src/types/webview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElD,kEAAkE;AAClE;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEhD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,EAAE,gBAAgB,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,eAAe,EAAE,gBAAgB,CAAC;IAClC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @fileoverview Resolve the DeepSeek Harness CLI (`dsh`) binary and its bootable profiles.
3
+ *
4
+ * Mirrors pi-cli-resolver.ts / grok-cli-resolver.ts, but the identity probe here
5
+ * is STRICTER than either, and deliberately so: `dsh` is not merely a short name
6
+ * with npm squatters, it is an EXISTING, widely packaged Unix program. Debian and
7
+ * Ubuntu ship `dsh` = "dancer's shell" / distributed shell (`apt install dsh`),
8
+ * which like nearly every Unix tool prints a version-shaped string of its own.
9
+ * A version-token probe alone (which is all pi and grok need) would
10
+ * therefore ACCEPT dancer's shell as the DeepSeek Harness and hand it to a spawn
11
+ * line, so every candidate must additionally prove its identity by printing the
12
+ * harness's own help banner.
13
+ *
14
+ * Two probes per candidate, both bounded and both cached behind the shared
15
+ * resolver's positive/negative caching:
16
+ * 1. `dsh --help` must match DEEPSEEK_IDENTITY_REGEX (`DeepSeek Harness`)
17
+ * 2. `dsh --version` must yield a version token (real output: `0.1.1-rc.2`)
18
+ * Order matters: identity is checked FIRST, so a foreign `dsh` is rejected on the
19
+ * cheaper, more discriminating signal and never contributes a version number.
20
+ *
21
+ * `dsh` is a profile LAUNCHER, not an agent: `dsh --profile <name>` boots an
22
+ * ordered stack of plugin-bundle patch layers, and DeepSeek ships only `web`
23
+ * (browser UI), `headless` (one-shot) and `base` (no app). The interactive
24
+ * terminal agent Codeman actually drives is a THIRD-PARTY profile the user
25
+ * installs. That is why this module resolves two independent things — a binary
26
+ * AND a profile inventory — and why "available" for the deepseek run mode means
27
+ * both (`isDeepSeekRunnable`, and `resolveDeepSeekLaunchError` in session-routes.ts
28
+ * for the actionable per-half message).
29
+ *
30
+ * @module utils/deepseek-cli-resolver
31
+ */
32
+ import { type CliResolverHost } from './cli-executable-resolver.js';
33
+ /**
34
+ * A real `dsh --version` prints a bare `0.1.1-rc.2` (measured, 0.1.1-rc.2), so
35
+ * the prerelease suffix is part of the token — truncating it to `0.1.1` would
36
+ * misreport a release-candidate as a release in `codeman doctor`.
37
+ *
38
+ * Exported and SHARED with the `dsh` entry in `config/dependency-registry.ts`,
39
+ * so the doctor and the run mode cannot disagree about what counts as an
40
+ * installed dsh (the same single-source rule as PI_VERSION_REGEX /
41
+ * GROK_VERSION_REGEX). Shape is dictated by the doctor's `extractVersion()`
42
+ * (first capture group, whole-output scan): hence a capturing group and a
43
+ * leading boundary instead of `^`. No `g` flag, so there is no shared
44
+ * `lastIndex` to reset.
45
+ */
46
+ export declare const DEEPSEEK_VERSION_REGEX: RegExp;
47
+ /**
48
+ * The identity marker that separates DeepSeek's `dsh` from Debian's dancer's
49
+ * shell. The real launcher's `--help` banner reads:
50
+ *
51
+ * dsh: boot a DeepSeek Harness profile — an ordered stack of plugin-bundle …
52
+ *
53
+ * Matched case-insensitively against the help output. This is the check that
54
+ * makes the resolver safe to point a spawn line at; see the module header.
55
+ */
56
+ export declare const DEEPSEEK_IDENTITY_REGEX: RegExp;
57
+ /** Where profiles live: `$DSH_HOME/profiles`, defaulting to `~/.dsh/profiles`. */
58
+ export declare function resolveDshHome(): string;
59
+ /**
60
+ * What a profile is FOR, inferred from the bundles it composes.
61
+ *
62
+ * `interactive` is the only kind a tmux pane can drive: `web` serves a browser
63
+ * UI and would occupy the pane with a logging server, `headless` answers one
64
+ * task and exits (which reads as an instantly-dead pane). `unknown` is treated
65
+ * as interactive-capable on purpose — the whole point of the harness is that
66
+ * anyone can publish an app bundle, so an unrecognized third-party profile must
67
+ * not be hidden from the picker just because this list has not heard of it.
68
+ */
69
+ export type DeepSeekProfileKind = 'interactive' | 'web' | 'headless' | 'unknown';
70
+ export interface DeepSeekProfile {
71
+ /** Directory name under `$DSH_HOME/profiles`, i.e. the `--profile` argument. */
72
+ name: string;
73
+ /** Bundle package names composed by the profile, in order. */
74
+ bundles: string[];
75
+ kind: DeepSeekProfileKind;
76
+ }
77
+ /**
78
+ * Inventory the profiles installed under `$DSH_HOME/profiles`.
79
+ *
80
+ * Never throws: a missing DSH_HOME (dsh installed but never run) is an empty
81
+ * list, which the callers render as "no profile yet" rather than an error.
82
+ * Deliberately un-cached — a user can create a profile at any moment (including
83
+ * through Codeman's own bootstrap), and the directory scan is cheap next to the
84
+ * two process spawns the binary probe already costs.
85
+ */
86
+ export declare function listDeepSeekProfiles(): DeepSeekProfile[];
87
+ /**
88
+ * The profile a session should boot when the user picked none.
89
+ *
90
+ * Prefers a positively-identified terminal profile, then an unrecognized one
91
+ * (third-party by construction — see TUI_BUNDLE_PATTERN), and refuses to fall
92
+ * back to `web`/`headless`, which cannot drive a pane. Returns null when nothing
93
+ * launchable is installed, which is what makes the mode report unavailable
94
+ * instead of spawning a pane that dies on arrival.
95
+ */
96
+ export declare function resolveDefaultDeepSeekProfile(profiles?: DeepSeekProfile[]): string | null;
97
+ /** True when the profile can occupy a tmux pane as an interactive agent. */
98
+ export declare function isLaunchableProfile(profile: DeepSeekProfile): boolean;
99
+ type DeepSeekVersionProbe = (binPath: string) => string | null;
100
+ /**
101
+ * Creates an isolated DeepSeek wrapper around an injected host, version probe
102
+ * and clock. Omitting `versionProbe` keeps the ambient (VITEST-gated) probe,
103
+ * which is exactly what the hermeticity test exercises.
104
+ */
105
+ export declare function createDeepSeekResolverForTest(host: CliResolverHost, versionProbe?: DeepSeekVersionProbe, now?: () => number): import("./cli-executable-resolver.js").CliExecutableResolver<string>;
106
+ /**
107
+ * Finds the directory containing a verified `dsh` binary.
108
+ * Checks the server PATH first, then the common install locations. Every
109
+ * candidate must pass the identity+version probe before it is accepted.
110
+ *
111
+ * @returns Directory path, or null if not found
112
+ */
113
+ export declare function resolveDeepSeekDir(): string | null;
114
+ /**
115
+ * Whether the `dsh` BINARY is installed. Note this is deliberately weaker than
116
+ * what the run mode needs: a dsh with no launchable profile cannot start a
117
+ * session. Callers gating the Run button want `isDeepSeekRunnable()`.
118
+ */
119
+ export declare function isDeepSeekAvailable(): boolean;
120
+ /** Binary present AND at least one profile that can occupy a pane. */
121
+ export declare function isDeepSeekRunnable(): boolean;
122
+ export declare function getDeepSeekNotFoundMessage(): string;
123
+ /**
124
+ * Version reported by the resolved `dsh` binary, or null when dsh is
125
+ * unavailable. Surfaced through `GET /api/deepseek/status` so a misresolution
126
+ * is diagnosable from the UI.
127
+ */
128
+ export declare function getDeepSeekCliVersion(): string | null;
129
+ /** Does the named profile exist and can it drive a pane? */
130
+ export declare function profileExists(name: string): boolean;
131
+ /**
132
+ * Why a DeepSeek session cannot start, or null when it can.
133
+ *
134
+ * Availability for this mode is TWO questions, not one, because `dsh` is a
135
+ * profile launcher rather than an agent: the binary must resolve (and prove it
136
+ * is the harness and not Debian's dancer's shell), AND a profile that can occupy
137
+ * a pane must exist. Every create path — both HTTP routes AND cron fires — must
138
+ * ask this before constructing a Session, or the pane boots the box's default
139
+ * profile, which may be a logging web server or a one-shot that exits on
140
+ * arrival, and the prompt is typed into it.
141
+ */
142
+ export declare function resolveDeepSeekLaunchError(requestedProfile?: string): string | null;
143
+ export {};
144
+ //# sourceMappingURL=deepseek-cli-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepseek-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/deepseek-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAOH,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;AAiBtC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,QAA6D,CAAC;AAEjG;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,QAAwB,CAAC;AAI7D,kFAAkF;AAClF,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEjF,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AA0ED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAcxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,GAAE,eAAe,EAA2B,GAAG,MAAM,GAAG,IAAI,CAIjH;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAErE;AA4DD,KAAK,oBAAoB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAqB/D;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,eAAe,EACrB,YAAY,CAAC,EAAE,oBAAoB,EACnC,GAAG,CAAC,EAAE,MAAM,MAAM,wEAGnB;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAErD;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBnF"}
@@ -0,0 +1,339 @@
1
+ /**
2
+ * @fileoverview Resolve the DeepSeek Harness CLI (`dsh`) binary and its bootable profiles.
3
+ *
4
+ * Mirrors pi-cli-resolver.ts / grok-cli-resolver.ts, but the identity probe here
5
+ * is STRICTER than either, and deliberately so: `dsh` is not merely a short name
6
+ * with npm squatters, it is an EXISTING, widely packaged Unix program. Debian and
7
+ * Ubuntu ship `dsh` = "dancer's shell" / distributed shell (`apt install dsh`),
8
+ * which like nearly every Unix tool prints a version-shaped string of its own.
9
+ * A version-token probe alone (which is all pi and grok need) would
10
+ * therefore ACCEPT dancer's shell as the DeepSeek Harness and hand it to a spawn
11
+ * line, so every candidate must additionally prove its identity by printing the
12
+ * harness's own help banner.
13
+ *
14
+ * Two probes per candidate, both bounded and both cached behind the shared
15
+ * resolver's positive/negative caching:
16
+ * 1. `dsh --help` must match DEEPSEEK_IDENTITY_REGEX (`DeepSeek Harness`)
17
+ * 2. `dsh --version` must yield a version token (real output: `0.1.1-rc.2`)
18
+ * Order matters: identity is checked FIRST, so a foreign `dsh` is rejected on the
19
+ * cheaper, more discriminating signal and never contributes a version number.
20
+ *
21
+ * `dsh` is a profile LAUNCHER, not an agent: `dsh --profile <name>` boots an
22
+ * ordered stack of plugin-bundle patch layers, and DeepSeek ships only `web`
23
+ * (browser UI), `headless` (one-shot) and `base` (no app). The interactive
24
+ * terminal agent Codeman actually drives is a THIRD-PARTY profile the user
25
+ * installs. That is why this module resolves two independent things — a binary
26
+ * AND a profile inventory — and why "available" for the deepseek run mode means
27
+ * both (`isDeepSeekRunnable`, and `resolveDeepSeekLaunchError` in session-routes.ts
28
+ * for the actionable per-half message).
29
+ *
30
+ * @module utils/deepseek-cli-resolver
31
+ */
32
+ import { execFileSync } from 'node:child_process';
33
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
34
+ import { join } from 'node:path';
35
+ import { homedir } from 'node:os';
36
+ import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
37
+ import { createCliExecutableResolver, formatCliNotFoundMessage, } from './cli-executable-resolver.js';
38
+ /**
39
+ * Common directories where the `dsh` binary may be installed.
40
+ *
41
+ * `dsh` is an npm package (`@deepseek-ai/dsh`), so unlike grok there is no
42
+ * vendor-owned install dir to lead with: the global npm bin is wherever the
43
+ * user's prefix points. `~/.local/bin` heads the list because it is the default
44
+ * for a prefix-relocated npm (and is where this box's install landed).
45
+ */
46
+ const DEEPSEEK_SEARCH_DIRS = [
47
+ join(homedir(), '.local', 'bin'),
48
+ '/usr/local/bin',
49
+ join(homedir(), '.npm-global', 'bin'),
50
+ join(homedir(), 'bin'),
51
+ ];
52
+ /**
53
+ * A real `dsh --version` prints a bare `0.1.1-rc.2` (measured, 0.1.1-rc.2), so
54
+ * the prerelease suffix is part of the token — truncating it to `0.1.1` would
55
+ * misreport a release-candidate as a release in `codeman doctor`.
56
+ *
57
+ * Exported and SHARED with the `dsh` entry in `config/dependency-registry.ts`,
58
+ * so the doctor and the run mode cannot disagree about what counts as an
59
+ * installed dsh (the same single-source rule as PI_VERSION_REGEX /
60
+ * GROK_VERSION_REGEX). Shape is dictated by the doctor's `extractVersion()`
61
+ * (first capture group, whole-output scan): hence a capturing group and a
62
+ * leading boundary instead of `^`. No `g` flag, so there is no shared
63
+ * `lastIndex` to reset.
64
+ */
65
+ export const DEEPSEEK_VERSION_REGEX = /(?:^|\s)v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z][0-9A-Za-z.-]*)?)/;
66
+ /**
67
+ * The identity marker that separates DeepSeek's `dsh` from Debian's dancer's
68
+ * shell. The real launcher's `--help` banner reads:
69
+ *
70
+ * dsh: boot a DeepSeek Harness profile — an ordered stack of plugin-bundle …
71
+ *
72
+ * Matched case-insensitively against the help output. This is the check that
73
+ * makes the resolver safe to point a spawn line at; see the module header.
74
+ */
75
+ export const DEEPSEEK_IDENTITY_REGEX = /DeepSeek\s+Harness/i;
76
+ const DEEPSEEK_NOT_FOUND = 'DeepSeek Harness CLI (dsh) not found. Install with: npm install -g @deepseek-ai/dsh';
77
+ /** Where profiles live: `$DSH_HOME/profiles`, defaulting to `~/.dsh/profiles`. */
78
+ export function resolveDshHome() {
79
+ const fromEnv = process.env.DSH_HOME?.trim();
80
+ return fromEnv && fromEnv.length > 0 ? fromEnv : join(homedir(), '.dsh');
81
+ }
82
+ /** Bundles that positively identify a non-interactive profile. */
83
+ const WEB_BUNDLE_PATTERN = /dsh-web-app|dsh-web-frontend/i;
84
+ const HEADLESS_BUNDLE_PATTERN = /dsh-headless/i;
85
+ /**
86
+ * Bundles that positively identify a terminal app. Intentionally a loose
87
+ * community-wide pattern rather than one blessed package: the terminal front
88
+ * door is third-party by construction (DeepSeek ships none), and a dozen
89
+ * scoped `dsh-tui` packages from a dozen different authors compete. Anything
90
+ * matching is a TUI; anything unmatched is `unknown`, which still counts as
91
+ * launchable.
92
+ *
93
+ * `tui` carries word boundaries so the loose arm stays a TOKEN match: `-` and
94
+ * `/` are non-word characters, so `@someone/tui-app` and `dsh-tui` both match
95
+ * while `intuition` and `gratuitous` do not. Being wrong here is cheap (an
96
+ * unmatched profile is `unknown`, which is launchable too) but it decides which
97
+ * profile a session boots by DEFAULT, and "the one whose name happens to contain
98
+ * t-u-i" is not a rule anyone could predict.
99
+ */
100
+ const TUI_BUNDLE_PATTERN = /dsh-tui|dsh-terminal-app|\btui\b/i;
101
+ /**
102
+ * The profile names DeepSeek itself ships for its non-interactive surfaces.
103
+ *
104
+ * Consulted only AFTER the bundle patterns have found nothing, and only against
105
+ * the directory name. `readProfile()` yields an empty bundle list for any
106
+ * `package.json` without a `dsh.profile.bundles` array — a hand-edited file, an
107
+ * older layout, a profile mid-install — and with no bundles to read, the stock
108
+ * `web` and `headless` profiles look exactly like an unrecognized third-party
109
+ * one and inherit its launchable-by-default treatment. That is the single
110
+ * "unknown" that is knowably wrong, and it produces precisely the
111
+ * pane-dies-on-arrival failure the two-part availability gate exists to prevent.
112
+ *
113
+ * Deliberately a fallback rather than a first check: a third-party profile that
114
+ * legitimately composes a terminal app is identified by its BUNDLES, and its
115
+ * directory name (which the user chose) must never override that evidence.
116
+ */
117
+ const STOCK_NON_INTERACTIVE_PROFILES = new Map([
118
+ ['web', 'web'],
119
+ ['headless', 'headless'],
120
+ ]);
121
+ /** Profile directory names that are not profiles. */
122
+ const NON_PROFILE_DIRS = new Set(['node_modules', '.bin', '.pnpm']);
123
+ function classifyProfile(name, bundles) {
124
+ const haystack = [name, ...bundles].join(' ');
125
+ // Order matters: a profile that composes BOTH a web app and a tui bundle is a
126
+ // web profile as far as a tmux pane is concerned, because the web app owns the
127
+ // process and blocks.
128
+ if (WEB_BUNDLE_PATTERN.test(haystack))
129
+ return 'web';
130
+ if (HEADLESS_BUNDLE_PATTERN.test(haystack))
131
+ return 'headless';
132
+ if (TUI_BUNDLE_PATTERN.test(haystack))
133
+ return 'interactive';
134
+ return STOCK_NON_INTERACTIVE_PROFILES.get(name.toLowerCase()) ?? 'unknown';
135
+ }
136
+ /**
137
+ * Read a single profile directory's `package.json` and return its bundle list.
138
+ * Returns null for anything that is not a readable dsh profile, so a stray
139
+ * directory under `profiles/` cannot break the inventory.
140
+ */
141
+ function readProfile(profilesDir, name) {
142
+ try {
143
+ const raw = readFileSync(join(profilesDir, name, 'package.json'), 'utf-8');
144
+ const parsed = JSON.parse(raw);
145
+ const rawBundles = parsed?.dsh?.profile?.bundles;
146
+ const bundles = Array.isArray(rawBundles) ? rawBundles.filter((b) => typeof b === 'string') : [];
147
+ return { name, bundles, kind: classifyProfile(name, bundles) };
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ }
153
+ /**
154
+ * Inventory the profiles installed under `$DSH_HOME/profiles`.
155
+ *
156
+ * Never throws: a missing DSH_HOME (dsh installed but never run) is an empty
157
+ * list, which the callers render as "no profile yet" rather than an error.
158
+ * Deliberately un-cached — a user can create a profile at any moment (including
159
+ * through Codeman's own bootstrap), and the directory scan is cheap next to the
160
+ * two process spawns the binary probe already costs.
161
+ */
162
+ export function listDeepSeekProfiles() {
163
+ const profilesDir = join(resolveDshHome(), 'profiles');
164
+ let entries;
165
+ try {
166
+ entries = readdirSync(profilesDir, { withFileTypes: true })
167
+ .filter((e) => e.isDirectory() && !NON_PROFILE_DIRS.has(e.name) && !e.name.startsWith('.'))
168
+ .map((e) => e.name);
169
+ }
170
+ catch {
171
+ return [];
172
+ }
173
+ return entries
174
+ .map((name) => readProfile(profilesDir, name))
175
+ .filter((p) => p !== null)
176
+ .sort((a, b) => a.name.localeCompare(b.name));
177
+ }
178
+ /**
179
+ * The profile a session should boot when the user picked none.
180
+ *
181
+ * Prefers a positively-identified terminal profile, then an unrecognized one
182
+ * (third-party by construction — see TUI_BUNDLE_PATTERN), and refuses to fall
183
+ * back to `web`/`headless`, which cannot drive a pane. Returns null when nothing
184
+ * launchable is installed, which is what makes the mode report unavailable
185
+ * instead of spawning a pane that dies on arrival.
186
+ */
187
+ export function resolveDefaultDeepSeekProfile(profiles = listDeepSeekProfiles()) {
188
+ return (profiles.find((p) => p.kind === 'interactive')?.name ?? profiles.find((p) => p.kind === 'unknown')?.name ?? null);
189
+ }
190
+ /** True when the profile can occupy a tmux pane as an interactive agent. */
191
+ export function isLaunchableProfile(profile) {
192
+ return profile.kind === 'interactive' || profile.kind === 'unknown';
193
+ }
194
+ /**
195
+ * Run the two-stage identity+version probe on a candidate path.
196
+ *
197
+ * Returns the version token only when the binary proves it is the DeepSeek
198
+ * Harness launcher. Returns null for anything else: a missing binary, a
199
+ * non-zero exit, a hang (timeout), a help banner without the harness marker
200
+ * (this is the dancer's-shell rejection), or output with no version-shaped
201
+ * token.
202
+ *
203
+ * Never runs under vitest: the suites must stay hermetic and must not depend on
204
+ * whether the dev box happens to have dsh installed — and since `dsh` names a
205
+ * real Debian program, this probe would EXECUTE whatever binary of that name the
206
+ * machine carries. The shared resolver host is already inert under vitest, so
207
+ * this gate is defense in depth for any opted-in host that still carries the
208
+ * default probe; tests drive resolution via `createDeepSeekResolverForTest`,
209
+ * whose injected probe bypasses it. Pinned by test/deepseek-cli-resolver.test.ts.
210
+ */
211
+ function probeDeepSeekVersion(binPath) {
212
+ if (process.env.VITEST)
213
+ return null;
214
+ const run = (args) => {
215
+ try {
216
+ return execFileSync(binPath, args, {
217
+ encoding: 'utf-8',
218
+ timeout: EXEC_TIMEOUT_MS,
219
+ stdio: ['ignore', 'pipe', 'ignore'],
220
+ // A stuck or hostile `dsh` that ignores SIGTERM would survive the timeout
221
+ // and block the server (execFileSync keeps waiting after the signal).
222
+ killSignal: 'SIGKILL',
223
+ }).trim();
224
+ }
225
+ catch (err) {
226
+ console.warn(`[DeepSeekResolver] Ignoring ${binPath}: "dsh ${args.join(' ')}" failed (${err.message})`);
227
+ return null;
228
+ }
229
+ };
230
+ // Identity first — the discriminating signal, and the one that keeps Debian's
231
+ // dancer's shell out of a spawn line.
232
+ const help = run(['--help']);
233
+ if (help === null)
234
+ return null;
235
+ if (!DEEPSEEK_IDENTITY_REGEX.test(help)) {
236
+ console.warn(`[DeepSeekResolver] Ignoring ${binPath}: "dsh --help" is not the DeepSeek Harness launcher ` +
237
+ `(printed ${JSON.stringify(help.slice(0, 80))}). A different program named "dsh" (e.g. Debian's ` +
238
+ `dancer's shell) is earlier on PATH.`);
239
+ return null;
240
+ }
241
+ const out = run(['--version']);
242
+ if (out === null)
243
+ return null;
244
+ const candidate = DEEPSEEK_VERSION_REGEX.exec(out)?.[1];
245
+ if (candidate)
246
+ return candidate;
247
+ console.warn(`[DeepSeekResolver] Ignoring ${binPath}: "dsh --version" printed ${JSON.stringify(out.slice(0, 80))}`);
248
+ return null;
249
+ }
250
+ function createDeepSeekResolver(host, versionProbe = probeDeepSeekVersion, now) {
251
+ return createCliExecutableResolver({
252
+ binary: 'dsh',
253
+ searchDirs: DEEPSEEK_SEARCH_DIRS,
254
+ validateCandidate: (binPath) => {
255
+ const version = versionProbe(binPath);
256
+ return version ? { accepted: true, metadata: version } : { accepted: false };
257
+ },
258
+ now,
259
+ }, host);
260
+ }
261
+ /**
262
+ * Creates an isolated DeepSeek wrapper around an injected host, version probe
263
+ * and clock. Omitting `versionProbe` keeps the ambient (VITEST-gated) probe,
264
+ * which is exactly what the hermeticity test exercises.
265
+ */
266
+ export function createDeepSeekResolverForTest(host, versionProbe, now) {
267
+ return createDeepSeekResolver(host, versionProbe ?? probeDeepSeekVersion, now);
268
+ }
269
+ const deepSeekResolver = createDeepSeekResolver();
270
+ /**
271
+ * Finds the directory containing a verified `dsh` binary.
272
+ * Checks the server PATH first, then the common install locations. Every
273
+ * candidate must pass the identity+version probe before it is accepted.
274
+ *
275
+ * @returns Directory path, or null if not found
276
+ */
277
+ export function resolveDeepSeekDir() {
278
+ return deepSeekResolver.resolve()?.directory ?? null;
279
+ }
280
+ /**
281
+ * Whether the `dsh` BINARY is installed. Note this is deliberately weaker than
282
+ * what the run mode needs: a dsh with no launchable profile cannot start a
283
+ * session. Callers gating the Run button want `isDeepSeekRunnable()`.
284
+ */
285
+ export function isDeepSeekAvailable() {
286
+ return resolveDeepSeekDir() !== null;
287
+ }
288
+ /** Binary present AND at least one profile that can occupy a pane. */
289
+ export function isDeepSeekRunnable() {
290
+ return isDeepSeekAvailable() && resolveDefaultDeepSeekProfile() !== null;
291
+ }
292
+ export function getDeepSeekNotFoundMessage() {
293
+ return formatCliNotFoundMessage(DEEPSEEK_NOT_FOUND, deepSeekResolver.diagnostics());
294
+ }
295
+ /**
296
+ * Version reported by the resolved `dsh` binary, or null when dsh is
297
+ * unavailable. Surfaced through `GET /api/deepseek/status` so a misresolution
298
+ * is diagnosable from the UI.
299
+ */
300
+ export function getDeepSeekCliVersion() {
301
+ return deepSeekResolver.resolve()?.metadata ?? null;
302
+ }
303
+ /** Does the named profile exist and can it drive a pane? */
304
+ export function profileExists(name) {
305
+ return existsSync(join(resolveDshHome(), 'profiles', name, 'package.json'));
306
+ }
307
+ /**
308
+ * Why a DeepSeek session cannot start, or null when it can.
309
+ *
310
+ * Availability for this mode is TWO questions, not one, because `dsh` is a
311
+ * profile launcher rather than an agent: the binary must resolve (and prove it
312
+ * is the harness and not Debian's dancer's shell), AND a profile that can occupy
313
+ * a pane must exist. Every create path — both HTTP routes AND cron fires — must
314
+ * ask this before constructing a Session, or the pane boots the box's default
315
+ * profile, which may be a logging web server or a one-shot that exits on
316
+ * arrival, and the prompt is typed into it.
317
+ */
318
+ export function resolveDeepSeekLaunchError(requestedProfile) {
319
+ if (!isDeepSeekAvailable())
320
+ return getDeepSeekNotFoundMessage();
321
+ const profiles = listDeepSeekProfiles();
322
+ if (requestedProfile) {
323
+ const match = profiles.find((p) => p.name === requestedProfile);
324
+ if (!match) {
325
+ return `DeepSeek Harness profile "${requestedProfile}" does not exist. Create it with: dsh plugin --profile ${requestedProfile} add <package>`;
326
+ }
327
+ if (match.kind === 'web' || match.kind === 'headless') {
328
+ return `DeepSeek Harness profile "${requestedProfile}" is a ${match.kind} profile and cannot run in a terminal session. Pick an interactive profile, or open the web profile as a Codeman web tab.`;
329
+ }
330
+ return null;
331
+ }
332
+ if (!resolveDefaultDeepSeekProfile(profiles)) {
333
+ return ('No interactive DeepSeek Harness profile is installed. DeepSeek ships only the web and headless ' +
334
+ 'profiles, so the terminal agent comes from a plugin — install one with: ' +
335
+ 'dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui');
336
+ }
337
+ return null;
338
+ }
339
+ //# sourceMappingURL=deepseek-cli-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepseek-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/deepseek-cli-resolver.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,8 @@ export { resolveGeminiDir, isGeminiAvailable, getGeminiNotFoundMessage } from '.
26
26
  export { resolveAntigravityDir, isAntigravityAvailable, getAntigravityNotFoundMessage, } from './antigravity-cli-resolver.js';
27
27
  export { resolvePiDir, isPiAvailable, getPiCliVersion, getPiNotFoundMessage } from './pi-cli-resolver.js';
28
28
  export { resolveGrokDir, isGrokAvailable, getGrokCliVersion, getGrokNotFoundMessage } from './grok-cli-resolver.js';
29
+ export { resolveDeepSeekDir, isDeepSeekAvailable, isDeepSeekRunnable, getDeepSeekCliVersion, getDeepSeekNotFoundMessage, listDeepSeekProfiles, resolveDefaultDeepSeekProfile, isLaunchableProfile, resolveDshHome, profileExists, } from './deepseek-cli-resolver.js';
30
+ export type { DeepSeekProfile, DeepSeekProfileKind } from './deepseek-cli-resolver.js';
29
31
  export { compileFileQuery, matchFileQuery } from './file-query.js';
30
32
  export type { FileQueryMatcher } from './file-query.js';
31
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -25,5 +25,6 @@ export { resolveGeminiDir, isGeminiAvailable, getGeminiNotFoundMessage } from '.
25
25
  export { resolveAntigravityDir, isAntigravityAvailable, getAntigravityNotFoundMessage, } from './antigravity-cli-resolver.js';
26
26
  export { resolvePiDir, isPiAvailable, getPiCliVersion, getPiNotFoundMessage } from './pi-cli-resolver.js';
27
27
  export { resolveGrokDir, isGrokAvailable, getGrokCliVersion, getGrokNotFoundMessage } from './grok-cli-resolver.js';
28
+ export { resolveDeepSeekDir, isDeepSeekAvailable, isDeepSeekRunnable, getDeepSeekCliVersion, getDeepSeekNotFoundMessage, listDeepSeekProfiles, resolveDefaultDeepSeekProfile, isLaunchableProfile, resolveDshHome, profileExists, } from './deepseek-cli-resolver.js';
28
29
  export { compileFileQuery, matchFileQuery } from './file-query.js';
29
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
Binary file