@pentoshi/clai 2.0.62 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (462) hide show
  1. package/README.md +262 -368
  2. package/dist/agent/context-manager.d.ts +5 -0
  3. package/dist/agent/context-manager.js +14 -2
  4. package/dist/agent/context-manager.js.map +1 -1
  5. package/dist/agent/events.d.ts +4 -1
  6. package/dist/agent/runner.js +150 -83
  7. package/dist/agent/runner.js.map +1 -1
  8. package/dist/agent/tool-call-parser.d.ts +15 -0
  9. package/dist/agent/tool-call-parser.js +171 -2
  10. package/dist/agent/tool-call-parser.js.map +1 -1
  11. package/dist/app/adapters/agent-event-adapter.d.ts +29 -0
  12. package/dist/app/adapters/agent-event-adapter.js +143 -0
  13. package/dist/app/adapters/agent-event-adapter.js.map +1 -0
  14. package/dist/app/adapters/current-agent-adapter.d.ts +7 -0
  15. package/dist/app/adapters/current-agent-adapter.js +27 -0
  16. package/dist/app/adapters/current-agent-adapter.js.map +1 -0
  17. package/dist/app/adapters/current-jobs-adapter.d.ts +4 -0
  18. package/dist/app/adapters/current-jobs-adapter.js +13 -0
  19. package/dist/app/adapters/current-jobs-adapter.js.map +1 -0
  20. package/dist/app/adapters/current-store-adapter.d.ts +3 -0
  21. package/dist/app/adapters/current-store-adapter.js +22 -0
  22. package/dist/app/adapters/current-store-adapter.js.map +1 -0
  23. package/dist/app/adapters/current-terminal-adapter.d.ts +9 -0
  24. package/dist/app/adapters/current-terminal-adapter.js +31 -0
  25. package/dist/app/adapters/current-terminal-adapter.js.map +1 -0
  26. package/dist/app/adapters/current-updates-adapter.d.ts +7 -0
  27. package/dist/app/adapters/current-updates-adapter.js +31 -0
  28. package/dist/app/adapters/current-updates-adapter.js.map +1 -0
  29. package/dist/app/adapters/in-memory-clipboard-adapter.d.ts +10 -0
  30. package/dist/app/adapters/in-memory-clipboard-adapter.js +20 -0
  31. package/dist/app/adapters/in-memory-clipboard-adapter.js.map +1 -0
  32. package/dist/app/commands/command.d.ts +24 -0
  33. package/dist/app/commands/command.js +4 -0
  34. package/dist/app/commands/command.js.map +1 -0
  35. package/dist/app/commands/registry.d.ts +45 -0
  36. package/dist/app/commands/registry.js +164 -0
  37. package/dist/app/commands/registry.js.map +1 -0
  38. package/dist/app/controllers/disposable.d.ts +15 -0
  39. package/dist/app/controllers/disposable.js +38 -0
  40. package/dist/app/controllers/disposable.js.map +1 -0
  41. package/dist/app/controllers/job-controller.d.ts +22 -0
  42. package/dist/app/controllers/job-controller.js +35 -0
  43. package/dist/app/controllers/job-controller.js.map +1 -0
  44. package/dist/app/controllers/plan-controller.d.ts +31 -0
  45. package/dist/app/controllers/plan-controller.js +69 -0
  46. package/dist/app/controllers/plan-controller.js.map +1 -0
  47. package/dist/app/controllers/session-controller.d.ts +167 -0
  48. package/dist/app/controllers/session-controller.js +467 -0
  49. package/dist/app/controllers/session-controller.js.map +1 -0
  50. package/dist/app/controllers/turn-controller.d.ts +52 -0
  51. package/dist/app/controllers/turn-controller.js +118 -0
  52. package/dist/app/controllers/turn-controller.js.map +1 -0
  53. package/dist/app/events/app-event.d.ts +118 -0
  54. package/dist/app/events/app-event.js +25 -0
  55. package/dist/app/events/app-event.js.map +1 -0
  56. package/dist/app/events/event-buffer.d.ts +51 -0
  57. package/dist/app/events/event-buffer.js +109 -0
  58. package/dist/app/events/event-buffer.js.map +1 -0
  59. package/dist/app/events/sequencer.d.ts +32 -0
  60. package/dist/app/events/sequencer.js +55 -0
  61. package/dist/app/events/sequencer.js.map +1 -0
  62. package/dist/app/ports/agent-port.d.ts +29 -0
  63. package/dist/app/ports/agent-port.js +2 -0
  64. package/dist/app/ports/agent-port.js.map +1 -0
  65. package/dist/app/ports/clipboard-port.d.ts +9 -0
  66. package/dist/app/ports/clipboard-port.js +2 -0
  67. package/dist/app/ports/clipboard-port.js.map +1 -0
  68. package/dist/app/ports/confirm-port.d.ts +17 -0
  69. package/dist/app/ports/confirm-port.js +2 -0
  70. package/dist/app/ports/confirm-port.js.map +1 -0
  71. package/dist/app/ports/jobs-port.d.ts +18 -0
  72. package/dist/app/ports/jobs-port.js +2 -0
  73. package/dist/app/ports/jobs-port.js.map +1 -0
  74. package/dist/app/ports/persistence-port.d.ts +21 -0
  75. package/dist/app/ports/persistence-port.js +2 -0
  76. package/dist/app/ports/persistence-port.js.map +1 -0
  77. package/dist/app/ports/secret-port.d.ts +12 -0
  78. package/dist/app/ports/secret-port.js +2 -0
  79. package/dist/app/ports/secret-port.js.map +1 -0
  80. package/dist/app/ports/terminal-port.d.ts +18 -0
  81. package/dist/app/ports/terminal-port.js +2 -0
  82. package/dist/app/ports/terminal-port.js.map +1 -0
  83. package/dist/app/ports/updates-port.d.ts +12 -0
  84. package/dist/app/ports/updates-port.js +2 -0
  85. package/dist/app/ports/updates-port.js.map +1 -0
  86. package/dist/commands/doctor.js +9 -0
  87. package/dist/commands/doctor.js.map +1 -1
  88. package/dist/commands/update.js +1 -1
  89. package/dist/commands/update.js.map +1 -1
  90. package/dist/index.js +9 -6
  91. package/dist/index.js.map +1 -1
  92. package/dist/llm/router.js +4 -2
  93. package/dist/llm/router.js.map +1 -1
  94. package/dist/prompts/index.d.ts +1 -1
  95. package/dist/prompts/index.js +5 -3
  96. package/dist/prompts/index.js.map +1 -1
  97. package/dist/repl/slash-commands.js +1 -1
  98. package/dist/repl/slash-commands.js.map +1 -1
  99. package/dist/repl.js +35 -107
  100. package/dist/repl.js.map +1 -1
  101. package/dist/store/config.js +3 -1
  102. package/dist/store/config.js.map +1 -1
  103. package/dist/store/history.d.ts +26 -2
  104. package/dist/store/history.js +383 -72
  105. package/dist/store/history.js.map +1 -1
  106. package/dist/store/logs.js +3 -3
  107. package/dist/store/logs.js.map +1 -1
  108. package/dist/store/paths.d.ts +6 -0
  109. package/dist/store/paths.js +38 -0
  110. package/dist/store/paths.js.map +1 -0
  111. package/dist/store/plan.js +8 -5
  112. package/dist/store/plan.js.map +1 -1
  113. package/dist/tools/jobs.js +2 -2
  114. package/dist/tools/jobs.js.map +1 -1
  115. package/dist/tools/registry.js +117 -46
  116. package/dist/tools/registry.js.map +1 -1
  117. package/dist/tools/shell.js +2 -2
  118. package/dist/tools/shell.js.map +1 -1
  119. package/dist/tui/state.js +20 -17
  120. package/dist/tui/state.js.map +1 -1
  121. package/dist/tui-v2/actions/action-id.d.ts +14 -0
  122. package/dist/tui-v2/actions/action-id.js +109 -0
  123. package/dist/tui-v2/actions/action-id.js.map +1 -0
  124. package/dist/tui-v2/actions/action-router.d.ts +18 -0
  125. package/dist/tui-v2/actions/action-router.js +62 -0
  126. package/dist/tui-v2/actions/action-router.js.map +1 -0
  127. package/dist/tui-v2/actions/chord-from-key.d.ts +26 -0
  128. package/dist/tui-v2/actions/chord-from-key.js +45 -0
  129. package/dist/tui-v2/actions/chord-from-key.js.map +1 -0
  130. package/dist/tui-v2/actions/keymap.d.ts +24 -0
  131. package/dist/tui-v2/actions/keymap.js +134 -0
  132. package/dist/tui-v2/actions/keymap.js.map +1 -0
  133. package/dist/tui-v2/app/App.d.ts +13 -0
  134. package/dist/tui-v2/app/App.js +320 -0
  135. package/dist/tui-v2/app/App.js.map +1 -0
  136. package/dist/tui-v2/app/command-handlers.d.ts +8 -0
  137. package/dist/tui-v2/app/command-handlers.js +66 -0
  138. package/dist/tui-v2/app/command-handlers.js.map +1 -0
  139. package/dist/tui-v2/app/commands/config-commands.d.ts +14 -0
  140. package/dist/tui-v2/app/commands/config-commands.js +161 -0
  141. package/dist/tui-v2/app/commands/config-commands.js.map +1 -0
  142. package/dist/tui-v2/app/commands/key-commands.d.ts +9 -0
  143. package/dist/tui-v2/app/commands/key-commands.js +263 -0
  144. package/dist/tui-v2/app/commands/key-commands.js.map +1 -0
  145. package/dist/tui-v2/app/commands/picker-commands.d.ts +24 -0
  146. package/dist/tui-v2/app/commands/picker-commands.js +423 -0
  147. package/dist/tui-v2/app/commands/picker-commands.js.map +1 -0
  148. package/dist/tui-v2/app/commands/session-commands.d.ts +19 -0
  149. package/dist/tui-v2/app/commands/session-commands.js +162 -0
  150. package/dist/tui-v2/app/commands/session-commands.js.map +1 -0
  151. package/dist/tui-v2/app/plan-lifecycle.d.ts +16 -0
  152. package/dist/tui-v2/app/plan-lifecycle.js +59 -0
  153. package/dist/tui-v2/app/plan-lifecycle.js.map +1 -0
  154. package/dist/tui-v2/app/providers.d.ts +17 -0
  155. package/dist/tui-v2/app/providers.js +32 -0
  156. package/dist/tui-v2/app/providers.js.map +1 -0
  157. package/dist/tui-v2/bootstrap/capabilities.d.ts +35 -0
  158. package/dist/tui-v2/bootstrap/capabilities.js +93 -0
  159. package/dist/tui-v2/bootstrap/capabilities.js.map +1 -0
  160. package/dist/tui-v2/bootstrap/composition-root.d.ts +85 -0
  161. package/dist/tui-v2/bootstrap/composition-root.js +131 -0
  162. package/dist/tui-v2/bootstrap/composition-root.js.map +1 -0
  163. package/dist/tui-v2/bootstrap/disable-native-selection.d.ts +11 -0
  164. package/dist/tui-v2/bootstrap/disable-native-selection.js +13 -0
  165. package/dist/tui-v2/bootstrap/disable-native-selection.js.map +1 -0
  166. package/dist/tui-v2/bootstrap/lifecycle.d.ts +62 -0
  167. package/dist/tui-v2/bootstrap/lifecycle.js +123 -0
  168. package/dist/tui-v2/bootstrap/lifecycle.js.map +1 -0
  169. package/dist/tui-v2/bootstrap/osc52-clipboard.d.ts +28 -0
  170. package/dist/tui-v2/bootstrap/osc52-clipboard.js +44 -0
  171. package/dist/tui-v2/bootstrap/osc52-clipboard.js.map +1 -0
  172. package/dist/tui-v2/bootstrap/overlay-ports.d.ts +12 -0
  173. package/dist/{tui/confirm.js → tui-v2/bootstrap/overlay-ports.js} +17 -25
  174. package/dist/tui-v2/bootstrap/overlay-ports.js.map +1 -0
  175. package/dist/tui-v2/bootstrap/pager-export.d.ts +24 -0
  176. package/dist/tui-v2/bootstrap/pager-export.js +87 -0
  177. package/dist/tui-v2/bootstrap/pager-export.js.map +1 -0
  178. package/dist/tui-v2/bootstrap/start-tui-v2.d.ts +15 -0
  179. package/dist/tui-v2/bootstrap/start-tui-v2.js +95 -0
  180. package/dist/tui-v2/bootstrap/start-tui-v2.js.map +1 -0
  181. package/dist/tui-v2/bootstrap/ui-selection.d.ts +30 -0
  182. package/dist/tui-v2/bootstrap/ui-selection.js +59 -0
  183. package/dist/tui-v2/bootstrap/ui-selection.js.map +1 -0
  184. package/dist/tui-v2/components/completion/completion-menu.d.ts +23 -0
  185. package/dist/tui-v2/components/completion/completion-menu.js +84 -0
  186. package/dist/tui-v2/components/completion/completion-menu.js.map +1 -0
  187. package/dist/tui-v2/components/jobs/jobs-panel.d.ts +16 -0
  188. package/dist/tui-v2/components/jobs/jobs-panel.js +92 -0
  189. package/dist/tui-v2/components/jobs/jobs-panel.js.map +1 -0
  190. package/dist/tui-v2/components/modal/confirm-modal.d.ts +21 -0
  191. package/dist/tui-v2/components/modal/confirm-modal.js +71 -0
  192. package/dist/tui-v2/components/modal/confirm-modal.js.map +1 -0
  193. package/dist/tui-v2/components/modal/prompt-actions-modal.d.ts +15 -0
  194. package/dist/tui-v2/components/modal/prompt-actions-modal.js +80 -0
  195. package/dist/tui-v2/components/modal/prompt-actions-modal.js.map +1 -0
  196. package/dist/tui-v2/components/modal/secret-modal.d.ts +24 -0
  197. package/dist/tui-v2/components/modal/secret-modal.js +50 -0
  198. package/dist/tui-v2/components/modal/secret-modal.js.map +1 -0
  199. package/dist/tui-v2/components/overlay/overlay-host.d.ts +17 -0
  200. package/dist/tui-v2/components/overlay/overlay-host.js +28 -0
  201. package/dist/tui-v2/components/overlay/overlay-host.js.map +1 -0
  202. package/dist/tui-v2/components/pager/pager.d.ts +20 -0
  203. package/dist/tui-v2/components/pager/pager.js +396 -0
  204. package/dist/tui-v2/components/pager/pager.js.map +1 -0
  205. package/dist/tui-v2/components/picker/picker.d.ts +17 -0
  206. package/dist/tui-v2/components/picker/picker.js +222 -0
  207. package/dist/tui-v2/components/picker/picker.js.map +1 -0
  208. package/dist/tui-v2/components/plan/plan-view.d.ts +20 -0
  209. package/dist/tui-v2/components/plan/plan-view.js +116 -0
  210. package/dist/tui-v2/components/plan/plan-view.js.map +1 -0
  211. package/dist/tui-v2/components/queue/queue-panel.d.ts +23 -0
  212. package/dist/tui-v2/components/queue/queue-panel.js +58 -0
  213. package/dist/tui-v2/components/queue/queue-panel.js.map +1 -0
  214. package/dist/tui-v2/components/status/status-line.d.ts +27 -0
  215. package/dist/tui-v2/components/status/status-line.js +158 -0
  216. package/dist/tui-v2/components/status/status-line.js.map +1 -0
  217. package/dist/tui-v2/components/toast/toast-host.d.ts +15 -0
  218. package/dist/tui-v2/components/toast/toast-host.js +48 -0
  219. package/dist/tui-v2/components/toast/toast-host.js.map +1 -0
  220. package/dist/tui-v2/components/transcript/assistant-message.d.ts +20 -0
  221. package/dist/tui-v2/components/transcript/assistant-message.js +35 -0
  222. package/dist/tui-v2/components/transcript/assistant-message.js.map +1 -0
  223. package/dist/tui-v2/components/transcript/compacted-row.d.ts +19 -0
  224. package/dist/tui-v2/components/transcript/compacted-row.js +94 -0
  225. package/dist/tui-v2/components/transcript/compacted-row.js.map +1 -0
  226. package/dist/tui-v2/components/transcript/intro-card.d.ts +19 -0
  227. package/dist/tui-v2/components/transcript/intro-card.js +50 -0
  228. package/dist/tui-v2/components/transcript/intro-card.js.map +1 -0
  229. package/dist/tui-v2/components/transcript/linkable-text.d.ts +21 -0
  230. package/dist/tui-v2/components/transcript/linkable-text.js +46 -0
  231. package/dist/tui-v2/components/transcript/linkable-text.js.map +1 -0
  232. package/dist/tui-v2/components/transcript/notice-row.d.ts +14 -0
  233. package/dist/tui-v2/components/transcript/notice-row.js +40 -0
  234. package/dist/tui-v2/components/transcript/notice-row.js.map +1 -0
  235. package/dist/tui-v2/components/transcript/search-bar.d.ts +19 -0
  236. package/dist/tui-v2/components/transcript/search-bar.js +7 -0
  237. package/dist/tui-v2/components/transcript/search-bar.js.map +1 -0
  238. package/dist/tui-v2/components/transcript/thinking-block.d.ts +22 -0
  239. package/dist/tui-v2/components/transcript/thinking-block.js +27 -0
  240. package/dist/tui-v2/components/transcript/thinking-block.js.map +1 -0
  241. package/dist/tui-v2/components/transcript/tool-card.d.ts +26 -0
  242. package/dist/tui-v2/components/transcript/tool-card.js +175 -0
  243. package/dist/tui-v2/components/transcript/tool-card.js.map +1 -0
  244. package/dist/tui-v2/components/transcript/transcript-row.d.ts +25 -0
  245. package/dist/tui-v2/components/transcript/transcript-row.js +30 -0
  246. package/dist/tui-v2/components/transcript/transcript-row.js.map +1 -0
  247. package/dist/tui-v2/components/transcript/transcript-scroll-port.d.ts +52 -0
  248. package/dist/tui-v2/components/transcript/transcript-scroll-port.js +86 -0
  249. package/dist/tui-v2/components/transcript/transcript-scroll-port.js.map +1 -0
  250. package/dist/tui-v2/components/transcript/transcript-view.d.ts +24 -0
  251. package/dist/tui-v2/components/transcript/transcript-view.js +403 -0
  252. package/dist/tui-v2/components/transcript/transcript-view.js.map +1 -0
  253. package/dist/tui-v2/components/transcript/use-click-without-drag.d.ts +13 -0
  254. package/dist/tui-v2/components/transcript/use-click-without-drag.js +35 -0
  255. package/dist/tui-v2/components/transcript/use-click-without-drag.js.map +1 -0
  256. package/dist/tui-v2/components/transcript/use-native-selection-copy.d.ts +10 -0
  257. package/dist/tui-v2/components/transcript/use-native-selection-copy.js +37 -0
  258. package/dist/tui-v2/components/transcript/use-native-selection-copy.js.map +1 -0
  259. package/dist/tui-v2/components/transcript/use-transcript-selection.d.ts +23 -0
  260. package/dist/tui-v2/components/transcript/use-transcript-selection.js +136 -0
  261. package/dist/tui-v2/components/transcript/use-transcript-selection.js.map +1 -0
  262. package/dist/tui-v2/components/transcript/user-message.d.ts +10 -0
  263. package/dist/tui-v2/components/transcript/user-message.js +23 -0
  264. package/dist/tui-v2/components/transcript/user-message.js.map +1 -0
  265. package/dist/tui-v2/composer/arrow-intent.d.ts +23 -0
  266. package/dist/tui-v2/composer/arrow-intent.js +35 -0
  267. package/dist/tui-v2/composer/arrow-intent.js.map +1 -0
  268. package/dist/tui-v2/composer/completion.d.ts +37 -0
  269. package/dist/tui-v2/composer/completion.js +67 -0
  270. package/dist/tui-v2/composer/completion.js.map +1 -0
  271. package/dist/tui-v2/composer/composer-editor.d.ts +33 -0
  272. package/dist/tui-v2/composer/composer-editor.js +620 -0
  273. package/dist/tui-v2/composer/composer-editor.js.map +1 -0
  274. package/dist/tui-v2/composer/composer-height.d.ts +21 -0
  275. package/dist/tui-v2/composer/composer-height.js +29 -0
  276. package/dist/tui-v2/composer/composer-height.js.map +1 -0
  277. package/dist/tui-v2/composer/composer-meta.d.ts +9 -0
  278. package/dist/tui-v2/composer/composer-meta.js +38 -0
  279. package/dist/tui-v2/composer/composer-meta.js.map +1 -0
  280. package/dist/tui-v2/composer/history-nav.d.ts +15 -0
  281. package/dist/tui-v2/composer/history-nav.js +16 -0
  282. package/dist/tui-v2/composer/history-nav.js.map +1 -0
  283. package/dist/tui-v2/composer/newline-hint.d.ts +13 -0
  284. package/dist/tui-v2/composer/newline-hint.js +13 -0
  285. package/dist/tui-v2/composer/newline-hint.js.map +1 -0
  286. package/dist/tui-v2/composer/paste-placeholder.d.ts +35 -0
  287. package/dist/tui-v2/composer/paste-placeholder.js +55 -0
  288. package/dist/tui-v2/composer/paste-placeholder.js.map +1 -0
  289. package/dist/tui-v2/composer/prompt-history.d.ts +22 -0
  290. package/dist/tui-v2/composer/prompt-history.js +51 -0
  291. package/dist/tui-v2/composer/prompt-history.js.map +1 -0
  292. package/dist/tui-v2/composer/secret-buffer.d.ts +20 -0
  293. package/dist/tui-v2/composer/secret-buffer.js +42 -0
  294. package/dist/tui-v2/composer/secret-buffer.js.map +1 -0
  295. package/dist/tui-v2/composer/textarea-keybindings.d.ts +22 -0
  296. package/dist/tui-v2/composer/textarea-keybindings.js +27 -0
  297. package/dist/tui-v2/composer/textarea-keybindings.js.map +1 -0
  298. package/dist/tui-v2/controllers/focus-controller.d.ts +30 -0
  299. package/dist/tui-v2/controllers/focus-controller.js +80 -0
  300. package/dist/tui-v2/controllers/focus-controller.js.map +1 -0
  301. package/dist/tui-v2/controllers/overlay-controller.d.ts +99 -0
  302. package/dist/tui-v2/controllers/overlay-controller.js +195 -0
  303. package/dist/tui-v2/controllers/overlay-controller.js.map +1 -0
  304. package/dist/tui-v2/controllers/selection-controller.d.ts +76 -0
  305. package/dist/tui-v2/controllers/selection-controller.js +238 -0
  306. package/dist/tui-v2/controllers/selection-controller.js.map +1 -0
  307. package/dist/tui-v2/controllers/toast-controller.d.ts +35 -0
  308. package/dist/tui-v2/controllers/toast-controller.js +88 -0
  309. package/dist/tui-v2/controllers/toast-controller.js.map +1 -0
  310. package/dist/tui-v2/layout/compute-layout.d.ts +59 -0
  311. package/dist/tui-v2/layout/compute-layout.js +170 -0
  312. package/dist/tui-v2/layout/compute-layout.js.map +1 -0
  313. package/dist/tui-v2/rendering/ansi-to-styled.d.ts +17 -0
  314. package/dist/tui-v2/rendering/ansi-to-styled.js +217 -0
  315. package/dist/tui-v2/rendering/ansi-to-styled.js.map +1 -0
  316. package/dist/tui-v2/rendering/batch-sections.d.ts +45 -0
  317. package/dist/tui-v2/rendering/batch-sections.js +109 -0
  318. package/dist/tui-v2/rendering/batch-sections.js.map +1 -0
  319. package/dist/tui-v2/rendering/link-detector.d.ts +16 -0
  320. package/dist/tui-v2/rendering/link-detector.js +43 -0
  321. package/dist/tui-v2/rendering/link-detector.js.map +1 -0
  322. package/dist/tui-v2/rendering/open-tool-output.d.ts +28 -0
  323. package/dist/tui-v2/rendering/open-tool-output.js +138 -0
  324. package/dist/tui-v2/rendering/open-tool-output.js.map +1 -0
  325. package/dist/tui-v2/rendering/picker-filter.d.ts +22 -0
  326. package/dist/tui-v2/rendering/picker-filter.js +68 -0
  327. package/dist/tui-v2/rendering/picker-filter.js.map +1 -0
  328. package/dist/tui-v2/rendering/plan-view.d.ts +32 -0
  329. package/dist/tui-v2/rendering/plan-view.js +196 -0
  330. package/dist/tui-v2/rendering/plan-view.js.map +1 -0
  331. package/dist/tui-v2/rendering/render-markdown-lines.d.ts +29 -0
  332. package/dist/tui-v2/rendering/render-markdown-lines.js +46 -0
  333. package/dist/tui-v2/rendering/render-markdown-lines.js.map +1 -0
  334. package/dist/tui-v2/rendering/sanitize-display.d.ts +13 -0
  335. package/dist/tui-v2/rendering/sanitize-display.js +24 -0
  336. package/dist/tui-v2/rendering/sanitize-display.js.map +1 -0
  337. package/dist/tui-v2/rendering/theme.d.ts +67 -0
  338. package/dist/tui-v2/rendering/theme.js +74 -0
  339. package/dist/tui-v2/rendering/theme.js.map +1 -0
  340. package/dist/tui-v2/rendering/tool-presenter.d.ts +39 -0
  341. package/dist/tui-v2/rendering/tool-presenter.js +207 -0
  342. package/dist/tui-v2/rendering/tool-presenter.js.map +1 -0
  343. package/dist/tui-v2/rendering/transcript-export.d.ts +11 -0
  344. package/dist/tui-v2/rendering/transcript-export.js +18 -0
  345. package/dist/tui-v2/rendering/transcript-export.js.map +1 -0
  346. package/dist/tui-v2/rendering/transcript-semantic.d.ts +17 -0
  347. package/dist/tui-v2/rendering/transcript-semantic.js +67 -0
  348. package/dist/tui-v2/rendering/transcript-semantic.js.map +1 -0
  349. package/dist/tui-v2/state/pager-search.d.ts +22 -0
  350. package/dist/tui-v2/state/pager-search.js +78 -0
  351. package/dist/tui-v2/state/pager-search.js.map +1 -0
  352. package/dist/tui-v2/state/semantic-document.d.ts +34 -0
  353. package/dist/tui-v2/state/semantic-document.js +201 -0
  354. package/dist/tui-v2/state/semantic-document.js.map +1 -0
  355. package/dist/tui-v2/state/transcript-compaction.d.ts +24 -0
  356. package/dist/tui-v2/state/transcript-compaction.js +79 -0
  357. package/dist/tui-v2/state/transcript-compaction.js.map +1 -0
  358. package/dist/tui-v2/state/transcript-hydrate.d.ts +27 -0
  359. package/dist/tui-v2/state/transcript-hydrate.js +272 -0
  360. package/dist/tui-v2/state/transcript-hydrate.js.map +1 -0
  361. package/dist/tui-v2/state/transcript-reducer.d.ts +10 -0
  362. package/dist/tui-v2/state/transcript-reducer.js +281 -0
  363. package/dist/tui-v2/state/transcript-reducer.js.map +1 -0
  364. package/dist/tui-v2/state/transcript-search.d.ts +17 -0
  365. package/dist/tui-v2/state/transcript-search.js +38 -0
  366. package/dist/tui-v2/state/transcript-search.js.map +1 -0
  367. package/dist/tui-v2/state/transcript-store.d.ts +32 -0
  368. package/dist/tui-v2/state/transcript-store.js +66 -0
  369. package/dist/tui-v2/state/transcript-store.js.map +1 -0
  370. package/dist/tui-v2/state/transcript-struct.d.ts +15 -0
  371. package/dist/tui-v2/state/transcript-struct.js +133 -0
  372. package/dist/tui-v2/state/transcript-struct.js.map +1 -0
  373. package/dist/tui-v2/state/transcript-types.d.ts +76 -0
  374. package/dist/tui-v2/state/transcript-types.js +65 -0
  375. package/dist/tui-v2/state/transcript-types.js.map +1 -0
  376. package/dist/tui-v2/state/use-overlay.d.ts +3 -0
  377. package/dist/tui-v2/state/use-overlay.js +6 -0
  378. package/dist/tui-v2/state/use-overlay.js.map +1 -0
  379. package/dist/tui-v2/state/use-plan.d.ts +4 -0
  380. package/dist/tui-v2/state/use-plan.js +6 -0
  381. package/dist/tui-v2/state/use-plan.js.map +1 -0
  382. package/dist/tui-v2/state/use-session-state.d.ts +2 -0
  383. package/dist/tui-v2/state/use-session-state.js +7 -0
  384. package/dist/tui-v2/state/use-session-state.js.map +1 -0
  385. package/dist/tui-v2/state/use-toast.d.ts +3 -0
  386. package/dist/tui-v2/state/use-toast.js +15 -0
  387. package/dist/tui-v2/state/use-toast.js.map +1 -0
  388. package/dist/tui-v2/state/use-transcript-store.d.ts +10 -0
  389. package/dist/tui-v2/state/use-transcript-store.js +12 -0
  390. package/dist/tui-v2/state/use-transcript-store.js.map +1 -0
  391. package/dist/ui/intro-card.js +3 -3
  392. package/dist/ui/intro-card.js.map +1 -1
  393. package/dist/ui/intro-header.d.ts +23 -0
  394. package/dist/ui/intro-header.js +232 -0
  395. package/dist/ui/intro-header.js.map +1 -0
  396. package/dist/ui/markdown.js +0 -1
  397. package/dist/ui/markdown.js.map +1 -1
  398. package/dist/ui/mentions.d.ts +9 -2
  399. package/dist/ui/mentions.js +102 -4
  400. package/dist/ui/mentions.js.map +1 -1
  401. package/dist/ui/output-pane.js +1 -1
  402. package/dist/ui/output-pane.js.map +1 -1
  403. package/dist/ui/plan-pane.d.ts +8 -0
  404. package/dist/ui/plan-pane.js +38 -0
  405. package/dist/ui/plan-pane.js.map +1 -1
  406. package/dist/ui/wordmark.d.ts +5 -0
  407. package/dist/ui/wordmark.js +6 -1
  408. package/dist/ui/wordmark.js.map +1 -1
  409. package/package.json +14 -10
  410. package/dist/tui/App.d.ts +0 -12
  411. package/dist/tui/App.js +0 -2174
  412. package/dist/tui/App.js.map +0 -1
  413. package/dist/tui/components/ConfirmModal.d.ts +0 -9
  414. package/dist/tui/components/ConfirmModal.js +0 -55
  415. package/dist/tui/components/ConfirmModal.js.map +0 -1
  416. package/dist/tui/components/JobsPanel.d.ts +0 -11
  417. package/dist/tui/components/JobsPanel.js +0 -55
  418. package/dist/tui/components/JobsPanel.js.map +0 -1
  419. package/dist/tui/components/Pager.d.ts +0 -14
  420. package/dist/tui/components/Pager.js +0 -56
  421. package/dist/tui/components/Pager.js.map +0 -1
  422. package/dist/tui/components/PickerPanel.d.ts +0 -15
  423. package/dist/tui/components/PickerPanel.js +0 -126
  424. package/dist/tui/components/PickerPanel.js.map +0 -1
  425. package/dist/tui/components/PlanSidebar.d.ts +0 -6
  426. package/dist/tui/components/PlanSidebar.js +0 -99
  427. package/dist/tui/components/PlanSidebar.js.map +0 -1
  428. package/dist/tui/components/SecretInputPanel.d.ts +0 -7
  429. package/dist/tui/components/SecretInputPanel.js +0 -38
  430. package/dist/tui/components/SecretInputPanel.js.map +0 -1
  431. package/dist/tui/confirm.d.ts +0 -16
  432. package/dist/tui/confirm.js.map +0 -1
  433. package/dist/tui/default.d.ts +0 -6
  434. package/dist/tui/default.js +0 -11
  435. package/dist/tui/default.js.map +0 -1
  436. package/dist/tui/hooks/useAgentRunner.d.ts +0 -73
  437. package/dist/tui/hooks/useAgentRunner.js +0 -277
  438. package/dist/tui/hooks/useAgentRunner.js.map +0 -1
  439. package/dist/tui/hooks/useJobs.d.ts +0 -7
  440. package/dist/tui/hooks/useJobs.js +0 -39
  441. package/dist/tui/hooks/useJobs.js.map +0 -1
  442. package/dist/tui/hooks/useSpinner.d.ts +0 -5
  443. package/dist/tui/hooks/useSpinner.js +0 -21
  444. package/dist/tui/hooks/useSpinner.js.map +0 -1
  445. package/dist/tui/hooks/useTerminalSize.d.ts +0 -9
  446. package/dist/tui/hooks/useTerminalSize.js +0 -26
  447. package/dist/tui/hooks/useTerminalSize.js.map +0 -1
  448. package/dist/tui/index.d.ts +0 -10
  449. package/dist/tui/index.js +0 -37
  450. package/dist/tui/index.js.map +0 -1
  451. package/dist/tui/key-intent.d.ts +0 -36
  452. package/dist/tui/key-intent.js +0 -54
  453. package/dist/tui/key-intent.js.map +0 -1
  454. package/dist/tui/mouse.d.ts +0 -8
  455. package/dist/tui/mouse.js +0 -34
  456. package/dist/tui/mouse.js.map +0 -1
  457. package/dist/tui/plan-sidebar-lines.d.ts +0 -2
  458. package/dist/tui/plan-sidebar-lines.js +0 -140
  459. package/dist/tui/plan-sidebar-lines.js.map +0 -1
  460. package/dist/tui/render-lines.d.ts +0 -22
  461. package/dist/tui/render-lines.js +0 -611
  462. package/dist/tui/render-lines.js.map +0 -1
