@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.
- package/.claude-plugin/marketplace.json +33 -0
- package/.claude-plugin/plugin.json +23 -0
- package/.eslintrc.json +23 -0
- package/.gitattributes +6 -0
- package/.github/FUNDING.yml +15 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +91 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +63 -0
- package/.github/ISSUE_TEMPLATE/plugin_request.yml +71 -0
- package/.github/README.md +13 -0
- package/.github/workflows/README.md +22 -0
- package/.github/workflows/auto-release.yml +112 -0
- package/.github/workflows/ci.yml +49 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +36 -0
- package/.github/workflows/sync-install.yml +47 -0
- package/.mcp.json +9 -0
- package/.prettierrc.json +7 -0
- package/C.png +0 -0
- package/CHANGELOG.md +74 -0
- package/CLAUDE.md +118 -0
- package/CONTRIBUTING.md +231 -0
- package/LICENSE +201 -0
- package/README.md +179 -0
- package/SECURITY.md +47 -0
- package/commands/conductor-setup.md +11 -0
- package/commands/conductor-status.md +7 -0
- package/dist/ai/base.d.ts +44 -0
- package/dist/ai/base.d.ts.map +1 -0
- package/dist/ai/base.js +47 -0
- package/dist/ai/base.js.map +1 -0
- package/dist/ai/claude.d.ts +11 -0
- package/dist/ai/claude.d.ts.map +1 -0
- package/dist/ai/claude.js +149 -0
- package/dist/ai/claude.js.map +1 -0
- package/dist/ai/gemini.d.ts +15 -0
- package/dist/ai/gemini.d.ts.map +1 -0
- package/dist/ai/gemini.js +156 -0
- package/dist/ai/gemini.js.map +1 -0
- package/dist/ai/maestro.d.ts +22 -0
- package/dist/ai/maestro.d.ts.map +1 -0
- package/dist/ai/maestro.js +142 -0
- package/dist/ai/maestro.js.map +1 -0
- package/dist/ai/manager.d.ts +47 -0
- package/dist/ai/manager.d.ts.map +1 -0
- package/dist/ai/manager.js +450 -0
- package/dist/ai/manager.js.map +1 -0
- package/dist/ai/ollama.d.ts +16 -0
- package/dist/ai/ollama.d.ts.map +1 -0
- package/dist/ai/ollama.js +151 -0
- package/dist/ai/ollama.js.map +1 -0
- package/dist/ai/openai.d.ts +11 -0
- package/dist/ai/openai.d.ts.map +1 -0
- package/dist/ai/openai.js +132 -0
- package/dist/ai/openai.js.map +1 -0
- package/dist/ai/openrouter.d.ts +11 -0
- package/dist/ai/openrouter.d.ts.map +1 -0
- package/dist/ai/openrouter.js +139 -0
- package/dist/ai/openrouter.js.map +1 -0
- package/dist/bot/slack.d.ts +17 -0
- package/dist/bot/slack.d.ts.map +1 -0
- package/dist/bot/slack.js +144 -0
- package/dist/bot/slack.js.map +1 -0
- package/dist/bot/telegram.d.ts +19 -0
- package/dist/bot/telegram.d.ts.map +1 -0
- package/dist/bot/telegram.js +157 -0
- package/dist/bot/telegram.js.map +1 -0
- package/dist/cli/commands/ai.d.ts +4 -0
- package/dist/cli/commands/ai.d.ts.map +1 -0
- package/dist/cli/commands/ai.js +161 -0
- package/dist/cli/commands/ai.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +18 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +213 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +281 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +16 -0
- package/dist/cli/commands/install.d.ts.map +1 -0
- package/dist/cli/commands/install.js +750 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +4 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +84 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/marketplace.d.ts +13 -0
- package/dist/cli/commands/marketplace.d.ts.map +1 -0
- package/dist/cli/commands/marketplace.js +197 -0
- package/dist/cli/commands/marketplace.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +83 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +10 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +207 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/plugin-create.d.ts +13 -0
- package/dist/cli/commands/plugin-create.d.ts.map +1 -0
- package/dist/cli/commands/plugin-create.js +122 -0
- package/dist/cli/commands/plugin-create.js.map +1 -0
- package/dist/cli/commands/plugins.d.ts +5 -0
- package/dist/cli/commands/plugins.d.ts.map +1 -0
- package/dist/cli/commands/plugins.js +30 -0
- package/dist/cli/commands/plugins.js.map +1 -0
- package/dist/cli/commands/release.d.ts +13 -0
- package/dist/cli/commands/release.d.ts.map +1 -0
- package/dist/cli/commands/release.js +243 -0
- package/dist/cli/commands/release.js.map +1 -0
- package/dist/cli/commands/telegram.d.ts +3 -0
- package/dist/cli/commands/telegram.d.ts.map +1 -0
- package/dist/cli/commands/telegram.js +20 -0
- package/dist/cli/commands/telegram.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +402 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/oauth.d.ts +8 -0
- package/dist/config/oauth.d.ts.map +1 -0
- package/dist/config/oauth.js +13 -0
- package/dist/config/oauth.js.map +1 -0
- package/dist/core/audit.d.ts +91 -0
- package/dist/core/audit.d.ts.map +1 -0
- package/dist/core/audit.js +233 -0
- package/dist/core/audit.js.map +1 -0
- package/dist/core/circuit-breaker.d.ts +56 -0
- package/dist/core/circuit-breaker.d.ts.map +1 -0
- package/dist/core/circuit-breaker.js +107 -0
- package/dist/core/circuit-breaker.js.map +1 -0
- package/dist/core/conductor.d.ts +44 -0
- package/dist/core/conductor.d.ts.map +1 -0
- package/dist/core/conductor.js +200 -0
- package/dist/core/conductor.js.map +1 -0
- package/dist/core/config.d.ts +66 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +86 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/database.d.ts +59 -0
- package/dist/core/database.d.ts.map +1 -0
- package/dist/core/database.js +342 -0
- package/dist/core/database.js.map +1 -0
- package/dist/core/errors.d.ts +231 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +254 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/health.d.ts +72 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +116 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/interfaces.d.ts +62 -0
- package/dist/core/interfaces.d.ts.map +1 -0
- package/dist/core/interfaces.js +8 -0
- package/dist/core/interfaces.js.map +1 -0
- package/dist/core/logger.d.ts +15 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +30 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/rbac.d.ts +132 -0
- package/dist/core/rbac.d.ts.map +1 -0
- package/dist/core/rbac.js +230 -0
- package/dist/core/rbac.js.map +1 -0
- package/dist/core/retry.d.ts +22 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +41 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/webhooks.d.ts +92 -0
- package/dist/core/webhooks.d.ts.map +1 -0
- package/dist/core/webhooks.js +176 -0
- package/dist/core/webhooks.js.map +1 -0
- package/dist/core/zero-config.d.ts +22 -0
- package/dist/core/zero-config.d.ts.map +1 -0
- package/dist/core/zero-config.js +59 -0
- package/dist/core/zero-config.js.map +1 -0
- package/dist/dashboard/cli.d.ts +6 -0
- package/dist/dashboard/cli.d.ts.map +1 -0
- package/dist/dashboard/cli.js +42 -0
- package/dist/dashboard/cli.js.map +1 -0
- package/dist/dashboard/index.html +3426 -0
- package/dist/dashboard/server.d.ts +7 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +1427 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/mcp/server.d.ts +27 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +380 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/misc.d.ts +15 -0
- package/dist/mcp/tools/misc.d.ts.map +1 -0
- package/dist/mcp/tools/misc.js +49 -0
- package/dist/mcp/tools/misc.js.map +1 -0
- package/dist/plugins/builtin/calculator.d.ts +11 -0
- package/dist/plugins/builtin/calculator.d.ts.map +1 -0
- package/dist/plugins/builtin/calculator.js +166 -0
- package/dist/plugins/builtin/calculator.js.map +1 -0
- package/dist/plugins/builtin/colors.d.ts +15 -0
- package/dist/plugins/builtin/colors.d.ts.map +1 -0
- package/dist/plugins/builtin/colors.js +193 -0
- package/dist/plugins/builtin/colors.js.map +1 -0
- package/dist/plugins/builtin/cron.d.ts +40 -0
- package/dist/plugins/builtin/cron.d.ts.map +1 -0
- package/dist/plugins/builtin/cron.js +578 -0
- package/dist/plugins/builtin/cron.js.map +1 -0
- package/dist/plugins/builtin/crypto.d.ts +11 -0
- package/dist/plugins/builtin/crypto.d.ts.map +1 -0
- package/dist/plugins/builtin/crypto.js +83 -0
- package/dist/plugins/builtin/crypto.js.map +1 -0
- package/dist/plugins/builtin/database.d.ts +29 -0
- package/dist/plugins/builtin/database.d.ts.map +1 -0
- package/dist/plugins/builtin/database.js +230 -0
- package/dist/plugins/builtin/database.js.map +1 -0
- package/dist/plugins/builtin/docker.d.ts +12 -0
- package/dist/plugins/builtin/docker.d.ts.map +1 -0
- package/dist/plugins/builtin/docker.js +436 -0
- package/dist/plugins/builtin/docker.js.map +1 -0
- package/dist/plugins/builtin/fun.d.ts +11 -0
- package/dist/plugins/builtin/fun.d.ts.map +1 -0
- package/dist/plugins/builtin/fun.js +114 -0
- package/dist/plugins/builtin/fun.js.map +1 -0
- package/dist/plugins/builtin/gcal.d.ts +38 -0
- package/dist/plugins/builtin/gcal.d.ts.map +1 -0
- package/dist/plugins/builtin/gcal.js +280 -0
- package/dist/plugins/builtin/gcal.js.map +1 -0
- package/dist/plugins/builtin/gdrive.d.ts +26 -0
- package/dist/plugins/builtin/gdrive.d.ts.map +1 -0
- package/dist/plugins/builtin/gdrive.js +295 -0
- package/dist/plugins/builtin/gdrive.js.map +1 -0
- package/dist/plugins/builtin/github-actions.d.ts +38 -0
- package/dist/plugins/builtin/github-actions.d.ts.map +1 -0
- package/dist/plugins/builtin/github-actions.js +629 -0
- package/dist/plugins/builtin/github-actions.js.map +1 -0
- package/dist/plugins/builtin/github.d.ts +26 -0
- package/dist/plugins/builtin/github.d.ts.map +1 -0
- package/dist/plugins/builtin/github.js +800 -0
- package/dist/plugins/builtin/github.js.map +1 -0
- package/dist/plugins/builtin/gmail.d.ts +50 -0
- package/dist/plugins/builtin/gmail.d.ts.map +1 -0
- package/dist/plugins/builtin/gmail.js +445 -0
- package/dist/plugins/builtin/gmail.js.map +1 -0
- package/dist/plugins/builtin/hash.d.ts +11 -0
- package/dist/plugins/builtin/hash.d.ts.map +1 -0
- package/dist/plugins/builtin/hash.js +95 -0
- package/dist/plugins/builtin/hash.js.map +1 -0
- package/dist/plugins/builtin/homekit.d.ts +53 -0
- package/dist/plugins/builtin/homekit.d.ts.map +1 -0
- package/dist/plugins/builtin/homekit.js +341 -0
- package/dist/plugins/builtin/homekit.js.map +1 -0
- package/dist/plugins/builtin/index.d.ts +4 -0
- package/dist/plugins/builtin/index.d.ts.map +1 -0
- package/dist/plugins/builtin/index.js +96 -0
- package/dist/plugins/builtin/index.js.map +1 -0
- package/dist/plugins/builtin/jira.d.ts +50 -0
- package/dist/plugins/builtin/jira.d.ts.map +1 -0
- package/dist/plugins/builtin/jira.js +353 -0
- package/dist/plugins/builtin/jira.js.map +1 -0
- package/dist/plugins/builtin/linear.d.ts +35 -0
- package/dist/plugins/builtin/linear.d.ts.map +1 -0
- package/dist/plugins/builtin/linear.js +397 -0
- package/dist/plugins/builtin/linear.js.map +1 -0
- package/dist/plugins/builtin/lumen.d.ts +21 -0
- package/dist/plugins/builtin/lumen.d.ts.map +1 -0
- package/dist/plugins/builtin/lumen.js +404 -0
- package/dist/plugins/builtin/lumen.js.map +1 -0
- package/dist/plugins/builtin/memory.d.ts +22 -0
- package/dist/plugins/builtin/memory.d.ts.map +1 -0
- package/dist/plugins/builtin/memory.js +184 -0
- package/dist/plugins/builtin/memory.js.map +1 -0
- package/dist/plugins/builtin/n8n.d.ts +60 -0
- package/dist/plugins/builtin/n8n.d.ts.map +1 -0
- package/dist/plugins/builtin/n8n.js +519 -0
- package/dist/plugins/builtin/n8n.js.map +1 -0
- package/dist/plugins/builtin/network.d.ts +11 -0
- package/dist/plugins/builtin/network.d.ts.map +1 -0
- package/dist/plugins/builtin/network.js +88 -0
- package/dist/plugins/builtin/network.js.map +1 -0
- package/dist/plugins/builtin/notes.d.ts +47 -0
- package/dist/plugins/builtin/notes.d.ts.map +1 -0
- package/dist/plugins/builtin/notes.js +641 -0
- package/dist/plugins/builtin/notes.js.map +1 -0
- package/dist/plugins/builtin/notion.d.ts +47 -0
- package/dist/plugins/builtin/notion.d.ts.map +1 -0
- package/dist/plugins/builtin/notion.js +317 -0
- package/dist/plugins/builtin/notion.js.map +1 -0
- package/dist/plugins/builtin/shell.d.ts +12 -0
- package/dist/plugins/builtin/shell.d.ts.map +1 -0
- package/dist/plugins/builtin/shell.js +310 -0
- package/dist/plugins/builtin/shell.js.map +1 -0
- package/dist/plugins/builtin/slack.d.ts +31 -0
- package/dist/plugins/builtin/slack.d.ts.map +1 -0
- package/dist/plugins/builtin/slack.js +295 -0
- package/dist/plugins/builtin/slack.js.map +1 -0
- package/dist/plugins/builtin/spotify.d.ts +55 -0
- package/dist/plugins/builtin/spotify.d.ts.map +1 -0
- package/dist/plugins/builtin/spotify.js +623 -0
- package/dist/plugins/builtin/spotify.js.map +1 -0
- package/dist/plugins/builtin/stripe.d.ts +35 -0
- package/dist/plugins/builtin/stripe.d.ts.map +1 -0
- package/dist/plugins/builtin/stripe.js +376 -0
- package/dist/plugins/builtin/stripe.js.map +1 -0
- package/dist/plugins/builtin/system.d.ts +11 -0
- package/dist/plugins/builtin/system.d.ts.map +1 -0
- package/dist/plugins/builtin/system.js +91 -0
- package/dist/plugins/builtin/system.js.map +1 -0
- package/dist/plugins/builtin/text-tools.d.ts +11 -0
- package/dist/plugins/builtin/text-tools.d.ts.map +1 -0
- package/dist/plugins/builtin/text-tools.js +146 -0
- package/dist/plugins/builtin/text-tools.js.map +1 -0
- package/dist/plugins/builtin/timezone.d.ts +13 -0
- package/dist/plugins/builtin/timezone.d.ts.map +1 -0
- package/dist/plugins/builtin/timezone.js +164 -0
- package/dist/plugins/builtin/timezone.js.map +1 -0
- package/dist/plugins/builtin/todoist.d.ts +49 -0
- package/dist/plugins/builtin/todoist.d.ts.map +1 -0
- package/dist/plugins/builtin/todoist.js +540 -0
- package/dist/plugins/builtin/todoist.js.map +1 -0
- package/dist/plugins/builtin/translate.d.ts +11 -0
- package/dist/plugins/builtin/translate.d.ts.map +1 -0
- package/dist/plugins/builtin/translate.js +42 -0
- package/dist/plugins/builtin/translate.js.map +1 -0
- package/dist/plugins/builtin/url-tools.d.ts +11 -0
- package/dist/plugins/builtin/url-tools.d.ts.map +1 -0
- package/dist/plugins/builtin/url-tools.js +70 -0
- package/dist/plugins/builtin/url-tools.js.map +1 -0
- package/dist/plugins/builtin/vercel.d.ts +55 -0
- package/dist/plugins/builtin/vercel.d.ts.map +1 -0
- package/dist/plugins/builtin/vercel.js +514 -0
- package/dist/plugins/builtin/vercel.js.map +1 -0
- package/dist/plugins/builtin/weather.d.ts +13 -0
- package/dist/plugins/builtin/weather.d.ts.map +1 -0
- package/dist/plugins/builtin/weather.js +103 -0
- package/dist/plugins/builtin/weather.js.map +1 -0
- package/dist/plugins/builtin/x.d.ts +54 -0
- package/dist/plugins/builtin/x.d.ts.map +1 -0
- package/dist/plugins/builtin/x.js +402 -0
- package/dist/plugins/builtin/x.js.map +1 -0
- package/dist/plugins/manager.d.ts +77 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +141 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/validation.d.ts +18 -0
- package/dist/plugins/validation.d.ts.map +1 -0
- package/dist/plugins/validation.js +81 -0
- package/dist/plugins/validation.js.map +1 -0
- package/dist/security/auth.d.ts +23 -0
- package/dist/security/auth.d.ts.map +1 -0
- package/dist/security/auth.js +56 -0
- package/dist/security/auth.js.map +1 -0
- package/dist/security/keychain.d.ts +60 -0
- package/dist/security/keychain.d.ts.map +1 -0
- package/dist/security/keychain.js +213 -0
- package/dist/security/keychain.js.map +1 -0
- package/dist/utils/google-auth.d.ts +21 -0
- package/dist/utils/google-auth.d.ts.map +1 -0
- package/dist/utils/google-auth.js +135 -0
- package/dist/utils/google-auth.js.map +1 -0
- package/dist/utils/retry.d.ts +5 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +34 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/README.md +13 -0
- package/docs/api.md +210 -0
- package/docs/getting-started.md +100 -0
- package/docs/plugins.md +306 -0
- package/docs-site/.vitepress/config.ts +59 -0
- package/docs-site/README.md +12 -0
- package/docs-site/index.md +30 -0
- package/eslint.config.js +29 -0
- package/install.ps1 +334 -0
- package/install.sh +1119 -0
- package/local-install.sh +304 -0
- package/package.json +90 -0
- package/packages/README.md +11 -0
- package/packages/plugin-sdk/README.md +12 -0
- package/packages/plugin-sdk/package.json +22 -0
- package/packages/plugin-sdk/src/README.md +11 -0
- package/packages/plugin-sdk/src/index.ts +191 -0
- package/sdks/README.md +26 -0
- package/sdks/csharp/ConductorClient.cs +65 -0
- package/sdks/csharp/README.md +11 -0
- package/sdks/go/README.md +11 -0
- package/sdks/go/conductor.go +257 -0
- package/sdks/java/ConductorClient.java +27 -0
- package/sdks/java/README.md +11 -0
- package/sdks/php/README.md +11 -0
- package/sdks/php/src/Client.php +72 -0
- package/sdks/python/README.md +12 -0
- package/sdks/python/conductor/__init__.py +227 -0
- package/sdks/python/pyproject.toml +30 -0
- package/sdks/ruby/README.md +11 -0
- package/sdks/ruby/lib/conductor.rb +46 -0
- package/sdks/rust/Cargo.toml +14 -0
- package/sdks/rust/README.md +11 -0
- package/sdks/swift/README.md +11 -0
- package/sdks/swift/Sources/Conductor/ConductorClient.swift +65 -0
- package/skills/conductor-mcp/SKILL.md +38 -0
- package/src/README.md +20 -0
- package/src/ai/README.md +18 -0
- package/src/ai/base.ts +93 -0
- package/src/ai/claude.ts +162 -0
- package/src/ai/gemini.ts +188 -0
- package/src/ai/maestro.ts +168 -0
- package/src/ai/manager.ts +537 -0
- package/src/ai/ollama.ts +186 -0
- package/src/ai/openai.ts +147 -0
- package/src/ai/openrouter.ts +152 -0
- package/src/bot/README.md +12 -0
- package/src/bot/slack.ts +164 -0
- package/src/bot/telegram.ts +185 -0
- package/src/cli/README.md +24 -0
- package/src/cli/commands/README.md +20 -0
- package/src/cli/commands/ai.ts +170 -0
- package/src/cli/commands/doctor.ts +221 -0
- package/src/cli/commands/init.ts +348 -0
- package/src/cli/commands/install.ts +792 -0
- package/src/cli/commands/lifecycle.ts +95 -0
- package/src/cli/commands/marketplace.ts +253 -0
- package/src/cli/commands/mcp.ts +92 -0
- package/src/cli/commands/onboard.ts +248 -0
- package/src/cli/commands/plugin-create.ts +130 -0
- package/src/cli/commands/plugins.ts +36 -0
- package/src/cli/commands/release.ts +251 -0
- package/src/cli/commands/telegram.ts +25 -0
- package/src/cli/index.ts +450 -0
- package/src/config/README.md +11 -0
- package/src/config/oauth.ts +26 -0
- package/src/core/README.md +22 -0
- package/src/core/audit.ts +291 -0
- package/src/core/circuit-breaker.ts +129 -0
- package/src/core/conductor.ts +240 -0
- package/src/core/config.ts +149 -0
- package/src/core/database.ts +411 -0
- package/src/core/errors.ts +275 -0
- package/src/core/health.ts +159 -0
- package/src/core/interfaces.ts +75 -0
- package/src/core/logger.ts +33 -0
- package/src/core/rbac.ts +321 -0
- package/src/core/retry.ts +61 -0
- package/src/core/webhooks.ts +234 -0
- package/src/core/zero-config.ts +72 -0
- package/src/dashboard/README.md +15 -0
- package/src/dashboard/cli.ts +48 -0
- package/src/dashboard/index.html +3426 -0
- package/src/dashboard/server.ts +1544 -0
- package/src/mcp/README.md +20 -0
- package/src/mcp/server.ts +475 -0
- package/src/mcp/tools/README.md +11 -0
- package/src/mcp/tools/misc.ts +61 -0
- package/src/plugins/README.md +28 -0
- package/src/plugins/builtin/README.md +23 -0
- package/src/plugins/builtin/calculator.ts +178 -0
- package/src/plugins/builtin/colors.ts +201 -0
- package/src/plugins/builtin/cron.ts +649 -0
- package/src/plugins/builtin/crypto.ts +85 -0
- package/src/plugins/builtin/database.ts +235 -0
- package/src/plugins/builtin/docker.ts +426 -0
- package/src/plugins/builtin/fun.ts +118 -0
- package/src/plugins/builtin/gcal.ts +305 -0
- package/src/plugins/builtin/gdrive.ts +326 -0
- package/src/plugins/builtin/github-actions.ts +666 -0
- package/src/plugins/builtin/github.ts +912 -0
- package/src/plugins/builtin/gmail.ts +492 -0
- package/src/plugins/builtin/hash.ts +98 -0
- package/src/plugins/builtin/homekit.ts +389 -0
- package/src/plugins/builtin/index.ts +116 -0
- package/src/plugins/builtin/jira.ts +380 -0
- package/src/plugins/builtin/linear.ts +448 -0
- package/src/plugins/builtin/lumen.ts +497 -0
- package/src/plugins/builtin/memory.ts +200 -0
- package/src/plugins/builtin/n8n.ts +565 -0
- package/src/plugins/builtin/network.ts +92 -0
- package/src/plugins/builtin/notes.ts +689 -0
- package/src/plugins/builtin/notion.ts +348 -0
- package/src/plugins/builtin/shell.ts +334 -0
- package/src/plugins/builtin/slack.ts +327 -0
- package/src/plugins/builtin/spotify.ts +665 -0
- package/src/plugins/builtin/stripe.ts +388 -0
- package/src/plugins/builtin/system.ts +93 -0
- package/src/plugins/builtin/text-tools.ts +150 -0
- package/src/plugins/builtin/timezone.ts +173 -0
- package/src/plugins/builtin/todoist.ts +625 -0
- package/src/plugins/builtin/translate.ts +47 -0
- package/src/plugins/builtin/url-tools.ts +73 -0
- package/src/plugins/builtin/vercel.ts +546 -0
- package/src/plugins/builtin/weather.ts +112 -0
- package/src/plugins/builtin/x.ts +440 -0
- package/src/plugins/manager.ts +213 -0
- package/src/plugins/validation.ts +94 -0
- package/src/security/README.md +12 -0
- package/src/security/auth.ts +72 -0
- package/src/security/keychain.ts +226 -0
- package/src/utils/README.md +12 -0
- package/src/utils/google-auth.ts +159 -0
- package/src/utils/retry.ts +41 -0
- package/test-all.mjs +1256 -0
- package/test.mjs +633 -0
- package/tests/README.md +19 -0
- package/tests/calculator.test.ts +54 -0
- package/tests/docker.test.ts +42 -0
- package/tests/load.test.ts +129 -0
- package/tests/mcp.test.ts +14 -0
- package/tests/shell.test.ts +42 -0
- package/tsconfig.json +21 -0
- 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
|
+
}
|