nikcli 0.0.6

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 (602) hide show
  1. package/.turbo/turbo-typecheck.log +1 -0
  2. package/AGENTS.md +27 -0
  3. package/Dockerfile +18 -0
  4. package/README.md +15 -0
  5. package/bin/nikcli +84 -0
  6. package/config.json +13 -0
  7. package/docs/tailscale-mobile/01-tailscale-setup.md +94 -0
  8. package/docs/tailscale-mobile/02-host-setup.md +115 -0
  9. package/docs/tailscale-mobile/03-phone-and-serve.md +134 -0
  10. package/docs/tailscale-mobile/README.md +59 -0
  11. package/examples/README.md +54 -0
  12. package/package.json +147 -0
  13. package/parsers-config.ts +253 -0
  14. package/script/build.ts +179 -0
  15. package/script/postinstall.mjs +125 -0
  16. package/script/publish-registries.ts +187 -0
  17. package/script/publish.ts +100 -0
  18. package/script/schema.ts +47 -0
  19. package/script/seed-e2e.ts +50 -0
  20. package/sequential-prancing-forest.md +373 -0
  21. package/src/acp/README.md +164 -0
  22. package/src/acp/agent.ts +1303 -0
  23. package/src/acp/session.ts +105 -0
  24. package/src/acp/types.ts +22 -0
  25. package/src/agent/agent.ts +528 -0
  26. package/src/agent/generate.txt +32 -0
  27. package/src/agent/prompt/compaction.txt +14 -0
  28. package/src/agent/prompt/explore.txt +18 -0
  29. package/src/agent/prompt/summary.txt +11 -0
  30. package/src/agent/prompt/title.txt +44 -0
  31. package/src/auth/index.ts +73 -0
  32. package/src/bun/index.ts +119 -0
  33. package/src/bun/registry.ts +54 -0
  34. package/src/bus/bus-event.ts +43 -0
  35. package/src/bus/global.ts +10 -0
  36. package/src/bus/index.ts +105 -0
  37. package/src/chatbot/handlers.ts +150 -0
  38. package/src/chatbot/index.ts +132 -0
  39. package/src/cli/bootstrap.ts +17 -0
  40. package/src/cli/cmd/acp.ts +69 -0
  41. package/src/cli/cmd/ads.ts +377 -0
  42. package/src/cli/cmd/agent.ts +259 -0
  43. package/src/cli/cmd/auth.ts +400 -0
  44. package/src/cli/cmd/chatbot.ts +420 -0
  45. package/src/cli/cmd/cmd.ts +7 -0
  46. package/src/cli/cmd/companion.ts +81 -0
  47. package/src/cli/cmd/connectors.ts +593 -0
  48. package/src/cli/cmd/debug/agent.ts +166 -0
  49. package/src/cli/cmd/debug/config.ts +16 -0
  50. package/src/cli/cmd/debug/file.ts +97 -0
  51. package/src/cli/cmd/debug/index.ts +48 -0
  52. package/src/cli/cmd/debug/lsp.ts +52 -0
  53. package/src/cli/cmd/debug/ripgrep.ts +87 -0
  54. package/src/cli/cmd/debug/scrap.ts +16 -0
  55. package/src/cli/cmd/debug/skill.ts +16 -0
  56. package/src/cli/cmd/debug/snapshot.ts +52 -0
  57. package/src/cli/cmd/export.ts +88 -0
  58. package/src/cli/cmd/generate.ts +38 -0
  59. package/src/cli/cmd/github.ts +412 -0
  60. package/src/cli/cmd/image-model.ts +128 -0
  61. package/src/cli/cmd/import.ts +201 -0
  62. package/src/cli/cmd/lovable.ts +128 -0
  63. package/src/cli/cmd/mcp.ts +738 -0
  64. package/src/cli/cmd/mobile.ts +223 -0
  65. package/src/cli/cmd/models.ts +77 -0
  66. package/src/cli/cmd/plug.ts +231 -0
  67. package/src/cli/cmd/pr.ts +104 -0
  68. package/src/cli/cmd/rag-model.ts +167 -0
  69. package/src/cli/cmd/remote.ts +416 -0
  70. package/src/cli/cmd/run.ts +589 -0
  71. package/src/cli/cmd/serve.ts +51 -0
  72. package/src/cli/cmd/session.ts +133 -0
  73. package/src/cli/cmd/speak-model.ts +204 -0
  74. package/src/cli/cmd/stats.ts +402 -0
  75. package/src/cli/cmd/tui/app.tsx +841 -0
  76. package/src/cli/cmd/tui/attach.ts +31 -0
  77. package/src/cli/cmd/tui/component/border.tsx +75 -0
  78. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  79. package/src/cli/cmd/tui/component/dialog-command.tsx +172 -0
  80. package/src/cli/cmd/tui/component/dialog-config.tsx +291 -0
  81. package/src/cli/cmd/tui/component/dialog-connectors.tsx +440 -0
  82. package/src/cli/cmd/tui/component/dialog-image-model.tsx +97 -0
  83. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  84. package/src/cli/cmd/tui/component/dialog-model.tsx +234 -0
  85. package/src/cli/cmd/tui/component/dialog-provider.tsx +260 -0
  86. package/src/cli/cmd/tui/component/dialog-rag-model.tsx +217 -0
  87. package/src/cli/cmd/tui/component/dialog-remote.tsx +489 -0
  88. package/src/cli/cmd/tui/component/dialog-session-list.tsx +170 -0
  89. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  90. package/src/cli/cmd/tui/component/dialog-settings/index.tsx +59 -0
  91. package/src/cli/cmd/tui/component/dialog-settings/prompt.tsx +40 -0
  92. package/src/cli/cmd/tui/component/dialog-settings/sidebar.tsx +39 -0
  93. package/src/cli/cmd/tui/component/dialog-settings/spinner.tsx +62 -0
  94. package/src/cli/cmd/tui/component/dialog-settings/ui.tsx +58 -0
  95. package/src/cli/cmd/tui/component/dialog-skills.tsx +117 -0
  96. package/src/cli/cmd/tui/component/dialog-speak-model.tsx +304 -0
  97. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  98. package/src/cli/cmd/tui/component/dialog-status.tsx +165 -0
  99. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  100. package/src/cli/cmd/tui/component/dialog-theme-create.tsx +717 -0
  101. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +52 -0
  102. package/src/cli/cmd/tui/component/dialog-workspace-list.tsx +350 -0
  103. package/src/cli/cmd/tui/component/error-component.tsx +91 -0
  104. package/src/cli/cmd/tui/component/logo.tsx +103 -0
  105. package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
  106. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +669 -0
  107. package/src/cli/cmd/tui/component/prompt/frecency.tsx +89 -0
  108. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  109. package/src/cli/cmd/tui/component/prompt/index.tsx +2165 -0
  110. package/src/cli/cmd/tui/component/prompt/stash.tsx +63 -0
  111. package/src/cli/cmd/tui/component/spinner.tsx +24 -0
  112. package/src/cli/cmd/tui/component/startup-loading.tsx +63 -0
  113. package/src/cli/cmd/tui/component/table/markdown-table.tsx +267 -0
  114. package/src/cli/cmd/tui/component/table-db/db/connections.ts +75 -0
  115. package/src/cli/cmd/tui/component/table-db/db/db-connection.ts +223 -0
  116. package/src/cli/cmd/tui/component/table-db/db/db-preview.ts +202 -0
  117. package/src/cli/cmd/tui/component/table-db/db/factory.ts +77 -0
  118. package/src/cli/cmd/tui/component/table-db/db/index.ts +9 -0
  119. package/src/cli/cmd/tui/component/table-db/db/mysql-connection.ts +330 -0
  120. package/src/cli/cmd/tui/component/table-db/db/postgres-connection.ts +338 -0
  121. package/src/cli/cmd/tui/component/table-db/db/sqlite-connection.ts +302 -0
  122. package/src/cli/cmd/tui/component/table-db/db/types.ts +108 -0
  123. package/src/cli/cmd/tui/component/table-db/table/dbedit-hooks.ts +74 -0
  124. package/src/cli/cmd/tui/component/table-db/table/index.ts +15 -0
  125. package/src/cli/cmd/tui/component/table-db/table/table-events.ts +54 -0
  126. package/src/cli/cmd/tui/component/table-db/table/table-formatters.ts +191 -0
  127. package/src/cli/cmd/tui/component/table-db/table/table-hooks.ts +105 -0
  128. package/src/cli/cmd/tui/component/table-db/table/table-keyboard-handler.ts +255 -0
  129. package/src/cli/cmd/tui/component/table-db/table/table-layout-engine.ts +208 -0
  130. package/src/cli/cmd/tui/component/table-db/table/table-renderable.ts +486 -0
  131. package/src/cli/cmd/tui/component/table-db/table/table-selection-manager.ts +136 -0
  132. package/src/cli/cmd/tui/component/table-db/table/table-state.ts +198 -0
  133. package/src/cli/cmd/tui/component/table-db/table/types.ts +69 -0
  134. package/src/cli/cmd/tui/component/table-db/ui/db-visualizer.tsx +71 -0
  135. package/src/cli/cmd/tui/component/table-db/ui/index.ts +2 -0
  136. package/src/cli/cmd/tui/component/table-db/ui/table-renderer.ts +607 -0
  137. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  138. package/src/cli/cmd/tui/component/tips.tsx +195 -0
  139. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  140. package/src/cli/cmd/tui/context/args.tsx +14 -0
  141. package/src/cli/cmd/tui/context/directory.ts +13 -0
  142. package/src/cli/cmd/tui/context/exit.tsx +24 -0
  143. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  144. package/src/cli/cmd/tui/context/keybind.tsx +102 -0
  145. package/src/cli/cmd/tui/context/kv.tsx +52 -0
  146. package/src/cli/cmd/tui/context/local.tsx +458 -0
  147. package/src/cli/cmd/tui/context/plugin-keybinds.ts +41 -0
  148. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  149. package/src/cli/cmd/tui/context/route.tsx +54 -0
  150. package/src/cli/cmd/tui/context/sdk.tsx +128 -0
  151. package/src/cli/cmd/tui/context/server.tsx +8 -0
  152. package/src/cli/cmd/tui/context/sync.tsx +510 -0
  153. package/src/cli/cmd/tui/context/theme/abyss.json +233 -0
  154. package/src/cli/cmd/tui/context/theme/apple.json +235 -0
  155. package/src/cli/cmd/tui/context/theme/arctic.json +232 -0
  156. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  157. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  158. package/src/cli/cmd/tui/context/theme/ayuai.json +229 -0
  159. package/src/cli/cmd/tui/context/theme/blood.json +229 -0
  160. package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
  161. package/src/cli/cmd/tui/context/theme/catmoe.json +235 -0
  162. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  163. package/src/cli/cmd/tui/context/theme/catppuccin-latte.json +233 -0
  164. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  165. package/src/cli/cmd/tui/context/theme/catppuccin.json +259 -0
  166. package/src/cli/cmd/tui/context/theme/charcoal.json +230 -0
  167. package/src/cli/cmd/tui/context/theme/chromatic.json +235 -0
  168. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  169. package/src/cli/cmd/tui/context/theme/cosmic.json +234 -0
  170. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  171. package/src/cli/cmd/tui/context/theme/cyber.json +235 -0
  172. package/src/cli/cmd/tui/context/theme/dawnfox.json +229 -0
  173. package/src/cli/cmd/tui/context/theme/dimension.json +235 -0
  174. package/src/cli/cmd/tui/context/theme/dracula-official.json +222 -0
  175. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  176. package/src/cli/cmd/tui/context/theme/dream.json +235 -0
  177. package/src/cli/cmd/tui/context/theme/duo.json +235 -0
  178. package/src/cli/cmd/tui/context/theme/dusk.json +235 -0
  179. package/src/cli/cmd/tui/context/theme/ebony.json +232 -0
  180. package/src/cli/cmd/tui/context/theme/equilibrium.json +232 -0
  181. package/src/cli/cmd/tui/context/theme/ethereal.json +235 -0
  182. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  183. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  184. package/src/cli/cmd/tui/context/theme/fusion.json +235 -0
  185. package/src/cli/cmd/tui/context/theme/ghost.json +235 -0
  186. package/src/cli/cmd/tui/context/theme/github-dark.json +229 -0
  187. package/src/cli/cmd/tui/context/theme/github-dimmed.json +231 -0
  188. package/src/cli/cmd/tui/context/theme/github-light.json +229 -0
  189. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  190. package/src/cli/cmd/tui/context/theme/glass.json +235 -0
  191. package/src/cli/cmd/tui/context/theme/gold.json +235 -0
  192. package/src/cli/cmd/tui/context/theme/gone.json +234 -0
  193. package/src/cli/cmd/tui/context/theme/greyscale.json +229 -0
  194. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  195. package/src/cli/cmd/tui/context/theme/hacker.json +229 -0
  196. package/src/cli/cmd/tui/context/theme/holo.json +235 -0
  197. package/src/cli/cmd/tui/context/theme/ink.json +235 -0
  198. package/src/cli/cmd/tui/context/theme/jet.json +233 -0
  199. package/src/cli/cmd/tui/context/theme/kanagawa.json +227 -0
  200. package/src/cli/cmd/tui/context/theme/lavender.json +236 -0
  201. package/src/cli/cmd/tui/context/theme/lightph.json +235 -0
  202. package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
  203. package/src/cli/cmd/tui/context/theme/material-ocean.json +230 -0
  204. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  205. package/src/cli/cmd/tui/context/theme/matrix.json +227 -0
  206. package/src/cli/cmd/tui/context/theme/mercury.json +245 -0
  207. package/src/cli/cmd/tui/context/theme/midnight.json +235 -0
  208. package/src/cli/cmd/tui/context/theme/modern.json +235 -0
  209. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  210. package/src/cli/cmd/tui/context/theme/muted.json +229 -0
  211. package/src/cli/cmd/tui/context/theme/neon.json +229 -0
  212. package/src/cli/cmd/tui/context/theme/neonfusion.json +235 -0
  213. package/src/cli/cmd/tui/context/theme/neutral.json +235 -0
  214. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  215. package/src/cli/cmd/tui/context/theme/nikcli.json +245 -0
  216. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  217. package/src/cli/cmd/tui/context/theme/nordic.json +235 -0
  218. package/src/cli/cmd/tui/context/theme/nova.json +235 -0
  219. package/src/cli/cmd/tui/context/theme/obsidian.json +234 -0
  220. package/src/cli/cmd/tui/context/theme/one-dark.json +231 -0
  221. package/src/cli/cmd/tui/context/theme/one-pro.json +229 -0
  222. package/src/cli/cmd/tui/context/theme/onyx.json +233 -0
  223. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  224. package/src/cli/cmd/tui/context/theme/osaka-jade.json +240 -0
  225. package/src/cli/cmd/tui/context/theme/oxocarbon.json +229 -0
  226. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  227. package/src/cli/cmd/tui/context/theme/poimandres.json +230 -0
  228. package/src/cli/cmd/tui/context/theme/prism.json +235 -0
  229. package/src/cli/cmd/tui/context/theme/radiant.json +235 -0
  230. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  231. package/src/cli/cmd/tui/context/theme/shadow.json +235 -0
  232. package/src/cli/cmd/tui/context/theme/silicon.json +235 -0
  233. package/src/cli/cmd/tui/context/theme/slate.json +233 -0
  234. package/src/cli/cmd/tui/context/theme/soft.json +235 -0
  235. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  236. package/src/cli/cmd/tui/context/theme/spectrum.json +235 -0
  237. package/src/cli/cmd/tui/context/theme/starlight.json +233 -0
  238. package/src/cli/cmd/tui/context/theme/sunrise.json +235 -0
  239. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  240. package/src/cli/cmd/tui/context/theme/tech.json +235 -0
  241. package/src/cli/cmd/tui/context/theme/tokyonight-storm.json +245 -0
  242. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  243. package/src/cli/cmd/tui/context/theme/vapor.json +235 -0
  244. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  245. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  246. package/src/cli/cmd/tui/context/theme/vivid.json +232 -0
  247. package/src/cli/cmd/tui/context/theme/void.json +235 -0
  248. package/src/cli/cmd/tui/context/theme/vscode.json +235 -0
  249. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  250. package/src/cli/cmd/tui/context/theme/zinc.json +236 -0
  251. package/src/cli/cmd/tui/context/theme.tsx +1303 -0
  252. package/src/cli/cmd/tui/event.ts +48 -0
  253. package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +152 -0
  254. package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +50 -0
  255. package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +63 -0
  256. package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +62 -0
  257. package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +93 -0
  258. package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +66 -0
  259. package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +96 -0
  260. package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +48 -0
  261. package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +288 -0
  262. package/src/cli/cmd/tui/plugin/api.tsx +407 -0
  263. package/src/cli/cmd/tui/plugin/index.ts +3 -0
  264. package/src/cli/cmd/tui/plugin/internal.ts +25 -0
  265. package/src/cli/cmd/tui/plugin/runtime.ts +1048 -0
  266. package/src/cli/cmd/tui/plugin/slots.tsx +61 -0
  267. package/src/cli/cmd/tui/routes/home.tsx +153 -0
  268. package/src/cli/cmd/tui/routes/session/dbedit.tsx +474 -0
  269. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +65 -0
  270. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +110 -0
  271. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +105 -0
  272. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  273. package/src/cli/cmd/tui/routes/session/footer.tsx +75 -0
  274. package/src/cli/cmd/tui/routes/session/header.tsx +177 -0
  275. package/src/cli/cmd/tui/routes/session/index.tsx +2280 -0
  276. package/src/cli/cmd/tui/routes/session/permission.tsx +540 -0
  277. package/src/cli/cmd/tui/routes/session/question.tsx +435 -0
  278. package/src/cli/cmd/tui/routes/session/sidebar.tsx +313 -0
  279. package/src/cli/cmd/tui/thread.ts +174 -0
  280. package/src/cli/cmd/tui/ui/dialog-alert.tsx +57 -0
  281. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
  282. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +204 -0
  283. package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
  284. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +102 -0
  285. package/src/cli/cmd/tui/ui/dialog-select.tsx +389 -0
  286. package/src/cli/cmd/tui/ui/dialog.tsx +180 -0
  287. package/src/cli/cmd/tui/ui/link.tsx +34 -0
  288. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  289. package/src/cli/cmd/tui/ui/toast.tsx +138 -0
  290. package/src/cli/cmd/tui/util/clipboard.ts +154 -0
  291. package/src/cli/cmd/tui/util/editor.ts +32 -0
  292. package/src/cli/cmd/tui/util/signal.ts +7 -0
  293. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  294. package/src/cli/cmd/tui/util/transcript.ts +98 -0
  295. package/src/cli/cmd/tui/win32.ts +110 -0
  296. package/src/cli/cmd/tui/worker.ts +156 -0
  297. package/src/cli/cmd/uninstall.ts +357 -0
  298. package/src/cli/cmd/upgrade.ts +72 -0
  299. package/src/cli/cmd/web.ts +87 -0
  300. package/src/cli/cmd/workspace-serve.ts +16 -0
  301. package/src/cli/error.ts +57 -0
  302. package/src/cli/network.ts +55 -0
  303. package/src/cli/remote/index.ts +36 -0
  304. package/src/cli/remote/notifications.ts +104 -0
  305. package/src/cli/remote/qr-renderer.ts +86 -0
  306. package/src/cli/remote/remote-service.ts +757 -0
  307. package/src/cli/remote/session-manager.ts +284 -0
  308. package/src/cli/remote/subagent-hooks.ts +151 -0
  309. package/src/cli/remote/types.ts +121 -0
  310. package/src/cli/ui.ts +96 -0
  311. package/src/cli/upgrade.ts +25 -0
  312. package/src/command/index.ts +174 -0
  313. package/src/command/template/initialize.txt +10 -0
  314. package/src/command/template/review.txt +99 -0
  315. package/src/config/config.ts +1760 -0
  316. package/src/config/markdown.ts +88 -0
  317. package/src/config/migrate-tui-config.ts +155 -0
  318. package/src/config/paths.ts +174 -0
  319. package/src/config/tui-schema.ts +36 -0
  320. package/src/config/tui.ts +209 -0
  321. package/src/connectors/api/base.ts +75 -0
  322. package/src/connectors/api/figma.ts +103 -0
  323. package/src/connectors/api/github.ts +247 -0
  324. package/src/connectors/api/lovable.ts +126 -0
  325. package/src/connectors/api/slack.ts +137 -0
  326. package/src/connectors/auth.ts +68 -0
  327. package/src/connectors/cache.ts +119 -0
  328. package/src/connectors/credentials.ts +81 -0
  329. package/src/connectors/index.ts +202 -0
  330. package/src/connectors/registry.ts +358 -0
  331. package/src/docs/context.ts +120 -0
  332. package/src/docs/library.ts +189 -0
  333. package/src/env/index.ts +26 -0
  334. package/src/file/ignore.ts +83 -0
  335. package/src/file/index.ts +411 -0
  336. package/src/file/ripgrep.ts +402 -0
  337. package/src/file/time.ts +65 -0
  338. package/src/file/watcher.ts +127 -0
  339. package/src/flag/flag.ts +128 -0
  340. package/src/format/formatter.ts +356 -0
  341. package/src/format/index.ts +137 -0
  342. package/src/global/index.ts +57 -0
  343. package/src/id/id.ts +83 -0
  344. package/src/ide/index.ts +76 -0
  345. package/src/index.ts +184 -0
  346. package/src/installation/index.ts +246 -0
  347. package/src/lsp/client.ts +250 -0
  348. package/src/lsp/index.ts +483 -0
  349. package/src/lsp/language.ts +119 -0
  350. package/src/lsp/server.ts +2046 -0
  351. package/src/mcp/auth.ts +121 -0
  352. package/src/mcp/index.ts +860 -0
  353. package/src/mcp/oauth-callback.ts +198 -0
  354. package/src/mcp/oauth-provider.ts +148 -0
  355. package/src/mobile/auth.ts +97 -0
  356. package/src/mobile/github-repo.ts +185 -0
  357. package/src/patch/index.ts +631 -0
  358. package/src/permission/arity.ts +150 -0
  359. package/src/permission/dbedit.ts +236 -0
  360. package/src/permission/index.ts +210 -0
  361. package/src/permission/next.ts +287 -0
  362. package/src/plugin/codex.ts +493 -0
  363. package/src/plugin/copilot.ts +261 -0
  364. package/src/plugin/index.ts +714 -0
  365. package/src/plugin/install.ts +379 -0
  366. package/src/plugin/meta.ts +165 -0
  367. package/src/plugin/shared.ts +188 -0
  368. package/src/project/bootstrap.ts +35 -0
  369. package/src/project/instance.ts +84 -0
  370. package/src/project/project.ts +373 -0
  371. package/src/project/state.ts +66 -0
  372. package/src/project/vcs.ts +76 -0
  373. package/src/prompt/stash-store.ts +93 -0
  374. package/src/provider/auth.ts +147 -0
  375. package/src/provider/models-macro.ts +22 -0
  376. package/src/provider/models.ts +216 -0
  377. package/src/provider/provider.ts +1483 -0
  378. package/src/provider/sdk/openai-compatible/src/README.md +5 -0
  379. package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
  380. package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
  381. package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
  382. package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +22 -0
  383. package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
  384. package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
  385. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
  386. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1732 -0
  387. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
  388. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
  389. package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
  390. package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
  391. package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
  392. package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
  393. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
  394. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
  395. package/src/provider/transform.ts +828 -0
  396. package/src/pty/index.ts +241 -0
  397. package/src/question/index.ts +171 -0
  398. package/src/rag/chunk.ts +43 -0
  399. package/src/rag/embed.ts +179 -0
  400. package/src/rag/index.ts +376 -0
  401. package/src/rag/storage.ts +76 -0
  402. package/src/scheduler/index.ts +61 -0
  403. package/src/server/error.ts +36 -0
  404. package/src/server/event.ts +7 -0
  405. package/src/server/mdns.ts +59 -0
  406. package/src/server/routes/chatbot.ts +205 -0
  407. package/src/server/routes/companion.ts +729 -0
  408. package/src/server/routes/config.ts +92 -0
  409. package/src/server/routes/connectors.ts +121 -0
  410. package/src/server/routes/dbedit.ts +76 -0
  411. package/src/server/routes/experimental.ts +210 -0
  412. package/src/server/routes/file.ts +197 -0
  413. package/src/server/routes/global.ts +135 -0
  414. package/src/server/routes/mcp.ts +225 -0
  415. package/src/server/routes/mobile.ts +2044 -0
  416. package/src/server/routes/permission.ts +68 -0
  417. package/src/server/routes/project.ts +82 -0
  418. package/src/server/routes/provider.ts +235 -0
  419. package/src/server/routes/pty.ts +169 -0
  420. package/src/server/routes/question.ts +98 -0
  421. package/src/server/routes/session.ts +968 -0
  422. package/src/server/routes/tui.ts +379 -0
  423. package/src/server/routes/workspace.ts +104 -0
  424. package/src/server/server.ts +761 -0
  425. package/src/server/ssh.ts +207 -0
  426. package/src/session/auth.ts +402 -0
  427. package/src/session/compaction.ts +253 -0
  428. package/src/session/generate.ts +38 -0
  429. package/src/session/index.ts +598 -0
  430. package/src/session/llm.ts +273 -0
  431. package/src/session/message-v2.ts +836 -0
  432. package/src/session/message.ts +189 -0
  433. package/src/session/processor.ts +408 -0
  434. package/src/session/prompt/anthropic-20250930.txt +165 -0
  435. package/src/session/prompt/anthropic.txt +105 -0
  436. package/src/session/prompt/anthropic_spoof.txt +1 -0
  437. package/src/session/prompt/beast.txt +147 -0
  438. package/src/session/prompt/build-switch.txt +5 -0
  439. package/src/session/prompt/codex_header.txt +79 -0
  440. package/src/session/prompt/copilot-gpt-5.txt +143 -0
  441. package/src/session/prompt/gemini.txt +155 -0
  442. package/src/session/prompt/max-steps.txt +16 -0
  443. package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
  444. package/src/session/prompt/plan.txt +25 -0
  445. package/src/session/prompt/qwen.txt +108 -0
  446. package/src/session/prompt.ts +1942 -0
  447. package/src/session/retry.ts +90 -0
  448. package/src/session/revert.ts +120 -0
  449. package/src/session/stats.ts +404 -0
  450. package/src/session/status.ts +84 -0
  451. package/src/session/summary.ts +184 -0
  452. package/src/session/system.ts +195 -0
  453. package/src/session/toast.tsx +105 -0
  454. package/src/session/todo.ts +258 -0
  455. package/src/session/uninstall.ts +357 -0
  456. package/src/share/share-next.ts +421 -0
  457. package/src/share/share.ts +92 -0
  458. package/src/shell/shell.ts +65 -0
  459. package/src/skill/index.ts +1 -0
  460. package/src/skill/skill.ts +232 -0
  461. package/src/snapshot/index.ts +297 -0
  462. package/src/storage/storage.ts +227 -0
  463. package/src/tool/apply_patch.ts +288 -0
  464. package/src/tool/apply_patch.txt +33 -0
  465. package/src/tool/bash.ts +252 -0
  466. package/src/tool/bash.txt +115 -0
  467. package/src/tool/batch.ts +175 -0
  468. package/src/tool/batch.txt +24 -0
  469. package/src/tool/codesearch.ts +132 -0
  470. package/src/tool/codesearch.txt +12 -0
  471. package/src/tool/context_collect.ts +152 -0
  472. package/src/tool/context_collect.txt +9 -0
  473. package/src/tool/context_diagnostics.ts +81 -0
  474. package/src/tool/context_diagnostics.txt +5 -0
  475. package/src/tool/context_related.ts +117 -0
  476. package/src/tool/context_related.txt +5 -0
  477. package/src/tool/context_search.ts +108 -0
  478. package/src/tool/context_search.txt +8 -0
  479. package/src/tool/db-diff.ts +434 -0
  480. package/src/tool/db-table.txt +15 -0
  481. package/src/tool/docs_add.ts +50 -0
  482. package/src/tool/docs_add.txt +5 -0
  483. package/src/tool/docs_context.ts +56 -0
  484. package/src/tool/docs_context.txt +4 -0
  485. package/src/tool/docs_gap_report.ts +79 -0
  486. package/src/tool/docs_gap_report.txt +7 -0
  487. package/src/tool/docs_load.ts +41 -0
  488. package/src/tool/docs_load.txt +4 -0
  489. package/src/tool/docs_request.ts +129 -0
  490. package/src/tool/docs_request.txt +7 -0
  491. package/src/tool/docs_search.ts +51 -0
  492. package/src/tool/docs_search.txt +6 -0
  493. package/src/tool/docs_unload.ts +38 -0
  494. package/src/tool/docs_unload.txt +5 -0
  495. package/src/tool/edit.ts +614 -0
  496. package/src/tool/edit.txt +10 -0
  497. package/src/tool/external-directory.ts +32 -0
  498. package/src/tool/generate_image.ts +174 -0
  499. package/src/tool/generate_image.txt +12 -0
  500. package/src/tool/glob.ts +79 -0
  501. package/src/tool/glob.txt +6 -0
  502. package/src/tool/grep.ts +153 -0
  503. package/src/tool/grep.txt +8 -0
  504. package/src/tool/invalid.ts +17 -0
  505. package/src/tool/ls.ts +116 -0
  506. package/src/tool/ls.txt +1 -0
  507. package/src/tool/lsp.ts +96 -0
  508. package/src/tool/lsp.txt +19 -0
  509. package/src/tool/memory_search.ts +141 -0
  510. package/src/tool/memory_search.txt +8 -0
  511. package/src/tool/multiedit.ts +46 -0
  512. package/src/tool/multiedit.txt +41 -0
  513. package/src/tool/plan-enter.txt +14 -0
  514. package/src/tool/plan-exit.txt +13 -0
  515. package/src/tool/plan.ts +130 -0
  516. package/src/tool/question.ts +33 -0
  517. package/src/tool/question.txt +10 -0
  518. package/src/tool/rag_index.ts +77 -0
  519. package/src/tool/rag_index.txt +10 -0
  520. package/src/tool/rag_reset.ts +26 -0
  521. package/src/tool/rag_reset.txt +4 -0
  522. package/src/tool/rag_search.ts +62 -0
  523. package/src/tool/rag_search.txt +6 -0
  524. package/src/tool/rag_status.ts +45 -0
  525. package/src/tool/rag_status.txt +4 -0
  526. package/src/tool/read.ts +203 -0
  527. package/src/tool/read.txt +12 -0
  528. package/src/tool/registry.ts +214 -0
  529. package/src/tool/skill.ts +169 -0
  530. package/src/tool/skill.txt +3 -0
  531. package/src/tool/smart_docs.ts +74 -0
  532. package/src/tool/smart_docs.txt +7 -0
  533. package/src/tool/speak/elevenlabs.ts +201 -0
  534. package/src/tool/speak/openrouter.ts +240 -0
  535. package/src/tool/speak/provider.ts +83 -0
  536. package/src/tool/speak.ts +440 -0
  537. package/src/tool/task.ts +194 -0
  538. package/src/tool/task.txt +60 -0
  539. package/src/tool/todo.ts +53 -0
  540. package/src/tool/todoread.txt +14 -0
  541. package/src/tool/todowrite.txt +167 -0
  542. package/src/tool/tool.ts +87 -0
  543. package/src/tool/tree.ts +218 -0
  544. package/src/tool/tree.txt +8 -0
  545. package/src/tool/truncation.ts +106 -0
  546. package/src/tool/use-connector.ts +47 -0
  547. package/src/tool/voice.ts +188 -0
  548. package/src/tool/webfetch.ts +205 -0
  549. package/src/tool/webfetch.txt +13 -0
  550. package/src/tool/websearch.ts +150 -0
  551. package/src/tool/websearch.txt +14 -0
  552. package/src/tool/write.ts +80 -0
  553. package/src/tool/write.txt +8 -0
  554. package/src/util/archive.ts +16 -0
  555. package/src/util/color.ts +19 -0
  556. package/src/util/context.ts +25 -0
  557. package/src/util/defer.ts +12 -0
  558. package/src/util/error.ts +77 -0
  559. package/src/util/eventloop.ts +20 -0
  560. package/src/util/filesystem.ts +125 -0
  561. package/src/util/flock.ts +329 -0
  562. package/src/util/fn.ts +11 -0
  563. package/src/util/format.ts +20 -0
  564. package/src/util/hash.ts +7 -0
  565. package/src/util/iife.ts +3 -0
  566. package/src/util/keybind.ts +103 -0
  567. package/src/util/lazy.ts +18 -0
  568. package/src/util/locale.ts +81 -0
  569. package/src/util/lock.ts +98 -0
  570. package/src/util/log.ts +180 -0
  571. package/src/util/network.ts +9 -0
  572. package/src/util/process.ts +15 -0
  573. package/src/util/queue.ts +32 -0
  574. package/src/util/record.ts +3 -0
  575. package/src/util/rpc.ts +66 -0
  576. package/src/util/scrap.ts +10 -0
  577. package/src/util/signal.ts +12 -0
  578. package/src/util/timeout.ts +14 -0
  579. package/src/util/token.ts +7 -0
  580. package/src/util/wildcard.ts +56 -0
  581. package/src/workspace/adaptors/index.ts +271 -0
  582. package/src/workspace/adaptors/types.ts +14 -0
  583. package/src/workspace/adaptors/worktree.ts +31 -0
  584. package/src/workspace/config.ts +19 -0
  585. package/src/workspace/index.ts +223 -0
  586. package/src/workspace/session-proxy-middleware.ts +97 -0
  587. package/src/workspace/sse.ts +66 -0
  588. package/src/workspace/workspace-context.ts +23 -0
  589. package/src/workspace/workspace-server/routes.ts +33 -0
  590. package/src/workspace/workspace-server/server.ts +47 -0
  591. package/src/worktree/index.ts +487 -0
  592. package/sst-env.d.ts +10 -0
  593. package/test/benchmark.test.ts +121 -0
  594. package/test/build-optimizations.test.ts +124 -0
  595. package/test/id-benchmark.test.ts +132 -0
  596. package/test/optimizations.test.ts +302 -0
  597. package/test/preload.ts +1 -0
  598. package/test/solidjs-benchmark.test.ts +262 -0
  599. package/test/solidjs-optimizations.test.ts +259 -0
  600. package/test/tui-benchmark.test.ts +230 -0
  601. package/test/wildcard-benchmark.test.ts +180 -0
  602. package/tsconfig.json +26 -0