package/README.md CHANGED
@@ -1,17 +1,51 @@
1
1
  # clai
2
2
 
3
- > A fast, cross-platform AI CLI assistant with `/ask` and `/agent` modes for general shell tasks, file operations, and cybersecurity / pentesting workflows. Free to build, free to run.
3
+ > **Offensive-security agent in your terminal** recon, enumerate, exploit, and report with an approve-before-run plan workflow. Also a strong coding/sysadmin agent for shell and files. Free to build, free to run.
4
+
5
+ clai is an AI **agent CLI** built for people who break (and fix) systems: authorized pentests, red-team style workflows, CTFs, report verification, and day-to-day security engineering. It runs real tools (`nmap`, `ffuf`, `sqlmap`, `http` evidence capture, …), keeps a **durable engagement plan**, and never pretends a finding is real without tool output to back it up.
6
+
7
+ It also builds software and runs shell/file workflows when that is the job — same agent, same safety gate, same UI.
8
+
9
+ ---
10
+
11
+ ## Why clai for pentesting?
12
+
13
+ | Pain | What clai does |
14
+ |------|----------------|
15
+ | Chatbots that only *describe* scans | **Runs** recon, fuzzers, and PoCs via shell + dedicated tools |
16
+ | Long engagements lose the thread | **Session plan** + task checklist survives compaction and reloads from history |
17
+ | Spray-and-pray tooling | **Stack fingerprint first**, then stack-matched wordlists and vectors |
18
+ | Noisy full dumps fill context | **High-signal tool use**, artifacts for long output, expandable cards |
19
+ | Unscoped scanning | **Authorize once**, optional **engagement scope**, confirm on mutating work |
20
+ | “AI said vulnerable” without evidence | Findings require **command + real output**; report-style structure encouraged |
21
+
22
+ ### Engagement shape (built into the agent)
23
+
24
+ ```
25
+ recon / discovery → fingerprint stack → plan.create (kind=pentest)
26
+ ↑ │
27
+ │ /implement (approve)
28
+ │ ↓
29
+ └──── enumerate → exploit → post-ex → report
30
+ (revise plan as surface grows; keep completed tasks)
31
+ ```
32
+
33
+ 1. **Recon first** (whois, DNS, `net.context`, `net.scan`, `http.fetch`, `pentest.recon`, …) — read-only discovery does **not** need a plan yet.
34
+ 2. **Analyze evidence**, then **`plan.create`** with `kind=pentest` from real ports/services/endpoints/weaknesses — then **stop**.
35
+ 3. You **`/implement`**, refine in chat, or **`/discard`**.
36
+ 4. Execute task-by-task with **`task.update`**; expand the plan when new surface appears without wiping done work.
37
+
38
+ Non-destructive by default: prove issues with the least invasive evidence (reflected values, auth bypass PoCs, `whoami` after a shell). Destructive impact only when you explicitly ask.
39
+
40
+ ---
4
41
 
