@useconductor/conductor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (504) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +23 -0
  3. package/.eslintrc.json +23 -0
  4. package/.gitattributes +6 -0
  5. package/.github/FUNDING.yml +15 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +91 -0
  7. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.yml +63 -0
  9. package/.github/ISSUE_TEMPLATE/plugin_request.yml +71 -0
  10. package/.github/README.md +13 -0
  11. package/.github/workflows/README.md +22 -0
  12. package/.github/workflows/auto-release.yml +112 -0
  13. package/.github/workflows/ci.yml +49 -0
  14. package/.github/workflows/claude-code-review.yml +44 -0
  15. package/.github/workflows/claude.yml +36 -0
  16. package/.github/workflows/sync-install.yml +47 -0
  17. package/.mcp.json +9 -0
  18. package/.prettierrc.json +7 -0
  19. package/C.png +0 -0
  20. package/CHANGELOG.md +74 -0
  21. package/CLAUDE.md +118 -0
  22. package/CONTRIBUTING.md +231 -0
  23. package/LICENSE +201 -0
  24. package/README.md +179 -0
  25. package/SECURITY.md +47 -0
  26. package/commands/conductor-setup.md +11 -0
  27. package/commands/conductor-status.md +7 -0
  28. package/dist/ai/base.d.ts +44 -0
  29. package/dist/ai/base.d.ts.map +1 -0
  30. package/dist/ai/base.js +47 -0
  31. package/dist/ai/base.js.map +1 -0
  32. package/dist/ai/claude.d.ts +11 -0
  33. package/dist/ai/claude.d.ts.map +1 -0
  34. package/dist/ai/claude.js +149 -0
  35. package/dist/ai/claude.js.map +1 -0
  36. package/dist/ai/gemini.d.ts +15 -0
  37. package/dist/ai/gemini.d.ts.map +1 -0
  38. package/dist/ai/gemini.js +156 -0
  39. package/dist/ai/gemini.js.map +1 -0
  40. package/dist/ai/maestro.d.ts +22 -0
  41. package/dist/ai/maestro.d.ts.map +1 -0
  42. package/dist/ai/maestro.js +142 -0
  43. package/dist/ai/maestro.js.map +1 -0
  44. package/dist/ai/manager.d.ts +47 -0
  45. package/dist/ai/manager.d.ts.map +1 -0
  46. package/dist/ai/manager.js +450 -0
  47. package/dist/ai/manager.js.map +1 -0
  48. package/dist/ai/ollama.d.ts +16 -0
  49. package/dist/ai/ollama.d.ts.map +1 -0
  50. package/dist/ai/ollama.js +151 -0
  51. package/dist/ai/ollama.js.map +1 -0
  52. package/dist/ai/openai.d.ts +11 -0
  53. package/dist/ai/openai.d.ts.map +1 -0
  54. package/dist/ai/openai.js +132 -0
  55. package/dist/ai/openai.js.map +1 -0
  56. package/dist/ai/openrouter.d.ts +11 -0
  57. package/dist/ai/openrouter.d.ts.map +1 -0
  58. package/dist/ai/openrouter.js +139 -0
  59. package/dist/ai/openrouter.js.map +1 -0
  60. package/dist/bot/slack.d.ts +17 -0
  61. package/dist/bot/slack.d.ts.map +1 -0
  62. package/dist/bot/slack.js +144 -0
  63. package/dist/bot/slack.js.map +1 -0
  64. package/dist/bot/telegram.d.ts +19 -0
  65. package/dist/bot/telegram.d.ts.map +1 -0
  66. package/dist/bot/telegram.js +157 -0
  67. package/dist/bot/telegram.js.map +1 -0
  68. package/dist/cli/commands/ai.d.ts +4 -0
  69. package/dist/cli/commands/ai.d.ts.map +1 -0
  70. package/dist/cli/commands/ai.js +161 -0
  71. package/dist/cli/commands/ai.js.map +1 -0
  72. package/dist/cli/commands/doctor.d.ts +18 -0
  73. package/dist/cli/commands/doctor.d.ts.map +1 -0
  74. package/dist/cli/commands/doctor.js +213 -0
  75. package/dist/cli/commands/doctor.js.map +1 -0
  76. package/dist/cli/commands/init.d.ts +15 -0
  77. package/dist/cli/commands/init.d.ts.map +1 -0
  78. package/dist/cli/commands/init.js +281 -0
  79. package/dist/cli/commands/init.js.map +1 -0
  80. package/dist/cli/commands/install.d.ts +16 -0
  81. package/dist/cli/commands/install.d.ts.map +1 -0
  82. package/dist/cli/commands/install.js +750 -0
  83. package/dist/cli/commands/install.js.map +1 -0
  84. package/dist/cli/commands/lifecycle.d.ts +4 -0
  85. package/dist/cli/commands/lifecycle.d.ts.map +1 -0
  86. package/dist/cli/commands/lifecycle.js +84 -0
  87. package/dist/cli/commands/lifecycle.js.map +1 -0
  88. package/dist/cli/commands/marketplace.d.ts +13 -0
  89. package/dist/cli/commands/marketplace.d.ts.map +1 -0
  90. package/dist/cli/commands/marketplace.js +197 -0
  91. package/dist/cli/commands/marketplace.js.map +1 -0
  92. package/dist/cli/commands/mcp.d.ts +6 -0
  93. package/dist/cli/commands/mcp.d.ts.map +1 -0
  94. package/dist/cli/commands/mcp.js +83 -0
  95. package/dist/cli/commands/mcp.js.map +1 -0
  96. package/dist/cli/commands/onboard.d.ts +10 -0
  97. package/dist/cli/commands/onboard.d.ts.map +1 -0
  98. package/dist/cli/commands/onboard.js +207 -0
  99. package/dist/cli/commands/onboard.js.map +1 -0
  100. package/dist/cli/commands/plugin-create.d.ts +13 -0
  101. package/dist/cli/commands/plugin-create.d.ts.map +1 -0
  102. package/dist/cli/commands/plugin-create.js +122 -0
  103. package/dist/cli/commands/plugin-create.js.map +1 -0
  104. package/dist/cli/commands/plugins.d.ts +5 -0
  105. package/dist/cli/commands/plugins.d.ts.map +1 -0
  106. package/dist/cli/commands/plugins.js +30 -0
  107. package/dist/cli/commands/plugins.js.map +1 -0
  108. package/dist/cli/commands/release.d.ts +13 -0
  109. package/dist/cli/commands/release.d.ts.map +1 -0
  110. package/dist/cli/commands/release.js +243 -0
  111. package/dist/cli/commands/release.js.map +1 -0
  112. package/dist/cli/commands/telegram.d.ts +3 -0
  113. package/dist/cli/commands/telegram.d.ts.map +1 -0
  114. package/dist/cli/commands/telegram.js +20 -0
  115. package/dist/cli/commands/telegram.js.map +1 -0
  116. package/dist/cli/index.d.ts +3 -0
  117. package/dist/cli/index.d.ts.map +1 -0
  118. package/dist/cli/index.js +402 -0
  119. package/dist/cli/index.js.map +1 -0
  120. package/dist/config/oauth.d.ts +8 -0
  121. package/dist/config/oauth.d.ts.map +1 -0
  122. package/dist/config/oauth.js +13 -0
  123. package/dist/config/oauth.js.map +1 -0
  124. package/dist/core/audit.d.ts +91 -0
  125. package/dist/core/audit.d.ts.map +1 -0
  126. package/dist/core/audit.js +233 -0
  127. package/dist/core/audit.js.map +1 -0
  128. package/dist/core/circuit-breaker.d.ts +56 -0
  129. package/dist/core/circuit-breaker.d.ts.map +1 -0
  130. package/dist/core/circuit-breaker.js +107 -0
  131. package/dist/core/circuit-breaker.js.map +1 -0
  132. package/dist/core/conductor.d.ts +44 -0
  133. package/dist/core/conductor.d.ts.map +1 -0
  134. package/dist/core/conductor.js +200 -0
  135. package/dist/core/conductor.js.map +1 -0
  136. package/dist/core/config.d.ts +66 -0
  137. package/dist/core/config.d.ts.map +1 -0
  138. package/dist/core/config.js +86 -0
  139. package/dist/core/config.js.map +1 -0
  140. package/dist/core/database.d.ts +59 -0
  141. package/dist/core/database.d.ts.map +1 -0
  142. package/dist/core/database.js +342 -0
  143. package/dist/core/database.js.map +1 -0
  144. package/dist/core/errors.d.ts +231 -0
  145. package/dist/core/errors.d.ts.map +1 -0
  146. package/dist/core/errors.js +254 -0
  147. package/dist/core/errors.js.map +1 -0
  148. package/dist/core/health.d.ts +72 -0
  149. package/dist/core/health.d.ts.map +1 -0
  150. package/dist/core/health.js +116 -0
  151. package/dist/core/health.js.map +1 -0
  152. package/dist/core/interfaces.d.ts +62 -0
  153. package/dist/core/interfaces.d.ts.map +1 -0
  154. package/dist/core/interfaces.js +8 -0
  155. package/dist/core/interfaces.js.map +1 -0
  156. package/dist/core/logger.d.ts +15 -0
  157. package/dist/core/logger.d.ts.map +1 -0
  158. package/dist/core/logger.js +30 -0
  159. package/dist/core/logger.js.map +1 -0
  160. package/dist/core/rbac.d.ts +132 -0
  161. package/dist/core/rbac.d.ts.map +1 -0
  162. package/dist/core/rbac.js +230 -0
  163. package/dist/core/rbac.js.map +1 -0
  164. package/dist/core/retry.d.ts +22 -0
  165. package/dist/core/retry.d.ts.map +1 -0
  166. package/dist/core/retry.js +41 -0
  167. package/dist/core/retry.js.map +1 -0
  168. package/dist/core/webhooks.d.ts +92 -0
  169. package/dist/core/webhooks.d.ts.map +1 -0
  170. package/dist/core/webhooks.js +176 -0
  171. package/dist/core/webhooks.js.map +1 -0
  172. package/dist/core/zero-config.d.ts +22 -0
  173. package/dist/core/zero-config.d.ts.map +1 -0
  174. package/dist/core/zero-config.js +59 -0
  175. package/dist/core/zero-config.js.map +1 -0
  176. package/dist/dashboard/cli.d.ts +6 -0
  177. package/dist/dashboard/cli.d.ts.map +1 -0
  178. package/dist/dashboard/cli.js +42 -0
  179. package/dist/dashboard/cli.js.map +1 -0
  180. package/dist/dashboard/index.html +3426 -0
  181. package/dist/dashboard/server.d.ts +7 -0
  182. package/dist/dashboard/server.d.ts.map +1 -0
  183. package/dist/dashboard/server.js +1427 -0
  184. package/dist/dashboard/server.js.map +1 -0
  185. package/dist/mcp/server.d.ts +27 -0
  186. package/dist/mcp/server.d.ts.map +1 -0
  187. package/dist/mcp/server.js +380 -0
  188. package/dist/mcp/server.js.map +1 -0
  189. package/dist/mcp/tools/misc.d.ts +15 -0
  190. package/dist/mcp/tools/misc.d.ts.map +1 -0
  191. package/dist/mcp/tools/misc.js +49 -0
  192. package/dist/mcp/tools/misc.js.map +1 -0
  193. package/dist/plugins/builtin/calculator.d.ts +11 -0
  194. package/dist/plugins/builtin/calculator.d.ts.map +1 -0
  195. package/dist/plugins/builtin/calculator.js +166 -0
  196. package/dist/plugins/builtin/calculator.js.map +1 -0
  197. package/dist/plugins/builtin/colors.d.ts +15 -0
  198. package/dist/plugins/builtin/colors.d.ts.map +1 -0
  199. package/dist/plugins/builtin/colors.js +193 -0
  200. package/dist/plugins/builtin/colors.js.map +1 -0
  201. package/dist/plugins/builtin/cron.d.ts +40 -0
  202. package/dist/plugins/builtin/cron.d.ts.map +1 -0
  203. package/dist/plugins/builtin/cron.js +578 -0
  204. package/dist/plugins/builtin/cron.js.map +1 -0
  205. package/dist/plugins/builtin/crypto.d.ts +11 -0
  206. package/dist/plugins/builtin/crypto.d.ts.map +1 -0
  207. package/dist/plugins/builtin/crypto.js +83 -0
  208. package/dist/plugins/builtin/crypto.js.map +1 -0
  209. package/dist/plugins/builtin/database.d.ts +29 -0
  210. package/dist/plugins/builtin/database.d.ts.map +1 -0
  211. package/dist/plugins/builtin/database.js +230 -0
  212. package/dist/plugins/builtin/database.js.map +1 -0
  213. package/dist/plugins/builtin/docker.d.ts +12 -0
  214. package/dist/plugins/builtin/docker.d.ts.map +1 -0
  215. package/dist/plugins/builtin/docker.js +436 -0
  216. package/dist/plugins/builtin/docker.js.map +1 -0
  217. package/dist/plugins/builtin/fun.d.ts +11 -0
  218. package/dist/plugins/builtin/fun.d.ts.map +1 -0
  219. package/dist/plugins/builtin/fun.js +114 -0
  220. package/dist/plugins/builtin/fun.js.map +1 -0
  221. package/dist/plugins/builtin/gcal.d.ts +38 -0
  222. package/dist/plugins/builtin/gcal.d.ts.map +1 -0
  223. package/dist/plugins/builtin/gcal.js +280 -0
  224. package/dist/plugins/builtin/gcal.js.map +1 -0
  225. package/dist/plugins/builtin/gdrive.d.ts +26 -0
  226. package/dist/plugins/builtin/gdrive.d.ts.map +1 -0
  227. package/dist/plugins/builtin/gdrive.js +295 -0
  228. package/dist/plugins/builtin/gdrive.js.map +1 -0
  229. package/dist/plugins/builtin/github-actions.d.ts +38 -0
  230. package/dist/plugins/builtin/github-actions.d.ts.map +1 -0
  231. package/dist/plugins/builtin/github-actions.js +629 -0
  232. package/dist/plugins/builtin/github-actions.js.map +1 -0
  233. package/dist/plugins/builtin/github.d.ts +26 -0
  234. package/dist/plugins/builtin/github.d.ts.map +1 -0
  235. package/dist/plugins/builtin/github.js +800 -0
  236. package/dist/plugins/builtin/github.js.map +1 -0
  237. package/dist/plugins/builtin/gmail.d.ts +50 -0
  238. package/dist/plugins/builtin/gmail.d.ts.map +1 -0
  239. package/dist/plugins/builtin/gmail.js +445 -0
  240. package/dist/plugins/builtin/gmail.js.map +1 -0
  241. package/dist/plugins/builtin/hash.d.ts +11 -0
  242. package/dist/plugins/builtin/hash.d.ts.map +1 -0
  243. package/dist/plugins/builtin/hash.js +95 -0
  244. package/dist/plugins/builtin/hash.js.map +1 -0
  245. package/dist/plugins/builtin/homekit.d.ts +53 -0
  246. package/dist/plugins/builtin/homekit.d.ts.map +1 -0
  247. package/dist/plugins/builtin/homekit.js +341 -0
  248. package/dist/plugins/builtin/homekit.js.map +1 -0
  249. package/dist/plugins/builtin/index.d.ts +4 -0
  250. package/dist/plugins/builtin/index.d.ts.map +1 -0
  251. package/dist/plugins/builtin/index.js +96 -0
  252. package/dist/plugins/builtin/index.js.map +1 -0
  253. package/dist/plugins/builtin/jira.d.ts +50 -0
  254. package/dist/plugins/builtin/jira.d.ts.map +1 -0
  255. package/dist/plugins/builtin/jira.js +353 -0
  256. package/dist/plugins/builtin/jira.js.map +1 -0
  257. package/dist/plugins/builtin/linear.d.ts +35 -0
  258. package/dist/plugins/builtin/linear.d.ts.map +1 -0
  259. package/dist/plugins/builtin/linear.js +397 -0
  260. package/dist/plugins/builtin/linear.js.map +1 -0
  261. package/dist/plugins/builtin/lumen.d.ts +21 -0
  262. package/dist/plugins/builtin/lumen.d.ts.map +1 -0
  263. package/dist/plugins/builtin/lumen.js +404 -0
  264. package/dist/plugins/builtin/lumen.js.map +1 -0
  265. package/dist/plugins/builtin/memory.d.ts +22 -0
  266. package/dist/plugins/builtin/memory.d.ts.map +1 -0
  267. package/dist/plugins/builtin/memory.js +184 -0
  268. package/dist/plugins/builtin/memory.js.map +1 -0
  269. package/dist/plugins/builtin/n8n.d.ts +60 -0
  270. package/dist/plugins/builtin/n8n.d.ts.map +1 -0
  271. package/dist/plugins/builtin/n8n.js +519 -0
  272. package/dist/plugins/builtin/n8n.js.map +1 -0
  273. package/dist/plugins/builtin/network.d.ts +11 -0
  274. package/dist/plugins/builtin/network.d.ts.map +1 -0
  275. package/dist/plugins/builtin/network.js +88 -0
  276. package/dist/plugins/builtin/network.js.map +1 -0
  277. package/dist/plugins/builtin/notes.d.ts +47 -0
  278. package/dist/plugins/builtin/notes.d.ts.map +1 -0
  279. package/dist/plugins/builtin/notes.js +641 -0
  280. package/dist/plugins/builtin/notes.js.map +1 -0
  281. package/dist/plugins/builtin/notion.d.ts +47 -0
  282. package/dist/plugins/builtin/notion.d.ts.map +1 -0
  283. package/dist/plugins/builtin/notion.js +317 -0
  284. package/dist/plugins/builtin/notion.js.map +1 -0
  285. package/dist/plugins/builtin/shell.d.ts +12 -0
  286. package/dist/plugins/builtin/shell.d.ts.map +1 -0
  287. package/dist/plugins/builtin/shell.js +310 -0
  288. package/dist/plugins/builtin/shell.js.map +1 -0
  289. package/dist/plugins/builtin/slack.d.ts +31 -0
  290. package/dist/plugins/builtin/slack.d.ts.map +1 -0
  291. package/dist/plugins/builtin/slack.js +295 -0
  292. package/dist/plugins/builtin/slack.js.map +1 -0
  293. package/dist/plugins/builtin/spotify.d.ts +55 -0
  294. package/dist/plugins/builtin/spotify.d.ts.map +1 -0
  295. package/dist/plugins/builtin/spotify.js +623 -0
  296. package/dist/plugins/builtin/spotify.js.map +1 -0
  297. package/dist/plugins/builtin/stripe.d.ts +35 -0
  298. package/dist/plugins/builtin/stripe.d.ts.map +1 -0
  299. package/dist/plugins/builtin/stripe.js +376 -0
  300. package/dist/plugins/builtin/stripe.js.map +1 -0
  301. package/dist/plugins/builtin/system.d.ts +11 -0
  302. package/dist/plugins/builtin/system.d.ts.map +1 -0
  303. package/dist/plugins/builtin/system.js +91 -0
  304. package/dist/plugins/builtin/system.js.map +1 -0
  305. package/dist/plugins/builtin/text-tools.d.ts +11 -0
  306. package/dist/plugins/builtin/text-tools.d.ts.map +1 -0
  307. package/dist/plugins/builtin/text-tools.js +146 -0
  308. package/dist/plugins/builtin/text-tools.js.map +1 -0
  309. package/dist/plugins/builtin/timezone.d.ts +13 -0
  310. package/dist/plugins/builtin/timezone.d.ts.map +1 -0
  311. package/dist/plugins/builtin/timezone.js +164 -0
  312. package/dist/plugins/builtin/timezone.js.map +1 -0
  313. package/dist/plugins/builtin/todoist.d.ts +49 -0
  314. package/dist/plugins/builtin/todoist.d.ts.map +1 -0
  315. package/dist/plugins/builtin/todoist.js +540 -0
  316. package/dist/plugins/builtin/todoist.js.map +1 -0
  317. package/dist/plugins/builtin/translate.d.ts +11 -0
  318. package/dist/plugins/builtin/translate.d.ts.map +1 -0
  319. package/dist/plugins/builtin/translate.js +42 -0
  320. package/dist/plugins/builtin/translate.js.map +1 -0
  321. package/dist/plugins/builtin/url-tools.d.ts +11 -0
  322. package/dist/plugins/builtin/url-tools.d.ts.map +1 -0
  323. package/dist/plugins/builtin/url-tools.js +70 -0
  324. package/dist/plugins/builtin/url-tools.js.map +1 -0
  325. package/dist/plugins/builtin/vercel.d.ts +55 -0
  326. package/dist/plugins/builtin/vercel.d.ts.map +1 -0
  327. package/dist/plugins/builtin/vercel.js +514 -0
  328. package/dist/plugins/builtin/vercel.js.map +1 -0
  329. package/dist/plugins/builtin/weather.d.ts +13 -0
  330. package/dist/plugins/builtin/weather.d.ts.map +1 -0
  331. package/dist/plugins/builtin/weather.js +103 -0
  332. package/dist/plugins/builtin/weather.js.map +1 -0
  333. package/dist/plugins/builtin/x.d.ts +54 -0
  334. package/dist/plugins/builtin/x.d.ts.map +1 -0
  335. package/dist/plugins/builtin/x.js +402 -0
  336. package/dist/plugins/builtin/x.js.map +1 -0
  337. package/dist/plugins/manager.d.ts +77 -0
  338. package/dist/plugins/manager.d.ts.map +1 -0
  339. package/dist/plugins/manager.js +141 -0
  340. package/dist/plugins/manager.js.map +1 -0
  341. package/dist/plugins/validation.d.ts +18 -0
  342. package/dist/plugins/validation.d.ts.map +1 -0
  343. package/dist/plugins/validation.js +81 -0
  344. package/dist/plugins/validation.js.map +1 -0
  345. package/dist/security/auth.d.ts +23 -0
  346. package/dist/security/auth.d.ts.map +1 -0
  347. package/dist/security/auth.js +56 -0
  348. package/dist/security/auth.js.map +1 -0
  349. package/dist/security/keychain.d.ts +60 -0
  350. package/dist/security/keychain.d.ts.map +1 -0
  351. package/dist/security/keychain.js +213 -0
  352. package/dist/security/keychain.js.map +1 -0
  353. package/dist/utils/google-auth.d.ts +21 -0
  354. package/dist/utils/google-auth.d.ts.map +1 -0
  355. package/dist/utils/google-auth.js +135 -0
  356. package/dist/utils/google-auth.js.map +1 -0
  357. package/dist/utils/retry.d.ts +5 -0
  358. package/dist/utils/retry.d.ts.map +1 -0
  359. package/dist/utils/retry.js +34 -0
  360. package/dist/utils/retry.js.map +1 -0
  361. package/docs/README.md +13 -0
  362. package/docs/api.md +210 -0
  363. package/docs/getting-started.md +100 -0
  364. package/docs/plugins.md +306 -0
  365. package/docs-site/.vitepress/config.ts +59 -0
  366. package/docs-site/README.md +12 -0
  367. package/docs-site/index.md +30 -0
  368. package/eslint.config.js +29 -0
  369. package/install.ps1 +334 -0
  370. package/install.sh +1119 -0
  371. package/local-install.sh +304 -0
  372. package/package.json +90 -0
  373. package/packages/README.md +11 -0
  374. package/packages/plugin-sdk/README.md +12 -0
  375. package/packages/plugin-sdk/package.json +22 -0
  376. package/packages/plugin-sdk/src/README.md +11 -0
  377. package/packages/plugin-sdk/src/index.ts +191 -0
  378. package/sdks/README.md +26 -0
  379. package/sdks/csharp/ConductorClient.cs +65 -0
  380. package/sdks/csharp/README.md +11 -0
  381. package/sdks/go/README.md +11 -0
  382. package/sdks/go/conductor.go +257 -0
  383. package/sdks/java/ConductorClient.java +27 -0
  384. package/sdks/java/README.md +11 -0
  385. package/sdks/php/README.md +11 -0
  386. package/sdks/php/src/Client.php +72 -0
  387. package/sdks/python/README.md +12 -0
  388. package/sdks/python/conductor/__init__.py +227 -0
  389. package/sdks/python/pyproject.toml +30 -0
  390. package/sdks/ruby/README.md +11 -0
  391. package/sdks/ruby/lib/conductor.rb +46 -0
  392. package/sdks/rust/Cargo.toml +14 -0
  393. package/sdks/rust/README.md +11 -0
  394. package/sdks/swift/README.md +11 -0
  395. package/sdks/swift/Sources/Conductor/ConductorClient.swift +65 -0
  396. package/skills/conductor-mcp/SKILL.md +38 -0
  397. package/src/README.md +20 -0
  398. package/src/ai/README.md +18 -0
  399. package/src/ai/base.ts +93 -0
  400. package/src/ai/claude.ts +162 -0
  401. package/src/ai/gemini.ts +188 -0
  402. package/src/ai/maestro.ts +168 -0
  403. package/src/ai/manager.ts +537 -0
  404. package/src/ai/ollama.ts +186 -0
  405. package/src/ai/openai.ts +147 -0
  406. package/src/ai/openrouter.ts +152 -0
  407. package/src/bot/README.md +12 -0
  408. package/src/bot/slack.ts +164 -0
  409. package/src/bot/telegram.ts +185 -0
  410. package/src/cli/README.md +24 -0
  411. package/src/cli/commands/README.md +20 -0
  412. package/src/cli/commands/ai.ts +170 -0
  413. package/src/cli/commands/doctor.ts +221 -0
  414. package/src/cli/commands/init.ts +348 -0
  415. package/src/cli/commands/install.ts +792 -0
  416. package/src/cli/commands/lifecycle.ts +95 -0
  417. package/src/cli/commands/marketplace.ts +253 -0
  418. package/src/cli/commands/mcp.ts +92 -0
  419. package/src/cli/commands/onboard.ts +248 -0
  420. package/src/cli/commands/plugin-create.ts +130 -0
  421. package/src/cli/commands/plugins.ts +36 -0
  422. package/src/cli/commands/release.ts +251 -0
  423. package/src/cli/commands/telegram.ts +25 -0
  424. package/src/cli/index.ts +450 -0
  425. package/src/config/README.md +11 -0
  426. package/src/config/oauth.ts +26 -0
  427. package/src/core/README.md +22 -0
  428. package/src/core/audit.ts +291 -0
  429. package/src/core/circuit-breaker.ts +129 -0
  430. package/src/core/conductor.ts +240 -0
  431. package/src/core/config.ts +149 -0
  432. package/src/core/database.ts +411 -0
  433. package/src/core/errors.ts +275 -0
  434. package/src/core/health.ts +159 -0
  435. package/src/core/interfaces.ts +75 -0
  436. package/src/core/logger.ts +33 -0
  437. package/src/core/rbac.ts +321 -0
  438. package/src/core/retry.ts +61 -0
  439. package/src/core/webhooks.ts +234 -0
  440. package/src/core/zero-config.ts +72 -0
  441. package/src/dashboard/README.md +15 -0
  442. package/src/dashboard/cli.ts +48 -0
  443. package/src/dashboard/index.html +3426 -0
  444. package/src/dashboard/server.ts +1544 -0
  445. package/src/mcp/README.md +20 -0
  446. package/src/mcp/server.ts +475 -0
  447. package/src/mcp/tools/README.md +11 -0
  448. package/src/mcp/tools/misc.ts +61 -0
  449. package/src/plugins/README.md +28 -0
  450. package/src/plugins/builtin/README.md +23 -0
  451. package/src/plugins/builtin/calculator.ts +178 -0
  452. package/src/plugins/builtin/colors.ts +201 -0
  453. package/src/plugins/builtin/cron.ts +649 -0
  454. package/src/plugins/builtin/crypto.ts +85 -0
  455. package/src/plugins/builtin/database.ts +235 -0
  456. package/src/plugins/builtin/docker.ts +426 -0
  457. package/src/plugins/builtin/fun.ts +118 -0
  458. package/src/plugins/builtin/gcal.ts +305 -0
  459. package/src/plugins/builtin/gdrive.ts +326 -0
  460. package/src/plugins/builtin/github-actions.ts +666 -0
  461. package/src/plugins/builtin/github.ts +912 -0
  462. package/src/plugins/builtin/gmail.ts +492 -0
  463. package/src/plugins/builtin/hash.ts +98 -0
  464. package/src/plugins/builtin/homekit.ts +389 -0
  465. package/src/plugins/builtin/index.ts +116 -0
  466. package/src/plugins/builtin/jira.ts +380 -0
  467. package/src/plugins/builtin/linear.ts +448 -0
  468. package/src/plugins/builtin/lumen.ts +497 -0
  469. package/src/plugins/builtin/memory.ts +200 -0
  470. package/src/plugins/builtin/n8n.ts +565 -0
  471. package/src/plugins/builtin/network.ts +92 -0
  472. package/src/plugins/builtin/notes.ts +689 -0
  473. package/src/plugins/builtin/notion.ts +348 -0
  474. package/src/plugins/builtin/shell.ts +334 -0
  475. package/src/plugins/builtin/slack.ts +327 -0
  476. package/src/plugins/builtin/spotify.ts +665 -0
  477. package/src/plugins/builtin/stripe.ts +388 -0
  478. package/src/plugins/builtin/system.ts +93 -0
  479. package/src/plugins/builtin/text-tools.ts +150 -0
  480. package/src/plugins/builtin/timezone.ts +173 -0
  481. package/src/plugins/builtin/todoist.ts +625 -0
  482. package/src/plugins/builtin/translate.ts +47 -0
  483. package/src/plugins/builtin/url-tools.ts +73 -0
  484. package/src/plugins/builtin/vercel.ts +546 -0
  485. package/src/plugins/builtin/weather.ts +112 -0
  486. package/src/plugins/builtin/x.ts +440 -0
  487. package/src/plugins/manager.ts +213 -0
  488. package/src/plugins/validation.ts +94 -0
  489. package/src/security/README.md +12 -0
  490. package/src/security/auth.ts +72 -0
  491. package/src/security/keychain.ts +226 -0
  492. package/src/utils/README.md +12 -0
  493. package/src/utils/google-auth.ts +159 -0
  494. package/src/utils/retry.ts +41 -0
  495. package/test-all.mjs +1256 -0
  496. package/test.mjs +633 -0
  497. package/tests/README.md +19 -0
  498. package/tests/calculator.test.ts +54 -0
  499. package/tests/docker.test.ts +42 -0
  500. package/tests/load.test.ts +129 -0
  501. package/tests/mcp.test.ts +14 -0
  502. package/tests/shell.test.ts +42 -0
  503. package/tsconfig.json +21 -0
  504. package/vitest.config.ts +14 -0
