Skip to content

Align GUI project-service CLI route surfaces#35

Merged
TraderSamwise merged 9 commits into
masterfrom
phase/gui-project-service-cli-consistency
May 26, 2026
Merged

Align GUI project-service CLI route surfaces#35
TraderSamwise merged 9 commits into
masterfrom
phase/gui-project-service-cli-consistency

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented May 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • expose worktree graveyard operations through app API/UI and CLI routes
  • add task read routes and align CLI thread/task reads and thread mark-seen through project service
  • update external route contracts for exchange-backed tasks/threads and notification inbox state

Verification

  • yarn verify
  • yarn build
  • cd app && yarn test lib/api.test.ts
  • cd app && yarn typecheck
  • push pre-push hook: yarn verify

Summary by CodeRabbit

  • New Features

    • Manage graveyarded worktrees (view, resurrect, delete) in UI and CLI; graveyard now shows both entries and worktrees.
    • Browse workflows and tasks with filters and view task details; thread mark-seen supported.
  • Bug Fixes

    • Improved URL-decoding robustness, notification/task listing, and stricter session validation for mark-seen flows.
    • Service-first fallbacks for threads, tasks, and worktree commands.
  • Documentation

    • Updated architecture and UI contract docs for new task and graveyard endpoints and CLI commands.
  • Tests

    • Expanded relay and server tests for worktree/graveyard, tasks, and thread flows.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b6bb5d8-721d-48de-b8f9-23aac177bad8

📥 Commits

Reviewing files that changed from the base of the PR and between d1372d7 and 5357ac8.

📒 Files selected for processing (1)
  • src/main.ts

📝 Walkthrough

Walkthrough

Adds worktree graveyard lifecycle and task-browsing endpoints; converts CLI and desktop commands to prefer project service with safe local fallbacks; extends Graveyard UI to manage graveyarded worktrees; implements metadata-server task read endpoints and thread mark-seen handling; updates tests and docs.

Changes

Worktree Graveyard Management and Task Browsing

Layer / File(s) Summary
API contracts and relay tests
app/lib/api.ts, app/lib/api.test.ts
Adds WorktreeGraveyardEntryResponse, TaskSummaryResponse, TaskListResponse, TaskDetailResponse and functions graveyardWorktree, resurrectGraveyardWorktree, deleteGraveyardWorktree, listWorkflow, listTasks, getTask; refactors listNotifications URL formatting; expands relay-proxy tests to cover workflow/tasks and worktree graveyard routes.
Metadata server endpoints & tests
src/metadata-server.ts, src/metadata-server.test.ts
Implements GET /tasks and GET /tasks/:taskId with optional session/status filters and guarded decoding; hardens /threads/:id decoding error handling; updates POST /threads/mark-seen session param handling; adds tests for malformed ids and task listing/detail.
CLI / daemon service-or-local commands
src/main.ts
Adds getProjectServiceJsonOrLocal and adjusts fallbacks; converts thread/task commands to service-first with local fallback; adds worktree subcommands (remove, graveyard, resurrect, delete-graveyard) with --json variants; introduces printGraveyard and rewrites graveyard list.
Desktop UI graveyard screen
app/app/(main)/(tabs)/(dashboard)/graveyard.tsx
Tracks graveyarded worktrees in component state, stores API worktrees, implements resurrectWorktree and deleteWorktree handlers with per-item busy tracking and local state updates, renders a Worktrees section and updates empty-state messaging.
Architecture & UI contract docs
docs/current-architecture.md, docs/desktop-ui-contract.md
Documents task browsing and notifications endpoints, adds project worktree graveyard routes and CLI examples, and clarifies state-split and SSE vs persistent inbox behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MetadataServer
  participant Storage
  Client->>MetadataServer: GET /tasks?session=s1&status=pending
  MetadataServer->>Storage: readAllTasks()
  Storage-->>MetadataServer: tasks[]
  MetadataServer-->>Client: { ok, tasks }
  Client->>MetadataServer: GET /tasks/t1
  MetadataServer->>Storage: readTask(t1)
  Storage-->>MetadataServer: task
  MetadataServer->>Storage: readThread(task.threadId)
  Storage-->>MetadataServer: thread, messages
  MetadataServer-->>Client: { ok, task, thread, messages }
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

  • TraderSamwise/aimux#32: Both PRs implement the resurrect/delete “graveyard worktrees” lifecycle end-to-end and touch metadata/topology wiring.
  • TraderSamwise/aimux#31: Related Graveyard UI and resurrection flows affecting agents and graveyard handling.
  • TraderSamwise/aimux#28: Overlaps worktree graveyard endpoint surface and runtime-topology integration.