5
42
  ## Installation
6
43
 
7
44
  ### macOS
8
45
 
9
46
  ```sh
10
- # Homebrew (recommended)
11
- brew tap pentoshi007/clai
12
- brew install clai
13
-
14
- # or via curl
47
+ brew tap pentoshi007/clai && brew install clai
48
+ # or
15
49
  curl -fsSL https://raw.githubusercontent.com/pentoshi007/clai/main/install/install.sh | sh
16
50
  ```
17
51
 
@@ -24,458 +58,318 @@ curl -fsSL https://raw.githubusercontent.com/pentoshi007/clai/main/install/insta
24
58
  ### Windows
25
59
 
26
60
  ```powershell
27
- # PowerShell (recommended)
28
61
  irm https://raw.githubusercontent.com/pentoshi007/clai/main/install/install.ps1 | iex
29
-
30
- # or Scoop
31
- scoop bucket add clai https://github.com/pentoshi007/clai
32
- scoop install clai
62
+ # or: scoop bucket add clai https://github.com/pentoshi007/clai && scoop install clai
33
63
  ```
34
64
 
35
- ### Any OS (via npm)
65
+ ### npm / from source
36
66
 
37
67
  ```sh
38
68
  npm i -g @pentoshi/clai
39
- ```
40
-
41
- ### From Source
42
69
 
