🤖 feat: archive merged workspaces in project#2132
Merged
Conversation
Member
Author
|
@codex review |
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
- Assert command palette includes ws:archive-merged-in-project and submits correctly - Add archiveMergedInProject coverage for mux-chat exclusion + unarchivedAt semantics - Wrap SigningService no-key/encrypted-key tests in withoutSshAgent to avoid env bleed
7340a04 to
0539351
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Command Palette action to archive all workspaces in a project whose GitHub PR state is MERGED (detected via
gh pr view).Implementation
workspace.archiveMergedInProjectthat checks each non-archived workspace in the project and archives those whose PR state isMERGED.Validation
make static-checkRisks
ghand perform cleanup.📋 Implementation Plan
Plan: Command Palette — Archive merged workspaces (GitHub PR state)
Context / Why
Add a new Command Palette action that lets you archive all workspaces whose GitHub PR status is
MERGED(as determined by Mux’s existing GitHub integration viagh pr view). This provides one-click cleanup of “done” workspaces without deleting them.Evidence
buildCoreSources()andCommandIds.src/browser/utils/commands/sources.ts(buildCoreSources, project/workspace prompt patterns)src/browser/utils/commandIds.ts(central command ID registry)src/browser/App.tsx(registers sources + suppliesBuildSourcesParamscallbacks)src/node/orpc/router.ts→workspace.archive→context.workspaceService.archive()src/node/services/workspaceService.ts#archive()setsarchivedAtand emits updated metadatasrc/browser/stores/PRStatusStore.tsrunsgh pr view --json ...viaworkspace.executeBashand treatsstate === "MERGED"as merged.src/common/types/links.tsdefinesGitHubPRStatus.state: "OPEN" | "CLOSED" | "MERGED".Implementation details (recommended approach)
1) Add a new ORPC endpoint to batch-archive merged workspaces
Goal: Avoid O(n) frontend→backend IPC loops by doing detection + archiving in one backend call.
Schema: Add a new workspace endpoint in
src/common/orpc/schemas/api.ts:workspace.archiveMergedInProject{ projectPath: string }ResultSchema({ archivedWorkspaceIds: string[], skippedWorkspaceIds: string[], errors: { workspaceId: string, error: string }[] })Router wiring: In
src/node/orpc/router.tsunderworkspace: { ... }, add:Service implementation: Add
WorkspaceService.archiveMergedInProject(projectPath)insrc/node/services/workspaceService.ts.Algorithm (defensive + best-effort):
await this.config.getAllWorkspaceMetadata().meta.projectPath === projectPath!isWorkspaceArchived(meta.archivedAt, meta.unarchivedAt))MUX_HELP_CHAT_WORKSPACE_IDgh pr view):PRStatusStorebehavior; never hard-fail on “no PR”):gh pr view --json state 2>/dev/null || echo '{"no_pr":true}'this.executeBash(workspaceId, script, { timeout_secs: 15 }).no_pr⇒ skip (not an error).state === "MERGED"⇒ mark for archive; otherwise skip.archiveMany(workspaceIds: string[])to update config once and emit metadata updates once.await this.archive(workspaceId)(acceptable but less efficient).Concurrency: Use a small concurrency limit (e.g., 3–5) for running
ghto avoid starting too many runtimes at once.Return value: Always return
Ok({ archivedWorkspaceIds, skippedWorkspaceIds, errors })unless the input project is invalid (thenErr("Project not found")).2) Add the Command Palette command
Command ID: Add an ID builder in
src/browser/utils/commandIds.ts:BuildSourcesParams: Extend
BuildSourcesParamsinsrc/browser/utils/commands/sources.ts:Command action: Add a new command under the Projects section in
buildCoreSources()(same pattern as “Create New Workspace in Project…”), prompting for a project then running the callback.3) Wire the command callback in
App.tsxsrc/browser/App.tsx, create a callback that calls the new API method:api.workspace.archiveMergedInProject({ projectPath })alert(result.error)(palette actions should never throw)registerParamsRef.currentasonArchiveMergedWorkspacesInProject.Tests / Validation
WorkspaceService.executeBashto return:{ "state": "MERGED" }for some workspaces and{ "state": "OPEN" }for othersbuildCoreSources()includes the new command.Estimated net new LoC (product code)
Alternative (smaller change, but not preferred): frontend loops
Implement the command purely in the browser by:
workspaceMetadatafor the chosen projectapi.workspace.executeBash({ workspaceId, script: 'gh pr view --json state ...' })api.workspace.archive({ workspaceId })Pros: ~60–90 LoC, no backend changes.
Cons: violates the repo guideline to avoid O(n) frontend→backend IPC loops; slow/fragile for many workspaces.
Estimated net new LoC: ~70–110 LoC.
Generated with
mux• Model:openai:gpt-5.2• Thinking:xhigh• Cost: $17.48