openhorse 0.1.5

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 (587) hide show
  1. package/README.md +460 -0
  2. package/bin/openhorse +56 -0
  3. package/dist/agents/coder.d.ts +12 -0
  4. package/dist/agents/coder.d.ts.map +1 -0
  5. package/dist/agents/coder.js +48 -0
  6. package/dist/agents/coder.js.map +1 -0
  7. package/dist/agents/leader.d.ts +12 -0
  8. package/dist/agents/leader.d.ts.map +1 -0
  9. package/dist/agents/leader.js +49 -0
  10. package/dist/agents/leader.js.map +1 -0
  11. package/dist/agents/router.d.ts +59 -0
  12. package/dist/agents/router.d.ts.map +1 -0
  13. package/dist/agents/router.js +193 -0
  14. package/dist/agents/router.js.map +1 -0
  15. package/dist/cli-ink.d.ts +7 -0
  16. package/dist/cli-ink.d.ts.map +1 -0
  17. package/dist/cli-ink.js +135 -0
  18. package/dist/cli-ink.js.map +1 -0
  19. package/dist/cli.d.ts +7 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +638 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands/index.d.ts +12 -0
  24. package/dist/commands/index.d.ts.map +1 -0
  25. package/dist/commands/index.js +1095 -0
  26. package/dist/commands/index.js.map +1 -0
  27. package/dist/commands/parser.d.ts +26 -0
  28. package/dist/commands/parser.d.ts.map +1 -0
  29. package/dist/commands/parser.js +61 -0
  30. package/dist/commands/parser.js.map +1 -0
  31. package/dist/commands/types.d.ts +61 -0
  32. package/dist/commands/types.d.ts.map +1 -0
  33. package/dist/commands/types.js +32 -0
  34. package/dist/commands/types.js.map +1 -0
  35. package/dist/core/agent.d.ts +66 -0
  36. package/dist/core/agent.d.ts.map +1 -0
  37. package/dist/core/agent.js +55 -0
  38. package/dist/core/agent.js.map +1 -0
  39. package/dist/core/brain.d.ts +41 -0
  40. package/dist/core/brain.d.ts.map +1 -0
  41. package/dist/core/brain.js +92 -0
  42. package/dist/core/brain.js.map +1 -0
  43. package/dist/core/cost-tracker.d.ts +107 -0
  44. package/dist/core/cost-tracker.d.ts.map +1 -0
  45. package/dist/core/cost-tracker.js +199 -0
  46. package/dist/core/cost-tracker.js.map +1 -0
  47. package/dist/core/strategy-tracker.d.ts +61 -0
  48. package/dist/core/strategy-tracker.d.ts.map +1 -0
  49. package/dist/core/strategy-tracker.js +124 -0
  50. package/dist/core/strategy-tracker.js.map +1 -0
  51. package/dist/framework/index.d.ts +20 -0
  52. package/dist/framework/index.d.ts.map +1 -0
  53. package/dist/framework/index.js +29 -0
  54. package/dist/framework/index.js.map +1 -0
  55. package/dist/framework/prompt.d.ts +40 -0
  56. package/dist/framework/prompt.d.ts.map +1 -0
  57. package/dist/framework/prompt.js +112 -0
  58. package/dist/framework/prompt.js.map +1 -0
  59. package/dist/framework/query.d.ts +86 -0
  60. package/dist/framework/query.d.ts.map +1 -0
  61. package/dist/framework/query.js +177 -0
  62. package/dist/framework/query.js.map +1 -0
  63. package/dist/framework/store.d.ts +64 -0
  64. package/dist/framework/store.d.ts.map +1 -0
  65. package/dist/framework/store.js +78 -0
  66. package/dist/framework/store.js.map +1 -0
  67. package/dist/framework/tool-state.d.ts +22 -0
  68. package/dist/framework/tool-state.d.ts.map +1 -0
  69. package/dist/framework/tool-state.js +40 -0
  70. package/dist/framework/tool-state.js.map +1 -0
  71. package/dist/framework/tool.d.ts +88 -0
  72. package/dist/framework/tool.d.ts.map +1 -0
  73. package/dist/framework/tool.js +60 -0
  74. package/dist/framework/tool.js.map +1 -0
  75. package/dist/harness/harness.d.ts +96 -0
  76. package/dist/harness/harness.d.ts.map +1 -0
  77. package/dist/harness/harness.js +224 -0
  78. package/dist/harness/harness.js.map +1 -0
  79. package/dist/harness/safety.d.ts +89 -0
  80. package/dist/harness/safety.d.ts.map +1 -0
  81. package/dist/harness/safety.js +178 -0
  82. package/dist/harness/safety.js.map +1 -0
  83. package/dist/index.d.ts +30 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +57 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/init.d.ts +178 -0
  88. package/dist/init.d.ts.map +1 -0
  89. package/dist/init.js +473 -0
  90. package/dist/init.js.map +1 -0
  91. package/dist/ink/bidi.d.ts +16 -0
  92. package/dist/ink/bidi.d.ts.map +1 -0
  93. package/dist/ink/bidi.js +124 -0
  94. package/dist/ink/bidi.js.map +1 -0
  95. package/dist/ink/clearTerminal.d.ts +14 -0
  96. package/dist/ink/clearTerminal.d.ts.map +1 -0
  97. package/dist/ink/clearTerminal.js +63 -0
  98. package/dist/ink/clearTerminal.js.map +1 -0
  99. package/dist/ink/colorize.d.ts +17 -0
  100. package/dist/ink/colorize.d.ts.map +1 -0
  101. package/dist/ink/colorize.js +208 -0
  102. package/dist/ink/colorize.js.map +1 -0
  103. package/dist/ink/components/App.d.ts +73 -0
  104. package/dist/ink/components/App.d.ts.map +1 -0
  105. package/dist/ink/components/App.js +646 -0
  106. package/dist/ink/components/App.js.map +1 -0
  107. package/dist/ink/components/AppContext.d.ts +12 -0
  108. package/dist/ink/components/AppContext.d.ts.map +1 -0
  109. package/dist/ink/components/AppContext.js +14 -0
  110. package/dist/ink/components/AppContext.js.map +1 -0
  111. package/dist/ink/components/Box.d.ts +44 -0
  112. package/dist/ink/components/Box.d.ts.map +1 -0
  113. package/dist/ink/components/Box.js +191 -0
  114. package/dist/ink/components/Box.js.map +1 -0
  115. package/dist/ink/components/ClockContext.d.ts +9 -0
  116. package/dist/ink/components/ClockContext.d.ts.map +1 -0
  117. package/dist/ink/components/ClockContext.js +146 -0
  118. package/dist/ink/components/ClockContext.js.map +1 -0
  119. package/dist/ink/components/CursorDeclarationContext.d.ts +23 -0
  120. package/dist/ink/components/CursorDeclarationContext.d.ts.map +1 -0
  121. package/dist/ink/components/CursorDeclarationContext.js +6 -0
  122. package/dist/ink/components/CursorDeclarationContext.js.map +1 -0
  123. package/dist/ink/components/ErrorOverview.d.ts +6 -0
  124. package/dist/ink/components/ErrorOverview.d.ts.map +1 -0
  125. package/dist/ink/components/ErrorOverview.js +27 -0
  126. package/dist/ink/components/ErrorOverview.js.map +1 -0
  127. package/dist/ink/components/Newline.d.ts +13 -0
  128. package/dist/ink/components/Newline.d.ts.map +1 -0
  129. package/dist/ink/components/Newline.js +36 -0
  130. package/dist/ink/components/Newline.js.map +1 -0
  131. package/dist/ink/components/NoSelect.d.ts +20 -0
  132. package/dist/ink/components/NoSelect.d.ts.map +1 -0
  133. package/dist/ink/components/NoSelect.js +63 -0
  134. package/dist/ink/components/NoSelect.js.map +1 -0
  135. package/dist/ink/components/RawAnsi.d.ts +17 -0
  136. package/dist/ink/components/RawAnsi.d.ts.map +1 -0
  137. package/dist/ink/components/RawAnsi.js +52 -0
  138. package/dist/ink/components/RawAnsi.js.map +1 -0
  139. package/dist/ink/components/Spacer.d.ts +6 -0
  140. package/dist/ink/components/Spacer.d.ts.map +1 -0
  141. package/dist/ink/components/Spacer.js +26 -0
  142. package/dist/ink/components/Spacer.js.map +1 -0
  143. package/dist/ink/components/StdinContext.d.ts +28 -0
  144. package/dist/ink/components/StdinContext.d.ts.map +1 -0
  145. package/dist/ink/components/StdinContext.js +19 -0
  146. package/dist/ink/components/StdinContext.js.map +1 -0
  147. package/dist/ink/components/TerminalFocusContext.d.ts +10 -0
  148. package/dist/ink/components/TerminalFocusContext.d.ts.map +1 -0
  149. package/dist/ink/components/TerminalFocusContext.js +81 -0
  150. package/dist/ink/components/TerminalFocusContext.js.map +1 -0
  151. package/dist/ink/components/TerminalSizeContext.d.ts +6 -0
  152. package/dist/ink/components/TerminalSizeContext.d.ts.map +1 -0
  153. package/dist/ink/components/TerminalSizeContext.js +6 -0
  154. package/dist/ink/components/TerminalSizeContext.js.map +1 -0
  155. package/dist/ink/components/Text.d.ts +56 -0
  156. package/dist/ink/components/Text.d.ts.map +1 -0
  157. package/dist/ink/components/Text.js +201 -0
  158. package/dist/ink/components/Text.js.map +1 -0
  159. package/dist/ink/constants.d.ts +2 -0
  160. package/dist/ink/constants.d.ts.map +1 -0
  161. package/dist/ink/constants.js +6 -0
  162. package/dist/ink/constants.js.map +1 -0
  163. package/dist/ink/devtools.d.ts +3 -0
  164. package/dist/ink/devtools.d.ts.map +1 -0
  165. package/dist/ink/devtools.js +5 -0
  166. package/dist/ink/devtools.js.map +1 -0
  167. package/dist/ink/dom.d.ts +77 -0
  168. package/dist/ink/dom.d.ts.map +1 -0
  169. package/dist/ink/dom.js +322 -0
  170. package/dist/ink/dom.js.map +1 -0
  171. package/dist/ink/events/click-event.d.ts +32 -0
  172. package/dist/ink/events/click-event.d.ts.map +1 -0
  173. package/dist/ink/events/click-event.js +30 -0
  174. package/dist/ink/events/click-event.js.map +1 -0
  175. package/dist/ink/events/dispatcher.d.ts +41 -0
  176. package/dist/ink/events/dispatcher.d.ts.map +1 -0
  177. package/dist/ink/events/dispatcher.js +181 -0
  178. package/dist/ink/events/dispatcher.js.map +1 -0
  179. package/dist/ink/events/emitter.d.ts +6 -0
  180. package/dist/ink/events/emitter.d.ts.map +1 -0
  181. package/dist/ink/events/emitter.js +36 -0
  182. package/dist/ink/events/emitter.js.map +1 -0
  183. package/dist/ink/events/event-handlers.d.ts +47 -0
  184. package/dist/ink/events/event-handlers.d.ts.map +1 -0
  185. package/dist/ink/events/event-handlers.js +34 -0
  186. package/dist/ink/events/event-handlers.js.map +1 -0
  187. package/dist/ink/events/event.d.ts +6 -0
  188. package/dist/ink/events/event.d.ts.map +1 -0
  189. package/dist/ink/events/event.js +16 -0
  190. package/dist/ink/events/event.js.map +1 -0
  191. package/dist/ink/events/focus-event.d.ts +14 -0
  192. package/dist/ink/events/focus-event.d.ts.map +1 -0
  193. package/dist/ink/events/focus-event.js +20 -0
  194. package/dist/ink/events/focus-event.js.map +1 -0
  195. package/dist/ink/events/input-event.d.ts +31 -0
  196. package/dist/ink/events/input-event.d.ts.map +1 -0
  197. package/dist/ink/events/input-event.js +163 -0
  198. package/dist/ink/events/input-event.js.map +1 -0
  199. package/dist/ink/events/keyboard-event.d.ts +20 -0
  200. package/dist/ink/events/keyboard-event.d.ts.map +1 -0
  201. package/dist/ink/events/keyboard-event.js +44 -0
  202. package/dist/ink/events/keyboard-event.js.map +1 -0
  203. package/dist/ink/events/terminal-event.d.ts +55 -0
  204. package/dist/ink/events/terminal-event.d.ts.map +1 -0
  205. package/dist/ink/events/terminal-event.js +79 -0
  206. package/dist/ink/events/terminal-event.js.map +1 -0
  207. package/dist/ink/events/terminal-focus-event.d.ts +14 -0
  208. package/dist/ink/events/terminal-focus-event.d.ts.map +1 -0
  209. package/dist/ink/events/terminal-focus-event.js +19 -0
  210. package/dist/ink/events/terminal-focus-event.js.map +1 -0
  211. package/dist/ink/focus.d.ts +44 -0
  212. package/dist/ink/focus.d.ts.map +1 -0
  213. package/dist/ink/focus.js +164 -0
  214. package/dist/ink/focus.js.map +1 -0
  215. package/dist/ink/frame.d.ts +95 -0
  216. package/dist/ink/frame.d.ts.map +1 -0
  217. package/dist/ink/frame.js +35 -0
  218. package/dist/ink/frame.js.map +1 -0
  219. package/dist/ink/get-max-width.d.ts +18 -0
  220. package/dist/ink/get-max-width.d.ts.map +1 -0
  221. package/dist/ink/get-max-width.js +26 -0
  222. package/dist/ink/get-max-width.js.map +1 -0
  223. package/dist/ink/hit-test.d.ts +34 -0
  224. package/dist/ink/hit-test.d.ts.map +1 -0
  225. package/dist/ink/hit-test.js +119 -0
  226. package/dist/ink/hit-test.js.map +1 -0
  227. package/dist/ink/hooks/use-animation-frame.d.ts +27 -0
  228. package/dist/ink/hooks/use-animation-frame.d.ts.map +1 -0
  229. package/dist/ink/hooks/use-animation-frame.js +52 -0
  230. package/dist/ink/hooks/use-animation-frame.js.map +1 -0
  231. package/dist/ink/hooks/use-app.d.ts +6 -0
  232. package/dist/ink/hooks/use-app.d.ts.map +1 -0
  233. package/dist/ink/hooks/use-app.js +13 -0
  234. package/dist/ink/hooks/use-app.js.map +1 -0
  235. package/dist/ink/hooks/use-declared-cursor.d.ts +27 -0
  236. package/dist/ink/hooks/use-declared-cursor.d.ts.map +1 -0
  237. package/dist/ink/hooks/use-declared-cursor.js +67 -0
  238. package/dist/ink/hooks/use-declared-cursor.js.map +1 -0
  239. package/dist/ink/hooks/use-input.d.ts +38 -0
  240. package/dist/ink/hooks/use-input.d.ts.map +1 -0
  241. package/dist/ink/hooks/use-input.js +86 -0
  242. package/dist/ink/hooks/use-input.js.map +1 -0
  243. package/dist/ink/hooks/use-interval.d.ts +19 -0
  244. package/dist/ink/hooks/use-interval.d.ts.map +1 -0
  245. package/dist/ink/hooks/use-interval.js +59 -0
  246. package/dist/ink/hooks/use-interval.js.map +1 -0
  247. package/dist/ink/hooks/use-search-highlight.d.ts +31 -0
  248. package/dist/ink/hooks/use-search-highlight.d.ts.map +1 -0
  249. package/dist/ink/hooks/use-search-highlight.js +39 -0
  250. package/dist/ink/hooks/use-search-highlight.js.map +1 -0
  251. package/dist/ink/hooks/use-selection.d.ts +40 -0
  252. package/dist/ink/hooks/use-selection.d.ts.map +1 -0
  253. package/dist/ink/hooks/use-selection.js +68 -0
  254. package/dist/ink/hooks/use-selection.js.map +1 -0
  255. package/dist/ink/hooks/use-stdin.d.ts +6 -0
  256. package/dist/ink/hooks/use-stdin.d.ts.map +1 -0
  257. package/dist/ink/hooks/use-stdin.js +13 -0
  258. package/dist/ink/hooks/use-stdin.js.map +1 -0
  259. package/dist/ink/hooks/use-tab-status.d.ts +14 -0
  260. package/dist/ink/hooks/use-tab-status.d.ts.map +1 -0
  261. package/dist/ink/hooks/use-tab-status.js +61 -0
  262. package/dist/ink/hooks/use-tab-status.js.map +1 -0
  263. package/dist/ink/hooks/use-terminal-focus.d.ts +11 -0
  264. package/dist/ink/hooks/use-terminal-focus.d.ts.map +1 -0
  265. package/dist/ink/hooks/use-terminal-focus.js +22 -0
  266. package/dist/ink/hooks/use-terminal-focus.js.map +1 -0
  267. package/dist/ink/hooks/use-terminal-title.d.ts +13 -0
  268. package/dist/ink/hooks/use-terminal-title.d.ts.map +1 -0
  269. package/dist/ink/hooks/use-terminal-title.js +36 -0
  270. package/dist/ink/hooks/use-terminal-title.js.map +1 -0
  271. package/dist/ink/hooks/use-terminal-viewport.d.ts +30 -0
  272. package/dist/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
  273. package/dist/ink/hooks/use-terminal-viewport.js +81 -0
  274. package/dist/ink/hooks/use-terminal-viewport.js.map +1 -0
  275. package/dist/ink/index.d.ts +54 -0
  276. package/dist/ink/index.d.ts.map +1 -0
  277. package/dist/ink/index.js +111 -0
  278. package/dist/ink/index.js.map +1 -0
  279. package/dist/ink/ink.d.ts +371 -0
  280. package/dist/ink/ink.d.ts.map +1 -0
  281. package/dist/ink/ink.js +1686 -0
  282. package/dist/ink/ink.js.map +1 -0
  283. package/dist/ink/instances.d.ts +4 -0
  284. package/dist/ink/instances.d.ts.map +1 -0
  285. package/dist/ink/instances.js +10 -0
  286. package/dist/ink/instances.js.map +1 -0
  287. package/dist/ink/line-width-cache.d.ts +2 -0
  288. package/dist/ink/line-width-cache.d.ts.map +1 -0
  289. package/dist/ink/line-width-cache.js +23 -0
  290. package/dist/ink/line-width-cache.js.map +1 -0
  291. package/dist/ink/log-update.d.ts +18 -0
  292. package/dist/ink/log-update.d.ts.map +1 -0
  293. package/dist/ink/log-update.js +637 -0
  294. package/dist/ink/log-update.js.map +1 -0
  295. package/dist/ink/measure-element.d.ts +17 -0
  296. package/dist/ink/measure-element.d.ts.map +1 -0
  297. package/dist/ink/measure-element.js +11 -0
  298. package/dist/ink/measure-element.js.map +1 -0
  299. package/dist/ink/measure-text.d.ts +7 -0
  300. package/dist/ink/measure-text.d.ts.map +1 -0
  301. package/dist/ink/measure-text.js +38 -0
  302. package/dist/ink/measure-text.js.map +1 -0
  303. package/dist/ink/node-cache.d.ts +21 -0
  304. package/dist/ink/node-cache.d.ts.map +1 -0
  305. package/dist/ink/node-cache.js +36 -0
  306. package/dist/ink/node-cache.js.map +1 -0
  307. package/dist/ink/optimizer.d.ts +16 -0
  308. package/dist/ink/optimizer.d.ts.map +1 -0
  309. package/dist/ink/optimizer.js +85 -0
  310. package/dist/ink/optimizer.js.map +1 -0
  311. package/dist/ink/output.d.ts +120 -0
  312. package/dist/ink/output.d.ts.map +1 -0
  313. package/dist/ink/output.js +559 -0
  314. package/dist/ink/output.js.map +1 -0
  315. package/dist/ink/parse-keypress.d.ts +112 -0
  316. package/dist/ink/parse-keypress.d.ts.map +1 -0
  317. package/dist/ink/parse-keypress.js +719 -0
  318. package/dist/ink/parse-keypress.js.map +1 -0
  319. package/dist/ink/parse-keypress.test.d.ts +2 -0
  320. package/dist/ink/parse-keypress.test.d.ts.map +1 -0
  321. package/dist/ink/parse-keypress.test.js +37 -0
  322. package/dist/ink/parse-keypress.test.js.map +1 -0
  323. package/dist/ink/reconciler.d.ts +12 -0
  324. package/dist/ink/reconciler.d.ts.map +1 -0
  325. package/dist/ink/reconciler.js +456 -0
  326. package/dist/ink/reconciler.js.map +1 -0
  327. package/dist/ink/render-border.d.ts +25 -0
  328. package/dist/ink/render-border.d.ts.map +1 -0
  329. package/dist/ink/render-border.js +141 -0
  330. package/dist/ink/render-border.js.map +1 -0
  331. package/dist/ink/render-node-to-output.d.ts +46 -0
  332. package/dist/ink/render-node-to-output.d.ts.map +1 -0
  333. package/dist/ink/render-node-to-output.js +1257 -0
  334. package/dist/ink/render-node-to-output.js.map +1 -0
  335. package/dist/ink/render-to-screen.d.ts +47 -0
  336. package/dist/ink/render-to-screen.d.ts.map +1 -0
  337. package/dist/ink/render-to-screen.js +213 -0
  338. package/dist/ink/render-to-screen.js.map +1 -0
  339. package/dist/ink/renderer.d.ts +15 -0
  340. package/dist/ink/renderer.d.ts.map +1 -0
  341. package/dist/ink/renderer.js +169 -0
  342. package/dist/ink/renderer.js.map +1 -0
  343. package/dist/ink/root.d.ts +75 -0
  344. package/dist/ink/root.d.ts.map +1 -0
  345. package/dist/ink/root.js +89 -0
  346. package/dist/ink/root.js.map +1 -0
  347. package/dist/ink/screen.d.ts +270 -0
  348. package/dist/ink/screen.d.ts.map +1 -0
  349. package/dist/ink/screen.js +1194 -0
  350. package/dist/ink/screen.js.map +1 -0
  351. package/dist/ink/searchHighlight.d.ts +21 -0
  352. package/dist/ink/searchHighlight.d.ts.map +1 -0
  353. package/dist/ink/searchHighlight.js +82 -0
  354. package/dist/ink/searchHighlight.js.map +1 -0
  355. package/dist/ink/selection.d.ts +230 -0
  356. package/dist/ink/selection.d.ts.map +1 -0
  357. package/dist/ink/selection.js +814 -0
  358. package/dist/ink/selection.js.map +1 -0
  359. package/dist/ink/squash-text-nodes.d.ts +23 -0
  360. package/dist/ink/squash-text-nodes.d.ts.map +1 -0
  361. package/dist/ink/squash-text-nodes.js +60 -0
  362. package/dist/ink/squash-text-nodes.js.map +1 -0
  363. package/dist/ink/stringWidth.d.ts +2 -0
  364. package/dist/ink/stringWidth.d.ts.map +1 -0
  365. package/dist/ink/stringWidth.js +207 -0
  366. package/dist/ink/stringWidth.js.map +1 -0
  367. package/dist/ink/styles.d.ts +307 -0
  368. package/dist/ink/styles.d.ts.map +1 -0
  369. package/dist/ink/styles.js +302 -0
  370. package/dist/ink/styles.js.map +1 -0
  371. package/dist/ink/supports-hyperlinks.d.ts +14 -0
  372. package/dist/ink/supports-hyperlinks.d.ts.map +1 -0
  373. package/dist/ink/supports-hyperlinks.js +48 -0
  374. package/dist/ink/supports-hyperlinks.js.map +1 -0
  375. package/dist/ink/tabstops.d.ts +2 -0
  376. package/dist/ink/tabstops.d.ts.map +1 -0
  377. package/dist/ink/tabstops.js +43 -0
  378. package/dist/ink/tabstops.js.map +1 -0
  379. package/dist/ink/terminal-focus-state.d.ts +7 -0
  380. package/dist/ink/terminal-focus-state.d.ts.map +1 -0
  381. package/dist/ink/terminal-focus-state.js +43 -0
  382. package/dist/ink/terminal-focus-state.js.map +1 -0
  383. package/dist/ink/terminal-querier.d.ts +130 -0
  384. package/dist/ink/terminal-querier.d.ts.map +1 -0
  385. package/dist/ink/terminal-querier.js +184 -0
  386. package/dist/ink/terminal-querier.js.map +1 -0
  387. package/dist/ink/terminal.d.ts +56 -0
  388. package/dist/ink/terminal.d.ts.map +1 -0
  389. package/dist/ink/terminal.js +249 -0
  390. package/dist/ink/terminal.js.map +1 -0
  391. package/dist/ink/termio/csi.d.ts +166 -0
  392. package/dist/ink/termio/csi.d.ts.map +1 -0
  393. package/dist/ink/termio/csi.js +285 -0
  394. package/dist/ink/termio/csi.js.map +1 -0
  395. package/dist/ink/termio/dec.d.ts +38 -0
  396. package/dist/ink/termio/dec.d.ts.map +1 -0
  397. package/dist/ink/termio/dec.js +59 -0
  398. package/dist/ink/termio/dec.js.map +1 -0
  399. package/dist/ink/termio.d.ts +25 -0
  400. package/dist/ink/termio.d.ts.map +1 -0
  401. package/dist/ink/termio.js +32 -0
  402. package/dist/ink/termio.js.map +1 -0
  403. package/dist/ink/useTerminalNotification.d.ts +27 -0
  404. package/dist/ink/useTerminalNotification.d.ts.map +1 -0
  405. package/dist/ink/useTerminalNotification.js +62 -0
  406. package/dist/ink/useTerminalNotification.js.map +1 -0
  407. package/dist/ink/warn.d.ts +2 -0
  408. package/dist/ink/warn.d.ts.map +1 -0
  409. package/dist/ink/warn.js +14 -0
  410. package/dist/ink/warn.js.map +1 -0
  411. package/dist/ink/widest-line.d.ts +2 -0
  412. package/dist/ink/widest-line.d.ts.map +1 -0
  413. package/dist/ink/widest-line.js +18 -0
  414. package/dist/ink/widest-line.js.map +1 -0
  415. package/dist/ink/wrap-text.d.ts +3 -0
  416. package/dist/ink/wrap-text.d.ts.map +1 -0
  417. package/dist/ink/wrap-text.js +61 -0
  418. package/dist/ink/wrap-text.js.map +1 -0
  419. package/dist/ink/wrapAnsi.d.ts +8 -0
  420. package/dist/ink/wrapAnsi.d.ts.map +1 -0
  421. package/dist/ink/wrapAnsi.js +13 -0
  422. package/dist/ink/wrapAnsi.js.map +1 -0
  423. package/dist/memory/embeddings.d.ts +33 -0
  424. package/dist/memory/embeddings.d.ts.map +1 -0
  425. package/dist/memory/embeddings.js +123 -0
  426. package/dist/memory/embeddings.js.map +1 -0
  427. package/dist/memory/index.d.ts +14 -0
  428. package/dist/memory/index.d.ts.map +1 -0
  429. package/dist/memory/index.js +31 -0
  430. package/dist/memory/index.js.map +1 -0
  431. package/dist/memory/prompts.d.ts +12 -0
  432. package/dist/memory/prompts.d.ts.map +1 -0
  433. package/dist/memory/prompts.js +117 -0
  434. package/dist/memory/prompts.js.map +1 -0
  435. package/dist/memory/semantic-search.d.ts +45 -0
  436. package/dist/memory/semantic-search.d.ts.map +1 -0
  437. package/dist/memory/semantic-search.js +112 -0
  438. package/dist/memory/semantic-search.js.map +1 -0
  439. package/dist/memory/storage.d.ts +79 -0
  440. package/dist/memory/storage.d.ts.map +1 -0
  441. package/dist/memory/storage.js +285 -0
  442. package/dist/memory/storage.js.map +1 -0
  443. package/dist/memory/store.d.ts +103 -0
  444. package/dist/memory/store.d.ts.map +1 -0
  445. package/dist/memory/store.js +226 -0
  446. package/dist/memory/store.js.map +1 -0
  447. package/dist/memory/types.d.ts +40 -0
  448. package/dist/memory/types.d.ts.map +1 -0
  449. package/dist/memory/types.js +71 -0
  450. package/dist/memory/types.js.map +1 -0
  451. package/dist/memory/validation.d.ts +28 -0
  452. package/dist/memory/validation.d.ts.map +1 -0
  453. package/dist/memory/validation.js +147 -0
  454. package/dist/memory/validation.js.map +1 -0
  455. package/dist/memory/vector-store.d.ts +49 -0
  456. package/dist/memory/vector-store.d.ts.map +1 -0
  457. package/dist/memory/vector-store.js +259 -0
  458. package/dist/memory/vector-store.js.map +1 -0
  459. package/dist/screens/REPL.d.ts +21 -0
  460. package/dist/screens/REPL.d.ts.map +1 -0
  461. package/dist/screens/REPL.js +139 -0
  462. package/dist/screens/REPL.js.map +1 -0
  463. package/dist/services/agent-runner.d.ts +68 -0
  464. package/dist/services/agent-runner.d.ts.map +1 -0
  465. package/dist/services/agent-runner.js +186 -0
  466. package/dist/services/agent-runner.js.map +1 -0
  467. package/dist/services/atomic-write.d.ts +12 -0
  468. package/dist/services/atomic-write.d.ts.map +1 -0
  469. package/dist/services/atomic-write.js +27 -0
  470. package/dist/services/atomic-write.js.map +1 -0
  471. package/dist/services/config-dir.d.ts +55 -0
  472. package/dist/services/config-dir.d.ts.map +1 -0
  473. package/dist/services/config-dir.js +136 -0
  474. package/dist/services/config-dir.js.map +1 -0
  475. package/dist/services/config.d.ts +54 -0
  476. package/dist/services/config.d.ts.map +1 -0
  477. package/dist/services/config.js +98 -0
  478. package/dist/services/config.js.map +1 -0
  479. package/dist/services/file-glob.d.ts +26 -0
  480. package/dist/services/file-glob.d.ts.map +1 -0
  481. package/dist/services/file-glob.js +134 -0
  482. package/dist/services/file-glob.js.map +1 -0
  483. package/dist/services/global-config.d.ts +109 -0
  484. package/dist/services/global-config.d.ts.map +1 -0
  485. package/dist/services/global-config.js +211 -0
  486. package/dist/services/global-config.js.map +1 -0
  487. package/dist/services/llm.d.ts +139 -0
  488. package/dist/services/llm.d.ts.map +1 -0
  489. package/dist/services/llm.js +376 -0
  490. package/dist/services/llm.js.map +1 -0
  491. package/dist/services/memory.d.ts +39 -0
  492. package/dist/services/memory.d.ts.map +1 -0
  493. package/dist/services/memory.js +88 -0
  494. package/dist/services/memory.js.map +1 -0
  495. package/dist/services/session-storage.d.ts +136 -0
  496. package/dist/services/session-storage.d.ts.map +1 -0
  497. package/dist/services/session-storage.js +304 -0
  498. package/dist/services/session-storage.js.map +1 -0
  499. package/dist/services/task-manager.d.ts +154 -0
  500. package/dist/services/task-manager.d.ts.map +1 -0
  501. package/dist/services/task-manager.js +288 -0
  502. package/dist/services/task-manager.js.map +1 -0
  503. package/dist/services/yaml-config.d.ts +57 -0
  504. package/dist/services/yaml-config.d.ts.map +1 -0
  505. package/dist/services/yaml-config.js +176 -0
  506. package/dist/services/yaml-config.js.map +1 -0
  507. package/dist/skills/discovery.d.ts +22 -0
  508. package/dist/skills/discovery.d.ts.map +1 -0
  509. package/dist/skills/discovery.js +75 -0
  510. package/dist/skills/discovery.js.map +1 -0
  511. package/dist/skills/index.d.ts +10 -0
  512. package/dist/skills/index.d.ts.map +1 -0
  513. package/dist/skills/index.js +26 -0
  514. package/dist/skills/index.js.map +1 -0
  515. package/dist/skills/loader.d.ts +48 -0
  516. package/dist/skills/loader.d.ts.map +1 -0
  517. package/dist/skills/loader.js +231 -0
  518. package/dist/skills/loader.js.map +1 -0
  519. package/dist/skills/registry.d.ts +37 -0
  520. package/dist/skills/registry.d.ts.map +1 -0
  521. package/dist/skills/registry.js +134 -0
  522. package/dist/skills/registry.js.map +1 -0
  523. package/dist/skills/types.d.ts +89 -0
  524. package/dist/skills/types.d.ts.map +1 -0
  525. package/dist/skills/types.js +24 -0
  526. package/dist/skills/types.js.map +1 -0
  527. package/dist/tools/bash_security.d.ts +64 -0
  528. package/dist/tools/bash_security.d.ts.map +1 -0
  529. package/dist/tools/bash_security.js +291 -0
  530. package/dist/tools/bash_security.js.map +1 -0
  531. package/dist/tools/index.d.ts +23 -0
  532. package/dist/tools/index.d.ts.map +1 -0
  533. package/dist/tools/index.js +965 -0
  534. package/dist/tools/index.js.map +1 -0
  535. package/dist/tools/mcp.d.ts +72 -0
  536. package/dist/tools/mcp.d.ts.map +1 -0
  537. package/dist/tools/mcp.js +422 -0
  538. package/dist/tools/mcp.js.map +1 -0
  539. package/dist/tools/plan.d.ts +18 -0
  540. package/dist/tools/plan.d.ts.map +1 -0
  541. package/dist/tools/plan.js +75 -0
  542. package/dist/tools/plan.js.map +1 -0
  543. package/dist/tools/todo.d.ts +18 -0
  544. package/dist/tools/todo.d.ts.map +1 -0
  545. package/dist/tools/todo.js +153 -0
  546. package/dist/tools/todo.js.map +1 -0
  547. package/dist/tools/web.d.ts +13 -0
  548. package/dist/tools/web.d.ts.map +1 -0
  549. package/dist/tools/web.js +377 -0
  550. package/dist/tools/web.js.map +1 -0
  551. package/dist/ui/box.d.ts +56 -0
  552. package/dist/ui/box.d.ts.map +1 -0
  553. package/dist/ui/box.js +241 -0
  554. package/dist/ui/box.js.map +1 -0
  555. package/dist/ui/command-panel.d.ts +55 -0
  556. package/dist/ui/command-panel.d.ts.map +1 -0
  557. package/dist/ui/command-panel.js +212 -0
  558. package/dist/ui/command-panel.js.map +1 -0
  559. package/dist/ui/file-completion.d.ts +62 -0
  560. package/dist/ui/file-completion.d.ts.map +1 -0
  561. package/dist/ui/file-completion.js +209 -0
  562. package/dist/ui/file-completion.js.map +1 -0
  563. package/dist/ui/markdown.d.ts +12 -0
  564. package/dist/ui/markdown.d.ts.map +1 -0
  565. package/dist/ui/markdown.js +215 -0
  566. package/dist/ui/markdown.js.map +1 -0
  567. package/dist/ui/multiline-input.d.ts +47 -0
  568. package/dist/ui/multiline-input.d.ts.map +1 -0
  569. package/dist/ui/multiline-input.js +94 -0
  570. package/dist/ui/multiline-input.js.map +1 -0
  571. package/dist/ui/status-bar.d.ts +33 -0
  572. package/dist/ui/status-bar.d.ts.map +1 -0
  573. package/dist/ui/status-bar.js +96 -0
  574. package/dist/ui/status-bar.js.map +1 -0
  575. package/dist/ui/stream-markdown.d.ts +35 -0
  576. package/dist/ui/stream-markdown.d.ts.map +1 -0
  577. package/dist/ui/stream-markdown.js +138 -0
  578. package/dist/ui/stream-markdown.js.map +1 -0
  579. package/dist/ui/suggestions.d.ts +35 -0
  580. package/dist/ui/suggestions.d.ts.map +1 -0
  581. package/dist/ui/suggestions.js +118 -0
  582. package/dist/ui/suggestions.js.map +1 -0
  583. package/dist/ui/tool-preview.d.ts +34 -0
  584. package/dist/ui/tool-preview.d.ts.map +1 -0
  585. package/dist/ui/tool-preview.js +128 -0
  586. package/dist/ui/tool-preview.js.map +1 -0
  587. package/package.json +93 -0
