Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
634edbb
feat(core): extract worktree primitives into ralph-core
taberoajorge Apr 11, 2026
587eb40
refactor(core): extract story scheduler
taberoajorge Apr 11, 2026
360e0c6
test(core): add worktree regression coverage
taberoajorge Apr 11, 2026
43f33b2
test(core): cover scheduler merge behavior
taberoajorge Apr 11, 2026
2c0b152
feat(core): add worktree domain primitives
taberoajorge Apr 11, 2026
0029104
feat(core): add parallel worktree scheduler
taberoajorge Apr 11, 2026
d2f22cb
feat(core): provision per-story worktrees
taberoajorge Apr 11, 2026
a25c8a0
feat(core): serialize shared artifact writes
taberoajorge Apr 11, 2026
7e3fd76
feat(core): run ready stories in parallel
taberoajorge Apr 11, 2026
758d2dd
refactor(tauri): serialize loop artifact merges
taberoajorge Apr 11, 2026
da26d6d
refactor(tauri): extract monitor services behind adapters
taberoajorge Apr 11, 2026
10f10ce
refactor(tauri): route project commands through app core
taberoajorge Apr 11, 2026
433689d
fix(tauri): centralize plan session cleanup
taberoajorge Apr 11, 2026
0a40048
refactor(tauri): route atomizer orchestration through app core
taberoajorge Apr 11, 2026
ea1df99
test(frontend): add phase one monitor hard-gate checks
taberoajorge Apr 11, 2026
e51fcd2
refactor(tauri): decommission tauri and react shell
taberoajorge Apr 11, 2026
efd85fc
feat(tokens): add native shell theming
taberoajorge Apr 11, 2026
eeaedd7
feat(frontend): port dashboard to native shell
taberoajorge Apr 11, 2026
f48f40a
feat(frontend): add native project lifecycle actions
taberoajorge Apr 11, 2026
bcd6916
feat(frontend): add native planning flow
taberoajorge Apr 11, 2026
28cd779
feat(frontend): add native atomization flow
taberoajorge Apr 11, 2026
931257b
feat(frontend): add native loop monitor
taberoajorge Apr 11, 2026
a153a8d
feat(core): restore persisted loop sessions on restart
taberoajorge Apr 11, 2026
7c22e0e
feat(frontend): enhance atomization flow with activity tracking and p…
taberoajorge Apr 12, 2026
0bfb279
refactor(tauri): migrate wizard logic, validation and stories CRUD to…
taberoajorge Apr 12, 2026
e038260
chore(core): enforce zero-warning lint baseline
taberoajorge Apr 13, 2026
dbf4e7e
chore(docs): refresh agent and cursor rule contracts
taberoajorge Apr 13, 2026
4856094
fix(ci): resolve all rust-tests compilation errors and updater signin…
taberoajorge Apr 13, 2026
a8b2f70
fix(lint): sort import order in tauri.ts
taberoajorge Apr 13, 2026
d17ea0b
fix(tests): resolve all 5 pre-existing test failures and improve atom…
taberoajorge Apr 13, 2026
eb7dc45
fix(ci): pin bun version to 1.3.10 in all workflow jobs
taberoajorge Apr 13, 2026
94b7708
fix(ci): use npm for bun install and use bash in agent path test
taberoajorge Apr 13, 2026
3735157
fix(tests): increase poll timeouts for CI runner latency
taberoajorge Apr 13, 2026
8f20f21
fix(tauri): add missing start-dragging window capability
taberoajorge Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 20 additions & 0 deletions .cursor/rules/antipatterns.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
description: Common LoopForge mistakes to avoid during edits
alwaysApply: false
---

# LoopForge Antipatterns

Avoid these mistakes:

- Editing plan or story data only in Zustand without persisting to artifact files
- Saving empty wizard snapshots like `"{}"` instead of full draft state
- Passing partial configure inputs that never reach `build_ralph_config`
- Leaving process cleanup stubs without child termination and flush behavior
- Creating oversized mixed concern modules instead of splitting commands, services, and storage

Preferred patterns:

- Persist `plan.md`, `prd.json`, `config.json`, and `draft.json` through backend commands
- Keep command handlers thin and move logic into services
- Validate artifact reads and writes with tests when changing flow contracts
16 changes: 16 additions & 0 deletions .cursor/rules/frozen-modules.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
description: Apply when a task touches frozen or unconnected modules
alwaysApply: false
---

# Frozen Modules

Do not modify, extend, or wire these modules into new code unless the task explicitly includes a planned vertical slice for them.

- `connections.rs` and `Connections.tsx`
- `plugin_registry.rs` and `Plugins.tsx`
- `scm_watcher.rs`
- `ephemeral_query.rs` and `EphemeralOverlay.tsx`
- `summary_generator.rs`

If work must touch one of these files, pause and confirm the intended slice boundary before coding.
22 changes: 0 additions & 22 deletions .cursor/rules/project.mdc

This file was deleted.

14 changes: 13 additions & 1 deletion .cursor/rules/react.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ globs: "src/**/*.{ts,tsx}"
## Components
- Functional components with named exports
- PascalCase for component names and files
- Props as inline type parameters, not separate interface files
- Keep components focused and extract early before large mixed concern files form

## State
- Zustand stores in `src/stores/`
- One store per domain: projectStore, agentStore, loopStore, wizardStore
- Use selectors to minimize re-renders
- Never treat Zustand as source of truth for `plan.md`, `prd.json`, `config.json`, or `draft.json`

## Styling
- Tailwind CSS 4 utility classes exclusively
Expand All @@ -32,3 +33,14 @@ globs: "src/**/*.{ts,tsx}"
- Bindings in `src/lib/tauri.ts`
- Use `@tauri-apps/api/core` for invoke
- Use `@tauri-apps/api/event` for listen
- Persist user edits through backend commands before advancing workflow stages

## Data Contracts
- Plan step edits must land in `plan.md`
- Atomize edits must land in `prd.json`
- Configure edits must land in `config.json`
- Wizard resume data must land in `draft.json`

## Testing Expectations
- Run `bun run typecheck` after TypeScript edits
- For flow changes, verify frontend action reaches backend command and artifact update
7 changes: 7 additions & 0 deletions .cursor/rules/rust.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ globs: "**/*.rs"
- `anyhow::Result` acceptable at application boundary (src-tauri commands)
- Never `unwrap()` in `crates/ralph-core/`; acceptable in tests
- Use `?` propagation, not `match` chains for simple forwarding
- Keep command errors serializable for IPC boundaries

## Async
- Runtime: tokio (multi-thread)
Expand All @@ -21,10 +22,16 @@ globs: "**/*.rs"
- New optional fields use `#[serde(default)]`
- JSON output: `serde_json` with `to_string_pretty` for artifact files

## Persistence Contracts
- Keep metadata in SQLite through `rusqlite` and managed `DbState`
- Keep project workflow artifacts on filesystem under project directories
- Do not use `tauri-plugin-sql` for project persistence

## Testing
- Unit tests in same file (`#[cfg(test)]` module)
- Integration tests in `tests/` directory
- `#[tokio::test]` for async tests
- For flow changes, test storage, service, and command layers together where possible

## Dependencies (ralph-core)
- serde, serde_json, tokio, anyhow, thiserror, regex, chrono
Expand Down
17 changes: 10 additions & 7 deletions .cursor/rules/tauri.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ globs: "src-tauri/**/*.rs"
- Define in `src-tauri/src/commands/` module
- Use `#[tauri::command]` macro
- Return `Result<T, String>` for IPC error serialization
- Group by domain: project_commands.rs, agent_commands.rs, loop_commands.rs
- Keep command handlers thin and delegate logic to services

## Events
- Emit from backend: `app_handle.emit("event-name", payload)`
- Listen in frontend: `listen("event-name", callback)`
- Event names: kebab-case (plan-activity, agent-output-stream, iteration-started)
- Event names: kebab-case (`plan-activity`, `agent-output-stream`, `iteration-started`)

