@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,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
|
+
}
|