@@ -0,0 +1,223 @@
1
+ import { cmd } from "./cmd"
2
+ import { withNetworkOptions, resolveNetworkOptions } from "../network"
3
+ import { Server } from "@/server/server"
4
+ import { Flag } from "@/flag/flag"
5
+ import { MobileAuth } from "@/mobile/auth"
6
+ import { generateQR } from "@nikcli-ai/remote"
7
+ import { Installation } from "@/installation"
8
+ import { Ssh } from "@/server/ssh"
9
+ import { networkInterfaces } from "os"
10
+
11
+ function normalizePublicUrl(input?: string) {
12
+ if (!input) return
13
+ const url = new URL(input)
14
+ return url.toString().replace(/\/$/, "")
15
+ }
16
+
17
+ function getLocalIPs(): string[] {
18
+ const ips: string[] = []
19
+ for (const iface of Object.values(networkInterfaces())) {
20
+ if (!iface) continue
21
+ for (const addr of iface) {
22
+ if (addr.family === "IPv4" && !addr.internal) ips.push(addr.address)
23
+ }
24
+ }
25
+ return ips
26
+ }
27
+
28
+ function isLoopbackHostname(hostname: string) {
29
+ return hostname === "127.0.0.1" || hostname === "::1" || hostname === "localhost"
30
+ }
31
+
32
+ function resolveServerUrl(input: { publicUrl?: string; hostname: string; port: number }) {
33
+ if (input.publicUrl) {
34
+ const value = normalizePublicUrl(input.publicUrl)
35
+ if (!value) throw new Error("Invalid public URL")
36
+ return value
37
+ }
38
+ const isAllInterfaces = input.hostname === "0.0.0.0" || input.hostname === "::"
39
+ const host = isAllInterfaces ? (getLocalIPs()[0] ?? input.hostname) : input.hostname
40
+ return `http://${host}:${input.port}`
41
+ }
42
+
43
+ function printPairing(info: { serverUrl: string; token: string; directory?: string }) {
44
+ const deepLink = new URL("nikcli://connect")
45
+ deepLink.searchParams.set("server", info.serverUrl)
46
+ deepLink.searchParams.set("token", info.token)
47
+ if (info.directory) deepLink.searchParams.set("directory", info.directory)
48
+
49
+ console.log("")
50
+ console.log("Nikcli Mobile Pairing")
51
+ console.log(`Server URL: ${info.serverUrl}`)
52
+ console.log(`Token: ${info.token}`)
53
+ console.log(`Deep Link: ${deepLink.toString()}`)
54
+ console.log("")
55
+
56
+ return generateQR(deepLink.toString())
57
+ }
58
+
59
+ export const MobileCommand = cmd({
60
+ command: "mobile",
61
+ describe: "mobile app host and pairing tools",
62
+ builder: (yargs) =>
63
+ yargs
64
+ .command({
65
+ command: "serve",
66
+ describe: "start nikcli with mobile-friendly defaults",
67
+ builder: (yargs) =>
68
+ withNetworkOptions(yargs)
69
+ .default("hostname", "0.0.0.0")
70
+ .option("public-url", {
71
+ type: "string",
72
+ describe: "public HTTPS URL used by the mobile app outside your tailnet",
73
+ })
74
+ .option("pair", {
75
+ type: "boolean",
76
+ default: false,
77
+ describe: "create and print a new mobile pairing token at startup",
78
+ })
79
+ .option("pair-name", {
80
+ type: "string",
81
+ default: "iphone",
82
+ describe: "name for the generated pairing token",
83
+ })
84
+ .option("pair-expiry-days", {
85
+ type: "number",
86
+ describe: "optional token expiry in days",
87
+ }),
88
+ handler: async (args) => {
89
+ const opts = await resolveNetworkOptions(args)
90
+ const loopback = isLoopbackHostname(opts.hostname)
91
+ const tailscaleAuthActive = Flag.NIKCLI_SERVER_TAILSCALE_AUTH && loopback
92
+ const publicExposure = Boolean(args.publicUrl) || !loopback
93
+
94
+ if (!Flag.NIKCLI_SERVER_PASSWORD && !tailscaleAuthActive) {
95
+ if (publicExposure) {
96
+ throw new Error(
97
+ "Public mobile hosting requires NIKCLI_SERVER_PASSWORD. Set a server password before binding to a non-loopback address or using --public-url.",
98
+ )
99
+ }
100
+
101
+ console.log(
102
+ "Mobile mode without a server password is only safe on loopback. Set NIKCLI_SERVER_PASSWORD for LAN or public access.",
103
+ )
104
+ }
105
+
106
+ const server = Server.listen(opts)
107
+ const hostname = server.hostname || opts.hostname
108
+ const port = server.port || opts.port || 4096
109
+ const serverUrl = resolveServerUrl({
110
+ publicUrl: args.publicUrl as string | undefined,
111
+ hostname,
112
+ port,
113
+ })
114
+
115
+ console.log(`nikcli mobile host listening on http://${hostname}:${port}`)
116
+ if (serverUrl !== `http://${hostname}:${port}`) {
117
+ console.log(`public mobile URL: ${serverUrl}`)
118
+ }
119
+
120
+ if (args.pair) {
121
+ const created = await MobileAuth.create({
122
+ name: String(args.pairName || "iphone"),
123
+ expiresInDays: args.pairExpiryDays ? Number(args.pairExpiryDays) : undefined,
124
+ })
125
+
126
+ const localIPs = getLocalIPs()
127
+ const isAllInterfaces = opts.hostname === "0.0.0.0" || opts.hostname === "::"
128
+ const pairingIPs = args.publicUrl
129
+ ? [serverUrl]
130
+ : isAllInterfaces && localIPs.length > 0
131
+ ? localIPs.map((ip) => `http://${ip}:${port}`)
132
+ : [serverUrl]
133
+
134
+ for (let i = 0; i < pairingIPs.length; i++) {
135
+ const url = pairingIPs[i]
136
+ if (pairingIPs.length > 1) console.log(`--- Interface ${i + 1}/${pairingIPs.length}: ${url} ---`)
137
+ const qr = await printPairing({ serverUrl: url, token: created.token, directory: process.cwd() })
138
+ console.log(qr)
139
+ }
140
+ }
141
+
142
+ const sshServer = Ssh.start()
143
+ if (sshServer) {
144
+ console.log(
145
+ `nikcli SSH server listening on ssh://${Flag.NIKCLI_SERVER_SSH_HOST}:${Flag.NIKCLI_SERVER_SSH_PORT}`,
146
+ )
147
+ }
148
+
149
+ await new Promise(() => {})
150
+
151
+ await server.stop()
152
+ if (sshServer) await Ssh.stop()
153
+ },
154
+ })
155
+ .command({
156
+ command: "pair",
157
+ describe: "generate a mobile pairing token and QR code",
158
+ builder: (yargs) =>
159
+ yargs
160
+ .option("public-url", {
161
+ type: "string",
162
+ demandOption: true,
163
+ describe: "public server URL the mobile app should connect to",
164
+ })
165
+ .option("name", {
166
+ type: "string",
167
+ default: "iphone",
168
+ describe: "token label",
169
+ })
170
+ .option("expiry-days", {
171
+ type: "number",
172
+ describe: "optional token expiry in days",
173
+ })
174
+ .option("directory", {
175
+ type: "string",
176
+ describe: "default directory or repo path for the paired app",
177
+ }),
178
+ handler: async (args) => {
179
+ const created = await MobileAuth.create({
180
+ name: String(args.name || "iphone"),
181
+ expiresInDays: args.expiryDays ? Number(args.expiryDays) : undefined,
182
+ })
183
+ const serverUrl = normalizePublicUrl(String(args.publicUrl))
184
+ if (!serverUrl) throw new Error("Invalid --public-url")
185
+ const qr = await printPairing({
186
+ serverUrl,
187
+ token: created.token,
188
+ directory: args.directory ? String(args.directory) : process.cwd(),
189
+ })
190
+ console.log(qr)
191
+ },
192
+ })
193
+ .command({
194
+ command: "token list",
195
+ describe: "list mobile pairing tokens",
196
+ handler: async () => {
197
+ const tokens = await MobileAuth.list()
198
+ if (!tokens.length) {
199
+ console.log("No mobile tokens found")
200
+ return
201
+ }
202
+ for (const token of tokens) {
203
+ console.log(`${token.id} ${token.name} created=${new Date(token.createdAt).toISOString()}`)
204
+ }
205
+ },
206
+ })
207
+ .command({
208
+ command: "token revoke <id>",
209
+ describe: "revoke a mobile pairing token",
210
+ builder: (yargs) =>
211
+ yargs.positional("id", {
212
+ type: "string",
213
+ describe: "token id to revoke",
214
+ }),
215
+ handler: async (args) => {
216
+ const ok = await MobileAuth.remove(String(args.id))
217
+ if (!ok) throw new Error(`Token not found: ${args.id}`)
218
+ console.log(`Revoked mobile token ${args.id}`)
219
+ },
220
+ })
221
+ .demandCommand(),
222
+ async handler() {},
223
+ })
@@ -0,0 +1,77 @@
1
+ import type { Argv } from "yargs"
2
+ import { Instance } from "../../project/instance"
3
+ import { Provider } from "../../provider/provider"
4
+ import { ModelsDev } from "../../provider/models"
5
+ import { cmd } from "./cmd"
6
+ import { UI } from "../ui"
7
+ import { EOL } from "os"
8
+
9
+ export const ModelsCommand = cmd({
10
+ command: "models [provider]",
11
+ describe: "list all available models",
12
+ builder: (yargs: Argv) => {
13
+ return yargs
14
+ .positional("provider", {
15
+ describe: "provider ID to filter models by",
16
+ type: "string",
17
+ array: false,
18
+ })
19
+ .option("verbose", {
20
+ describe: "use more verbose model output (includes metadata like costs)",
21
+ type: "boolean",
22
+ })
23
+ .option("refresh", {
24
+ describe: "refresh the models cache from models.dev",
25
+ type: "boolean",
26
+ })
27
+ },
28
+ handler: async (args) => {
29
+ if (args.refresh) {
30
+ await ModelsDev.refresh()
31
+ UI.println(UI.Style.TEXT_SUCCESS_BOLD + "Models cache refreshed" + UI.Style.TEXT_NORMAL)
32
+ }
33
+
34
+ await Instance.provide({
35
+ directory: process.cwd(),
36
+ async fn() {
37
+ const providers = await Provider.list()
38
+
39
+ function printModels(providerID: string, verbose?: boolean) {
40
+ const provider = providers[providerID]
41
+ const sortedModels = Object.entries(provider.models).sort(([a], [b]) => a.localeCompare(b))
42
+ for (const [modelID, model] of sortedModels) {
43
+ process.stdout.write(`${providerID}/${modelID}`)
44
+ process.stdout.write(EOL)
45
+ if (verbose) {
46
+ process.stdout.write(JSON.stringify(model, null, 2))
47
+ process.stdout.write(EOL)
48
+ }
49
+ }
50
+ }
51
+
52
+ if (args.provider) {
53
+ const provider = providers[args.provider]
54
+ if (!provider) {
55
+ UI.error(`Provider not found: ${args.provider}`)
56
+ return
57
+ }
58
+
59
+ printModels(args.provider, args.verbose)
60
+ return
61
+ }
62
+
63
+ const providerIDs = Object.keys(providers).sort((a, b) => {
64
+ const aIsNikcli = a.startsWith("nikcli")
65
+ const bIsNikcli = b.startsWith("nikcli")
66
+ if (aIsNikcli && !bIsNikcli) return -1
67
+ if (!aIsNikcli && bIsNikcli) return 1
68
+ return a.localeCompare(b)
69
+ })
70
+
71
+ for (const providerID of providerIDs) {
72
+ printModels(providerID, args.verbose)
73
+ }
74
+ },
75
+ })
76
+ },
77
+ })
@@ -0,0 +1,231 @@
1
+ import { intro, log, outro, spinner } from "@clack/prompts"
2
+ import type { Argv } from "yargs"
3
+
4
+ import { ConfigPaths } from "../../config/paths"
5
+ import { Global } from "../../global"
6
+ import { installPlugin, patchPluginConfig, readPluginManifest } from "../../plugin/install"
7
+ import { resolvePluginTarget } from "../../plugin/shared"
8
+ import { Instance } from "../../project/instance"
9
+ import { errorMessage } from "../../util/error"
10
+ import { Filesystem } from "../../util/filesystem"
11
+ import { Process } from "../../util/process"
12
+ import { UI } from "../ui"
13
+ import { cmd } from "./cmd"
14
+
15
+ type Spin = {
16
+ start: (msg: string) => void
17
+ stop: (msg: string, code?: number) => void
18
+ }
19
+
20
+ export type PlugDeps = {
21
+ spinner: () => Spin
22
+ log: {
23
+ error: (msg: string) => void
24
+ info: (msg: string) => void
25
+ success: (msg: string) => void
26
+ }
27
+ resolve: (spec: string) => Promise<string>
28
+ readText: (file: string) => Promise<string>
29
+ write: (file: string, text: string) => Promise<void>
30
+ exists: (file: string) => Promise<boolean>
31
+ files: (dir: string, name: "nikcli" | "tui") => string[]
32
+ global: string
33
+ }
34
+
35
+ export type PlugInput = {
36
+ mod: string
37
+ global?: boolean
38
+ force?: boolean
39
+ }
40
+
41
+ export type PlugCtx = {
42
+ vcs?: string
43
+ worktree: string
44
+ directory: string
45
+ }
46
+
47
+ const defaultPlugDeps: PlugDeps = {
48
+ spinner: () => spinner(),
49
+ log: {
50
+ error: (msg) => log.error(msg),
51
+ info: (msg) => log.info(msg),
52
+ success: (msg) => log.success(msg),
53
+ },
54
+ resolve: (spec) => resolvePluginTarget(spec),
55
+ readText: (file) => Filesystem.readText(file),
56
+ write: async (file, text) => {
57
+ await Filesystem.write(file, text)
58
+ },
59
+ exists: (file) => Filesystem.exists(file),
60
+ files: (dir, name) => ConfigPaths.fileInDirectory(dir, name),
61
+ global: Global.Path.config,
62
+ }
63
+
64
+ function cause(err: unknown) {
65
+ if (!err || typeof err !== "object") return
66
+ if (!("cause" in err)) return
67
+ return (err as { cause?: unknown }).cause
68
+ }
69
+
70
+ export function createPlugTask(input: PlugInput, dep: PlugDeps = defaultPlugDeps) {
71
+ const mod = input.mod
72
+ const force = Boolean(input.force)
73
+ const global = Boolean(input.global)
74
+
75
+ return async (ctx: PlugCtx) => {
76
+ const install = dep.spinner()
77
+ install.start("Installing plugin package...")
78
+ const target = await installPlugin(mod, dep)
79
+ if (!target.ok) {
80
+ install.stop("Install failed", 1)
81
+ dep.log.error(`Could not install "${mod}"`)
82
+ const hit = cause(target.error) ?? target.error
83
+ if (hit instanceof Process.RunFailedError) {
84
+ const lines = hit.stderr
85
+ .toString()
86
+ .split(/\r?\n/)
87
+ .map((line) => line.trim())
88
+ .filter(Boolean)
89
+ const errs = lines.filter((line) => line.startsWith("error:")).map((line) => line.replace(/^error:\s*/, ""))
90
+ const detail = errs[0] ?? lines.at(-1)
91
+ if (detail) dep.log.error(detail)
92
+ if (lines.some((line) => line.includes("No version matching"))) {
93
+ dep.log.info("This package depends on a version that is not available in your npm registry.")
94
+ dep.log.info("Check npm registry/auth settings and try again.")
95
+ }
96
+ }
97
+ if (!(hit instanceof Process.RunFailedError)) {
98
+ dep.log.error(errorMessage(hit))
99
+ }
100
+ return false
101
+ }
102
+ install.stop("Plugin package ready")
103
+
104
+ const inspect = dep.spinner()
105
+ inspect.start("Reading plugin manifest...")
106
+ const manifest = await readPluginManifest(target.target)
107
+ if (!manifest.ok) {
108
+ if (manifest.code === "manifest_read_failed") {
109
+ inspect.stop("Manifest read failed", 1)
110
+ dep.log.error(`Installed "${mod}" but failed to read ${manifest.file}`)
111
+ dep.log.error(errorMessage(cause(manifest.error) ?? manifest.error))
112
+ return false
113
+ }
114
+
115
+ if (manifest.code === "manifest_no_targets") {
116
+ inspect.stop("No plugin targets found", 1)
117
+ dep.log.error(`"${mod}" does not declare supported targets in package.json`)
118
+ dep.log.info('Expected: "oc-plugin": ["server", "tui"] or tuples like [["tui", { ... }]].')
119
+ return false
120
+ }
121
+
122
+ inspect.stop("Manifest read failed", 1)
123
+ return false
124
+ }
125
+
126
+ inspect.stop(
127
+ `Detected ${manifest.targets.map((item) => item.kind).join(" + ")} target${manifest.targets.length === 1 ? "" : "s"}`,
128
+ )
129
+
130
+ const patch = dep.spinner()
131
+ patch.start("Updating plugin config...")
132
+ const out = await patchPluginConfig(
133
+ {
134
+ spec: mod,
135
+ targets: manifest.targets,
136
+ force,
137
+ global,
138
+ vcs: ctx.vcs,
139
+ worktree: ctx.worktree,
140
+ directory: ctx.directory,
141
+ config: dep.global,
142
+ },
143
+ dep,
144
+ )
145
+ if (!out.ok) {
146
+ if (out.code === "invalid_json") {
147
+ patch.stop(`Failed updating ${out.kind} config`, 1)
148
+ dep.log.error(`Invalid JSON in ${out.file} (${out.parse} at line ${out.line}, column ${out.col})`)
149
+ dep.log.info("Fix the config file and run the command again.")
150
+ return false
151
+ }
152
+
153
+ patch.stop("Failed updating plugin config", 1)
154
+ dep.log.error(errorMessage(out.error))
155
+ return false
156
+ }
157
+ patch.stop("Plugin config updated")
158
+ for (const item of out.items) {
159
+ if (item.mode === "noop") {
160
+ dep.log.info(`Already configured in ${item.file}`)
161
+ continue
162
+ }
163
+ if (item.mode === "replace") {
164
+ dep.log.info(`Replaced in ${item.file}`)
165
+ continue
166
+ }
167
+ dep.log.info(`Added to ${item.file}`)
168
+ }
169
+
170
+ dep.log.success(`Installed ${mod}`)
171
+ dep.log.info(global ? `Scope: global (${out.dir})` : `Scope: local (${out.dir})`)
172
+ return true
173
+ }
174
+ }
175
+
176
+ export const PluginCommand = cmd({
177
+ command: "plugin <module>",
178
+ aliases: ["plug"],
179
+ describe: "install plugin and update config",
180
+ builder: (yargs: Argv) => {
181
+ return yargs
182
+ .positional("module", {
183
+ type: "string",
184
+ describe: "npm module name",
185
+ })
186
+ .option("global", {
187
+ alias: ["g"],
188
+ type: "boolean",
189
+ default: false,
190
+ describe: "install in global config",
191
+ })
192
+ .option("force", {
193
+ alias: ["f"],
194
+ type: "boolean",
195
+ default: false,
196
+ describe: "replace existing plugin version",
197
+ })
198
+ },
199
+ handler: async (args) => {
200
+ const mod = String(args.module ?? "").trim()
201
+ if (!mod) {
202
+ UI.error("module is required")
203
+ process.exitCode = 1
204
+ return
205
+ }
206
+
207
+ UI.empty()
208
+ intro(`Install plugin ${mod}`)
209
+
210
+ const run = createPlugTask({
211
+ mod,
212
+ global: Boolean(args.global),
213
+ force: Boolean(args.force),
214
+ })
215
+ let ok = true
216
+
217
+ await Instance.provide({
218
+ directory: process.cwd(),
219
+ fn: async () => {
220
+ ok = await run({
221
+ vcs: Instance.project.vcs,
222
+ worktree: Instance.worktree,
223
+ directory: Instance.directory,
224
+ })
225
+ },
226
+ })
227
+
228
+ outro("Done")
229
+ if (!ok) process.exitCode = 1
230
+ },
231
+ })
@@ -0,0 +1,104 @@
1
+ import { UI } from "../ui"
2
+ import { cmd } from "./cmd"
3
+ import { Instance } from "@/project/instance"
4
+ import { $ } from "bun"
5
+
6
+ export const PrCommand = cmd({
7
+ command: "pr <number>",
8
+ describe: "fetch and checkout a GitHub PR branch, then run nikcli",
9
+ builder: (yargs) =>
10
+ yargs.positional("number", {
11
+ type: "number",
12
+ describe: "PR number to checkout",
13
+ demandOption: true,
14
+ }),
15
+ async handler(args) {
16
+ await Instance.provide({
17
+ directory: process.cwd(),
18
+ async fn() {
19
+ const project = Instance.project
20
+ if (project.vcs !== "git") {
21
+ UI.error("Could not find git repository. Please run this command from a git repository.")
22
+ process.exit(1)
23
+ }
24
+
25
+ const prNumber = args.number
26
+ const localBranchName = `pr/${prNumber}`
27
+ UI.println(`Fetching and checking out PR #${prNumber}...`)
28
+
29
+ const result = await $`gh pr checkout ${prNumber} --branch ${localBranchName} --force`.nothrow()
30
+
31
+ if (result.exitCode !== 0) {
32
+ UI.error(`Failed to checkout PR #${prNumber}. Make sure you have gh CLI installed and authenticated.`)
33
+ process.exit(1)
34
+ }
35
+
36
+ const prInfoResult =
37
+ await $`gh pr view ${prNumber} --json headRepository,headRepositoryOwner,isCrossRepository,headRefName,body`.nothrow()
38
+
39
+ let sessionId: string | undefined
40
+
41
+ if (prInfoResult.exitCode === 0) {
42
+ const prInfoText = prInfoResult.text()
43
+ if (prInfoText.trim()) {
44
+ const prInfo = JSON.parse(prInfoText)
45
+
46
+ if (prInfo && prInfo.isCrossRepository && prInfo.headRepository && prInfo.headRepositoryOwner) {
47
+ const forkOwner = prInfo.headRepositoryOwner.login
48
+ const forkName = prInfo.headRepository.name
49
+ const remoteName = forkOwner
50
+
51
+ const remotes = (await $`git remote`.nothrow().text()).trim()
52
+ if (!remotes.split("\n").includes(remoteName)) {
53
+ await $`git remote add ${remoteName} https://github.com/${forkOwner}/${forkName}.git`.nothrow()
54
+ UI.println(`Added fork remote: ${remoteName}`)
55
+ }
56
+
57
+ const headRefName = prInfo.headRefName
58
+ await $`git branch --set-upstream-to=${remoteName}/${headRefName} ${localBranchName}`.nothrow()
59
+ }
60
+
61
+ if (prInfo && prInfo.body) {
62
+ const sessionMatch = prInfo.body.match(/https:\/\/nikcli\.ai\/s\/([a-zA-Z0-9_-]+)/)
63
+ if (sessionMatch) {
64
+ const sessionUrl = sessionMatch[0]
65
+ UI.println(`Found nikcli session: ${sessionUrl}`)
66
+ UI.println(`Importing session...`)
67
+
68
+ const importResult = await $`nikcli import ${sessionUrl}`.nothrow()
69
+ if (importResult.exitCode === 0) {
70
+ const importOutput = importResult.text().trim()
71
+ const sessionIdMatch = importOutput.match(/Imported session: ([a-zA-Z0-9_-]+)/)
72
+ if (sessionIdMatch) {
73
+ sessionId = sessionIdMatch[1]
74
+ UI.println(`Session imported: ${sessionId}`)
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ UI.println(`Successfully checked out PR #${prNumber} as branch '${localBranchName}'`)
83
+ UI.println()
84
+ UI.println("Starting nikcli...")
85
+ UI.println()
86
+
87
+ const { spawn } = await import("child_process")
88
+ const nikcliArgs = sessionId ? ["-s", sessionId] : []
89
+ const nikcliProcess = spawn("nikcli", nikcliArgs, {
90
+ stdio: "inherit",
91
+ cwd: process.cwd(),
92
+ })
93
+
94
+ await new Promise<void>((resolve, reject) => {
95
+ nikcliProcess.on("exit", (code) => {
96
+ if (code === 0) resolve()
97
+ else reject(new Error(`nikcli exited with code ${code}`))
98
+ })
99
+ nikcliProcess.on("error", reject)
100
+ })
101
+ },
102
+ })
103
+ },
104
+ })