@@ -0,0 +1,1095 @@
1
+ "use strict";
2
+ /**
3
+ * openhorse - Command Registry
4
+ *
5
+ * 注册所有 slash 命令,提供查找和列表功能。
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.getCommands = getCommands;
12
+ exports.findCommand = findCommand;
13
+ exports.getCommandNames = getCommandNames;
14
+ exports.executeChat = handleChat;
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ const task_manager_1 = require("../services/task-manager");
17
+ const agent_runner_1 = require("../services/agent-runner");
18
+ const config_1 = require("../services/config");
19
+ const box_1 = require("../ui/box");
20
+ const stream_markdown_1 = require("../ui/stream-markdown");
21
+ const framework_1 = require("../framework");
22
+ const tools_1 = require("../tools");
23
+ const mcp_1 = require("../tools/mcp");
24
+ const session_storage_1 = require("../services/session-storage");
25
+ // ============================================================================
26
+ // 颜色常量
27
+ // ============================================================================
28
+ const BRAND = chalk_1.default.hex('#FF6B35');
29
+ const ACCENT = chalk_1.default.hex('#00D4AA');
30
+ const DIM = chalk_1.default.dim;
31
+ const ERROR = chalk_1.default.red;
32
+ const WARN = chalk_1.default.yellow;
33
+ const SUCCESS = chalk_1.default.green;
34
+ const HEADER = chalk_1.default.cyan.bold;
35
+ // ============================================================================
36
+ // 工具参数摘要
37
+ // ============================================================================
38
+ function compactToolArgs(args) {
39
+ if (typeof args.path === 'string') {
40
+ return args.path.length > 48 ? args.path.slice(0, 45) + '...' : args.path;
41
+ }
42
+ if (typeof args.command === 'string') {
43
+ return args.command.length > 48 ? args.command.slice(0, 45) + '...' : args.command;
44
+ }
45
+ if (typeof args.pattern === 'string') {
46
+ return args.pattern.length > 48 ? args.pattern.slice(0, 45) + '...' : args.pattern;
47
+ }
48
+ for (const val of Object.values(args)) {
49
+ if (typeof val === 'string') {
50
+ return val.length > 48 ? val.slice(0, 45) + '...' : val;
51
+ }
52
+ }
53
+ return '';
54
+ }
55
+ // ============================================================================
56
+ // 命令实现
57
+ // ============================================================================
58
+ let taskManager = null;
59
+ function showHelp() {
60
+ console.log();
61
+ console.log(HEADER('Commands:'));
62
+ console.log();
63
+ for (const cmd of COMMANDS) {
64
+ const aliases = cmd.aliases ? ` (${cmd.aliases.join(', ')})` : '';
65
+ const params = cmd.params?.map(p => `<${p.name}>`).join(' ') || '';
66
+ console.log(` ${ACCENT(`/${cmd.name}`)}${aliases} ${DIM(params)}`);
67
+ console.log(` ${DIM(cmd.description)}`);
68
+ }
69
+ console.log();
70
+ console.log(DIM('Type any text without / prefix to chat with the LLM.'));
71
+ console.log();
72
+ return { success: true };
73
+ }
74
+ function showStatus(ctx) {
75
+ console.log();
76
+ console.log(HEADER('System Status'));
77
+ console.log(DIM('─'.repeat(40)));
78
+ const brainStatus = ctx.runtime.brain.getStatus();
79
+ const memStatus = ctx.runtime.memory.getStatus();
80
+ const storeStats = ctx.runtime.store.getStats();
81
+ console.log(` Mode ${BRAND(ctx.config.mode)}`);
82
+ console.log(` Log level ${DIM(ctx.config.logLevel)}`);
83
+ console.log();
84
+ console.log(` Agents ${SUCCESS(brainStatus.agents.length)} registered`);
85
+ console.log(` Tasks ${brainStatus.pendingTasks} pending (${brainStatus.strategy} strategy)`);
86
+ console.log();
87
+ console.log(` Memory (inline):`);
88
+ console.log(` Working ${memStatus.working} entries`);
89
+ console.log(` Short-term ${memStatus['short-term']} entries`);
90
+ console.log(` Long-term ${memStatus['long-term']} entries`);
91
+ console.log();
92
+ console.log(` Memory (store):`);
93
+ console.log(` Working ${storeStats.working} entries`);
94
+ console.log(` Short-term ${storeStats['short-term']} entries`);
95
+ console.log(` Long-term ${storeStats['long-term']} entries`);
96
+ console.log();
97
+ return { success: true };
98
+ }
99
+ function showAgents(ctx) {
100
+ console.log();
101
+ console.log(HEADER('Registered Agents'));
102
+ console.log(DIM('─'.repeat(40)));
103
+ for (const agent of ctx.runtime.agents) {
104
+ const status = agent.getStatus();
105
+ const statusColor = status.status === 'idle' ? SUCCESS : WARN;
106
+ console.log();
107
+ console.log(` ${ACCENT(status.name)} ${DIM(`(${status.id})`)}`);
108
+ console.log(` Status: ${statusColor(status.status)}`);
109
+ console.log(` Capabilities: ${status.capabilities.join(', ')}`);
110
+ }
111
+ console.log();
112
+ return { success: true };
113
+ }
114
+ function showMemory(ctx) {
115
+ console.log();
116
+ console.log(HEADER('Memory Status'));
117
+ console.log(DIM('─'.repeat(40)));
118
+ const memStatus = ctx.runtime.memory.getStatus();
119
+ const storeStats = ctx.runtime.store.getStats();
120
+ console.log();
121
+ console.log(HEADER(' Inline MemorySystem:'));
122
+ console.log(` Working ${memStatus.working} / ${ctx.runtime.config.memory.workingCapacity}`);
123
+ console.log(` Short-term ${memStatus['short-term']} / ${ctx.runtime.config.memory.shortTermCapacity}`);
124
+ console.log(` Long-term ${memStatus['long-term']} entries`);
125
+ console.log();
126
+ console.log(HEADER(' Modular MemoryStore:'));
127
+ console.log(` Working ${storeStats.working}`);
128
+ console.log(` Short-term ${storeStats['short-term']}`);
129
+ console.log(` Long-term ${storeStats['long-term']} entries`);
130
+ console.log();
131
+ return { success: true };
132
+ }
133
+ async function handleMemoryReindex(ctx) {
134
+ const { isSemanticEnabled, getSemanticSearchService } = require('../memory/semantic-search');
135
+ if (!isSemanticEnabled()) {
136
+ console.log();
137
+ console.log(WARN('⚠ Semantic search is not enabled.'));
138
+ console.log(DIM(' Set OPENHORSE_EMBEDDING_PROVIDER=ollama or openai to enable.'));
139
+ console.log();
140
+ return { success: false };
141
+ }
142
+ console.log();
143
+ console.log(HEADER('Reindexing project memories...'));
144
+ try {
145
+ const service = getSemanticSearchService();
146
+ const count = await service.indexExistingMemories(process.cwd());
147
+ console.log(SUCCESS(`✔ Indexed ${count} memories`));
148
+ }
149
+ catch (err) {
150
+ console.log(ERROR(`✗ Reindex failed: ${err.message}`));
151
+ return { success: false };
152
+ }
153
+ console.log();
154
+ return { success: true };
155
+ }
156
+ async function handleMemory(ctx, args) {
157
+ const sub = args.trim().toLowerCase();
158
+ if (sub === 'reindex') {
159
+ return handleMemoryReindex(ctx);
160
+ }
161
+ return showMemory(ctx);
162
+ }
163
+ function showSafety(ctx) {
164
+ console.log();
165
+ console.log(HEADER('Safety Checker'));
166
+ console.log(DIM('─'.repeat(40)));
167
+ const policy = ctx.runtime.safety.getPolicy();
168
+ const summary = ctx.runtime.safety.getAuditSummary();
169
+ console.log();
170
+ console.log(` Enabled ${policy.enabled ? SUCCESS('yes') : ERROR('no')}`);
171
+ console.log(` Sandbox ${policy.sandboxMode ? WARN('on') : DIM('off')}`);
172
+ console.log();
173
+ console.log(` Blocked patterns:`);
174
+ for (const pattern of policy.blocked) {
175
+ console.log(` ${ERROR('✗')} ${DIM(pattern)}`);
176
+ }
177
+ console.log();
178
+ console.log(` Dangerous patterns:`);
179
+ for (const pattern of policy.dangerousPatterns) {
180
+ console.log(` ${WARN('⚠')} ${DIM(pattern)}`);
181
+ }
182
+ console.log();
183
+ console.log(` Audit summary: ${summary.total} checks | ${SUCCESS(`${summary.passed} passed`)} | ${ERROR(`${summary.blocked} blocked`)}`);
184
+ console.log();
185
+ return { success: true };
186
+ }
187
+ function showHarness(ctx) {
188
+ console.log();
189
+ console.log(HEADER('Harness Config'));
190
+ console.log(DIM('─'.repeat(40)));
191
+ const cfg = ctx.runtime.harness.getConfig();
192
+ console.log();
193
+ console.log(` Max steps ${cfg.maxSteps}`);
194
+ console.log(` Boundary check ${cfg.boundaryCheck ? SUCCESS('on') : ERROR('off')}`);
195
+ console.log(` Goal constraint ${cfg.goalConstraint ? SUCCESS('on') : ERROR('off')}`);
196
+ console.log(` Result validate ${cfg.resultValidation ? SUCCESS('on') : ERROR('off')}`);
197
+ console.log(` Sandbox ${cfg.sandbox ? WARN('on') : DIM('off')}`);
198
+ console.log(` Timeout ${cfg.timeout}ms`);
199
+ console.log();
200
+ console.log(` Blocked actions: ${cfg.blockedActions.join(', ')}`);
201
+ console.log();
202
+ return { success: true };
203
+ }
204
+ function showConfig(ctx) {
205
+ console.log();
206
+ console.log(HEADER('Configuration'));
207
+ console.log(DIM('─'.repeat(40)));
208
+ const summary = {
209
+ name: ctx.config.name,
210
+ model: ctx.config.model,
211
+ apiBaseUrl: ctx.config.apiBaseUrl || '(default OpenAI)',
212
+ apiKey: ctx.config.apiKey ? `${ctx.config.apiKey.slice(0, 7)}***` : '(not set)',
213
+ maxTokens: String(ctx.config.maxTokens),
214
+ temperature: String(ctx.config.temperature),
215
+ mode: ctx.config.mode,
216
+ logLevel: ctx.config.logLevel,
217
+ };
218
+ const llmSummary = ctx.llm?.getConfigSummary() ?? {};
219
+ for (const [key, val] of Object.entries(summary)) {
220
+ console.log(` ${ACCENT(key.padEnd(16))} ${DIM(val)}`);
221
+ }
222
+ console.log();
223
+ console.log(HEADER(' LLM Settings:'));
224
+ for (const [key, val] of Object.entries(llmSummary)) {
225
+ console.log(` ${ACCENT(key.padEnd(16))} ${DIM(val)}`);
226
+ }
227
+ console.log();
228
+ return { success: true };
229
+ }
230
+ function handleModel(ctx, args) {
231
+ // 模型别名映射
232
+ const MODEL_ALIASES = {
233
+ 'opus': 'claude-opus-4-7',
234
+ 'sonnet': 'claude-sonnet-4-6',
235
+ 'haiku': 'claude-haiku-4-5-20251001',
236
+ 'claude': 'claude-sonnet-4-6',
237
+ 'gpt4': 'gpt-4o',
238
+ 'gpt4o': 'gpt-4o',
239
+ 'gpt35': 'gpt-3.5-turbo',
240
+ // Bailian (coding.dashscope.aliyuncs.com) — OpenAI-compatible
241
+ 'qwen': 'qwen3.5-plus',
242
+ 'qwenplus': 'qwen3.5-plus',
243
+ 'qwen36': 'qwen3.6-plus',
244
+ 'qwenmax': 'qwen3-max-2026-01-23',
245
+ 'coder': 'qwen3-coder-plus',
246
+ 'codernext': 'qwen3-coder-next',
247
+ 'glm': 'glm-5',
248
+ 'glm47': 'glm-4.7',
249
+ 'kimi': 'kimi-k2.5',
250
+ 'minimax': 'MiniMax-M2.5',
251
+ };
252
+ // 可用模型列表
253
+ const AVAILABLE_MODELS = [
254
+ { name: 'claude-opus-4-7', alias: 'opus', provider: 'Anthropic' },
255
+ { name: 'claude-sonnet-4-6', alias: 'sonnet', provider: 'Anthropic' },
256
+ { name: 'claude-haiku-4-5-20251001', alias: 'haiku', provider: 'Anthropic' },
257
+ { name: 'gpt-4o', alias: 'gpt4o', provider: 'OpenAI' },
258
+ { name: 'gpt-3.5-turbo', alias: 'gpt35', provider: 'OpenAI' },
259
+ { name: 'glm-5', alias: 'glm', provider: 'Bailian (Zhipu)' },
260
+ { name: 'glm-4.7', alias: 'glm47', provider: 'Bailian (Zhipu)' },
261
+ { name: 'qwen3.5-plus', alias: 'qwen', provider: 'Bailian (Alibaba)' },
262
+ { name: 'qwen3.6-plus', alias: 'qwen36', provider: 'Bailian (Alibaba)' },
263
+ { name: 'qwen3-max-2026-01-23', alias: 'qwenmax', provider: 'Bailian (Alibaba)' },
264
+ { name: 'qwen3-coder-plus', alias: 'coder', provider: 'Bailian (Alibaba)' },
265
+ { name: 'qwen3-coder-next', alias: 'codernext', provider: 'Bailian (Alibaba)' },
266
+ { name: 'kimi-k2.5', alias: 'kimi', provider: 'Bailian (Moonshot)' },
267
+ { name: 'MiniMax-M2.5', alias: 'minimax', provider: 'Bailian (MiniMax)' },
268
+ ];
269
+ const trimmedArgs = args.trim().toLowerCase();
270
+ // 显示当前模型
271
+ if (!args || trimmedArgs === '?' || trimmedArgs === 'info') {
272
+ console.log();
273
+ if (ctx.llm) {
274
+ const currentModel = ctx.llm.getModel();
275
+ const aliasEntry = AVAILABLE_MODELS.find(m => m.name === currentModel || m.alias === currentModel);
276
+ console.log(HEADER('Current Model'));
277
+ console.log(DIM('─'.repeat(40)));
278
+ console.log(` Model ${BRAND(currentModel)}`);
279
+ if (aliasEntry) {
280
+ console.log(` Alias ${ACCENT(aliasEntry.alias)}`);
281
+ console.log(` Provider ${DIM(aliasEntry.provider)}`);
282
+ }
283
+ }
284
+ else {
285
+ console.log(ERROR('LLM not initialized. Set OPENHORSE_API_KEY first.'));
286
+ }
287
+ console.log();
288
+ return { success: true };
289
+ }
290
+ // 显示模型列表
291
+ if (trimmedArgs === 'list' || trimmedArgs === 'ls') {
292
+ console.log();
293
+ console.log(HEADER('Available Models'));
294
+ console.log(DIM('─'.repeat(40)));
295
+ const currentModel = ctx.llm?.getModel() || '';
296
+ for (const m of AVAILABLE_MODELS) {
297
+ const isCurrent = m.name === currentModel || m.alias === currentModel;
298
+ const marker = isCurrent ? SUCCESS('●') : DIM('○');
299
+ console.log(` ${marker} ${ACCENT(m.name)} ${DIM(`(${m.alias})`)} ${isCurrent ? BRAND('(current)') : ''}`);
300
+ console.log(` ${DIM(m.provider)}`);
301
+ }
302
+ console.log();
303
+ console.log(DIM('Use /model <name|alias> to switch, e.g. /model sonnet'));
304
+ console.log();
305
+ return { success: true };
306
+ }
307
+ // 显示帮助
308
+ if (trimmedArgs === 'help') {
309
+ console.log();
310
+ console.log(HEADER('/model Command Help'));
311
+ console.log(DIM('─'.repeat(40)));
312
+ console.log();
313
+ console.log(` ${ACCENT('/model')} Show current model`);
314
+ console.log(` ${ACCENT('/model list')} Show available models`);
315
+ console.log(` ${ACCENT('/model <name>')} Switch to specific model`);
316
+ console.log(` ${ACCENT('/model <alias>')} Switch using alias (opus, sonnet, haiku)`);
317
+ console.log();
318
+ console.log(DIM('Aliases: opus, sonnet, haiku, gpt4o, qwen, glm'));
319
+ console.log();
320
+ return { success: true };
321
+ }
322
+ // 设置模型
323
+ if (!ctx.llm) {
324
+ console.log(ERROR('LLM not initialized. Set OPENHORSE_API_KEY first.'));
325
+ console.log();
326
+ return { success: false };
327
+ }
328
+ // 解析别名
329
+ const resolvedModel = MODEL_ALIASES[trimmedArgs] || args.trim();
330
+ ctx.llm.setModel(resolvedModel);
331
+ ctx.store.setState({ currentModel: resolvedModel });
332
+ console.log(SUCCESS(`✔ Model changed to ${BRAND(resolvedModel)}`));
333
+ console.log();
334
+ return { success: true };
335
+ }
336
+ function handleTask(ctx, args) {
337
+ const [sub, ...rest] = args.trim().split(/\s+/);
338
+ if (sub === 'list' || sub === 'ls') {
339
+ if (!taskManager) {
340
+ taskManager = new task_manager_1.TaskManager();
341
+ }
342
+ console.log();
343
+ console.log(HEADER('Task List'));
344
+ console.log(DIM('─'.repeat(40)));
345
+ const stats = taskManager.getStats();
346
+ console.log(` Total ${stats.total}`);
347
+ console.log(` Pending ${stats.pending}`);
348
+ console.log(` Running ${stats.running}`);
349
+ console.log(` Completed ${SUCCESS(stats.completed)}`);
350
+ console.log(` Failed ${ERROR(stats.failed)}`);
351
+ console.log(` Cancelled ${DIM(stats.cancelled)}`);
352
+ const tasks = taskManager.list();
353
+ if (tasks.length > 0) {
354
+ console.log();
355
+ for (const t of tasks) {
356
+ const statusIcon = t.status === 'completed' ? SUCCESS('✓')
357
+ : t.status === 'failed' ? ERROR('✗')
358
+ : t.status === 'running' ? WARN('◌')
359
+ : t.status === 'cancelled' ? DIM('⊘')
360
+ : DIM('○');
361
+ console.log(` ${statusIcon} ${ACCENT(t.name)} ${DIM(`(${t.id.slice(0, 8)})`)}`);
362
+ console.log(` ${DIM(`[${t.priority}]`)} ${t.description.slice(0, 60)}`);
363
+ }
364
+ }
365
+ console.log();
366
+ return { success: true };
367
+ }
368
+ // 默认行为: 作为任务名提交
369
+ const taskName = args.trim() || 'demo-task';
370
+ const task = {
371
+ id: `cli-${Date.now()}`,
372
+ name: taskName,
373
+ description: `Task submitted from CLI: ${taskName}`,
374
+ priority: 'P1',
375
+ assignedTo: 'leader',
376
+ status: 'pending',
377
+ };
378
+ console.log();
379
+ ctx.runtime.brain.submitTask(task);
380
+ console.log(SUCCESS(`✔ Task "${taskName}" submitted`));
381
+ console.log();
382
+ return { success: true };
383
+ }
384
+ async function handleRun(ctx, args) {
385
+ if (!args.trim()) {
386
+ console.log(ERROR('Usage: /run <task description>'));
387
+ console.log(DIM(' Creates a task and executes it through the Agent + LLM pipeline.'));
388
+ console.log();
389
+ return { success: false };
390
+ }
391
+ if (!ctx.llm || !(0, config_1.isConfigured)(ctx.config)) {
392
+ console.log(WARN('⚠ LLM not configured. Set OPENHORSE_API_KEY in .env to enable run mode.'));
393
+ console.log();
394
+ return { success: false };
395
+ }
396
+ if (!taskManager) {
397
+ taskManager = new task_manager_1.TaskManager();
398
+ }
399
+ const taskOptions = {
400
+ name: args.slice(0, 80),
401
+ description: args,
402
+ priority: 'P1',
403
+ assignedTo: 'leader',
404
+ tags: ['cli', 'interactive'],
405
+ };
406
+ const record = taskManager.create(taskOptions);
407
+ console.log();
408
+ console.log(SUCCESS(`✔ Task created: ${ACCENT(record.name)}`));
409
+ console.log(DIM(` ID: ${record.id} | Tags: ${record.tags.join(', ')}`));
410
+ taskManager.start(record.id);
411
+ console.log(WARN('◌ Running task through Agent + LLM...'));
412
+ try {
413
+ const agent = ctx.runtime.agents[0];
414
+ if (!agent) {
415
+ throw new Error('No agents registered');
416
+ }
417
+ const runner = new agent_runner_1.AgentRunner(agent, ctx.llm);
418
+ const task = taskManager.toTask(record);
419
+ const result = await runner.run(task);
420
+ if (result.success) {
421
+ taskManager.complete(record.id, result);
422
+ console.log(SUCCESS(`✓ Task completed in ${result.duration}ms`));
423
+ if (result.tokenUsage) {
424
+ console.log(DIM(` Tokens: ${result.tokenUsage.promptTokens} in / ${result.tokenUsage.completionTokens} out`));
425
+ }
426
+ if (result.data?.summary) {
427
+ console.log();
428
+ console.log(ACCENT(' Summary:'));
429
+ console.log(` ${result.data.summary}`);
430
+ }
431
+ }
432
+ else {
433
+ taskManager.fail(record.id, result.error, result);
434
+ console.log(ERROR(`✗ Task failed: ${result.error}`));
435
+ }
436
+ }
437
+ catch (error) {
438
+ taskManager.fail(record.id, error.message);
439
+ console.log(ERROR(`✗ Task error: ${error.message}`));
440
+ }
441
+ console.log();
442
+ return { success: true };
443
+ }
444
+ async function handleChat(ctx, input) {
445
+ if (!input) {
446
+ console.log(ERROR('Usage: /chat <message>'));
447
+ console.log();
448
+ return { success: false };
449
+ }
450
+ if (!ctx.llm || !(0, config_1.isConfigured)(ctx.config)) {
451
+ console.log(WARN('⚠ LLM not configured. Set OPENHORSE_API_KEY in .env to enable chat.'));
452
+ console.log();
453
+ return { success: false };
454
+ }
455
+ // Record user message to session
456
+ if (ctx.sessionId) {
457
+ (0, session_storage_1.appendSessionMessage)(ctx.sessionId, {
458
+ role: 'user',
459
+ content: input,
460
+ timestamp: Date.now(),
461
+ });
462
+ }
463
+ ctx.store.addMessage({ role: 'user', content: input });
464
+ const snapshot = ctx.store.getSnapshot();
465
+ const promptCtx = {
466
+ cwd: ctx.cwd,
467
+ platform: process.platform,
468
+ nodeVersion: process.version,
469
+ tools: tools_1.TOOLS,
470
+ memoryContent: snapshot.memoryContent,
471
+ skillsContent: snapshot.skillsContent,
472
+ };
473
+ const systemPrompt = (0, framework_1.getSystemPrompt)(promptCtx);
474
+ const spinner = (0, box_1.createSpinner)();
475
+ spinner.start('Thinking');
476
+ let finalContent = '';
477
+ let finalModel = '';
478
+ let finalUsage;
479
+ let responseStarted = false;
480
+ const sessionMessagesToRecord = [];
481
+ let lastToolCallId = '';
482
+ let lastToolArgs = {};
483
+ // 收集当前 turn 的所有 tool_calls,用于构建完整的 assistant 消息
484
+ let pendingToolCalls = [];
485
+ let currentAssistantContent = '';
486
+ // 流式 Markdown 渲染器
487
+ let streamRenderer = null;
488
+ const toolExecutor = async (name, args) => {
489
+ const result = await (0, tools_1.executeTool)(name, args);
490
+ // 不在这里打印,让 tool_result 事件处理
491
+ return result;
492
+ };
493
+ const streamCallbacks = {
494
+ onChunk: (chunk) => {
495
+ if (!responseStarted) {
496
+ responseStarted = true;
497
+ spinner.stop();
498
+ // 打印换行,让流式输出在新行开始
499
+ console.log();
500
+ // 初始化流式渲染器
501
+ streamRenderer = (0, stream_markdown_1.createStreamRenderer)();
502
+ }
503
+ currentAssistantContent += chunk;
504
+ // 使用流式渲染器处理 chunk
505
+ if (streamRenderer) {
506
+ const rendered = streamRenderer.feed(chunk);
507
+ if (rendered) {
508
+ process.stdout.write(rendered);
509
+ }
510
+ }
511
+ else {
512
+ process.stdout.write(chunk);
513
+ }
514
+ },
515
+ };
516
+ try {
517
+ const messages = [{ role: 'system', content: systemPrompt }, ...snapshot.conversationHistory];
518
+ for await (const event of (0, framework_1.query)({
519
+ messages,
520
+ tools: tools_1.TOOLS,
521
+ toolExecutor,
522
+ llm: ctx.llm,
523
+ streamCallbacks,
524
+ costTracker: snapshot.costTracker,
525
+ })) {
526
+ switch (event.type) {
527
+ case 'request_start':
528
+ // 停止 spinner,等待 LLM 响应
529
+ spinner.stop();
530
+ console.log();
531
+ console.log(DIM(`Turn ${event.turn}...`));
532
+ // 重置当前 turn 的状态
533
+ pendingToolCalls = [];
534
+ currentAssistantContent = '';
535
+ // 重置流式渲染器
536
+ streamRenderer = (0, stream_markdown_1.createStreamRenderer)();
537
+ break;
538
+ case 'tool_call':
539
+ // 收集完整的 tool_call 信息
540
+ lastToolCallId = event.callId;
541
+ lastToolArgs = event.args;
542
+ pendingToolCalls.push({
543
+ id: event.callId,
544
+ type: 'function',
545
+ function: {
546
+ name: event.name,
547
+ arguments: JSON.stringify(event.args),
548
+ },
549
+ });
550
+ break;
551
+ case 'tool_result':
552
+ // 显示工具结果后,准备下一轮(不启动 spinner)
553
+ const parsedResult = JSON.parse(event.result);
554
+ console.log((0, box_1.toolLine)(event.name, lastToolArgs, parsedResult.success !== false, event.duration));
555
+ // Record tool result for session
556
+ sessionMessagesToRecord.push({
557
+ role: 'tool',
558
+ content: event.result,
559
+ timestamp: Date.now(),
560
+ toolCallId: lastToolCallId,
561
+ });
562
+ break;
563
+ case 'message':
564
+ // 收到 assistant 文本消息,如果有 pending tool_calls,先记录带 tool_calls 的消息
565
+ if (pendingToolCalls.length > 0) {
566
+ sessionMessagesToRecord.push({
567
+ role: 'assistant',
568
+ content: event.content || '',
569
+ timestamp: Date.now(),
570
+ tool_calls: pendingToolCalls,
571
+ });
572
+ pendingToolCalls = [];
573
+ }
574
+ else if (event.content) {
575
+ sessionMessagesToRecord.push({
576
+ role: 'assistant',
577
+ content: event.content,
578
+ timestamp: Date.now(),
579
+ });
580
+ }
581
+ break;
582
+ case 'strategy_exhausted':
583
+ console.log(WARN(`⚠ ${event.suggestion}`));
584
+ break;
585
+ case 'complete':
586
+ finalContent = event.content;
587
+ finalModel = event.model;
588
+ finalUsage = event.usage;
589
+ // 如果 complete 时还有 pending tool_calls(没有 message 事件),记录它们
590
+ if (pendingToolCalls.length > 0) {
591
+ sessionMessagesToRecord.push({
592
+ role: 'assistant',
593
+ content: finalContent || '',
594
+ timestamp: Date.now(),
595
+ tool_calls: pendingToolCalls,
596
+ });
597
+ pendingToolCalls = [];
598
+ }
599
+ break;
600
+ }
601
+ }
602
+ // 刷新流式渲染器,输出剩余内容
603
+ if (streamRenderer) {
604
+ const remaining = streamRenderer.flush();
605
+ if (remaining) {
606
+ process.stdout.write(remaining);
607
+ }
608
+ streamRenderer = null;
609
+ }
610
+ if (finalContent) {
611
+ ctx.store.addMessage({ role: 'assistant', content: finalContent });
612
+ // Record assistant message to session
613
+ if (ctx.sessionId) {
614
+ (0, session_storage_1.appendSessionMessage)(ctx.sessionId, {
615
+ role: 'assistant',
616
+ content: finalContent,
617
+ timestamp: Date.now(),
618
+ });
619
+ // Record any tool messages
620
+ if (sessionMessagesToRecord.length > 0) {
621
+ (0, session_storage_1.appendSessionMessages)(ctx.sessionId, sessionMessagesToRecord);
622
+ }
623
+ }
624
+ }
625
+ if (finalUsage) {
626
+ ctx.store.setTokenUsage(finalUsage);
627
+ }
628
+ if (responseStarted) {
629
+ console.log();
630
+ }
631
+ const stats = [
632
+ finalUsage ? `tokens: ${finalUsage.promptTokens}+${finalUsage.completionTokens}` : '',
633
+ finalModel ? finalModel : '',
634
+ ].filter(Boolean).join(' ');
635
+ if (stats) {
636
+ console.log(DIM(stats));
637
+ }
638
+ }
639
+ catch (error) {
640
+ spinner.stop();
641
+ console.log();
642
+ console.log(ERROR(`✗ ${error.message || String(error)}`));
643
+ const hist = ctx.store.getSnapshot().conversationHistory;
644
+ if (hist.length > 0) {
645
+ ctx.store.setState({ conversationHistory: hist.slice(0, -1) });
646
+ }
647
+ }
648
+ return { success: true };
649
+ }
650
+ async function handleExit(ctx) {
651
+ console.log();
652
+ console.log(DIM('Shutting down...'));
653
+ // Update session summary before exit
654
+ if (ctx.sessionId) {
655
+ const messages = (0, session_storage_1.readSessionMessages)(ctx.sessionId);
656
+ if (messages.length > 0) {
657
+ (0, session_storage_1.updateSessionSummary)(ctx.sessionId, messages);
658
+ }
659
+ (0, session_storage_1.endSession)(ctx.sessionId);
660
+ }
661
+ await ctx.runtime.shutdown();
662
+ console.log(SUCCESS('Goodbye! 🐴'));
663
+ process.exit(0);
664
+ }
665
+ function handleCost(ctx) {
666
+ console.log();
667
+ console.log(HEADER('Session Cost'));
668
+ console.log(DIM('─'.repeat(40)));
669
+ const costTracker = ctx.store.getSnapshot().costTracker;
670
+ const stats = costTracker.getSessionStats();
671
+ if (stats.recordCount === 0) {
672
+ console.log(DIM(' No usage recorded yet.'));
673
+ console.log(DIM(' Use /run or /chat to interact with LLM.'));
674
+ console.log();
675
+ return { success: true };
676
+ }
677
+ // Summary
678
+ console.log();
679
+ console.log(` ${ACCENT('Total Tokens')} ${stats.totalTokens}`);
680
+ console.log(` ${ACCENT('Prompt')} ${stats.totalPromptTokens}`);
681
+ console.log(` ${ACCENT('Completion')} ${stats.totalCompletionTokens}`);
682
+ console.log(` ${ACCENT('Est. Cost')} ${costTracker.formatCost(stats.totalCost)}`);
683
+ console.log(` ${ACCENT('Requests')} ${stats.recordCount}`);
684
+ // By Model
685
+ if (Object.keys(stats.byModel).length > 0) {
686
+ console.log();
687
+ console.log(HEADER(' By Model:'));
688
+ for (const [model, data] of Object.entries(stats.byModel)) {
689
+ console.log(` ${BRAND(model.padEnd(20))} ${data.tokens} tokens, ${costTracker.formatCost(data.cost)}`);
690
+ }
691
+ }
692
+ // Budget
693
+ const budget = costTracker.getBudget();
694
+ if (budget !== null) {
695
+ const check = costTracker.checkBudget();
696
+ console.log();
697
+ console.log(HEADER(' Budget:'));
698
+ console.log(` ${ACCENT('Limit')} ${costTracker.formatCost(budget)}`);
699
+ console.log(` ${ACCENT('Used')} ${costTracker.formatCost(check.used)}`);
700
+ console.log(` ${check.ok ? SUCCESS('✓ Within budget') : WARN('⚠ Budget exceeded')}`);
701
+ }
702
+ console.log();
703
+ return { success: true };
704
+ }
705
+ function handleSkills(ctx) {
706
+ const { getSkillsRegistry } = require('../skills');
707
+ console.log();
708
+ console.log(HEADER('Loaded Skills'));
709
+ console.log(DIM('─'.repeat(40)));
710
+ try {
711
+ const registry = getSkillsRegistry();
712
+ const summary = registry.getSummary();
713
+ if (summary.count === 0) {
714
+ console.log();
715
+ console.log(DIM(' No skills loaded.'));
716
+ console.log(DIM(' Place SKILL.md files in ~/.openhorse/skills/<name>/ or .openhorse/skills/<name>/'));
717
+ console.log();
718
+ return { success: true };
719
+ }
720
+ console.log();
721
+ console.log(` Total ${SUCCESS(summary.count)} skills (${WARN(summary.autoCount)} auto-trigger)`);
722
+ console.log();
723
+ for (const skill of registry.getAllSkills()) {
724
+ const source = registry['loader']?.getSource(skill.name);
725
+ const sourceType = source?.type || 'unknown';
726
+ console.log(` ${ACCENT(skill.name)} ${DIM(`(${sourceType})`)}`);
727
+ console.log(` ${DIM(skill.description || '(no description)')}`);
728
+ }
729
+ console.log();
730
+ }
731
+ catch (err) {
732
+ console.log(ERROR(`✗ ${err.message}`));
733
+ return { success: false };
734
+ }
735
+ return { success: true };
736
+ }
737
+ function handleMcp(ctx) {
738
+ console.log();
739
+ console.log(HEADER('MCP Servers'));
740
+ console.log(DIM('─'.repeat(40)));
741
+ const status = mcp_1.mcpManager.getStatus();
742
+ if (status.length === 0) {
743
+ console.log();
744
+ console.log(DIM(' No servers configured. Add to ~/.openhorse/mcp.json'));
745
+ console.log();
746
+ return { success: true };
747
+ }
748
+ console.log();
749
+ for (const s of status) {
750
+ const stateLabel = s.dead
751
+ ? ERROR('dead')
752
+ : s.connected
753
+ ? SUCCESS('connected')
754
+ : WARN('disconnected');
755
+ console.log(` ${ACCENT(s.name.padEnd(20))} ${stateLabel} ${DIM(`${s.toolCount} tools`)}`);
756
+ }
757
+ console.log();
758
+ return { success: true };
759
+ }
760
+ function handleClearHistory(ctx) {
761
+ const history = ctx.store.getSnapshot().conversationHistory;
762
+ if (history.length === 0) {
763
+ console.log(DIM('Conversation history is already empty'));
764
+ console.log();
765
+ return { success: true };
766
+ }
767
+ ctx.store.resetConversation();
768
+ (0, framework_1.resetToolState)();
769
+ console.log(SUCCESS(`✔ Cleared ${history.length} messages from conversation history`));
770
+ console.log(DIM(' Configuration and system state preserved'));
771
+ console.log();
772
+ return { success: true };
773
+ }
774
+ function handleUsage(ctx) {
775
+ console.log();
776
+ console.log(HEADER('Usage Statistics'));
777
+ console.log(DIM('─'.repeat(40)));
778
+ const snapshot = ctx.store.getSnapshot();
779
+ const usage = snapshot.tokenUsage;
780
+ const history = snapshot.conversationHistory;
781
+ console.log();
782
+ // Token usage
783
+ console.log(HEADER(' Tokens:'));
784
+ if (usage) {
785
+ console.log(` Input ${ACCENT(usage.promptTokens.toLocaleString())}`);
786
+ console.log(` Output ${ACCENT(usage.completionTokens.toLocaleString())}`);
787
+ const total = usage.promptTokens + usage.completionTokens;
788
+ console.log(` Total ${DIM(total.toLocaleString())}`);
789
+ const ratio = usage.completionTokens / usage.promptTokens;
790
+ console.log(` Ratio ${DIM(ratio.toFixed(2))} (output/input)`);
791
+ }
792
+ else {
793
+ console.log(DIM(' No token usage recorded'));
794
+ }
795
+ console.log();
796
+ // Conversation stats
797
+ console.log(HEADER(' Conversation:'));
798
+ console.log(` Messages ${DIM(history.length.toString())}`);
799
+ console.log(` Turns ${DIM(Math.floor(history.length / 2).toString())}`);
800
+ // Count by role
801
+ const byRole = { user: 0, assistant: 0, system: 0, tool: 0 };
802
+ for (const msg of history) {
803
+ byRole[msg.role] = (byRole[msg.role] || 0) + 1;
804
+ }
805
+ console.log(` User msgs ${DIM(byRole.user.toString())}`);
806
+ console.log(` Assistant ${DIM(byRole.assistant.toString())}`);
807
+ console.log();
808
+ // Model info
809
+ console.log(HEADER(' Model:'));
810
+ console.log(` Current ${BRAND(snapshot.currentModel)}`);
811
+ if (ctx.llm) {
812
+ console.log(` Active ${ACCENT(ctx.llm.getModel())}`);
813
+ }
814
+ console.log();
815
+ return { success: true };
816
+ }
817
+ // ============================================================================
818
+ // Session 命令
819
+ // ============================================================================
820
+ function handleSessions(ctx) {
821
+ console.log();
822
+ console.log(HEADER('Sessions'));
823
+ console.log(DIM('─'.repeat(40)));
824
+ const sessions = (0, session_storage_1.listSessions)(10);
825
+ if (sessions.length === 0) {
826
+ console.log(DIM(' No sessions found'));
827
+ console.log();
828
+ return { success: true };
829
+ }
830
+ console.log();
831
+ for (const session of sessions) {
832
+ const startTime = new Date(session.startTime).toLocaleString();
833
+ const duration = session.endTime
834
+ ? Math.round((session.endTime - session.startTime) / 1000) + 's'
835
+ : 'active';
836
+ const status = session.endTime ? DIM('completed') : ACCENT('active');
837
+ console.log(` ${status} ${BRAND(session.id.slice(0, 8))} ${DIM(session.model)}`);
838
+ console.log(` ${DIM(`Started: ${startTime}`)} ${DIM(`Duration: ${duration}`)}`);
839
+ console.log(` ${DIM(`Tokens: ${session.tokenCount}`)} ${DIM(`Cost: $${session.cost.toFixed(4)}`)}`);
840
+ console.log();
841
+ }
842
+ console.log(DIM('Use /resume <session-id> to restore a session'));
843
+ console.log();
844
+ return { success: true };
845
+ }
846
+ function handleResume(ctx, args) {
847
+ const sessionId = args.trim();
848
+ if (!sessionId) {
849
+ // Try to resume last session for current project
850
+ const lastSession = (0, session_storage_1.getLastSession)(process.cwd());
851
+ if (lastSession) {
852
+ console.log();
853
+ console.log(HEADER(`Resuming last session`));
854
+ console.log(DIM(` ID: ${lastSession.id.slice(0, 8)}`));
855
+ console.log(DIM(` Model: ${lastSession.model}`));
856
+ console.log(DIM(` Started: ${new Date(lastSession.startTime).toLocaleString()}`));
857
+ // Load history and show summary
858
+ const history = (0, session_storage_1.loadSessionHistory)(lastSession.id);
859
+ if (history.length > 0) {
860
+ const summary = generateHistorySummary(history);
861
+ console.log(DIM(` Summary: ${summary}`));
862
+ console.log();
863
+ ctx.store.setState({ conversationHistory: history });
864
+ (0, framework_1.resetToolState)();
865
+ console.log(SUCCESS(`✔ Restored ${history.length} messages from session`));
866
+ }
867
+ else {
868
+ console.log();
869
+ console.log(DIM(' No messages in session'));
870
+ }
871
+ console.log();
872
+ return { success: true };
873
+ }
874
+ else {
875
+ console.log(ERROR('No previous session found for this project'));
876
+ console.log(DIM('Use /sessions to list all sessions'));
877
+ console.log();
878
+ return { success: false };
879
+ }
880
+ }
881
+ // Resume specific session
882
+ const session = (0, session_storage_1.loadSessionMeta)(sessionId) || (0, session_storage_1.listSessions)().find(s => s.id.startsWith(sessionId));
883
+ if (!session) {
884
+ console.log(ERROR(`Session not found: ${sessionId}`));
885
+ console.log(DIM('Use /sessions to list all sessions'));
886
+ console.log();
887
+ return { success: false };
888
+ }
889
+ console.log();
890
+ console.log(HEADER(`Resuming session ${session.id.slice(0, 8)}`));
891
+ console.log(DIM(` Model: ${session.model}`));
892
+ console.log(DIM(` Started: ${new Date(session.startTime).toLocaleString()}`));
893
+ // Load history and show summary
894
+ const history = (0, session_storage_1.loadSessionHistory)(session.id);
895
+ if (history.length > 0) {
896
+ const summary = generateHistorySummary(history);
897
+ console.log(DIM(` Summary: ${summary}`));
898
+ console.log();
899
+ ctx.store.setState({ conversationHistory: history });
900
+ (0, framework_1.resetToolState)();
901
+ console.log(SUCCESS(`✔ Restored ${history.length} messages`));
902
+ }
903
+ else {
904
+ console.log();
905
+ console.log(DIM(' No messages in session'));
906
+ }
907
+ console.log();
908
+ return { success: true };
909
+ }
910
+ /** Generate a brief summary of conversation history */
911
+ function generateHistorySummary(messages) {
912
+ const userMsgs = messages.filter(m => m.role === 'user' && m.content);
913
+ const assistantMsgsWithTools = messages.filter(m => m.role === 'assistant' && m.tool_calls && m.tool_calls.length > 0);
914
+ // Extract topics from first few user messages
915
+ const topics = userMsgs.slice(0, 3).map(m => {
916
+ const content = m.content || '';
917
+ return content.length > 40 ? content.slice(0, 40) + '...' : content;
918
+ });
919
+ // Extract tools used
920
+ const toolsUsed = assistantMsgsWithTools.flatMap(m => m.tool_calls?.map(tc => tc.function.name) || []);
921
+ const uniqueTools = [...new Set(toolsUsed)];
922
+ // Build summary
923
+ const parts = [];
924
+ if (topics.length > 0) {
925
+ parts.push(`Topics: ${topics.join('; ')}`);
926
+ }
927
+ if (uniqueTools.length > 0) {
928
+ parts.push(`Tools: ${uniqueTools.join(', ')}`);
929
+ }
930
+ if (parts.length === 0) {
931
+ return 'No significant activity';
932
+ }
933
+ return parts.join('. ');
934
+ }
935
+ // ============================================================================
936
+ // 命令注册表
937
+ // ============================================================================
938
+ const COMMANDS = [
939
+ // 系统命令
940
+ {
941
+ name: 'help',
942
+ aliases: ['h'],
943
+ description: 'Show available commands',
944
+ type: 'builtin',
945
+ execute: () => showHelp(),
946
+ },
947
+ {
948
+ name: 'status',
949
+ aliases: ['s'],
950
+ description: 'Show system status overview',
951
+ type: 'builtin',
952
+ execute: (ctx) => showStatus(ctx),
953
+ },
954
+ {
955
+ name: 'clear',
956
+ description: 'Clear the terminal screen',
957
+ type: 'builtin',
958
+ execute: () => {
959
+ process.stdout.write('\x1Bc');
960
+ return { success: true };
961
+ },
962
+ },
963
+ {
964
+ name: 'clear-history',
965
+ aliases: ['reset'],
966
+ description: 'Clear conversation history (keep config)',
967
+ type: 'builtin',
968
+ execute: (ctx) => handleClearHistory(ctx),
969
+ },
970
+ {
971
+ name: 'exit',
972
+ aliases: ['quit', 'q'],
973
+ description: 'Shutdown and exit',
974
+ type: 'builtin',
975
+ execute: (ctx) => handleExit(ctx),
976
+ },
977
+ // 成本/用量命令
978
+ {
979
+ name: 'cost',
980
+ description: 'Show session token usage',
981
+ type: 'builtin',
982
+ execute: (ctx) => handleCost(ctx),
983
+ },
984
+ {
985
+ name: 'usage',
986
+ aliases: ['stats'],
987
+ description: 'Show detailed usage statistics',
988
+ type: 'builtin',
989
+ execute: (ctx) => handleUsage(ctx),
990
+ },
991
+ // 配置命令
992
+ {
993
+ name: 'model',
994
+ description: 'Show or change the current model',
995
+ argumentHint: '[model|list|help]',
996
+ type: 'builtin',
997
+ execute: (ctx, args) => handleModel(ctx, args),
998
+ },
999
+ {
1000
+ name: 'config',
1001
+ description: 'Show current configuration',
1002
+ type: 'builtin',
1003
+ execute: (ctx) => showConfig(ctx),
1004
+ },
1005
+ // Agent/Harness 命令
1006
+ {
1007
+ name: 'agents',
1008
+ description: 'List registered agents and their status',
1009
+ type: 'builtin',
1010
+ execute: (ctx) => showAgents(ctx),
1011
+ },
1012
+ {
1013
+ name: 'memory',
1014
+ description: 'Show memory status, or `/memory reindex` to rebuild semantic index',
1015
+ argumentHint: '[reindex]',
1016
+ type: 'builtin',
1017
+ execute: (ctx, args) => handleMemory(ctx, args),
1018
+ },
1019
+ {
1020
+ name: 'safety',
1021
+ description: 'Show safety checker status and audit summary',
1022
+ type: 'builtin',
1023
+ execute: (ctx) => showSafety(ctx),
1024
+ },
1025
+ {
1026
+ name: 'harness',
1027
+ description: 'Show harness configuration',
1028
+ type: 'builtin',
1029
+ execute: (ctx) => showHarness(ctx),
1030
+ },
1031
+ // Task 命令
1032
+ {
1033
+ name: 'task',
1034
+ description: 'Submit or list tasks',
1035
+ params: [{ name: 'action', description: 'list | <task-name>', required: false }],
1036
+ type: 'builtin',
1037
+ execute: (ctx, args) => handleTask(ctx, args),
1038
+ },
1039
+ {
1040
+ name: 'run',
1041
+ description: 'Create and run a task through Agent + LLM',
1042
+ params: [{ name: 'description', description: 'Task description', required: true }],
1043
+ type: 'builtin',
1044
+ execute: (ctx, args) => handleRun(ctx, args),
1045
+ },
1046
+ // Session 命令
1047
+ {
1048
+ name: 'sessions',
1049
+ description: 'List recent sessions',
1050
+ type: 'builtin',
1051
+ execute: (ctx) => handleSessions(ctx),
1052
+ },
1053
+ {
1054
+ name: 'resume',
1055
+ description: 'Resume a previous session',
1056
+ argumentHint: '[session-id]',
1057
+ type: 'builtin',
1058
+ execute: (ctx, args) => handleResume(ctx, args),
1059
+ },
1060
+ // MCP
1061
+ {
1062
+ name: 'mcp',
1063
+ description: 'Show connected MCP servers and their status',
1064
+ type: 'builtin',
1065
+ execute: (ctx) => handleMcp(ctx),
1066
+ },
1067
+ // Skills
1068
+ {
1069
+ name: 'skills',
1070
+ description: 'List loaded skills (built-in / user / project)',
1071
+ type: 'builtin',
1072
+ execute: (ctx) => handleSkills(ctx),
1073
+ },
1074
+ // Chat 命令
1075
+ {
1076
+ name: 'chat',
1077
+ description: 'Send a message to the LLM',
1078
+ params: [{ name: 'message', description: 'Message to send', required: true }],
1079
+ type: 'chat',
1080
+ execute: (ctx, args) => ({ success: true, continueAsChat: true, chatInput: args }),
1081
+ },
1082
+ ];
1083
+ // ============================================================================
1084
+ // 导出
1085
+ // ============================================================================
1086
+ function getCommands() {
1087
+ return COMMANDS;
1088
+ }
1089
+ function findCommand(name) {
1090
+ return COMMANDS.find(c => c.name === name || c.aliases?.includes(name));
1091
+ }
1092
+ function getCommandNames() {
1093
+ return COMMANDS.map(c => c.name);
1094
+ }
1095
+ //# sourceMappingURL=index.js.map