43
- ```sh
70
+ # or
44
71
  git clone https://github.com/pentoshi007/clai.git
45
- cd clai && npm install && npm run dev
72
+ cd clai && npm install && npm run build && npm start
46
73
  ```
47
74
 
48
- After installing, type `clai` in any terminal to start.
75
+ Type `clai` in any terminal to start.
76
+
77
+ ---
49
78
 
50
- ## Quick Start
79
+ ## Quick start (security)
51
80
 
52
81
  ```sh
53
- # Open the full-screen terminal UI (default)
82
+ # Full-screen agent UI
54
83
  clai
55
84
 
56
- # Frontend selection
57
- clai --tui # explicitly request the TUI
58
- clai --classic # start the legacy line-based REPL
59
- CLAI_CLASSIC=1 clai # persistent shell-level opt-out (CLAI_TUI=0 also works)
85
+ # Authorize offensive tools for this machine (once)
86
+ clai authorize-pentest AGREE
60
87
 
61
- # One-shot ask mode (explains but doesn't execute)
62
- clai --mode ask "how to create a python venv and install requests"
88
+ # Optional: remember engagement boundaries
89
+ clai scope add --targets lab.example.com,10.10.0.0/24
63
90
 
64
- # One-shot agent mode (executes)
65
- clai --mode agent "find all PDFs larger than 10MB in ~/Documents"
91
+ # One-shot agent against an in-scope target
92
+ clai --mode agent "recon lab.example.com open ports, stack, and interesting endpoints"
66
93
 
67
- # Auto-confirm tool execution
68
- clai -y "list the 10 largest files in my home directory"
94
+ # Ask mode: methodology / commands only, no execution
95
+ clai --mode ask "how would you enum an internal AD lab from a foothold?"
69
96
  ```
