refactor(mcp-server): split 1697-line index.ts into per-domain modules - #2
Merged
Merged
Conversation
Pure mechanical split, no behavior changes. Pulls the 70+ tool handlers out of one monolith into api.ts (PLATFORM_URL + apiCall) plus 12 tools/*.ts files grouped by domain (workspaces, agents, secrets, files, memory, plugins, channels, delegation, schedules, approvals, discovery, remote_agents). Each module exports its handlers and a registerXxxTools(srv) function; createServer() wires them up. index.ts drops from 1697 → 89 lines. Largest new file is 183 lines. All handlers still re-exported from index.ts so existing tests that import them via "../index.js" keep working. Build clean; jest results unchanged from pre-refactor baseline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3 tasks
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 13, 2026
The get_remote_agent_setup_command handler emitted \`python3 -m examples.remote-agent.run\` — an invalid Python module path (dashes not allowed in module names), so the command never actually worked. Replace with a direct \`python3 -c "..."\` snippet that imports from \`molecule_agent\` (the real SDK module) and points to the demo script for reference. Fixes the pre-existing jest failure in \`handleGetRemoteAgentSetupCommand emits bash for external workspace\` that was flagged against PR #2. Updates test expectation to \`molecule_agent\` (the actual importable module name) from the never-valid \`molecule-agent\`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 14, 2026
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 15, 2026
…board nav Addresses the three release-blocking WCAG violations from the UX audit (3rd consecutive cycle) and the new ChatTab ARIA gap from Audit #2. Changes: - Toaster: split into polite (success/info) + assertive (error) live regions, both always in DOM so screen readers register them before any toast fires. Adds x dismiss button on every toast. Errors no longer auto-expire after 4s — persist until explicitly dismissed. - ConfirmDialog: on open, requestAnimationFrame focuses the first button inside the dialog. Tab/Shift-Tab is now trapped inside the dialog while open. Added role="dialog" aria-modal="true" and aria-labelledby pointing to the title h3. - WorkspaceNode: outer div gains role="button", tabIndex={0}, aria-label, aria-pressed, and onKeyDown (Enter/Space => selectNode, ContextMenu key => openContextMenu). Keyboard-only users can now reach and activate workspace nodes. - ChatTab sub-tab bar: role="tablist" on wrapper, role="tab" + aria-selected + aria-controls on each button, matching role="tabpanel" + id on each panel div. Textarea gets aria-label="Message to agent". 453/453 Vitest tests pass. Production build clean (Next.js 15). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced Apr 15, 2026
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 15, 2026
Every publish-platform-image run since the aa41947 self-hosted runner migration has been failing with two runner-level issues that the workflow now works around (keychain) or surfaces clearly (path): 1. "error storing credentials - err: exit status 1, out: 'User interaction is not allowed. (-25308)'" docker/login-action tries to persist the GHCR + Fly tokens in the macOS Keychain, but the Mac mini runner runs as a non-interactive launchd service without an unlocked desktop session — keychain access raises -25308. Fix: set DOCKER_CONFIG to a per-run temp dir containing a plain config.json before the login step so credentials land in a file, not the keychain. This is the same trick the GitHub-hosted macos runners use in docker action examples. 2. "Unexpected error attempting to determine if executable file exists '/usr/local/bin/docker': Error: EACCES: permission denied, stat '/usr/local/bin/docker'" Not a workflow bug — the runner literally can't read the Docker binary path. Adds a diagnostic step before QEMU/buildx setup that prints: PATH, `command -v docker`, `docker --version`, and `ls -la` on both /usr/local/bin/docker and /opt/homebrew/bin/docker. Surfacing these in the log means the next failure (if any) shows the actual problem instead of hiding behind a cryptic buildx error. Does NOT fix the root cause of #2 — that needs the user to SSH into the Mac mini runner and reinstall / re-permission Docker Desktop (or switch to Colima/OrbStack). The diagnostic output will tell us exactly which path is broken. The 20+ queued CI runs from `ci.yml` are unrelated to this PR — they are stuck because the self-hosted runner has severely degraded queue throughput (runs wait 2+ hours before being picked up). That's a separate runner-health issue tracked as a user action in the triage report. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 16, 2026
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 16, 2026
Code review fixes: - 🟡 #1: Replace python3 with jq in Dockerfile template stages (~50MB → ~2MB) - 🟡 #2: Add clone count verification to scripts/clone-manifest.sh (set -e + expected vs actual count check — fails build if any clone fails) - 🟡 #3: Drop 'unsafe-eval' from CSP (not needed for Next.js production standalone builds, only dev mode). Updated test assertion. - 🟡 #4: Remove broken pyproject.toml from workspace-template/ (it claimed to package as molecule-ai-workspace-runtime but the directory structure didn't match — the real package ships from the standalone repo) - 🔵 #1: Add version-pinning TODO comment to manifest.json - 🔵 #3: Add full repo URLs + test counts for SDK/MCP/CLI/runtime in CLAUDE.md Security (GitGuardian alert): - Removed Telegram bot token (8633739353:AA...) from template-molecule-dev pm/.env — replaced with ${TELEGRAM_BOT_TOKEN} placeholder - Removed Claude OAuth token (sk-ant-oat01-...) from template-molecule-dev root .env — replaced with ${CLAUDE_CODE_OAUTH_TOKEN} placeholder - Both tokens need immediate rotation by the operator Tests: Platform middleware tests updated + all pass.
This was referenced Apr 17, 2026
3 tasks
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
refactor(mcp-server): split 1697-line index.ts into per-domain modules
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
The get_remote_agent_setup_command handler emitted \`python3 -m examples.remote-agent.run\` — an invalid Python module path (dashes not allowed in module names), so the command never actually worked. Replace with a direct \`python3 -c "..."\` snippet that imports from \`molecule_agent\` (the real SDK module) and points to the demo script for reference. Fixes the pre-existing jest failure in \`handleGetRemoteAgentSetupCommand emits bash for external workspace\` that was flagged against PR #2. Updates test expectation to \`molecule_agent\` (the actual importable module name) from the never-valid \`molecule-agent\`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
…board nav Addresses the three release-blocking WCAG violations from the UX audit (3rd consecutive cycle) and the new ChatTab ARIA gap from Audit #2. Changes: - Toaster: split into polite (success/info) + assertive (error) live regions, both always in DOM so screen readers register them before any toast fires. Adds x dismiss button on every toast. Errors no longer auto-expire after 4s — persist until explicitly dismissed. - ConfirmDialog: on open, requestAnimationFrame focuses the first button inside the dialog. Tab/Shift-Tab is now trapped inside the dialog while open. Added role="dialog" aria-modal="true" and aria-labelledby pointing to the title h3. - WorkspaceNode: outer div gains role="button", tabIndex={0}, aria-label, aria-pressed, and onKeyDown (Enter/Space => selectNode, ContextMenu key => openContextMenu). Keyboard-only users can now reach and activate workspace nodes. - ChatTab sub-tab bar: role="tablist" on wrapper, role="tab" + aria-selected + aria-controls on each button, matching role="tabpanel" + id on each panel div. Textarea gets aria-label="Message to agent". 453/453 Vitest tests pass. Production build clean (Next.js 15). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
Every publish-platform-image run since the 3ff40c4 self-hosted runner migration has been failing with two runner-level issues that the workflow now works around (keychain) or surfaces clearly (path): 1. "error storing credentials - err: exit status 1, out: 'User interaction is not allowed. (-25308)'" docker/login-action tries to persist the GHCR + Fly tokens in the macOS Keychain, but the Mac mini runner runs as a non-interactive launchd service without an unlocked desktop session — keychain access raises -25308. Fix: set DOCKER_CONFIG to a per-run temp dir containing a plain config.json before the login step so credentials land in a file, not the keychain. This is the same trick the GitHub-hosted macos runners use in docker action examples. 2. "Unexpected error attempting to determine if executable file exists '/usr/local/bin/docker': Error: EACCES: permission denied, stat '/usr/local/bin/docker'" Not a workflow bug — the runner literally can't read the Docker binary path. Adds a diagnostic step before QEMU/buildx setup that prints: PATH, `command -v docker`, `docker --version`, and `ls -la` on both /usr/local/bin/docker and /opt/homebrew/bin/docker. Surfacing these in the log means the next failure (if any) shows the actual problem instead of hiding behind a cryptic buildx error. Does NOT fix the root cause of #2 — that needs the user to SSH into the Mac mini runner and reinstall / re-permission Docker Desktop (or switch to Colima/OrbStack). The diagnostic output will tell us exactly which path is broken. The 20+ queued CI runs from `ci.yml` are unrelated to this PR — they are stuck because the self-hosted runner has severely degraded queue throughput (runs wait 2+ hours before being picked up). That's a separate runner-health issue tracked as a user action in the triage report. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
Code review fixes: - 🟡 #1: Replace python3 with jq in Dockerfile template stages (~50MB → ~2MB) - 🟡 #2: Add clone count verification to scripts/clone-manifest.sh (set -e + expected vs actual count check — fails build if any clone fails) - 🟡 #3: Drop 'unsafe-eval' from CSP (not needed for Next.js production standalone builds, only dev mode). Updated test assertion. - 🟡 #4: Remove broken pyproject.toml from workspace-template/ (it claimed to package as molecule-ai-workspace-runtime but the directory structure didn't match — the real package ships from the standalone repo) - 🔵 #1: Add version-pinning TODO comment to manifest.json - 🔵 #3: Add full repo URLs + test counts for SDK/MCP/CLI/runtime in CLAUDE.md Security (GitGuardian alert): - Removed Telegram bot token (8633739353:AA...) from template-molecule-dev pm/.env — replaced with ${TELEGRAM_BOT_TOKEN} placeholder - Removed Claude OAuth token (sk-ant-oat01-...) from template-molecule-dev root .env — replaced with ${CLAUDE_CODE_OAUTH_TOKEN} placeholder - Both tokens need immediate rotation by the operator Tests: Platform middleware tests updated + all pass.
4 tasks
4 tasks
This was referenced Apr 23, 2026
4 tasks
HongmingWang-Rabbit
added a commit
that referenced
this pull request
Apr 26, 2026
…zed-node string simplify-review note: the |/,-delimited node string is brittle if a future string-typed field is added without sanitization. Document which fields are user-typed (name — already sanitized) vs primitive (id is UUID, runtime is a slug, provisionTimeoutMs is numeric) so the next field-add doesn't accidentally introduce an injection vector for the splitter. Skipped (false-positive review finding): the agent flagged the prop > runtime-profile order as inconsistent with the docstring, but the docstring explicitly lists the prop at #2 (between node and runtime-profile) — matches both the implementation AND the original behavior pre-#2054 (the prop was 'timeoutMs ?? runtime-profile'). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 27, 2026
…lper Self-review on PR #2185 surfaced a latent race the original fix exposed: the WS-clears-guards path now releases sendInFlightRef immediately, which means a user can fire msg #2 between WS-arrival and HTTP-arrival for msg #1. Without coordination, msg #1's late .then() sees sendingFromAPIRef=true (set by msg #2's send), enters the main body, and runs setSending(false) + appendMessageDeduped against msg #1's response body — clobbering msg #2's in-flight UI state. This race is realistic for claude-code SDK: the comment at line 294-298 already calls WS the "authoritative reply arrived" signal, and the user typically reads-then-types before the trailing HTTP completes. Without the original Send-button freeze "protecting" the race, it surfaces. Two changes: 1. Token-keyed callbacks. sendTokenRef bumps on every sendMessage entry; .then()/.catch() capture the token in closure and bail without touching any flags if a newer send has superseded them. The newer send owns the in-flight guards. 2. releaseSendGuards() helper. The three-clear-guards trio (setSending, sendingFromAPIRef, sendInFlightRef) now lives in one useCallback so the WS handler, .then() success, and .catch() success can't drift apart. A future contributor dropping one of the three would silently re-introduce either the post-WS Send freeze or the stale-callback clobber. Skipped a unit test for this regression — ChatTab has no __tests__ file and a mount test would need WS + zustand + api mocks. The fix is 4 logical lines (token capture + 2 guard checks) and the manual test covers it. Follow-up to add a focused mount test when ChatTab gets its first __tests__ file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 29, 2026
Open
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
May 3, 2026
Independent code review of #2555 caught two contrast regressions left by the bulk perl pass: 1. text-white → text-ink mass-substitution silently broke destructive and primary buttons. text-ink resolves to #15181c (warm-paper near-black) in light mode — dark text on bg-red-600 / bg-amber-600 / bg-emerald-600 / bg-blue-600 / bg-accent / bg-accent-strong / bg-good / bg-bad fails WCAG contrast and looks broken. Per-line pass flips text-ink → text-white only when a saturated bg utility is present; tinted-state pills (bg-red-950/50 etc.) keep their intentionally-retained text-* literals. 2. Original mapping table was missing bg-zinc-600 (most-used hover-state literal for cancel buttons — caused them to JUMP from warm cream resting state to dark zinc on hover in light mode) and text-zinc-700/800/900 (separator dots and decorative dim text invisible on warm-paper light bg). Extended mapping fills these gaps with bg-surface-card / text-ink-soft. Also: drop stale tailwind.config.ts reference from components.json (file deleted by the v3→v4 migration); switch baseColor zinc → neutral and enable cssVariables since v4 uses CSS-driven tokens. Future shadcn-cli invocations would have failed or written malformed components without this. 27 sites in 27 files affected by #1, ~20 sites in 20 files by #2. 1214/1214 unit tests still pass; build still clean. Findings courtesy of multi-model review per code-review-and-quality skill — different blind spots catch different bugs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 3, 2026
4 tasks
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
Addresses both review subagents' REQUEST_CHANGES verdicts on PR #1929: Code review (correctness) - #1: Move schedule seeding to AFTER provisionWorkspaceAuto succeeds so the scheduler never fires cron rows against a workspace whose backend never wired. Failed-backend workspaces no longer end up with orphan template_schedules rows. - #2: seedTemplateSchedules now returns (seeded, skipped int) so the caller can observe partial-seed states; workspace.go Create logs the (seeded, skipped) pair when skipped > 0, surfacing silent partial-loss that the prior (int) return masked. Security review (hostile-template defenses) - #3 / #4: parseTemplateSchedules reads config.yaml through an io.LimitReader bounded by maxTemplateConfigYAMLBytes (1 MiB) and rejects files over the cap before yaml.Unmarshal runs. Defends against billion-laughs / anchor-explosion DoS. - #3: schedules slice length capped at maxTemplateSchedules (100, 10x the largest current production grid). Hostile template with 50k schedules now rejected at parse time, not after 50k inserts. - #3: cron_expr length capped at maxScheduleCronExprLen (128) per schedule; resolved prompt body capped at maxSchedulePromptBytes (16 KiB) per schedule. Oversized entries are skipped (counted as `skipped`) so one bad row doesn't break the rest. - #3: Seed loop honours ctx.Err() so an aborted Create request stops further inserts rather than running to completion on a dead goroutine. - #8: Schedule names quoted via %q in all log lines so CRLF in a hostile name can't injection-pollute stdout/Loki. Tests - TestParseTemplateSchedules_RejectsOversizeFile — gate against the LimitReader cap (1 MiB + 1 byte of '#'). - TestParseTemplateSchedules_RejectsTooManySchedules — gate against the schedule-count cap (maxTemplateSchedules + 1 minimal entries). - Full handlers test suite still green (17.4s). Non-fix surface - Code-review #3 (runtime-default fallback also seeds): runtime- default templates do not currently ship a schedules: block so this is benign in practice; documented behavior in the comment. - Code-review #4 (files_dir in workspace-template config.yaml): not part of the current template_registry schema; flagged for follow-up if templates start declaring files_dir. - Security-review #7 (cron prompt as agent self-message escalation vector): out of scope per security reviewer's own note; tracked separately. Will file an issue. Verified locally: go vet ./... → clean go build ./... → clean gofmt -d <changed files> → clean go test ./internal/handlers/ → PASS (7 unit tests for parser, full suite 17.4s) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
…tion tests (#2166 blocker #2) **Step A — Go-level fail-closed** Extract a shared `requireIntegrationDBURL(t)` helper into `integration_helper_test.go` (build-tag: integration). The helper: - Returns $INTEGRATION_DB_URL when present - Calls `t.Fatalf` when the URL is empty AND any CI marker is set (`CI`, `GITHUB_ACTIONS`, or `GITEA_ACTIONS`), preventing a silent skip-to-green in CI - Calls `t.Skip` when the URL is empty AND no CI marker is set, preserving the local-dev ergonomics Update all three integration test files to use the shared helper: - delegation_ledger_integration_test.go - pending_uploads_integration_test.go - workspace_create_name_integration_test.go This closes the Go-level fail-open where a missing INTEGRATION_DB_URL in CI would cause every integration test to skip and report PASS. **Step C — Workflow bash preflight** Add a `Preflight — INTEGRATION_DB_URL must be present` step in `.gitea/workflows/handlers-postgres-integration.yml` immediately before the `go test` invocation. If the postgres-start step failed to export the variable, the preflight exits 1 with `::error::` so the job fails loud before the test binary can even start. **Step B — Workflow CoE mask** ALREADY FIXED in current main: both `detect-changes` and `integration` jobs have `continue-on-error: false` (lines 93 and 125). The context is already listed in `audit-force-merge.yml` REQUIRED_CHECKS_JSON for `main`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
…/recovery paths (#73) Add SQL status guards to the two heartbeat evaluateStatus paths that lacked them, preventing a removed workspace from being resurrected to 'online' or 'degraded' by a racing heartbeat: 1. error_rate degrade path: AND status = 'online' 2. degraded→online recovery path: AND status = 'degraded' Both paths previously used WHERE id = only, so a heartbeat that started before CascadeDelete's UPDATE could flip the just-removed row back to a live status. This is the status-persist trio false-online / inconsistent-teardown class identified in the Researcher cleanup audit. The other three evaluateStatus paths (wedged→degraded, offline→online, provisioning→online, awaiting_agent→online) already carried guards. Adds regression tests (TestHeartbeat_ErrorRateDegrade_Guarded and TestHeartbeat_DegradedRecovery_Guarded) that verify the guards are present and return 0 rows when the workspace has been concurrently removed. Closes ticket #2 from Researcher cleanup audit.
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
…2 10782 follow-up) Augments the prior fail-CLOSED fix on reserved-path-review.sh (76a8a057). Researcher adjudication (job 467485/run 346968, on molecule-runner-robot-1-4 image CACHED — confirmed NOT infra) found a SECOND defect: the workflow checks out the BASE ref (f44d688) and runs `bash .gitea/scripts/ reserved-path-review.sh`, but #2570 is the PR that INTRODUCES that script — so on this PR the script is ABSENT on base → 'No such file or directory', the check hard-fails. This is a bootstrap / self-reference problem: the guard gates the very PR that adds the guard. Unfixable without a workflow change. Fix: refine the checkout strategy in the workflow to break the self-reference while preserving the security model: 1. The SCRIPT is now checked out from the PR HEAD (not base), so the gate is always present — including on the bootstrap PR that adds the gate. `actions/checkout` uses `ref: ${{ github.event.pull_request.head.sha }}` for this. (`pull_request_target` ensures the run runs with the BASE commit's permissions, not the PR's — so the PR author cannot inject code that runs in the workflow's auth context. The head checkout is for FILE READING only.) 2. The reserved-paths MANIFEST (.gitea/reserved-paths.txt) is read from the BASE branch via `git show <base.sha>:.gitea/reserved-paths.txt` and staged to .gitea/reserved-paths.txt in the workspace. This preserves the original security intent: a PR author cannot widen the gate by adding new reserved patterns in their own PR (the manifest is base-sourced for every steady-state PR). 3. Bootstrap PR fallback: if `git show` on the base manifest fails (the single PR that INTRODUCES the manifest — base has no file yet), the workflow falls back to the head's manifest and emits a loud `::notice::` log line so reviewers see the bootstrap path ran. The script still executes — this is NOT an unconditional pass; it is a graceful one-time bootstrap. 4. The script is invoked with `RESERVED_PATHS_FILE: .gitea/reserved-paths.txt` so it uses the (base-overridden or head-fallback) manifest we just staged — not whatever the script's own RESERVED_PATHS_FILE default resolves to. 5. The DETECTIVE backstop (audit-force-merge.sh emitting incident.reserved_self_merge) is unchanged — intentionally fail-OPEN-by-design per its own header. New regression tests (5 added on top of the prior 9, now 14 total): T6d: workflow checks out PR HEAD (so the gate script is present, including on the bootstrap PR) T6e: workflow fetches .gitea/reserved-paths.txt from BASE via git show (security model preserved) T6f: workflow logs the bootstrap fallback explicitly T6g: workflow does NOT have an unconditional pass shortcut (re-introduce-fail-open guard) T6h: workflow passes RESERVED_PATHS_FILE explicitly to the script ALL 14 TESTS PASS locally. Combined with the prior fix at 76a8a057: Defect #1 (CR2 10782, fail-OPEN return-code): CLOSED at 76a8a057 (script now branches on MATCH_RC explicitly; 0/1/2 with 2+ failing closed; 9 regression tests lock the contract). Defect #2 (Researcher adjudication, bootstrap / self-reference): CLOSED here (workflow now checks out PR HEAD + reads base manifest via git show + bootstrap fallback for the introducing PR; 5 new regression tests lock the contract). Head moves from 76a8a057 to (new) on the same chore/core-self-merge-guard-reserved-paths branch. The CR-A approval chain (agent-researcher 04:43Z) and CR2 REQUEST_CHANGES (10782, also from agent-researcher) are against the prior head 57557d8c — they will need to re-review this new head. Spec-only execution — no review/decisions, no self-merge. CR2 10782 fix (this is the augmented 03744380).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mcp-server/src/index.ts(1697 → 89 lines) intoapi.ts+ 12tools/*.tsmodules grouped by domainregisterXxxTools(srv)function;createServer()inindex.tsjust wires themhandleXfunctions still re-exported fromindex.tsso existing tests importing via"../index.js"work unchangedFiles
```
api.ts 33
tools/workspaces.ts 131
tools/agents.ts 97
tools/secrets.ts 82
tools/files.ts 110
tools/memory.ts 165
tools/plugins.ts 106
tools/channels.ts 142
tools/delegation.ts 183 ← largest new file
tools/schedules.ts 131
tools/approvals.ts 75
tools/discovery.ts 173
tools/remote_agents.ts 182
index.ts 89
```
Test plan
🤖 Generated with Claude Code