Poem

🐰 I hopped into code where the worktrees sleep,

I nudged the graveyard, woke tasks from the deep,
CLI asks the service, falls back with a sigh,
UI lifts a root — then the dead branches fly,
The rabbit nods off with a tiny code-cheep.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Align GUI project-service CLI route surfaces' clearly and concisely summarizes the main objective of the PR, which is to align GUI, project-service, and CLI route surfaces through worktree graveyard operations, task reads, and thread/mark-seen endpoints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 phase/gui-project-service-cli-consistency

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main.ts (1)

2665-2690: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't translate project-service errors into an empty graveyard.

If /graveyard fails on a live service, this catch reports an empty graveyard instead of falling back to listTopologySessionStates() / listTopologyWorktreeGraveyard(). That makes the CLI lie about recoverable state.

Suggested fix
+    const localGraveyard = () => ({
+      ok: true,
+      entries: listTopologySessionStates({ statuses: ["graveyard"] }),
+      worktrees: listTopologyWorktreeGraveyard(),
+    });
     try {
-      const graveyard = await getLiveProjectServiceJsonOrLocal(projectRoot, "/graveyard", () => ({
-        ok: true,
-        entries: listTopologySessionStates({ statuses: ["graveyard"] }),
-        worktrees: listTopologyWorktreeGraveyard(),
-      }));
+      const graveyard = await getLiveProjectServiceJsonOrLocal(projectRoot, "/graveyard", localGraveyard);
       if (opts.json) {
         console.log(
           JSON.stringify(
@@
       }
       printGraveyard(graveyard);
     } catch {
+      const graveyard = localGraveyard();
       if (opts.json) {
-        console.log(JSON.stringify({ entries: [], worktrees: [] }, null, 2));
+        console.log(JSON.stringify({ entries: graveyard.entries, worktrees: graveyard.worktrees }, null, 2));
         return;
       }
-      console.log("Graveyard is empty.");
+      printGraveyard(graveyard);
     }
🤖 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/main.ts` around lines 2665 - 2690, The catch block currently swallows
failures from getLiveProjectServiceJsonOrLocal and returns an empty graveyard;
change it to fallback to the local providers instead: on error call
listTopologySessionStates({ statuses: ["graveyard"] }) and
listTopologyWorktreeGraveyard() to build the same graveyard shape used above,
then proceed to JSON output or printGraveyard like the success path; reference
getLiveProjectServiceJsonOrLocal, listTopologySessionStates,
listTopologyWorktreeGraveyard, printGraveyard and opts.json when implementing
the fallback so failures from the live service don't falsely report an empty
graveyard.
🤖 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/current-architecture.md`:
- Around line 187-190: The project-service HTTP endpoint list is missing the
endpoints corresponding to the new CLI commands; add the following POST
endpoints to the service endpoint list to match the CLI and the desktop UI
contract: POST /worktrees/remove (for "aimux worktree remove"), POST
/worktrees/graveyard (for "aimux worktree graveyard"), POST
/graveyard/worktrees/resurrect (for "aimux worktree resurrect"), and POST
/graveyard/worktrees/delete (for "aimux worktree delete-graveyard"); ensure they
are formatted and ordered consistently with the existing endpoint list and match
the definitions in the desktop UI contract.

In `@docs/desktop-ui-contract.md`:
- Around line 52-56: Update the project-service HTTP endpoint list in
docs/current-architecture.md to include the notification inbox endpoints GET
/notifications, POST /notifications/read, and POST /notifications/clear (or add
an explicit pointer to the notification inbox surface described in
docs/desktop-ui-contract.md and docs/notification-system.md). Reference the
actual implementation in src/metadata-server.ts and the client helpers in
app/lib/api.ts so readers can find the server and client code and associated
tests.

In `@src/main.ts`:
- Around line 2435-2438: prepareProjectContext() changes process.cwd(), so
calling pathResolve(targetPath) after it causes relative targetPath to be
resolved against the repo root instead of the caller's cwd; move the resolution
of the worktree path (the pathResolve(targetPath) call that produces
resolvedPath) to run before prepareProjectContext(opts.project) (and likewise
before any prepareProjectContext calls near the other occurrences) so that
targetPath is resolved against the original working directory; update the blocks
containing prepareProjectContext, ensureDaemonProjectReadyForFallback, and
postLiveProjectServiceJsonOrLocal to compute resolvedPath first and then call
prepareProjectContext.
- Around line 2438-2446: postLiveProjectServiceJsonOrLocal currently only falls
back when the endpoint is absent, causing hard failures when a reachable service
returns 404/405/501; change its error-handling so that when the HTTP response
status is exactly 404, 405, or 501 it invokes the provided local fallback
callback (the function that constructs a Multiplexer and calls methods like
Multiplexer.removeDesktopWorktree), but for other HTTP errors (5xx) or network
errors it should rethrow/propagate the error as before; update
postLiveProjectServiceJsonOrLocal so callers such as the calls that pass () => {
const mux = new Multiplexer(); return mux.removeDesktopWorktree(resolvedPath); }
(and the other similar Multiplexer fallbacks) will only be used for
route-not-found/unsupported responses.

In `@src/metadata-server.ts`:
- Around line 1238-1240: The code currently calls decodeURIComponent on
url.pathname for the "/tasks/" (and similarly "/threads/") routes without
guarding against malformed percent-encoding; wrap the decodeURIComponent call
used to produce taskId (and threadId) in a try/catch and if decodeURIComponent
throws (URIError) respond with a 400 Bad Request (e.g., set status 400 and end
the response) instead of letting the exception bubble; update the handler around
the existing req.method === "GET" && url.pathname.startsWith("/tasks/") logic
where taskId is derived and likewise for the "/threads/" branch where threadId
is derived before calling readTask/readThread so that readTask/readThread are
only invoked with a valid decoded id.

---

Outside diff comments:
In `@src/main.ts`:
- Around line 2665-2690: The catch block currently swallows failures from
getLiveProjectServiceJsonOrLocal and returns an empty graveyard; change it to
fallback to the local providers instead: on error call
listTopologySessionStates({ statuses: ["graveyard"] }) and
listTopologyWorktreeGraveyard() to build the same graveyard shape used above,
then proceed to JSON output or printGraveyard like the success path; reference
getLiveProjectServiceJsonOrLocal, listTopologySessionStates,
listTopologyWorktreeGraveyard, printGraveyard and opts.json when implementing
the fallback so failures from the live service don't falsely report an empty
graveyard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6dd8f0a5-7494-4aad-b6f0-bcf6fdc0a384

📥 Commits

Reviewing files that changed from the base of the PR and between 8f6639d and ef25ea2.

📒 Files selected for processing (8)
  • app/app/(main)/(tabs)/(dashboard)/graveyard.tsx
  • app/lib/api.test.ts
  • app/lib/api.ts
  • docs/current-architecture.md
  • docs/desktop-ui-contract.md
  • src/main.ts
  • src/metadata-server.test.ts
  • src/metadata-server.ts

Comment thread docs/current-architecture.md
Comment thread docs/desktop-ui-contract.md
Comment thread src/main.ts
Comment thread src/main.ts
Comment thread src/metadata-server.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/main.ts`:
- Around line 396-398: getLiveProjectServiceJsonOrLocal currently throws on any
HTTP error; modify it to mirror the POST variant by catching HTTP errors and
returning fallback() when the response status is one of the route-not-found
statuses (at least 404, 405, 501 and also handle the broader 405–422 range as
appropriate). Locate getLiveProjectServiceJsonOrLocal, wrap its fetch/axios call
in a try/catch (or inspect the response status) and if error.status (or
response.status) is in the allowed fallback set call and return fallback();
otherwise rethrow or propagate the error as before.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e341c97-bd56-4839-8e3e-0ab5267eb4ff

📥 Commits

Reviewing files that changed from the base of the PR and between ef25ea2 and a16e2c4.

📒 Files selected for processing (4)
  • docs/current-architecture.md
  • src/main.ts
  • src/metadata-server.test.ts
  • src/metadata-server.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/current-architecture.md

Comment thread src/main.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/main.ts`:
- Around line 415-420: The code calls requestJson(...) inside
ensureDaemonProjectReadyForFallback() and only checks status codes 404/405/501,
but if requestJson() rejects (stale endpoint/transport failure) the function
hard-fails; wrap the requestJson call in a try/catch around the GET to catch
rejections and in the catch branch call and return fallback() (same as when
status is 404/405/501), using the same endpoint/ path variables and preserving
existing behavior for successful responses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 149e1e8b-890d-4f99-ad01-28bca32bda70

📥 Commits

Reviewing files that changed from the base of the PR and between a16e2c4 and d1372d7.

📒 Files selected for processing (1)
  • src/main.ts

Comment thread src/main.ts Outdated
@TraderSamwise
TraderSamwise merged commit cc4b9bf into master May 26, 2026
1 check passed
@TraderSamwise
TraderSamwise deleted the phase/gui-project-service-cli-consistency branch May 26, 2026 07:15
Sign up for free to 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