70
97
 
71
- ### Terminal UI
72
-
73
- `clai` launches the full-screen interface by default. It uses the same agent as
74
- the legacy REPL, with a persistent composer, streaming responses, live tool
75
- cards, searchable pickers, secure credential/password prompts, and restorable
76
- session transcripts. Use `clai --classic` when a line-based interface is
77
- required.
78
-
79
- In the TUI:
80
-
81
- - Type to chat; `Enter` sends. While the agent works you can keep typing — the
82
- message is queued and sent when the turn finishes.
83
- - `/` opens the command menu (`/ask`, `/agent`, `/model <name>`,
84
- `/provider <name>`, `/implement`, `/plan`, `/jobs`, `/output`, `/clear`,
85
- `/think`, `/cwd`, `/allow`, `/context`, `/compact`, `/save`, `/help`, …).
86
- - `@path` attaches files (and images on vision-capable models).
87
- - `Esc` cancels the running turn · `Ctrl+T` expand/collapse thinking ·
88
- `Ctrl+O` view full tool output · `Ctrl+P` view the plan · `Ctrl+J` jobs panel
89
- · `Ctrl+C` twice to exit.
90
- - `Up`/`Down` browse submitted prompts; reaching the newest entry restores the
91
- draft. Use `PageUp`/`PageDown` or `Ctrl+U`/`Ctrl+D` to scroll the transcript.
92
- - Provider, model, variant, and history pickers filter as you type.
93
- - `/compact` shows active progress and asks the selected model to turn the full
94
- session—prompts, reasoning, plans, commands, outputs, results, completed
95
- tasks, failures, and remaining work—into compact continuation memory. That
96
- memory replaces older model context while the eight newest messages remain
97
- verbatim. If the provider is unavailable, a local deterministic fallback is
98
- used.
99
- - `/history` restores user prompts, assistant responses, thinking, tool calls,
100
- and tool outputs for sessions saved by v1.2.9 or newer.
101
-
102
- If the terminal is not interactive or is too small, clai falls back to the
103
- classic REPL automatically.
104
-
105
- ## Features
106
-
107
- - **`/ask` mode** — Read-only. AI explains, gives commands & step-by-step guidance, but does NOT execute anything.
108
- - **`/agent` mode** — Agentic. AI plans, waits for approval, then executes shell commands, edits files, installs missing tools, parses output, and continues until the goal is met. Tasks run on an approve/refine/discard plan workflow (`/implement`, free-text to refine, `/discard` to cancel).
109
- - **12 LLM providers** — Groq, Google Gemini, OpenRouter, OpenAI, Anthropic, NVIDIA NIM, AgentRouter, Kimchi, AWS Mantle, Ollama (local), Bynara, and Qwen Cloud. All with streaming.
110
- - **10 built-in tools** — `shell.exec`, `fs.read`, `fs.write`, `fs.list`, `fs.search`, `pkg.install`, `net.scan`, `http.fetch`, `sysinfo`, `pentest.recon`.
111
- - **Smart safety gate** — Read-only commands auto-execute; mutating commands require confirmation; destructive patterns are blocked.
112
- - **OS-aware & tool-frugal** — Picks the best approach for your OS, prefers tools already installed (installs only when nothing suitable exists), broadens its approach and escalates privileges as needed to finish the task.
113
- - **Cross-platform** — macOS, Linux, and Windows. Detects OS-native package managers (brew, apt, dnf, pacman, winget, choco).
114
- - **Pentest-aware** — nmap, nikto, sqlmap, gobuster, ffuf, hydra, masscan, whois, dig, netcat, tshark.
115
- - **Auto-update** — Checks for new versions on startup; run `/update` or `clai update` to upgrade.
116
- - **Persistent history** — Full transcript restoration with automatic secret
117
- redaction, including thinking and tool activity.
118
- - **Context compaction** — Model-generated continuation memory with recent-turn
119
- preservation and an offline fallback.
120
- - **Modern terminal UI by default** — Boxed session header, searchable pickers,
121
- cancellable tools, secure prompts, full-output pager, and queued messages.
122
-
123
- ## Provider Setup
124
-
125
- clai supports 12 LLM providers (9 with free tiers):
126
-
127
- | Provider | Default Model | Free? | API Key Prefix |
128
- |-------------|----------------------------------------------|-------|----------------|
129
- | Groq | `llama-3.3-70b-versatile` | ✓ | `gsk_` |
130
- | Gemini | `gemini-2.0-flash` | ✓ | `AIza` |
131
- | OpenRouter | `meta-llama/llama-3.3-70b-instruct:free` | ✓ | `sk-or-` |
132
- | OpenAI | `gpt-4o-mini` | — | `sk-` |
133
- | Anthropic | `claude-3-5-haiku-latest` | — | `sk-ant-` |
134
- | NVIDIA NIM | `openai/gpt-oss-20b` | ✓ | `nvapi-` |
135
- | AgentRouter | `gpt-5` | — | `sk-` |
136
- | Kimchi | `kimi-k2.6` | ✓ | (any) |
137
- | AWS Mantle | `anthropic.claude-haiku-4-5` | — | `sk-ant-` |
138
- | Ollama | `llama3.1:8b` | ✓ | (local URL) |
139
- | Bynara | `mimo-v2.5-free` | ✓ | `sk_nry_` |
140
- | Qwen Cloud | `qwen3.7-plus` | — | `sk-` |
98
+ Inside a session:
141
99
 
142
- ```sh
143
- # Store an API key
144
- clai set groq gsk_xxxxxxxxxxxxxxxx
100
+ ```text
101
+ > recon app.lab.local and map the attack surface
102
+ agent runs whois/dns/nmap/http evidence …
103
+ … plan.create (pentest checklist) …
104
+ > /implement
105
+ … tasks execute with live plan pane (Ctrl+H) …
106
+ > verify the IDOR on /api/v1/orders/{id} with a low-impact PoC
107
+ ```
145
108
 
146
- # Import from environment variable
147
- clai set gemini --from-env GEMINI_API_KEY
109
+ ---
148
110
 
149
- # Read from stdin (safer — avoids shell history)
150
- echo "gsk_xxx" | clai set groq --stdin
111
+ ## Security & pentest capabilities
151
112
 
152
- # Set Ollama endpoint
153
- clai set ollama --url http://localhost:11434
113
+ ### Tools that matter for engagements
154
114
 
155
- # List configured providers (keys masked)
156
- clai keys
157
-
158
- # Switch active provider
159
- clai use groq
115
+ | Area | What you get |
116
+ |------|----------------|
117
+ | **Network** | `net.scan` (nmap wrapper, SYN with privilege / TCP fallback), `net.context`, `net.pingSweep`, `pentest.recon` (whois + dig + top ports) |
118
+ | **HTTP evidence** | `http.fetch` — status, headers, cookies, TLS, body for **raw protocol / pentest** work (not casual page reading) |
119
+ | **Web reading / OSINT** | `web.search`, `web.fetch` (readable pages), plus shell for specialized CLIs |
120
+ | **Discovery** | `tool.check`, `pkg.install`, `wordlist.find` — install only what is missing; locate wordlists per OS (no Kali-only path guesses) |
121
+ | **DNS / ownership** | `dns.lookup`, `whois.lookup` for narrow questions |
122
+ | **Shell** | Full toolbox: `nmap`, `ffuf`, `gobuster`, `feroxbuster`, `sqlmap`, `hydra`, `nikto`, `masscan`, `nuclei`, `tshark`, … via `shell.exec` |
123
+ | **Jobs** | Long scanners/listeners as background jobs (`shell.start` / `/jobs` / `Ctrl+J`) |
124
+ | **Reporting** | Markdown tables, artifact paths for long scans, structured finding style (title, severity, evidence, repro, impact, remediations) |
160
125
 
161
- # Interactive provider picker
162
- clai provider
126
+ ### Methodology the agent is steered toward
163
127
 
164
- # Remove a key
165
- clai unset groq
166
- ```
128
+ - **Recon fingerprint → enumerate → exploit → post-ex → report**
129
+ - **Tech stack from real headers/body** before directory fuzz or exploit choice (Next.js ≠ PHP wordlists)
130
+ - **Fuzz, don’t guess** — one bounded content-discovery pass with filters, not dozens of blind `http.fetch` paths
131
+ - **Enumerate before exploit**; match vectors to the stack
132
+ - **Verify from tool output** — no fabricated banners or fake CVE hits
133
+ - **Scope discipline** — flag out-of-scope hosts; keep authorized targets as the boundary
167
134
 