@@ -0,0 +1,149 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { homedir } from 'os';
4
+
5
+ export interface ConductorConfig {
6
+ user?: {
7
+ id: string;
8
+ name?: string;
9
+ role?: string;
10
+ projects?: string;
11
+ services?: string[];
12
+ verified_at?: string;
13
+ };
14
+ telegram?: {
15
+ enabled?: boolean;
16
+ bot_username?: string;
17
+ user_id?: number;
18
+ verified?: boolean;
19
+ verified_at?: string;
20
+ };
21
+ ai?: {
22
+ provider?: 'claude' | 'openai' | 'gemini' | 'ollama' | string;
23
+ model?: string;
24
+ mode?: 'desktop_app' | 'api' | 'telegram' | 'oauth';
25
+ api_config?: {
26
+ endpoint?: string;
27
+ key_stored?: boolean;
28
+ max_tokens?: number;
29
+ };
30
+ local_config?: {
31
+ endpoint?: string;
32
+ model?: string;
33
+ context_window?: number;
34
+ };
35
+ };
36
+ oauth?: {
37
+ google?: {
38
+ clientId: string;
39
+ clientSecret: string;
40
+ redirectUri: string;
41
+ };
42
+ };
43
+ plugins?: {
44
+ installed: string[];
45
+ enabled: string[];
46
+ };
47
+ security?: {
48
+ allowed_plugins: string[];
49
+ filesystem_access: {
50
+ enabled: boolean;
51
+ allowed_paths: string[];
52
+ };
53
+ system_commands: boolean;
54
+ desktop_control: boolean;
55
+ };
56
+ }
57
+
58
+ export class ConfigManager {
59
+ private configDir: string;
60
+ private configPath: string;
61
+ private config: ConductorConfig;
62
+
63
+ constructor(customPath?: string) {
64
+ this.configDir = customPath || path.join(homedir(), '.conductor');
65
+ this.configPath = path.join(this.configDir, 'config.json');
66
+ this.config = {};
67
+ }
68
+
69
+ async initialize(): Promise<void> {
70
+ // Create config directory tree
71
+ try {
72
+ await fs.mkdir(this.configDir, { recursive: true });
73
+ await fs.mkdir(path.join(this.configDir, 'plugins'), { recursive: true });
74
+ await fs.mkdir(path.join(this.configDir, 'logs'), { recursive: true });
75
+ await fs.mkdir(path.join(this.configDir, 'keychain'), { recursive: true, mode: 0o700 });
76
+ } catch (error) {
77
+ throw new Error(`Failed to create config directory: ${error}`);
78
+ }
79
+
80
+ await this.load();
81
+ }
82
+
83
+ async load(): Promise<void> {
84
+ try {
85
+ const data = await fs.readFile(this.configPath, 'utf-8');
86
+ this.config = JSON.parse(data);
87
+ } catch {
88
+ // Config doesn't exist yet — use defaults
89
+ this.config = {
90
+ plugins: {
91
+ installed: [],
92
+ enabled: [],
93
+ },
94
+ security: {
95
+ allowed_plugins: [],
96
+ filesystem_access: {
97
+ enabled: false,
98
+ allowed_paths: [],
99
+ },
100
+ system_commands: false,
101
+ desktop_control: false,
102
+ },
103
+ };
104
+ await this.save();
105
+ }
106
+ }
107
+
108
+ async save(): Promise<void> {
109
+ const tmp = this.configPath + '.tmp';
110
+ await fs.writeFile(tmp, JSON.stringify(this.config, null, 2), 'utf-8');
111
+ await fs.rename(tmp, this.configPath);
112
+ }
113
+
114
+ get<T>(key: string): T | undefined {
115
+ const keys = key.split('.');
116
+ let value: any = this.config;
117
+
118
+ for (const k of keys) {
119
+ if (value === undefined || value === null) return undefined;
120
+ value = value[k];
121
+ }
122
+
123
+ return value as T;
124
+ }
125
+
126
+ async set(key: string, value: any): Promise<void> {
127
+ const keys = key.split('.');
128
+ let target: any = this.config;
129
+
130
+ for (let i = 0; i < keys.length - 1; i++) {
131
+ const k = keys[i];
132
+ if (!(k in target) || typeof target[k] !== 'object') {
133
+ target[k] = {};
134
+ }
135
+ target = target[k];
136
+ }
137
+
138
+ target[keys[keys.length - 1]] = value;
139
+ await this.save();
140
+ }
141
+
142
+ getConfigDir(): string {
143
+ return this.configDir;
144
+ }
145
+
146
+ getConfig(): ConductorConfig {
147
+ return this.config;
148
+ }
149
+ }
@@ -0,0 +1,411 @@
1
+ import initSqlJs, { Database } from 'sql.js';
2
+ import fs from 'fs/promises';
3
+ import { writeFileSync, renameSync } from 'fs';
4
+ import path from 'path';
5
+ import { AIMessage } from '../ai/base.js';
6
+
7
+ export class DatabaseManager {
8
+ private db: Database | null = null;
9
+ private dbPath: string;
10
+ /** Pending debounced flush timer */
11
+ private flushTimer: NodeJS.Timeout | null = null;
12
+ /** True when in-memory state has outpaced what's on disk */
13
+ private dirty = false;
14
+ /** Debounce interval in ms — flush at most this often */
15
+ private static readonly DEBOUNCE_MS = 500;
16
+
17
+ constructor(configDir: string) {
18
+ this.dbPath = path.join(configDir, 'conductor.db');
19
+
20
+ // Ensure flush on process exit
21
+ const onExit = (): void => {
22
+ this.flushSync();
23
+ };
24
+ process.on('exit', onExit);
25
+ process.on('SIGINT', () => {
26
+ this.flushSync();
27
+ process.exit(0);
28
+ });
29
+ process.on('SIGTERM', () => {
30
+ this.flushSync();
31
+ process.exit(0);
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Mark the database dirty and arm the debounce timer.
37
+ * Multiple writes within DEBOUNCE_MS coalesce into a single disk write.
38
+ */
39
+ private scheduleFlush(): void {
40
+ this.dirty = true;
41
+ if (this.flushTimer) return; // timer already armed — do nothing more
42
+ this.flushTimer = setTimeout(() => {
43
+ this.flushTimer = null;
44
+ this.save().catch((err) => {
45
+ process.stderr.write(`DatabaseManager: flush error: ${(err as Error).message}\n`);
46
+ });
47
+ }, DatabaseManager.DEBOUNCE_MS);
48
+ }
49
+
50
+ /**
51
+ * Synchronous flush used by signal handlers — no async I/O allowed after
52
+ * SIGINT/SIGTERM because the event loop may already be draining.
53
+ * Uses the top-level `writeFileSync`/`renameSync` imports (not require()).
54
+ */
55
+ private flushSync(): void {
56
+ if (!this.db || !this.dirty) return;
57
+ try {
58
+ if (this.flushTimer) {
59
+ clearTimeout(this.flushTimer);
60
+ this.flushTimer = null;
61
+ }
62
+ const data = this.db.export();
63
+ const tmp = this.dbPath + '.tmp';
64
+ writeFileSync(tmp, data);
65
+ renameSync(tmp, this.dbPath);
66
+ this.dirty = false;
67
+ } catch {
68
+ /* best-effort on shutdown */
69
+ }
70
+ }
71
+
72
+ /** Cancel the debounce timer and flush immediately (async). */
73
+ async flush(): Promise<void> {
74
+ if (this.flushTimer) {
75
+ clearTimeout(this.flushTimer);
76
+ this.flushTimer = null;
77
+ }
78
+ if (this.dirty) {
79
+ await this.save();
80
+ }
81
+ }
82
+
83
+ async initialize(): Promise<void> {
84
+ const SQL = await initSqlJs();
85
+
86
+ // Try to load existing database
87
+ try {
88
+ const buffer = await fs.readFile(this.dbPath);
89
+ this.db = new SQL.Database(new Uint8Array(buffer));
90
+ } catch {
91
+ // Create new database
92
+ this.db = new SQL.Database();
93
+ await this.createTables();
94
+ }
95
+ }
96
+
97
+ private async createTables(): Promise<void> {
98
+ if (!this.db) throw new Error('Database not initialized');
99
+
100
+ this.db.run(`
101
+ CREATE TABLE IF NOT EXISTS activity_logs (
102
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
103
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
104
+ user_id TEXT,
105
+ action TEXT NOT NULL,
106
+ plugin TEXT,
107
+ details TEXT,
108
+ success BOOLEAN DEFAULT 1
109
+ )
110
+ `);
111
+
112
+ this.db.run(`
113
+ CREATE TABLE IF NOT EXISTS plugins (
114
+ id TEXT PRIMARY KEY,
115
+ name TEXT NOT NULL,
116
+ type TEXT NOT NULL,
117
+ version TEXT,
118
+ enabled BOOLEAN DEFAULT 0,
119
+ config TEXT,
120
+ installed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
121
+ last_used DATETIME
122
+ )
123
+ `);
124
+
125
+ this.db.run(`
126
+ CREATE TABLE IF NOT EXISTS credentials (
127
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
128
+ service TEXT NOT NULL UNIQUE,
129
+ encrypted_data TEXT NOT NULL,
130
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
131
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
132
+ )
133
+ `);
134
+
135
+ this.db.run(`
136
+ CREATE TABLE IF NOT EXISTS messages (
137
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
138
+ user_id TEXT,
139
+ role TEXT NOT NULL,
140
+ content TEXT,
141
+ tool_calls TEXT,
142
+ tool_call_id TEXT,
143
+ name TEXT,
144
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
145
+ )
146
+ `);
147
+
148
+ this.db.run(`
149
+ CREATE TABLE IF NOT EXISTS core_memory (
150
+ id TEXT PRIMARY KEY,
151
+ user_id TEXT,
152
+ text TEXT NOT NULL,
153
+ category TEXT,
154
+ importance REAL,
155
+ tags TEXT,
156
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
157
+ )
158
+ `);
159
+
160
+ // Immediate save on fresh database creation
161
+ await this.save();
162
+ }
163
+
164
+ async logActivity(
165
+ userId: string,
166
+ action: string,
167
+ plugin?: string,
168
+ details?: string,
169
+ success: boolean = true,
170
+ ): Promise<void> {
171
+ if (!this.db) throw new Error('Database not initialized');
172
+
173
+ this.db.run(
174
+ `INSERT INTO activity_logs (user_id, action, plugin, details, success)
175
+ VALUES (?, ?, ?, ?, ?)`,
176
+ [userId, action, plugin ?? null, details ?? null, success ? 1 : 0],
177
+ );
178
+
179
+ this.scheduleFlush();
180
+ }
181
+
182
+ async getRecentActivity(limit: number = 50): Promise<any[]> {
183
+ if (!this.db) throw new Error('Database not initialized');
184
+
185
+ // sql.js exec() doesn't support parameterized queries — use prepare+bind
186
+ const stmt = this.db.prepare(`SELECT * FROM activity_logs ORDER BY timestamp DESC LIMIT ?`);
187
+ stmt.bind([limit]);
188
+
189
+ const results: any[] = [];
190
+ while (stmt.step()) {
191
+ results.push(stmt.getAsObject());
192
+ }
193
+ stmt.free();
194
+ return results;
195
+ }
196
+
197
+ async addMessage(userId: string, message: AIMessage): Promise<void> {
198
+ if (!this.db) throw new Error('Database not initialized');
199
+
200
+ const toolCalls = message.tool_calls ? JSON.stringify(message.tool_calls) : null;
201
+ this.db.run(
202
+ `INSERT INTO messages (user_id, role, content, tool_calls, tool_call_id, name)
203
+ VALUES (?, ?, ?, ?, ?, ?)`,
204
+ [userId, message.role, message.content || null, toolCalls, message.tool_call_id || null, message.name || null],
205
+ );
206
+ this.scheduleFlush();
207
+ }
208
+
209
+ async getHistory(userId: string, limit: number = 20): Promise<AIMessage[]> {
210
+ if (!this.db) throw new Error('Database not initialized');
211
+
212
+ const stmt = this.db.prepare(
213
+ `SELECT * FROM (SELECT * FROM messages WHERE user_id = ? ORDER BY id DESC LIMIT ?) ORDER BY id ASC`,
214
+ );
215
+ stmt.bind([userId, limit]);
216
+
217
+ const results: AIMessage[] = [];
218
+ while (stmt.step()) {
219
+ const row = stmt.getAsObject() as any;
220
+ results.push({
221
+ role: row.role as any,
222
+ content: row.content || '',
223
+ ...(row.tool_calls ? { tool_calls: JSON.parse(row.tool_calls) } : {}),
224
+ ...(row.tool_call_id ? { tool_call_id: row.tool_call_id } : {}),
225
+ ...(row.name ? { name: row.name } : {}),
226
+ });
227
+ }
228
+ stmt.free();
229
+ return results;
230
+ }
231
+
232
+ async clearHistory(userId: string): Promise<void> {
233
+ if (!this.db) throw new Error('Database not initialized');
234
+ this.db.run(`DELETE FROM messages WHERE user_id = ?`, [userId]);
235
+ this.scheduleFlush();
236
+ }
237
+
238
+ async addCoreMemory(entry: {
239
+ id: string;
240
+ userId: string;
241
+ text: string;
242
+ category: string;
243
+ importance: number;
244
+ tags?: string[];
245
+ }): Promise<void> {
246
+ if (!this.db) throw new Error('Database not initialized');
247
+ this.db.run(`INSERT INTO core_memory (id, user_id, text, category, importance, tags) VALUES (?, ?, ?, ?, ?, ?)`, [
248
+ entry.id,
249
+ entry.userId,
250
+ entry.text,
251
+ entry.category,
252
+ entry.importance,
253
+ entry.tags ? JSON.stringify(entry.tags) : null,
254
+ ]);
255
+ this.scheduleFlush();
256
+ }
257
+
258
+ async searchCoreMemory(userId: string, query: string, limit: number = 5, category?: string): Promise<any[]> {
259
+ if (!this.db) throw new Error('Database not initialized');
260
+
261
+ let sql = `SELECT * FROM core_memory WHERE user_id = ? AND text LIKE ?`;
262
+ let params: any[] = [userId, `%${query}%`];
263
+
264
+ if (category) {
265
+ sql += ` AND category = ?`;
266
+ params.push(category);
267
+ }
268
+
269
+ sql += ` ORDER BY importance DESC, timestamp DESC LIMIT ?`;
270
+ params.push(limit);
271
+
272
+ const stmt = this.db.prepare(sql);
273
+ stmt.bind(params);
274
+
275
+ const results: any[] = [];
276
+ while (stmt.step()) {
277
+ results.push(stmt.getAsObject());
278
+ }
279
+ stmt.free();
280
+ return results;
281
+ }
282
+
283
+ async deleteCoreMemory(id: string): Promise<boolean> {
284
+ if (!this.db) throw new Error('Database not initialized');
285
+ this.db.run(`DELETE FROM core_memory WHERE id = ?`, [id]);
286
+ this.scheduleFlush();
287
+ // SQLite run() doesn't return changes cleanly in sql.js without extra steps, we assume it succeeds
288
+ return true;
289
+ }
290
+
291
+ async listCoreMemory(userId: string, category?: string, limit: number = 20): Promise<any[]> {
292
+ if (!this.db) throw new Error('Database not initialized');
293
+ let sql = `SELECT * FROM core_memory WHERE user_id = ?`;
294
+ let params: any[] = [userId];
295
+
296
+ if (category) {
297
+ sql += ` AND category = ?`;
298
+ params.push(category);
299
+ }
300
+ sql += ` ORDER BY timestamp DESC LIMIT ?`;
301
+ params.push(limit);
302
+
303
+ const stmt = this.db.prepare(sql);
304
+ stmt.bind(params);
305
+
306
+ const results: any[] = [];
307
+ while (stmt.step()) {
308
+ results.push(stmt.getAsObject());
309
+ }
310
+ stmt.free();
311
+ return results;
312
+ }
313
+
314
+ /** Get recent messages across all users for the dashboard conversations view. */
315
+ async getRecentMessages(limit: number = 100): Promise<any[]> {
316
+ if (!this.db) throw new Error('Database not initialized');
317
+ const stmt = this.db.prepare(
318
+ `SELECT user_id, role, content, timestamp FROM messages
319
+ WHERE role IN ('user', 'assistant')
320
+ ORDER BY id DESC LIMIT ?`,
321
+ );
322
+ stmt.bind([limit]);
323
+ const results: any[] = [];
324
+ while (stmt.step()) {
325
+ results.push(stmt.getAsObject());
326
+ }
327
+ stmt.free();
328
+ return results;
329
+ }
330
+
331
+ async searchMessages(userId: string, query: string, limit: number = 10): Promise<any[]> {
332
+ if (!this.db) throw new Error('Database not initialized');
333
+
334
+ // Simple fast LIKE search to prevent heavy vector RAM usage
335
+ const stmt = this.db.prepare(
336
+ `SELECT role, content, timestamp FROM messages WHERE user_id = ? AND content LIKE ? ORDER BY timestamp DESC LIMIT ?`,
337
+ );
338
+ stmt.bind([userId, `%${query}%`, limit]);
339
+
340
+ const results: any[] = [];
341
+ while (stmt.step()) {
342
+ results.push(stmt.getAsObject());
343
+ }
344
+ stmt.free();
345
+ return results;
346
+ }
347
+
348
+ async savePlugin(plugin: {
349
+ id: string;
350
+ name: string;
351
+ type: string;
352
+ version?: string;
353
+ enabled?: boolean;
354
+ config?: any;
355
+ }): Promise<void> {
356
+ if (!this.db) throw new Error('Database not initialized');
357
+
358
+ const configJson = plugin.config ? JSON.stringify(plugin.config) : null;
359
+
360
+ this.db.run(
361
+ `INSERT OR REPLACE INTO plugins (id, name, type, version, enabled, config)
362
+ VALUES (?, ?, ?, ?, ?, ?)`,
363
+ [plugin.id, plugin.name, plugin.type, plugin.version || '1.0.0', plugin.enabled ? 1 : 0, configJson],
364
+ );
365
+
366
+ this.scheduleFlush();
367
+ }
368
+
369
+ async getPlugins(): Promise<any[]> {
370
+ if (!this.db) throw new Error('Database not initialized');
371
+
372
+ const stmt = this.db.prepare(`SELECT * FROM plugins ORDER BY name`);
373
+ const results: any[] = [];
374
+ while (stmt.step()) {
375
+ results.push(stmt.getAsObject());
376
+ }
377
+ stmt.free();
378
+ return results;
379
+ }
380
+
381
+ async updatePluginStatus(pluginId: string, enabled: boolean): Promise<void> {
382
+ if (!this.db) throw new Error('Database not initialized');
383
+
384
+ this.db.run(`UPDATE plugins SET enabled = ?, last_used = CURRENT_TIMESTAMP WHERE id = ?`, [
385
+ enabled ? 1 : 0,
386
+ pluginId,
387
+ ]);
388
+
389
+ this.scheduleFlush();
390
+ }
391
+
392
+ async save(): Promise<void> {
393
+ if (!this.db) throw new Error('Database not initialized');
394
+ // Clear dirty before the I/O so a write that arrives mid-save
395
+ // will re-arm the flag and schedule another flush rather than
396
+ // being silently dropped.
397
+ this.dirty = false;
398
+ const data = this.db.export();
399
+ const tmp = this.dbPath + '.tmp';
400
+ await fs.writeFile(tmp, data);
401
+ await fs.rename(tmp, this.dbPath);
402
+ }
403
+
404
+ async close(): Promise<void> {
405
+ if (this.db) {
406
+ await this.flush();
407
+ this.db.close();
408
+ this.db = null;
409
+ }
410
+ }
411
+ }