@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,95 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { Conductor } from '../../core/conductor.js';
6
+
7
+ // ESM equivalent of __dirname
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+
11
+ export function registerLifecycleCommands(program: Command, conductor: Conductor): void {
12
+ program
13
+ .command('version')
14
+ .description('Show Conductor version')
15
+ .action(async () => {
16
+ try {
17
+ // Walk up from dist/cli/commands/ to find package.json
18
+ const packagePath = path.resolve(__dirname, '..', '..', '..', 'package.json');
19
+ const pkg = JSON.parse(await fs.readFile(packagePath, 'utf-8'));
20
+ console.log(`Conductor v${pkg.version}`);
21
+ } catch {
22
+ console.log('Conductor (version unknown)');
23
+ }
24
+ });
25
+
26
+ program
27
+ .command('status')
28
+ .description('Show Conductor status')
29
+ .action(async () => {
30
+ await conductor.initialize();
31
+
32
+ const config = conductor.getConfig();
33
+ const user = config.get<any>('user');
34
+ const ai = config.get<any>('ai');
35
+ const telegram = config.get<any>('telegram');
36
+ const plugins = config.get<string[]>('plugins.enabled') || [];
37
+
38
+ console.log('═══ Conductor Status ═══\n');
39
+ console.log(`User: ${user?.name || 'not configured'}`);
40
+ console.log(`AI Provider: ${ai?.provider || 'none'}`);
41
+ console.log(`AI Model: ${ai?.model || 'default'}`);
42
+ console.log(`Telegram: ${telegram?.enabled ? '✅ enabled' : '❌ disabled'}`);
43
+ console.log(`Plugins: ${plugins.length > 0 ? plugins.join(', ') : 'none'}`);
44
+ });
45
+
46
+ program
47
+ .command('reset')
48
+ .description('Reset Conductor configuration')
49
+ .option('--confirm', 'Skip confirmation prompt')
50
+ .action(async (opts) => {
51
+ if (!opts.confirm) {
52
+ const { default: inquirer } = await import('inquirer');
53
+ const { proceed } = await inquirer.prompt([
54
+ {
55
+ type: 'confirm',
56
+ name: 'proceed',
57
+ message: 'This will reset all Conductor configuration. Are you sure?',
58
+ default: false,
59
+ },
60
+ ]);
61
+ if (!proceed) {
62
+ console.log('Cancelled.');
63
+ return;
64
+ }
65
+ }
66
+
67
+ const configDir = conductor.getConfig().getConfigDir();
68
+ await fs.rm(configDir, { recursive: true, force: true });
69
+ console.log('Conductor has been reset. Run the installer again to set up.');
70
+ });
71
+
72
+ program
73
+ .command('logs')
74
+ .description('Show recent activity logs')
75
+ .option('-n, --count <number>', 'Number of entries', '20')
76
+ .action(async (opts) => {
77
+ await conductor.initialize();
78
+
79
+ const count = parseInt(opts.count, 10);
80
+ const activities = await conductor.getRecentActivity(count);
81
+
82
+ if (activities.length === 0) {
83
+ console.log('No activity logged yet.');
84
+ return;
85
+ }
86
+
87
+ for (const entry of activities) {
88
+ const time = new Date(entry.timestamp).toLocaleString();
89
+ console.log(`[${time}] ${entry.user_id ?? 'system'}: ${entry.action}`);
90
+ if (entry.details) {
91
+ console.log(` ${entry.details}`);
92
+ }
93
+ }
94
+ });
95
+ }
@@ -0,0 +1,253 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { Conductor } from '../../core/conductor.js';
4
+
5
+ const REGISTRY_URLS = [
6
+ 'https://raw.githubusercontent.com/thegreatalxx/conductor-plugins/main/registry.json',
7
+ 'https://conductor.thealxlabs.ca/registry.json',
8
+ ];
9
+ const GITHUB_RAW = 'https://raw.githubusercontent.com';
10
+
11
+ // ── Types ─────────────────────────────────────────────────────────────────────
12
+
13
+ interface RegistryPlugin {
14
+ id: string;
15
+ name: string;
16
+ description: string;
17
+ longDescription: string;
18
+ category: string;
19
+ author: string;
20
+ version: string;
21
+ repo: string;
22
+ path: string;
23
+ asset: string;
24
+ credentials: { service: string; key: string; label: string; setup: string }[];
25
+ tools: string[];
26
+ tags: string[];
27
+ icon: string;
28
+ }
29
+
30
+ interface Registry {
31
+ version: string;
32
+ plugins: RegistryPlugin[];
33
+ }
34
+
35
+ // ── Helpers ───────────────────────────────────────────────────────────────────
36
+
37
+ async function fetchRegistry(): Promise<Registry> {
38
+ let lastError: Error | undefined;
39
+ for (const url of REGISTRY_URLS) {
40
+ try {
41
+ const res = await fetch(url, { signal: AbortSignal.timeout(10000) });
42
+ if (res.ok) return res.json() as Promise<Registry>;
43
+ lastError = new Error(`Registry at ${url} returned ${res.status}`);
44
+ } catch (e) {
45
+ lastError = e as Error;
46
+ }
47
+ }
48
+ throw new Error(`Cannot reach plugin registry. Check your internet connection.\n${lastError?.message ?? ''}`);
49
+ }
50
+
51
+ function pluginsDir(conductor: Conductor): string {
52
+ return path.join(conductor.getConfig().getConfigDir(), 'plugins');
53
+ }
54
+
55
+ function dim(s: string) {
56
+ return `\x1b[2m${s}\x1b[0m`;
57
+ }
58
+ function green(s: string) {
59
+ return `\x1b[32m${s}\x1b[0m`;
60
+ }
61
+ function red(s: string) {
62
+ return `\x1b[31m${s}\x1b[0m`;
63
+ }
64
+ function cyan(s: string) {
65
+ return `\x1b[36m${s}\x1b[0m`;
66
+ }
67
+ function bold(s: string) {
68
+ return `\x1b[1m${s}\x1b[0m`;
69
+ }
70
+ function yellow(s: string) {
71
+ return `\x1b[33m${s}\x1b[0m`;
72
+ }
73
+
74
+ // ── Commands ──────────────────────────────────────────────────────────────────
75
+
76
+ /** conductor install <plugin> */
77
+ export async function installPlugin(conductor: Conductor, pluginId: string): Promise<void> {
78
+ console.log('');
79
+ console.log(` ${cyan('▶')} Fetching registry…`);
80
+
81
+ const registry = await fetchRegistry();
82
+ const plugin = registry.plugins.find((p) => p.id === pluginId);
83
+
84
+ if (!plugin) {
85
+ const ids = registry.plugins.map((p) => p.id).join(', ');
86
+ console.error(` ${red('✗')} Plugin "${pluginId}" not found in registry.`);
87
+ console.error(` ${dim('Available:')} ${ids}`);
88
+ console.error(` ${dim('Browse:')} conductor marketplace`);
89
+ process.exit(1);
90
+ }
91
+
92
+ // Check if already installed
93
+ const dir = pluginsDir(conductor);
94
+ const dest = path.join(dir, `${plugin.id}.js`);
95
+ try {
96
+ await fs.access(dest);
97
+ console.log(` ${yellow('⚠')} ${bold(plugin.name)} is already installed. Reinstalling…`);
98
+ } catch {
99
+ /* not installed, continue */
100
+ }
101
+
102
+ // Download from GitHub
103
+ const url = `${GITHUB_RAW}/${plugin.repo}/main/${plugin.asset}`;
104
+ console.log(` ${cyan('▶')} Downloading ${bold(plugin.name)} ${dim(`v${plugin.version}`)}…`);
105
+
106
+ let source: string;
107
+ try {
108
+ const res = await fetch(url);
109
+ if (!res.ok) throw new Error(`GitHub returned ${res.status} for ${url}`);
110
+ source = await res.text();
111
+ } catch (e: any) {
112
+ console.error(` ${red('✗')} Download failed: ${e.message}`);
113
+ console.error(` ${dim('Expected asset at:')} ${url}`);
114
+ process.exit(1);
115
+ }
116
+
117
+ // Save to plugins dir
118
+ await fs.mkdir(dir, { recursive: true });
119
+ await fs.writeFile(dest, source, 'utf-8');
120
+
121
+ // Mark as installed in config
122
+ const installed = conductor.getConfig().get<string[]>('plugins.installed') ?? [];
123
+ if (!installed.includes(plugin.id)) {
124
+ await conductor.getConfig().set('plugins.installed', [...installed, plugin.id]);
125
+ }
126
+
127
+ console.log(` ${green('✓')} ${bold(plugin.name)} installed`);
128
+ console.log('');
129
+
130
+ // Show credential setup instructions
131
+ if (plugin.credentials.length > 0) {
132
+ console.log(` ${bold('Setup required:')} ${plugin.name} needs credentials to work.`);
133
+ for (const cred of plugin.credentials) {
134
+ console.log(` ${dim('→')} ${cred.label}`);
135
+ console.log(` ${cyan(cred.setup)}`);
136
+ }
137
+ console.log('');
138
+ }
139
+
140
+ console.log(` ${dim('Enable it:')} ${cyan(`conductor plugins enable ${plugin.id}`)}`);
141
+ console.log(` ${dim('Dashboard:')} ${cyan('conductor dashboard')}`);
142
+ console.log('');
143
+ }
144
+
145
+ /** conductor uninstall <plugin> */
146
+ export async function uninstallPlugin(conductor: Conductor, pluginId: string): Promise<void> {
147
+ console.log('');
148
+ const dir = pluginsDir(conductor);
149
+ const dest = path.join(dir, `${pluginId}.js`);
150
+
151
+ try {
152
+ await fs.access(dest);
153
+ } catch {
154
+ console.error(` ${red('✗')} Plugin "${pluginId}" is not installed.`);
155
+ process.exit(1);
156
+ }
157
+
158
+ await fs.unlink(dest);
159
+
160
+ // Remove from installed + enabled lists
161
+ const cfg = conductor.getConfig();
162
+ const installed = (cfg.get<string[]>('plugins.installed') ?? []).filter((p) => p !== pluginId);
163
+ const enabled = (cfg.get<string[]>('plugins.enabled') ?? []).filter((p) => p !== pluginId);
164
+ await cfg.set('plugins.installed', installed);
165
+ await cfg.set('plugins.enabled', enabled);
166
+
167
+ console.log(` ${green('✓')} ${bold(pluginId)} uninstalled`);
168
+ console.log('');
169
+ }
170
+
171
+ /** conductor marketplace (list) */
172
+ export async function listMarketplace(
173
+ _conductor: Conductor,
174
+ opts: { category?: string; search?: string },
175
+ ): Promise<void> {
176
+ console.log('');
177
+ console.log(` ${bold(cyan('Conductor Marketplace'))}`);
178
+ console.log(` ${dim('Browse at: https://conductor.thealxlabs.ca/marketplace')}`);
179
+ console.log('');
180
+
181
+ let registry: Registry;
182
+ try {
183
+ registry = await fetchRegistry();
184
+ } catch (e: any) {
185
+ console.error(` ${red('✗')} ${e.message}`);
186
+ process.exit(1);
187
+ }
188
+
189
+ let plugins = registry.plugins;
190
+
191
+ if (opts.category) {
192
+ plugins = plugins.filter((p) => p.category === opts.category);
193
+ }
194
+ if (opts.search) {
195
+ const q = opts.search.toLowerCase();
196
+ plugins = plugins.filter(
197
+ (p) =>
198
+ p.id.includes(q) ||
199
+ p.name.toLowerCase().includes(q) ||
200
+ p.description.toLowerCase().includes(q) ||
201
+ p.tags.includes(q),
202
+ );
203
+ }
204
+
205
+ // Group by category
206
+ const categories = [...new Set(plugins.map((p) => p.category))];
207
+ for (const cat of categories) {
208
+ const group = plugins.filter((p) => p.category === cat);
209
+ console.log(` ${bold(cat.toUpperCase())}`);
210
+ for (const p of group) {
211
+ console.log(` ${p.icon} ${bold(p.name.padEnd(20))} ${dim(p.id.padEnd(18))} ${p.description.slice(0, 55)}…`);
212
+ }
213
+ console.log('');
214
+ }
215
+
216
+ console.log(` ${dim('Install:')} ${cyan('conductor install <id>')}`);
217
+ console.log(` ${dim('Details:')} ${cyan('conductor marketplace info <id>')}`);
218
+ console.log(` ${dim('Search:')} ${cyan('conductor marketplace --search <query>')}`);
219
+ console.log('');
220
+ }
221
+
222
+ /** conductor marketplace info <plugin> */
223
+ export async function pluginInfo(_conductor: Conductor, pluginId: string): Promise<void> {
224
+ console.log('');
225
+ const registry = await fetchRegistry();
226
+ const plugin = registry.plugins.find((p) => p.id === pluginId);
227
+
228
+ if (!plugin) {
229
+ console.error(` ${red('✗')} Plugin "${pluginId}" not found.`);
230
+ process.exit(1);
231
+ }
232
+
233
+ console.log(` ${plugin.icon} ${bold(plugin.name)} ${dim(`v${plugin.version} by ${plugin.author}`)}`);
234
+ console.log('');
235
+ console.log(` ${plugin.longDescription}`);
236
+ console.log('');
237
+ console.log(` ${bold('Tools:')} ${plugin.tools.join(', ')}`);
238
+ console.log(` ${bold('Tags:')} ${plugin.tags.join(', ')}`);
239
+ console.log('');
240
+
241
+ if (plugin.credentials.length > 0) {
242
+ console.log(` ${bold('Credentials needed:')}`);
243
+ for (const c of plugin.credentials) {
244
+ console.log(` ${dim('→')} ${c.label}`);
245
+ }
246
+ console.log('');
247
+ }
248
+
249
+ console.log(` ${bold('Source:')} https://github.com/${plugin.repo}/tree/main/${plugin.path}`);
250
+ console.log('');
251
+ console.log(` ${cyan(`conductor install ${plugin.id}`)}`);
252
+ console.log('');
253
+ }
@@ -0,0 +1,92 @@
1
+ import { Conductor } from '../../core/conductor.js';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { homedir } from 'os';
5
+
6
+ const CLAUDE_DESKTOP_CONFIG = path.join(
7
+ homedir(),
8
+ process.platform === 'darwin'
9
+ ? 'Library/Application Support/Claude/claude_desktop_config.json'
10
+ : process.platform === 'win32'
11
+ ? 'AppData/Roaming/Claude/claude_desktop_config.json'
12
+ : '.config/Claude/claude_desktop_config.json',
13
+ );
14
+
15
+ export async function mcpSetup(conductor: Conductor): Promise<void> {
16
+ await conductor.initialize();
17
+
18
+ // Build MCP server config entry
19
+ const conductorPath = process.argv[1]; // Path to the conductor CLI
20
+ const mcpConfig = {
21
+ command: 'node',
22
+ args: [conductorPath, 'mcp', 'start'],
23
+ };
24
+
25
+ try {
26
+ let config: any = {};
27
+ try {
28
+ const existing = await fs.readFile(CLAUDE_DESKTOP_CONFIG, 'utf-8');
29
+ config = JSON.parse(existing);
30
+ } catch {
31
+ // File doesn't exist yet
32
+ }
33
+
34
+ if (!config.mcpServers) config.mcpServers = {};
35
+ config.mcpServers.conductor = mcpConfig;
36
+
37
+ await fs.mkdir(path.dirname(CLAUDE_DESKTOP_CONFIG), { recursive: true });
38
+ await fs.writeFile(CLAUDE_DESKTOP_CONFIG, JSON.stringify(config, null, 2));
39
+
40
+ console.log('✅ MCP server configured for Claude Desktop.');
41
+ console.log(` Config: ${CLAUDE_DESKTOP_CONFIG}`);
42
+ console.log(' Restart Claude Desktop to connect.');
43
+ } catch (error: any) {
44
+ console.error(`❌ Failed to configure MCP: ${error.message}`);
45
+ }
46
+ }
47
+
48
+ export async function mcpStatus(_conductor: Conductor): Promise<void> {
49
+ try {
50
+ const data = await fs.readFile(CLAUDE_DESKTOP_CONFIG, 'utf-8');
51
+ const config = JSON.parse(data);
52
+
53
+ if (config.mcpServers?.conductor) {
54
+ console.log('✅ Conductor MCP server is configured.');
55
+ console.log(` Command: ${config.mcpServers.conductor.command}`);
56
+ console.log(` Args: ${config.mcpServers.conductor.args.join(' ')}`);
57
+ } else {
58
+ console.log('❌ Conductor MCP server is not configured.');
59
+ console.log(' Run: conductor mcp setup');
60
+ }
61
+ } catch {
62
+ console.log('❌ Claude Desktop config not found.');
63
+ console.log(' Run: conductor mcp setup');
64
+ }
65
+ }
66
+
67
+ export async function mcpStart(_conductor: Conductor): Promise<void> {
68
+ // Start in MCP stdio mode — quiet to avoid polluting stdout
69
+ const quietConductor = new (await import('../../core/conductor.js')).Conductor(undefined, { quiet: true });
70
+ await quietConductor.initialize();
71
+
72
+ // Import and start MCP server (writes JSON-RPC to stdout)
73
+ const { startMCPServer } = await import('../../mcp/server.js');
74
+ await startMCPServer(quietConductor);
75
+ }
76
+
77
+ export async function mcpRemove(_conductor: Conductor): Promise<void> {
78
+ try {
79
+ const data = await fs.readFile(CLAUDE_DESKTOP_CONFIG, 'utf-8');
80
+ const config = JSON.parse(data);
81
+
82
+ if (config.mcpServers?.conductor) {
83
+ delete config.mcpServers.conductor;
84
+ await fs.writeFile(CLAUDE_DESKTOP_CONFIG, JSON.stringify(config, null, 2));
85
+ console.log('✅ Conductor MCP server removed from Claude Desktop config.');
86
+ } else {
87
+ console.log('Conductor was not configured in Claude Desktop.');
88
+ }
89
+ } catch {
90
+ console.log('Claude Desktop config not found. Nothing to remove.');
91
+ }
92
+ }
@@ -0,0 +1,248 @@
1
+ /**
2
+ * conductor onboard — interactive TUI plugin picker
3
+ *
4
+ * Lets users browse all available plugins by category, select which ones
5
+ * to enable, and immediately configure credentials for any that need them.
6
+ * Works on first install or any time via `conductor plugins onboard`.
7
+ */
8
+
9
+ import chalk from 'chalk';
10
+ import inquirer from 'inquirer';
11
+ import { Conductor } from '../../core/conductor.js';
12
+ import { PluginManager } from '../../plugins/manager.js';
13
+
14
+ interface _PluginEntry {
15
+ name: string;
16
+ description: string;
17
+ enabled: boolean;
18
+ configured: boolean;
19
+ zeroConfig: boolean;
20
+ category: string;
21
+ }
22
+
23
+ // Category groupings for the TUI picker
24
+ const CATEGORIES: Record<string, string[]> = {
25
+ 'Developer Tools': [
26
+ 'shell', 'docker', 'github', 'git', 'github-actions', 'vercel', 'n8n', 'linear', 'jira',
27
+ ],
28
+ 'Communication': ['slack', 'telegram'],
29
+ 'Google Workspace': ['gmail', 'google-calendar', 'google-drive'],
30
+ 'Productivity': ['notes', 'memory', 'notion', 'todoist'],
31
+ 'Finance & Commerce': ['stripe'],
32
+ 'Utilities': [
33
+ 'calculator', 'colors', 'crypto', 'hash', 'text-tools',
34
+ 'timezone', 'network', 'url-tools', 'fun', 'system', 'cron', 'weather', 'translate',
35
+ ],
36
+ 'Media & Social': ['spotify', 'x'],
37
+ 'Smart Home': ['homekit'],
38
+ };
39
+
40
+ const ZERO_CONFIG_SET = new Set([
41
+ 'calculator', 'colors', 'hash', 'text-tools', 'timezone',
42
+ 'network', 'url-tools', 'fun', 'system', 'notes', 'memory',
43
+ 'cron', 'shell', 'docker', 'github', 'translate',
44
+ 'weather',
45
+ 'crypto',
46
+ ]);
47
+
48
+ function header(): void {
49
+ console.log('');
50
+ console.log(chalk.bold.white(' ╔══════════════════════════════════════╗'));
51
+ console.log(chalk.bold.white(' ║') + chalk.bold(' 🎼 Conductor — Plugin Setup ') + chalk.bold.white('║'));
52
+ console.log(chalk.bold.white(' ╚══════════════════════════════════════╝'));
53
+ console.log('');
54
+ console.log(chalk.dim(' Select the plugins you want to enable.'));
55
+ console.log(
56
+ chalk.dim(' Zero-config plugins ') + chalk.green('[free]') + chalk.dim(' work instantly — no credentials needed.'),
57
+ );
58
+ console.log('');
59
+ }
60
+
61
+ function categoryHeader(name: string): void {
62
+ console.log(' ' + chalk.bold.white('─── ' + name + ' '));
63
+ }
64
+
65
+ export async function onboard(conductor: Conductor): Promise<void> {
66
+ await conductor.initialize();
67
+ const pm = new PluginManager(conductor);
68
+ await pm.loadBuiltins();
69
+
70
+ header();
71
+
72
+ const available = pm.listPlugins();
73
+ const availableByName = new Map(available.map((p) => [p.name, p]));
74
+ const currentlyEnabled = new Set(available.filter((p) => p.enabled).map((p) => p.name));
75
+
76
+ // Build choices grouped by category
77
+ const choices: Array<{ type?: string; name?: string; value?: string; checked?: boolean; short?: string }> = [];
78
+
79
+ for (const [catName, pluginNames] of Object.entries(CATEGORIES)) {
80
+ categoryHeader(catName);
81
+
82
+ const catChoices = pluginNames
83
+ .filter((name) => availableByName.has(name))
84
+ .map((name) => {
85
+ const p = availableByName.get(name)!;
86
+ const zc = ZERO_CONFIG_SET.has(name);
87
+ const badge = zc ? ' ' + chalk.green('[zero-config]') : ' ' + chalk.yellow('[needs setup]');
88
+
89
+ return {
90
+ name: `${chalk.white(p.name.padEnd(22))} ${chalk.dim(p.description)}${badge}`,
91
+ value: name,
92
+ checked: currentlyEnabled.has(name) || zc,
93
+ short: name,
94
+ };
95
+ });
96
+
97
+ if (catChoices.length > 0) {
98
+ choices.push({ type: 'separator', name: '' });
99
+ choices.push(...catChoices);
100
+ }
101
+ }
102
+
103
+ // Also include plugins not in any category
104
+ const categorized = new Set(Object.values(CATEGORIES).flat());
105
+ const uncategorized = available.filter((p) => !categorized.has(p.name));
106
+ if (uncategorized.length > 0) {
107
+ categoryHeader('Other Plugins');
108
+ choices.push({ type: 'separator', name: '' });
109
+ for (const p of uncategorized) {
110
+ const zc = ZERO_CONFIG_SET.has(p.name);
111
+ choices.push({
112
+ name: `${chalk.white(p.name.padEnd(22))} ${chalk.dim(p.description)}${zc ? chalk.green(' [zero-config]') : chalk.yellow(' [needs setup]')}`,
113
+ value: p.name,
114
+ checked: currentlyEnabled.has(p.name) || zc,
115
+ short: p.name,
116
+ });
117
+ }
118
+ }
119
+
120
+ console.log('');
121
+ const { selected } = await inquirer.prompt<{ selected: string[] }>([
122
+ {
123
+ type: 'checkbox',
124
+ name: 'selected',
125
+ message: 'Select plugins to enable (Space to toggle, Enter to confirm):',
126
+ choices,
127
+ pageSize: 24,
128
+ },
129
+ ]);
130
+
131
+ if (selected.length === 0) {
132
+ console.log('');
133
+ console.log(chalk.yellow(' No plugins selected. Run conductor onboard again to pick plugins.'));
134
+ console.log('');
135
+ return;
136
+ }
137
+
138
+ // Determine which newly selected plugins need configuration
139
+ const toEnable = selected;
140
+ const needsSetup = toEnable.filter((name) => !ZERO_CONFIG_SET.has(name) && !currentlyEnabled.has(name));
141
+
142
+ // Update enabled list
143
+ const newEnabled = [...new Set([...Array.from(currentlyEnabled), ...toEnable])];
144
+ await conductor.getConfig().set('plugins.enabled', newEnabled);
145
+
146
+ console.log('');
147
+ console.log(chalk.bold.white(' ✓ Updated plugin list'));
148
+ console.log('');
149
+
150
+ // Offer to configure each credentialed plugin that was just selected
151
+ if (needsSetup.length > 0) {
152
+ console.log(chalk.dim(` The following plugins need credentials to work:`));
153
+ for (const name of needsSetup) {
154
+ console.log(` ${chalk.yellow('⚠')} ${chalk.white(name)}`);
155
+ }
156
+ console.log('');
157
+
158
+ const { configureNow } = await inquirer.prompt<{ configureNow: boolean }>([
159
+ {
160
+ type: 'confirm',
161
+ name: 'configureNow',
162
+ message: 'Configure credentials for these plugins now?',
163
+ default: true,
164
+ },
165
+ ]);
166
+
167
+ if (configureNow) {
168
+ for (const name of needsSetup) {
169
+ await setupPlugin(conductor, pm, name);
170
+ }
171
+ } else {
172
+ console.log('');
173
+ console.log(chalk.dim(' Configure later with:'));
174
+ for (const name of needsSetup) {
175
+ console.log(` ${chalk.cyan(`conductor plugins setup ${name}`)}`);
176
+ }
177
+ }
178
+ }
179
+
180
+ // Final summary
181
+ console.log('');
182
+ console.log(chalk.bold.white(' ─────────────────────────────────────────'));
183
+ console.log(chalk.bold.white(` 🎼 ${toEnable.length} plugins enabled — ready to start`));
184
+ console.log('');
185
+ console.log(chalk.dim(' Start the MCP server:'));
186
+ console.log(` ${chalk.cyan('conductor mcp start')}`);
187
+ console.log('');
188
+ console.log(chalk.dim(' Or connect your AI agent (auto-configures Claude Desktop):'));
189
+ console.log(` ${chalk.cyan('conductor mcp setup')}`);
190
+ console.log('');
191
+ }
192
+
193
+ async function setupPlugin(conductor: Conductor, _pm: PluginManager, name: string): Promise<void> {
194
+ console.log('');
195
+ console.log(chalk.bold(` ── Setting up ${chalk.white(name)} ──`));
196
+
197
+ const pm2 = new PluginManager(conductor);
198
+ await pm2.loadBuiltins();
199
+ const plugins = pm2.listPlugins();
200
+ const p = plugins.find((x) => x.name === name);
201
+
202
+ if (!p) {
203
+ console.log(chalk.yellow(` Plugin "${name}" not found — skipping`));
204
+ return;
205
+ }
206
+
207
+ if (!p.configSchema || p.configSchema.fields.length === 0) {
208
+ console.log(chalk.green(` ✓ ${name} requires no configuration`));
209
+ return;
210
+ }
211
+
212
+ if (p.configSchema.setupInstructions) {
213
+ console.log('');
214
+ console.log(chalk.dim(' ' + p.configSchema.setupInstructions.split('\n').join('\n ')));
215
+ console.log('');
216
+ }
217
+
218
+ // Build inquirer prompts from the plugin's configSchema
219
+ const prompts = p.configSchema.fields.map((field) => ({
220
+ type: field.type === 'password' ? 'password' : field.type === 'boolean' ? 'confirm' : 'input',
221
+ name: field.key,
222
+ message: `${field.label}${field.required ? '' : ' (optional)'}:`,
223
+ mask: field.type === 'password' ? '*' : undefined,
224
+ validate: (input: string) => {
225
+ if (field.required && !input) return `${field.label} is required`;
226
+ return true;
227
+ },
228
+ }));
229
+
230
+ const answers = await inquirer.prompt<Record<string, string>>(prompts);
231
+
232
+ // Persist the values
233
+ const { Keychain } = await import('../../security/keychain.js');
234
+ const keychain = new Keychain(conductor.getConfig().getConfigDir());
235
+
236
+ for (const field of p.configSchema.fields) {
237
+ const value = answers[field.key];
238
+ if (!value) continue;
239
+
240
+ if (field.secret) {
241
+ await keychain.set(field.service ?? name, field.key, value);
242
+ } else {
243
+ await conductor.getConfig().set(`plugins.${name}.${field.key}`, value);
244
+ }
245
+ }
246
+
247
+ console.log(chalk.green(` ✓ ${name} configured`));
248
+ }