Skip to content

feat(dashboard): add multi-level repo shell with searchable loop navigation - #75

Merged
chriswritescode-dev merged 7 commits into
mainfrom
feat/dashboard-repo-shell
Jul 27, 2026
Merged

feat(dashboard): add multi-level repo shell with searchable loop navigation#75
chriswritescode-dev merged 7 commits into
mainfrom
feat/dashboard-repo-shell

Conversation

@chriswritescode-dev

@chriswritescode-devchriswritescode-dev commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces the flat dashboard loop list with a three-level shell: a repository index, a per-repo view with Loops/Groups/Findings/Plans sections, and a per-loop detail with tabs. Adds a searchable loop picker in the breadcrumb and recency-ordered prev/next navigation that share the same loop ordering.

Key changes

  • src/dashboard/app/app.ts — three-level routing shell, project/loop selection, reactive store over the dashboard payload, breadcrumb with the loop picker.
  • src/dashboard/app/components.ts — Breadcrumb, LoopPicker combobox, FilterBar, RepoMenu, RepoIndexPane, SectionNav, LoopTable, LoopDetail, GroupsPanel, GroupDetail, FindingsPanel, PlansPanel, TabBar.
  • src/dashboard/app/helpers.ts — hash routing parse/build, repo label disambiguation, sorting, formatters, status classes.
  • src/dashboard/render.ts — full CSS restyle using design tokens, including picker, section-nav, and tab-bar styles.
  • src/dashboard/data.ts — server-side payload builder for the new shell.
  • src/storage/repos/loop-session-usage-repo.ts — usage aggregate query support.
  • src/dashboard/app/machine-graph.ts — loop state visualization.
  • AGENTS.md — dashboard notes updated for the new shell.
  • Comprehensive tests across app-dom, app-helpers, data, render, server, and the new usage repo.

Files changed

16 files changed, 6025 insertions(+), 510 deletions(-)

Summary by CodeRabbit

  • New Features
    • Redesigned dashboard navigation with repository views, deep links, filters, groups, findings, plans, and tabbed loop details.
    • Added scoped data loading and “Showing N of M” list controls for faster, focused views.
    • Added plan authoring and editing tools with validation and structural feedback.
    • Stored plans now take priority during execution, with legacy fallback support.
    • Usage displays now include breakdowns by role and model.
  • Documentation
    • Updated dashboard, planning, API, tool, and troubleshooting guidance to reflect the new workflows.

Forgeand others added 5 commits July 26, 2026 09:51
…gation
Replace the flat dashboard loop list with a three-level shell: a repository
index, a per-repo view with Loops/Groups/Findings/Plans sections, and a
per-loop detail with tabs. Add a searchable loop picker in the breadcrumb
that lists every repo loop sorted most recent first with a timestamp,
supports type-to-filter and arrow/Enter/Escape keyboard navigation, and
preserves the active tab on jump. The recency-ordered options drive both
the picker and the prev/next pager so they agree on order. Hide the
repo-level section-nav inside a loop detail, leaving only the loop tabs.
Replace the internal scroll box with a full-height body that toggles
collapse via an accessible caret, and promote the state-machine graph
on the timeline tab out of a <details> block to always-visible.
* feat: add plan-authoring tools, capture, and structure utilities
Introduces a plan-authoring tool surface with capture and parsing
helpers, section-bootstrap and decomposer updates, plus tests across
plan-authoring, capture, structure, fences, and TUI stored-plan state.
* refactor: centralize plan-authoring tool names and plan-of-record resolution
---------
Co-authored-by: Forge <forge@example.com>
@coderabbitai

coderabbitaiBot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR introduces SQL-backed plan authoring with marker-based fallback, scoped dashboard routing and payloads, role-based usage aggregation, unified Forge database path resolution, feature-group and repository queries, updated TUI plan sourcing, refreshed styling, and extensive regression coverage.

Changes

Plan authoring and capture

