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,358 @@
1
+ import { dynamicTool, type Tool, jsonSchema } from "ai"
2
+ import { Config } from "../config/config"
3
+ import { resolveCredential } from "./credentials"
4
+ import { FigmaApi } from "./api/figma"
5
+ import { SlackApi } from "./api/slack"
6
+ import { GithubApi } from "./api/github"
7
+ import { LovableApi } from "./api/lovable"
8
+
9
+ export interface OperationArg {
10
+ name: string
11
+ description: string
12
+ required?: boolean
13
+ type?: "string" | "number" | "boolean"
14
+ enum?: string[]
15
+ }
16
+
17
+ export interface OperationSpec {
18
+ name: string
19
+ description: string
20
+ args: OperationArg[]
21
+ execute: (credential: string, args: Record<string, any>) => Promise<any>
22
+ }
23
+
24
+ export interface ConnectorSpec {
25
+ type: string
26
+ credentialType: "token" | "botToken" | "apiKey"
27
+ operations: OperationSpec[]
28
+ healthCheck: (credential: string) => Promise<void>
29
+ }
30
+
31
+ const FIGMA_OPERATIONS: OperationSpec[] = [
32
+ {
33
+ name: "figma_get_file",
34
+ description: "Get the contents of a Figma file including all pages and frames",
35
+ args: [{ name: "fileKey", description: "The Figma file key (found in Figma URL after /file/)", required: true }],
36
+ execute: (cred, args) => FigmaApi.getFile(cred, args.fileKey),
37
+ },
38
+ {
39
+ name: "figma_get_components",
40
+ description: "Get all components from a Figma file",
41
+ args: [{ name: "fileKey", description: "The Figma file key", required: true }],
42
+ execute: (cred, args) => FigmaApi.getFileComponents(cred, args.fileKey),
43
+ },
44
+ {
45
+ name: "figma_get_styles",
46
+ description: "Get all styles from a Figma file",
47
+ args: [{ name: "fileKey", description: "The Figma file key", required: true }],
48
+ execute: (cred, args) => FigmaApi.getFileStyles(cred, args.fileKey),
49
+ },
50
+ {
51
+ name: "figma_get_comments",
52
+ description: "Get all comments from a Figma file",
53
+ args: [{ name: "fileKey", description: "The Figma file key", required: true }],
54
+ execute: (cred, args) => FigmaApi.getComments(cred, args.fileKey),
55
+ },
56
+ ]
57
+
58
+ const SLACK_OPERATIONS: OperationSpec[] = [
59
+ {
60
+ name: "slack_list_channels",
61
+ description: "List all channels in a Slack workspace",
62
+ args: [
63
+ {
64
+ name: "types",
65
+ description: "Comma-separated channel types: public_channel, private_channel, mpim, im",
66
+ type: "string",
67
+ },
68
+ ],
69
+ execute: (cred, args) => SlackApi.listConversations(cred, args.types),
70
+ },
71
+ {
72
+ name: "slack_send_message",
73
+ description: "Send a message to a Slack channel",
74
+ args: [
75
+ {
76
+ name: "channel",
77
+ description: "The Slack channel ID (e.g., C01234567) or name (e.g., general)",
78
+ required: true,
79
+ },
80
+ { name: "text", description: "The message text to send", required: true },
81
+ ],
82
+ execute: (cred, args) => SlackApi.sendMessage(cred, args.channel, args.text),
83
+ },
84
+ {
85
+ name: "slack_search_messages",
86
+ description: "Search for messages in Slack",
87
+ args: [
88
+ { name: "query", description: "The search query", required: true },
89
+ { name: "count", description: "Maximum number of results (default 20)", type: "number" },
90
+ ],
91
+ execute: (cred, args) => SlackApi.searchMessages(cred, args.query, args.count),
92
+ },
93
+ {
94
+ name: "slack_get_channel_info",
95
+ description: "Get information about a Slack channel",
96
+ args: [{ name: "channel", description: "The Slack channel ID", required: true }],
97
+ execute: (cred, args) => SlackApi.getConversationInfo(cred, args.channel),
98
+ },
99
+ {
100
+ name: "slack_reply_to_thread",
101
+ description: "Reply to a message thread in Slack",
102
+ args: [
103
+ { name: "channel", description: "The Slack channel ID", required: true },
104
+ { name: "threadTs", description: "The thread timestamp (ts) from the original message", required: true },
105
+ { name: "text", description: "The reply text", required: true },
106
+ ],
107
+ execute: (cred, args) => SlackApi.replyToMessage(cred, args.channel, args.threadTs, args.text),
108
+ },
109
+ ]
110
+
111
+ const GITHUB_OPERATIONS: OperationSpec[] = [
112
+ {
113
+ name: "github_get_repo",
114
+ description: "Get information about a GitHub repository",
115
+ args: [
116
+ { name: "owner", description: "Repository owner (username or organization)", required: true },
117
+ { name: "repo", description: "Repository name", required: true },
118
+ ],
119
+ execute: (cred, args) => GithubApi.getRepo(cred, args.owner, args.repo),
120
+ },
121
+ {
122
+ name: "github_get_file",
123
+ description: "Get the contents of a file from a GitHub repository",
124
+ args: [
125
+ { name: "owner", description: "Repository owner", required: true },
126
+ { name: "repo", description: "Repository name", required: true },
127
+ { name: "path", description: "Path to the file in the repository", required: true },
128
+ { name: "ref", description: "Branch, tag, or commit (optional)", type: "string" },
129
+ ],
130
+ execute: (cred, args) => GithubApi.getFileContent(cred, args.owner, args.repo, args.path),
131
+ },
132
+ {
133
+ name: "github_create_issue",
134
+ description: "Create a new issue in a GitHub repository",
135
+ args: [
136
+ { name: "owner", description: "Repository owner", required: true },
137
+ { name: "repo", description: "Repository name", required: true },
138
+ { name: "title", description: "Issue title", required: true },
139
+ { name: "body", description: "Issue body (optional)", type: "string" },
140
+ ],
141
+ execute: (cred, args) => GithubApi.createIssue(cred, args.owner, args.repo, args.title, args.body),
142
+ },
143
+ {
144
+ name: "github_list_issues",
145
+ description: "List issues in a GitHub repository",
146
+ args: [
147
+ { name: "owner", description: "Repository owner", required: true },
148
+ { name: "repo", description: "Repository name", required: true },
149
+ { name: "state", description: "Issue state (default: open)", enum: ["open", "closed", "all"], type: "string" },
150
+ ],
151
+ execute: (cred, args) => GithubApi.listIssues(cred, args.owner, args.repo, args.state),
152
+ },
153
+ {
154
+ name: "github_search_code",
155
+ description: "Search for code in GitHub",
156
+ args: [
157
+ { name: "query", description: "Search query (supports GitHub code search syntax)", required: true },
158
+ { name: "sort", description: "Sort by", enum: ["indexed"], type: "string" },
159
+ { name: "order", description: "Order direction", enum: ["asc", "desc"], type: "string" },
160
+ ],
161
+ execute: (cred, args) => GithubApi.searchCode(cred, args.query, args.sort, args.order),
162
+ },
163
+ {
164
+ name: "github_list_repos",
165
+ description: "List repositories for the authenticated user",
166
+ args: [
167
+ {
168
+ name: "type",
169
+ description: "Repository type (default: owner)",
170
+ enum: ["all", "owner", "member"],
171
+ type: "string",
172
+ },
173
+ { name: "sort", description: "Sort by", enum: ["updated", "pushed", "full_name"], type: "string" },
174
+ ],
175
+ execute: (cred, args) => GithubApi.listRepos(cred, args.type, args.sort),
176
+ },
177
+ ]
178
+
179
+ const LOVABLE_OPERATIONS: OperationSpec[] = [
180
+ {
181
+ name: "lovable_get_projects",
182
+ description: "Get all Lovable projects",
183
+ args: [],
184
+ execute: (cred) => LovableApi.getProjects(cred),
185
+ },
186
+ {
187
+ name: "lovable_get_project",
188
+ description: "Get information about a Lovable project",
189
+ args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
190
+ execute: (cred, args) => LovableApi.getProject(cred, args.projectId),
191
+ },
192
+ {
193
+ name: "lovable_get_chats",
194
+ description: "Get all chats for a Lovable project",
195
+ args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
196
+ execute: (cred, args) => LovableApi.getChats(cred, args.projectId),
197
+ },
198
+ {
199
+ name: "lovable_send_message",
200
+ description: "Send a message to a Lovable project",
201
+ args: [
202
+ { name: "projectId", description: "The Lovable project ID", required: true },
203
+ { name: "message", description: "The message to send", required: true },
204
+ { name: "chatId", description: "Existing chat ID (optional, creates new chat if not provided)", type: "string" },
205
+ ],
206
+ execute: (cred, args) => LovableApi.sendMessage(cred, args.projectId, args.message, args.chatId),
207
+ },
208
+ {
209
+ name: "lovable_get_project_files",
210
+ description: "Get all files in a Lovable project",
211
+ args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
212
+ execute: (cred, args) => LovableApi.getProjectFiles(cred, args.projectId),
213
+ },
214
+ {
215
+ name: "lovable_run_prompt",
216
+ description: "Run a prompt in a Lovable project",
217
+ args: [
218
+ { name: "projectId", description: "The Lovable project ID", required: true },
219
+ { name: "prompt", description: "The prompt to run", required: true },
220
+ ],
221
+ execute: (cred, args) => LovableApi.runPrompt(cred, args.projectId, args.prompt),
222
+ },
223
+ ]
224
+
225
+ const CONNECTOR_SPECS: Record<string, ConnectorSpec> = {
226
+ figma: {
227
+ type: "figma",
228
+ credentialType: "token",
229
+ operations: FIGMA_OPERATIONS,
230
+ healthCheck: (cred) => FigmaApi.getMe(cred),
231
+ },
232
+ slack: {
233
+ type: "slack",
234
+ credentialType: "botToken",
235
+ operations: SLACK_OPERATIONS,
236
+ healthCheck: (cred) => SlackApi.listUsers(cred),
237
+ },
238
+ github: {
239
+ type: "github",
240
+ credentialType: "token",
241
+ operations: GITHUB_OPERATIONS,
242
+ healthCheck: (cred) => GithubApi.getUser(cred),
243
+ },
244
+ lovable: {
245
+ type: "lovable",
246
+ credentialType: "token",
247
+ operations: LOVABLE_OPERATIONS,
248
+ healthCheck: (cred) => LovableApi.getProjects(cred),
249
+ },
250
+ discord: {
251
+ type: "discord",
252
+ credentialType: "botToken",
253
+ operations: [],
254
+ healthCheck: async () => {},
255
+ },
256
+ teams: {
257
+ type: "teams",
258
+ credentialType: "botToken",
259
+ operations: [],
260
+ healthCheck: async () => {},
261
+ },
262
+ gchat: {
263
+ type: "gchat",
264
+ credentialType: "botToken",
265
+ operations: [],
266
+ healthCheck: async () => {},
267
+ },
268
+ linear: {
269
+ type: "linear",
270
+ credentialType: "botToken",
271
+ operations: [],
272
+ healthCheck: async () => {},
273
+ },
274
+ }
275
+
276
+ export function getConnectorSpec(type: string): ConnectorSpec | undefined {
277
+ return CONNECTOR_SPECS[type]
278
+ }
279
+
280
+ export function listConnectorTypes(): string[] {
281
+ return Object.keys(CONNECTOR_SPECS)
282
+ }
283
+
284
+ export async function createTools(name: string, connector: Config.Connector): Promise<Record<string, Tool>> {
285
+ const spec = CONNECTOR_SPECS[connector.type]
286
+ if (!spec) return {}
287
+
288
+ const credential = await resolveCredential(name, connector)
289
+ if (!credential) return {}
290
+
291
+ const tools: Record<string, Tool> = {}
292
+
293
+ for (const operation of spec.operations) {
294
+ const toolName = `${name}_${operation.name}`
295
+ tools[toolName] = dynamicTool({
296
+ description: operation.description,
297
+ inputSchema: jsonSchema({
298
+ type: "object",
299
+ properties: Object.fromEntries(
300
+ operation.args.map((arg) => [
301
+ arg.name,
302
+ {
303
+ type: arg.type ?? "string",
304
+ description: arg.description,
305
+ ...(arg.enum && { enum: arg.enum }),
306
+ },
307
+ ]),
308
+ ),
309
+ required: operation.args.filter((arg) => arg.required).map((arg) => arg.name),
310
+ additionalProperties: false,
311
+ }),
312
+ execute: async (args: unknown) => {
313
+ const typedArgs = args as Record<string, any>
314
+ const result = await operation.execute(credential, typedArgs)
315
+ return typeof result === "string" ? result : JSON.stringify(result, null, 2)
316
+ },
317
+ }) as Tool
318
+ }
319
+
320
+ return tools
321
+ }
322
+
323
+ export async function executeOperation(
324
+ name: string,
325
+ connector: Config.Connector,
326
+ operationName: string,
327
+ args: Record<string, any>,
328
+ ): Promise<any> {
329
+ const spec = CONNECTOR_SPECS[connector.type]
330
+ if (!spec) throw new Error(`Unknown connector type: ${connector.type}`)
331
+
332
+ const credential = await resolveCredential(name, connector)
333
+ if (!credential) throw new Error(`No credential for connector "${name}"`)
334
+
335
+ const operation = spec.operations.find((op) => op.name === operationName)
336
+ if (!operation) throw new Error(`Unknown operation: ${operationName}`)
337
+
338
+ return operation.execute(credential, args)
339
+ }
340
+
341
+ export function getHealthCheck(type: string): ((credential: string) => Promise<void>) | undefined {
342
+ return CONNECTOR_SPECS[type]?.healthCheck
343
+ }
344
+
345
+ export function getOperationSpec(type: string, operationName: string): OperationSpec | undefined {
346
+ return CONNECTOR_SPECS[type]?.operations.find((op) => op.name === operationName)
347
+ }
348
+
349
+ export function getPrompts(type: string): Array<{ name: string; description: string; args: OperationArg[] }> {
350
+ const spec = CONNECTOR_SPECS[type]
351
+ if (!spec) return []
352
+
353
+ return spec.operations.map((op) => ({
354
+ name: op.name,
355
+ description: op.description,
356
+ args: op.args,
357
+ }))
358
+ }
@@ -0,0 +1,120 @@
1
+ import path from "path"
2
+ import { mkdir } from "fs/promises"
3
+ import { Global } from "@/global"
4
+ import { getAllDocs, type DocEntry } from "./library"
5
+
6
+ type DocsContext = {
7
+ ids: string[]
8
+ updatedAt: number
9
+ }
10
+
11
+ const DIR = path.join(Global.Path.data, "docs")
12
+ const FILE = path.join(DIR, "context.json")
13
+ const MAX_SUMMARY_CHARS = 4000
14
+ const MAX_FULL_CHARS = 20000
15
+
16
+ async function ensureDir() {
17
+ await mkdir(DIR, { recursive: true })
18
+ }
19
+
20
+ async function readContext(): Promise<DocsContext> {
21
+ const file = Bun.file(FILE)
22
+ const exists = await file.exists()
23
+ if (!exists) return { ids: [], updatedAt: Date.now() }
24
+ const data = await file.json().catch(() => null)
25
+ if (!data || !Array.isArray(data.ids)) return { ids: [], updatedAt: Date.now() }
26
+ return {
27
+ ids: data.ids,
28
+ updatedAt: typeof data.updatedAt === "number" ? data.updatedAt : Date.now(),
29
+ }
30
+ }
31
+
32
+ async function writeContext(context: DocsContext): Promise<void> {
33
+ await ensureDir()
34
+ await Bun.write(FILE, JSON.stringify(context, null, 2))
35
+ }
36
+
37
+ function unique(ids: string[]): string[] {
38
+ return Array.from(new Set(ids))
39
+ }
40
+
41
+ export async function loadDocs(ids: string[]): Promise<{ loaded: DocEntry[]; missing: string[] }> {
42
+ const ctx = await readContext()
43
+ const all = await getAllDocs()
44
+ const valid = all.filter((entry) => ids.some((id) => matches(entry, id)))
45
+ const foundIds = valid.map((entry) => entry.id)
46
+ const missing = ids.filter((id) => !all.some((entry) => matches(entry, id)))
47
+ const next = unique([...ctx.ids, ...foundIds])
48
+ await writeContext({ ids: next, updatedAt: Date.now() })
49
+ return { loaded: valid, missing }
50
+ }
51
+
52
+ export async function unloadDocs(ids?: string[]): Promise<{ removed: string[] }> {
53
+ const ctx = await readContext()
54
+ if (!ids || ids.length === 0) {
55
+ await writeContext({ ids: [], updatedAt: Date.now() })
56
+ return { removed: ctx.ids }
57
+ }
58
+ const all = await getAllDocs()
59
+ const loaded = ctx.ids
60
+ .map((id) => all.find((entry) => entry.id === id))
61
+ .filter((entry): entry is DocEntry => Boolean(entry))
62
+ const toRemove = loaded.filter((entry) => ids.some((id) => matches(entry, id))).map((entry) => entry.id)
63
+ const removed = ctx.ids.filter((id) => toRemove.includes(id))
64
+ const next = ctx.ids.filter((id) => !toRemove.includes(id))
65
+ await writeContext({ ids: next, updatedAt: Date.now() })
66
+ return { removed }
67
+ }
68
+
69
+ export async function getLoadedDocs(): Promise<DocEntry[]> {
70
+ const ctx = await readContext()
71
+ if (ctx.ids.length === 0) return []
72
+ const docs = await getAllDocs()
73
+ const sorted = ctx.ids
74
+ .map((id) => docs.find((entry) => entry.id === id))
75
+ .filter((entry): entry is DocEntry => Boolean(entry))
76
+ return sorted
77
+ }
78
+
79
+ function summaryLine(entry: DocEntry): string {
80
+ const tags = entry.tags.length > 0 ? ` tags: ${entry.tags.join(", ")}` : ""
81
+ return `- ${entry.title} (${entry.category})${tags}`
82
+ }
83
+
84
+ function matches(entry: DocEntry, key: string): boolean {
85
+ const lower = key.toLowerCase()
86
+ if (entry.id === key) return true
87
+ if (entry.url.toLowerCase().includes(lower)) return true
88
+ if (entry.title.toLowerCase().includes(lower)) return true
89
+ if (entry.tags.some((tag) => tag.toLowerCase().includes(lower))) return true
90
+ return false
91
+ }
92
+
93
+ export async function getContextSummary(): Promise<string> {
94
+ const docs = await getLoadedDocs()
95
+ if (docs.length === 0) return "No documentation loaded."
96
+ const lines = docs.map(summaryLine)
97
+ const summary = `Documentation context (${docs.length} docs)\n` + lines.join("\n")
98
+ if (summary.length <= MAX_SUMMARY_CHARS) return summary
99
+ return summary.slice(0, MAX_SUMMARY_CHARS) + "\n[summary truncated]"
100
+ }
101
+
102
+ export async function getFullContext(): Promise<string> {
103
+ const docs = await getLoadedDocs()
104
+ if (docs.length === 0) return ""
105
+ const chunks = docs.map((entry) => {
106
+ return [
107
+ `## ${entry.title}`,
108
+ `Category: ${entry.category}`,
109
+ entry.tags.length > 0 ? `Tags: ${entry.tags.join(", ")}` : "",
110
+ entry.url ? `Source: ${entry.url}` : "",
111
+ "",
112
+ entry.content,
113
+ ]
114
+ .filter(Boolean)
115
+ .join("\n")
116
+ })
117
+ const content = `# DOCUMENTATION CONTEXT\n\n` + chunks.join("\n\n---\n\n")
118
+ if (content.length <= MAX_FULL_CHARS) return content
119
+ return content.slice(0, MAX_FULL_CHARS) + "\n[context truncated]"
120
+ }
@@ -0,0 +1,189 @@
1
+ import path from "path"
2
+ import { mkdir } from "fs/promises"
3
+ import { randomUUID } from "crypto"
4
+ import TurndownService from "turndown"
5
+ import { Global } from "@/global"
6
+
7
+ export type DocEntry = {
8
+ id: string
9
+ url: string
10
+ title: string
11
+ content: string
12
+ category: string
13
+ tags: string[]
14
+ addedAt: number
15
+ }
16
+
17
+ export type DocSearchResult = {
18
+ entry: DocEntry
19
+ score: number
20
+ snippet: string
21
+ terms: string[]
22
+ }
23
+
24
+ const DIR = path.join(Global.Path.data, "docs")
25
+ const LIB = path.join(DIR, "library.json")
26
+ const MAX_CONTENT = 60000
27
+ const MIN_CONTENT = 200
28
+
29
+ const turndown = new TurndownService({
30
+ codeBlockStyle: "fenced",
31
+ headingStyle: "atx",
32
+ })
33
+
34
+ async function ensureDir() {
35
+ await mkdir(DIR, { recursive: true })
36
+ }
37
+
38
+ async function readAll(): Promise<DocEntry[]> {
39
+ const file = Bun.file(LIB)
40
+ const exists = await file.exists()
41
+ if (!exists) return []
42
+ const data = await file.json()
43
+ const list = Array.isArray(data) ? data : []
44
+ return list as DocEntry[]
45
+ }
46
+
47
+ async function writeAll(list: DocEntry[]): Promise<void> {
48
+ await ensureDir()
49
+ await Bun.write(LIB, JSON.stringify(list, null, 2))
50
+ }
51
+
52
+ function cleanHtml(html: string): string {
53
+ const noScript = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, " ")
54
+ const noStyle = noScript.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, " ")
55
+ return noStyle
56
+ }
57
+
58
+ function toText(html: string): string {
59
+ const cleaned = cleanHtml(html)
60
+ const text = turndown.turndown(cleaned)
61
+ return text.replace(/\n{3,}/g, "\n\n").trim()
62
+ }
63
+
64
+ function getTitle(html: string, url: string): string {
65
+ const match = html.match(/<title[^>]*>([^<]+)<\/title>/i)
66
+ if (match?.[1]) return match[1].trim().slice(0, 120)
67
+ return url
68
+ }
69
+
70
+ function normalize(text: string): string {
71
+ return text
72
+ .toLowerCase()
73
+ .replace(/[^a-z0-9\s]/g, " ")
74
+ .replace(/\s+/g, " ")
75
+ .trim()
76
+ }
77
+
78
+ function terms(text: string): string[] {
79
+ const list = normalize(text).split(" ").filter(Boolean)
80
+ if (list.length === 0) return []
81
+ return Array.from(new Set(list))
82
+ }
83
+
84
+ function score(entry: DocEntry, query: string): { score: number; terms: string[] } {
85
+ const items = terms(query)
86
+ if (items.length === 0) return { score: 0, terms: [] }
87
+ const title = normalize(entry.title)
88
+ const body = normalize(entry.content)
89
+ const tags = entry.tags.map((tag) => normalize(tag)).join(" ")
90
+ const base = items.reduce((sum, item) => {
91
+ const inTitle = title.includes(item) ? 2 : 0
92
+ const inBody = body.includes(item) ? 1 : 0
93
+ const inTags = tags.includes(item) ? 1 : 0
94
+ return sum + inTitle + inBody + inTags
95
+ }, 0)
96
+ const value = base / items.length
97
+ return { score: value, terms: items }
98
+ }
99
+
100
+ function snippet(entry: DocEntry, query: string): string {
101
+ const items = terms(query)
102
+ const text = entry.content
103
+ const lower = text.toLowerCase()
104
+ const idx = items
105
+ .map((item) => lower.indexOf(item))
106
+ .filter((val) => val >= 0)
107
+ .sort((a, b) => a - b)[0]
108
+ if (idx === undefined) return text.slice(0, 200)
109
+ const start = Math.max(0, idx - 80)
110
+ const end = Math.min(text.length, idx + 140)
111
+ return text.slice(start, end).replace(/\s+/g, " ").trim()
112
+ }
113
+
114
+ function match(entry: DocEntry, key: string): boolean {
115
+ const lower = key.toLowerCase()
116
+ if (entry.id === key) return true
117
+ if (entry.url.toLowerCase().includes(lower)) return true
118
+ if (entry.title.toLowerCase().includes(lower)) return true
119
+ if (entry.tags.some((tag) => tag.toLowerCase().includes(lower))) return true
120
+ return false
121
+ }
122
+
123
+ export async function addDoc(input: { url: string; category?: string; tags?: string[] }): Promise<DocEntry> {
124
+ const res = await fetch(input.url)
125
+ if (!res.ok) {
126
+ throw new Error(`Docs fetch failed: ${res.status} ${res.statusText}`)
127
+ }
128
+ const html = await res.text()
129
+ const title = getTitle(html, input.url)
130
+ const text = toText(html)
131
+ if (text.length < MIN_CONTENT) {
132
+ throw new Error("Docs content too short to index")
133
+ }
134
+
135
+ const entry: DocEntry = {
136
+ id: randomUUID(),
137
+ url: input.url,
138
+ title,
139
+ content: text.slice(0, MAX_CONTENT),
140
+ category: input.category || "general",
141
+ tags: (input.tags ?? []).filter(Boolean),
142
+ addedAt: Date.now(),
143
+ }
144
+
145
+ await ensureDir()
146
+ const list = await readAll()
147
+ const next = [entry, ...list]
148
+ await writeAll(next)
149
+ return entry
150
+ }
151
+
152
+ export async function listDocs(category?: string): Promise<DocEntry[]> {
153
+ const list = await readAll()
154
+ if (!category) return list
155
+ return list.filter((item) => item.category === category)
156
+ }
157
+
158
+ export async function getAllDocs(): Promise<DocEntry[]> {
159
+ return readAll()
160
+ }
161
+
162
+ export async function getDoc(key: string): Promise<DocEntry | undefined> {
163
+ const list = await readAll()
164
+ return list.find((entry) => match(entry, key))
165
+ }
166
+
167
+ export async function getDocs(keys: string[]): Promise<DocEntry[]> {
168
+ const list = await readAll()
169
+ return list.filter((entry) => keys.some((key) => match(entry, key)))
170
+ }
171
+
172
+ export async function searchDocs(query: string, category?: string, limit = 5): Promise<DocSearchResult[]> {
173
+ const list = await readAll()
174
+ const items = category ? list.filter((item) => item.category === category) : list
175
+ const scored = items
176
+ .map((entry) => {
177
+ const result = score(entry, query)
178
+ return {
179
+ entry,
180
+ score: result.score,
181
+ snippet: snippet(entry, query),
182
+ terms: result.terms,
183
+ }
184
+ })
185
+ .filter((item) => item.score > 0)
186
+ .sort((a, b) => b.score - a.score)
187
+ .slice(0, limit)
188
+ return scored
189
+ }
@@ -0,0 +1,26 @@
1
+ import { Instance } from "../project/instance"
2
+
3
+ export namespace Env {
4
+ const state = Instance.state(() => {
5
+ return process.env as Record<string, string | undefined>
6
+ })
7
+
8
+ export function get(key: string) {
9
+ const env = state()
10
+ return env[key]
11
+ }
12
+
13
+ export function all() {
14
+ return state()
15
+ }
16
+
17
+ export function set(key: string, value: string) {
18
+ const env = state()
19
+ env[key] = value
20
+ }
21
+
22
+ export function remove(key: string) {
23
+ const env = state()
24
+ delete env[key]
25
+ }
26
+ }