@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,185 @@
1
+ import { Telegraf } from 'telegraf';
2
+ import { Conductor } from '../core/conductor.js';
3
+ import { Keychain } from '../security/keychain.js';
4
+ import { AIManager } from '../ai/manager.js';
5
+ import type { ConductorNotification } from '../core/interfaces.js';
6
+
7
+ export class TelegramBot {
8
+ private conductor: Conductor;
9
+ private keychain: Keychain;
10
+ private bot: Telegraf | null = null;
11
+ private aiManager: AIManager;
12
+ private authorizedUserId: number | null = null;
13
+
14
+ constructor(conductor: Conductor) {
15
+ this.conductor = conductor;
16
+ this.keychain = new Keychain(conductor.getConfig().getConfigDir());
17
+ this.aiManager = new AIManager(conductor);
18
+ }
19
+
20
+ /** Start the Telegram bot. */
21
+ async start(): Promise<void> {
22
+ // Bug fix: install.sh saves token to keychain, NOT to config.
23
+ // Read from keychain first, fall back to config for backward compat.
24
+ let token = await this.keychain.get('telegram', 'bot_token');
25
+ if (!token) {
26
+ // Legacy fallback: some users may have set it in config
27
+ token = this.conductor.getConfig().get<string>('telegram.token') ?? null;
28
+ }
29
+
30
+ if (!token) {
31
+ throw new Error('Telegram bot token not found. Run the installer or set it with: conductor telegram setup');
32
+ }
33
+
34
+ // Load authorized user ID from config (set during install verification)
35
+ this.authorizedUserId = this.conductor.getConfig().get<number>('telegram.user_id') ?? null;
36
+
37
+ this.bot = new Telegraf(token);
38
+
39
+ this.registerHandlers();
40
+
41
+ // Graceful shutdown
42
+ process.once('SIGINT', () => this.bot?.stop('SIGINT'));
43
+ process.once('SIGTERM', () => this.bot?.stop('SIGTERM'));
44
+
45
+ process.stderr.write('Telegram bot starting...\n');
46
+ await this.bot.launch();
47
+
48
+ // Register this bot as the notification handler for Conductor
49
+ this.conductor.setNotificationHandler(this.sendMessage.bind(this));
50
+
51
+ // Start the proactive loop (every 30 mins default)
52
+ await this.conductor.startProactiveMode(30);
53
+ }
54
+
55
+ /** Register message handlers. */
56
+ private registerHandlers(): void {
57
+ if (!this.bot) return;
58
+
59
+ // Auth middleware — only respond to the verified owner
60
+ this.bot.use(async (ctx, next) => {
61
+ if (this.authorizedUserId && ctx.from?.id !== this.authorizedUserId) {
62
+ await ctx.reply('⛔ Unauthorized. This bot is private.');
63
+ return;
64
+ }
65
+ return next();
66
+ });
67
+
68
+ this.bot.command('start', async (ctx) => {
69
+ await ctx.reply("👋 Conductor is online.\n\nSend me a message and I'll route it through your AI provider.");
70
+ });
71
+
72
+ this.bot.command('status', async (ctx) => {
73
+ const config = this.conductor.getConfig();
74
+ const provider = config.get<string>('ai.provider') || 'none';
75
+ const plugins = config.get<string[]>('plugins.enabled') || [];
76
+
77
+ await ctx.reply(
78
+ `📊 Status:\n` +
79
+ `AI: ${provider}\n` +
80
+ `Plugins: ${plugins.length > 0 ? plugins.join(', ') : 'none'}\n` +
81
+ `User: ${config.get<string>('user.name') || 'not set'}`,
82
+ );
83
+ });
84
+
85
+ // Default: route text messages through AI
86
+ this.bot.on('text', async (ctx) => {
87
+ const message = ctx.message.text;
88
+
89
+ try {
90
+ const provider = await this.aiManager.getCurrentProvider();
91
+ if (!provider) {
92
+ await ctx.reply('No AI provider configured. Run: conductor ai');
93
+ return;
94
+ }
95
+
96
+ // Send typing indicator
97
+ await ctx.sendChatAction('typing');
98
+
99
+ const userId = String(ctx.from.id);
100
+ const agentResponse = await this.aiManager.handleConversation(userId, message);
101
+
102
+ await this.sendAgentResponse(ctx, agentResponse);
103
+ } catch (error: any) {
104
+ process.stderr.write(`Telegram AI error: ${error.message}\n`);
105
+ await ctx.reply(`❌ Error: ${error.message}`);
106
+ }
107
+ });
108
+
109
+ this.bot.action(/^approve:(.+)$/, async (ctx) => {
110
+ await ctx.answerCbQuery();
111
+ await ctx.editMessageReplyMarkup(undefined); // remove buttons
112
+
113
+ const toolCallId = ctx.match[1];
114
+ const userId = String(ctx.from?.id);
115
+
116
+ try {
117
+ await ctx.reply('âŗ Executing approved action...');
118
+ await ctx.sendChatAction('typing');
119
+ const agentResponse = await this.aiManager.executeApprovedTool(userId, toolCallId);
120
+ await this.sendAgentResponse(ctx, agentResponse);
121
+ } catch (error: any) {
122
+ process.stderr.write(`Telegram execute error: ${error.message}\n`);
123
+ await ctx.reply(`❌ Error: ${error.message}`);
124
+ }
125
+ });
126
+
127
+ this.bot.action(/^deny:(.+)$/, async (ctx) => {
128
+ await ctx.answerCbQuery();
129
+ await ctx.editMessageReplyMarkup(undefined); // remove buttons
130
+
131
+ const toolCallId = ctx.match[1];
132
+ const userId = String(ctx.from?.id);
133
+
134
+ try {
135
+ await ctx.reply('🛑 Action denied. Informing AI...');
136
+ await ctx.sendChatAction('typing');
137
+ const agentResponse = await this.aiManager.denyTool(userId, toolCallId);
138
+ await this.sendAgentResponse(ctx, agentResponse);
139
+ } catch (error: any) {
140
+ process.stderr.write(`Telegram deny error: ${error.message}\n`);
141
+ await ctx.reply(`❌ Error: ${error.message}`);
142
+ }
143
+ });
144
+ }
145
+
146
+ private async sendAgentResponse(ctx: any, res: any): Promise<void> {
147
+ if (res.approvalRequired) {
148
+ const { toolCallId, toolName, arguments: args } = res.approvalRequired;
149
+ const text = `*âš ī¸ Action Requires Approval*\n\nThe AI wants to use the \`${toolName}\` tool.\n\n*Arguments:*\n\`\`\`json\n${JSON.stringify(args, null, 2)}\n\`\`\`\n\n${res.text || 'Do you approve?'}`;
150
+
151
+ await ctx.reply(text, {
152
+ parse_mode: 'Markdown',
153
+ reply_markup: {
154
+ inline_keyboard: [
155
+ [
156
+ { text: '✅ Approve', callback_data: `approve:${toolCallId}` },
157
+ { text: '❌ Deny', callback_data: `deny:${toolCallId}` },
158
+ ],
159
+ ],
160
+ },
161
+ });
162
+ } else {
163
+ await ctx.reply(res.text);
164
+ }
165
+ }
166
+
167
+ async stop(): Promise<void> {
168
+ this.bot?.stop();
169
+ }
170
+
171
+ /** Send a proactive notification to the authorized user. */
172
+ async sendMessage(notification: ConductorNotification): Promise<void> {
173
+ if (!this.bot) throw new Error('Bot not started');
174
+ if (!this.authorizedUserId) {
175
+ process.stderr.write(' [Telegram] Cannot send proactive message: No authorizedUserId set.\n');
176
+ return;
177
+ }
178
+ // Format as Telegram Markdown
179
+ let text = `*${notification.title}*\n\n${notification.body}`;
180
+ if (notification.codeBlock) {
181
+ text += `\n\n\`\`\`json\n${notification.codeBlock}\n\`\`\``;
182
+ }
183
+ await this.bot.telegram.sendMessage(this.authorizedUserId, text, { parse_mode: 'Markdown' });
184
+ }
185
+ }
@@ -0,0 +1,24 @@
1
+ # src/cli
2
+
3
+ Command-line interface for Conductor, built with Commander.
4
+
5
+ ## Contents
6
+
7
+ - `index.ts` - CLI entry point, command registration
8
+ - `commands/` - Individual CLI command implementations
9
+
10
+ ## Architecture
11
+
12
+ The CLI is the primary user interface for managing Conductor. Entry point is `src/cli/index.ts`. Commands live in `commands/` and cover plugin management, MCP server setup, lifecycle control, diagnostics, and plugin scaffolding.
13
+
14
+ Run locally without building:
15
+
16
+ ```bash
17
+ npx tsx src/cli/index.ts <command>
18
+ ```
19
+
20
+ After building:
21
+
22
+ ```bash
23
+ node dist/cli/index.js <command>
24
+ ```
@@ -0,0 +1,20 @@
1
+ # src/cli/commands
2
+
3
+ Individual CLI command implementations for Conductor.
4
+
5
+ ## Contents
6
+
7
+ - `plugins.ts` - Enable/disable/list/install plugins
8
+ - `mcp.ts` - Start/setup MCP server
9
+ - `lifecycle.ts` - Start/stop/status for Conductor services
10
+ - `doctor.ts` - System health diagnostics
11
+ - `marketplace.ts` - Plugin marketplace operations
12
+ - `plugin-create.ts` - Scaffold new plugins
13
+ - `ai.ts` - AI provider configuration
14
+ - `init.ts` / `onboard.ts` - Initial setup and onboarding
15
+ - `install.ts` - Installation utilities
16
+ - `telegram.ts` - Telegram bot configuration
17
+
18
+ ## Architecture
19
+
20
+ Each command is a Commander subcommand registered in `src/cli/index.ts`. Commands interact with the `Conductor` instance to manage plugins, configure AI providers, control service lifecycle, and perform diagnostics.
@@ -0,0 +1,170 @@
1
+ import { Conductor } from '../../core/conductor.js';
2
+ import { AIManager } from '../../ai/manager.js';
3
+
4
+ export async function setupAI(conductor: Conductor): Promise<void> {
5
+ await conductor.initialize();
6
+
7
+ const { default: inquirer } = await import('inquirer');
8
+
9
+ const { provider } = await inquirer.prompt([
10
+ {
11
+ type: 'list',
12
+ name: 'provider',
13
+ message: 'Select an AI provider:',
14
+ choices: [
15
+ { name: 'Claude (Anthropic)', value: 'claude' },
16
+ { name: 'OpenAI (GPT-4o)', value: 'openai' },
17
+ { name: 'OpenRouter', value: 'openrouter' },
18
+ { name: 'Gemini (Google)', value: 'gemini' },
19
+ { name: 'Ollama (Local)', value: 'ollama' },
20
+ ],
21
+ },
22
+ ]);
23
+
24
+ const aiManager = new AIManager(conductor);
25
+
26
+ switch (provider) {
27
+ case 'claude': {
28
+ const { apiKey } = await inquirer.prompt([
29
+ {
30
+ type: 'password',
31
+ name: 'apiKey',
32
+ message: 'Enter your Anthropic API key:',
33
+ mask: '*',
34
+ },
35
+ ]);
36
+ await aiManager.setupClaude(apiKey);
37
+ console.log('✅ Claude configured successfully.');
38
+ break;
39
+ }
40
+ case 'openai': {
41
+ const { apiKey } = await inquirer.prompt([
42
+ {
43
+ type: 'password',
44
+ name: 'apiKey',
45
+ message: 'Enter your OpenAI API key:',
46
+ mask: '*',
47
+ },
48
+ ]);
49
+ await aiManager.setupOpenAI(apiKey);
50
+ console.log('✅ OpenAI configured successfully.');
51
+ break;
52
+ }
53
+ case 'openrouter': {
54
+ const { apiKey } = await inquirer.prompt([
55
+ {
56
+ type: 'password',
57
+ name: 'apiKey',
58
+ message: 'Enter your OpenRouter API key:',
59
+ mask: '*',
60
+ },
61
+ ]);
62
+
63
+ // Fetch available models from OpenRouter using the provided key
64
+ let modelChoices: { name: string; value: string }[] = [];
65
+ try {
66
+ process.stdout.write('Fetching available models from OpenRouter...');
67
+ const res = await fetch('https://openrouter.ai/api/v1/models', {
68
+ headers: { Authorization: `Bearer ${apiKey}` },
69
+ });
70
+ if (res.ok) {
71
+ const json = (await res.json()) as { data: { id: string; name: string }[] };
72
+ modelChoices = json.data
73
+ .sort((a: { id: string; name: string }, b: { id: string; name: string }) => a.id.localeCompare(b.id))
74
+ .map((m: { id: string; name: string }) => ({ name: `${m.name} (${m.id})`, value: m.id }));
75
+ process.stdout.write(` ${modelChoices.length} models found.\n`);
76
+ }
77
+ } catch {
78
+ // silently fall through to manual entry
79
+ }
80
+
81
+ let model: string;
82
+ if (modelChoices.length > 0) {
83
+ const answer = await inquirer.prompt([
84
+ {
85
+ type: 'select',
86
+ name: 'model',
87
+ message: 'Select a model:',
88
+ choices: modelChoices,
89
+ pageSize: 15,
90
+ },
91
+ ]);
92
+ model = answer.model;
93
+ } else {
94
+ console.log('Could not fetch model list. Please enter a model ID manually.');
95
+ const answer = await inquirer.prompt([
96
+ {
97
+ type: 'input',
98
+ name: 'model',
99
+ message: 'Model ID (e.g. openai/gpt-4o, anthropic/claude-3.5-sonnet):',
100
+ default: 'openai/gpt-4o',
101
+ },
102
+ ]);
103
+ model = answer.model;
104
+ }
105
+
106
+ await aiManager.setupOpenRouter(apiKey, model);
107
+ console.log(`\u2705 OpenRouter configured successfully with ${model}.`);
108
+ break;
109
+ }
110
+ case 'gemini': {
111
+ const { method } = await inquirer.prompt([
112
+ {
113
+ type: 'list',
114
+ name: 'method',
115
+ message: 'How would you like to authenticate?',
116
+ choices: [
117
+ { name: 'Google Sign-In (easiest)', value: 'oauth' },
118
+ { name: 'API Key', value: 'api_key' },
119
+ ],
120
+ },
121
+ ]);
122
+
123
+ if (method === 'oauth') {
124
+ console.log('Opening browser for Google Sign-In...');
125
+ await aiManager.setupGeminiOAuthEasy();
126
+ console.log('✅ Gemini configured with Google Sign-In.');
127
+ } else {
128
+ const { apiKey } = await inquirer.prompt([
129
+ {
130
+ type: 'password',
131
+ name: 'apiKey',
132
+ message: 'Enter your Gemini API key:',
133
+ mask: '*',
134
+ },
135
+ ]);
136
+ await aiManager.setupGemini(apiKey);
137
+ console.log('✅ Gemini configured successfully.');
138
+ }
139
+ break;
140
+ }
141
+ case 'ollama': {
142
+ const { model } = await inquirer.prompt([
143
+ {
144
+ type: 'input',
145
+ name: 'model',
146
+ message: 'Which Ollama model?',
147
+ default: 'llama3.2',
148
+ },
149
+ ]);
150
+ await aiManager.setupOllama(model);
151
+ console.log(`✅ Ollama configured with ${model}.`);
152
+ break;
153
+ }
154
+ }
155
+ }
156
+
157
+ export async function testAI(conductor: Conductor): Promise<void> {
158
+ await conductor.initialize();
159
+ const aiManager = new AIManager(conductor);
160
+
161
+ const provider = await aiManager.getCurrentProvider();
162
+ if (!provider) {
163
+ console.log('No AI provider configured. Run: conductor ai setup');
164
+ return;
165
+ }
166
+
167
+ console.log(`Testing ${provider.getName()}...`);
168
+ const works = await provider.test();
169
+ console.log(works ? '✅ AI provider is working.' : '❌ AI provider test failed.');
170
+ }
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Conductor Doctor — diagnose every possible issue and tell you how to fix it.
3
+ *
4
+ * Checks:
5
+ * - Node.js version
6
+ * - Config file existence and validity
7
+ * - Keychain accessibility
8
+ * - AI provider configuration
9
+ * - Plugin status
10
+ * - MCP server connectivity
11
+ * - Disk space
12
+ * - Environment variables
13
+ * - Dependency versions
14
+ * - File permissions
15
+ */
16
+
17
+ import { Conductor } from '../../core/conductor.js';
18
+ import fs from 'fs/promises';
19
+ import path from 'path';
20
+ import os from 'os';
21
+
22
+ interface CheckResult {
23
+ name: string;
24
+ status: 'ok' | 'warning' | 'error';
25
+ message: string;
26
+ fix?: string;
27
+ }
28
+
29
+ export async function doctor(conductor: Conductor): Promise<void> {
30
+ const checks: CheckResult[] = [];
31
+
32
+ // Node.js version
33
+ const nodeVersion = process.version;
34
+ const major = parseInt(nodeVersion.slice(1).split('.')[0]);
35
+ if (major >= 18) {
36
+ checks.push({ name: 'Node.js', status: 'ok', message: `${nodeVersion}` });
37
+ } else if (major >= 16) {
38
+ checks.push({
39
+ name: 'Node.js',
40
+ status: 'warning',
41
+ message: `${nodeVersion} (upgrade to 18+ recommended)`,
42
+ fix: 'nvm install 18',
43
+ });
44
+ } else {
45
+ checks.push({ name: 'Node.js', status: 'error', message: `${nodeVersion} (requires 18+)`, fix: 'nvm install 18' });
46
+ }
47
+
48
+ // Config directory
49
+ await conductor.initialize();
50
+ const configDir = conductor.getConfig().getConfigDir();
51
+ try {
52
+ await fs.access(configDir);
53
+ checks.push({ name: 'Config directory', status: 'ok', message: configDir });
54
+ } catch {
55
+ checks.push({
56
+ name: 'Config directory',
57
+ status: 'error',
58
+ message: `${configDir} does not exist`,
59
+ fix: `mkdir -p ${configDir}`,
60
+ });
61
+ }
62
+
63
+ // Config file
64
+ try {
65
+ const configFile = path.join(configDir, 'config.json');
66
+ const content = await fs.readFile(configFile, 'utf-8');
67
+ JSON.parse(content);
68
+ checks.push({ name: 'Config file', status: 'ok', message: configFile });
69
+ } catch (err) {
70
+ const msg = err instanceof Error ? err.message : String(err);
71
+ checks.push({
72
+ name: 'Config file',
73
+ status: 'warning',
74
+ message: `Not found or invalid: ${msg}`,
75
+ fix: 'Run: conductor ai setup',
76
+ });
77
+ }
78
+
79
+ // Keychain
80
+ try {
81
+ const keychainDir = path.join(configDir, 'keychain');
82
+ await fs.access(keychainDir);
83
+ const files = await fs.readdir(keychainDir);
84
+ checks.push({ name: 'Keychain', status: 'ok', message: `${files.length} credentials stored` });
85
+ } catch {
86
+ checks.push({
87
+ name: 'Keychain',
88
+ status: 'warning',
89
+ message: 'Not initialized',
90
+ fix: 'Run: conductor ai setup or conductor auth google',
91
+ });
92
+ }
93
+
94
+ // AI Provider
95
+ const aiProvider = conductor.getConfig().get<string>('ai.provider');
96
+ if (aiProvider) {
97
+ checks.push({ name: 'AI Provider', status: 'ok', message: aiProvider });
98
+ } else {
99
+ checks.push({ name: 'AI Provider', status: 'warning', message: 'Not configured', fix: 'Run: conductor ai setup' });
100
+ }
101
+
102
+ // Enabled plugins
103
+ const enabledPlugins = conductor.getConfig().get<string[]>('plugins.enabled') || [];
104
+ if (enabledPlugins.length > 0) {
105
+ checks.push({
106
+ name: 'Plugins',
107
+ status: 'ok',
108
+ message: `${enabledPlugins.length} enabled: ${enabledPlugins.join(', ')}`,
109
+ });
110
+ } else {
111
+ checks.push({
112
+ name: 'Plugins',
113
+ status: 'warning',
114
+ message: 'No plugins enabled',
115
+ fix: 'Run: conductor plugins enable <name>',
116
+ });
117
+ }
118
+
119
+ // Disk space
120
+ const homeDir = os.homedir();
121
+ try {
122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
+ const si = await import('systeminformation');
124
+ const fsInfo = await si.default.fsSize();
125
+ const homeFs = fsInfo.find((f: any) => homeDir.startsWith(f.mount));
126
+ if (homeFs) {
127
+ const usedPercent = homeFs.use;
128
+ if (usedPercent > 90) {
129
+ checks.push({
130
+ name: 'Disk space',
131
+ status: 'error',
132
+ message: `${usedPercent.toFixed(1)}% used on ${homeFs.mount}`,
133
+ fix: 'Free up disk space',
134
+ });
135
+ } else if (usedPercent > 80) {
136
+ checks.push({
137
+ name: 'Disk space',
138
+ status: 'warning',
139
+ message: `${usedPercent.toFixed(1)}% used on ${homeFs.mount}`,
140
+ });
141
+ } else {
142
+ checks.push({
143
+ name: 'Disk space',
144
+ status: 'ok',
145
+ message: `${usedPercent.toFixed(1)}% used on ${homeFs.mount}`,
146
+ });
147
+ }
148
+ }
149
+ } catch {
150
+ // systeminformation might not be available
151
+ }
152
+
153
+ // Environment variables
154
+ const envVars = ['CLAUDE_API_KEY', 'OPENAI_API_KEY', 'GEMINI_API_KEY', 'GITHUB_TOKEN'];
155
+ const setVars = envVars.filter((v) => process.env[v]);
156
+ if (setVars.length > 0) {
157
+ checks.push({
158
+ name: 'Environment',
159
+ status: 'ok',
160
+ message: `${setVars.length} env vars set: ${setVars.join(', ')}`,
161
+ });
162
+ } else {
163
+ checks.push({
164
+ name: 'Environment',
165
+ status: 'warning',
166
+ message: 'No API keys in environment',
167
+ fix: 'Add keys to .env or run conductor ai setup',
168
+ });
169
+ }
170
+
171
+ // Audit log integrity
172
+ try {
173
+ const { AuditLogger } = await import('../../core/audit.js');
174
+ const audit = new AuditLogger(configDir);
175
+ const integrity = await audit.verifyIntegrity();
176
+ if (integrity.valid) {
177
+ checks.push({ name: 'Audit log', status: 'ok', message: 'Integrity verified' });
178
+ } else {
179
+ checks.push({
180
+ name: 'Audit log',
181
+ status: 'error',
182
+ message: `Integrity broken at ${integrity.brokenAt}`,
183
+ fix: 'Audit log may have been tampered with',
184
+ });
185
+ }
186
+ await audit.close();
187
+ } catch {
188
+ checks.push({ name: 'Audit log', status: 'warning', message: 'Not accessible' });
189
+ }
190
+
191
+ // Print results
192
+ console.log('');
193
+ console.log(' 🔍 Conductor Doctor');
194
+ console.log(' ═══════════════════\n');
195
+
196
+ const errors = checks.filter((c) => c.status === 'error');
197
+ const warnings = checks.filter((c) => c.status === 'warning');
198
+ const oks = checks.filter((c) => c.status === 'ok');
199
+
200
+ for (const check of checks) {
201
+ const icon = check.status === 'ok' ? '✅' : check.status === 'warning' ? 'âš ī¸' : '❌';
202
+ console.log(` ${icon} ${check.name}`);
203
+ console.log(` ${check.message}`);
204
+ if (check.fix) {
205
+ console.log(` Fix: ${check.fix}`);
206
+ }
207
+ console.log('');
208
+ }
209
+
210
+ console.log(' ═══════════════════');
211
+ console.log(` ${oks.length} ok, ${warnings.length} warnings, ${errors.length} errors\n`);
212
+
213
+ if (errors.length > 0) {
214
+ console.log(' âš ī¸ Critical issues found. Fix them before using Conductor.\n');
215
+ process.exit(1);
216
+ } else if (warnings.length > 0) {
217
+ console.log(' â„šī¸ Some warnings found. Conductor will work, but consider fixing them.\n');
218
+ } else {
219
+ console.log(' 🎉 Everything looks good!\n');
220
+ }
221
+ }