Conversation
Split the agent->Discord CLI into `send`, `notify`, and `status` verbs so the surface can grow beyond the original single-purpose flag form. Verbs use Node's built-in parseArgs and live in src/cli/verbs/, with shared HTTP and exec helpers in src/cli/lib.ts. All three currently ride the existing /api/send endpoint; no server changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surface previously-unused maestro-cli capabilities as Discord slash commands: - /playbook list|show|run — list playbooks, show details, run with completion summary posted to the channel (service layer was already wired) - /agents show <id> — embed of agent stats and recent activity - /gist [description] [public] — publish the channel's agent transcript as a GitHub gist; returns the URL in-channel - /notes synopsis|history — Director's Notes (AI synopsis with 2 min LLM timeout, or unified history feed across agents) - /auto-run start <doc> — launch an Auto Run for the channel's agent; bare filenames are resolved against the agent's autoRunFolderPath and autocomplete reads .md files from that directory Adds five service methods (showAgent, createGist, directorSynopsis, directorHistory, startAutoRun) and supporting types. Introduces a CommandModule type in index.ts so the command registry Map type-unifies across builders with different shapes (subcommand-only vs options-only). Updates the README slash-command table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nts show Discord rejects embed payloads with description > 4096 chars or field value > 1024 chars. Long playbook descriptions, long document path lists, long cwds, and accumulated recent-activity text could all trip these limits and fail editReply with a validation error. Adds src/utils/embed.ts with clampDescription and clampFieldValue helpers (append a "\n…" marker when truncating) and applies them to: - /playbook show — description and Documents field - /agents show — Cwd, Stats, and Recent activity fields Also adds focused tests: - embed.test.ts — clamp limits and edge cases - playbook-command.test.ts — list/show happy paths, oversize-input clamp, load-failure error path - agents-command.test.ts — show happy path, oversize-cwd clamp, load-failure error path Test count: 110 -> 122 (all green). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- cli/lib: add 5s timeout + single-settle guard to postToSendApi; new
parsePort() helper that strictly validates --port (digits only, 1-65535)
- cli/verbs/{send,notify,status}: use parsePort()
- cli/verbs/status: split runMaestroCli execution from JSON.parse so each
surfaces a distinct error
- utils/embed: add EMBED_TITLE_MAX (256) + clampTitle()
- commands/agents: clamp title and groupName in handleShow; bound channel
name to Discord's 100-char limit; replace `as TextChannel` cast with
isSendable() guard + friendly error reply
- commands/auto-run: fetch autoRunFolderPath via showAgent (listAgents
doesn't return it); resolve any non-absolute doc path against the agent
folder, not only bare filenames
- commands/gist: normalize non-Error rejection values before slicing
- commands/playbook: clamp title and agent name in handleShow
Tests:
- new cli-lib.test.ts: parsePort validation + postToSendApi timeout,
ECONNREFUSED, invalid-JSON, and double-settle protection
- new auto-run-command.test.ts: bare filename, subdir path regression,
absolute passthrough, showAgent failure, missing folder
- new gist-command.test.ts: success, Error throw, string throw, object
throw, long-message truncation
- extend agents/playbook/embed tests with clamp + bound regressions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- agents: drop the unsafe `as TextChannel` cast (and import) since isSendable() already narrows the channel type - tests/auto-run: add callCount guards before reading mock.calls[0] in absolute-path / showAgent-fail / missing-folder tests so a regression produces a clean assertion failure rather than a TypeError - tests/cli-lib: drop the port-1 ECONNREFUSED trick (unreliable on Windows). Bind a server to a random free port, close it immediately, then connect — the OS keeps the port reserved long enough to refuse predictably across platforms - tests/gist: tighten truncation test with a lower-bound assertion and prefix check so over-truncation regressions don't slip through Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d adapter Restructure the codebase into src/core/ (provider-agnostic kernel) and src/providers/discord/ (adapter implementing a new BridgeProvider interface). All Discord-specific code now lives behind the adapter; the kernel speaks only in IncomingMessage / ConversationRecord / ChannelTarget types. A new provider can be added by dropping src/providers/<name>/ without touching the kernel. Behavior preserved end-to-end: - All 7 slash commands, voice transcription, and HTTP /api/send work identically from the user's perspective. - All env vars unchanged (DISCORD_*, API_PORT, WHISPER_*); new optional ENABLED_PROVIDERS defaults to 'discord'. - /api/send accepts an optional `provider` field (defaults to 'discord'). - DB schema upgrades automatically on first start: agent_channels gets a `provider` column and composite PK (provider, channel_id); agent_threads is renamed to discord_agent_threads with rows preserved. - CLI binary maestro-discord unchanged. Tests: 158/158 pass (151 baseline + 7 new). Includes a MockProvider smoke test exercising the BridgeProvider interface end-to-end without any Discord code, and a legacy-schema-upgrade migration test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the project to reflect the new architecture: a provider-agnostic bridge between chat platforms and Maestro agents, with Discord as the first provider. Local changes only — does NOT rename the GitHub repo or migrate the installer in RunMaestro/Maestro-Discord; both require manual follow-up. Renames: - package name: discord-maestro -> maestro-bridge - bin: maestro-bridge (primary), maestro-discord kept as alias pointing at the same dist/cli/maestro-bridge.js - src/cli/maestro-discord.ts -> src/cli/maestro-bridge.ts - npm script: maestro-bridge (alias maestro-discord retained) User-facing strings in CLI help, README, AGENTS.md, docs/api.md, and docs/architecture.md updated to "Maestro Bridge". All DISCORD_* env vars unchanged. .env.example reorganised into Core / Discord sections with ENABLED_PROVIDERS=discord (default) added. Migration: existing scripts calling `maestro-discord ...` keep working unchanged via the alias bin. Tests, typecheck, and lint all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Imports the installer plumbing that lives on main (install.sh, maestro-discord-ctl, systemd/launchd templates) into this branch and renames it for Maestro Bridge. This branch is stacked on feat/rename-to-bridge, so it includes the provider-agnostic kernel + the package rename + the installer rename together. Land the upstream branches first. Renames: - bin/maestro-discord-ctl.sh -> bin/maestro-bridge-ctl.sh - templates/maestro-discord.service -> templates/maestro-bridge.service - templates/sh.maestro.discord.plist -> templates/sh.maestro.bridge.plist - install dir default: ~/.local/share/maestro-bridge - config dir default: ~/.config/maestro-bridge - systemd unit: maestro-bridge.service - launchd label: sh.maestro.bridge - repo default: RunMaestro/Maestro-Bridge Backwards compatibility: - MAESTRO_DISCORD_* env vars accepted as fallback for every MAESTRO_BRIDGE_* var (so v0.0.x `maestro-discord-ctl update` works). - Legacy ~/.local/share/maestro-discord and ~/.config/maestro-discord are auto-detected when the new dirs do not exist. - install_ctl creates BOTH `maestro-bridge-ctl` and `maestro-discord-ctl` symlinks pointing at the same wrapper. - install.sh removes a legacy maestro-discord systemd unit / launchd plist on upgrade so two services do not run side by side. - uninstall cleans up both legacy and new service files + symlinks. Bot path fixes: - ctl deploy now runs `dist/providers/discord/deploy.js` (the post- refactor location) instead of the old `dist/deploy-commands.js`. Note: a matching change to .github/workflows/release.yml (tarball staging name maestro-discord-<tag> -> maestro-bridge-<tag>) is required but excluded from this commit because the bot OAuth token lacks workflow scope. Apply the diff in a follow-up commit pushed with a PAT that has 'workflow' scope (the file is left unstaged in the working tree for that purpose). Manual follow-ups (not in this PR): - Rename the GitHub repo RunMaestro/Maestro-Discord to RunMaestro/Maestro-Bridge (auto-redirects existing curl URLs). - Push the .github/workflows/release.yml change with workflow scope. - Cut a v0.0.5+ release once the rename PRs merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… adapter (#27) Conflict resolution favoured the incoming refactor's structure (-X theirs). Two rc-only improvements were ported back manually after the merge to preserve them on top of the new architecture: 1. Multilingual whisper transcription (rc commit 4460cdc): - Added `whisperLanguage` to src/core/config.ts (auto-merged) - Added `-l <language>` flag to whisper-cli invocation in src/core/transcription.ts (auto-merged) 2. Auto Run path-containment security fix (rc commit a9cc725): - Re-introduced `resolveContainedDocPath()` in src/providers/discord/commands/auto-run.ts to reject absolute paths outside the agent's Auto Run folder and `..` traversal escapes. - Replaced `src/__tests__/auto-run-command.test.ts` with rc's full 18-test version (security + autocomplete recursion tests) and rewrote the imports to point at the post-refactor module paths. Tests: 169/169 pass (previously 158 on the feature branch alone; +11 are the rc-only auto-run security and autocomplete-recursion tests now preserved on top of the refactor). Typecheck: clean.
…31) * chore(rename): transition bridge naming to maestro-relay with compat aliases * feat(installer,cli): add module switch scaffold and complete relay rename
install.sh downloads maestro-relay-${tag}.tar.gz but the workflow was
still building maestro-discord-${tag}.tar.gz, so a fresh tag would 404
on download. Aligns the release artifact with the installer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (71)
📝 WalkthroughWalkthroughThis PR refactors Maestro-Discord into Maestro-Relay, a provider-agnostic relay system. The codebase shifts from Discord-specific logic to a modular architecture: a provider-neutral kernel manages conversations and queueing, while pluggable providers (Discord adapter first) handle platform-specific behavior. Configuration, database schema, installer, CLI, and tests are reorganized to support this multi-provider design. ChangesMaestro Relay Refactor
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes
✨ Finishing Touches🧪 Generate unit tests (beta)
|
…e matching The sed extraction in deploy_commands (install.sh) and cmd_deploy (maestro-relay-ctl) captured everything that wasn't whitespace or '#', so a quoted value like ENABLED_PROVIDERS="discord" became "discord" (quotes included). The subsequent case ",$ep," in *,discord,*) check then failed against ,"discord", and the installer/ctl falsely reported Discord as not enabled, skipping slash-command deployment. Strip a single layer of leading/trailing single or double quotes after extraction. Reported by Codex review of PR #32. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR completes a major re-architecture and rebrand: it extracts a provider-agnostic bridge “kernel” under src/core/ (no discord.js imports) and moves Discord-specific behavior into a BridgeProvider implementation, while renaming the project from discord-maestro to maestro-relay end-to-end (CLI, installers, service templates, docs) with back-compat aliases.
Changes:
- Introduces a provider-agnostic kernel (
core/{types,queue,api,db,maestro,transcription,...}) and a Discord adapter implementingBridgeProvider. - Rebrands binaries / installer / service units to
maestro-relaywith legacymaestro-discord/maestro-bridgealiases and migration logic. - Updates CLI to verb-based commands and expands Discord slash commands, with tests adjusted to the new architecture.
Reviewed changes
Copilot reviewed 63 out of 72 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/sh.maestro.relay.plist | Renames launchd label and log paths for the new maestro-relay service. |
| templates/maestro-relay.service | Updates systemd unit description for the renamed service. |
| src/utils/splitMessage.ts | Removed; functionality moved to provider-agnostic src/core/splitMessage.ts. |
| src/services/queueFactory.ts | Removed; queue moved/refactored into provider-agnostic src/core/queue.ts. |
| src/services/queue.ts | Removed; queue wiring moved into kernel orchestration (src/index.ts). |
| src/services/.gitkeep | Keeps empty legacy directory after moving services into src/core/. |
| src/server.ts | Removed; HTTP API moved/refactored to src/core/api.ts. |
| src/providers/discord/voice.ts | Adds Discord-specific voice message/attachment detection + attachment translation. |
| src/providers/discord/threadsDb.ts | Adds Discord-only thread registry for discord_agent_threads. |
| src/providers/discord/messageCreate.ts | Reworks message handler to emit kernel IncomingMessage and support transcription flow. |
| src/providers/discord/embed.ts | Adds Discord embed limit constants and truncation helpers. |
| src/providers/discord/deploy.ts | Updates slash-command deploy script to use discordConfig. |
| src/providers/discord/config.ts | Adds lazy-loaded Discord env config to avoid failing when Discord provider disabled. |
| src/providers/discord/commands/session.ts | Updates imports to new Discord DB wrappers + kernel maestro. |
| src/providers/discord/commands/playbook.ts | Updates imports to kernel maestro and new embed helpers. |
| src/providers/discord/commands/notes.ts | Updates imports to kernel maestro. |
| src/providers/discord/commands/health.ts | Updates imports to kernel maestro. |
| src/providers/discord/commands/gist.ts | Updates imports to Discord channel DB wrapper + kernel maestro. |
| src/providers/discord/commands/auto-run.ts | Updates imports to new DB wrapper/kernel maestro and refines comments. |
| src/providers/discord/commands/agents.ts | Updates imports to kernel maestro, new DB wrappers, and new config module. |
| src/providers/discord/channelsDb.ts | Adds Discord wrapper around provider-aware core agent_channels registry. |
| src/providers/discord/adapter.ts | Introduces DiscordProvider implementing BridgeProvider and wiring commands/events to kernel. |
| src/index.ts | New orchestrator: builds providers, starts them with kernel context, starts API, handles shutdown. |
| src/handlers/.gitkeep | Keeps legacy directory after moving handler into provider module. |
| src/db/migrations.ts | Removed; migrations moved to src/core/db/migrations.ts. |
| src/db/index.ts | Removed; DB moved to src/core/db/index.ts and provider-specific DB split out. |
| src/core/types.ts | Adds provider-agnostic kernel contract types (BridgeProvider, IncomingMessage, etc.). |
| src/core/transcription.ts | Refactors transcription pipeline to be provider-agnostic and accept IncomingAttachment. |
| src/core/splitMessage.ts | Adds provider-agnostic message splitting utility with configurable max length. |
| src/core/queue.ts | Adds provider-agnostic per-conversation queue using BridgeProvider for send/react/typing. |
| src/core/providers.ts | Adds dynamic provider loader driven by ENABLED_PROVIDERS. |
| src/core/maestro.ts | Adds kernel-level maestro-cli wrapper with caching and expanded CLI surface. |
| src/core/logger.ts | Adds simple file-backed error logger for operational logging. |
| src/core/db/migrations.ts | Adds idempotent migrations including provider-aware channel PK and Discord threads table rename. |
| src/core/db/index.ts | Adds provider-aware agent_channels table + CRUD and migration bootstrap. |
| src/core/config.ts | Splits core config from provider config; introduces ENABLED_PROVIDERS. |
| src/core/attachments.ts | Makes attachment downloads provider-agnostic (list of URLs) and adds configurable subdir. |
| src/core/api.ts | Adds provider-routed HTTP API (/api/send, /api/health) driven by enabled providers. |
| src/commands/.gitkeep | Keeps legacy directory after moving commands into provider module. |
| src/cli/verbs/status.ts | Updates usage/docs and adds --provider support for routed sends. |
| src/cli/verbs/send.ts | Updates usage/docs and adds --provider support for routed sends. |
| src/cli/verbs/notify.ts | Updates usage/docs and adds --provider support for routed sends. |
| src/cli/maestro-relay.ts | Updates root CLI help text and documents legacy aliases. |
| src/cli/lib.ts | Extends /api/send payload type to include optional provider. |
| src/tests/transcription.test.ts | Updates tests for provider-agnostic transcription + Discord voice helper split. |
| src/tests/splitMessage.test.ts | Updates tests to import from src/core/splitMessage. |
| src/tests/session-command.test.ts | Updates tests to new Discord command location and new DB wrappers/kernel maestro. |
| src/tests/server.test.ts | Updates tests to new provider-routed src/core/api behavior. |
| src/tests/queue.test.ts | Updates tests for provider-agnostic queue behavior and new types. |
| src/tests/playbook-command.test.ts | Updates tests for command relocation and new embed helpers/kernel maestro. |
| src/tests/mockProvider.test.ts | Adds smoke test for implementing a new BridgeProvider without Discord dependencies. |
| src/tests/messageCreate.test.ts | Updates tests for Discord handler to enqueue kernel IncomingMessage and attachment semantics. |
| src/tests/gist-command.test.ts | Updates tests for command relocation and kernel maestro. |
| src/tests/getAgentCwd.test.ts | Updates tests for kernel maestro caching module path. |
| src/tests/embed.test.ts | Updates tests to new embed helper module path. |
| src/tests/db.test.ts | Updates tests to new Discord DB wrappers. |
| src/tests/db-migrations.test.ts | Updates tests for new migration behavior and renamed threads table. |
| src/tests/config.test.ts | Updates tests for split core vs Discord configuration modules. |
| src/tests/auto-run-command.test.ts | Updates tests for command relocation and kernel maestro. |
| src/tests/attachments.test.ts | Updates tests for provider-agnostic attachment download API + renamed constants. |
| src/tests/agents-command.test.ts | Updates tests for command relocation, new embed helpers, new DB wrappers, kernel maestro. |
| README.md | Rebrands to Maestro Relay, documents kernel/provider split, migration/back-compat, and updated install/run steps. |
| package.json | Renames package, adds binary aliases, updates build/deploy scripts for new structure. |
| package-lock.json | Updates lock metadata and bin mappings for renamed package/binaries. |
| install.sh | Rebrands installer, adds legacy env fallbacks, provider/module selection, and legacy unit cleanup. |
| docs/architecture.md | Rewrites architecture docs for kernel/provider contract and updated project structure. |
| docs/api.md | Updates API docs for provider routing, new CLI name, and updated health response. |
| bin/maestro-relay-ctl.sh | Adds new control wrapper with back-compat cleanup and deploy/update/uninstall flows. |
| bin/maestro-discord-ctl.sh | Removed; replaced by symlink/aliasing to maestro-relay-ctl. |
| AGENTS.md | Updates contributor/agent guide for the kernel/provider split and new commands/paths. |
| .github/workflows/release.yml | Updates release artifact naming to maestro-relay-${tag}.tar.gz. |
| .env.example | Updates env template for core + provider-specific configuration after the split. |
Comments suppressed due to low confidence (1)
src/core/config.ts:29
config.enabledProvidersreturns the raw CSV values without normalization, butbuildProviders/loadProvideronly matches lowercase names (e.g.'discord'). As a result, values likeENABLED_PROVIDERS=Discord(or accidental whitespace/casing from templating) will silently disable the provider. Consider normalizing to lowercase here (and/or inbuildProviders) so provider selection is case-insensitive and robust.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| listByGuild(guildId: string): AgentChannel[] { | ||
| return db | ||
| .prepare("SELECT * FROM agent_channels WHERE provider = 'discord' AND guild_id = ?") | ||
| .all(guildId) as AgentChannel[]; | ||
| }, |
| FFMPEG_PATH=ffmpeg # optional: override ffmpeg executable path | ||
| WHISPER_CLI_PATH=whisper-cli # optional: override whisper-cli executable path | ||
| # mkdir -p ./models && curl -L -o models/ggml-base.en.bin https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin | ||
| WHISPER_MODEL_PATH=models/ggml-base.en.bin # optional: whisper.cpp model path |
Summary
src/core/) from the Discord-specific code (src/providers/discord/); the kernel has zerodiscord.jsimports and aBridgeProvidercontract for adding new platforms.discord-maestro→maestro-relayend to end (package, CLI, service templates, control wrapper, install paths, docs); legacy names are preserved as binary aliases, env-var fallbacks, and ctl symlinks./playbook,/gist,/notes,/auto-run,/agents show) and restructure the CLI into verbs (send,notify,status).Notable changes
src/core/{types,queue,api,providers,db,maestro,transcription,attachments,...}.ts— provider-agnostic kernel.src/providers/discord/{adapter,messageCreate,voice,commands/,deploy,channelsDb,threadsDb,embed,config}.ts— Discord adapter implementingBridgeProvider.src/cli/maestro-relay.ts+src/cli/verbs/{send,notify,status}.ts— new verb-based CLI.package.json:discord-maestro@0.0.4→maestro-relay@0.1.0; binariesmaestro-relay,maestro-bridge,maestro-discordall map to the same dist file.bin/maestro-relay-ctl.sh(new), withmaestro-bridge-ctlandmaestro-discord-ctlsymlinks for back-compat.templates/maestro-relay.serviceandtemplates/sh.maestro.relay.plist; installer disables and removes legacy units on upgrade.install.sh: production one-liner installer, supportsMAESTRO_RELAY_MODULE(currentlydiscordonly), acceptsMAESTRO_BRIDGE_*/MAESTRO_DISCORD_*env vars as fallback, auto-detects legacy~/.config/maestro-{bridge,discord}and~/.local/share/maestro-{bridge,discord}install dirs..github/workflows/release.yml: buildmaestro-relay-${tag}.tar.gz(wasmaestro-discord-${tag}.tar.gz) so the new installer's download URL resolves.agent_channelsrebuilt with composite PK(provider, channel_id)defaulting existing rows todiscord;agent_threadsrenamed todiscord_agent_threads. Idempotent on first start..env.example,README.md,AGENTS.md,docs/architecture.md,docs/api.mdrewritten for the new structure with a clear migration section.Migration / back-compat
maestro-discordandmaestro-bridgebinaries are aliases ofmaestro-relay.maestro-discord-ctl/maestro-bridge-ctlsymlinks point atmaestro-relay-ctl.DISCORD_*env vars unchanged; newENABLED_PROVIDERSdefaults todiscord./api/sendaccepts an optionalproviderfield defaulting todiscord.maestro-discord-ctl update.Test plan
npm run buildcleannpm test— 169/169 tests pass onrcv0.1.0and verify the release workflow publishesmaestro-relay-v0.1.0.tar.gzbash -c "$(curl -fsSL https://raw.githubusercontent.com/RunMaestro/Maestro-Relay/main/install.sh)"on a fresh machine and verifymaestro-relay-ctl startboots the bridgemaestro-discord-ctl update) preserves config, DB, and disables the legacy systemd/launchd unit🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores