Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
84 changes: 84 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CI

on:
push:
branches:
- '**'
tags:
- 'v*'
pull_request:

jobs:
lint-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- run: npm ci
- run: npm run typecheck
- run: npm run lint

test:
runs-on: ubuntu-latest
needs: lint-typecheck
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- run: npm ci
- run: npm run test:coverage

build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- run: npm ci
- run: npm run build
- run: test -n "$(find dist -mindepth 1 -maxdepth 1 -print -quit)"

release:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
needs: [lint-typecheck, test, build]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
93 changes: 93 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# CLAUDE.md

## 1) Project overview

`vexdo` is a task orchestrator CLI for multi-service repositories. The core flow is: load task + config, run Codex for each step, run Claude reviewer + arbiter loop, then submit PRs or escalate.

## 2) Architecture

Dependency direction should stay:

```text
types ← lib ← commands ← index.ts
```

Key invariants:
- `commands/` may exit process; `lib/` should generally return errors.
- `lib/` is reusable orchestration/integration logic.
- `types/` stays free of runtime dependencies.
- Reviewer and arbiter must run with isolated contexts/data.

## 3) Key files and roles

```text
src/
index.ts # commander bootstrap, global flags, command wiring
commands/
init.ts # interactive bootstrap (`vexdo init`)
start.ts # primary task execution flow
review.ts # rerun review loop on active step
fix.ts # feed corrective prompt to Codex then review
submit.ts # PR creation and state completion
abort.ts # cancel task, preserve branches
status.ts # print active state
logs.ts # print iteration logs
lib/
config.ts # .vexdo.yml discovery + validation
tasks.ts # task loading/validation and lane moves
state.ts # active state persistence
review-loop.ts # reviewer/arbiter loop control
claude.ts # Anthropic SDK wrapper
codex.ts # codex CLI wrapper
gh.ts # gh CLI wrapper for PRs
git.ts # git operations
logger.ts # output formatting
requirements.ts # env/runtime checks
prompts/
reviewer.ts # reviewer prompt construction
arbiter.ts # arbiter prompt construction
types/index.ts # shared type contracts
```

## 4) Common tasks

### Add a command
1. Add `src/commands/<name>.ts` with `register<Name>Command`.
2. Keep parsing and CLI concerns in command file.
3. Put reusable logic in `lib/`.
4. Register in `src/index.ts`.
5. Add tests and README docs.

### Add a lib function
1. Add function to the nearest `lib/*` module.
2. Keep signature typed and avoid `any`.
3. Return errors; avoid process termination.
4. Add focused unit tests.

### Add a test
1. Unit tests in `test/unit` or `tests/unit` for isolated behavior.
2. Integration tests in `test/integration` or `tests/integration` for flow.
3. Use `vi.mock` for `child_process`, SDKs, and external CLIs.

## 5) Constraints to always enforce

- No `any` in new code.
- Keep ESM `.js` import specifiers in TS source.
- No `process.exit` inside `lib/` modules.
- Do not add `chalk`; use `picocolors` for output styling.
- Reviewer and arbiter contexts must remain isolated.

## 6) Test conventions

- Prefer mocking at module boundary.
- `child_process` calls should be mocked with `vi.mock('node:child_process', ...)`.
- Anthropic SDK behavior should be mocked through `lib/claude.ts` dependencies.
- Use temp directories for filesystem side effects.

## 7) What not to do

- Do not embed orchestration logic directly in `index.ts`.
- Do not tightly couple command handlers to specific prompt text.
- Do not bypass task/config validation.
- Do not mutate state without persisting through `state.ts` helpers.
- Do not mix reviewer and arbiter outputs in a single decision context.
62 changes: 62 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Contributing to vexdo

## 1) Development setup

```bash
git clone <repo-url>
cd vexdo-cli
npm install
npm link
npm test
```

Useful checks:
- `npm run typecheck`
- `npm run lint`
- `npm run build`

## 2) Project structure

```text
src/
index.ts # CLI entrypoint and command registration
commands/ # User-facing command handlers
lib/ # Core orchestration, integrations, and helpers
prompts/ # Claude reviewer/arbiter prompt templates
types/ # Shared TypeScript types
test/ + tests/ # Unit and integration tests
```

## 3) Adding a new command

1. Create `src/commands/<name>.ts`.
2. Export `register<Name>Command(program: Command)`.
3. Implement `run<Name>` function and keep side effects inside command layer.
4. Add registration in `src/index.ts`.
5. Add unit tests for parsing/behavior and integration tests if command touches git/fs/process.
6. Update README command docs.

## 4) Testing conventions

- **Unit tests**: isolated logic, heavy mocking (`child_process`, SDK clients, filesystem helpers).
- **Integration tests**: flow-level behavior and state transitions.
- Prefer deterministic fixtures and temporary directories.
- External dependencies (Anthropic, gh, codex) must be mocked in unit tests.

## 5) Commit conventions

- Follow Conventional Commits, e.g.:
- `feat: add init command`
- `fix: prevent duplicate gitignore entry`
- `docs: expand README`
- PRs should include:
- clear summary
- tests run
- any breaking changes

## 6) Release process

1. Bump version and update changelog/release notes.
2. Push tag `vX.Y.Z`.
3. GitHub Actions CI runs lint/typecheck/test/build.
4. Release job publishes to npm using `NPM_TOKEN`.
Loading
Loading