chore: add ion package, codesight wiki, work plans, ascli config
New @boocode/ion package (v0.0.1) for inference optimization network. .codesight/ wiki artifacts for codebase documentation. .omo/ work plans for openspec cleanup and enhanced file panel.
This commit is contained in:
89
.omo/drafts/openspec-cleanup.md
Normal file
89
.omo/drafts/openspec-cleanup.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Draft: openspec-cleanup
|
||||
|
||||
## Cross-Reference: Git Tags vs openspec Batches
|
||||
|
||||
### Archived Stub Files — Tag Verification
|
||||
|
||||
| Stub File | Claims Version | Actual Tag | Verdict |
|
||||
|---|---|---|---|
|
||||
| `v1.13.12-skills-audit.md` (57B) | v1.13.12 | `v1.13.14-skills-audit` | **WRONG** — off by 2 versions |
|
||||
| `v1.13.15-codecontext-synth.md` (62B) | v1.13.15 | `v1.13.15-codecontext-synth` | ✅ correct |
|
||||
| `v1.13.17-cross-repo-reads.md` (61B) | v1.13.17 | `v1.13.17-cross-repo-reads` | ✅ correct |
|
||||
| `v1.13.18-codecontext-file-path.md` (66B) | v1.13.18 | `v1.13.18-codecontext-file-path` | ✅ correct |
|
||||
| `v1.13.20-drop-legacy-cols.md` (61B) | v1.13.20 | `v1.13.20-drop-legacy-cols` | ✅ correct |
|
||||
| `v1.14-outer-loop.md` (52B) | v1.14 | `v1.14.0-outer-loop` | ⚠️ close (1.14 → 1.14.0) |
|
||||
| `v1.14.1-mcp-poc.md` (51B) | v1.14.1 | `v1.14.1-mcp-poc` | ✅ correct |
|
||||
| `v1.14.x-html-artifact-panes.md` (63B) | v1.14.x | `v1.13.19-html-artifact-panes` | **WRONG** — shipped as 1.13.19 |
|
||||
| `v1.15-mcp-multi.md` (51B) | v1.15 | `v1.15.0-mcp-multi` | ⚠️ close (1.15 → 1.15.0) |
|
||||
| `v2.0-boocoder.md` (49B) | v2.0 | `v2.0.0` | ⚠️ close (2.0 → 2.0.0) |
|
||||
| `v2.2-paseo-providers.md` (222B) | v2.2 | `v2.2-paseo-providers` | ✅ correct |
|
||||
|
||||
### Archived Folder Entries — Tag Verification
|
||||
|
||||
| Archived Folder | Git Tag(s) | Status |
|
||||
|---|---|---|
|
||||
| `agent-status-normalize/` | `v2.7.6-agent-status-normalize` | ✅ shipped |
|
||||
| `claude-sdk-sessionstore/` | `v2.7.5-claude-sdk-sessionstore` | ✅ shipped |
|
||||
| `contracts-ssot/` | `v2.7.13-contracts-ssot` | ✅ shipped |
|
||||
| `license-debt-mit/` | `v2.7.0-mit` | ✅ shipped |
|
||||
| `mistake-tracker-file-ledger/` | `v2.7.4-mistake-tracker-ledger` | ✅ shipped (slug differs slightly) |
|
||||
| `orchestrator/` | `v2.7.17-orchestrator` | ✅ shipped |
|
||||
| `sampling-streamjson-tokens/` | `v2.7.3-sampling-streamjson-tokens` | ✅ shipped |
|
||||
| `v2-3-provider-lifecycle/` | `v2.5.4-*` through `v2.5.13-*` | ✅ shipped (diff version numbering) |
|
||||
| `v2-6-persistent-agent-sessions/` | `v2.6.4-*`, `v2.6.8-*` | ✅ shipped |
|
||||
| `write-edit-robustness/` | `v2.7.1-write-edit-robustness` | ✅ shipped |
|
||||
|
||||
### Misplaced Proposals in Archived/
|
||||
|
||||
| 2026-06-07 Folder | Git Tag? | Actually Shipped? | Should Be |
|
||||
|---|---|---|---|
|
||||
| `2026-06-07-boocontext/` | **None** | No | `changes/boocontext/` (partly shipped in v2.8.0) |
|
||||
| `2026-06-07-eval-sandbox-agent-runtime/` | **None** | No | Merge into `changes/import-*` |
|
||||
| `2026-06-07-hybrid-workflow-engine/` | **None** | No | Merge into `changes/orchestrator-flow-advanced/` |
|
||||
| `2026-06-07-memory-context-engineering/` | **None** | No | Merge into `changes/memory-context/` |
|
||||
| `2026-06-07-port-audit-parlant-patterns/` | **None** | No | Merge into `changes/add-behavioral-engine/` |
|
||||
|
||||
## Active Batches — All Uncommitted, All Unshipped
|
||||
|
||||
All 22 active batches (changes/*/) have **zero** git tags or commits referencing them. Every batch was created locally on 2026-06-07 and exists only on the filesystem.
|
||||
|
||||
## High-Value Prioritization (for Implementation Plan)
|
||||
|
||||
### Tier 1: Ship in Current Batch (small scope, high value)
|
||||
1. **openspec-cleanup** — Fix folder structure: delete stubs, move misplaced proposals, add .openspec.yaml, populate config.yaml
|
||||
2. **llama-cache-and-spec** — KV cache quantization + ngram speculative decoding (llama-server arg changes only)
|
||||
3. **results-page** — New `/results` route, uses existing API endpoints
|
||||
4. **token-analyzer-ui** — New `/analytics` route, uses existing DB data
|
||||
|
||||
### Tier 2: Current+ Batch (moderate scope)
|
||||
5. **enhanced-file-panel** — Side-by-side diff, inline comments, in-browser editing
|
||||
6. **pty-enhancements** — Exit notifications, session metadata, X-Agent-Flags
|
||||
|
||||
### Tier 3: Next Batch (larger scope, foundation work)
|
||||
7. **memory-v2-hybrid-search** — BM25 + local embedding hybrid search
|
||||
8. **orchestrator-flow-advanced** — Trigger rules, conditional branching, HITL
|
||||
9. **omo-paseo-bridge** — OMO subagent visibility in Paseo
|
||||
|
||||
### Tier 4: Future Batches (speculative / big effort)
|
||||
10. **add-behavioral-engine** / **audit-harness-integration** / **import-llm-evaluator** / **import-pregel-engine** — Big integration efforts
|
||||
11. **code-intelligence-upgrade** / **dev-workflow** / **conductor-evolution** — Platform work
|
||||
12. **plugin-platform** / **ui-overhaul** / **add-3tier-memory** / **add-type-inject-mcp** — Future
|
||||
|
||||
## Scope Boundaries for This Plan
|
||||
|
||||
**IN SCOPE:**
|
||||
- Delete 11 stub files from archived/
|
||||
- Move 5 misplaced 2026-06-07 proposals from archived/ to changes/ (with dedup)
|
||||
- Add missing .openspec.yaml to 6 active batches
|
||||
- Populate openspec/config.yaml with project context
|
||||
- Implement Tier 1-2 high-value batches:
|
||||
- llama-cache-and-spec (llama-server args)
|
||||
- results-page (new route, frontend)
|
||||
- token-analyzer-ui (new route, frontend + backend)
|
||||
- enhanced-file-panel (frontend changes)
|
||||
- pty-enhancements (backend changes)
|
||||
|
||||
**OUT OF SCOPE:**
|
||||
- Tier 3-4 batches (future planning)
|
||||
- Full behavioral engine or Pregel state machine integration
|
||||
- Plugin platform architecture
|
||||
485
.omo/plans/enhanced-file-panel.md
Normal file
485
.omo/plans/enhanced-file-panel.md
Normal file
@@ -0,0 +1,485 @@
|
||||
# Enhanced File Panel — Implementation Plan
|
||||
|
||||
## TL;DR
|
||||
|
||||
> **Quick Summary**: Add side-by-side diff, hide whitespace, wrap lines, expand all files, inline diff comments, and in-browser file editing to BooCode's right-rail file panel.
|
||||
>
|
||||
> **Deliverables**:
|
||||
> - Enhanced `GitDiffView.tsx` with toolbar (layout/whitespace/wrap/expand-all toggles)
|
||||
> - Split-layout diff renderer (side-by-side)
|
||||
> - `useDiffPreferences` hook (localStorage persistence)
|
||||
> - Inline diff comment components + Zustand store
|
||||
> - File editing mode in file tree + server write endpoint
|
||||
> - Server `git diff -w` support
|
||||
>
|
||||
> **Estimated Effort**: Medium-Large
|
||||
> **Parallel Execution**: YES — 4 waves
|
||||
> **Critical Path**: Wave 1 (server) → Wave 2 (diff preferences + toolbar) → Wave 3 (split layout) → Wave 4 (comments + editing)
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
### Original Request
|
||||
User wants to implement these features from Paseo into BooCode's file manager:
|
||||
1. Unified diff ✅ (exists) / Side by side diff ❌
|
||||
2. Hide whitespace ❌
|
||||
3. Wrap long lines ❌
|
||||
4. Expand all files ❌ (only per-file)
|
||||
5. Refresh ✅ (exists)
|
||||
6. Comments on specific diffs ❌
|
||||
7. File edits (editing in the file browser) ❌
|
||||
|
||||
### Research Findings
|
||||
- **Paseo** (`/opt/forks/paseo`): Best reference for all features. Key files: `diff-pane.tsx`, `diff-layout.ts`, `diff-rendering.ts`, `review/surface.tsx`, `review/store.ts`, `use-changes-preferences/`
|
||||
- **Existing BooCode files**: `GitDiffView.tsx`, `RightRail.tsx`, `useGitDiff.ts`, `git_diff.ts`, `FileViewerOverlay.tsx`
|
||||
- Key insight: None of the web references have true inline file editing in the browser — this is new ground
|
||||
|
||||
---
|
||||
|
||||
## Work Objectives
|
||||
|
||||
### Core Objective
|
||||
Augment the existing file panel with side-by-side diff, whitespace/wrap/expand toggles, inline comments, and inline file editing.
|
||||
|
||||
### Definition of Done
|
||||
- [x] `pnpm -C apps/web build` succeeds with no errors
|
||||
- [x] `pnpm -C apps/server build` succeeds with no errors
|
||||
- [ ] Side-by-side diff renders correctly (two aligned columns)
|
||||
- [ ] Hide whitespace toggles and re-fetches diff
|
||||
- [ ] Wrap lines toggles between pre / pre-wrap
|
||||
- [ ] Expand/Collapse all toggles all file diffs
|
||||
- [ ] Inline comments: click gutter → type → save → display thread
|
||||
- [ ] File edit: double-click tree → edit → save → file changes on disk
|
||||
- [ ] All preferences persist across page refresh
|
||||
|
||||
### Must Have
|
||||
- Side-by-side diff view
|
||||
- Hide whitespace toggle (server param)
|
||||
- Wrap long lines toggle (CSS)
|
||||
- Expand/Collapse all file diffs
|
||||
- Inline diff comments with thread UI
|
||||
- In-browser file editing with save
|
||||
- Preference persistence
|
||||
|
||||
### Must NOT Have (Guardrails)
|
||||
- No DB migration (comments are client-side)
|
||||
- No new WS frames (reuse git_diff_refresh)
|
||||
- No new `@boocode/contracts` types
|
||||
- No multi-user comment sharing
|
||||
- No git push/pull/PR operations
|
||||
- No inline hunk staging
|
||||
|
||||
---
|
||||
|
||||
## Verification Strategy
|
||||
|
||||
### Test Decision
|
||||
- **Infrastructure exists**: YES (vitest for server)
|
||||
- **Automated tests**: Tests-after for new server route + `git_diff.ts` changes
|
||||
- **Agent-Executed QA**: Playwright for diff interactions, curl for API endpoints
|
||||
|
||||
### QA Policy
|
||||
Every task includes agent-executed scenarios. Evidence saved to `.omo/evidence/`.
|
||||
|
||||
---
|
||||
|
||||
## Execution Strategy
|
||||
|
||||
### Waves
|
||||
|
||||
```
|
||||
Wave 1 (Server — foundation):
|
||||
├── Task 1: Server: whitespace param in git_diff.ts
|
||||
├── Task 2: Server: POST /api/projects/:id/write_file endpoint
|
||||
├── Task 3: Server tests for whitespace + write
|
||||
└── [tests + typecheck]
|
||||
|
||||
Wave 2 (Frontend — preferences + toolbar):
|
||||
├── Task 4: useDiffPreferences hook (localStorage)
|
||||
├── Task 5: GitDiffView toolbar (layout/whitespace/wrap/expand-all toggles)
|
||||
├── Task 6: Wrap lines CSS + hide whitespace re-fetch
|
||||
└── [pnpm build]
|
||||
|
||||
Wave 3 (Frontend — split layout):
|
||||
├── Task 7: Diff layout utilities (buildSplitDiffRows etc.)
|
||||
├── Task 8: Side-by-side renderer in GitDiffView
|
||||
├── Task 9: Line number gutter + alignment
|
||||
└── [pnpm build]
|
||||
|
||||
Wave 4 (Frontend — comments + file editing):
|
||||
├── Task 10: InlineComment store (Zustand + localStorage)
|
||||
├── Task 11: InlineReviewGutterCell + InlineReviewEditor
|
||||
├── Task 12: InlineReviewThread (comment display)
|
||||
├── Task 13: File editing mode in RightRail file tree
|
||||
└── [pnpm build + full smoke test]
|
||||
```
|
||||
|
||||
Critical Path: T1 → T2 → T4 → T5 → T7 → T8 → T10 → T11 → T12 → T13
|
||||
|
||||
---
|
||||
|
||||
## TODOs
|
||||
|
||||
- [x] 1. **Server: Add `ignoreWhitespace` param to git diff**
|
||||
|
||||
**What to do**:
|
||||
- In `apps/server/src/services/git_diff.ts`, add `ignoreWhitespace?: boolean` to the `getGitDiff` function signature
|
||||
- When `ignoreWhitespace` is true, append `'-w'` to the git diff argv call in `getGitDiff` (the main diff command, not name-status)
|
||||
- Update `GET /api/projects/:id/git/diff` route in `routes/projects.ts` to accept optional query param `whitespace=1`
|
||||
- The param should be optional (backward compatible) — default false
|
||||
|
||||
**Files to modify**:
|
||||
- `apps/server/src/services/git_diff.ts` — update `getGitDiff()` to accept and use `ignoreWhitespace`
|
||||
- `apps/server/src/routes/projects.ts` — add `whitespace` query param
|
||||
|
||||
**References**:
|
||||
- Paseo: `useCheckoutDiffQuery({ ignoreWhitespace })` passes to server → `git diff -w`
|
||||
- Existing `git_diff.ts:36-48` `runGit` function — argv pattern to follow
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Diff with whitespace changes respects ignoreWhitespace param
|
||||
Tool: Bash (curl)
|
||||
Preconditions: A file exists with whitespace-only changes (extra spaces)
|
||||
Steps:
|
||||
1. GET /api/projects/:id/git/diff ⇒ verify diff_body includes whitespace changes
|
||||
2. GET /api/projects/:id/git/diff?whitespace=1 ⇒ verify diff_body excludes whitespace-only changes
|
||||
Expected: With whitespace=1, files that only had whitespace changes show as unchanged
|
||||
Evidence: .omo/evidence/task-1-whitespace.txt
|
||||
```
|
||||
|
||||
- [x] 2. **Server: Add POST /api/projects/:id/write_file endpoint**
|
||||
|
||||
**What to do**:
|
||||
- Add `POST /api/projects/:id/write_file` route in `routes/projects.ts`
|
||||
- Accept `{ path: string, content: string }` body
|
||||
- Validate path via existing `pathGuard` helper (same as git discard)
|
||||
- Write file content atomically: write to `.tmp` then `rename` the file
|
||||
- Return `{ ok: boolean }` on success
|
||||
- Reuse the safe file-write pattern from `services/file_ops.ts`
|
||||
|
||||
**Files to modify**:
|
||||
- `apps/server/src/routes/projects.ts` — add POST route
|
||||
- `apps/web/src/api/client.ts` — add `writeFile` method
|
||||
- `apps/web/src/api/types.ts` — add write types if needed
|
||||
|
||||
**References**:
|
||||
- `apps/server/src/services/file_ops.ts` — existing file operations pattern
|
||||
- `apps/server/src/routes/projects.ts:544-592` — git write routes (same security pattern)
|
||||
- `apps/server/src/services/path_guard.ts` — path validation
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Write file content and verify on disk
|
||||
Tool: Bash (curl)
|
||||
Preconditions: A project exists with a writable path
|
||||
Steps:
|
||||
1. POST /api/projects/:id/write_file { path: "test.txt", content: "hello" }
|
||||
2. GET /api/projects/:id/view_file?path=test.txt
|
||||
Expected: Status 200, view_file returns "hello"
|
||||
Evidence: .omo/evidence/task-2-write.txt
|
||||
```
|
||||
|
||||
- [x] 3. **Frontend: useDiffPreferences hook**
|
||||
|
||||
**What to do**:
|
||||
- Create `apps/web/src/hooks/useDiffPreferences.ts`
|
||||
- Define `DiffPreferences` interface: `{ layout: 'unified'|'split', wrapLines: boolean, hideWhitespace: boolean }`
|
||||
- Default: `{ layout: 'unified', wrapLines: false, hideWhitespace: false }`
|
||||
- Read/write to localStorage key `boocode.diff.preferences`
|
||||
- Return `{ preferences, updatePreferences, resetPreferences }`
|
||||
- Zod-validate on read for forward compatibility
|
||||
|
||||
**Files to create/modify**:
|
||||
- Create `apps/web/src/hooks/useDiffPreferences.ts`
|
||||
|
||||
**References**:
|
||||
- `/opt/forks/paseo/packages/app/src/hooks/use-changes-preferences/storage.ts` — exact pattern
|
||||
- `apps/web/src/hooks/useProjectGit.ts` — hooks pattern in BooCode
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Preferences persist across page refresh
|
||||
Tool: Playwright
|
||||
Preconditions: Page loaded
|
||||
Steps:
|
||||
1. Call updatePreferences({ layout: 'split' })
|
||||
2. Read localStorage.getItem('boocode.diff.preferences')
|
||||
3. Reload page, read preferences again
|
||||
Expected: layout is 'split' after reload
|
||||
Evidence: .omo/evidence/task-3-prefs.txt
|
||||
```
|
||||
|
||||
- [x] 4. **Frontend: GitDiffView toolbar with all toggles**
|
||||
|
||||
**What to do**:
|
||||
- Add a toolbar row inside `GitDiffView.tsx` between the mode selector and file list
|
||||
- Controls (left to right):
|
||||
- **Layout toggle**: two-segment button (Unified | Split) — uses `AlignJustify` / `Columns2` icons
|
||||
- **Hide whitespace**: toggle button — `Pilcrow` icon, active state highlights
|
||||
- **Wrap lines**: toggle button — `WrapText` icon
|
||||
- **Expand/Collapse all**: toggle button — `ListChevronsUpDown` / `ListChevronsDownUp` icons
|
||||
- **Refresh**: existing button (already present)
|
||||
- Wire each toggle to the `useDiffPreferences` hook
|
||||
- Expand all state: compute `allExpanded = files.every(f => expandedPaths.has(f.path))`
|
||||
- Pass expand state as a new prop or local state
|
||||
|
||||
**Files to modify**:
|
||||
- `apps/web/src/components/GitDiffView.tsx` — add toolbar section, expand-all logic
|
||||
|
||||
**References**:
|
||||
- Paseo `diff-pane.tsx:1114-1273` — `DiffLayoutToggleGroup`, `DiffWhitespaceToggle`, `DiffFilesToolbar`
|
||||
- openchamber `DiffViewToggle.tsx` — simple toggle pattern
|
||||
- happy `InlineFileDiff.tsx:196-219` — `DiffStyleToggle` segment control
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: All toolbar controls render and toggle
|
||||
Tool: Playwright
|
||||
Preconditions: Git tab active with changed files
|
||||
Steps:
|
||||
1. Verify layout toggle shows "Unified" / "Split" buttons
|
||||
2. Click "Split" — verify visual change
|
||||
3. Click "Wrap" — verify wrap toggle
|
||||
4. Click "Expand all" — verify all files expand
|
||||
5. Click "Collapse all" — verify all files collapse
|
||||
Expected: Each toggle works and updates state
|
||||
Evidence: .omo/evidence/task-4-toolbar.png
|
||||
```
|
||||
|
||||
- [x] 5. **Frontend: Diff layout utilities + side-by-side renderer**
|
||||
|
||||
**What to do**:
|
||||
- Create `apps/web/src/utils/diff-layout.ts` with pure functions:
|
||||
- `buildNumberedDiffHunks(diffBody: string): NumberedDiffHunk[]` — parse diff text into hunks with old/new line numbers
|
||||
- `buildUnifiedDiffLines(file): UnifiedDiffDisplayLine[]` — existing behavior
|
||||
- `buildSplitDiffRows(file): SplitDiffRow[]` — pair removals/additions into left/right rows
|
||||
- Create `apps/web/src/components/DiffSplitView.tsx` — the side-by-side renderer:
|
||||
- Two columns (left = deletions, right = additions) with a thin divider
|
||||
- Each column has its own gutter (line numbers) + code content
|
||||
- Use Shiki `codeToHtml(language)` for syntax highlighting per side
|
||||
- Handle empty cells (unpaired lines render as blank)
|
||||
- In `GitDiffView.tsx`, when `layout === 'split'`, render `DiffSplitView` instead of the unified diff body
|
||||
|
||||
**Files to create/modify**:
|
||||
- Create `apps/web/src/utils/diff-layout.ts`
|
||||
- Create `apps/web/src/components/DiffSplitView.tsx`
|
||||
- Modify `apps/web/src/components/GitDiffView.tsx` — add layout branching
|
||||
|
||||
**References**:
|
||||
- `/opt/forks/paseo/packages/app/src/utils/diff-layout.ts` — full algorithm
|
||||
- `/opt/forks/paseo/packages/app/src/git/diff-pane.tsx:968-989` — split layout rendering
|
||||
- existing `git_diff.ts` `splitDiffByFile` — already splits unified diff per file
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Side-by-side diff renders correctly
|
||||
Tool: Playwright
|
||||
Preconditions: Git tab active, files with changes
|
||||
Steps:
|
||||
1. Click "Split" layout toggle
|
||||
2. Verify two columns appear with a divider
|
||||
3. Verify deleted lines are on left side (red background)
|
||||
4. Verify added lines are on right side (green background)
|
||||
5. Verify context lines appear on both sides, aligned
|
||||
Expected: Layout matches Paseo's split diff
|
||||
Evidence: .omo/evidence/task-5-splitdiff.png
|
||||
```
|
||||
|
||||
- [x] 6. **Frontend: Inline comment store + Zustand**
|
||||
|
||||
**What to do**:
|
||||
- Create `apps/web/src/stores/useDiffCommentStore.ts`
|
||||
- Define `DiffComment` interface: `{ id, filePath, side, lineNumber, body, createdAt, updatedAt }`
|
||||
- Create Zustand store with:
|
||||
- `commentsByKey: Map<string, DiffComment[]>` keyed by `${sessionId}:${mode}:${filePath}`
|
||||
- `addComment(key, comment)` / `updateComment(key, id, body)` / `deleteComment(key, id)`
|
||||
- `loadComments(key)` — load from localStorage
|
||||
- `persist()` — subscribe to store changes, write to localStorage key `boocode.diff.comments.[key]`
|
||||
- Export `useDiffCommentStore`
|
||||
|
||||
**Files to create**:
|
||||
- Create `apps/web/src/stores/useDiffCommentStore.ts`
|
||||
|
||||
**References**:
|
||||
- `/opt/forks/paseo/packages/app/src/review/store.ts` — zustand store for comments
|
||||
- `/opt/forks/paseo/packages/app/src/review/state.ts` — CRUD operations
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Comments persist across page refresh
|
||||
Tool: Playwright
|
||||
Preconditions: Diff panel open with changes
|
||||
Steps:
|
||||
1. Add comment on a diff line
|
||||
2. Verify comment thread appears
|
||||
3. Reload page
|
||||
4. Navigate to same diff
|
||||
Expected: Comment thread still visible after reload
|
||||
Evidence: .omo/evidence/task-6-comment-store.txt
|
||||
```
|
||||
|
||||
- [x] 7. **Frontend: InlineReviewGutterCell + InlineReviewEditor**
|
||||
|
||||
**What to do**:
|
||||
- Create `apps/web/src/components/InlineReviewGutterCell.tsx`:
|
||||
- Replaces the plain line-number display in diff rows
|
||||
- Shows line number + "+" icon on hover (to start a comment)
|
||||
- Uses `ReviewableDiffTarget { filePath, side, lineNumber }` for tracking
|
||||
- Create `apps/web/src/components/InlineReviewEditor.tsx`:
|
||||
- Textarea with placeholder "Add comment..."
|
||||
- Save (Ctrl+Enter) / Cancel (Escape) buttons
|
||||
- Animates in below the target line
|
||||
- Integrate into `GitDiffView.tsx` — gutter cells render in the diff line view
|
||||
- Wire to `useDiffCommentStore`
|
||||
|
||||
**Files to create/modify**:
|
||||
- Create `apps/web/src/components/InlineReviewGutterCell.tsx`
|
||||
- Create `apps/web/src/components/InlineReviewEditor.tsx`
|
||||
- Modify `apps/web/src/components/GitDiffView.tsx` — integrate gutter cells
|
||||
|
||||
**References**:
|
||||
- Paseo `review/surface.tsx:245-309` — `DiffGutterCell` + `InlineReviewGutterCell`
|
||||
- Paseo `InlineReviewEditor` pattern
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Create inline comment on diff line
|
||||
Tool: Playwright
|
||||
Preconditions: Git tab, file expanded
|
||||
Steps:
|
||||
1. Hover over a gutter cell
|
||||
2. Click "+" button
|
||||
3. Type comment text
|
||||
4. Click Save (or Ctrl+Enter)
|
||||
Expected: Comment thread appears below the line
|
||||
Evidence: .omo/evidence/task-7-comment-create.png
|
||||
```
|
||||
|
||||
- [x] 8. **Frontend: InlineReviewThread component**
|
||||
|
||||
**What to do**:
|
||||
- Create `apps/web/src/components/InlineReviewThread.tsx`:
|
||||
- Renders below a diff line when comments exist for that target
|
||||
- Each comment shown as a card: avatar placeholder, body, timestamp, edit/delete actions
|
||||
- Collapsed state shows comment count badge
|
||||
- Expanded state shows full thread
|
||||
- Integrate into `GitDiffView.tsx` below diff line rows
|
||||
|
||||
**Files to create/modify**:
|
||||
- Create `apps/web/src/components/InlineReviewThread.tsx`
|
||||
- Modify `apps/web/src/components/GitDiffView.tsx` — render thread below lines
|
||||
|
||||
**Reference**:
|
||||
- Paseo `review/surface.tsx:537-573` — `InlineReviewThreadContent`
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Comment thread displays and supports edit/delete
|
||||
Tool: Playwright
|
||||
Preconditions: Comments exist on a diff line
|
||||
Steps:
|
||||
1. Expand comment thread
|
||||
2. Verify comment body is visible with timestamp
|
||||
3. Click edit → modify text → save
|
||||
4. Click delete → verify comment removed
|
||||
Expected: Full CRUD works on comments
|
||||
Evidence: .omo/evidence/task-8-thread.png
|
||||
```
|
||||
|
||||
- [x] 9. **Frontend: File editing in the file tree**
|
||||
|
||||
**What to do**:
|
||||
- In `RightRail.tsx`, add a file edit mode:
|
||||
- Double-click a file in the tree (or context menu "Edit") enters edit mode
|
||||
- The file row transforms: file name becomes a monospace textarea pre-filled with file content (fetched via existing `api.projects.viewFile`)
|
||||
- The row shows Save / Cancel buttons
|
||||
- Save: calls `api.projects.writeFile(projectId, path, content)` — the new endpoint from Task 2
|
||||
- Cancel: reverts to the original content and exits edit mode
|
||||
- After save: re-fetch the file tree + emit `git_diff_refresh`
|
||||
- Only one file editable at a time (close any existing editor before opening new)
|
||||
- Visual indicator (highlighted row) when in edit mode
|
||||
|
||||
**Files to modify**:
|
||||
- `apps/web/src/components/RightRail.tsx` — add edit mode state, edit UI
|
||||
- `apps/web/src/api/client.ts` — add `writeFile` method (from Task 2)
|
||||
- `apps/web/src/components/TreeLevel.tsx` (inline in RightRail) — accept edit mode props
|
||||
|
||||
**References**:
|
||||
- Existing `RightRail.tsx:170-175` `openFile` function — pattern for file interaction
|
||||
- Existing `FileViewerOverlay.tsx` — Shiki highlighting reference
|
||||
- Paseo `file-explorer-pane.tsx` — context menu actions pattern
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: Edit file in file tree and save
|
||||
Tool: Playwright
|
||||
Preconditions: Project with a text file
|
||||
Steps:
|
||||
1. Double-click a file in the file tree
|
||||
2. Verify file enters edit mode (textarea replaces filename)
|
||||
3. Modify content
|
||||
4. Ctrl+Enter to save
|
||||
5. Verify success indicator
|
||||
Expected: File content updated on disk, tree refreshes
|
||||
Evidence: .omo/evidence/task-9-edit-save.png
|
||||
|
||||
Scenario: Cancel file edit reverts changes
|
||||
Tool: Playwright
|
||||
Preconditions: File in edit mode
|
||||
Steps:
|
||||
1. Modify content in textarea
|
||||
2. Click Cancel / press Escape
|
||||
3. Re-open file
|
||||
Expected: Original content preserved, edit mode exited
|
||||
Evidence: .omo/evidence/task-9-edit-cancel.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Final Verification
|
||||
|
||||
- [ ] F1. **Plan Compliance Audit** — `oracle`
|
||||
Verify all Must Have features are implemented, Must NOT Have are absent.
|
||||
Output: VERDICT
|
||||
|
||||
- [ ] F2. **Code Quality** — `unspecified-high`
|
||||
Run `pnpm -C apps/web build`, `pnpm -C apps/server build`, check for `as any`/`@ts-ignore`/console.log.
|
||||
Output: VERDICT
|
||||
|
||||
- [ ] F3. **Real Manual QA** — `unspecified-high` + `playwright`
|
||||
Execute all QA scenarios from every task, capture evidence.
|
||||
Output: Scenarios [N/N pass]
|
||||
|
||||
- [ ] F4. **Scope Fidelity** — `deep`
|
||||
Verify spec matches implementation, no scope creep.
|
||||
Output: Tasks [N/N compliant]
|
||||
|
||||
---
|
||||
|
||||
## Commit Strategy
|
||||
|
||||
- **1**: `feat(server): add whitespace param to git diff + write_file endpoint`
|
||||
- **2**: `feat(web): diff preferences hook, toolbar toggles, split layout`
|
||||
- **3**: `feat(web): inline diff comments with zustand store`
|
||||
- **4**: `feat(web): in-browser file editing in file tree`
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Verification Commands
|
||||
```bash
|
||||
pnpm -C apps/web build # Must pass
|
||||
pnpm -C apps/server build # Must pass
|
||||
```
|
||||
|
||||
### Final Checklist
|
||||
- [ ] Side-by-side diff renders correctly
|
||||
- [ ] Hide whitespace re-fetches with `-w`
|
||||
- [ ] Wrap lines toggles CSS
|
||||
- [ ] Expand/Collapse all toggles
|
||||
- [ ] Inline comments: create, read, update, delete
|
||||
- [ ] File editing: read, modify, save, cancel
|
||||
- [ ] All preferences survive page reload
|
||||
1015
.omo/plans/openspec-cleanup.md
Normal file
1015
.omo/plans/openspec-cleanup.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user