Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/architecture/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ When changing PR status fetching, derivation, or UI rendering:
- `src/types/window-api.d.ts` — type definitions for the 4 methods
- `src/store/app.store.ts` — `workspacePrInfoById`, `fetchWorkspacePrStatus`, `fetchAllWorkspacePrStatuses`
- `src/components/layout/PrStatusIcon.tsx` — icon lookup and color mapping
- `src/components/layout/TopBarOpenPR.tsx` — PR hub trigger, dropdown, creation dialog
- `src/components/layout/TopBarOpenPR.tsx` — PR hub trigger, ship-skill dispatch, dropdown actions
- `src/components/layout/ProjectWorkspaceSidebar.tsx` — sidebar icon rendering

See `docs/features/workspace-pr-status.md` for the full architecture reference.
Expand Down
65 changes: 31 additions & 34 deletions docs/features/workspace-pr-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,24 +120,24 @@ gh pr view --json ...
│ │
Sidebar icon TopBar PR Hub
(PrStatusIcon) (DropdownMenu +
creation dialog)
ship workflow)
```

### File Map

| Layer | File | Role |
| ------------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Types & derivation | `src/lib/pr-status.ts` | `WorkspacePrStatus`, `GitHubPrPayload`, `derivePrStatus()`, visual config, action config |
| IPC handlers | `electron/main/ipc/scm.ts` | `scm:get-pr-status`, `scm:get-pr-status-for-url`, `scm:set-pr-ready`, `scm:merge-pr`, `scm:update-pr-branch` |
| Preload bridge | `electron/preload.ts` | `getPrStatus`, `getPrStatusForUrl`, `setPrReady`, `mergePr`, `updatePrBranch` |
| Window API types | `src/types/window-api.d.ts` | Type definitions for the 5 PR-related methods |
| Layer | File | Role |
| ------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Types & derivation | `src/lib/pr-status.ts` | `WorkspacePrStatus`, `GitHubPrPayload`, `derivePrStatus()`, visual config, action config |
| IPC handlers | `electron/main/ipc/scm.ts` | `scm:get-pr-status`, `scm:get-pr-status-for-url`, `scm:set-pr-ready`, `scm:merge-pr`, `scm:update-pr-branch` |
| Preload bridge | `electron/preload.ts` | `getPrStatus`, `getPrStatusForUrl`, `setPrReady`, `mergePr`, `updatePrBranch` |
| Window API types | `src/types/window-api.d.ts` | Type definitions for the 5 PR-related methods |
| Store | `src/store/app.store.ts` | `workspacePrInfoById`, `fetchWorkspacePrStatus`, `fetchAllWorkspacePrStatuses`, `continueWorkspaceFromSummary` |
| Icon component | `src/components/layout/PrStatusIcon.tsx` | Reusable icon renderer: status → Lucide icon + color |
| Sidebar | `src/components/layout/ProjectWorkspaceSidebar.tsx` | Renders `PrStatusIcon` for non-default workspaces |
| TopBar hub | `src/components/layout/TopBarOpenPR.tsx` | PR status badge, dropdown actions, creation dialog, and continue entry for completed workspaces |
| Continue dialog | `src/components/layout/ContinueWorkspaceDialog.tsx` | New workspace handoff dialog for completed PR workspaces |
| Information panel | `src/components/layout/WorkspaceInformationPanel.tsx` | Shows the current branch PR plus related manual PR URLs resolved through GitHub metadata when available |
| Continue helper | `src/lib/workspace-continue.ts` | Builds the continuation markdown brief and `.stave/context/...` file path |
| Icon component | `src/components/layout/PrStatusIcon.tsx` | Reusable icon renderer: status → Lucide icon + color |
| Sidebar | `src/components/layout/ProjectWorkspaceSidebar.tsx` | Renders `PrStatusIcon` for non-default workspaces |
| TopBar hub | `src/components/layout/TopBarOpenPR.tsx` | PR status badge, dropdown actions, ship-skill dispatch, and continue entry for completed workspaces |
| Continue dialog | `src/components/layout/ContinueWorkspaceDialog.tsx` | New workspace handoff dialog for completed PR workspaces |
| Information panel | `src/components/layout/WorkspaceInformationPanel.tsx` | Shows the current branch PR plus related manual PR URLs resolved through GitHub metadata when available |
| Continue helper | `src/lib/workspace-continue.ts` | Builds the continuation markdown brief and `.stave/context/...` file path |

### IPC Handlers

Expand All @@ -153,12 +153,12 @@ All handlers check `gh auth status` before executing.

## Polling Strategy

| Context | Interval | Trigger |
| ------------------------- | ---------- | ---------------------------- |
| Active workspace (TopBar) | 60 seconds | `useEffect` interval |
| All workspaces (Sidebar) | 5 minutes | `useEffect` interval |
| Manual | On demand | Dropdown "Refresh" item |
| After action | Immediate | Post-create/merge/mark-ready |
| Context | Interval | Trigger |
| ------------------------- | ---------- | ----------------------- |
| Active workspace (TopBar) | 60 seconds | `useEffect` interval |
| All workspaces (Sidebar) | 5 minutes | `useEffect` interval |
| Manual | On demand | Dropdown "Refresh" item |
| After action | Immediate | Post-merge/mark-ready |

PR info is **transient state** — not persisted in `RecentProjectState` or SQLite.
Each session fetches fresh from GitHub on mount.
Expand All @@ -167,10 +167,10 @@ Each session fetches fresh from GitHub on mount.

The top bar button changes based on status:

| Status | Button Appearance | Click Behavior |
| --------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `no_pr` | `[GitPullRequest] Create PR` (primary badge) | Opens PR creation dialog _(disabled while any task in the active workspace is responding)_ |
| Any other | `[StatusIcon] Status Label` (status-colored badge) | Opens dropdown menu |
| Status | Button Appearance | Click Behavior |
| --------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `no_pr` | `[GitPullRequest] Create PR` (primary badge) | Starts the `ship` skill in the active task _(disabled while a task is responding or the active workspace skill catalog is not ready)_ |
| Any other | `[StatusIcon] Status Label` (status-colored badge) | Opens dropdown menu |

### Dropdown Actions by Status

Expand Down Expand Up @@ -207,17 +207,14 @@ This is intentionally a **summary brief** flow, not a full task-history clone. I

The dialog keeps the base branch simple by default. It shows the current remote base as a badge and reveals a searchable remote branch picker only after the user clicks **Change**.

### PR Creation Dialog
### Ship Workflow

- The dialog opens in a loading splash state until the suggested PR title and description are ready. Stave no longer shows a provisional fallback draft first and then replaces it in place.
- Draft generation now includes the active workspace task, prompt-draft context, attached continuation brief snippets, notes, and open todos so the first AI draft stays focused on the current workspace instead of echoing older workspace PR summaries.
- The dialog includes a **Target Branch** picker so users can choose which base branch the PR should merge into before running `gh pr create`.
- Suggested PR titles are normalized against the branch's latest conventional commit subject so the type and scope stay aligned with the workspace PR flow guidance.
- The title field validates Conventional Commits format and expects a lowercase subject, for example `fix(topbar): add create pr loading splash`.
- If the user switches to another workspace while the dialog is open, Stave closes the dialog and discards the in-flight draft request so a previous workspace response cannot bleed into the newly active workspace.
- Right before submission, Stave refreshes git status again and auto-commits only the files that are still currently uncommitted before pushing and opening the PR.
- When uncommitted files are auto-committed during PR creation, progress, success, and failure messages are shown inline inside the dialog instead of as transient toast notifications.
- While commit, push, or PR creation is running, the dialog no longer accepts dismiss attempts that would clear the prepared title and description mid-flight.
- Create PR activates the installed `ship` skill in the active task instead of maintaining a second PR orchestration path in the renderer.
- The skill owns repository-rule discovery, scoped validation, intentional staging and commit, push, ready PR creation, and auto-merge setup.
- Dispatch uses the task-to-workspace ownership map, so git and provider work resolve from the task's workspace rather than whichever workspace becomes active later.
- Stave requires the skill catalog to be loaded for the exact active workspace before enabling Create PR. A catalog from a previously selected workspace is never reused for this action.
- Progress and approval requests appear in the active task conversation. There is no PR draft dialog or cross-workspace draft state to hydrate, replace, or leak during workspace switches.
- Draft PR creation is intentionally not offered by this flow because the `ship` workflow creates a ready PR and queues it for automatic merge.

## Store Shape

Expand All @@ -244,7 +241,7 @@ interface WorkspacePrInfo {

## Future Work (Phase 2+)

- **PR creation → auto-refresh**: After `scm:create-pr` succeeds, immediately fetch status _(done in Phase 1)_
- **Ship completion → auto-refresh**: Refresh PR status immediately when the ship task reports that PR creation completed
- **Merge queue**: Add `queued_for_merge` status for repos using GitHub merge queues
- **Edit PR**: `gh pr edit` for title/body changes from within Stave
- **Close/Reopen PR**: `gh pr close` / `gh pr reopen`
Expand Down
Loading
Loading