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
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,6 +23,8 @@
- Keep the section-summary markers in `src/prompts/agents/auditor-loop-addendum.md` synchronized with the constants in `src/utils/section-summary.ts`.
- `MAX_TOTAL_SECTIONS` in `src/constants/loop.ts` is the single section cap; the decomposer, section bootstrap, plan structure summary, TUI inline plan preview and `plan-adjust` all read it, and the architect system reminder in `src/index.ts` interpolates it. `src/prompts/agents/architect.md` is prose and repeats the number literally — update it when the cap changes.
- `PLAN_AUTHORING_TOOL_NAMES` in `src/constants/loop.ts` is the single list of plan-authoring tools; the `code`, `auditor`, and `feature-splitter` tool-exclude lists and both permission rulesets derive their deny entries from it.
- `LoopService.resolveActiveLoopForSession` is the only correct "is this session inside a running loop" check. `resolveLoopName` matches terminated loops too, so using it as an activity guard blocks a session forever after its loop ends.
- `resolveForgeDbPath` in `src/utils/opencode-paths.ts` is the only place `<dataDir>/forge.db` is built; every entry point must route through it so a configured `dataDir` is honoured uniformly.

## Dashboard and storage gotchas

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,9 @@ All endpoints are read-only (non-GET requests return 404):
| Endpoint | Description |
|----------|-------------|
| `GET /` | HTML page (inlined SolidJS app) |
| `GET /api/data` | JSON snapshot of Forge loop/project state |
| `GET /api/data` | JSON snapshot of Forge loop/project state. Accepts optional `project` and `loop` query parameters (`/api/data?project=<projectId>&loop=<loopName>`) to scope the payload: per-loop text (`plan`, `goal`, `lastAuditResult`, `postActionReport`, `sections`, `amendments`) is materialised only for the scoped loop, and `findings` rows, `usage`, and `transitions` only for the scoped project. `duration`, `hasPlan`, `sectionCount`, and `bugCount` are always populated so the repo index, tab set, and section/bug counts render correctly while detail is in flight. |

In the browser, the loop table, repo findings list, plans list, and loop picker cap their rendered rows behind a "Showing N of M" affordance (a "Show all" toggle expands the loop table, findings, and plans lists).

## Screenshots

Expand DownExpand Up@@ -403,7 +405,7 @@ Audit findings survive session rotation via the **review store**. The auditor st

### Usage Tracking

Loop sessions rotate between code and auditor work, so Forge persists per-session usage rows in `loop_session_usage` and merges them for `loop-status`. Detailed status includes cumulative cost, input/output/reasoning/cache token totals, per-model breakdowns, and live active-session output when available.
Loop sessions rotate between code and auditor work, so Forge persists per-session usage rows in `loop_session_usage` and merges them for `loop-status`. Detailed status includes cumulative cost, input/output/reasoning/cache token totals, per-model breakdowns, a per-role (`code`/`auditor`/`unknown`) breakdown, and live active-session output when available.

### Worktree Isolation

Expand Down
6 changes: 4 additions & 2 deletions docs/api/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,9 @@ All endpoints are read-only (non-GET requests return 404):
| Endpoint | Description |
|----------|-------------|
| `GET /` | HTML page (inlined SolidJS app) |
| `GET /api/data` | JSON snapshot of Forge loop/project state |
| `GET /api/data` | JSON snapshot of Forge loop/project state. Accepts optional `project` and `loop` query parameters (`/api/data?project=<projectId>&loop=<loopName>`) to scope the payload: per-loop text (`plan`, `goal`, `lastAuditResult`, `postActionReport`, `sections`, `amendments`) is materialised only for the scoped loop, and `findings` rows, `usage`, and `transitions` only for the scoped project. `duration`, `hasPlan`, `sectionCount`, and `bugCount` are always populated so the repo index, tab set, and section/bug counts render correctly while detail is in flight. |

In the browser, the loop table, repo findings list, plans list, and loop picker cap their rendered rows behind a "Showing N of M" affordance (a "Show all" toggle expands the loop table, findings, and plans lists).

## Screenshots

Expand DownExpand Up@@ -405,7 +407,7 @@ Audit findings survive session rotation via the **review store**. The auditor st

### Usage Tracking

Loop sessions rotate between code and auditor work, so Forge persists per-session usage rows in `loop_session_usage` and merges them for `loop-status`. Detailed status includes cumulative cost, input/output/reasoning/cache token totals, per-model breakdowns, and live active-session output when available.
Loop sessions rotate between code and auditor work, so Forge persists per-session usage rows in `loop_session_usage` and merges them for `loop-status`. Detailed status includes cumulative cost, input/output/reasoning/cache token totals, per-model breakdowns, a per-role (`code`/`auditor`/`unknown`) breakdown, and live active-session output when available.

### Worktree Isolation

Expand Down
4 changes: 2 additions & 2 deletions docs/api/_media/loop-system.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -132,7 +132,7 @@ Loop usage is captured across rotated code and auditor sessions so `loop-status`
- `loop-status <name>` merges persisted rows with the currently live session output while avoiding double-counting the active session.
- When no loops are active, `loop-status` can still show cumulative usage for completed loops that have persisted usage data.

Tracked token buckets are input, output, reasoning, cache read, and cache write, plus cost and assistant message count.
Tracked token buckets are input, output, reasoning, cache read, and cache write, plus cost and assistant message count. Totals are reported three ways: overall, per model, and per role (`code`, `auditor`, `unknown`) derived from the `role` column, so execution and audit spend can be compared for the same loop.

## Stall Detection