168
- ### Environment Variable Overrides
135
+ ### Authorization & safety gate
169
136
 
170
- Runtime env vars override stored keys:
137
+ clai assumes **you** own authorization. The product still gates risk:
171
138
 
172
139
  ```sh
173
- export GROQ_API_KEY=gsk_...
174
- export GEMINI_API_KEY=AIza...
175
- export OPENROUTER_API_KEY=sk-or-...
176
- export OPENAI_API_KEY=sk-...
177
- export ANTHROPIC_API_KEY=sk-ant-...
178
- export NVIDIA_API_KEY=nvapi-...
179
- export CASTAI_API_KEY=...
180
- export ANTHROPIC_WORKSPACE_ID=default # optional, for AWS Mantle
181
- export OLLAMA_HOST=http://localhost:11434
182
- export DASHSCOPE_API_KEY=sk-...
140
+ clai authorize-pentest AGREE # session-level ack before scan/attack tools
141
+ clai scope add --targets a.com,10.0.0.0/24
142
+ # in UI: /scope add a.com · /scope show · /scope clear
183
143
  ```
184
144
 
185
- ## REPL Commands
186
-
187
- | Command | Action |
188
- |---------|--------|
189
- | `/ask` | Switch to read-only ask mode (suggests commands/steps but does not execute them) |
190
- | `/agent` | Switch to active agent mode (proposes plans, executes commands, installs tools) |
191
- | `/model` | Open the interactive model picker to select a model (press Enter to open) |
192
- | `/model <name\|#>` | Switch active model by model name or index number (e.g. `/model 2`) |
193
- | `/provider [name]` | Switch LLM provider or open interactive provider picker |
194
- | `/use <provider>` | Alias for `/provider <name>` |
195
- | `/set <provider> [key]` | Store API key for a provider (prompts with masked input if key is omitted) |
196
- | `/unset <provider>` | Remove stored API key for a provider |
197
- | `/keys` | List configured providers with their API keys masked |
198
- | `/info [provider]` | Show model parameters, token/thinking limits, and usage details for a provider |
199
- | `/search [provider]` | Switch search provider (Brave, Tavily, etc.) or open interactive picker |
200
- | `/search-provider [name]`| Alias for `/search` |
201
- | `/mouse [on\|off]` | Enable (`on`) or disable (`off`) REPL mouse tracking for scrolling vs native copy-paste selection |
202
- | `/variants [on\|off\|none\|minimal\|low\|medium\|high\|xhigh]` | Configure reasoning effort. Use `on`/`off` to toggle, or set reasoning effort level (opens picker if no arg) |
203
- | `/reasoning [...]` | Alias for `/variants` |
204
- | `/think` / `/thinking` | Print the full, hidden reasoning/thinking trace from the last LLM response |
205
- | `/output [last\|id\|list]`| Toggle full tool output pager (`Ctrl+O`) or list saved output files |
206
- | `/clear` | Clear the current conversation messages and active state in memory |
207
- | `/new` / `/clean` | Save current session to history and start a fresh session with cleared context |
208
- | `/history` | Open interactive session browser to search and restore past conversation sessions |
209
- | `/save <name>` | Manually save the current session under a custom name |
210
- | `/reset` | Clear all saved history sessions permanently |
211
- | `/cwd <path>` | Change the current working directory for shell and tool executions |
212
- | `/allow <tool>` | Whitelist a tool for the current session to run without prompting for confirmation |
213
- | `/disallow <tool>` | Revoke session authorization for a tool |
214
- | `/freeonly [on\|off]` | Toggle (`on` to restrict, `off` to permit) paid providers when automatic fallback is active |
215
- | `/fallback [on\|off]` | Toggle (`on` to try other providers after a primary failure, `off` to fail immediately) |
216
- | `/compact` | Compress session history to fit context window constraints |
217
- | `/context` | Display estimated current context size in tokens |
218
- | `/plan` | View the current session plan checklist (also `Ctrl+P`) |
219
- | `/implement` | Approve the proposed plan and begin automated execution |
220
- | `/discard` | Discard the current plan and return to normal conversational mode |
221
- | `/scope [show\|clear\|new\|add <targets>]` | View or adjust authorized penetration testing target scopes |
222
- | `/privacy [status\|clear-history\|clear-logs\|clear-artifacts\|clear-all\|on\|off]` | Toggle private mode (`on` disables all disk writing, `off` enables) or purge logs/history |
223
- | `/permissions [default\|allow-all]` | Set confirmation prompt behavior (`allow-all` bypasses confirm prompts for mutating tasks except keys) |
224
- | `/update` | Check for updates and upgrade clai |
225
- | `/exit` / `/quit` | Quit and close the REPL |
226
- | `/help` | Print this command reference guide |
227
- | `Ctrl+C` | Abort current response (second Ctrl+C exits) |
228
- | `Ctrl+O` | Toggle full tool output (same keys on all OSes) |
229
- | `Ctrl+P` | View the current session plan |
230
-
231
- ### Plan → Implement workflow
232
-
233
- For multi-step coding or pentest tasks, clai first proposes a **plan** (a goal,
234
- an approach, and an ordered task checklist) and then waits. Nothing runs until
235
- you approve it.
236
-
237
- - **Approve** — type `/implement` to execute the plan task by task.
238
- - **Refine** — type any normal message (e.g. "use only installed tools",
239
- "skip task 2", "also enumerate subdomains") and clai produces a **revised
240
- plan**, then waits again. While a plan is awaiting approval, free-text is
241
- treated as plan feedback, not as a signal to start running.
242
- - **Cancel** — type `/discard` to drop the plan. After discarding, later
243
- messages are independent of it.
244
-
245
- ## Built-in Tools (Agent Mode)
246
-
247
- | Tool | Description | Risk Level |
248
- |------------------|--------------------------------------------------------------------|------------|
249
- | `shell.exec` | Run shell commands via execa (120s timeout, streams output) | smart* |
250
- | `fs.read` | Read files (sandboxed to approved roots) | safe |
251
- | `fs.write` | Write files (sandboxed) | confirm |
252
- | `fs.list` | List directory contents | safe |
253
- | `fs.search` | Search files with ripgrep (falls back to grep) | safe |
254
- | `pkg.install` | Install packages via detected OS package manager | confirm |
255
- | `net.scan` | Nmap wrapper. Defaults to a stealth SYN scan, auto-elevates (sudo/doas/gsudo) and falls back to an unprivileged TCP connect scan | confirm |
256
- | `http.fetch` | HTTP GET/POST with response size limits | safe |
257
- | `sysinfo` | OS, architecture, shell, and working directory info | safe |
258
- | `pentest.recon` | Composite: whois + dig + stealth nmap top-100 ports | confirm |
259
-
260
- > \* **smart** = read-only commands (`curl`, `ls`, `whoami`, `gobuster`, `dirb`, etc.) auto-execute; mutating commands require confirmation.
261
-
262
- ## Web tools
263
-
264
- Two higher-level tools sit alongside `http.fetch` for agent-driven web reading:
265
-
266
- - **`web.search`** — query the public web through a configurable search provider and return structured `{title, url, snippet}` hits. Default provider is **DuckDuckGo** (keyless, works out of the box). **Brave Search** and **Tavily** are supported when an API key is configured. Use this for current-events or post-cutoff information; the agent prompt steers `web.search` toward time-sensitive questions and `web.fetch` toward reading a known URL.
267
- - **`web.fetch`** — fetch a URL and return readable prose (HTML stripped of `<script>`/`<style>`/chrome) plus rich metadata: response headers, TLS session details (cipher, peer cert SAN list, fingerprint), redirect chain, fine-grained timing, resolved IP. Sensitive headers and cookie values are redacted by default; pass `redactSensitive=false` to expose them in the *output* (the audit log never carries them). Loopback / RFC1918 / link-local / cloud-metadata addresses are blocked by SSRF checks at every redirect hop, with DNS rebinding defeated by IP-pinning the connection to the resolved address.
268
-
269
- ### Search provider configuration
145
+ | Risk | Behavior |
146
+ |------|----------|
147
+ | **safe** | Auto-run read-only recon patterns, `http.fetch` GET evidence, many enum CLIs |
148
+ | **confirm** | Mutating shell, writes, installs, aggressive scans |
149
+ | **block** | Destructive patterns (`rm -rf /`, fork bombs, classic exfil signatures, ) |
270
150
 
