Skip to content
Merged
Show file tree
Hide file tree
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 Jun 30, 2026
2b169db
feat: claude agent sdk engine and event mapping
efenocchi Jun 30, 2026
112e3bb
feat: claude agent roles and in-process openrepl tools
efenocchi Jun 30, 2026
ca6d5a4
feat: wire claude provider and engine into the session
efenocchi Jun 30, 2026
c449434
test: claude engine unit tests and e2e smoke
efenocchi Jun 30, 2026
77276c4
docs: update prd with validated agent sdk design
efenocchi Jun 30, 2026
b549b4e
fix: harden claude engine isolation and make reviewer read-only
efenocchi Jun 30, 2026
fa84821
fix: record claude usage under the orchestrator model
efenocchi Jun 30, 2026
1325173
feat: surface the claude provider in the web ui and model list
efenocchi Jun 30, 2026
5546af6
fix: guard read-only tool loops and apply reviewer fixes before finis…
efenocchi Jun 30, 2026
acb66c2
test: cover the canUseTool permission gate and loop guard
efenocchi Jun 30, 2026
5561b32
ci: add coderabbit, github actions, codeql, jscpd, and pr template
efenocchi Jun 30, 2026
7ef37bc
chore: drop dead demo and openai-compatible providers
efenocchi Jun 30, 2026
c4d5763
test: reconcile stale tests to current apis for green ci
efenocchi Jun 30, 2026
8759de9
ci: scope codeql to product source, excluding dev scripts and tests
efenocchi Jun 30, 2026
019d887
fix: do not persist synthetic assistant text on an empty abort
efenocchi Jun 30, 2026
4bb8edb
fix: match run_command allowlist on a command boundary
efenocchi Jun 30, 2026
7c04125
fix: swap to provider-appropriate model defaults on provider switch
efenocchi Jun 30, 2026
fed7809
test: harden the claude engine e2e harness
efenocchi Jun 30, 2026
7e0763e
docs: sync prd tool-split with the implemented role contract
efenocchi Jun 30, 2026
91b0d76
fix: cancel in-flight command and app-probe work when a turn is stopped
efenocchi Jul 1, 2026
c7868ca
test: abort the e2e harness on a phase a timeout
efenocchi Jul 1, 2026
775f335
chore: stop tracking internal design docs; keep them local only
efenocchi Jul 1, 2026
caccb64
fix: report non-zero exit when a stopped command is killed
efenocchi Jul 1, 2026
7c3c855
ci: run codeql on every pr, not only prs into main
efenocchi Jul 1, 2026
a9a555f
fix: report actual provider readiness after a provider switch
efenocchi Jul 1, 2026
aec26f1
test: exact model-catalog assertions and free-port e2e server
efenocchi Jul 1, 2026
c9a679b
fix: disable sdk session persistence and gate every tool through canU…
efenocchi Jul 1, 2026
6821109
fix: report claude readiness based on an available credential
efenocchi Jul 1, 2026
d8f4b16
fix: kill the whole process tree when a stopped command or install is…
efenocchi Jul 1, 2026
6e493d7
chore: remove competitor references from public docs and metadata
efenocchi Jul 1, 2026
1ce66ac
fix: restore tool auto-approval and default-allow canUseTool to unblo…
efenocchi Jul 1, 2026
365dcf6
ci: add per-file coverage thresholds and report the four categories o…
efenocchi Jul 1, 2026
3eeb8b6
docs: document why coverage scopes to server and shared packages
efenocchi Jul 1, 2026
c784164
test: cover config defaults, claude readiness, and the command-abort …
efenocchi Jul 1, 2026
b898408
refactor: extract openrepl tool handlers so they can be unit-tested
efenocchi Jul 1, 2026
5f1cfb4
ci: exclude llm-loop files from coverage and run test files sequentially
efenocchi Jul 1, 2026
d31c6e4
test: broaden server coverage (workflow, probe, providers, static-ser…
efenocchi Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .coderabbit.yaml
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.
10 changes: 10 additions & 0 deletions .github/pull_request_template.md
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`)
92 changes: 92 additions & 0 deletions .github/workflows/ci.yaml
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
51 changes: 51 additions & 0 deletions .github/workflows/codeql.yaml
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"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

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"
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,14 @@ dist/
coverage/
packages/web/dist/
.test-tmp/
jscpd-report/

# Internal / agent-authored docs — never committed to the public repo (kept local only)
.internal/
PRD-*.md
BACKLOG.md
IMPLEMENTATION.md
NIGHT-LOG.md
PLAN.md
STATUS.md
todo_list.md
19 changes: 19 additions & 0 deletions .jscpd.json
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
}
Loading
Loading