@code-yeongyu/senpi 2026.7.25-2 → 2026.7.26

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 (463) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +1 -1
  3. package/dist/cli/args.d.ts +4 -16
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +9 -25
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/grok-neo-gate.d.ts +12 -0
  8. package/dist/cli/grok-neo-gate.d.ts.map +1 -0
  9. package/dist/cli/grok-neo-gate.js +18 -0
  10. package/dist/cli/grok-neo-gate.js.map +1 -0
  11. package/dist/cli-main.js +4 -0
  12. package/dist/cli-main.js.map +1 -1
  13. package/dist/cli.js +2 -0
  14. package/dist/cli.js.map +1 -1
  15. package/dist/core/agent-session-runtime.d.ts +2 -0
  16. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  17. package/dist/core/agent-session-runtime.js +33 -8
  18. package/dist/core/agent-session-runtime.js.map +1 -1
  19. package/dist/core/agent-session.d.ts +9 -3
  20. package/dist/core/agent-session.d.ts.map +1 -1
  21. package/dist/core/agent-session.js +179 -57
  22. package/dist/core/agent-session.js.map +1 -1
  23. package/dist/core/auth-providers.d.ts +2 -2
  24. package/dist/core/auth-providers.js +2 -2
  25. package/dist/core/auth-providers.js.map +1 -1
  26. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/bash-timeout/timeout.js +3 -2
  28. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  29. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/compaction/index.js +30 -2
  31. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/compaction/speculative.js +28 -0
  34. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  35. package/dist/core/extensions/builtin/goal/command-registration.js +2 -2
  36. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  37. package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
  38. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/goal/format.js +9 -2
  40. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  41. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/goal/index.js +38 -23
  43. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  44. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +6 -0
  45. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -0
  46. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +19 -0
  47. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -0
  48. package/dist/core/extensions/builtin/goal/persistence.d.ts +6 -0
  49. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -0
  50. package/dist/core/extensions/builtin/goal/persistence.js +141 -0
  51. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -0
  52. package/dist/core/extensions/builtin/goal/store.d.ts +7 -3
  53. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/goal/store.js +66 -181
  55. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  56. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
  57. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/goal/tool-registration.js +26 -15
  59. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/transitions.d.ts +3 -0
  61. package/dist/core/extensions/builtin/goal/transitions.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/goal/transitions.js +45 -0
  63. package/dist/core/extensions/builtin/goal/transitions.js.map +1 -0
  64. package/dist/core/extensions/builtin/goal/types.d.ts +10 -4
  65. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  66. package/dist/core/extensions/builtin/goal/types.js +2 -2
  67. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  68. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/goal/ui.js +2 -0
  70. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/validation.d.ts +8 -1
  72. package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/goal/validation.js +24 -12
  74. package/dist/core/extensions/builtin/goal/validation.js.map +1 -1
  75. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  76. package/dist/core/extensions/builtin/index.js +0 -2
  77. package/dist/core/extensions/builtin/index.js.map +1 -1
  78. package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
  79. package/dist/core/extensions/builtin/mcp/index.js +8 -5
  80. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  81. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  82. package/dist/core/extensions/builtin/permission-system/parsers.js +1 -0
  83. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  84. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/terminal/extension.js +32 -0
  86. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  87. package/dist/core/extensions/builtin/terminal/index.d.ts +1 -1
  88. package/dist/core/extensions/builtin/terminal/index.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/terminal/index.js +1 -1
  90. package/dist/core/extensions/builtin/terminal/index.js.map +1 -1
  91. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +29 -0
  92. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -0
  93. package/dist/core/extensions/builtin/terminal/monitor-notify.js +185 -0
  94. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -0
  95. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +35 -0
  96. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -0
  97. package/dist/core/extensions/builtin/terminal/monitor-registry.js +98 -0
  98. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -0
  99. package/dist/core/extensions/builtin/terminal/notify.d.ts +9 -0
  100. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/terminal/notify.js +30 -14
  102. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/prompt.d.ts +1 -1
  104. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  105. package/dist/core/extensions/builtin/terminal/prompt.js +13 -5
  106. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  107. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +3 -12
  108. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/terminal/runtime-session.js +4 -59
  110. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  111. package/dist/core/extensions/builtin/terminal/settings.d.ts +8 -0
  112. package/dist/core/extensions/builtin/terminal/settings.d.ts.map +1 -1
  113. package/dist/core/extensions/builtin/terminal/settings.js +16 -2
  114. package/dist/core/extensions/builtin/terminal/settings.js.map +1 -1
  115. package/dist/core/extensions/builtin/terminal/shared.d.ts +2 -2
  116. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  117. package/dist/core/extensions/builtin/terminal/shared.js +2 -1
  118. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  119. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +10 -4
  120. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  121. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +17 -96
  122. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  123. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -0
  124. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  126. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +41 -0
  127. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -0
  128. package/dist/core/extensions/builtin/terminal/tools/monitor.js +97 -0
  129. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -0
  130. package/dist/core/extensions/builtin/terminal/tools/render.d.ts +3 -0
  131. package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
  132. package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
  133. package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
  134. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts +19 -0
  135. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts.map +1 -0
  136. package/dist/core/extensions/builtin/todotools/fuzzy-match.js +70 -0
  137. package/dist/core/extensions/builtin/todotools/fuzzy-match.js.map +1 -0
  138. package/dist/core/extensions/builtin/todotools/normalize.d.ts +8 -0
  139. package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -0
  140. package/dist/core/extensions/builtin/todotools/normalize.js +174 -0
  141. package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -0
  142. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
  143. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  144. package/dist/core/extensions/builtin/todotools/prompt.js +4 -2
  145. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  146. package/dist/core/extensions/builtin/todotools/state.d.ts +9 -8
  147. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  148. package/dist/core/extensions/builtin/todotools/state.js +99 -48
  149. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  150. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +1 -1
  151. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/todotools/tools/todo.js +65 -38
  153. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  154. package/dist/core/extensions/loader.d.ts.map +1 -1
  155. package/dist/core/extensions/loader.js +12 -0
  156. package/dist/core/extensions/loader.js.map +1 -1
  157. package/dist/core/extensions/runner.d.ts +5 -0
  158. package/dist/core/extensions/runner.d.ts.map +1 -1
  159. package/dist/core/extensions/runner.js +12 -1
  160. package/dist/core/extensions/runner.js.map +1 -1
  161. package/dist/core/extensions/types.d.ts +23 -1
  162. package/dist/core/extensions/types.d.ts.map +1 -1
  163. package/dist/core/extensions/types.js.map +1 -1
  164. package/dist/core/keybindings.d.ts +0 -5
  165. package/dist/core/keybindings.d.ts.map +1 -1
  166. package/dist/core/keybindings.js +0 -2
  167. package/dist/core/keybindings.js.map +1 -1
  168. package/dist/core/messages.d.ts +32 -0
  169. package/dist/core/messages.d.ts.map +1 -1
  170. package/dist/core/messages.js +91 -0
  171. package/dist/core/messages.js.map +1 -1
  172. package/dist/core/model-resolver.d.ts +9 -1
  173. package/dist/core/model-resolver.d.ts.map +1 -1
  174. package/dist/core/model-resolver.js.map +1 -1
  175. package/dist/core/model-runtime.d.ts +2 -0
  176. package/dist/core/model-runtime.d.ts.map +1 -1
  177. package/dist/core/model-runtime.js +4 -3
  178. package/dist/core/model-runtime.js.map +1 -1
  179. package/dist/core/resource-loader.d.ts +9 -0
  180. package/dist/core/resource-loader.d.ts.map +1 -1
  181. package/dist/core/resource-loader.js +10 -2
  182. package/dist/core/resource-loader.js.map +1 -1
  183. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
  184. package/dist/core/retry-fallback/cooldown.js +5 -0
  185. package/dist/core/retry-fallback/cooldown.js.map +1 -1
  186. package/dist/core/sdk.d.ts.map +1 -1
  187. package/dist/core/sdk.js +11 -35
  188. package/dist/core/sdk.js.map +1 -1
  189. package/dist/core/settings-manager.d.ts +5 -16
  190. package/dist/core/settings-manager.d.ts.map +1 -1
  191. package/dist/core/settings-manager.js +0 -13
  192. package/dist/core/settings-manager.js.map +1 -1
  193. package/dist/core/slash-commands.d.ts.map +1 -1
  194. package/dist/core/slash-commands.js +1 -0
  195. package/dist/core/slash-commands.js.map +1 -1
  196. package/dist/core/timings.d.ts +7 -2
  197. package/dist/core/timings.d.ts.map +1 -1
  198. package/dist/core/timings.js +11 -0
  199. package/dist/core/timings.js.map +1 -1
  200. package/dist/inspector-policy.d.ts +22 -0
  201. package/dist/inspector-policy.d.ts.map +1 -0
  202. package/dist/inspector-policy.js +84 -0
  203. package/dist/inspector-policy.js.map +1 -0
  204. package/dist/main.d.ts +6 -0
  205. package/dist/main.d.ts.map +1 -1
  206. package/dist/main.js +20 -23
  207. package/dist/main.js.map +1 -1
  208. package/dist/modes/app-server/runtime.d.ts.map +1 -1
  209. package/dist/modes/app-server/runtime.js +1 -0
  210. package/dist/modes/app-server/runtime.js.map +1 -1
  211. package/dist/modes/app-server/threads/goal-handlers.js +4 -2
  212. package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
  213. package/dist/modes/app-server/threads/goal-wire.d.ts.map +1 -1
  214. package/dist/modes/app-server/threads/goal-wire.js +1 -0
  215. package/dist/modes/app-server/threads/goal-wire.js.map +1 -1
  216. package/dist/modes/app-server/threads/handlers.d.ts +1 -0
  217. package/dist/modes/app-server/threads/handlers.d.ts.map +1 -1
  218. package/dist/modes/app-server/threads/handlers.js +2 -0
  219. package/dist/modes/app-server/threads/handlers.js.map +1 -1
  220. package/dist/modes/app-server/threads/turn-runtime.d.ts +1 -0
  221. package/dist/modes/app-server/threads/turn-runtime.d.ts.map +1 -1
  222. package/dist/modes/app-server/threads/turn-runtime.js.map +1 -1
  223. package/dist/modes/app-server/threads/turns.d.ts.map +1 -1
  224. package/dist/modes/app-server/threads/turns.js +47 -3
  225. package/dist/modes/app-server/threads/turns.js.map +1 -1
  226. package/dist/modes/interactive/components/status-indicator.d.ts +1 -0
  227. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  228. package/dist/modes/interactive/components/status-indicator.js +29 -4
  229. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  230. package/dist/modes/interactive/components/tool-execution.d.ts +5 -1
  231. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  232. package/dist/modes/interactive/components/tool-execution.js +43 -17
  233. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  234. package/dist/modes/interactive/grok/chrome-tokens.d.ts +22 -0
  235. package/dist/modes/interactive/grok/chrome-tokens.d.ts.map +1 -0
  236. package/dist/modes/interactive/grok/chrome-tokens.js +27 -0
  237. package/dist/modes/interactive/grok/chrome-tokens.js.map +1 -0
  238. package/dist/modes/interactive/grok/chrome.d.ts +51 -0
  239. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -0
  240. package/dist/modes/interactive/grok/chrome.js +105 -0
  241. package/dist/modes/interactive/grok/chrome.js.map +1 -0
  242. package/dist/modes/interactive/grok/footer.d.ts +14 -0
  243. package/dist/modes/interactive/grok/footer.d.ts.map +1 -0
  244. package/dist/modes/interactive/grok/footer.js +27 -0
  245. package/dist/modes/interactive/grok/footer.js.map +1 -0
  246. package/dist/modes/interactive/grok/input-card.d.ts +9 -0
  247. package/dist/modes/interactive/grok/input-card.d.ts.map +1 -0
  248. package/dist/modes/interactive/grok/input-card.js +30 -0
  249. package/dist/modes/interactive/grok/input-card.js.map +1 -0
  250. package/dist/modes/interactive/grok/palette.d.ts +145 -0
  251. package/dist/modes/interactive/grok/palette.d.ts.map +1 -0
  252. package/dist/modes/interactive/grok/palette.js +92 -0
  253. package/dist/modes/interactive/grok/palette.js.map +1 -0
  254. package/dist/modes/interactive/grok/tool-row.d.ts +17 -0
  255. package/dist/modes/interactive/grok/tool-row.d.ts.map +1 -0
  256. package/dist/modes/interactive/grok/tool-row.js +26 -0
  257. package/dist/modes/interactive/grok/tool-row.js.map +1 -0
  258. package/dist/modes/interactive/grok/welcome-card.d.ts +10 -0
  259. package/dist/modes/interactive/grok/welcome-card.d.ts.map +1 -0
  260. package/dist/modes/interactive/grok/welcome-card.js +30 -0
  261. package/dist/modes/interactive/grok/welcome-card.js.map +1 -0
  262. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  263. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-mode.js +108 -52
  265. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/dist/modes/interactive/theme/grok-day.json +77 -0
  267. package/dist/modes/interactive/theme/grok-night.json +93 -0
  268. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  269. package/dist/modes/interactive/theme/theme.js +4 -0
  270. package/dist/modes/interactive/theme/theme.js.map +1 -1
  271. package/dist/modes/rpc/connection-handler.d.ts +3 -3
  272. package/dist/modes/rpc/connection-handler.js +6 -6
  273. package/dist/modes/rpc/connection-handler.js.map +1 -1
  274. package/dist/modes/rpc/custom-capability.d.ts +6 -7
  275. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  276. package/dist/modes/rpc/custom-capability.js +6 -7
  277. package/dist/modes/rpc/custom-capability.js.map +1 -1
  278. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  279. package/dist/modes/rpc/rpc-mode.js +5 -5
  280. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  281. package/dist/senpi +2 -0
  282. package/docs/docs.json +4 -0
  283. package/docs/environment-variables.md +1 -0
  284. package/docs/grok-neo.md +77 -0
  285. package/docs/keybindings.md +0 -1
  286. package/docs/settings.md +3 -3
  287. package/docs/terminal-tools.md +6 -3
  288. package/docs/usage.md +1 -1
  289. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
  290. package/node_modules/@code-yeongyu/senpi-codemode/README.md +39 -19
  291. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  292. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +6 -1
  293. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +0 -1
  294. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-notifier.ts +40 -0
  295. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +46 -66
  296. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +5 -2
  297. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -0
  298. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +19 -4
  299. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +7 -0
  300. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +8 -5
  301. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +23 -5
  302. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +322 -0
  303. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +253 -18
  304. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +58 -0
  305. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +28 -6
  306. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +20 -0
  307. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +65 -22
  308. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  309. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +4 -41
  310. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +3 -0
  312. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  313. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
  314. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  315. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +10 -0
  316. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -0
  317. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +38 -0
  318. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -0
  319. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
  320. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  321. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  322. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  323. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  324. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +135 -16
  325. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  326. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  328. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  329. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +1 -4
  330. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  331. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  332. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +4 -3
  333. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +2 -2
  335. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  336. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  338. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +67 -31
  339. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  340. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -1
  341. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  342. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  343. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  344. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  345. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +10 -0
  346. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  347. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +1 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -1
  349. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +7 -3
  350. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -1
  351. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts +9 -0
  352. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts.map +1 -0
  353. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js +16 -0
  354. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js.map +1 -0
  355. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  356. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  357. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +1 -0
  358. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  359. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +35 -3
  360. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  361. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -0
  362. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  363. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  364. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +32 -0
  365. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
  366. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +15 -7
  367. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
  368. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  369. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  370. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  371. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  372. package/package.json +8 -8
  373. package/dist/cli/neo/build-argv.d.ts +0 -19
  374. package/dist/cli/neo/build-argv.d.ts.map +0 -1
  375. package/dist/cli/neo/build-argv.js +0 -84
  376. package/dist/cli/neo/build-argv.js.map +0 -1
  377. package/dist/cli/neo/daemon-launch.d.ts +0 -25
  378. package/dist/cli/neo/daemon-launch.d.ts.map +0 -1
  379. package/dist/cli/neo/daemon-launch.js +0 -97
  380. package/dist/cli/neo/daemon-launch.js.map +0 -1
  381. package/dist/cli/neo/gate.d.ts +0 -15
  382. package/dist/cli/neo/gate.d.ts.map +0 -1
  383. package/dist/cli/neo/gate.js +0 -21
  384. package/dist/cli/neo/gate.js.map +0 -1
  385. package/dist/cli/neo/launch.d.ts +0 -24
  386. package/dist/cli/neo/launch.d.ts.map +0 -1
  387. package/dist/cli/neo/launch.js +0 -66
  388. package/dist/cli/neo/launch.js.map +0 -1
  389. package/dist/cli/neo/platform.d.ts +0 -38
  390. package/dist/cli/neo/platform.d.ts.map +0 -1
  391. package/dist/cli/neo/platform.js +0 -54
  392. package/dist/cli/neo/platform.js.map +0 -1
  393. package/dist/cli/neo/resolve-binary.d.ts +0 -39
  394. package/dist/cli/neo/resolve-binary.d.ts.map +0 -1
  395. package/dist/cli/neo/resolve-binary.js +0 -66
  396. package/dist/cli/neo/resolve-binary.js.map +0 -1
  397. package/dist/core/extensions/builtin/session-observer/index.d.ts +0 -5
  398. package/dist/core/extensions/builtin/session-observer/index.d.ts.map +0 -1
  399. package/dist/core/extensions/builtin/session-observer/index.js +0 -36
  400. package/dist/core/extensions/builtin/session-observer/index.js.map +0 -1
  401. package/dist/core/extensions/builtin/session-observer/loader.d.ts +0 -3
  402. package/dist/core/extensions/builtin/session-observer/loader.d.ts.map +0 -1
  403. package/dist/core/extensions/builtin/session-observer/loader.js +0 -20
  404. package/dist/core/extensions/builtin/session-observer/loader.js.map +0 -1
  405. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts +0 -7
  406. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts.map +0 -1
  407. package/dist/core/extensions/builtin/session-observer/overlay-format.js +0 -30
  408. package/dist/core/extensions/builtin/session-observer/overlay-format.js.map +0 -1
  409. package/dist/core/extensions/builtin/session-observer/overlay.d.ts +0 -51
  410. package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +0 -1
  411. package/dist/core/extensions/builtin/session-observer/overlay.js +0 -229
  412. package/dist/core/extensions/builtin/session-observer/overlay.js.map +0 -1
  413. package/dist/core/extensions/builtin/session-observer/scanner.d.ts +0 -10
  414. package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +0 -1
  415. package/dist/core/extensions/builtin/session-observer/scanner.js +0 -142
  416. package/dist/core/extensions/builtin/session-observer/scanner.js.map +0 -1
  417. package/dist/core/extensions/builtin/session-observer/text.d.ts +0 -7
  418. package/dist/core/extensions/builtin/session-observer/text.d.ts.map +0 -1
  419. package/dist/core/extensions/builtin/session-observer/text.js +0 -37
  420. package/dist/core/extensions/builtin/session-observer/text.js.map +0 -1
  421. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts +0 -7
  422. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts.map +0 -1
  423. package/dist/core/extensions/builtin/session-observer/transcript-entries.js +0 -71
  424. package/dist/core/extensions/builtin/session-observer/transcript-entries.js.map +0 -1
  425. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts +0 -11
  426. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts.map +0 -1
  427. package/dist/core/extensions/builtin/session-observer/transcript-format.js +0 -65
  428. package/dist/core/extensions/builtin/session-observer/transcript-format.js.map +0 -1
  429. package/dist/core/extensions/builtin/session-observer/transcript.d.ts +0 -4
  430. package/dist/core/extensions/builtin/session-observer/transcript.d.ts.map +0 -1
  431. package/dist/core/extensions/builtin/session-observer/transcript.js +0 -81
  432. package/dist/core/extensions/builtin/session-observer/transcript.js.map +0 -1
  433. package/dist/core/extensions/builtin/session-observer/types.d.ts +0 -33
  434. package/dist/core/extensions/builtin/session-observer/types.d.ts.map +0 -1
  435. package/dist/core/extensions/builtin/session-observer/types.js +0 -2
  436. package/dist/core/extensions/builtin/session-observer/types.js.map +0 -1
  437. package/dist/modes/rpc/neo-daemon-child-worker.d.ts +0 -29
  438. package/dist/modes/rpc/neo-daemon-child-worker.d.ts.map +0 -1
  439. package/dist/modes/rpc/neo-daemon-child-worker.js +0 -95
  440. package/dist/modes/rpc/neo-daemon-child-worker.js.map +0 -1
  441. package/dist/modes/rpc/neo-daemon-mode.d.ts +0 -110
  442. package/dist/modes/rpc/neo-daemon-mode.d.ts.map +0 -1
  443. package/dist/modes/rpc/neo-daemon-mode.js +0 -267
  444. package/dist/modes/rpc/neo-daemon-mode.js.map +0 -1
  445. package/dist/modes/rpc/neo-daemon-protocol.d.ts +0 -50
  446. package/dist/modes/rpc/neo-daemon-protocol.d.ts.map +0 -1
  447. package/dist/modes/rpc/neo-daemon-protocol.js +0 -66
  448. package/dist/modes/rpc/neo-daemon-protocol.js.map +0 -1
  449. package/dist/modes/rpc/neo-daemon-registry.d.ts +0 -98
  450. package/dist/modes/rpc/neo-daemon-registry.d.ts.map +0 -1
  451. package/dist/modes/rpc/neo-daemon-registry.js +0 -209
  452. package/dist/modes/rpc/neo-daemon-registry.js.map +0 -1
  453. package/dist/modes/rpc/neo-runtime-options-argv.d.ts +0 -17
  454. package/dist/modes/rpc/neo-runtime-options-argv.d.ts.map +0 -1
  455. package/dist/modes/rpc/neo-runtime-options-argv.js +0 -79
  456. package/dist/modes/rpc/neo-runtime-options-argv.js.map +0 -1
  457. package/dist/modes/rpc/neo-runtime-options.d.ts +0 -84
  458. package/dist/modes/rpc/neo-runtime-options.d.ts.map +0 -1
  459. package/dist/modes/rpc/neo-runtime-options.js +0 -92
  460. package/dist/modes/rpc/neo-runtime-options.js.map +0 -1
  461. package/docs/neo.md +0 -111
  462. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/runtime.ts +0 -258
  463. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/tools.ts +0 -106