Expand DownExpand Up@@ -217,7 +217,7 @@ In user-facing language, a plan is decomposed into **milestones** — ordered un
- `<!-- forge-section -->` markers in the architect plan output
- `section-read` tool reads the current or specified milestone

Decomposition is a one-shot preprocessing step at loop start (`services/deterministic-decomposer.ts`), not a runtime loop phase. Once milestones exist, the loop advances through them via `advance-section` transitions inside the `auditing` phase. When the `final_auditing` phase reports outstanding bug findings, the loop rotates to a coding session in the persisted `final_audit_fix` phase — the code agent fixes the reported findings without rewinding to a specific section, and on idle the loop transitions straight back to `final_auditing` for re-verification. A loop stopped mid-fix restarts as a coding pass that re-sends the final-audit fix prompt (rebuilt from the persisted `lastAuditResult`).
Decomposition is a one-shot preprocessing step at loop start (`services/deterministic-decomposer.ts`), not a runtime loop phase. A plan is capped at `MAX_TOTAL_SECTIONS` (24) executed milestones; markers past the cap are dropped rather than merged, so the tail of an over-long plan is not executed. The same constant caps `plan-adjust` amendments, so a plan can never grow past it mid-loop. Once milestones exist, the loop advances through them via `advance-section` transitions inside the `auditing` phase. When the `final_auditing` phase reports outstanding bug findings, the loop rotates to a coding session in the persisted `final_audit_fix` phase — the code agent fixes the reported findings without rewinding to a specific section, and on idle the loop transitions straight back to `final_auditing` for re-verification. A loop stopped mid-fix restarts as a coding pass that re-sends the final-audit fix prompt (rebuilt from the persisted `lastAuditResult`).

### Plan Amendments

Expand Down
2 changes: 1 addition & 1 deletion docs/api/functions/createForgePlugin.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

> **createForgePlugin**(`config`): `Plugin`

Defined in: [index.ts:199](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L199)
Defined in: [index.ts:200](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L200)

Creates an OpenCode plugin instance with loop management and sandboxing.

Expand Down
2 changes: 1 addition & 1 deletion docs/api/functions/createParentSessionLookup.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

> **createParentSessionLookup**(`__namedParameters`): (`sessionId`) => `Promise`\<`string` \| `null`\>

Defined in: [index.ts:53](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L53)
Defined in: [index.ts:54](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L54)

## Parameters

Expand Down
2 changes: 1 addition & 1 deletion docs/api/functions/createSessionDirectoryLookup.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

> **createSessionDirectoryLookup**(`__namedParameters`): (`sessionId`) => `Promise`\<`string` \| `null`\>

Defined in: [index.ts:134](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L134)
Defined in: [index.ts:135](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L135)

## Parameters

Expand Down
6 changes: 3 additions & 3 deletions docs/api/interfaces/CompactionConfig.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@

# Interface: CompactionConfig

Defined in: [types.ts:152](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/types.ts#L152)
Defined in: [types.ts:152](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/types.ts#L152)

Configuration for session compaction behavior.

Expand All@@ -16,7 +16,7 @@ Configuration for session compaction behavior.

> `optional` **customPrompt?**: `boolean`

Defined in: [types.ts:154](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/types.ts#L154)
Defined in: [types.ts:154](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/types.ts#L154)

Use a custom compaction prompt.

Expand All@@ -26,6 +26,6 @@ Use a custom compaction prompt.

> `optional` **maxContextTokens?**: `number`

Defined in: [types.ts:156](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/types.ts#L156)
Defined in: [types.ts:156](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/types.ts#L156)

Maximum context tokens for compaction.
12 changes: 6 additions & 6 deletions docs/api/interfaces/CreateParentSessionLookupOptions.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,31 +6,31 @@

# Interface: CreateParentSessionLookupOptions

Defined in: [index.ts:43](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L43)
Defined in: [index.ts:44](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L44)

## Properties

### client

> **client**: `ForgeClient`

Defined in: [index.ts:44](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L44)
Defined in: [index.ts:45](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L45)

***

### directory

> **directory**: `string`

Defined in: [index.ts:45](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L45)
Defined in: [index.ts:46](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L46)

***

### logger

> **logger**: `object`

Defined in: [index.ts:47](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L47)
Defined in: [index.ts:48](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L48)

#### debug

Expand DownExpand Up@@ -92,12 +92,12 @@ Defined in: [index.ts:47](https://github.com/chriswritescode-dev/opencode-forge/

> **loop**: `Loop`

Defined in: [index.ts:46](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L46)
Defined in: [index.ts:47](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L47)

***

### negativeTtlMs?

> `optional` **negativeTtlMs?**: `number`

Defined in: [index.ts:48](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L48)
Defined in: [index.ts:49](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L49)
8 changes: 4 additions & 4 deletions docs/api/interfaces/CreateSessionDirectoryLookupOptions.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,28 +6,28 @@

# Interface: CreateSessionDirectoryLookupOptions

Defined in: [index.ts:128](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L128)
Defined in: [index.ts:129](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L129)

## Properties

### client

> **client**: `ForgeClient`

Defined in: [index.ts:129](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L129)
Defined in: [index.ts:130](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L130)

***

### directory

> **directory**: `string`

Defined in: [index.ts:130](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L130)
Defined in: [index.ts:131](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L131)

***

### loop

> **loop**: `Loop`

Defined in: [index.ts:131](https://github.com/chriswritescode-dev/opencode-forge/blob/7692f27202f2fb152720f5d5c2214b0908746dbb/src/index.ts#L131)
Defined in: [index.ts:132](https://github.com/chriswritescode-dev/opencode-forge/blob/e558f4d5bbe13223fcc02388824eb728b08e9520/src/index.ts#L132)
Loading