Layer / File(s)Summary
Stored plan tools and capture
src/tools/plan-authoring.ts, src/services/plan-capture.ts, src/utils/marked-plan-parser.ts, src/utils/plan-structure.ts
Adds plan-write and plan-edit, stores session plans with structural reports, prioritizes stored plans, and retains fenced-aware marker capture as fallback.
Plan execution and permissions
src/tools/loop.ts, src/constants/loop.ts, src/loop/service.ts, src/index.ts, src/prompts/agents/*
Uses stored plans for execution, centralizes authoring-tool exclusions and section limits, adds the active-loop resolver, and updates architect workflow prompts.
Planning documentation and tests
README.md, docs/**, test/tools/plan-authoring.test.ts, test/plan-capture.test.ts
Documents SQL-first planning, fallback markers, plan-tool behavior, caps, and storage precedence, with coverage for authoring and concurrency cases.

Scoped dashboard

Layer / File(s)Summary
Route and scoped data contracts
src/dashboard/app/helpers.ts, src/dashboard/data.ts, src/dashboard/server.ts
Replaces loop-only hashes with dashboard routes and query filters, scopes /api/data, removes totals, and adds groups and conditional payload materialization.
Dashboard shell and loop views
src/dashboard/app/app.ts, src/dashboard/app/components.ts
Adds repo navigation, section navigation, loop tabs, groups, findings, plans, lazy tab bodies, stable markdown nodes, phase/timeline views, and filtering controls.
Dashboard presentation and validation
src/dashboard/render.ts, src/dashboard/app-bundle.ts, test/dashboard/*
Adds theme variables and new component styling, regenerates the client bundle, and expands routing, scoped-fetch, DOM identity, data, and stylesheet tests.

Usage and storage integration

Layer / File(s)Summary
Role-based usage
src/loop/token-usage.ts, src/storage/repos/loop-session-usage-repo.ts, src/utils/loop-format.ts
Adds code/auditor/unknown role aggregation, deterministic ordering, per-role formatting, and cumulative usage rendering.
Repository-backed dashboard data
src/storage/repos/*, src/services/group-orchestrator.ts, src/dashboard/data.ts
Adds grouped feature, transition, plan, finding, and section queries and uses them to populate scoped dashboard fields.
Database paths and TUI reads
src/utils/opencode-paths.ts, src/dashboard/launch.ts, src/tui.tsx, src/utils/tui-client.ts, src/utils/tui-loop-store.ts
Centralizes forge.db resolution, threads configured paths through dashboard and TUI components, and reads stored plans before chat history.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.80% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly summarizes the main dashboard UI change and its searchable loop navigation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dashboard-repo-shell

Comment @coderabbitai help to get the list of available commands.

…d UI refinements (#77)
* feat(dashboard): reduce poll/render cost with leaner usage queries and UI refinements
* refactor: unify forge-db path and active-loop guards, slim dashboard payload
* Update test/utils/tui-client-stored-plan.test.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: Forge <forge@example.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
src/dashboard/data.ts (1)

199-205: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Findings/usage still fan out one query per loop in the scoped project.

bugCounts/sectionCounts were batched, but listByLoopName and getAggregate run per loop for every loop in the scoped project (only findings/usage rows are needed, and the repo-level Findings panel consumes all of them). For repos with many loops this is the dominant cost of a scoped poll every 5s. Consider batched listByProject/aggregatesByLoop variants mirroring bugCountsByLoop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/dashboard/data.ts` around lines 199 - 205, Batch scoped-project findings
and usage retrieval before the loop, replacing per-loop calls to
reviewFindingsRepo.listByLoopName and loopSessionUsageRepo.getAggregate with
project-level listByProject and aggregatesByLoop results keyed by loop name.
Preserve empty results for unscoped projects and use the precomputed values when
assigning findings and usage inside the loop.
src/tools/loop.ts (1)

489-496: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hoist formatCumulativeUsage to a static import.

The module is already statically imported for formatPostActionReport/formatAuditResult, so the three await import('../utils/loop-format') sites (here, line 599, and line 330) buy nothing and add async work on the status path.

Also applies to: 599-606

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/tools/loop.ts` around lines 489 - 496, Replace the dynamic import of
formatCumulativeUsage in the status path with a static import from
../utils/loop-format, consolidating it with the existing static imports for
formatPostActionReport and formatAuditResult. Apply the same change to the other
formatCumulativeUsage usage sites around the referenced lines, while preserving
their existing calls and behavior.
src/dashboard/render.ts (1)

270-271: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Monospace stack is duplicated instead of using var(--mono).

--mono is defined in :root but several rules still inline 'SF Mono','Fira Code',Menlo,Consolas,monospace (also at lines 343, 488, 528, 533, 544). Same drift the hex-token test guards against, just for fonts.

Also applies to: 380-381, 408-409

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/dashboard/render.ts` around lines 270 - 271, Replace the duplicated
inline monospace font stack in the CSS rules for .section-duration,
.section-attempts, and the additional affected rules with the existing
var(--mono) token. Update every referenced occurrence while preserving each
rule’s other styles unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/agents-and-commands.md`:
- Line 12: Update the auditor exclusion entries in both
docs/agents-and-commands.md:12-12 and
docs/api/_media/agents-and-commands.md:12-12 to include plan-write and plan-edit
alongside plan and plan_exit, matching the shared PLAN_AUTHORING_TOOL_NAMES deny
list. Keep the mirrored tables consistent.
In `@docs/tools.md`:
- Around line 55-57: Update the plan-edit documentation to remove the trailing
space from the inline code span containing the line-number prefix, and describe
that spacing in surrounding prose instead while preserving the documented
behavior.
In `@README.md`:
- Line 128: Update the README statement about execution being dispatched without
additional LLM calls to scope it explicitly to New session and Execute modes.
Clarify that Loop mode remains an exception and requires the architect to invoke
execute-plan, consistent with the existing Loop-mode documentation.
- Line 328: Update the README description of marker-based plan capture to state
that it is used when no stored plan was written, rather than only when
plan-write/plan-edit tools are unavailable. Preserve the existing explanation of
the forge-plan markers and automatic capture behavior.
In `@test/dashboard/app-helpers.test.ts`:
- Around line 465-476: Update the makeDash helper to include default values for
all newly required DashboardLoop fields, including hasPlan, sectionCount, and
bugCount, while preserving the existing overrides supplied through the over
parameter.
In `@test/dashboard/render.test.ts`:
- Around line 76-83: Update the static-class coverage test around
renderDashboardHtml and staticAppClassNames to render the dashboard HTML once,
then check stylesheet selectors with a class-name boundary so a class is not
considered covered by a longer prefixed class. Preserve the existing
UNSTYLED_BY_DESIGN exclusions and empty unstyled assertion.
---
Nitpick comments:
In `@src/dashboard/data.ts`:
- Around line 199-205: Batch scoped-project findings and usage retrieval before
the loop, replacing per-loop calls to reviewFindingsRepo.listByLoopName and
loopSessionUsageRepo.getAggregate with project-level listByProject and
aggregatesByLoop results keyed by loop name. Preserve empty results for unscoped
projects and use the precomputed values when assigning findings and usage inside
the loop.
In `@src/dashboard/render.ts`:
- Around line 270-271: Replace the duplicated inline monospace font stack in the
CSS rules for .section-duration, .section-attempts, and the additional affected
rules with the existing var(--mono) token. Update every referenced occurrence
while preserving each rule’s other styles unchanged.
In `@src/tools/loop.ts`:
- Around line 489-496: Replace the dynamic import of formatCumulativeUsage in
the status path with a static import from ../utils/loop-format, consolidating it
with the existing static imports for formatPostActionReport and
formatAuditResult. Apply the same change to the other formatCumulativeUsage
usage sites around the referenced lines, while preserving their existing calls
and behavior.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bb00837-a0af-43fe-afa7-17bf79c5a23c

📥 Commits

Reviewing files that changed from the base of the PR and between b4475bf and 31ad952.

📒 Files selected for processing (105)
  • AGENTS.md
  • README.md
  • docs/agents-and-commands.md
  • docs/api/README.md
  • docs/api/_media/agents-and-commands.md
  • docs/api/_media/architecture.md
  • docs/api/_media/loop-system.md
  • docs/api/_media/tools.md
  • docs/api/functions/createForgePlugin.md
  • docs/api/functions/createParentSessionLookup.md
  • docs/api/functions/createSessionDirectoryLookup.md
  • docs/api/interfaces/CompactionConfig.md
  • docs/api/interfaces/CreateParentSessionLookupOptions.md
  • docs/api/interfaces/CreateSessionDirectoryLookupOptions.md
  • docs/api/interfaces/PluginConfig.md
  • docs/api/variables/VERSION.md
  • docs/api/variables/default.md
  • docs/architecture.md
  • docs/loop-system.md
  • docs/modules.md
  • docs/tools.md
  • scripts/dashboard.ts
  • src/agents/auditor.ts
  • src/agents/code.ts
  • src/agents/feature-splitter.ts
  • src/constants/loop.ts
  • src/dashboard/app-bundle.ts
  • src/dashboard/app/app.ts
  • src/dashboard/app/components.ts
  • src/dashboard/app/helpers.ts
  • src/dashboard/app/machine-graph.ts
  • src/dashboard/app/types.ts
  • src/dashboard/data.ts
  • src/dashboard/launch.ts
  • src/dashboard/render.ts
  • src/dashboard/server.ts
  • src/hooks/plan-approval.ts
  • src/hooks/plan-capture.ts
  • src/index.ts
  • src/loop/service.ts
  • src/loop/token-usage.ts
  • src/prompts/agents/architect-auto.md
  • src/prompts/agents/architect.md
  • src/services/deterministic-decomposer.ts
  • src/services/execution.ts
  • src/services/group-orchestrator.ts
  • src/services/plan-capture.ts
  • src/services/section-bootstrap.ts
  • src/storage/database.ts
  • src/storage/index.ts
  • src/storage/repos/feature-groups-repo.ts
  • src/storage/repos/loop-session-usage-repo.ts
  • src/storage/repos/loop-transitions-repo.ts
  • src/storage/repos/plans-repo.ts
  • src/storage/repos/review-findings-repo.ts
  • src/storage/repos/section-plans-repo.ts
  • src/tools/index.ts
  • src/tools/loop.ts
  • src/tools/plan-adjust.ts
  • src/tools/plan-authoring.ts
  • src/tui.tsx
  • src/utils/format.ts
  • src/utils/logger.ts
  • src/utils/loop-format.ts
  • src/utils/markdown-fences.ts
  • src/utils/marked-plan-parser.ts
  • src/utils/opencode-paths.ts
  • src/utils/plan-execution.ts
  • src/utils/plan-from-messages.ts
  • src/utils/plan-structure.ts
  • src/utils/tui-client.ts
  • src/utils/tui-loop-store.ts
  • test/agent-tools-map.test.ts
  • test/agents.test.ts
  • test/config.test.ts
  • test/constants/loop.test.ts
  • test/dashboard/app-dom.test.ts
  • test/dashboard/app-helpers.test.ts
  • test/dashboard/data.test.ts
  • test/dashboard/launch.test.ts
  • test/dashboard/render.test.ts
  • test/dashboard/server.test.ts
  • test/deterministic-decomposer.test.ts
  • test/hooks/plan-approval-dedupe.test.ts
  • test/hooks/plan-approval-worktree-timing.test.ts
  • test/loop-format.test.ts
  • test/loop-permission-ruleset.test.ts
  • test/loop-session-usage-repo.test.ts
  • test/loop-status-tool.test.ts
  • test/loop-tool-new-session.test.ts
  • test/loop-transitions-repo.test.ts
  • test/loop/token-usage.test.ts
  • test/markdown-fences.test.ts
  • test/plan-approval.test.ts
  • test/plan-capture.test.ts
  • test/plan-structure.test.ts
  • test/plugin.test.ts
  • test/prompts/loader.test.ts
  • test/review-findings-repo.test.ts
  • test/services/group-orchestrator.test.ts
  • test/services/section-bootstrap.test.ts
  • test/tools/plan-authoring.test.ts
  • test/utils/tui-client-stored-plan.test.ts
  • test/utils/tui-stored-plan.test.ts
  • test/worktree-log.test.ts

|---|---|---|
| `code` | `all` | Primary implementation agent. |
| `architect` | `primary` | Read-only planning agent. Produces marked plans for approval and execution. |
| `architect` | `primary` | Read-only planning agent. Authors the stored plan with `plan-write`/`plan-edit` for approval and execution; marked plans in chat are still captured. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
printf'\n== Files ==\n'
git ls-files 'docs/agents-and-commands.md''docs/api/_media/agents-and-commands.md'| cat
printf'\n== Relevant mentions in docs ==\n'
rg -n 'plan-write|plan-edit|plan_exit|plan\b|AUDITOR_TOOL_EXCLUDES|PLAN_AUTHORING_TOOL_NAMES|auditor' docs/agents-and-commands.md docs/api/_media/agents-and-commands.md
printf'\n== Search repo for tool name constants ==\n'
rg -n 'PLAN_AUTHORING_TOOL_NAMES|AUDITOR_TOOL_EXCLUDES|plan-write|plan-edit|plan_exit|plan'. --glob '!docs/api/_media/agents-and-commands.md' --glob '!docs/agents-and-commands.md'

Repository: chriswritescode-dev/opencode-forge

Length of output: 50391


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo'== docs/agents-and-commands.md =='
cat -n docs/agents-and-commands.md | sed -n '1,40p'echoecho'== docs/api/_media/agents-and-commands.md =='
cat -n docs/api/_media/agents-and-commands.md | sed -n '1,40p'echoecho'== targeted source search =='
rg -n 'AUDITOR_TOOL_EXCLUDES|PLAN_AUTHORING_TOOL_NAMES|plan-adjust|plan-write|plan-edit|plan_exit|plan_enter' src test docs -g '!docs/api/_media/agents-and-commands.md' -g '!docs/agents-and-commands.md'

Repository: chriswritescode-dev/opencode-forge

Length of output: 36724


Document plan-write and plan-edit in the auditor exclusions.
Both docs still list only plan and plan_exit, but the shared auditor deny list also excludes plan-write and plan-edit via PLAN_AUTHORING_TOOL_NAMES; update the mirrored tables to match.

📍 Affects 2 files
  • docs/agents-and-commands.md#L12-L12 (this comment)
  • docs/api/_media/agents-and-commands.md#L12-L12
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/agents-and-commands.md` at line 12, Update the auditor exclusion entries
in both docs/agents-and-commands.md:12-12 and
docs/api/_media/agents-and-commands.md:12-12 to include plan-write and plan-edit
alongside plan and plan_exit, matching the shared PLAN_AUTHORING_TOOL_NAMES deny
list. Keep the mirrored tables consistent.

Source: Coding guidelines

Comment threaddocs/tools.md Outdated
Comment on lines +55 to +57
### `plan-edit`

Edits the stored session plan by exact string replacement, the same way the Edit tool edits a file. Use `plan-read` to inspect the current text first; do not include `plan-read`'s `N: ` line-number prefixes in `oldString`. Subject to the same availability and running-loop guard as `plan-write`. On success the tool rewrites the plan through the shared session-scoped write path and returns a `Replaced N occurrence(s).` line followed by a structure report.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove padding inside the inline code span.

Line 57's `N: ` violates MD038. Describe the trailing space in prose instead.

Proposed fix
- do not include `plan-read`'s `N: ` line-number prefixes in `oldString`.+ do not include `plan-read`'s `N:` line-number prefixes (including their trailing space) in `oldString`.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### `plan-edit`
Edits the stored session plan by exact string replacement, the same way the Edit tool edits a file. Use `plan-read` to inspect the current text first; do not include `plan-read`'s `N:` line-number prefixes in `oldString`. Subject to the same availability and running-loop guard as `plan-write`. On success the tool rewrites the plan through the shared session-scoped write path and returns a `Replaced N occurrence(s).` line followed by a structure report.
### `plan-edit`
Edits the stored session plan by exact string replacement, the same way the Edit tool edits a file. Use `plan-read` to inspect the current text first; do not include `plan-read`'s `N:` line-number prefixes (including their trailing space) in `oldString`. Subject to the same availability and running-loop guard as `plan-write`. On success the tool rewrites the plan through the shared session-scoped write path and returns a `Replaced N occurrence(s).` line followed by a structure report.
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 57-57: Spaces inside code span elements

(MD038, no-space-in-code)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/tools.md` around lines 55 - 57, Update the plan-edit documentation to
remove the trailing space from the inline code span containing the line-number
prefix, and describe that spacing in surrounding prose instead while preserving
the documented behavior.

Source: Linters/SAST tools

Comment threadREADME.md Outdated
**Tool restrictions:** The auditor cannot use file-editing tools, planning tools, or loop-management tools. See [Auditor restrictions](docs/agents-and-commands.md#auditor-restrictions).

The architect agent operates as a read-only planner with message-level reinforcement via the `experimental.chat.messages.transform` hook. Final plans are rendered once in the assistant response between `<!-- forge-plan:start -->` and `<!-- forge-plan:end -->` markers, then auto-captured into SQL before execution approval. After user approval via the question tool, execution is dispatched programmatically — no additional LLM calls are needed. The user can view and edit the cached plan from the sidebar or command palette before or during execution.
The architect agent operates as a read-only planner with message-level reinforcement via the `experimental.chat.messages.transform` hook. Final plans are authored straight into SQL storage with the `plan-write` and `plan-edit` tools, which return a structure report the architect uses to fix warnings before asking for approval. A plan emitted in the assistant response between `<!-- forge-plan:start -->` and `<!-- forge-plan:end -->` markers is still auto-captured into the same row, so marker-only architect prompts keep working. After user approval via the question tool, execution is dispatched programmatically — no additional LLM calls are needed. The user can view and edit the stored plan from the sidebar or command palette before or during execution.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Scope the no-extra-call claim to non-loop execution modes.

The same page says Loop mode requires the architect to invoke execute-plan (Line 348, reinforced by src/index.ts Lines 781-782). Clarify that the “no additional LLM calls” behavior applies to New session and Execute here; Loop still requires the tool call.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` at line 128, Update the README statement about execution being
dispatched without additional LLM calls to scope it explicitly to New session
and Execute modes. Clarify that Loop mode remains an exception and requires the
architect to invoke execute-plan, consistent with the existing Loop-mode
documentation.

Comment threadREADME.md Outdated
### How Plans Work

The architect is read-only and must output exactly one final planbetween `<!-- forge-plan:start -->` and `<!-- forge-plan:end -->` markers. Forge auto-captures that marked plan into SQL storage for the current session.
The architect is read-only and authors the plan into SQL storage for the current session with `plan-write`, appending further phases with `plan-write { append: true }` and revising with `plan-edit`. Every write returns a structure report — line/character counts, the detected `Loop Name:`, the sections the decomposer would emit, and warnings — so structural problems surface before approval. If those tools are unavailable, a plan emitted once between `<!-- forge-plan:start -->` and `<!-- forge-plan:end -->` markers is auto-captured into the same row.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Describe marker capture as a no-stored-plan fallback.

resolveSessionPlanOfRecord and the completion hook inspect marked messages whenever no stored plan exists; they do not check whether plan-write/plan-edit were unavailable. Replace “If those tools are unavailable” with “If no stored plan was written” or equivalent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` at line 328, Update the README description of marker-based plan
capture to state that it is used when no stored plan was written, rather than
only when plan-write/plan-edit tools are unavailable. Preserve the existing
explanation of the forge-plan markers and automatic capture behavior.

Comment on lines +465 to +476
function makeDash(over: Partial<DashboardLoop> = {}): DashboardLoop {
return {
loop: mockLoopRow(),
lastAuditResult: null,
plan: null,
sections: [],
findings: [],
usage: null,
duration: null,
...over,
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Inspect the DashboardLoop definition to confirm which fields are required.
fd -t f 'data.ts' src/dashboard --exec ast-grep outline {} --items all
rg -nP -A25 'export (interface|type) DashboardLoop\b' src/dashboard

Repository: chriswritescode-dev/opencode-forge

Length of output: 3617


makeDash needs the required DashboardLoop fields.

DashboardLoop now includes required fields like hasPlan, sectionCount, and bugCount, but this helper still returns an incomplete object. Add the missing defaults here so typechecking stays green.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/dashboard/app-helpers.test.ts` around lines 465 - 476, Update the
makeDash helper to include default values for all newly required DashboardLoop
fields, including hasPlan, sectionCount, and bugCount, while preserving the
existing overrides supplied through the over parameter.

Comment on lines +76 to +83
test('every static class the app emits has a rule in the stylesheet', () => {
const style = renderDashboardHtml().slice(0, renderDashboardHtml().indexOf('</style>'))
const unstyled = staticAppClassNames().filter(
cls => !UNSTYLED_BY_DESIGN.has(cls) && !style.includes('.' + cls),
)

expect(unstyled).toEqual([])
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Prefix substring match makes the guard leaky.

style.includes('.' + cls) matches any longer selector sharing the prefix, so tab-body is "covered" by .tab-bodies and finding by .findings-panel. Match on a class-name boundary instead. Also renderDashboardHtml() is invoked twice here — hoist it like the other tests do.

💚 Boundary-aware match
 test('every static class the app emits has a rule in the stylesheet', () => {
- const style = renderDashboardHtml().slice(0, renderDashboardHtml().indexOf('</style>'))- const unstyled = staticAppClassNames().filter(- cls => !UNSTYLED_BY_DESIGN.has(cls) && !style.includes('.' + cls),- )+ const html = renderDashboardHtml()+ const style = html.slice(html.indexOf('<style>'), html.indexOf('</style>'))+ const unstyled = staticAppClassNames().filter(+ cls =>+ !UNSTYLED_BY_DESIGN.has(cls) &&+ !new RegExp(`\\.${cls.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')}(?![\\w-])`).test(style),+ )
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('every static class the app emits has a rule in the stylesheet',()=>{
conststyle=renderDashboardHtml().slice(0,renderDashboardHtml().indexOf('</style>'))
constunstyled=staticAppClassNames().filter(
cls=>!UNSTYLED_BY_DESIGN.has(cls)&&!style.includes('.'+cls),
)
expect(unstyled).toEqual([])
})
test('every static class the app emits has a rule in the stylesheet',()=>{
consthtml=renderDashboardHtml()
conststyle=html.slice(html.indexOf('<style>'),html.indexOf('</style>'))
constunstyled=staticAppClassNames().filter(
cls=>
!UNSTYLED_BY_DESIGN.has(cls)&&
!newRegExp(`\\.${cls.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')}(?![\\w-])`).test(style),
)
expect(unstyled).toEqual([])
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/dashboard/render.test.ts` around lines 76 - 83, Update the static-class
coverage test around renderDashboardHtml and staticAppClassNames to render the
dashboard HTML once, then check stylesheet selectors with a class-name boundary
so a class is not considered covered by a longer prefixed class. Preserve the
existing UNSTYLED_BY_DESIGN exclusions and empty unstyled assertion.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 7 file(s) based on 6 unresolved review comments.

Files modified:

  • README.md
  • docs/agents-and-commands.md
  • docs/api/_media/agents-and-commands.md
  • docs/api/_media/tools.md
  • docs/tools.md
  • test/dashboard/app-helpers.test.ts
  • test/dashboard/render.test.ts

Commit:5015afe99f6b9c5a105d04b6e128c7caf4968914

The changes have been pushed to the feat/dashboard-repo-shell branch.

Time taken:5m 34s

Fixed 7 file(s) based on 6 unresolved review comments.
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@chriswritescode-dev