mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
v0.16.4
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68418e2a35 |
feat(review): add dockview center workspace (#453)
* chore(review): add dockview-react dependency * feat(review): add dockview center workspace * fix(review): stabilize diff search navigation * feat(review): add progressive file search UI * feat(review): streamline header controls * fix(review): portal annotation toolbar * refactor(review): streamline header and action menus * fix(review): make file header responsive * fix(review): align split diff drag handle * chore(review): hide review agents sidebar * fix(review): remount diff viewer on file switch * fix(review): wrap inline diff comments |
||
|
|
d8a67beb1c |
feat: agentic review — background job runner with SSE streaming (#443)
* feat(server): add agent job manager with process lifecycle and SSE streaming
Introduces the backend for agentic review — a server-agnostic job runner
that spawns agent processes, monitors their lifecycle via proc.exited, and
broadcasts status updates over a dedicated SSE stream.
New files:
- packages/shared/agent-jobs.ts: runtime-agnostic types, SSE helpers, state machine
- packages/server/agent-jobs.ts: Bun HTTP adapter with spawn/kill/SSE/REST routes
Wired into the review server with late-bound serverUrl, killAll on stop
and process exit for defense-in-depth cleanup. Capability detection via
Bun.which() for Claude Code, Codex CLI, and shell.
For provenance purposes, this commit was AI assisted.
* feat(ui): add Review Agents tab with job management and live status
Adds the client-side UI for agentic review:
- useAgentJobs hook: SSE primary with polling fallback, capabilities fetch
- AgentsTab: shared component with provider dropdown, job cards, kill controls
- ReviewAgentsIcon: magnifying glass with cog icon
- ReviewPanel: new "Review Agents" tab conditional on detected capabilities
- App.tsx: initializes hook and passes props to ReviewPanel
Jobs show live elapsed time, status badges, annotation counts per source,
and expandable error details. Stub command (sleep 10-30s) for initial testing.
For provenance purposes, this commit was AI assisted.
* fix(server): narrow proc.stderr type to satisfy TS
Bun types proc.stderr as ReadableStream | number. Add typeof guard
to narrow before passing to Response constructor.
For provenance purposes, this commit was AI assisted.
* fix(server): prevent stdout deadlock, stderr pipe stall, and worktree cwd mismatch
- Change stdout from "pipe" to "ignore" — agents post findings via the
annotations API, not stdout. Unconsumed pipe buffer caused deadlock.
- Drain stderr continuously instead of reading after exit — prevents
pipe-full stall on chatty agents.
- Make agent getCwd worktree-aware using the same currentDiffType check
the AI endpoints use, so agents spawn in the correct checkout.
- Exclude 'agents' tab from PR context fetch guard in ReviewPanel.
For provenance purposes, this commit was AI assisted.
* feat(pi): mirror agent-job endpoints in Pi review server
Add apps/pi-extension/server/agent-jobs.ts — a Node.js port of the Bun
agent-jobs handler using child_process.spawn, res.write() SSE, and
execFileSync for capability detection.
Wire into serverReview.ts: route delegation, killAll in stop(),
process.on("exit") guard, worktree-aware getCwd, and serverUrl
late-binding. Add agent-jobs to vendor.sh for shared type vendoring.
For provenance purposes, this commit was AI assisted.
* fix(agents): harden agent jobs — listener leak, provider allowlist, Windows support, docs
- Use process.once instead of process.on to prevent exit listener accumulation
- Validate provider against known capabilities before spawning (rejects unknown providers)
- Use platform-aware which/where for CLI detection on Windows
- Broadcast jobs:cleared event from kill-all endpoint (was dead client code)
- Document all /api/agents/* endpoints in CLAUDE.md Review Server table
For provenance purposes, this commit was AI assisted.
* fix(agents): SSE ref reset, jobs:cleared divergence, exit listener cleanup
- Reset receivedSnapshotRef/fallbackRef on re-mount so polling fallback
activates correctly on subsequent tab switches
- Remove jobs:cleared broadcast from kill-all — killAll() already fires
individual job:completed events, so the UI shows status transitions
instead of going blank
- Store exit handler ref so stop() can removeListener, preventing
accumulation in long-lived hosts (OpenCode, Pi)
For provenance purposes, this commit was AI assisted.
|
||
|
|
4627f75426 |
feat: external annotations API with real-time SSE (#400)
Adds a general-purpose External Annotations API that allows external programs (linters, AI tools, security scanners) to push annotations into a live Plannotator session via HTTP, with real-time delivery over SSE. ## What's included - **Shared core** (`packages/shared/external-annotation.ts`): types, in-memory store, input validation, SSE serialization - **Server handlers**: Bun + Pi implementations with full CRUD (GET/POST/PATCH/DELETE) + SSE streaming - **Client hook** (`useExternalAnnotations`): EventSource with polling fallback, optimistic updates - **Editor integration**: two-array state model (local + external), content-aware dedup, ID-based routing - **Persistence**: source field preserved through share URLs and crash-recovery drafts - **Docs**: new Integrations category with API overview page, updated API reference ## API surface All three servers (plan, review, annotate) expose: - `GET /api/external-annotations/stream` - SSE stream - `GET /api/external-annotations` - JSON snapshot (polling fallback) - `POST /api/external-annotations` - Add annotations (single or batch) - `PATCH /api/external-annotations?id=` - Update fields - `DELETE /api/external-annotations` - Remove by id, source, or clear all For provenance purposes, this commit was AI assisted. |
||
|
|
a278fdaf77 |
feat: plan archive browser (#369)
* feat: plan archive browser with in-session sidebar tab (#362) Add `plannotator archive` subcommand and archive sidebar tab for browsing saved plan decisions from ~/.plannotator/plans/. Plans show approved/denied badges and timestamps. In-session mode uses the linked doc overlay pattern so users can reference old plans while reviewing a current one. - New archive server (packages/server/archive.ts) following annotate pattern - New ArchiveBrowser sidebar component, reusable in both contexts - Archive listing/parsing functions in storage.ts (reads decision snapshots) - Archive endpoints on plan server for in-session use (/api/archive/plans) - Remove dead "Other Plans" UI, projectPlans state, /api/plan/history endpoint - Fix resize handle touch area covering scrollbars in sidebar/main content - Fix sidebar tab bar overflow when narrow For provenance purposes, this commit was AI assisted. * fix: code quality sweep for plan archive - Remove `as any` cast: add "archive" to SessionInfo.mode union - Replace inline import() type with proper import for ArchivedPlan - Replace any[] with ArchivedPlan[] in fetch response types - Fix infinite re-fetch when archive is empty (use hasFetched ref) - Cache archive plan list in plan server (avoid re-scanning filesystem) - Document ResizeHandle side prop behavior - Remove redundant comment on Viewer archiveInfo prop For provenance purposes, this commit was AI assisted. * chore: remove dead marketing components Step.astro and Landing.astro are unused — landing page inlines step markup and pages use Base.astro directly. For provenance purposes, this commit was AI assisted. * fix: address code review findings for plan archive - Path traversal: use resolve() + trailing separator guard (matches reference-handlers.ts) - Thread customPath into in-session archive endpoints via query param - Sort same-day archive entries by mtime instead of title - Clear selectedArchiveFile on linked doc back to prevent badge leak - Hide archive tab in annotate mode (server doesn't serve those endpoints) - Add targetTab param to useLinkedDoc.open() to preserve calling sidebar tab - Replace mutable render variable with index-based date grouping For provenance purposes, this commit was AI assisted. * refactor: collapse standalone archive server into plan server Delete packages/server/archive.ts (187 lines) — nearly all duplicated from the plan server. Add mode:"archive" option to startPlannotatorServer instead. Fixes two bugs from code review: - handleArchiveCopy now splits on "# Plan Feedback" marker instead of bare "---", preventing truncation at horizontal rules in plan content - customPath support works in standalone archive mode (was only working in-session because the standalone server never received it) For provenance purposes, this commit was AI assisted. * refactor: extract useArchive hook from App.tsx Move archive state (archiveMode, plans, selectedFile, isLoading) and handlers (select, fetchPlans, done, copy) into a dedicated useArchive hook. Reduces App.tsx by ~75 lines and makes the archive feature self-contained. For provenance purposes, this commit was AI assisted. * feat: Pi archive parity + eliminate server duplication Move runtime-agnostic storage, draft, and project functions from packages/server/ to packages/shared/ — eliminating ~250 lines of duplicated code in Pi's server.ts. Server package becomes thin re-exports, preserving all existing import paths. Add archive mode to Pi's plan review server (mode, routes, waitForDone) and register /plannotator-archive command in the Pi extension. Consolidate ArchivedPlan type to single definition in shared/storage.ts. Simplify archive copy to include full content with feedback. For provenance purposes, this commit was AI assisted. * fix: drop -core suffix from Pi shared copies The -core suffix broke cross-file imports — storage.ts imports from ./project which didn't resolve to project-core.ts. Using the original filenames (no collision) lets relative imports work naturally. For provenance purposes, this commit was AI assisted. * fix: archive custom path bugs, disable sharing, update docs - Normalize planDir via resolve() in getPlanDir() to handle relative paths and trailing slashes in the path traversal guard - Re-fetch archive plans client-side with cookie-backed customPath so standalone archive respects the user's configured save location - Disable sharing in archive mode (read-only viewer, no need) - Remove dead /api/plan/history endpoint and listProjectPlans import from Pi extension - Remove dead /api/plan/history mock from dev-mock-api - Update CLAUDE.md and AGENTS.md: add archive flow, archive API endpoints, shared package structure, correct storage location, sidebar tab count, remove stale /api/plan/history references - Update hook server docstring from four to five modes For provenance purposes, this commit was AI assisted. * fix: empty archive shows demo content, stale viewer after customPath fetch - Clear demo markdown when archive opens with no plans (plan: "" was falsy, so setMarkdown was never called) - Remove redundant fetchPlans() from archive init — server already sends archivePlans in initial response - After fetchPlans() resolves with customPath results, auto-select and load the first plan into the viewer - Remove dead listProjectPlans re-export from server barrel For provenance purposes, this commit was AI assisted. * refactor: gitignore Pi shared copies, add @generated headers Pi's copied .ts files (storage, draft, project, feedback-templates, review-core) are build artifacts generated from packages/shared/. They looked like editable source files, leading to confusion about which file to edit. Now gitignored like the HTML copies, with @generated headers prepended by the build script. For provenance purposes, this commit was AI assisted. * fix: generate Pi shared copies in CI before tests The Pi .ts copies are now gitignored build artifacts. CI needs to generate them before running tests since server.test.ts transitively imports them via server.ts. For provenance purposes, this commit was AI assisted. * fix: generate Pi shared copies in release pipeline test job Same fix as test.yml — the Pi .ts copies are gitignored, so the test job in the release pipeline also needs to generate them before bun test. For provenance purposes, this commit was AI assisted. * fix: use block scalar in CI workflow to avoid YAML parse error The inline `run:` had a colon in the printf string that YAML interpreted as a mapping key. Switch to `run: |` block scalar. For provenance purposes, this commit was AI assisted. |
||
|
|
8b8487db3e |
docs: add AGENTS.md (copy of CLAUDE.md)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |