@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,497 @@
|
|
|
1
|
+
import { Plugin, PluginTool, PluginConfigSchema } from '../manager.js';
|
|
2
|
+
import { Conductor } from '../../core/conductor.js';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
6
|
+
import { dirname } from 'path';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
|
|
11
|
+
// ── Zod schemas for executeTool args ─────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
const RunShellArgsSchema = z.object({
|
|
14
|
+
command: z.string().min(1, 'command is required'),
|
|
15
|
+
working_dir: z.string().optional(),
|
|
16
|
+
timeout: z.number().int().positive().optional(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const ReadFileArgsSchema = z.object({
|
|
20
|
+
path: z.string().min(1, 'path is required'),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const WriteFileArgsSchema = z.object({
|
|
24
|
+
path: z.string().min(1, 'path is required'),
|
|
25
|
+
content: z.string(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ── Ollama API response types ─────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
interface OllamaToolCallFunction {
|
|
31
|
+
name: string;
|
|
32
|
+
arguments: string | Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface OllamaToolCall {
|
|
36
|
+
function: OllamaToolCallFunction;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface OllamaMessage {
|
|
40
|
+
role: string;
|
|
41
|
+
content: string | null;
|
|
42
|
+
tool_calls?: OllamaToolCall[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface OllamaResponse {
|
|
46
|
+
message: OllamaMessage;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const LUMEN_TOOLS = [
|
|
50
|
+
{
|
|
51
|
+
type: 'function',
|
|
52
|
+
function: {
|
|
53
|
+
name: 'run_shell',
|
|
54
|
+
description: 'Run a shell command and return stdout/stderr.',
|
|
55
|
+
parameters: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {
|
|
58
|
+
command: { type: 'string' },
|
|
59
|
+
working_dir: { type: 'string' },
|
|
60
|
+
timeout: { type: 'integer' },
|
|
61
|
+
},
|
|
62
|
+
required: ['command'],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: 'function',
|
|
68
|
+
function: {
|
|
69
|
+
name: 'read_file',
|
|
70
|
+
description: 'Read the contents of a file.',
|
|
71
|
+
parameters: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
properties: { path: { type: 'string' } },
|
|
74
|
+
required: ['path'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'function',
|
|
80
|
+
function: {
|
|
81
|
+
name: 'write_file',
|
|
82
|
+
description: 'Write content to a file, creating directories as needed.',
|
|
83
|
+
parameters: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
path: { type: 'string' },
|
|
87
|
+
content: { type: 'string' },
|
|
88
|
+
},
|
|
89
|
+
required: ['path', 'content'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
const LUMEN_SYSTEM = `You are Lumen, an agentic AI coding assistant built by Alexander (TheAlxLabs). You run inside Conductor. You have access to tools: run_shell, read_file, write_file. Think step-by-step. Always use tools to verify your work. Be concise in explanations but thorough in execution.`;
|
|
96
|
+
|
|
97
|
+
async function executeTool(name: string, args: unknown): Promise<string> {
|
|
98
|
+
if (name === 'run_shell') {
|
|
99
|
+
const parsed = RunShellArgsSchema.safeParse(args);
|
|
100
|
+
if (!parsed.success) {
|
|
101
|
+
return JSON.stringify({
|
|
102
|
+
error: `Invalid run_shell args: ${parsed.error.issues.map((i) => i.message).join(', ')}`,
|
|
103
|
+
returncode: 1,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const { command, working_dir, timeout } = parsed.data;
|
|
107
|
+
try {
|
|
108
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
109
|
+
cwd: working_dir || process.cwd(),
|
|
110
|
+
timeout: (timeout ?? 30) * 1000,
|
|
111
|
+
});
|
|
112
|
+
return JSON.stringify({ stdout, stderr, returncode: 0 });
|
|
113
|
+
} catch (e: unknown) {
|
|
114
|
+
const err = e as { stdout?: string; stderr?: string; message?: string; code?: number };
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
stdout: err.stdout || '',
|
|
117
|
+
stderr: err.stderr || err.message,
|
|
118
|
+
returncode: err.code || 1,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (name === 'read_file') {
|
|
124
|
+
const parsed = ReadFileArgsSchema.safeParse(args);
|
|
125
|
+
if (!parsed.success) {
|
|
126
|
+
return JSON.stringify({
|
|
127
|
+
error: `Invalid read_file args: ${parsed.error.issues.map((i) => i.message).join(', ')}`,
|
|
128
|
+
success: false,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const content = await readFile(parsed.data.path, 'utf8');
|
|
133
|
+
return JSON.stringify({ content, success: true });
|
|
134
|
+
} catch (e: unknown) {
|
|
135
|
+
return JSON.stringify({ error: (e as Error).message, success: false });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (name === 'write_file') {
|
|
140
|
+
const parsed = WriteFileArgsSchema.safeParse(args);
|
|
141
|
+
if (!parsed.success) {
|
|
142
|
+
return JSON.stringify({
|
|
143
|
+
error: `Invalid write_file args: ${parsed.error.issues.map((i) => i.message).join(', ')}`,
|
|
144
|
+
success: false,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const { path, content } = parsed.data;
|
|
148
|
+
try {
|
|
149
|
+
await mkdir(dirname(path), { recursive: true });
|
|
150
|
+
await writeFile(path, content, 'utf8');
|
|
151
|
+
return JSON.stringify({ success: true, path });
|
|
152
|
+
} catch (e: unknown) {
|
|
153
|
+
return JSON.stringify({ error: (e as Error).message, success: false });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function runLumenAgent(
|
|
161
|
+
task: string,
|
|
162
|
+
endpoint: string,
|
|
163
|
+
model: string,
|
|
164
|
+
maxIterations = 10,
|
|
165
|
+
): Promise<{ result: string; iterations: number; toolCalls: string[] }> {
|
|
166
|
+
const messages: OllamaMessage[] = [
|
|
167
|
+
{ role: 'system', content: LUMEN_SYSTEM },
|
|
168
|
+
{ role: 'user', content: task },
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const toolCallLog: string[] = [];
|
|
172
|
+
let iterations = 0;
|
|
173
|
+
|
|
174
|
+
while (iterations < maxIterations) {
|
|
175
|
+
iterations++;
|
|
176
|
+
|
|
177
|
+
const response = await fetch(`${endpoint}/api/chat`, {
|
|
178
|
+
method: 'POST',
|
|
179
|
+
headers: { 'Content-Type': 'application/json' },
|
|
180
|
+
body: JSON.stringify({
|
|
181
|
+
model,
|
|
182
|
+
messages,
|
|
183
|
+
tools: LUMEN_TOOLS,
|
|
184
|
+
stream: false,
|
|
185
|
+
}),
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
throw new Error(`Lumen API error: ${response.status} ${response.statusText}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const data = (await response.json()) as OllamaResponse;
|
|
193
|
+
const message = data.message;
|
|
194
|
+
messages.push(message);
|
|
195
|
+
|
|
196
|
+
// No tool calls — Lumen is done
|
|
197
|
+
if (!message.tool_calls || message.tool_calls.length === 0) {
|
|
198
|
+
return {
|
|
199
|
+
result: message.content || '(no response)',
|
|
200
|
+
iterations,
|
|
201
|
+
toolCalls: toolCallLog,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Execute each tool call
|
|
206
|
+
for (const toolCall of message.tool_calls) {
|
|
207
|
+
const name = toolCall.function.name;
|
|
208
|
+
const args =
|
|
209
|
+
typeof toolCall.function.arguments === 'string'
|
|
210
|
+
? JSON.parse(toolCall.function.arguments)
|
|
211
|
+
: toolCall.function.arguments;
|
|
212
|
+
|
|
213
|
+
const logEntry = `${name}(${JSON.stringify(args)})`;
|
|
214
|
+
toolCallLog.push(logEntry);
|
|
215
|
+
process.stderr.write(`[Lumen] → ${logEntry}\n`);
|
|
216
|
+
|
|
217
|
+
const result = await executeTool(name, args);
|
|
218
|
+
process.stderr.write(`[Lumen] ← ${result.slice(0, 150)}\n`);
|
|
219
|
+
|
|
220
|
+
messages.push({ role: 'tool', content: result });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
result: 'Max iterations reached without a final answer.',
|
|
226
|
+
iterations,
|
|
227
|
+
toolCalls: toolCallLog,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export class LumenPlugin implements Plugin {
|
|
232
|
+
name = 'lumen';
|
|
233
|
+
description =
|
|
234
|
+
'Lumen — agentic AI coding assistant by TheAlxLabs. Writes code, runs shell commands, uses git/GitHub autonomously.';
|
|
235
|
+
version = '1.0.0';
|
|
236
|
+
|
|
237
|
+
private endpoint = 'http://localhost:11434';
|
|
238
|
+
private model = 'lumen';
|
|
239
|
+
|
|
240
|
+
configSchema: PluginConfigSchema = {
|
|
241
|
+
fields: [
|
|
242
|
+
{
|
|
243
|
+
key: 'endpoint',
|
|
244
|
+
label: 'Ollama Endpoint',
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: 'URL where Ollama is running (default: http://localhost:11434)',
|
|
247
|
+
required: false,
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
key: 'model',
|
|
251
|
+
label: 'Model Name',
|
|
252
|
+
type: 'string',
|
|
253
|
+
description: 'Ollama model name to use (default: lumen)',
|
|
254
|
+
required: false,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
setupInstructions: `
|
|
258
|
+
Lumen Setup:
|
|
259
|
+
1. Install Ollama: brew install ollama
|
|
260
|
+
2. Pull Lumen: ollama pull thealxlabs/lumen
|
|
261
|
+
OR import from GGUF: ollama create lumen -f Lumen.Modelfile
|
|
262
|
+
3. Start Ollama: ollama serve
|
|
263
|
+
4. Enable this plugin: conductor plugin enable lumen
|
|
264
|
+
`,
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
async initialize(conductor: Conductor): Promise<void> {
|
|
268
|
+
const config = conductor.getConfig();
|
|
269
|
+
this.endpoint = config.get<string>('plugins.lumen.endpoint') || 'http://localhost:11434';
|
|
270
|
+
this.model = config.get<string>('plugins.lumen.model') || 'lumen';
|
|
271
|
+
|
|
272
|
+
// Verify Ollama is reachable
|
|
273
|
+
const ok = await this.ping();
|
|
274
|
+
if (!ok) {
|
|
275
|
+
throw new Error(`Lumen: Cannot reach Ollama at ${this.endpoint}. Run: ollama serve`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Check if the model exists
|
|
279
|
+
const models = await this.listModels();
|
|
280
|
+
if (!models.some((m) => m.includes(this.model))) {
|
|
281
|
+
throw new Error(`Lumen: Model "${this.model}" not found in Ollama. Run: ollama pull thealxlabs/lumen`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
isConfigured(): boolean {
|
|
286
|
+
return true; // Config is optional — uses defaults
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private async ping(): Promise<boolean> {
|
|
290
|
+
try {
|
|
291
|
+
const res = await fetch(`${this.endpoint}/api/tags`);
|
|
292
|
+
return res.ok;
|
|
293
|
+
} catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private async listModels(): Promise<string[]> {
|
|
299
|
+
try {
|
|
300
|
+
const res = await fetch(`${this.endpoint}/api/tags`);
|
|
301
|
+
const data = (await res.json()) as { models?: { name: string }[] };
|
|
302
|
+
return data.models?.map((m) => m.name) ?? [];
|
|
303
|
+
} catch {
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getTools(): PluginTool[] {
|
|
309
|
+
return [
|
|
310
|
+
// ── Main agent tool ───────────────────────────────────────────────
|
|
311
|
+
{
|
|
312
|
+
name: 'lumen_ask',
|
|
313
|
+
description:
|
|
314
|
+
'Ask Lumen to complete a coding task autonomously. Lumen can write code, run shell commands, use git, fix bugs, and more.',
|
|
315
|
+
inputSchema: {
|
|
316
|
+
type: 'object',
|
|
317
|
+
properties: {
|
|
318
|
+
task: {
|
|
319
|
+
type: 'string',
|
|
320
|
+
description: 'The task for Lumen to complete, e.g. "commit all changes with message fix: auth"',
|
|
321
|
+
},
|
|
322
|
+
max_iterations: {
|
|
323
|
+
type: 'number',
|
|
324
|
+
description: 'Max agentic loop iterations (default: 10)',
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
required: ['task'],
|
|
328
|
+
},
|
|
329
|
+
requiresApproval: true,
|
|
330
|
+
handler: async (input: { task: string; max_iterations?: number }) => {
|
|
331
|
+
const { result, iterations, toolCalls } = await runLumenAgent(
|
|
332
|
+
input.task,
|
|
333
|
+
this.endpoint,
|
|
334
|
+
this.model,
|
|
335
|
+
input.max_iterations || 10,
|
|
336
|
+
);
|
|
337
|
+
return { result, iterations, toolCalls };
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
// ── Git shortcuts ─────────────────────────────────────────────────
|
|
342
|
+
{
|
|
343
|
+
name: 'lumen_git_commit',
|
|
344
|
+
description: 'Stage all changes and commit with a message using Lumen.',
|
|
345
|
+
inputSchema: {
|
|
346
|
+
type: 'object',
|
|
347
|
+
properties: {
|
|
348
|
+
message: { type: 'string', description: 'Commit message' },
|
|
349
|
+
working_dir: { type: 'string', description: 'Repo directory (default: cwd)' },
|
|
350
|
+
},
|
|
351
|
+
required: ['message'],
|
|
352
|
+
},
|
|
353
|
+
handler: async (input: { message: string; working_dir?: string }) => {
|
|
354
|
+
const cwd = input.working_dir || process.cwd();
|
|
355
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
356
|
+
`Stage all changes and commit with message: "${input.message}". Working directory: ${cwd}`,
|
|
357
|
+
this.endpoint,
|
|
358
|
+
this.model,
|
|
359
|
+
);
|
|
360
|
+
return { result, toolCalls };
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
{
|
|
365
|
+
name: 'lumen_git_push',
|
|
366
|
+
description: 'Push current branch to origin using Lumen.',
|
|
367
|
+
inputSchema: {
|
|
368
|
+
type: 'object',
|
|
369
|
+
properties: {
|
|
370
|
+
working_dir: { type: 'string', description: 'Repo directory (default: cwd)' },
|
|
371
|
+
},
|
|
372
|
+
required: [],
|
|
373
|
+
},
|
|
374
|
+
handler: async (input: { working_dir?: string }) => {
|
|
375
|
+
const cwd = input.working_dir || process.cwd();
|
|
376
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
377
|
+
`Push the current branch to origin. Working directory: ${cwd}`,
|
|
378
|
+
this.endpoint,
|
|
379
|
+
this.model,
|
|
380
|
+
);
|
|
381
|
+
return { result, toolCalls };
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
|
|
385
|
+
{
|
|
386
|
+
name: 'lumen_git_status',
|
|
387
|
+
description: 'Get git status of a repository using Lumen.',
|
|
388
|
+
inputSchema: {
|
|
389
|
+
type: 'object',
|
|
390
|
+
properties: {
|
|
391
|
+
working_dir: { type: 'string', description: 'Repo directory (default: cwd)' },
|
|
392
|
+
},
|
|
393
|
+
required: [],
|
|
394
|
+
},
|
|
395
|
+
handler: async (input: { working_dir?: string }) => {
|
|
396
|
+
const cwd = input.working_dir || process.cwd();
|
|
397
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
398
|
+
`Show git status and a brief summary of changes. Working directory: ${cwd}`,
|
|
399
|
+
this.endpoint,
|
|
400
|
+
this.model,
|
|
401
|
+
);
|
|
402
|
+
return { result, toolCalls };
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
// ── Code tools ────────────────────────────────────────────────────
|
|
407
|
+
{
|
|
408
|
+
name: 'lumen_fix_bug',
|
|
409
|
+
description: 'Ask Lumen to investigate and fix a bug in your codebase.',
|
|
410
|
+
inputSchema: {
|
|
411
|
+
type: 'object',
|
|
412
|
+
properties: {
|
|
413
|
+
description: { type: 'string', description: 'Bug description or error message' },
|
|
414
|
+
working_dir: { type: 'string', description: 'Project directory (default: cwd)' },
|
|
415
|
+
},
|
|
416
|
+
required: ['description'],
|
|
417
|
+
},
|
|
418
|
+
requiresApproval: true,
|
|
419
|
+
handler: async (input: { description: string; working_dir?: string }) => {
|
|
420
|
+
const cwd = input.working_dir || process.cwd();
|
|
421
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
422
|
+
`Investigate and fix this bug: ${input.description}\nWorking directory: ${cwd}`,
|
|
423
|
+
this.endpoint,
|
|
424
|
+
this.model,
|
|
425
|
+
);
|
|
426
|
+
return { result, toolCalls };
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
{
|
|
431
|
+
name: 'lumen_write_file',
|
|
432
|
+
description: 'Ask Lumen to write or generate a file with given requirements.',
|
|
433
|
+
inputSchema: {
|
|
434
|
+
type: 'object',
|
|
435
|
+
properties: {
|
|
436
|
+
path: { type: 'string', description: 'File path to create/overwrite' },
|
|
437
|
+
requirements: { type: 'string', description: 'What the file should contain or do' },
|
|
438
|
+
},
|
|
439
|
+
required: ['path', 'requirements'],
|
|
440
|
+
},
|
|
441
|
+
requiresApproval: true,
|
|
442
|
+
handler: async (input: { path: string; requirements: string }) => {
|
|
443
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
444
|
+
`Write a file at "${input.path}" with these requirements: ${input.requirements}`,
|
|
445
|
+
this.endpoint,
|
|
446
|
+
this.model,
|
|
447
|
+
);
|
|
448
|
+
return { result, toolCalls };
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
// ── Shell tool ────────────────────────────────────────────────────
|
|
453
|
+
{
|
|
454
|
+
name: 'lumen_shell',
|
|
455
|
+
description: 'Ask Lumen to run a shell task and interpret the results.',
|
|
456
|
+
inputSchema: {
|
|
457
|
+
type: 'object',
|
|
458
|
+
properties: {
|
|
459
|
+
task: { type: 'string', description: 'What you want done in the terminal' },
|
|
460
|
+
working_dir: { type: 'string', description: 'Working directory (default: cwd)' },
|
|
461
|
+
},
|
|
462
|
+
required: ['task'],
|
|
463
|
+
},
|
|
464
|
+
requiresApproval: true,
|
|
465
|
+
handler: async (input: { task: string; working_dir?: string }) => {
|
|
466
|
+
const cwd = input.working_dir || process.cwd();
|
|
467
|
+
const { result, toolCalls } = await runLumenAgent(
|
|
468
|
+
`${input.task}\nWorking directory: ${cwd}`,
|
|
469
|
+
this.endpoint,
|
|
470
|
+
this.model,
|
|
471
|
+
);
|
|
472
|
+
return { result, toolCalls };
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
|
|
476
|
+
// ── Status / ping ─────────────────────────────────────────────────
|
|
477
|
+
{
|
|
478
|
+
name: 'lumen_ping',
|
|
479
|
+
description: 'Check if Lumen is running and available.',
|
|
480
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
481
|
+
handler: async () => {
|
|
482
|
+
const ok = await this.ping();
|
|
483
|
+
if (!ok) return { status: 'offline', endpoint: this.endpoint };
|
|
484
|
+
const models = await this.listModels();
|
|
485
|
+
const hasLumen = models.some((m) => m.includes(this.model));
|
|
486
|
+
return {
|
|
487
|
+
status: hasLumen ? 'ready' : 'ollama_running_but_model_missing',
|
|
488
|
+
model: this.model,
|
|
489
|
+
endpoint: this.endpoint,
|
|
490
|
+
available_models: models,
|
|
491
|
+
hint: hasLumen ? null : `Run: ollama pull thealxlabs/lumen`,
|
|
492
|
+
};
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
];
|
|
496
|
+
}
|
|
497
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Plugin
|
|
3
|
+
*
|
|
4
|
+
* Lightning-fast, leak-proof long-term memory using native SQLite.
|
|
5
|
+
* Uses simple text search (LIKE) to completely avoid RAM bloating and context leaks.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import crypto from 'crypto';
|
|
9
|
+
import { Plugin, PluginTool } from '../manager.js';
|
|
10
|
+
import { Conductor } from '../../core/conductor.js';
|
|
11
|
+
|
|
12
|
+
export type MemoryCategory = 'preference' | 'fact' | 'decision' | 'entity' | 'other';
|
|
13
|
+
|
|
14
|
+
const _DEFAULT_CAPTURE_MAX_CHARS = 500;
|
|
15
|
+
|
|
16
|
+
function detectCategory(text: string): MemoryCategory {
|
|
17
|
+
const t = text.toLowerCase();
|
|
18
|
+
if (/prefer|like|love|hate|want/i.test(t)) return 'preference';
|
|
19
|
+
if (/decided|will use|budeme/i.test(t)) return 'decision';
|
|
20
|
+
if (/\+\d{10,}|@[\w.-]+\.\w+|is called|jmenuje se/i.test(t)) return 'entity';
|
|
21
|
+
if (/\b(is|are|has|have|je|má|jsou)\b/i.test(t)) return 'fact';
|
|
22
|
+
return 'other';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function looksLikePromptInjection(text: string): boolean {
|
|
26
|
+
const normalized = text.replace(/\s+/g, ' ').trim();
|
|
27
|
+
const patterns = [
|
|
28
|
+
/ignore (all|any|previous|above|prior) instructions/i,
|
|
29
|
+
/do not follow (the )?(system|developer)/i,
|
|
30
|
+
/system prompt/i,
|
|
31
|
+
];
|
|
32
|
+
return patterns.some((p) => p.test(normalized));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class MemoryPlugin implements Plugin {
|
|
36
|
+
name = 'memory';
|
|
37
|
+
description = 'Long-term memory — store and recall important facts across conversations';
|
|
38
|
+
version = '2.0.0';
|
|
39
|
+
|
|
40
|
+
private conductor!: Conductor;
|
|
41
|
+
private currentUserId: string = 'global';
|
|
42
|
+
|
|
43
|
+
async initialize(conductor: Conductor): Promise<void> {
|
|
44
|
+
this.conductor = conductor;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Called by AIManager at the start of each conversation to scope queries correctly. */
|
|
48
|
+
setUserId(userId: string): void {
|
|
49
|
+
this.currentUserId = userId || 'global';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
isConfigured(): boolean {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getTools(): PluginTool[] {
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
name: 'memory_recall',
|
|
60
|
+
description: 'Search long-term memory for relevant facts, preferences, or decisions.',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
query: { type: 'string', description: 'What to search for' },
|
|
65
|
+
limit: { type: 'number', description: 'Max results (default: 5)' },
|
|
66
|
+
category: { type: 'string', description: 'Optional category filter' },
|
|
67
|
+
},
|
|
68
|
+
required: ['query'],
|
|
69
|
+
},
|
|
70
|
+
handler: async ({ query, limit = 5, category }: any) => {
|
|
71
|
+
const db = this.conductor.getDatabase();
|
|
72
|
+
const results = await db.searchCoreMemory('global', query, limit, category);
|
|
73
|
+
|
|
74
|
+
if (results.length === 0) return { found: 0, memories: [] };
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
found: results.length,
|
|
78
|
+
memories: results.map((r) => ({
|
|
79
|
+
id: r.id,
|
|
80
|
+
text: r.text,
|
|
81
|
+
category: r.category,
|
|
82
|
+
importance: r.importance,
|
|
83
|
+
createdAt: r.timestamp,
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'memory_store',
|
|
90
|
+
description: 'Save important information to long-term memory.',
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
text: { type: 'string', description: 'Information to remember' },
|
|
95
|
+
importance: { type: 'number', description: 'Importance score 0–1 (default: 0.7)' },
|
|
96
|
+
category: { type: 'string', description: 'Category (auto-detected if omitted)' },
|
|
97
|
+
tags: { type: 'array', items: { type: 'string' } },
|
|
98
|
+
},
|
|
99
|
+
required: ['text'],
|
|
100
|
+
},
|
|
101
|
+
handler: async ({ text, importance = 0.7, category, tags }: any) => {
|
|
102
|
+
if (looksLikePromptInjection(text)) {
|
|
103
|
+
return { error: 'Rejected: text looks like a prompt injection attempt.' };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const detectedCategory: MemoryCategory = category ?? detectCategory(text);
|
|
107
|
+
const db = this.conductor.getDatabase();
|
|
108
|
+
|
|
109
|
+
const entry = {
|
|
110
|
+
id: crypto.randomUUID(),
|
|
111
|
+
userId: 'global',
|
|
112
|
+
text,
|
|
113
|
+
category: detectedCategory,
|
|
114
|
+
importance: Math.max(0, Math.min(1, importance)),
|
|
115
|
+
tags,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
await db.addCoreMemory(entry);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
action: 'stored',
|
|
122
|
+
id: entry.id,
|
|
123
|
+
category: detectedCategory,
|
|
124
|
+
text: text.slice(0, 100),
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'memory_forget',
|
|
130
|
+
description: 'Delete a memory by ID.',
|
|
131
|
+
inputSchema: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
memoryId: { type: 'string', description: 'Exact memory UUID to delete' },
|
|
135
|
+
},
|
|
136
|
+
required: ['memoryId'],
|
|
137
|
+
},
|
|
138
|
+
handler: async ({ memoryId }: any) => {
|
|
139
|
+
const db = this.conductor.getDatabase();
|
|
140
|
+
await db.deleteCoreMemory(memoryId);
|
|
141
|
+
return { action: 'deleted', id: memoryId };
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: 'memory_list',
|
|
146
|
+
description: 'List all stored memories.',
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
category: { type: 'string', description: 'Filter by category' },
|
|
151
|
+
limit: { type: 'number', description: 'Max entries (default: 20)' },
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
handler: async ({ category, limit = 20 }: any) => {
|
|
155
|
+
const db = this.conductor.getDatabase();
|
|
156
|
+
const all = await db.listCoreMemory('global', category, limit);
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
total: all.length,
|
|
160
|
+
memories: all.map((e) => ({
|
|
161
|
+
id: e.id,
|
|
162
|
+
text: e.text.slice(0, 120),
|
|
163
|
+
category: e.category,
|
|
164
|
+
importance: e.importance,
|
|
165
|
+
createdAt: e.timestamp,
|
|
166
|
+
})),
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'search_past_conversations',
|
|
172
|
+
description: 'Search raw past chat logs and conversations without bloating the context window.',
|
|
173
|
+
inputSchema: {
|
|
174
|
+
type: 'object',
|
|
175
|
+
properties: {
|
|
176
|
+
query: { type: 'string', description: 'What text to search for' },
|
|
177
|
+
limit: { type: 'number', description: 'Max messages to return (default: 10)' },
|
|
178
|
+
},
|
|
179
|
+
required: ['query'],
|
|
180
|
+
},
|
|
181
|
+
handler: async ({ query, limit = 10 }: any) => {
|
|
182
|
+
const db = this.conductor.getDatabase();
|
|
183
|
+
// Use the stored userId set by setUserId(). Falls back to 'global' if not set.
|
|
184
|
+
const results = await db.searchMessages(this.currentUserId, query, limit);
|
|
185
|
+
|
|
186
|
+
if (results.length === 0) return { found: 0, messages: [] };
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
found: results.length,
|
|
190
|
+
messages: results.map((r) => ({
|
|
191
|
+
role: r.role,
|
|
192
|
+
content: r.content ? r.content.slice(0, 200) : '',
|
|
193
|
+
timestamp: r.timestamp,
|
|
194
|
+
})),
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
}
|