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,330 @@
1
+ import type { DBSchema, DBTable, DBColumn, DBForeignKey, DBIndex, TablePreview, QueryResult } from "./types"
2
+ import type { IDBConnection, ConnectionConfig } from "./connections"
3
+
4
+ export class MySQLConnection implements IDBConnection {
5
+ readonly type = "mysql"
6
+ private _config: ConnectionConfig
7
+ private _connection: any = null
8
+
9
+ constructor(config: ConnectionConfig) {
10
+ this._config = config
11
+ }
12
+
13
+ get connected(): boolean {
14
+ return this._connection !== null
15
+ }
16
+
17
+ private async _getConnection(): Promise<any> {
18
+ if (!this._connection) {
19
+ const mysql = await import("mysql2/promise")
20
+ this._connection = await mysql.default.createConnection({
21
+ host: this._config.host,
22
+ port: this._config.port || 3306,
23
+ database: this._config.database,
24
+ user: this._config.username,
25
+ password: this._config.password,
26
+ })
27
+ }
28
+ return this._connection
29
+ }
30
+
31
+ async getSchema(): Promise<DBSchema> {
32
+ const conn = await this._getConnection()
33
+ const tables = await this._getMySQLTables(conn)
34
+ const views = await this._getMySQLViews(conn)
35
+ const indexes = await this._getMySQLIndexes(conn)
36
+ return { tables, views, indexes }
37
+ }
38
+
39
+ private async _getMySQLTables(conn: any): Promise<DBTable[]> {
40
+ const [rows] = await conn.query(`
41
+ SELECT table_name
42
+ FROM information_schema.tables
43
+ WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
44
+ ORDER BY table_name
45
+ `)
46
+
47
+ const tables: DBTable[] = []
48
+ for (const row of rows as any[]) {
49
+ const tableName = row.TABLE_NAME
50
+ const columns = await this._getMySQLTableInfo(conn, tableName)
51
+ const rowCount = await this._getMySQLRowCount(conn, tableName)
52
+ const foreignKeys = await this._getMySQLForeignKeys(conn, tableName)
53
+
54
+ tables.push({
55
+ name: tableName,
56
+ columns,
57
+ primaryKey: columns.filter((c) => c.primaryKey).map((c) => c.name),
58
+ foreignKeys,
59
+ rowCount,
60
+ })
61
+ }
62
+ return tables
63
+ }
64
+
65
+ private async _getMySQLTableInfo(conn: any, tableName: string): Promise<DBColumn[]> {
66
+ const [rows] = await conn.query(
67
+ `
68
+ SELECT column_name, data_type, is_nullable, column_default, extra
69
+ FROM information_schema.columns
70
+ WHERE table_schema = DATABASE() AND table_name = ?
71
+ ORDER BY ordinal_position
72
+ `,
73
+ [tableName],
74
+ )
75
+
76
+ const pkResult = await conn.query(
77
+ `
78
+ SELECT column_name
79
+ FROM information_schema.key_column_usage
80
+ WHERE table_schema = DATABASE() AND table_name = ? AND constraint_name = 'PRIMARY'
81
+ `,
82
+ [tableName],
83
+ )
84
+
85
+ const pkColumns = new Set((pkResult[0] as any[]).map((r: any) => r.column_name))
86
+
87
+ return (rows as any[]).map((col: any) => ({
88
+ name: col.COLUMN_NAME,
89
+ type: col.DATA_TYPE.toUpperCase(),
90
+ notNull: col.IS_NULLABLE === "NO",
91
+ defaultValue: col.COLUMN_DEFAULT || undefined,
92
+ primaryKey: pkColumns.has(col.COLUMN_NAME),
93
+ }))
94
+ }
95
+
96
+ private async _getMySQLRowCount(conn: any, tableName: string): Promise<number> {
97
+ try {
98
+ const [rows] = await conn.query(`SELECT COUNT(*) as count FROM ${tableName}`)
99
+ return (rows as any[])[0]?.count || 0
100
+ } catch {
101
+ return 0
102
+ }
103
+ }
104
+
105
+ private async _getMySQLForeignKeys(conn: any, tableName: string): Promise<DBForeignKey[]> {
106
+ const [rows] = await conn.query(
107
+ `
108
+ SELECT
109
+ column_name,
110
+ referenced_table_name,
111
+ referenced_column_name,
112
+ delete_rule
113
+ FROM information_schema.key_column_usage
114
+ WHERE table_schema = DATABASE()
115
+ AND table_name = ?
116
+ AND referenced_table_name IS NOT NULL
117
+ `,
118
+ [tableName],
119
+ )
120
+
121
+ return (rows as any[]).map((row: any) => ({
122
+ table: tableName,
123
+ column: row.COLUMN_NAME,
124
+ referencedTable: row.REFERENCED_TABLE_NAME,
125
+ referencedColumn: row.REFERENCED_COLUMN_NAME,
126
+ onDelete: this._mapMySQLOnDelete(row.DELETE_RULE),
127
+ }))
128
+ }
129
+
130
+ private _mapMySQLOnDelete(rule: string): "CASCADE" | "RESTRICT" | "SET NULL" | "NO ACTION" {
131
+ switch (rule) {
132
+ case "CASCADE":
133
+ return "CASCADE"
134
+ case "RESTRICT":
135
+ return "RESTRICT"
136
+ case "SET NULL":
137
+ return "SET NULL"
138
+ default:
139
+ return "NO ACTION"
140
+ }
141
+ }
142
+
143
+ private async _getMySQLViews(conn: any): Promise<Array<{ name: string; sql: string }>> {
144
+ const [rows] = await conn.query(`
145
+ SELECT table_name AS name, view_definition
146
+ FROM information_schema.views
147
+ WHERE table_schema = DATABASE()
148
+ ORDER BY table_name
149
+ `)
150
+
151
+ return (rows as any[]).map((row: any) => ({
152
+ name: row.name,
153
+ sql: row.view_definition || "",
154
+ }))
155
+ }
156
+
157
+ private async _getMySQLIndexes(conn: any): Promise<DBIndex[]> {
158
+ const [rows] = await conn.query(`
159
+ SELECT index_name, table_name, non_unique, index_columns
160
+ FROM information_schema.statistics
161
+ WHERE table_schema = DATABASE()
162
+ ORDER BY table_name, index_name
163
+ `)
164
+
165
+ const indexMap = new Map<string, DBIndex>()
166
+ for (const row of rows as any[]) {
167
+ const key = `${row.TABLE_NAME}_${row.INDEX_NAME}`
168
+ if (!indexMap.has(key)) {
169
+ indexMap.set(key, {
170
+ name: row.INDEX_NAME,
171
+ tableName: row.TABLE_NAME,
172
+ columns: [],
173
+ unique: row.NON_UNIQUE === 0,
174
+ })
175
+ }
176
+ indexMap.get(key)!.columns.push(row.COLUMN_NAME)
177
+ }
178
+
179
+ return Array.from(indexMap.values())
180
+ }
181
+
182
+ async getTablePreview(tableName: string, limit: number = 10): Promise<TablePreview> {
183
+ const conn = await this._getConnection()
184
+ const schema = await this.getSchema()
185
+ const table = schema.tables.find((t) => t.name === tableName)
186
+
187
+ if (!table) {
188
+ return { tableName, columns: [], sampleData: [], rowCount: 0 }
189
+ }
190
+
191
+ const [rows] = await conn.query(`SELECT * FROM ${tableName} LIMIT ?`, [limit])
192
+
193
+ return {
194
+ tableName,
195
+ columns: table.columns,
196
+ sampleData: rows as any[],
197
+ rowCount: table.rowCount ?? 0,
198
+ }
199
+ }
200
+
201
+ async executeQuery(sql: string): Promise<QueryResult> {
202
+ const conn = await this._getConnection()
203
+ const startTime = Date.now()
204
+
205
+ try {
206
+ const isSelect = sql.trim().toUpperCase().startsWith("SELECT")
207
+
208
+ if (isSelect) {
209
+ const [rows, fields] = await conn.query(sql)
210
+ const columns = fields ? fields.map((f: any) => f.name) : []
211
+
212
+ return {
213
+ columns,
214
+ rows: rows as any[],
215
+ rowCount: Array.isArray(rows) ? rows.length : 0,
216
+ executionTime: Date.now() - startTime,
217
+ }
218
+ } else {
219
+ const [result] = await conn.query(sql)
220
+ return {
221
+ columns: ["affected_rows"],
222
+ rows: [{ affected_rows: (result as any).affectedRows || 0 }],
223
+ rowCount: 1,
224
+ executionTime: Date.now() - startTime,
225
+ }
226
+ }
227
+ } catch (error) {
228
+ throw new Error(`Query failed: ${error}`)
229
+ }
230
+ }
231
+
232
+ async executeCommand(sql: string): Promise<void> {
233
+ const conn = await this._getConnection()
234
+ await conn.query(sql)
235
+ }
236
+
237
+ async createTable(name: string, columns: DBColumn[], foreignKeys?: DBForeignKey[]): Promise<void> {
238
+ const columnDefs = columns.map((col) => {
239
+ let def = `${col.name} ${col.type}`
240
+ if (col.notNull) def += " NOT NULL"
241
+ if (col.defaultValue) def += ` DEFAULT ${col.defaultValue}`
242
+ return def
243
+ })
244
+
245
+ const fkDefs =
246
+ foreignKeys?.map(
247
+ (fk) =>
248
+ `FOREIGN KEY (${fk.column}) REFERENCES ${fk.referencedTable}(${fk.referencedColumn}) ON DELETE ${fk.onDelete}`,
249
+ ) || []
250
+
251
+ const pkColumns = columns.filter((c) => c.primaryKey).map((c) => c.name)
252
+ const pkDef = pkColumns.length > 0 ? `, PRIMARY KEY (${pkColumns.join(", ")})` : ""
253
+
254
+ const sql = `CREATE TABLE ${name} (${columnDefs.concat(fkDefs).join(", ")}${pkDef})`
255
+ await this.executeCommand(sql)
256
+ }
257
+
258
+ async dropTable(name: string): Promise<void> {
259
+ await this.executeCommand(`DROP TABLE IF EXISTS ${name}`)
260
+ }
261
+
262
+ async addColumn(tableName: string, column: DBColumn): Promise<void> {
263
+ let sql = `ALTER TABLE ${tableName} ADD COLUMN ${column.name} ${column.type}`
264
+ if (column.notNull) sql += " NOT NULL"
265
+ if (column.defaultValue) sql += ` DEFAULT ${column.defaultValue}`
266
+ await this.executeCommand(sql)
267
+ }
268
+
269
+ async dropColumn(tableName: string, columnName: string): Promise<void> {
270
+ await this.executeCommand(`ALTER TABLE ${tableName} DROP COLUMN ${columnName}`)
271
+ }
272
+
273
+ async modifyColumn(tableName: string, columnName: string, newDef: DBColumn): Promise<void> {
274
+ await this.executeCommand(`ALTER TABLE ${tableName} CHANGE ${columnName} ${newDef.name} ${newDef.type}`)
275
+ }
276
+
277
+ async getIndexes(): Promise<DBIndex[]> {
278
+ return this._getMySQLIndexes(await this._getConnection())
279
+ }
280
+
281
+ async createIndex(name: string, tableName: string, columns: string[], unique: boolean = false): Promise<void> {
282
+ const uniqueStr = unique ? " UNIQUE" : ""
283
+ const cols = columns.join(", ")
284
+ await this.executeCommand(`CREATE${uniqueStr} INDEX ${name} ON ${tableName} (${cols})`)
285
+ }
286
+
287
+ async dropIndex(name: string): Promise<void> {
288
+ await this.executeCommand(`DROP INDEX IF EXISTS ${name}`)
289
+ }
290
+
291
+ async beginTransaction(): Promise<void> {
292
+ const conn = await this._getConnection()
293
+ await conn.beginTransaction()
294
+ }
295
+
296
+ async commit(): Promise<void> {
297
+ const conn = await this._getConnection()
298
+ await conn.commit()
299
+ }
300
+
301
+ async rollback(): Promise<void> {
302
+ const conn = await this._getConnection()
303
+ await conn.rollback()
304
+ }
305
+
306
+ async close(): Promise<void> {
307
+ if (this._connection) {
308
+ await this._connection.end()
309
+ this._connection = null
310
+ }
311
+ }
312
+
313
+ static async testConnection(config: ConnectionConfig): Promise<boolean> {
314
+ try {
315
+ const mysql = await import("mysql2/promise")
316
+ const conn = await mysql.default.createConnection({
317
+ host: config.host,
318
+ port: config.port || 3306,
319
+ database: config.database,
320
+ user: config.username,
321
+ password: config.password,
322
+ })
323
+ await conn.query("SELECT 1")
324
+ await conn.end()
325
+ return true
326
+ } catch {
327
+ return false
328
+ }
329
+ }
330
+ }
@@ -0,0 +1,338 @@
1
+ import type { DBSchema, DBTable, DBColumn, DBForeignKey, DBIndex, TablePreview, QueryResult } from "./types"
2
+ import type { IDBConnection, ConnectionConfig } from "./connections"
3
+
4
+ export class PostgresConnection implements IDBConnection {
5
+ readonly type = "postgres"
6
+ private _config: ConnectionConfig
7
+ private _pool: any = null
8
+
9
+ constructor(config: ConnectionConfig) {
10
+ this._config = config
11
+ }
12
+
13
+ get connected(): boolean {
14
+ return this._pool !== null
15
+ }
16
+
17
+ private async _getPool(): Promise<any> {
18
+ if (!this._pool) {
19
+ const { default: pg } = await import("pg")
20
+ const { Pool } = pg
21
+ this._pool = new Pool({
22
+ host: this._config.host,
23
+ port: this._config.port || 5432,
24
+ database: this._config.database,
25
+ user: this._config.username,
26
+ password: this._config.password,
27
+ })
28
+ }
29
+ return this._pool
30
+ }
31
+
32
+ async getSchema(): Promise<DBSchema> {
33
+ const pool = await this._getPool()
34
+ const tables = await this._getPgTables(pool)
35
+ const views = await this._getPgViews(pool)
36
+ const indexes = await this._getPgIndexes(pool)
37
+ return { tables, views, indexes }
38
+ }
39
+
40
+ private async _getPgTables(pool: any): Promise<DBTable[]> {
41
+ const result = await pool.query(`
42
+ SELECT table_name, table_schema
43
+ FROM information_schema.tables
44
+ WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
45
+ ORDER BY table_name
46
+ `)
47
+
48
+ const tables: DBTable[] = []
49
+ for (const row of result.rows) {
50
+ const tableName = row.table_name
51
+ const columns = await this._getPgTableInfo(pool, tableName)
52
+ const rowCount = await this._getPgRowCount(pool, tableName)
53
+ const foreignKeys = await this._getPgForeignKeys(pool, tableName)
54
+
55
+ tables.push({
56
+ name: tableName,
57
+ columns,
58
+ primaryKey: columns.filter((c) => c.primaryKey).map((c) => c.name),
59
+ foreignKeys,
60
+ rowCount,
61
+ })
62
+ }
63
+ return tables
64
+ }
65
+
66
+ private async _getPgTableInfo(pool: any, tableName: string): Promise<DBColumn[]> {
67
+ const result = await pool.query(
68
+ `
69
+ SELECT column_name, data_type, is_nullable, column_default, is_identity
70
+ FROM information_schema.columns
71
+ WHERE table_name = $1
72
+ ORDER BY ordinal_position
73
+ `,
74
+ [tableName],
75
+ )
76
+
77
+ const pkResult = await pool.query(
78
+ `
79
+ SELECT a.attname as column_name
80
+ FROM pg_index i
81
+ JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
82
+ WHERE i.indrelid = $1::regclass AND i.indisprimary
83
+ `,
84
+ [tableName],
85
+ )
86
+
87
+ const pkColumns = new Set(pkResult.rows.map((r: any) => r.column_name))
88
+
89
+ return result.rows.map((col: any) => ({
90
+ name: col.column_name,
91
+ type: col.data_type.toUpperCase(),
92
+ notNull: col.is_nullable === "NO",
93
+ defaultValue: col.column_default || undefined,
94
+ primaryKey: pkColumns.has(col.column_name),
95
+ }))
96
+ }
97
+
98
+ private async _getPgRowCount(pool: any, tableName: string): Promise<number> {
99
+ try {
100
+ const result = await pool.query(`SELECT COUNT(*) as count FROM ${tableName}`)
101
+ return parseInt(result.rows[0].count) || 0
102
+ } catch {
103
+ return 0
104
+ }
105
+ }
106
+
107
+ private async _getPgForeignKeys(pool: any, tableName: string): Promise<DBForeignKey[]> {
108
+ const result = await pool.query(
109
+ `
110
+ SELECT
111
+ kcu.column_name,
112
+ ccu.table_name AS referenced_table,
113
+ kcu.column_name AS referenced_column,
114
+ rc.delete_rule AS on_delete
115
+ FROM information_schema.table_constraints AS tc
116
+ JOIN information_schema.key_column_usage AS kcu
117
+ ON tc.constraint_name = kcu.constraint_name
118
+ AND tc.table_schema = kcu.table_schema
119
+ JOIN information_schema.constraint_column_usage AS ccu
120
+ ON ccu.constraint_name = tc.constraint_name
121
+ AND ccu.table_schema = tc.table_schema
122
+ WHERE tc.constraint_type = 'FOREIGN KEY'
123
+ AND tc.table_name = $1
124
+ `,
125
+ [tableName],
126
+ )
127
+
128
+ return result.rows.map((row: any) => ({
129
+ table: tableName,
130
+ column: row.column_name,
131
+ referencedTable: row.referenced_table,
132
+ referencedColumn: row.referenced_column,
133
+ onDelete: this._mapPgOnDelete(row.on_delete),
134
+ }))
135
+ }
136
+
137
+ private _mapPgOnDelete(rule: string): "CASCADE" | "RESTRICT" | "SET NULL" | "NO ACTION" {
138
+ switch (rule) {
139
+ case "CASCADE":
140
+ return "CASCADE"
141
+ case "RESTRICT":
142
+ return "RESTRICT"
143
+ case "SET NULL":
144
+ return "SET NULL"
145
+ default:
146
+ return "NO ACTION"
147
+ }
148
+ }
149
+
150
+ private async _getPgViews(pool: any): Promise<Array<{ name: string; sql: string }>> {
151
+ const result = await pool.query(`
152
+ SELECT table_name AS name, view_definition
153
+ FROM information_schema.views
154
+ WHERE table_schema = 'public'
155
+ ORDER BY table_name
156
+ `)
157
+
158
+ return result.rows.map((row: any) => ({
159
+ name: row.name,
160
+ sql: row.view_definition || "",
161
+ }))
162
+ }
163
+
164
+ private async _getPgIndexes(pool: any): Promise<DBIndex[]> {
165
+ const result = await pool.query(`
166
+ SELECT indexname, tablename, indexdef
167
+ FROM pg_indexes
168
+ WHERE schemaname = 'public'
169
+ ORDER BY tablename, indexname
170
+ `)
171
+
172
+ return result.rows.map((row: any) => {
173
+ const columns = this._extractPgIndexColumns(row.indexdef)
174
+ return {
175
+ name: row.indexname,
176
+ tableName: row.tablename,
177
+ columns,
178
+ unique: row.indexdef.toUpperCase().includes("UNIQUE"),
179
+ }
180
+ })
181
+ }
182
+
183
+ private _extractPgIndexColumns(indexDef: string): string[] {
184
+ const match = indexDef.match(/\(([^)]+)\)/)
185
+ if (!match) return []
186
+ return match[1].split(",").map((c) => c.trim())
187
+ }
188
+
189
+ async getTablePreview(tableName: string, limit: number = 10): Promise<TablePreview> {
190
+ const pool = await this._getPool()
191
+ const schema = await this.getSchema()
192
+ const table = schema.tables.find((t) => t.name === tableName)
193
+
194
+ if (!table) {
195
+ return { tableName, columns: [], sampleData: [], rowCount: 0 }
196
+ }
197
+
198
+ const result = await pool.query(`SELECT * FROM ${tableName} LIMIT $1`, [limit])
199
+
200
+ return {
201
+ tableName,
202
+ columns: table.columns,
203
+ sampleData: result.rows as any[],
204
+ rowCount: table.rowCount ?? 0,
205
+ }
206
+ }
207
+
208
+ async executeQuery(sql: string): Promise<QueryResult> {
209
+ const pool = await this._getPool()
210
+ const startTime = Date.now()
211
+
212
+ try {
213
+ const isSelect = sql.trim().toUpperCase().startsWith("SELECT")
214
+
215
+ if (isSelect) {
216
+ const result = await pool.query(sql)
217
+ const columns = result.fields.map((f: any) => f.name)
218
+
219
+ return {
220
+ columns,
221
+ rows: result.rows as any[],
222
+ rowCount: result.rowCount || 0,
223
+ executionTime: Date.now() - startTime,
224
+ }
225
+ } else {
226
+ const result = await pool.query(sql)
227
+ return {
228
+ columns: ["affected_rows"],
229
+ rows: [{ affected_rows: result.rowCount || 0 }],
230
+ rowCount: 1,
231
+ executionTime: Date.now() - startTime,
232
+ }
233
+ }
234
+ } catch (error) {
235
+ throw new Error(`Query failed: ${error}`)
236
+ }
237
+ }
238
+
239
+ async executeCommand(sql: string): Promise<void> {
240
+ const pool = await this._getPool()
241
+ await pool.query(sql)
242
+ }
243
+
244
+ async createTable(name: string, columns: DBColumn[], foreignKeys?: DBForeignKey[]): Promise<void> {
245
+ const columnDefs = columns.map((col) => {
246
+ let def = `${col.name} ${col.type}`
247
+ if (col.notNull) def += " NOT NULL"
248
+ if (col.defaultValue) def += ` DEFAULT ${col.defaultValue}`
249
+ return def
250
+ })
251
+
252
+ const fkDefs =
253
+ foreignKeys?.map(
254
+ (fk) =>
255
+ `FOREIGN KEY (${fk.column}) REFERENCES ${fk.referencedTable}(${fk.referencedColumn}) ON DELETE ${fk.onDelete}`,
256
+ ) || []
257
+
258
+ const pkColumns = columns.filter((c) => c.primaryKey).map((c) => c.name)
259
+ const pkDef = pkColumns.length > 0 ? `, PRIMARY KEY (${pkColumns.join(", ")})` : ""
260
+
261
+ const sql = `CREATE TABLE ${name} (${columnDefs.concat(fkDefs).join(", ")}${pkDef})`
262
+ await this.executeCommand(sql)
263
+ }
264
+
265
+ async dropTable(name: string): Promise<void> {
266
+ await this.executeCommand(`DROP TABLE IF EXISTS ${name}`)
267
+ }
268
+
269
+ async addColumn(tableName: string, column: DBColumn): Promise<void> {
270
+ let sql = `ALTER TABLE ${tableName} ADD COLUMN ${column.name} ${column.type}`
271
+ if (column.notNull) sql += " NOT NULL"
272
+ if (column.defaultValue) sql += ` DEFAULT ${column.defaultValue}`
273
+ await this.executeCommand(sql)
274
+ }
275
+
276
+ async dropColumn(tableName: string, columnName: string): Promise<void> {
277
+ await this.executeCommand(`ALTER TABLE ${tableName} DROP COLUMN ${columnName}`)
278
+ }
279
+
280
+ async modifyColumn(tableName: string, columnName: string, newDef: DBColumn): Promise<void> {
281
+ await this.executeCommand(`ALTER TABLE ${tableName} RENAME COLUMN ${columnName} TO ${newDef.name}`)
282
+ if (newDef.type !== "TEXT") {
283
+ await this.executeCommand(`ALTER TABLE ${tableName} ALTER COLUMN ${newDef.name} TYPE ${newDef.type}`)
284
+ }
285
+ }
286
+
287
+ async getIndexes(): Promise<DBIndex[]> {
288
+ return this._getPgIndexes(await this._getPool())
289
+ }
290
+
291
+ async createIndex(name: string, tableName: string, columns: string[], unique: boolean = false): Promise<void> {
292
+ const uniqueStr = unique ? " UNIQUE" : ""
293
+ const cols = columns.join(", ")
294
+ await this.executeCommand(`CREATE${uniqueStr} INDEX IF NOT EXISTS ${name} ON ${tableName} (${cols})`)
295
+ }
296
+
297
+ async dropIndex(name: string): Promise<void> {
298
+ await this.executeCommand(`DROP INDEX IF EXISTS ${name}`)
299
+ }
300
+
301
+ async beginTransaction(): Promise<void> {
302
+ await this.executeCommand("BEGIN")
303
+ }
304
+
305
+ async commit(): Promise<void> {
306
+ await this.executeCommand("COMMIT")
307
+ }
308
+
309
+ async rollback(): Promise<void> {
310
+ await this.executeCommand("ROLLBACK")
311
+ }
312
+
313
+ async close(): Promise<void> {
314
+ if (this._pool) {
315
+ await this._pool.end()
316
+ this._pool = null
317
+ }
318
+ }
319
+
320
+ static async testConnection(config: ConnectionConfig): Promise<boolean> {
321
+ try {
322
+ const { default: pg } = await import("pg")
323
+ const { Pool } = pg
324
+ const pool = new Pool({
325
+ host: config.host,
326
+ port: config.port || 5432,
327
+ database: config.database,
328
+ user: config.username,
329
+ password: config.password,
330
+ })
331
+ await pool.query("SELECT 1")
332
+ await pool.end()
333
+ return true
334
+ } catch {
335
+ return false
336
+ }
337
+ }
338
+ }