-
Notifications
You must be signed in to change notification settings - Fork 0
feat: multi-agent engine on the Claude Agent SDK #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
bed122f
build: add claude agent sdk dependency
efenocchi 2b169db
feat: claude agent sdk engine and event mapping
efenocchi 112e3bb
feat: claude agent roles and in-process openrepl tools
efenocchi ca6d5a4
feat: wire claude provider and engine into the session
efenocchi c449434
test: claude engine unit tests and e2e smoke
efenocchi 77276c4
docs: update prd with validated agent sdk design
efenocchi b549b4e
fix: harden claude engine isolation and make reviewer read-only
efenocchi fa84821
fix: record claude usage under the orchestrator model
efenocchi 1325173
feat: surface the claude provider in the web ui and model list
efenocchi 5546af6
fix: guard read-only tool loops and apply reviewer fixes before finis…
efenocchi acb66c2
test: cover the canUseTool permission gate and loop guard
efenocchi 5561b32
ci: add coderabbit, github actions, codeql, jscpd, and pr template
efenocchi 7ef37bc
chore: drop dead demo and openai-compatible providers
efenocchi c4d5763
test: reconcile stale tests to current apis for green ci
efenocchi 8759de9
ci: scope codeql to product source, excluding dev scripts and tests
efenocchi 019d887
fix: do not persist synthetic assistant text on an empty abort
efenocchi 4bb8edb
fix: match run_command allowlist on a command boundary
efenocchi 7c04125
fix: swap to provider-appropriate model defaults on provider switch
efenocchi fed7809
test: harden the claude engine e2e harness
efenocchi 7e0763e
docs: sync prd tool-split with the implemented role contract
efenocchi 91b0d76
fix: cancel in-flight command and app-probe work when a turn is stopped
efenocchi c7868ca
test: abort the e2e harness on a phase a timeout
efenocchi 775f335
chore: stop tracking internal design docs; keep them local only
efenocchi caccb64
fix: report non-zero exit when a stopped command is killed
efenocchi 7c3c855
ci: run codeql on every pr, not only prs into main
efenocchi a9a555f
fix: report actual provider readiness after a provider switch
efenocchi aec26f1
test: exact model-catalog assertions and free-port e2e server
efenocchi c9a679b
fix: disable sdk session persistence and gate every tool through canU…
efenocchi 6821109
fix: report claude readiness based on an available credential
efenocchi d8f4b16
fix: kill the whole process tree when a stopped command or install is…
efenocchi 6e493d7
chore: remove competitor references from public docs and metadata
efenocchi 1ce66ac
fix: restore tool auto-approval and default-allow canUseTool to unblo…
efenocchi 365dcf6
ci: add per-file coverage thresholds and report the four categories o…
efenocchi 3eeb8b6
docs: document why coverage scopes to server and shared packages
efenocchi c784164
test: cover config defaults, claude readiness, and the command-abort …
efenocchi b898408
refactor: extract openrepl tool handlers so they can be unit-tested
efenocchi 5f1cfb4
ci: exclude llm-loop files from coverage and run test files sequentially
efenocchi d31c6e4
test: broaden server coverage (workflow, probe, providers, static-ser…
efenocchi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # CodeRabbit configuration — https://docs.coderabbit.ai/getting-started/yaml-configuration | ||
| # Repo-level config for activeloopai/open-repl. Requires the CodeRabbit GitHub | ||
| # App to be installed on the repo/org for reviews to run. | ||
| language: en-US | ||
| reviews: | ||
| profile: chill # fewer low-value nitpicks; "assertive" is the only alternative | ||
| request_changes_workflow: false | ||
| high_level_summary: true | ||
| auto_review: | ||
| enabled: true | ||
| base_branches: ["main"] | ||
| # Don't spend review on generated / vendored / lock artifacts. | ||
| path_filters: | ||
| - "!**/package-lock.json" | ||
| - "!**/dist/**" | ||
| - "!**/coverage/**" | ||
| - "!.test-tmp/**" | ||
| # Repo-specific context so CodeRabbit stops re-raising known by-design items. | ||
| path_instructions: | ||
| - path: "packages/server/src/agent/claude/**" | ||
| instructions: > | ||
| This is the Claude Agent SDK engine. A deliberate, e2e-validated design | ||
| constraint: an in-process createSdkMcpServer is only reachable from the | ||
| MAIN thread — delegated subagents' MCP calls return "Stream closed", so | ||
| the ORCHESTRATOR does all file work via the MCP tools and the | ||
| planner/reviewer subagents use the SDK's built-in read-only tools. Do | ||
| NOT suggest giving subagents the MCP tools, nor moving run_app off the | ||
| orchestrator. The read-only loop guard in canUseTool is intentional. | ||
| - path: "packages/server/src/agent/claude/tools.ts" | ||
| instructions: > | ||
| The run_command allowlist is a coarse prefix guard, not a sandbox — this | ||
| is documented in the file. Don't re-flag that an allowed binary can | ||
| re-shell; true isolation is OS-level and deliberately deferred. | ||
| - path: "packages/server/src/agent/{orchestrator,subagents,runtime}.ts" | ||
| instructions: > | ||
| This is the legacy Vercel AI SDK path, intentionally kept for the | ||
| OpenRouter/Codex providers. Do not suggest deleting it as dead code. | ||
| - path: "packages/**/*.test.ts" | ||
| instructions: > | ||
| Prefer asserting on specific values (paths, tool names, model tiers) | ||
| over generic substrings. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| ## Summary | ||
|
|
||
| <!-- What does this PR do and why? --> | ||
|
|
||
| ## Test plan | ||
|
|
||
| - [ ] `npm run typecheck` passes | ||
| - [ ] `npm test` passes | ||
| - [ ] Relevant new tests added (1:1 with the source they cover) | ||
| - [ ] For agent/engine changes: verified end-to-end (`npx tsx scripts/check-claude-engine.ts`) |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| # Run on every PR regardless of base branch. | ||
| pull_request: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| typecheck-test: | ||
| name: Typecheck and test | ||
| runs-on: ubuntu-latest | ||
| # pull-requests: write lets the coverage-report action post its PR comment. | ||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: npm | ||
| - name: Install dependencies | ||
| run: npm ci | ||
| - name: Typecheck | ||
| run: npm run typecheck | ||
| - name: Test with coverage | ||
| # Per-file thresholds (statements/branches/functions/lines) live in | ||
| # vitest.config.ts under coverage.thresholds — vitest exits non-zero if | ||
| # a listed file regresses below its bar, failing the job. | ||
| run: npx vitest run --coverage | ||
| - name: Coverage summary (four categories) | ||
| if: always() | ||
| run: | | ||
| if [ -f coverage/coverage-summary.json ]; then | ||
| node -e " | ||
| const t = require('./coverage/coverage-summary.json').total; | ||
| const f = (m) => m.pct.toFixed(2) + '% (' + m.covered + '/' + m.total + ')'; | ||
| const out = [ | ||
| '### Test coverage', | ||
| '', | ||
| '| Category | Coverage |', | ||
| '|----------|----------|', | ||
| '| Statements | ' + f(t.statements) + ' |', | ||
| '| Branches | ' + f(t.branches) + ' |', | ||
| '| Functions | ' + f(t.functions) + ' |', | ||
| '| Lines | ' + f(t.lines) + ' |', | ||
| ].join('\n'); | ||
| require('fs').appendFileSync(process.env.GITHUB_STEP_SUMMARY, out + '\n'); | ||
| console.log(out); | ||
| " | ||
| fi | ||
| - name: Report coverage on the PR | ||
| if: ${{ always() && github.event_name == 'pull_request' }} | ||
| uses: davelosert/vitest-coverage-report-action@v2 | ||
| with: | ||
| json-summary-path: coverage/coverage-summary.json | ||
| json-final-path: coverage/coverage-final.json | ||
| - name: Build web | ||
| run: npm run build:web | ||
|
|
||
| duplication: | ||
| # Code-duplication regression guard (jscpd). Separate job so the PR checks | ||
| # table shows a dedicated pass/fail row. Threshold lives in .jscpd.json. | ||
| name: Duplication check | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: npm | ||
| - name: Install dependencies | ||
| run: npm ci | ||
| - name: Run jscpd | ||
| run: npm run dup | ||
| - name: Upload jscpd report | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: jscpd-report | ||
| path: jscpd-report/ | ||
| if-no-files-found: ignore |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| name: CodeQL | ||
|
|
||
| # Static security analysis (SAST) for the TypeScript sources — surfaces | ||
| # command-injection / path-traversal / unsafe-shell patterns (the bug class the | ||
| # run_command allowlist guards) in the repo's Security tab and as inline PR | ||
| # annotations. Findings do NOT fail the build by default; gate via branch | ||
| # protection later if desired. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| # Every PR regardless of base, so stacked / intermediate PRs don't skip SAST. | ||
| pull_request: | ||
| schedule: | ||
| # Weekly full scan (Mondays 06:00 UTC). | ||
| - cron: "0 6 * * 1" | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| analyze: | ||
| name: Analyze (javascript-typescript) | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| security-events: write # upload SARIF results to the Security tab | ||
| actions: read | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Initialize CodeQL | ||
| uses: github/codeql-action/init@v3 | ||
| with: | ||
| languages: javascript-typescript | ||
| queries: security-extended | ||
| # Scan shipped product source only. Dev/test harnesses (scripts/, | ||
| # *.test.ts) are not deployed and trip taint queries on values that | ||
| # come from our own server, not an attacker (e.g. the e2e driver's | ||
| # provider check). Keep SAST focused on packages/*/src. | ||
| config: | | ||
| paths-ignore: | ||
| - scripts/** | ||
| - "**/*.test.ts" | ||
| - "**/dist/**" | ||
| - name: Analyze | ||
| uses: github/codeql-action/analyze@v3 | ||
| with: | ||
| category: "/language:javascript-typescript" | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "threshold": 7, | ||
| "reporters": ["console", "markdown"], | ||
| "output": "./jscpd-report", | ||
| "ignore": [ | ||
| "**/node_modules/**", | ||
| "**/dist/**", | ||
| "**/coverage/**", | ||
| "**/.test-tmp/**", | ||
| "**/*.test.ts", | ||
| "**/test/**", | ||
| "**/scripts/**" | ||
| ], | ||
| "absolute": false, | ||
| "gitignore": true, | ||
| "format": ["typescript", "tsx"], | ||
| "minLines": 10, | ||
| "minTokens": 60 | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.