@@ -4,12 +4,43 @@ export interface SelectItem {
4
4
  label: string;
5
5
  description?: string;
6
6
  }
7
+ /**
8
+ * Decomposed parts of a single select-list row, handed to a custom
9
+ * {@link SelectListTheme.renderRow} composer.
10
+ */
11
+ export interface SelectListRowParts {
12
+ /**
13
+ * The selection prefix exactly as rendered ("→ " selected, " " not).
14
+ * For selected rows the theme's `selectedPrefix` has already been applied,
15
+ * so the prefix can be coloured independently of the row background.
16
+ */
17
+ prefix: string;
18
+ /** The truncated primary label, without column-alignment padding. */
19
+ primary: string;
20
+ /**
21
+ * The truncated description including the column-alignment spacing that
22
+ * separates it from the primary text. Undefined when the row renders no
23
+ * description column (no description, or a terminal narrower than 40).
24
+ */
25
+ description?: string;
26
+ isSelected: boolean;
27
+ }
28
+ /** Custom row composer for {@link SelectListTheme.renderRow}. */
29
+ export type SelectListRenderRow = (parts: SelectListRowParts) => string;
7
30
  export interface SelectListTheme {
8
31
  selectedPrefix: (text: string) => string;
9
32
  selectedText: (text: string) => string;
10
33
  description: (text: string) => string;
11
34
  scrollInfo: (text: string) => string;
12
35
  noMatch: (text: string) => string;
36
+ /**
37
+ * Optional row composer. When present it takes over rendering of every
38
+ * item row, receiving the decomposed {@link SelectListRowParts} so prefix,
39
+ * primary text, description, and row background can be styled
40
+ * independently. When absent, rendering is byte-identical to the legacy
41
+ * composition (prefix + primary wrapped in `selectedText`, etc.).
42
+ */
43
+ renderRow?: SelectListRenderRow;
13
44
  }