271
- ```sh
272
- # Set a key for Brave or Tavily (DuckDuckGo is keyless and is a no-op).
273
- clai set brave bsx-xxxxxxxxxxxxxxxx
274
- clai set tavily tvly-xxxxxxxxxxxxxxxx
151
+ Default posture is **non-destructive proof**. Escalate impact only when you ask for it.
275
152
 
276
- # Remove a stored key.
277
- clai unset brave
153
+ ### Plan pane for engagements
278
154
 
279
- # Switch the active search provider used by web.search.
280
- clai search-provider tavily
155
+ - Live checklist while you work (`Ctrl+H`)
156
+ - Full plan + notes pager (`Ctrl+P` / `/plan`)
157
+ - Approve with `/implement`, revise in chat, cancel with `/discard`
158
+ - Plans **survive context compaction** and **reload with `/history`**
281
159
 
282
- # List configured keys (LLM and search) with the same masking rule.
283
- clai keys
284
- ```
160
+ ---
285
161
 
286
- Environment variables override stored keys at call time:
162
+ ## Terminal UI (operator console)
287
163
 
288
- | Provider | Env var |
289
- |--------------|--------------------------|
290
- | Brave Search | `BRAVE_SEARCH_API_KEY` |
291
- | Tavily | `TAVILY_API_KEY` |
292
- | DuckDuckGo | (none, keyless) |
164
+ Full-screen UI by default: streaming chat, tool cards, plan pane, pickers, history, secure key prompts. Falls back to a classic line REPL if the terminal cannot host the UI.
293
165
 
294
- ## Safety Gate
166
+ | Action | How |
167
+ |--------|-----|
168
+ | Send | `Enter` |
169
+ | Newline | `Shift+Enter` |
170
+ | Abort turn | `Esc` |
171
+ | Expand thinking | `Ctrl+T` (clickable on status strip) |
172
+ | Expand tool / compacted output | `Ctrl+O` |
173
+ | Plan pane | `Ctrl+H` |
174
+ | Full plan document | `Ctrl+P` |
175
+ | Background jobs | `Ctrl+J` |
176
+ | Commands / files | `/` · `@` |
177
+ | Exit | `Ctrl+C` twice |
295
178
 
296
- Every tool call passes through a 3-tier classifier:
179
+ Tool cards show **command/input** clearly and keep long scan tails in **OUTPUT** (expand or open pager). Compaction cards preserve engagement memory without dropping the plan.
297
180
 
298
- - **`safe`** Auto-run: read-only fs, sysinfo, http.fetch, read-only shell commands (`curl`, `ls`, `whoami`, `ifconfig`, `gobuster`, `dirb`, `ffuf`, `nikto`, etc.)
299
- - **`confirm`** — User prompt: mutating shell commands, fs.write, pkg.install, net.scan
300
- - **`block`** — Refuse with explanation: `rm -rf /`, fork bombs, public IP scans without authorization, exfiltration patterns
181
+ **`/history`** restores full sessions prompts, tools, findings context, and the matching plan when present.
301
182
 
302
- ### Pentest Authorization
183
+ ---
303
184
 
304
- Security tools require a one-time acknowledgment:
185
+ ## Modes
305
186
 
306
- ```sh
307
- clai authorize-pentest AGREE
308
- ```
187
+ | Mode | Security use |
188
+ |------|----------------|
189
+ | **`/agent`** | Run recon, build a pentest plan, execute after `/implement`, verify findings with tools |
190
+ | **`/ask`** | Methodology, commands, and writeups **without** executing tools |
309
191
 
310
- Public targets do not require a stored scope, but keeping one helps clai remember what you are authorized to test. Add targets with:
192
+ Switch anytime: `/agent`, `/ask`, or `clai --mode agent|ask "…"`.
311
193
 
312
- ```sh
313
- clai scope add --targets example.com,10.0.0.0/24
314
- ```
194
+ Coding and general sysadmin work use the same agent (scaffold, debug, packages) with the same plan gate for multi-step jobs.
315
195
 
316
- Inside the REPL, use `/scope add example.com`. If the agent proposes a public recon target that is not covered, clai shows a scope suggestion and still lets you continue through the normal confirmation flow.
196
+ ---
317
197
 
318
- ## Updates
198
+ ## Features (summary)
319
199
 
320
- clai checks for updates automatically on startup (every 4 hours, non-blocking). You can also check manually:
200
+ - **Pentest-first agent loop** recon-before-plan, stack-aware enum, evidence-backed findings
201
+ - **Durable plans** — `plan.create` / `task.update`, side pane, approve/refine/discard
202
+ - **11 LLM providers** with streaming (many free tiers + local Ollama)
203
+ - **Safety gate** + pentest authorization + optional engagement scope
204
+ - **OS-aware** installs and wordlist discovery (macOS / Linux / Windows)
205
+ - **Context compaction** (auto + `/compact`) that keeps the plan alive
206
+ - **Session history** with full transcript restore
207
+ - **Background jobs** for long scanners and listeners
208
+ - **Web OSINT** — `web.search` / `web.fetch` alongside raw `http.fetch`
321
209
 
322
- ```sh
323
- # CLI command
324
- clai update
210
+ ---
325
211
 
326
- # Inside the REPL
327
- /update
328
- ```
212
+ ## Provider setup
329
213
 
330
- ## Diagnostics
214
+ | Provider | Default model | Free tier | Key prefix |
215
+ |----------|---------------|-----------|------------|
216
+ | Groq | `llama-3.3-70b-versatile` | ✓ | `gsk_` |
217
+ | Gemini | `gemini-2.0-flash` | ✓ | `AIza` |
218
+ | OpenRouter | `meta-llama/llama-3.3-70b-instruct:free` | ✓ | `sk-or-` |
219
+ | OpenAI | `gpt-4o-mini` | — | `sk-` |
220
+ | Anthropic | `claude-3-5-haiku-latest` | — | `sk-ant-` |
221
+ | NVIDIA NIM | `openai/gpt-oss-20b` | ✓ | `nvapi-` |
222
+ | AgentRouter | `gpt-5` | — | `sk-` |
223
+ | Kimchi | `kimi-k2.6` | ✓ | (any) |
224
+ | AWS Mantle | `anthropic.claude-haiku-4-5` | — | `sk-ant-` |
225
+ | Ollama | `llama3.1:8b` | ✓ local | URL |
226
+ | Bynara | `mimo-v2.5-free` | ✓ | `sk_nry_` |
331
227
 
332
228
  ```sh
333
- clai doctor
229
+ clai set groq gsk_...
230
+ clai set gemini --from-env GEMINI_API_KEY
231
+ echo "gsk_..." | clai set groq --stdin
232
+ clai set ollama --url http://localhost:11434
233
+ clai keys
234
+ clai use groq
235
+ clai provider # picker shows selected model per provider
236
+ clai unset groq
334
237
  ```
335
238
 
336
- Outputs: OS, shell, architecture, config paths, provider key status, available pentest tools with install commands for missing ones.
239
+ Env overrides: `GROQ_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `NVIDIA_API_KEY`, `OLLAMA_HOST`,
337
240
 
338
- ## Per-Project Context
241
+ ---
339
242
 
340
- Create a `.clai/context.md` file in your project root to automatically inject project context into every prompt:
243
+ ## Commands operators use most
341
244
 
342
- ```md
343
- This is a Node.js project using Express and PostgreSQL.
344
- The API server runs on port 3000.
345
- ```
245
+ | Command | For security work |
246
+ |---------|-------------------|
247
+ | `/agent` | Offensive / execution mode |
248
+ | `/ask` | Research & methodology only |
249
+ | `/implement` · `/discard` · `/plan` | Plan lifecycle |
250
+ | `/scope` | Engagement targets |
251
+ | `/output` · `Ctrl+O` | Full tool / scan tails |
252
+ | `/jobs` · `Ctrl+J` | Long-running tools |
253
+ | `/compact` · `/context` | Keep long engagements inside the window |
254
+ | `/history` | Resume yesterday’s engagement |
255
+ | `/allow` | Session tool allow-list |
256
+ | `/cwd` | Switch lab / loot directory |
257
+ | `/model` · `/provider` | Capacity for the job |
258
+ | `/update` · `/help` · `/exit` | Housekeeping |
346
259
 
347
- ## Configuration
260
+ CLI mirrors: `clai authorize-pentest`, `clai scope add`, `clai doctor` (missing tools + install hints), `clai update`.
261
+
262
+ ---
263
+
264
+ ## Built-in tools (agent)
265
+
266
+ | Tool | Role in engagements |
267
+ |------|---------------------|
268
+ | `shell.exec` / `shell.start` | nmap, ffuf, sqlmap, hydra, custom PoCs, listeners |
269
+ | `net.scan` · `net.context` · `pentest.recon` | Host/port/service discovery |
270
+ | `http.fetch` | Raw HTTP/TLS evidence |
271
+ | `web.search` · `web.fetch` | OSINT / docs (readable), not raw exploit traffic |
272
+ | `dns.lookup` · `whois.lookup` | Narrow DNS / ownership |
273
+ | `tool.check` · `pkg.install` · `wordlist.find` | Tooling readiness |
274
+ | `fs.*` | Loot, notes, report files (sandboxed roots) |
275
+ | `plan.create` · `task.update` | Engagement checklist |
276
+ | `sysinfo` · `image.ocr` · `pdf.read` | Host context, report/screenshot OCR |
348
277
 
349
- Configuration is stored at `~/.config/clai/config.json` (varies by OS):
278
+ ### Search providers (OSINT)
350
279
 
351
280
  ```sh