## State Management
- Use `tauri::State<Mutex<T>>` or `tauri::State<Arc<RwLock<T>>>`
Expand All @@ -28,15 +28,18 @@ globs: "src-tauri/**/*.rs"
- Track PIDs for graceful termination (SIGTERM, then SIGKILL after timeout)

## SQLite
- Use `tauri-plugin-sql` with migrations defined in Rust
- Migrations registered via `tauri_plugin_sql::Builder::default().add_migrations()`
- Database at `sqlite:loopforge.db` (resolves to AppConfig directory)
- Frontend queries via `@tauri-apps/plugin-sql` (`Database.load()`, `db.select()`, `db.execute()`)
- Permissions in `capabilities/default.json`: `sql:default`, `sql:allow-execute`, `sql:allow-select`
- Use `rusqlite` directly via `DbState`
- Do not use `tauri-plugin-sql` or `@tauri-apps/plugin-sql`
- Keep SQLite access in backend services and expose data through Tauri commands
- Store metadata in SQLite and keep artifact files on filesystem per project directory

## Shell (Agent CLI)
- Use `tauri-plugin-shell` for spawning agent CLIs
- `ShellExt` trait: `app.shell().command("claude").args([...]).spawn()`
- Returns `(Receiver<CommandEvent>, Child)` for async streaming
- `child.write(bytes)` for stdin piping
- Permissions in `capabilities/default.json`: `shell:default`

## Vertical Slice Reminder
- Add features in this order: storage, model, service, command, event, IPC binding, UI, test
- Do not ship scaffolding steps without wiring the end to end path
15 changes: 15 additions & 0 deletions .cursor/rules/templates.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
description: MiniJinja template editing conventions
globs: "src-tauri/templates/**/*.j2"
alwaysApply: false
---

# MiniJinja Template Rules

- Keep templates deterministic and data driven
- Prefer explicit variable names that match Rust struct fields
- Avoid hidden control flow and nested branching when simple conditional blocks work
- Keep prompt and output sections easy to diff across iterations
- Preserve whitespace behavior expected by downstream parsers

When template fields change, update the corresponding Rust serializer or model and verify the full atomizer pipeline.
19 changes: 19 additions & 0 deletions .cursor/rules/vertical-slice.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: Apply when adding new features or extending IPC flows
alwaysApply: false
---

# Vertical Slice Workflow

Implement feature changes in this exact order:

1. Storage schema or artifact contract
2. Rust models with serde support
3. Service logic in backend
4. Tauri command wrapper
5. Event and stream wiring if needed
6. Frontend IPC binding in `src/lib/tauri.ts`
7. UI integration
8. Tests proving end to end behavior

Do not ship partial scaffolding. Each step depends on the previous step being wired and verified.
22 changes: 22 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8

[*.{ts,tsx,js,json,css,html}]
indent_style = space
indent_size = 2

[*.rs]
indent_style = space
indent_size = 4

[*.toml]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
34 changes: 26 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,29 @@
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
run: npm install -g bun@1.3.10

- name: Install frontend dependencies
run: bun install

- name: TypeScript check
run: bun run typecheck

lint:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Setup Bun
run: npm install -g bun@1.3.10

- name: Install frontend dependencies
run: bun install

- name: Biome lint
run: bun run lint

build:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -70,18 +84,14 @@
node-version: lts/*

- name: Setup Bun
uses: oven-sh/setup-bun@v2
run: npm install -g bun@1.3.10

- name: Install frontend dependencies
run: bun install

- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tauriScript: bunx tauri
args: ${{ matrix.args }}
shell: bash
run: bunx tauri build ${{ matrix.args }} --config '{"bundle":{"createUpdaterArtifacts":false}}'

rust-tests:
runs-on: ubuntu-22.04
Expand All @@ -90,6 +100,8 @@

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt

- name: Rust cache
uses: swatinem/rust-cache@v2
Expand All @@ -101,3 +113,9 @@

- name: Run tests
run: cargo test

- name: Rust format check
run: cargo fmt --all -- --check

- name: Rust clippy
run: cargo clippy --workspace -- -D warnings
Loading
Loading