14
45
  export interface SelectListTruncatePrimaryContext {
15
46
  text: string;
@@ -40,6 +71,7 @@ export declare class SelectList implements Component {
40
71
  render(width: number): string[];
41
72
  handleInput(keyData: string): void;
42
73
  private renderItem;
74
+ private composeRow;
43
75
  private getPrimaryColumnWidth;
44
76
  private getPrimaryColumnBounds;
45
77
  private truncatePrimary;
@@ -1 +1 @@
1
- {"version":3,"file":"select-list.d.ts","sourceRoot":"","sources":["../../src/components/select-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACvC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,gCAAgC,KAAK,MAAM,CAAC;CACxE;AAED,qBAAa,UAAW,YAAW,SAAS;IAC3C,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,MAAM,CAA0B;IAEjC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAEtD,YAAY,KAAK,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,GAAE,uBAA4B,EAMhH;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI9B;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEpC;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAoC9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAyBjC;IAED,OAAO,CAAC,UAAU;IAuClB,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,qBAAqB;IAO7B,eAAe,IAAI,UAAU,GAAG,IAAI,CAGnC;CACD"}
1
+ {"version":3,"file":"select-list.d.ts","sourceRoot":"","sources":["../../src/components/select-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,iEAAiE;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,MAAM,CAAC;AAExE,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACvC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,gCAAgC,KAAK,MAAM,CAAC;CACxE;AAED,qBAAa,UAAW,YAAW,SAAS;IAC3C,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,MAAM,CAA0B;IAEjC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAEtD,YAAY,KAAK,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,GAAE,uBAA4B,EAMhH;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI9B;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEpC;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAoC9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAyBjC;IAED,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,qBAAqB;IAO7B,eAAe,IAAI,UAAU,GAAG,IAAI,CAGnC;CACD"}
@@ -95,19 +95,27 @@ export class SelectList {
95
95
  const remainingWidth = width - descriptionStart - 2; // -2 for safety
96
96
  if (remainingWidth > MIN_DESCRIPTION_WIDTH) {
97
97
  const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
98
- if (isSelected) {
99
- return this.theme.selectedText(`${prefix}${truncatedValue}${spacing}${truncatedDesc}`);
100
- }
101
- const descText = this.theme.description(spacing + truncatedDesc);
102
- return prefix + truncatedValue + descText;
98
+ return this.composeRow(prefix, truncatedValue, spacing + truncatedDesc, isSelected);
103
99
  }
104
100
  }
105
101
  const maxWidth = width - prefixWidth - 2;
106
102
  const truncatedValue = this.truncatePrimary(item, isSelected, maxWidth, maxWidth);
103
+ return this.composeRow(prefix, truncatedValue, undefined, isSelected);
104
+ }
105
+ composeRow(prefix, primary, description, isSelected) {
106
+ if (this.theme.renderRow) {
107
+ return this.theme.renderRow({
108
+ prefix: isSelected ? this.theme.selectedPrefix(prefix) : prefix,
109
+ primary,
110
+ description,
111
+ isSelected,
112
+ });
113
+ }
114
+ // Legacy composition — byte-identical to the pre-seam renderer.
107
115
  if (isSelected) {
108
- return this.theme.selectedText(`${prefix}${truncatedValue}`);
116
+ return this.theme.selectedText(`${prefix}${primary}${description ?? ""}`);
109
117
  }
110
- return prefix + truncatedValue;
118
+ return prefix + primary + (description !== undefined ? this.theme.description(description) : "");
111
119
  }
112
120
  getPrimaryColumnWidth() {
113
121
  const { min, max } = this.getPrimaryColumnBounds();
@@ -1 +1 @@
1
- {"version":3,"file":"select-list.js","sourceRoot":"","sources":["../../src/components/select-list.ts"],"names":[],"mappings":"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","sourcesContent":["import { getKeybindings } from \"../keybindings.ts\";\nimport type { Component } from \"../tui.ts\";\nimport { truncateToWidth, visibleWidth } from \"../utils.ts\";\n\nconst DEFAULT_PRIMARY_COLUMN_WIDTH = 32;\nconst PRIMARY_COLUMN_GAP = 2;\nconst MIN_DESCRIPTION_WIDTH = 10;\n\nconst normalizeToSingleLine = (text: string): string => text.replace(/[\\r\\n]+/g, \" \").trim();\nconst clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(value, max));\n\nexport interface SelectItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\nexport interface SelectListTheme {\n\tselectedPrefix: (text: string) => string;\n\tselectedText: (text: string) => string;\n\tdescription: (text: string) => string;\n\tscrollInfo: (text: string) => string;\n\tnoMatch: (text: string) => string;\n}\n\nexport interface SelectListTruncatePrimaryContext {\n\ttext: string;\n\tmaxWidth: number;\n\tcolumnWidth: number;\n\titem: SelectItem;\n\tisSelected: boolean;\n}\n\nexport interface SelectListLayoutOptions {\n\tminPrimaryColumnWidth?: number;\n\tmaxPrimaryColumnWidth?: number;\n\ttruncatePrimary?: (context: SelectListTruncatePrimaryContext) => string;\n}\n\nexport class SelectList implements Component {\n\tprivate items: SelectItem[] = [];\n\tprivate filteredItems: SelectItem[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate maxVisible: number = 5;\n\tprivate theme: SelectListTheme;\n\tprivate layout: SelectListLayoutOptions;\n\n\tpublic onSelect?: (item: SelectItem) => void;\n\tpublic onCancel?: () => void;\n\tpublic onSelectionChange?: (item: SelectItem) => void;\n\n\tconstructor(items: SelectItem[], maxVisible: number, theme: SelectListTheme, layout: SelectListLayoutOptions = {}) {\n\t\tthis.items = items;\n\t\tthis.filteredItems = items;\n\t\tthis.maxVisible = maxVisible;\n\t\tthis.theme = theme;\n\t\tthis.layout = layout;\n\t}\n\n\tsetFilter(filter: string): void {\n\t\tthis.filteredItems = this.items.filter((item) => item.value.toLowerCase().startsWith(filter.toLowerCase()));\n\t\t// Reset selection when filter changes\n\t\tthis.selectedIndex = 0;\n\t}\n\n\tsetSelectedIndex(index: number): void {\n\t\tthis.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// If no items match filter, show message\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(this.theme.noMatch(\" No matching commands\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst primaryColumnWidth = this.getPrimaryColumnWidth();\n\n\t\t// Calculate visible range with scrolling\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\t// Render visible items\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst item = this.filteredItems[i];\n\t\t\tif (!item) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst descriptionSingleLine = item.description ? normalizeToSingleLine(item.description) : undefined;\n\t\t\tlines.push(this.renderItem(item, isSelected, width, descriptionSingleLine, primaryColumnWidth));\n\t\t}\n\n\t\t// Add scroll indicators if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;\n\t\t\t// Truncate if too long for terminal\n\t\t\tlines.push(this.theme.scrollInfo(truncateToWidth(scrollText, width - 2, \"\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Up arrow - wrap to bottom when at top\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1;\n\t\t\tthis.notifySelectionChange();\n\t\t}\n\t\t// Down arrow - wrap to top when at bottom\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t\tthis.notifySelectionChange();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedItem = this.filteredItems[this.selectedIndex];\n\t\t\tif (selectedItem && this.onSelect) {\n\t\t\t\tthis.onSelect(selectedItem);\n\t\t\t}\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tif (this.onCancel) {\n\t\t\t\tthis.onCancel();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate renderItem(\n\t\titem: SelectItem,\n\t\tisSelected: boolean,\n\t\twidth: number,\n\t\tdescriptionSingleLine: string | undefined,\n\t\tprimaryColumnWidth: number,\n\t): string {\n\t\tconst prefix = isSelected ? \"→ \" : \" \";\n\t\tconst prefixWidth = visibleWidth(prefix);\n\n\t\tif (descriptionSingleLine && width > 40) {\n\t\t\tconst effectivePrimaryColumnWidth = Math.max(1, Math.min(primaryColumnWidth, width - prefixWidth - 4));\n\t\t\tconst maxPrimaryWidth = Math.max(1, effectivePrimaryColumnWidth - PRIMARY_COLUMN_GAP);\n\t\t\tconst truncatedValue = this.truncatePrimary(item, isSelected, maxPrimaryWidth, effectivePrimaryColumnWidth);\n\t\t\tconst truncatedValueWidth = visibleWidth(truncatedValue);\n\t\t\tconst spacing = \" \".repeat(Math.max(1, effectivePrimaryColumnWidth - truncatedValueWidth));\n\t\t\tconst descriptionStart = prefixWidth + truncatedValueWidth + spacing.length;\n\t\t\tconst remainingWidth = width - descriptionStart - 2; // -2 for safety\n\n\t\t\tif (remainingWidth > MIN_DESCRIPTION_WIDTH) {\n\t\t\t\tconst truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, \"\");\n\t\t\t\tif (isSelected) {\n\t\t\t\t\treturn this.theme.selectedText(`${prefix}${truncatedValue}${spacing}${truncatedDesc}`);\n\t\t\t\t}\n\n\t\t\t\tconst descText = this.theme.description(spacing + truncatedDesc);\n\t\t\t\treturn prefix + truncatedValue + descText;\n\t\t\t}\n\t\t}\n\n\t\tconst maxWidth = width - prefixWidth - 2;\n\t\tconst truncatedValue = this.truncatePrimary(item, isSelected, maxWidth, maxWidth);\n\t\tif (isSelected) {\n\t\t\treturn this.theme.selectedText(`${prefix}${truncatedValue}`);\n\t\t}\n\n\t\treturn prefix + truncatedValue;\n\t}\n\n\tprivate getPrimaryColumnWidth(): number {\n\t\tconst { min, max } = this.getPrimaryColumnBounds();\n\t\tconst widestPrimary = this.filteredItems.reduce((widest, item) => {\n\t\t\treturn Math.max(widest, visibleWidth(this.getDisplayValue(item)) + PRIMARY_COLUMN_GAP);\n\t\t}, 0);\n\n\t\treturn clamp(widestPrimary, min, max);\n\t}\n\n\tprivate getPrimaryColumnBounds(): { min: number; max: number } {\n\t\tconst rawMin =\n\t\t\tthis.layout.minPrimaryColumnWidth ?? this.layout.maxPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n\t\tconst rawMax =\n\t\t\tthis.layout.maxPrimaryColumnWidth ?? this.layout.minPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n\n\t\treturn {\n\t\t\tmin: Math.max(1, Math.min(rawMin, rawMax)),\n\t\t\tmax: Math.max(1, Math.max(rawMin, rawMax)),\n\t\t};\n\t}\n\n\tprivate truncatePrimary(item: SelectItem, isSelected: boolean, maxWidth: number, columnWidth: number): string {\n\t\tconst displayValue = this.getDisplayValue(item);\n\t\tconst truncatedValue = this.layout.truncatePrimary\n\t\t\t? this.layout.truncatePrimary({\n\t\t\t\t\ttext: displayValue,\n\t\t\t\t\tmaxWidth,\n\t\t\t\t\tcolumnWidth,\n\t\t\t\t\titem,\n\t\t\t\t\tisSelected,\n\t\t\t\t})\n\t\t\t: truncateToWidth(displayValue, maxWidth, \"\");\n\n\t\treturn truncateToWidth(truncatedValue, maxWidth, \"\");\n\t}\n\n\tprivate getDisplayValue(item: SelectItem): string {\n\t\treturn item.label || item.value;\n\t}\n\n\tprivate notifySelectionChange(): void {\n\t\tconst selectedItem = this.filteredItems[this.selectedIndex];\n\t\tif (selectedItem && this.onSelectionChange) {\n\t\t\tthis.onSelectionChange(selectedItem);\n\t\t}\n\t}\n\n\tgetSelectedItem(): SelectItem | null {\n\t\tconst item = this.filteredItems[this.selectedIndex];\n\t\treturn item || null;\n\t}\n}\n"]}
1
+ {"version":3,"file":"select-list.js","sourceRoot":"","sources":["../../src/components/select-list.ts"],"names":[],"mappings":"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","sourcesContent":["import { getKeybindings } from \"../keybindings.ts\";\nimport type { Component } from \"../tui.ts\";\nimport { truncateToWidth, visibleWidth } from \"../utils.ts\";\n\nconst DEFAULT_PRIMARY_COLUMN_WIDTH = 32;\nconst PRIMARY_COLUMN_GAP = 2;\nconst MIN_DESCRIPTION_WIDTH = 10;\n\nconst normalizeToSingleLine = (text: string): string => text.replace(/[\\r\\n]+/g, \" \").trim();\nconst clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(value, max));\n\nexport interface SelectItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\n/**\n * Decomposed parts of a single select-list row, handed to a custom\n * {@link SelectListTheme.renderRow} composer.\n */\nexport interface SelectListRowParts {\n\t/**\n\t * The selection prefix exactly as rendered (\"→ \" selected, \" \" not).\n\t * For selected rows the theme's `selectedPrefix` has already been applied,\n\t * so the prefix can be coloured independently of the row background.\n\t */\n\tprefix: string;\n\t/** The truncated primary label, without column-alignment padding. */\n\tprimary: string;\n\t/**\n\t * The truncated description including the column-alignment spacing that\n\t * separates it from the primary text. Undefined when the row renders no\n\t * description column (no description, or a terminal narrower than 40).\n\t */\n\tdescription?: string;\n\tisSelected: boolean;\n}\n\n/** Custom row composer for {@link SelectListTheme.renderRow}. */\nexport type SelectListRenderRow = (parts: SelectListRowParts) => string;\n\nexport interface SelectListTheme {\n\tselectedPrefix: (text: string) => string;\n\tselectedText: (text: string) => string;\n\tdescription: (text: string) => string;\n\tscrollInfo: (text: string) => string;\n\tnoMatch: (text: string) => string;\n\t/**\n\t * Optional row composer. When present it takes over rendering of every\n\t * item row, receiving the decomposed {@link SelectListRowParts} so prefix,\n\t * primary text, description, and row background can be styled\n\t * independently. When absent, rendering is byte-identical to the legacy\n\t * composition (prefix + primary wrapped in `selectedText`, etc.).\n\t */\n\trenderRow?: SelectListRenderRow;\n}\n\nexport interface SelectListTruncatePrimaryContext {\n\ttext: string;\n\tmaxWidth: number;\n\tcolumnWidth: number;\n\titem: SelectItem;\n\tisSelected: boolean;\n}\n\nexport interface SelectListLayoutOptions {\n\tminPrimaryColumnWidth?: number;\n\tmaxPrimaryColumnWidth?: number;\n\ttruncatePrimary?: (context: SelectListTruncatePrimaryContext) => string;\n}\n\nexport class SelectList implements Component {\n\tprivate items: SelectItem[] = [];\n\tprivate filteredItems: SelectItem[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate maxVisible: number = 5;\n\tprivate theme: SelectListTheme;\n\tprivate layout: SelectListLayoutOptions;\n\n\tpublic onSelect?: (item: SelectItem) => void;\n\tpublic onCancel?: () => void;\n\tpublic onSelectionChange?: (item: SelectItem) => void;\n\n\tconstructor(items: SelectItem[], maxVisible: number, theme: SelectListTheme, layout: SelectListLayoutOptions = {}) {\n\t\tthis.items = items;\n\t\tthis.filteredItems = items;\n\t\tthis.maxVisible = maxVisible;\n\t\tthis.theme = theme;\n\t\tthis.layout = layout;\n\t}\n\n\tsetFilter(filter: string): void {\n\t\tthis.filteredItems = this.items.filter((item) => item.value.toLowerCase().startsWith(filter.toLowerCase()));\n\t\t// Reset selection when filter changes\n\t\tthis.selectedIndex = 0;\n\t}\n\n\tsetSelectedIndex(index: number): void {\n\t\tthis.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// If no items match filter, show message\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(this.theme.noMatch(\" No matching commands\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst primaryColumnWidth = this.getPrimaryColumnWidth();\n\n\t\t// Calculate visible range with scrolling\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\t// Render visible items\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst item = this.filteredItems[i];\n\t\t\tif (!item) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst descriptionSingleLine = item.description ? normalizeToSingleLine(item.description) : undefined;\n\t\t\tlines.push(this.renderItem(item, isSelected, width, descriptionSingleLine, primaryColumnWidth));\n\t\t}\n\n\t\t// Add scroll indicators if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;\n\t\t\t// Truncate if too long for terminal\n\t\t\tlines.push(this.theme.scrollInfo(truncateToWidth(scrollText, width - 2, \"\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Up arrow - wrap to bottom when at top\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1;\n\t\t\tthis.notifySelectionChange();\n\t\t}\n\t\t// Down arrow - wrap to top when at bottom\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t\tthis.notifySelectionChange();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedItem = this.filteredItems[this.selectedIndex];\n\t\t\tif (selectedItem && this.onSelect) {\n\t\t\t\tthis.onSelect(selectedItem);\n\t\t\t}\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tif (this.onCancel) {\n\t\t\t\tthis.onCancel();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate renderItem(\n\t\titem: SelectItem,\n\t\tisSelected: boolean,\n\t\twidth: number,\n\t\tdescriptionSingleLine: string | undefined,\n\t\tprimaryColumnWidth: number,\n\t): string {\n\t\tconst prefix = isSelected ? \"→ \" : \" \";\n\t\tconst prefixWidth = visibleWidth(prefix);\n\n\t\tif (descriptionSingleLine && width > 40) {\n\t\t\tconst effectivePrimaryColumnWidth = Math.max(1, Math.min(primaryColumnWidth, width - prefixWidth - 4));\n\t\t\tconst maxPrimaryWidth = Math.max(1, effectivePrimaryColumnWidth - PRIMARY_COLUMN_GAP);\n\t\t\tconst truncatedValue = this.truncatePrimary(item, isSelected, maxPrimaryWidth, effectivePrimaryColumnWidth);\n\t\t\tconst truncatedValueWidth = visibleWidth(truncatedValue);\n\t\t\tconst spacing = \" \".repeat(Math.max(1, effectivePrimaryColumnWidth - truncatedValueWidth));\n\t\t\tconst descriptionStart = prefixWidth + truncatedValueWidth + spacing.length;\n\t\t\tconst remainingWidth = width - descriptionStart - 2; // -2 for safety\n\n\t\t\tif (remainingWidth > MIN_DESCRIPTION_WIDTH) {\n\t\t\t\tconst truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, \"\");\n\t\t\t\treturn this.composeRow(prefix, truncatedValue, spacing + truncatedDesc, isSelected);\n\t\t\t}\n\t\t}\n\n\t\tconst maxWidth = width - prefixWidth - 2;\n\t\tconst truncatedValue = this.truncatePrimary(item, isSelected, maxWidth, maxWidth);\n\t\treturn this.composeRow(prefix, truncatedValue, undefined, isSelected);\n\t}\n\n\tprivate composeRow(prefix: string, primary: string, description: string | undefined, isSelected: boolean): string {\n\t\tif (this.theme.renderRow) {\n\t\t\treturn this.theme.renderRow({\n\t\t\t\tprefix: isSelected ? this.theme.selectedPrefix(prefix) : prefix,\n\t\t\t\tprimary,\n\t\t\t\tdescription,\n\t\t\t\tisSelected,\n\t\t\t});\n\t\t}\n\n\t\t// Legacy composition — byte-identical to the pre-seam renderer.\n\t\tif (isSelected) {\n\t\t\treturn this.theme.selectedText(`${prefix}${primary}${description ?? \"\"}`);\n\t\t}\n\n\t\treturn prefix + primary + (description !== undefined ? this.theme.description(description) : \"\");\n\t}\n\n\tprivate getPrimaryColumnWidth(): number {\n\t\tconst { min, max } = this.getPrimaryColumnBounds();\n\t\tconst widestPrimary = this.filteredItems.reduce((widest, item) => {\n\t\t\treturn Math.max(widest, visibleWidth(this.getDisplayValue(item)) + PRIMARY_COLUMN_GAP);\n\t\t}, 0);\n\n\t\treturn clamp(widestPrimary, min, max);\n\t}\n\n\tprivate getPrimaryColumnBounds(): { min: number; max: number } {\n\t\tconst rawMin =\n\t\t\tthis.layout.minPrimaryColumnWidth ?? this.layout.maxPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n\t\tconst rawMax =\n\t\t\tthis.layout.maxPrimaryColumnWidth ?? this.layout.minPrimaryColumnWidth ?? DEFAULT_PRIMARY_COLUMN_WIDTH;\n\n\t\treturn {\n\t\t\tmin: Math.max(1, Math.min(rawMin, rawMax)),\n\t\t\tmax: Math.max(1, Math.max(rawMin, rawMax)),\n\t\t};\n\t}\n\n\tprivate truncatePrimary(item: SelectItem, isSelected: boolean, maxWidth: number, columnWidth: number): string {\n\t\tconst displayValue = this.getDisplayValue(item);\n\t\tconst truncatedValue = this.layout.truncatePrimary\n\t\t\t? this.layout.truncatePrimary({\n\t\t\t\t\ttext: displayValue,\n\t\t\t\t\tmaxWidth,\n\t\t\t\t\tcolumnWidth,\n\t\t\t\t\titem,\n\t\t\t\t\tisSelected,\n\t\t\t\t})\n\t\t\t: truncateToWidth(displayValue, maxWidth, \"\");\n\n\t\treturn truncateToWidth(truncatedValue, maxWidth, \"\");\n\t}\n\n\tprivate getDisplayValue(item: SelectItem): string {\n\t\treturn item.label || item.value;\n\t}\n\n\tprivate notifySelectionChange(): void {\n\t\tconst selectedItem = this.filteredItems[this.selectedIndex];\n\t\tif (selectedItem && this.onSelectionChange) {\n\t\t\tthis.onSelectionChange(selectedItem);\n\t\t}\n\t}\n\n\tgetSelectedItem(): SelectItem | null {\n\t\tconst item = this.filteredItems[this.selectedIndex];\n\t\treturn item || null;\n\t}\n}\n"]}
@@ -6,7 +6,7 @@ export { Image, type ImageOptions, type ImageTheme } from "./components/image.ts
6
6
  export { Input } from "./components/input.ts";
7
7
  export { Loader, type LoaderIndicatorOptions } from "./components/loader.ts";
8
8
  export { clearRenderCache, type DefaultTextStyle, getMarkdownHighlightCallCount, Markdown, type MarkdownOptions, type MarkdownTheme, resetMarkdownHighlightCallCount, } from "./components/markdown.ts";
9
- export { type SelectItem, SelectList, type SelectListLayoutOptions, type SelectListTheme, type SelectListTruncatePrimaryContext, } from "./components/select-list.ts";
9
+ export { type SelectItem, SelectList, type SelectListLayoutOptions, type SelectListRenderRow, type SelectListRowParts, type SelectListTheme, type SelectListTruncatePrimaryContext, } from "./components/select-list.ts";
10
10
  export { type SettingItem, SettingsList, type SettingsListTheme } from "./components/settings-list.ts";
11
11
  export { Spacer } from "./components/spacer.ts";
12
12
  export { Text } from "./components/text.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAIN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAA+B,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EACN,gBAAgB,EAEhB,6BAA6B,EAC7B,QAAQ,EAGR,+BAA+B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEN,UAAU,GAIV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,cAAc,EAOd,kBAAkB,EAClB,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAC;AAC5F,kBAAkB;AAClB,OAAO,EACN,yBAAyB,EACzB,8BAA8B,GAG9B,MAAM,sBAAsB,CAAC;AAC9B,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EAIT,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAOX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EACN,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport {\n\tclearRenderCache,\n\ttype DefaultTextStyle,\n\tgetMarkdownHighlightCallCount,\n\tMarkdown,\n\ttype MarkdownOptions,\n\ttype MarkdownTheme,\n\tresetMarkdownHighlightCallCount,\n} from \"./components/markdown.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type ProcessTerminalOptions, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.ts\";\nexport { imageFallback, sanitizeTerminalLabel } from \"./terminal-text.ts\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.ts\";\n// Utilities\nexport {\n\tgetGraphemeSegmenter,\n\tgetWordSegmenter,\n\tsliceByColumn,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAIN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAA+B,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EACN,gBAAgB,EAEhB,6BAA6B,EAC7B,QAAQ,EAGR,+BAA+B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEN,UAAU,GAMV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,cAAc,EAOd,kBAAkB,EAClB,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAC;AAC5F,kBAAkB;AAClB,OAAO,EACN,yBAAyB,EACzB,8BAA8B,GAG9B,MAAM,sBAAsB,CAAC;AAC9B,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EAIT,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAOX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EACN,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport {\n\tclearRenderCache,\n\ttype DefaultTextStyle,\n\tgetMarkdownHighlightCallCount,\n\tMarkdown,\n\ttype MarkdownOptions,\n\ttype MarkdownTheme,\n\tresetMarkdownHighlightCallCount,\n} from \"./components/markdown.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListRenderRow,\n\ttype SelectListRowParts,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type ProcessTerminalOptions, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.ts\";\nexport { imageFallback, sanitizeTerminalLabel } from \"./terminal-text.ts\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.ts\";\n// Utilities\nexport {\n\tgetGraphemeSegmenter,\n\tgetWordSegmenter,\n\tsliceByColumn,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-tui",
3
3
  "private": true,
4
- "version": "2026.7.25-2",
4
+ "version": "2026.7.26",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.7.25-2",
3
+ "version": "2026.7.26",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -32,9 +32,9 @@
32
32
  "clean": "shx rm -rf dist",
33
33
  "dev": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
34
34
  "build": "tsgo -p tsconfig.build.json && npm run copy-assets && shx chmod +x dist/cli.js dist/rpc-entry.js && shx cp dist/cli.js dist/senpi && shx chmod +x dist/senpi",
35
- "build:binary": "npm --prefix ../tui run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm run build && bun build --compile --no-compile-autoload-dotenv --minify --keep-names ./dist/bun/cli.js ./src/utils/image-resize-worker.ts --outfile dist/pi && npm run copy-binary-assets",
35
+ "build:binary": "npm --prefix ../tui run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm run build && bun build --compile --compile-autoload-package-json --external=css-tree --no-compile-autoload-dotenv --minify --keep-names ./dist/bun/cli.js ./src/utils/image-resize-worker.ts --outfile dist/pi && npm run copy-binary-assets",
36
36
  "copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/",
37
- "copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html dist/export-html/ && shx cp src/core/export-html/vendor/*.js dist/export-html/vendor/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && node ../../scripts/copy-pty-native.mjs",
37
+ "copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/export-html/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx mkdir -p dist/node_modules && shx cp -r ../../node_modules/css-tree ../../node_modules/mdn-data ../../node_modules/source-map-js dist/node_modules/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/native/darwin dist/native/win32 && shx cp -r ../../packages/tui/native/darwin/prebuilds dist/native/darwin/ && shx cp -r ../../packages/tui/native/win32/prebuilds dist/native/win32/ && node ../../scripts/copy-pty-native.mjs",
38
38
  "qa:app-server": "node scripts/qa-app-server/run-all.mjs",
39
39
  "test": "vitest --run",
40
40
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap",
@@ -43,11 +43,11 @@
43
43
  "dependencies": {
44
44
  "@anthropic-ai/sdk": "0.91.1",
45
45
  "@aws-sdk/client-bedrock-runtime": "3.1048.0",
46
- "@code-yeongyu/senpi-codemode": "^2026.7.25-2",
47
- "@earendil-works/pi-agent-core": "^2026.7.25-2",
48
- "@earendil-works/pi-ai": "^2026.7.25-2",
49
- "@earendil-works/pi-pty": "^2026.7.25-2",
50
- "@earendil-works/pi-tui": "^2026.7.25-2",
46
+ "@code-yeongyu/senpi-codemode": "^2026.7.26",
47
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@^2026.7.26",
48
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@^2026.7.26",
49
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@^2026.7.26",
50
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@^2026.7.26",
51
51
  "@mistralai/mistralai": "2.2.6",
52
52
  "@modelcontextprotocol/sdk": "1.29.0",
53
53
  "@mozilla/readability": "0.6.0",
@@ -1,19 +0,0 @@
1
- /**
2
- * Translate a parsed classic argv into the argv handed to the neo (Go) binary.
3
- *
4
- * The launcher forwards every runtime-relevant flag so the Go TUI (and, through
5
- * it, the daemon connection) reconstructs the same runtime the classic path
6
- * would have built. Initial inputs — positional messages and @file mentions —
7
- * are forwarded RAW (no expansion here). Launch-time @file/image expansion is NOT
8
- * yet implemented on the daemon side: the plain positional text is delivered as a
9
- * `prompt` command, and the Go TUI surfaces a one-line non-fatal notice for any
10
- * @file arg instead of sending it as an unexpanded `@`-literal. @file args are
11
- * still re-prefixed with `@` to match the tokens the Go arg parser expects.
12
- */
13
- import type { Args } from "../args.ts";
14
- export interface BuildNeoArgvOptions {
15
- /** When true, emit the leading `--isolated` flag for a per-instance backend. */
16
- readonly isolated: boolean;
17
- }
18
- export declare function buildNeoArgv(parsed: Args, options: BuildNeoArgvOptions): string[];
19
- //# sourceMappingURL=build-argv.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-argv.d.ts","sourceRoot":"","sources":["../../../src/cli/neo/build-argv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IACnC,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,EAAE,CA2DjF"}
@@ -1,84 +0,0 @@
1
- /**
2
- * Translate a parsed classic argv into the argv handed to the neo (Go) binary.
3
- *
4
- * The launcher forwards every runtime-relevant flag so the Go TUI (and, through
5
- * it, the daemon connection) reconstructs the same runtime the classic path
6
- * would have built. Initial inputs — positional messages and @file mentions —
7
- * are forwarded RAW (no expansion here). Launch-time @file/image expansion is NOT
8
- * yet implemented on the daemon side: the plain positional text is delivered as a
9
- * `prompt` command, and the Go TUI surfaces a one-line non-fatal notice for any
10
- * @file arg instead of sending it as an unexpanded `@`-literal. @file args are
11
- * still re-prefixed with `@` to match the tokens the Go arg parser expects.
12
- */
13
- export function buildNeoArgv(parsed, options) {
14
- const argv = [];
15
- if (options.isolated) {
16
- argv.push("--isolated");
17
- }
18
- // Provider / model / thinking / auth.
19
- pushValue(argv, "--provider", parsed.provider);
20
- pushValue(argv, "--model", parsed.model);
21
- pushValue(argv, "--models", parsed.models?.join(","));
22
- pushValue(argv, "--thinking", parsed.thinking);
23
- pushValue(argv, "--api-key", parsed.apiKey);
24
- // Session selection.
25
- pushValue(argv, "--session", parsed.session);
26
- pushValue(argv, "--session-id", parsed.sessionId);
27
- pushValue(argv, "--session-dir", parsed.sessionDir);
28
- pushValue(argv, "--fork", parsed.fork);
29
- pushValue(argv, "--name", parsed.name);
30
- pushFlag(argv, "--resume", parsed.resume);
31
- pushFlag(argv, "--continue", parsed.continue);
32
- pushFlag(argv, "--no-session", parsed.noSession);
33
- // Approval.
34
- if (parsed.projectTrustOverride === true) {
35
- argv.push("--approve");
36
- }
37
- else if (parsed.projectTrustOverride === false) {
38
- argv.push("--no-approve");
39
- }
40
- // Tool scoping.
41
- pushValue(argv, "--tools", parsed.tools?.join(","));
42
- pushValue(argv, "--exclude-tools", parsed.excludeTools?.join(","));
43
- pushFlag(argv, "--no-tools", parsed.noTools);
44
- pushFlag(argv, "--no-builtin-tools", parsed.noBuiltinTools);
45
- // Resource loading.
46
- pushRepeated(argv, "--extension", parsed.extensions);
47
- pushRepeated(argv, "--skill", parsed.skills);
48
- pushRepeated(argv, "--prompt-template", parsed.promptTemplates);
49
- pushRepeated(argv, "--theme", parsed.themes);
50
- pushFlag(argv, "--no-extensions", parsed.noExtensions);
51
- pushFlag(argv, "--no-skills", parsed.noSkills);
52
- pushFlag(argv, "--no-prompt-templates", parsed.noPromptTemplates);
53
- pushFlag(argv, "--no-themes", parsed.noThemes);
54
- pushFlag(argv, "--no-context-files", parsed.noContextFiles);
55
- pushValue(argv, "--system-prompt", parsed.systemPrompt);
56
- pushRepeated(argv, "--append-system-prompt", parsed.appendSystemPrompt);
57
- // Initial inputs — RAW, no expansion in the launcher.
58
- for (const message of parsed.messages) {
59
- argv.push(message);
60
- }
61
- for (const fileArg of parsed.fileArgs) {
62
- argv.push(`@${fileArg}`);
63
- }
64
- return argv;
65
- }
66
- function pushValue(argv, flag, value) {
67
- if (value !== undefined) {
68
- argv.push(flag, value);
69
- }
70
- }
71
- function pushFlag(argv, flag, value) {
72
- if (value === true) {
73
- argv.push(flag);
74
- }
75
- }
76
- function pushRepeated(argv, flag, values) {
77
- if (values === undefined) {
78
- return;
79
- }
80
- for (const value of values) {
81
- argv.push(flag, value);
82
- }
83
- }
84
- //# sourceMappingURL=build-argv.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-argv.js","sourceRoot":"","sources":["../../../src/cli/neo/build-argv.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Translate a parsed classic argv into the argv handed to the neo (Go) binary.\n *\n * The launcher forwards every runtime-relevant flag so the Go TUI (and, through\n * it, the daemon connection) reconstructs the same runtime the classic path\n * would have built. Initial inputs — positional messages and @file mentions —\n * are forwarded RAW (no expansion here). Launch-time @file/image expansion is NOT\n * yet implemented on the daemon side: the plain positional text is delivered as a\n * `prompt` command, and the Go TUI surfaces a one-line non-fatal notice for any\n * @file arg instead of sending it as an unexpanded `@`-literal. @file args are\n * still re-prefixed with `@` to match the tokens the Go arg parser expects.\n */\n\nimport type { Args } from \"../args.ts\";\n\nexport interface BuildNeoArgvOptions {\n\t/** When true, emit the leading `--isolated` flag for a per-instance backend. */\n\treadonly isolated: boolean;\n}\n\nexport function buildNeoArgv(parsed: Args, options: BuildNeoArgvOptions): string[] {\n\tconst argv: string[] = [];\n\n\tif (options.isolated) {\n\t\targv.push(\"--isolated\");\n\t}\n\n\t// Provider / model / thinking / auth.\n\tpushValue(argv, \"--provider\", parsed.provider);\n\tpushValue(argv, \"--model\", parsed.model);\n\tpushValue(argv, \"--models\", parsed.models?.join(\",\"));\n\tpushValue(argv, \"--thinking\", parsed.thinking);\n\tpushValue(argv, \"--api-key\", parsed.apiKey);\n\n\t// Session selection.\n\tpushValue(argv, \"--session\", parsed.session);\n\tpushValue(argv, \"--session-id\", parsed.sessionId);\n\tpushValue(argv, \"--session-dir\", parsed.sessionDir);\n\tpushValue(argv, \"--fork\", parsed.fork);\n\tpushValue(argv, \"--name\", parsed.name);\n\tpushFlag(argv, \"--resume\", parsed.resume);\n\tpushFlag(argv, \"--continue\", parsed.continue);\n\tpushFlag(argv, \"--no-session\", parsed.noSession);\n\n\t// Approval.\n\tif (parsed.projectTrustOverride === true) {\n\t\targv.push(\"--approve\");\n\t} else if (parsed.projectTrustOverride === false) {\n\t\targv.push(\"--no-approve\");\n\t}\n\n\t// Tool scoping.\n\tpushValue(argv, \"--tools\", parsed.tools?.join(\",\"));\n\tpushValue(argv, \"--exclude-tools\", parsed.excludeTools?.join(\",\"));\n\tpushFlag(argv, \"--no-tools\", parsed.noTools);\n\tpushFlag(argv, \"--no-builtin-tools\", parsed.noBuiltinTools);\n\n\t// Resource loading.\n\tpushRepeated(argv, \"--extension\", parsed.extensions);\n\tpushRepeated(argv, \"--skill\", parsed.skills);\n\tpushRepeated(argv, \"--prompt-template\", parsed.promptTemplates);\n\tpushRepeated(argv, \"--theme\", parsed.themes);\n\tpushFlag(argv, \"--no-extensions\", parsed.noExtensions);\n\tpushFlag(argv, \"--no-skills\", parsed.noSkills);\n\tpushFlag(argv, \"--no-prompt-templates\", parsed.noPromptTemplates);\n\tpushFlag(argv, \"--no-themes\", parsed.noThemes);\n\tpushFlag(argv, \"--no-context-files\", parsed.noContextFiles);\n\tpushValue(argv, \"--system-prompt\", parsed.systemPrompt);\n\tpushRepeated(argv, \"--append-system-prompt\", parsed.appendSystemPrompt);\n\n\t// Initial inputs — RAW, no expansion in the launcher.\n\tfor (const message of parsed.messages) {\n\t\targv.push(message);\n\t}\n\tfor (const fileArg of parsed.fileArgs) {\n\t\targv.push(`@${fileArg}`);\n\t}\n\n\treturn argv;\n}\n\nfunction pushValue(argv: string[], flag: string, value: string | undefined): void {\n\tif (value !== undefined) {\n\t\targv.push(flag, value);\n\t}\n}\n\nfunction pushFlag(argv: string[], flag: string, value: boolean | undefined): void {\n\tif (value === true) {\n\t\targv.push(flag);\n\t}\n}\n\nfunction pushRepeated(argv: string[], flag: string, values: readonly string[] | undefined): void {\n\tif (values === undefined) {\n\t\treturn;\n\t}\n\tfor (const value of values) {\n\t\targv.push(flag, value);\n\t}\n}\n"]}
@@ -1,25 +0,0 @@
1
- /**
2
- * Launch the neo shared daemon from the classic CLI.
3
- *
4
- * Dispatched from main.ts when `--listen <path>` is present. This runs the
5
- * daemon SUPERVISOR: it does NOT construct an AgentSessionRuntime in this
6
- * process — each accepted connection gets its own child `senpi --mode rpc`
7
- * worker with its own AuthStorage (see neo-daemon-mode.ts for the isolation
8
- * rationale). The supervisor owns the socket, the registry, and idle shutdown.
9
- */
10
- import type { Args } from "../args.ts";
11
- /** Exit code the launcher uses when it lost the bind race to another daemon. */
12
- export declare const NEO_DAEMON_ADDRESS_IN_USE_EXIT = 75;
13
- export interface NeoDaemonLauncherDeps {
14
- /** Injectable error sink; defaults to console.error. */
15
- readonly errorSink?: (message: string) => void;
16
- /** Override the child worker's CLI entry base args (dev/test). */
17
- readonly workerBaseArgs?: readonly string[];
18
- }
19
- /**
20
- * Run the neo daemon supervisor. Resolves to the process exit code once the
21
- * daemon has fully shut down (idle or signal), or {@link NEO_DAEMON_ADDRESS_IN_USE_EXIT}
22
- * when another daemon already owns the socket.
23
- */
24
- export declare function runNeoDaemonLauncher(parsed: Args, deps?: NeoDaemonLauncherDeps): Promise<number>;
25
- //# sourceMappingURL=daemon-launch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"daemon-launch.d.ts","sourceRoot":"","sources":["../../../src/cli/neo/daemon-launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,gFAAgF;AAChF,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACrC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyD1G"}
@@ -1,97 +0,0 @@
1
- /**
2
- * Launch the neo shared daemon from the classic CLI.
3
- *
4
- * Dispatched from main.ts when `--listen <path>` is present. This runs the
5
- * daemon SUPERVISOR: it does NOT construct an AgentSessionRuntime in this
6
- * process — each accepted connection gets its own child `senpi --mode rpc`
7
- * worker with its own AuthStorage (see neo-daemon-mode.ts for the isolation
8
- * rationale). The supervisor owns the socket, the registry, and idle shutdown.
9
- */
10
- import { randomBytes } from "node:crypto";
11
- import { join } from "node:path";
12
- import { getAgentDir, getPackageDir } from "../../config.js";
13
- import { SettingsManager } from "../../core/settings-manager.js";
14
- import { createNeoChildWorkerFactory } from "../../modes/rpc/neo-daemon-child-worker.js";
15
- import { NeoDaemonAddressInUseError, runNeoDaemon } from "../../modes/rpc/neo-daemon-mode.js";
16
- /** Exit code the launcher uses when it lost the bind race to another daemon. */
17
- export const NEO_DAEMON_ADDRESS_IN_USE_EXIT = 75;
18
- /**
19
- * Run the neo daemon supervisor. Resolves to the process exit code once the
20
- * daemon has fully shut down (idle or signal), or {@link NEO_DAEMON_ADDRESS_IN_USE_EXIT}
21
- * when another daemon already owns the socket.
22
- */
23
- export async function runNeoDaemonLauncher(parsed, deps = {}) {
24
- const errorSink = deps.errorSink ?? ((message) => console.error(message));
25
- const listenPath = parsed.neoListen;
26
- if (!listenPath) {
27
- errorSink("Error: --listen requires a socket path");
28
- return 1;
29
- }
30
- const cwd = process.cwd();
31
- const agentDir = getAgentDir();
32
- const settings = SettingsManager.create(cwd, agentDir, { projectTrusted: false });
33
- const idleShutdownMs = settings.getNeoDaemonIdleShutdownMs();
34
- // The daemon mints its own token and publishes it in the registry; the
35
- // spawning client reads it back to complete the handshake.
36
- const token = randomBytes(24).toString("hex");
37
- const workerBaseArgs = deps.workerBaseArgs ?? resolveWorkerBaseArgs();
38
- const workerFactory = createNeoChildWorkerFactory({ baseArgs: workerBaseArgs });
39
- let handle;
40
- try {
41
- handle = await runNeoDaemon({
42
- listenPath,
43
- cwd,
44
- agentDir,
45
- register: parsed.neoRegister === true,
46
- idleShutdownMs,
47
- token,
48
- workerFactory,
49
- });
50
- }
51
- catch (error) {
52
- if (error instanceof NeoDaemonAddressInUseError) {
53
- // Race lost: another daemon owns the socket. The client attaches to it.
54
- return NEO_DAEMON_ADDRESS_IN_USE_EXIT;
55
- }
56
- const message = error instanceof Error ? error.message : String(error);
57
- errorSink(`Error: failed to start neo daemon: ${message}`);
58
- return 1;
59
- }
60
- const shutdownOnSignal = () => {
61
- void handle.shutdown();
62
- };
63
- const signals = ["SIGTERM", "SIGINT"];
64
- if (process.platform !== "win32") {
65
- signals.push("SIGHUP");
66
- }
67
- for (const signal of signals) {
68
- process.on(signal, shutdownOnSignal);
69
- }
70
- await handle.closed;
71
- for (const signal of signals) {
72
- process.off(signal, shutdownOnSignal);
73
- }
74
- return 0;
75
- }
76
- /**
77
- * Resolve the base args used to spawn each connection's `senpi --mode rpc`
78
- * worker. `SENPI_NEO_WORKER_ARGS` (a JSON array of args following the node
79
- * executable, e.g. the tsx loader chain in dev) overrides the default built
80
- * `dist/rpc-entry.js` entry. This mirrors the `SENPI_NEO_BIN` dev override.
81
- */
82
- function resolveWorkerBaseArgs() {
83
- const override = process.env.SENPI_NEO_WORKER_ARGS;
84
- if (override) {
85
- try {
86
- const parsed = JSON.parse(override);
87
- if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
88
- return parsed;
89
- }
90
- }
91
- catch {
92
- // fall through to the default entry
93
- }
94
- }
95
- return [join(getPackageDir(), "dist", "rpc-entry.js")];
96
- }
97
- //# sourceMappingURL=daemon-launch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"daemon-launch.js","sourceRoot":"","sources":["../../../src/cli/neo/daemon-launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAwB,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGpH,gFAAgF;AAChF,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AASjD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAY,EAAE,IAAI,GAA0B,EAAE;IACxF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,SAAS,CAAC,wCAAwC,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAClF,MAAM,cAAc,GAAG,QAAQ,CAAC,0BAA0B,EAAE,CAAC;IAE7D,uEAAuE;IACvE,2DAA2D;IAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,qBAAqB,EAAE,CAAC;IACtE,MAAM,aAAa,GAAG,2BAA2B,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAEhF,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACJ,MAAM,GAAG,MAAM,YAAY,CAAC;YAC3B,UAAU;YACV,GAAG;YACH,QAAQ;YACR,QAAQ,EAAE,MAAM,CAAC,WAAW,KAAK,IAAI;YACrC,cAAc;YACd,KAAK;YACL,aAAa;SACb,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,0BAA0B,EAAE,CAAC;YACjD,wEAAwE;YACxE,OAAO,8BAA8B,CAAC;QACvC,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,SAAS,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,gBAAgB,GAAG,GAAS,EAAE;QACnC,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,OAAO,GAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,MAAM,CAAC,MAAM,CAAC;IACpB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACnD,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC/F,OAAO,MAAM,CAAC;YACf,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,oCAAoC;QACrC,CAAC;IACF,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;AACxD,CAAC","sourcesContent":["/**\n * Launch the neo shared daemon from the classic CLI.\n *\n * Dispatched from main.ts when `--listen <path>` is present. This runs the\n * daemon SUPERVISOR: it does NOT construct an AgentSessionRuntime in this\n * process — each accepted connection gets its own child `senpi --mode rpc`\n * worker with its own AuthStorage (see neo-daemon-mode.ts for the isolation\n * rationale). The supervisor owns the socket, the registry, and idle shutdown.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { getAgentDir, getPackageDir } from \"../../config.ts\";\nimport { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { createNeoChildWorkerFactory } from \"../../modes/rpc/neo-daemon-child-worker.ts\";\nimport { NeoDaemonAddressInUseError, type NeoDaemonHandle, runNeoDaemon } from \"../../modes/rpc/neo-daemon-mode.ts\";\nimport type { Args } from \"../args.ts\";\n\n/** Exit code the launcher uses when it lost the bind race to another daemon. */\nexport const NEO_DAEMON_ADDRESS_IN_USE_EXIT = 75;\n\nexport interface NeoDaemonLauncherDeps {\n\t/** Injectable error sink; defaults to console.error. */\n\treadonly errorSink?: (message: string) => void;\n\t/** Override the child worker's CLI entry base args (dev/test). */\n\treadonly workerBaseArgs?: readonly string[];\n}\n\n/**\n * Run the neo daemon supervisor. Resolves to the process exit code once the\n * daemon has fully shut down (idle or signal), or {@link NEO_DAEMON_ADDRESS_IN_USE_EXIT}\n * when another daemon already owns the socket.\n */\nexport async function runNeoDaemonLauncher(parsed: Args, deps: NeoDaemonLauncherDeps = {}): Promise<number> {\n\tconst errorSink = deps.errorSink ?? ((message: string) => console.error(message));\n\tconst listenPath = parsed.neoListen;\n\tif (!listenPath) {\n\t\terrorSink(\"Error: --listen requires a socket path\");\n\t\treturn 1;\n\t}\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settings = SettingsManager.create(cwd, agentDir, { projectTrusted: false });\n\tconst idleShutdownMs = settings.getNeoDaemonIdleShutdownMs();\n\n\t// The daemon mints its own token and publishes it in the registry; the\n\t// spawning client reads it back to complete the handshake.\n\tconst token = randomBytes(24).toString(\"hex\");\n\n\tconst workerBaseArgs = deps.workerBaseArgs ?? resolveWorkerBaseArgs();\n\tconst workerFactory = createNeoChildWorkerFactory({ baseArgs: workerBaseArgs });\n\n\tlet handle: NeoDaemonHandle;\n\ttry {\n\t\thandle = await runNeoDaemon({\n\t\t\tlistenPath,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tregister: parsed.neoRegister === true,\n\t\t\tidleShutdownMs,\n\t\t\ttoken,\n\t\t\tworkerFactory,\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof NeoDaemonAddressInUseError) {\n\t\t\t// Race lost: another daemon owns the socket. The client attaches to it.\n\t\t\treturn NEO_DAEMON_ADDRESS_IN_USE_EXIT;\n\t\t}\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\terrorSink(`Error: failed to start neo daemon: ${message}`);\n\t\treturn 1;\n\t}\n\n\tconst shutdownOnSignal = (): void => {\n\t\tvoid handle.shutdown();\n\t};\n\tconst signals: NodeJS.Signals[] = [\"SIGTERM\", \"SIGINT\"];\n\tif (process.platform !== \"win32\") {\n\t\tsignals.push(\"SIGHUP\");\n\t}\n\tfor (const signal of signals) {\n\t\tprocess.on(signal, shutdownOnSignal);\n\t}\n\n\tawait handle.closed;\n\tfor (const signal of signals) {\n\t\tprocess.off(signal, shutdownOnSignal);\n\t}\n\treturn 0;\n}\n\n/**\n * Resolve the base args used to spawn each connection's `senpi --mode rpc`\n * worker. `SENPI_NEO_WORKER_ARGS` (a JSON array of args following the node\n * executable, e.g. the tsx loader chain in dev) overrides the default built\n * `dist/rpc-entry.js` entry. This mirrors the `SENPI_NEO_BIN` dev override.\n */\nfunction resolveWorkerBaseArgs(): string[] {\n\tconst override = process.env.SENPI_NEO_WORKER_ARGS;\n\tif (override) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(override);\n\t\t\tif (Array.isArray(parsed) && parsed.every((item): item is string => typeof item === \"string\")) {\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t} catch {\n\t\t\t// fall through to the default entry\n\t\t}\n\t}\n\treturn [join(getPackageDir(), \"dist\", \"rpc-entry.js\")];\n}\n"]}
@@ -1,15 +0,0 @@
1
- /**
2
- * Feature gate for the neo (Go-native) TUI.
3
- *
4
- * The neo TUI ships as a separate Go binary distributed via per-platform npm
5
- * packages (`@code-yeongyu/senpi-neo-tui-<platform>-<arch>`). Those packages are
6
- * NOT built or published yet, so on a released senpi the `--neo` handoff can only
7
- * fail at binary resolution. Until the binary ships, neo stays behind an opt-in
8
- * env gate: OFF by default, so `--neo` and its sibling flags are absent from help
9
- * and parse as unknown flags (never dispatched), exactly as if the feature did not
10
- * exist. Set `SENPI_ENABLE_NEO=1` (or `true`/`yes`) to develop against it.
11
- */
12
- export declare const ENV_ENABLE_NEO = "SENPI_ENABLE_NEO";
13
- /** Whether the neo (Go TUI) flags and handoff are exposed for this process. */
14
- export declare function isNeoEnabled(env?: NodeJS.ProcessEnv): boolean;
15
- //# sourceMappingURL=gate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../../src/cli/neo/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK1E"}
@@ -1,21 +0,0 @@
1
- /**
2
- * Feature gate for the neo (Go-native) TUI.
3
- *
4
- * The neo TUI ships as a separate Go binary distributed via per-platform npm
5
- * packages (`@code-yeongyu/senpi-neo-tui-<platform>-<arch>`). Those packages are
6
- * NOT built or published yet, so on a released senpi the `--neo` handoff can only
7
- * fail at binary resolution. Until the binary ships, neo stays behind an opt-in
8
- * env gate: OFF by default, so `--neo` and its sibling flags are absent from help
9
- * and parse as unknown flags (never dispatched), exactly as if the feature did not
10
- * exist. Set `SENPI_ENABLE_NEO=1` (or `true`/`yes`) to develop against it.
11
- */
12
- export const ENV_ENABLE_NEO = "SENPI_ENABLE_NEO";
13
- /** Whether the neo (Go TUI) flags and handoff are exposed for this process. */
14
- export function isNeoEnabled(env = process.env) {
15
- const value = env[ENV_ENABLE_NEO];
16
- if (value === undefined)
17
- return false;
18
- const normalized = value.trim().toLowerCase();
19
- return normalized === "1" || normalized === "true" || normalized === "yes";
20
- }
21
- //# sourceMappingURL=gate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/cli/neo/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IAChE,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;IAClC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,CAAC;AAC5E,CAAC","sourcesContent":["/**\n * Feature gate for the neo (Go-native) TUI.\n *\n * The neo TUI ships as a separate Go binary distributed via per-platform npm\n * packages (`@code-yeongyu/senpi-neo-tui-<platform>-<arch>`). Those packages are\n * NOT built or published yet, so on a released senpi the `--neo` handoff can only\n * fail at binary resolution. Until the binary ships, neo stays behind an opt-in\n * env gate: OFF by default, so `--neo` and its sibling flags are absent from help\n * and parse as unknown flags (never dispatched), exactly as if the feature did not\n * exist. Set `SENPI_ENABLE_NEO=1` (or `true`/`yes`) to develop against it.\n */\nexport const ENV_ENABLE_NEO = \"SENPI_ENABLE_NEO\";\n\n/** Whether the neo (Go TUI) flags and handoff are exposed for this process. */\nexport function isNeoEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n\tconst value = env[ENV_ENABLE_NEO];\n\tif (value === undefined) return false;\n\tconst normalized = value.trim().toLowerCase();\n\treturn normalized === \"1\" || normalized === \"true\" || normalized === \"yes\";\n}\n"]}