352
- clai config # Print config path and settings
353
- clai mode agent # Set default mode
354
- clai model llama-3.3-70b-versatile # Set model
281
+ clai set brave bsx-...
282
+ clai set tavily tvly-...
283
+ clai search-provider tavily
355
284
  ```
356
285
 
357
- ## Development
286
+ DuckDuckGo is default and keyless. Env: `BRAVE_SEARCH_API_KEY`, `TAVILY_API_KEY`.
287
+
288
+ ---
289
+
290
+ ## Updates & doctor
358
291
 
359
292
  ```sh
360
- npm install # Install dependencies
361
- npm run dev # Run in development mode
362
- npm run typecheck # Type check
363
- npm run build # Build TypeScript
364
- npm test # Run tests (39 tests)
365
- npm run compile # Build native binaries (requires Bun)
293
+ clai update
294
+ clai doctor # OS, keys, and which security tools are installed
366
295
  ```
367
296
 
368
- ## Releasing
297
+ ---
298
+
299
+ ## Per-project context
369
300
 
370
- Releases are fully automated by `.github/workflows/release.yml`, triggered when
371
- you push a `v*.*.*` tag. To cut a release:
301
+ `.clai/context.md` in a repo injects durable notes (e.g. lab topology, in-scope hosts, stack assumptions) every turn.
302
+
303
+ ---
304
+
305
+ ## Configuration
372
306
 
373
307
  ```sh
374
- npm version 1.0.6 --no-git-tag-version # bump package.json + lockfile
375
- # also bump: src/commands/update.ts (FALLBACK_VERSION),
376
- # manifests/homebrew/clai.rb, manifests/scoop/clai.json
377
- git commit -am "v1.0.6"
378
- git push origin main
379
- git tag -a v1.0.6 -m "clai v1.0.6"
380
- git push origin v1.0.6 # this triggers the workflow
308
+ clai config
309
+ clai mode agent
310
+ clai model <name>
381
311
  ```
382
312
 
383
- On the tag push the workflow:
313
+ Config lives under the OS user config dir (e.g. `~/.config/clai/`).
384
314
 
385
- 1. **build** — runs typecheck + tests and compiles native binaries for all platforms.
386
- 2. **publish** — creates the GitHub Release with the binaries and SHA256 sidecars.
387
- 3. **publish-npm** — publishes `@pentoshi/clai` to npm.
388
- 4. **sync-tap** — regenerates the Homebrew formula in `pentoshi007/homebrew-clai`.
315
+ ---
389
316
 
390
- > **Reruns don't pick up newer workflow code.** Re-running a workflow runs it
391
- > against the commit the tag points to. If you change `release.yml` after
392
- > tagging, you must move/recreate the tag (or cut a new version) for the change
393
- > to take effect.
317
+ ## Development
394
318
 
395
- Required repository secrets (Settings → Secrets and variables → Actions). Each
396
- job skips gracefully if its secret is absent:
319
+ ```sh
320
+ npm install
321
+ npm run dev
322
+ npm run typecheck
323
+ npm run build
324
+ npm test
325
+ npm run compile # native binaries (Bun)
326
+ ```
397
327
 
398
- | Secret | Used by | How to create |
399
- |--------------------|---------------|-------------------------------------------------------------------------------|
400
- | `NPM_TOKEN` | `publish-npm` | npm → Access Tokens → **Granular** (Read and write on `@pentoshi/clai`) or classic **Automation** token. These bypass the interactive OTP prompt that blocks CI. |
401
- | `TAP_GITHUB_TOKEN` | `sync-tap` | A GitHub PAT with `contents:write` on the `pentoshi007/homebrew-clai` repo |
328
+ Node.js 20.
402
329
 
403
- Optional repository **variable** (not a secret):
330
+ ---
404
331
 
405
- | Variable | Effect |
406
- |------------------|---------------------------------------------------------------------------------|
407
- | `NPM_PROVENANCE` | Set to `true` to publish with `--provenance`. Only works if the npm account's 2FA is set to **"authorization only"**. Leave unset otherwise — the job publishes without provenance. |
332
+ ## Releasing
333
+
334
+ Tag-driven CI (`.github/workflows/release.yml`): tests multi-platform binaries GitHub Release npm `@pentoshi/clai` Homebrew tap.
335
+
336
+ ```sh
337
+ npm version 2.0.34 --no-git-tag-version
338
+ # bump FALLBACK_VERSION / manifests as needed
339
+ git commit -am "v2.0.34" && git push origin main
340
+ git tag -a v2.0.34 -m "clai v2.0.34" && git push origin v2.0.34
341
+ ```
408
342
 
409
- The `publish-npm` job verifies the tag matches `package.json` version and skips
410
- if that version is already on npm, so re-running a tag is safe.
343
+ Secrets: `NPM_TOKEN`, `TAP_GITHUB_TOKEN`. Optional: `NPM_PROVENANCE=true`.
411
344
 
412
- > A normal account with 2FA set to **"auth and writes"** prompts for a one-time
413
- > password on every publish, which fails in CI. Use a Granular/Automation
414
- > `NPM_TOKEN` (token-level auth) so CI can publish without an OTP — you can keep
415
- > 2FA enabled on the account.
345
+ ---
416
346
 
417
- ## Architecture
347
+ ## Architecture (overview)
418
348
 
419
349
  ```
420
350
  clai/
421
351
  ├─ src/
422
- │ ├─ index.ts # CLI entry, argv parsing via commander
423
- │ ├─ repl.ts # Interactive REPL with readline
424
- │ ├─ modes/
425
- ├─ ask.ts # Read-only mode (no tool execution)
426
- │ └─ agent.ts # Agentic mode (tool execution)
427
- │ ├─ agent/
428
- │ └─ runner.ts # Agent loop: LLM parse → classify → execute → loop
429
- │ ├─ llm/
430
- ├─ provider.ts # Provider interface & utilities
431
- │ ├─ router.ts # Provider selection & fallback chain
432
- │ │ ├─ http.ts # OpenAI-compatible HTTP client
433
- │ │ ├─ groq.ts # Groq provider (streaming)
434
- │ │ ├─ gemini.ts # Gemini provider (streaming)
435
- │ │ ├─ ollama.ts # Ollama provider (streaming)
436
- │ │ ├─ openai.ts # OpenAI provider (streaming)
437
- │ │ ├─ anthropic.ts # Anthropic provider (streaming)
438
- │ │ ├─ nvidia.ts # NVIDIA NIM provider (streaming)
439
- │ │ ├─ openrouter.ts # OpenRouter provider (streaming)
440
- │ │ └─ qwen-cloud.ts # Qwen Cloud provider (streaming + live models)
441
- │ ├─ tools/
442
- │ │ ├─ registry.ts # Tool dispatch table
443
- │ │ ├─ shell.ts # shell.exec via execa
444
- │ │ ├─ fs.ts # Sandboxed file operations
445
- │ │ └─ http.ts # HTTP fetch tool
446
- │ ├─ safety/
447
- │ │ ├─ classifier.ts # 3-tier risk classification
448
- │ │ └─ patterns.ts # Destructive & exfiltration regexes
449
- │ ├─ os/
450
- │ │ ├─ detect.ts # OS/arch/shell detection
451
- │ │ └─ pkgmgr.ts # Package manager detection
452
- │ ├─ store/
453
- │ │ ├─ config.ts # Persistent config via `conf`
454
- │ │ ├─ history.ts # Session history
455
- │ │ ├─ keys.ts # Keychain + fallback key storage
456
- │ │ ├─ logs.ts # Audit log with rotation
457
- │ │ └─ project.ts # Per-project context loader
458
- │ ├─ commands/
459
- │ │ ├─ doctor.ts # System diagnostics
460
- │ │ ├─ update.ts # Auto-update checker
461
- │ │ └─ providers.ts # Provider management commands
462
- │ └─ prompts/
463
- │ └─ index.ts # Prompt template renderer
464
- ├─ bin/clai.mjs # ESM shebang launcher
465
- ├─ scripts/build.ts # Bun compile per target
466
- ├─ .github/workflows/
467
- │ └─ release.yml # CI: build + publish binaries on tag
468
- ├─ manifests/
469
- │ ├─ homebrew/clai.rb # Homebrew formula
470
- │ └─ scoop/clai.json # Scoop manifest
471
- ├─ install/
472
- │ ├─ install.sh # macOS/Linux curl installer
473
- │ └─ install.ps1 # Windows PowerShell installer
474
- ├─ package.json
475
- ├─ tsconfig.json
476
- └─ README.md
352
+ │ ├─ index.ts # CLI entry
353
+ │ ├─ modes/ # ask · agent
354
+ │ ├─ agent/ # loop, plans, compaction, tool parsing
355
+ │ ├─ llm/ # providers + streaming
356
+ ├─ tools/ # shell, net, http, web, fs, pentest, …
357
+ │ ├─ safety/ # classifier + patterns
358
+ ├─ store/ # config, history, keys, plans, scope, logs
359
+ │ ├─ tui/ # full-screen terminal UI
360
+ │ ├─ app/ # session, commands, events
361
+ └─ prompts/ # agent methodology (incl. pentest)
362
+ ├─ bin/clai.mjs
363
+ ├─ install/ · manifests/
364
+ └─ package.json
477
365
  ```
478
366
 
367
+ ---
368
+
479
369
  ## License
480
370
 
481
371
  MIT
372
+
373
+ ---
374
+
375
+ **Use only on systems you are authorized to test.** clai is an operator tool: authorization, scope, and impact are yours; the agent executes with the gates and confirmations you configure.