Skip to content

chore(upstream): PR8 - 新規upstream 8件取り込み#149

Merged
MocA-Love merged 8 commits intomainfrom
upstream-merge/pr8-new-upstream
Apr 11, 2026
Merged

chore(upstream): PR8 - 新規upstream 8件取り込み#149
MocA-Love merged 8 commits intomainfrom
upstream-merge/pr8-new-upstream

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

Summary

upstream に新たに追加された8コミットを取り込み。fork 危険領域との overlap 0、全て v2/CLI/host-service の新機能・修正。

取り込みコミット

元コミット 内容 規模
23b53ed37 (superset-sh#3320) feat: v2 file tree に git decoration 15ファイル +494行
87b6ffff9 (superset-sh#3332) feat: agent settings にドロップダウン矢印 1ファイル +10行
d7eed7872 (superset-sh#3334) fix: PromptInput で file attachments を渡す 1ファイル (refactor)
1bdd70022 (superset-sh#3318) fix(cli): CLI auth を OAuth + PKCE + loopback に変更 61ファイル +6847行
bf07410ca (superset-sh#3345) feat(host-service): project.setup エンドポイント 3ファイル +530行
ec1baccac (superset-sh#3302) feat: V1 new-workspace composer を V2 modal にクローン 76ファイル +3714行
a44108af9 (superset-sh#3347) feat: TopBar に v1/v2 バージョントグル 8ファイル +98行
2c6736416 (superset-sh#3346) feat: v2 workspace に browser pane を追加 26ファイル +1433行

コンフリクト解決

3件の軽微な「両方追加」型衝突を解決:

  • _dashboard/layout.tsx: fork 独自 import + upstream の useIsV2CloudEnabled
  • _authenticated/layout.tsx: fork 独自 Provider + upstream の V2 Provider
  • v2-workspace/$workspaceId/types.ts: fork 独自 type + upstream の BrowserPaneData

検証

  • 8コミット cherry-pick + 衝突解決
  • bun install → 変更なし
  • bun run typecheck → 新規エラーなし
  • 重複 import チェック済み

Test plan

  • CI通過確認
  • ローカル動作確認

saddlepaddle and others added 8 commits April 11, 2026 15:23
* feat(desktop): git decoration in v2 "All files" tree

Adds VS Code-style decoration to the v2 workspace file tree:
- Modified files get a colored name + single-letter badge (M/A/U/D/R/C)
- Ancestor folders of any change get a colored dot roll-up
- Gitignored paths (node_modules, dist, .turbo, etc.) render muted

Backend: git.getStatus gains an ignoredPaths field populated by
`git ls-files --others --ignored --exclude-standard --directory`, run
inside the existing Promise.all so it adds zero wall-clock latency.

Client: new useGitStatusMap hook is a pure derivation over the shared
git.getStatus query cache (same key as useChangesTab → React Query
dedupes → zero extra subscriptions). TreeNode resolves decoration +
isMuted once per node and passes primitives down so WorkspaceFilesTreeItem
can React.memo cleanly — after a refresh, only rows whose state actually
flipped re-render.

Also unifies the server-side dirty signal: GitWatcher now watches both
.git/ and the worktree (via @superset/workspace-fs's multiplexed watcher
manager, so zero duplicate native watchers) and coalesces both sources
into one debounced git:changed per workspace. useChangesTab drops its
fs:events subscription and client-side 300ms debounce — git:changed is
now the single refetch trigger.

* fix(desktop): add right padding to file tree status badge

* fix(desktop): file tree polish — padding, indent, z-index, decoration tweaks

- Bump row right padding to pr-4 for breathing room on status badges
- Reduce TREE_INDENT from 16px to 10px so deep paths stay on screen
- Shift paddingLeft to (depth-1)*indent so root items aren't over-indented
- Fix sticky folder z-index going negative at depth > 10 (was 10-depth,
  now 50-depth) — folders at depth 11+ were rendering behind the
  scroll container background
- Use LuCircle icon at opacity-50 for folder status dots instead of
  the tiny bullet character
- Skip deleted files when rolling up status to ancestor folders —
  expanding the folder wouldn't show the deleted file anyway
- Remove "Loading files..." placeholder

* refactor(desktop): split git status fetching from derivation + Changes tab UI

Three single-purpose hooks instead of one tangled one:

- useGitStatus(workspaceId) — fetches + subscribes + invalidates. Single
  owner of the git.getStatus query and git:changed subscription. Called
  once at the WorkspaceSidebar level.
- useGitStatusMap(statusData) — pure useMemo over the data, returns
  { fileStatusByPath, folderStatusByPath, ignoredPaths }. No fetching,
  no subscription, no dependency on CollectionsProvider.
- useChangesTab({ workspaceId, gitStatus, ... }) — now just the Changes
  tab UI. Accepts git status as a param instead of fetching internally.
  Still owns its Changes-tab-specific queries (listCommits, listBranches,
  getCommitFiles) and filter state.

WorkspaceSidebar calls useGitStatus once and passes the query result to
useChangesTab and the query data to FilesTab. Single query, single
subscription, explicit data flow — no more React Query dedup tricks or
"two hooks with the same key happen to share a cache entry."

Also:
- Renamed `statusByPath` → `fileStatusByPath` and `worstStatusByFolder`
  → `folderStatusByPath` for symmetry.
- Dropped the unused `changedAncestors` set (value-equivalent to
  folderStatusByPath.keys()).

* refactor(desktop): drop custom --diff-* tokens for standard Tailwind colors

Removed 15 lines of custom CSS variables (--diff-added, --diff-modified,
etc.) from globals.css. These were only used in two places — ChangesFileList
and WorkspaceFilesTreeItem — and encouraged a pattern of adding bespoke
tokens to globals.css for every semantic color.

Replaced with standard Tailwind colors + dark: variants, leveraging the
existing @custom-variant dark (&:is(.dark *)) in packages/ui/src/globals.css
and the .dark class the theme store sets on the root element.

* fix(desktop): tighten diff status colors to match old OKLCH tokens

* refactor(desktop): use yellow instead of amber for modified status

* fix(desktop): address PR review feedback

- useGitStatus: stop invalidating listCommits on git:changed. With the
  unified watcher, git:changed now fires on ordinary file edits, so
  refetching commit history every save was wasteful. listCommits now
  refreshes on window focus / mutations only.
- FilesTab: gate the "No files found" empty state on !isLoadingRoot so
  it doesn't flash during the initial root fetch.
- git-watcher: reorder initialization so disposeWorktreeWatch is captured
  in the .git watcher's error handler closure — fixes a race where the
  error could fire before this.watched.set ran, leaking the worktree
  watch.
- useGitStatusMap: swap EMPTY_RESULT singleton for an emptyResult()
  factory so consumers can't accidentally mutate a module-level Map/Set.
- WorkspaceFilesTreeItem: clamp sticky folder z-index with
  Math.max(1, ...) so depths past 50 don't underflow into the scroll
  container.
…sh#3332)

Each row in Settings > Agents is collapsible but had no visual
affordance, so users didn't realize they could expand it to
configure the agent. Adds a rotating ChevronDownIcon next to
the enable switch.
…erset-sh#3334)

* fix(desktop): pass file attachments through PromptInput onSubmit callback

handlePromptSubmit was ignoring the message argument from PromptInput,
causing file attachments to be lost when submitting via Enter. Now
converts the already-available FileUIParts and passes them directly to
handleCreate, skipping the redundant takeFiles() path.

* style(desktop): format PromptGroup with biome
…h#3318)

* fix(cli): switch CLI auth to OAuth code + PKCE + loopback

The CLI's device flow always landed multi-org users on the wrong org.
Better Auth's `deviceAuthorization` mints a fresh session with
`activeOrganizationId = null`, and `customSession` then falls back to
`allMemberships[0]` — the org picked on the `/device` consent page
only ever wrote to the *web* session, never the new CLI session.

Replaces the device flow with RFC 8252 authorization_code + PKCE +
loopback redirect, matching what gcloud/stripe/vercel do. Consent-
time `customAccessTokenClaims` bakes `organizationId`, `email`, and
`plan` into the JWT, so the CLI's bearer carries the picked org (and
plan, for billing gates) with zero session lookups.

Server:
- Narrow `protectedProcedure`'s session to `AuthSession` =
  `{user:{id,email}, session:{activeOrganizationId, plan}}` — the
  complete set of fields any tRPC route actually reads today, plus
  `plan` for imminent billing gates. `customSession` still returns
  the full enriched shape for cookie callers.
- Rewrite `apps/api/src/trpc/context.ts` to resolve the session from
  one of three sources, bearer-authoritative: (1) OAuth JWT via
  `verifyAccessToken`+JWKS, (2) `sk_live_*` API key via
  `verifyApiKey` with org from metadata, (3) cookie session via
  `getSession`. A malformed or invalid bearer returns null (→ 401);
  we never silently fall through to cookie auth on failure.
- Hydrate `user.me` from the DB so callers see consistent fields
  regardless of auth method.
- Seed the `superset-cli` OAuth client at API startup via a new
  `seedSupersetCliOAuthClient` helper called from Next.js's
  `instrumentation.ts:register()` hook. Uses a hardcoded public
  `client_id` instead of per-install dynamic registration, matching
  every major CLI's pattern (gh/gcloud/stripe). Loopback ports
  51789-51793 are seeded as `redirect_uris`.
- Add the `authTime` column `@better-auth/oauth-provider@1.5.6`
  expects on `oauthRefreshTokens` (migration 0033).
- Extend `customAccessTokenClaims` to also return `email` and `plan`
  so the JWT carries everything the narrowed session needs.
- Extract `resolvePlanForOrganization` shared between `customSession`
  and `customAccessTokenClaims`.
- Extract `looksLikeJwt`/`parseApiKeyMetadata`/etc. into a shared
  `apps/api/src/lib/auth-utils.ts` used by both the MCP auth-flow
  and the new tRPC context builder.
- Delete `deviceAuthorization` plugin + `apps/web/src/app/device/`.

CLI:
- `packages/cli/src/lib/auth.ts` — `authorizationCodeAuth` does:
  generate PKCE S256 + random state, bind a one-shot loopback HTTP
  server on the first free candidate port, open the browser to
  `/oauth2/authorize` with `prompt=consent` (always show the picker
  so re-running login can switch orgs), verify the state on the
  callback (CSRF), exchange the code at `/oauth2/token` with
  `resource` in the POST body (required for JWT mint).
  `refreshAccessToken` uses the same hardcoded `client_id`.
- `packages/cli/src/lib/config.ts` — new auth shape
  `{accessToken, refreshToken, expiresAt}`, dropped `activeOrg` and
  `clientIds`. Fix 0600 file mode bug (both on write and repair on
  read for pre-0.1.x installs).
- `packages/cli/src/lib/api-client.ts` — explicit `bearer` option,
  no more `config.auth` peek.
- `packages/cli/src/lib/resolve-auth.ts` — shared bearer resolution
  used by the middleware, `auth check`, and host commands. Order:
  `--api-key` flag → `SUPERSET_API_KEY` env → stored OAuth token
  (pre-emptively refreshed if within 5 min of expiry).
- `packages/cli/src/lib/active-org.ts` — derive the active org from
  the bearer (JWT claim for OAuth, API call for API keys).
- `packages/cli/src/commands/middleware.ts` — use `resolveAuth`,
  pass bearer + authSource on ctx.
- `packages/cli/src/bin.ts` + `run-static.ts` — new `--api-key`
  global flag (`.env("SUPERSET_API_KEY")`).
- `auth whoami` → `auth check`; new output reports auth source and
  OAuth token expiry.
- Delete `org switch` — the JWT is pinned to the org at mint time,
  so switching means re-running `auth login` and picking a different
  org on the consent screen. `prompt=consent` on the authorize URL
  ensures the picker always shows.
- `host start/stop/status` derive the active org via `getActiveOrgId`
  instead of the dropped `config.activeOrg`.

Verified locally against a multi-org user: logout + login + pick
a different org swaps the JWT organizationId, user.me returns the
right account, token refresh advances `iat`/`exp` in the decoded
payload, and sending `Authorization: Bearer <invalid>` with a
browser cookie attached returns 401 instead of silently falling
through to the cookie user.

* fix: remove oauth client seed, insert row directly into prod/dev

* fix(cli): replace JWT auth with session tokens

Reverts the oauthProvider JWT infrastructure (context.ts rewrite,
AuthSession narrowing, auth-utils, plan helper, user.me hydration)
and replaces it with normal Better Auth sessions — the same token
format the desktop and web app use.

New flow: CLI opens browser to /cli/authorize (org picker page),
user picks an org, page calls /api/cli/create-code (stores a
one-time code in Redis keyed to userId:orgId, 5min TTL), redirects
to the CLI's loopback callback with the code. CLI exchanges the
code at /api/cli/exchange, which creates a session via
internalAdapter.createSession with activeOrganizationId set
correctly. CLI stores the session token and uses it as
Authorization: Bearer — getSession + bearer() + customSession
handles the rest. Context.ts untouched.

Net -548 lines server-side. CLI auth.ts 160 lines (was 435).

* refactor(cli): framework-owned dev/build, fix native packaging

cli-framework now exposes a bin with `dev` and `build` subcommands.
Consumer writes cli.config.ts (defineConfig) and commands/; zero glue
files. No bin.ts, no commands/index.ts stub, no runtime plugin()
registration. `cli-framework dev` scans the commands directory at
runtime; `cli-framework build` generates a temp entry in
.cache/cli-framework and calls Bun.build() with createCommandsPlugin,
which now has an onResolve hook so no filesystem stub is needed.

createCommand<CliContext>() gives every command typed ctx. Group-level
middleware skip markers are gone — commands that don't need
middleware declare `skipMiddleware: true`. active-org.ts and
run-static.ts are deleted; the CLI is now one code path.

Also fixes three pre-existing packaging gaps surfaced while testing
the staged tarball end-to-end on darwin-arm64:

1. libsql native binding never shipped. It's transitively pulled by
   mastra; now listed in NATIVE_PACKAGES with platform subpackages
   (@libsql/darwin-arm64 etc.) in TARGET_NATIVE_PACKAGES.

2. findPackagePath couldn't locate transitive packages in Bun's
   isolated store. Added a `.bun/<encoded>@*/node_modules/<name>`
   fallback so transitives (not just direct host-service deps) are
   walkable.

3. Native ABI mismatch. Desktop's root install:deps runs
   electron-rebuild on every `bun install`, clobbering the hoisted
   build/Release/*.node binaries with Electron-ABI (143) builds that
   can't load under Node 22 (ABI 127). fixNativeBinariesForNode now
   runs after the copy: downloads the Node-ABI better-sqlite3
   prebuild straight from GitHub releases, deletes node-pty/build/
   so the `bindings` loader falls through to N-API prebuilds/, and
   @parcel/watcher-<target> is listed so the platform subpackage
   (untouched by electron-rebuild) is copied and preferred at
   runtime over the clobbered main package build.

Verified end-to-end on darwin-arm64: bun run build:dist produces a
tarball whose bin/superset-host starts, runs migrations via
better-sqlite3, and listens on Hono.

* fix(cli): PR review followups on framework refactor

Seven independent fixes against comments on 311067d:

- plugin.ts: conditionally import root middleware. dev.ts treats
  commandsDir/middleware.ts as optional, but the build plugin used
  to emit an unconditional import — a consumer without a root
  middleware would work in dev and crash at build.
- plugin.ts: JSON.stringify import specifiers in the generated
  module. Matches the pattern already used in build.ts. Raw
  interpolation was fragile on Windows paths or repo paths with
  special characters.
- runner.ts: thread opts.name through handleError instead of
  hardcoding "superset auth login" in the UNAUTHORIZED branch.
  run() is a framework-level API.
- runner.ts: leading global flags no longer break routing.
  `superset --json auth check` used to print root help because
  routeCommand stops at the first `-` segment. Added a
  splitArgsForRouting helper that peels known globals from argv
  before routing and concatenates them back into remainingArgs for
  the command parser. Applied to both the help path and main
  routing.
- runner.ts: reject surplus positionals. Non-variadic commands
  previously silently dropped trailing positional arguments, so
  typos like `tasks get ABC extra` ran successfully.
- runner.ts: require middleware to invoke next() before running
  typed commands. A short-circuiting middleware used to leave ctx
  as {} while cmd.run received it typed as the consumer's
  CliContext, turning a middleware bug into a runtime undefined
  access. Now throws CLIError with a clear message.
- build-dist.ts: error on ambiguous .bun store matches. If the
  isolated store contains multiple versions of the same package,
  readdirSync previously returned whichever one the filesystem
  yielded first. Now collects all matches and throws unless
  exactly one is found.
…ment (superset-sh#3345)

* docs: add design doc for v2 host project paths

Outlines the approach for allowing users to import existing local repos
or clone to a chosen location instead of auto-cloning to a fixed path.
Covers local-only storage decision, throw-on-create pattern, and phased
implementation plan.

* feat(host-service): add project.setup endpoint for importing/cloning repos

Adds a `project.setup` mutation that lets users either import an
existing local repo or clone to a chosen directory. Validates git
remotes against the cloud project's GitHub repo (handles SSH + HTTPS).
Upserts the local projects table so re-running handles re-pointing.

* fix(host-service): address PR review feedback on project.setup

- Reuse existing parseGitHubRemote helper instead of custom regex,
  adds ssh:// URI support and credential-safe URL storage
- Validate parentDir is a directory in cloneRepo, not just exists
- Wrap simpleGit().clone() in try/catch for actionable error messages
- Return remotes from importExistingRepo to avoid double git remote -v
- Use path.resolve for absolute clone paths
- Fix design doc: git rev-parse instead of .git folder check

* fix(host-service): replace non-null assertions with explicit guards

* fix(host-service): clean up cloned directory on post-clone validation failure

* fix(host-service): add cleanup on all cloneRepo error paths
…t-sh#3302)

* feat(desktop): clone V1 new-workspace composer onto V2 modal

Replaces the tab-based V2 create-workspace modal with a clone of the
battle-tested V1 composer, rewiring only the backend boundaries.

Backend boundary changes (V1 → V2):
- Project list: electronTrpc.projects.getRecents → v2Projects +
  githubRepositories collections
- Branch list: electronTrpc.projects.getBranches* →
  workspaceCreation.searchBranches on host-service
- Create action: 4 V1 mutations (create/createFromPr/openTracked/
  openExternal) → single workspaceCreation.create on host-service
- GitHub issues/PRs list + content: electronTrpc.projects.{listIssues,
  listPullRequests, searchPullRequests, getIssueContent} →
  workspaceCreation.{searchGitHubIssues, searchPullRequests,
  getGitHubIssueContent} on host-service (Octokit via ctx.github())
- Navigation: navigateToWorkspace → navigateToV2Workspace

V2 additions:
- DevicePicker in the composer footer for host target selection; on
  host change, compareBaseBranch resets
- hostTarget field in the draft context

Intentionally dropped for Phase 1 (deferred to Phase 2):
- Branch prefix feature (projects.get, getGitAuthor, settings.
  getBranchPrefix, settings.getGitInfo, resolveBranchPrefix) — crosses
  V2 host boundary, needs host-aware prefix in Phase 2
- Worktree preflight UI (getExternalWorktrees, getWorktreesByProject,
  resolveOpenableWorktrees, worktree badges/filter tab) — host-service
  workspaceCreation.create handles tracked/external/adopt server-side

Host-service endpoints added:
- workspaceCreation.getContext — project + default branch
- workspaceCreation.searchBranches — git branches with hasWorkspace
- workspaceCreation.create — semantic create with outcome resolution
  (created_workspace / opened_existing_workspace / opened_worktree /
  adopted_external_worktree) and path-traversal guard on branchName
- workspaceCreation.searchGitHubIssues — Octokit issue list/search
- workspaceCreation.searchPullRequests — Octokit PR list/search
- workspaceCreation.getGitHubIssueContent — Octokit issue body fetch

* fix: pass organizationId to cloud API calls in workspaceCreation router

After merging main, v2Project.get and v2Workspace.create were converted
to jwtProcedure and now require organizationId in their input. The
host-service workspace.create endpoint was already updated in main, but
our new workspaceCreation router still had four call sites missing it.

* chore: add instrumentation to workspace creation flow

Temporary console.log at key points to debug "workspace created" toast
showing but workspace not appearing:
- useCreateDashboardWorkspace: log input + result
- PromptGroup: log create result + navigation
- workspaceCreation.create: log resolved names, each outcome path

* Update docs

* docs: clean up plan files, keep only final decisions + scenario analysis

Remove superseded docs (v2-create-fix-plan, v2-create-decisions,
v1-workspace-creation-logic). Keep v1-create-scenario-analysis as
V1 behavior reference and v2-create-decisions-final as the 13
implementation decisions.

* feat: implement v2 create decisions — always create, never collide

Host-service workspaceCreation.create rewrite:
- Strip collision detection (no opened_existing_workspace / opened_worktree
  / adopted_external_worktree). Create always creates.
- Sanitize + deduplicate branch name server-side. If branch exists,
  append -2, -3, etc. Renderer sends best-effort name.
- Simplified return: { workspace, warnings } — no outcome field.
- Add setup script execution (runs .superset/setup.sh in worktree,
  blocks until done, non-fatal on failure).
- Remove source and behavior fields from input schema.
- Add sanitize-branch utils (copied from shared/utils/branch.ts).

Renderer PromptGroup rewrite:
- Remove AI branch gen (electronTrpc.workspaces.generateBranchName) —
  boundary violation, needs V1 project ID.
- Renderer computes branch name: user-typed > prompt slug > random UUID.
- Renderer computes workspace name: user-typed > prompt > branch name.
- Single pending phase: "creating" (no "generating-branch" or "preparing").
- Remove buildLaunchRequest, hostUrl resolution, agentConfigsById —
  dead code after removing AI gen and collision paths.

Per decisions in apps/desktop/plans/v2-create-decisions-final.md.

* feat: draft stash for failure recovery

On create submit: snapshot the draft into a zustand atom before
closing the modal. On success: clear the stash. On failure: restore
the stash and reopen the modal so the user can retry with their
prompt, attachments, and linked context intact.

- Added stashedDraft / stashDraft / clearStashedDraft /
  restoreStashedDraft to the new-workspace-modal zustand store
- PromptGroup.handleCreate stashes before closeAndResetDraft,
  restores on catch
- DashboardNewWorkspaceModalContent applies stash on reopen via
  useEffect that reads from the zustand store
- Replaced runAsyncAction with direct try/catch for clearer
  success/failure handling

* chore: add logging + error handling to cloud API calls in create

The create flow was hanging silently when ensureV2Host or
v2Workspace.create failed (e.g. Neon DB schema mismatch). Now
both calls log before + catch errors explicitly, rollback the
worktree on failure, and throw with a descriptive message
instead of hanging.

* docs: finalize v2 workspace creation status + pending workspace design

- pendingWorkspaces local collection (localStorage-backed via @tanstack/react-db)
  holds full draft data for retry on failure
- Attachments stored as raw blobs in IndexedDB (no compression — files
  are already compressed, IndexedDB has no size limit)
- EventBus workspace:creating events for live step-by-step progress
- /v2-workspace/pending/$pendingId route shows progress, error + retry
- Sidebar renders pending workspaces as clickable skeletons
- Multiple concurrent creates supported
- Host-service returns initialCommands, setup dispatched to terminal pane

* docs: switch from EventBus to polling for create progress

- Host-service writes to in-memory Map during create mutation
- New getProgress query endpoint, pending page polls every 500ms
- PromptGroup owns the create promise (fire-and-forget, survives
  unmount), updates pendingWorkspaces collection on resolve/reject
- Pending page is purely a progress viewer, not an owner
- Sidebar reads collection via useLiveQuery, no polling
- Removed all EventBus references from the design

* docs: add TODO for cleaning up stale createProgress map entries

* chore: add TODO to migrate chat pane uploads to IndexedDB blob pattern

* chore: move IndexedDB migration TODO to ChatLaunchConfig where base64 blobs are stored

* feat: add create progress infrastructure

Host-service:
- In-memory progress map with TTL sweep for stale entries
- getProgress query endpoint (polled by pending page at 500ms)
- Create mutation writes step progress (ensuring_repo → creating_worktree → registering)
- Clears progress on success or failure
- Returns initialCommands instead of running execSync (setup dispatched to terminal pane)
- Accepts pendingId for progress correlation

Renderer:
- pendingWorkspaces local collection (localStorage-backed via @tanstack/react-db)
  with full draft data for retry on failure
- pending-attachment-store.ts: IndexedDB wrapper for attachment blobs
  (store/load/clear keyed by pendingId)
- useCreateDashboardWorkspace accepts + forwards pendingId

* feat: rewrite PromptGroup submit to use pendingWorkspaces collection + IndexedDB

- Insert full draft into pendingWorkspaces collection before closing modal
- Store attachment blobs in IndexedDB (keyed by pendingId/blobUUID)
- Navigate to /v2-workspace/pending/$pendingId immediately
- Fire-and-forget createWorkspace — closure survives modal unmount
- On success: update collection row to succeeded, clear IndexedDB blobs
- On failure: update collection row to failed (draft preserved for retry)
- Removed zustand stashedDraft/pendingWorkspace hooks (replaced by collection)
- Removed inline convertBlobUrlToDataUrl (moved to pending-attachment-store)

* feat: add pending workspace page with live progress polling

New route: /v2-workspace/pending/$pendingId

- Reads pending workspace from pendingWorkspaces collection via useLiveQuery
- Polls workspaceCreation.getProgress every 500ms for step-by-step progress
- Shows: workspace name, branch name, step checklist (ensuring_repo → creating_worktree → registering)
- On succeeded: auto-navigates to /v2-workspace/$workspaceId, cleans up pending row
- On failed: shows error message with Retry + Dismiss buttons
- Retry resets status to creating (full re-fire is a follow-up TODO)
- Dismiss deletes pending row + clears IndexedDB attachments

* feat: sidebar renders pending workspaces from collection, clickable

- Replace single zustand pendingWorkspace with useLiveQuery on
  pendingWorkspaces collection (supports multiple concurrent creates)
- Pending sidebar items are now clickable — navigate to
  /v2-workspace/pending/$pendingId to view progress
- Add "failed" status to creationStatus type across sidebar components
  (types, icon, collapsed button, status text helper)
- Succeeded pending workspaces are filtered out (replaced by real
  workspace from Electric sync)

* refactor: split PromptGroup into focused files

PromptGroup.tsx: 890 → 441 lines (UI render only)

Extracted:
- components/AttachmentButtons/ (74 lines)
- components/ProjectPickerPill/ (79 lines)
- components/CompareBaseBranchPicker/ (134 lines)
- hooks/useHandleCreate/ (181 lines) — full create orchestration
- types.ts (15 lines) — shared types + constants

Existing sub-components unchanged:
- GitHubIssueLinkCommand, LinkedGitHubIssuePill, LinkedPRPill, PRLinkCommand

* fix: sidebar pending workspace visual states

- Failed: red triangle icon + red "Failed" text
- Creating: keeps spinner + gray "Creating..." text

* fix: center pending workspace page layout

* fix: pending page centered on page, left-aligned text

* fix: pending page takes full width of content area

* refactor: host-service defines step labels, renderer just renders

Host-service getProgress now returns fully resolved steps with id,
label, and status (pending/active/done). The renderer maps over
the array directly — no STEP_LABELS, no STEP_ORDER, no string
matching. If the host-service adds/changes steps, the UI updates
automatically.

* fix: pending page top-aligned with padding, update dev seed scripts

* feat: elapsed timer + staleness detection on pending page

* fix: coerce createdAt to timestamp regardless of string/Date type

* fix: timer inline before status text

* fix: formatRelativeTime shows seconds under 1 minute

Was returning "now" for everything under 60s. Now returns "now" for
<5s, then "5s", "30s", etc. Pending page consumes it for the elapsed
timer instead of a custom formatter.

* chore: remove dev seed files and dead stash restore code

- Delete dev-seed-pending-workspace.ts and DevSeedPendingWorkspace.tsx
- Remove stash restore effect from DashboardNewWorkspaceModalContent
  (draft recovery now handled by pending page retry, not modal reopen)
- Remove DevSeedPendingWorkspace from layout
- Leave zustand store untouched (V1 still uses it)

* fix: move pending page out of v2-workspace layout

The pending page was under /v2-workspace/pending/$pendingId which
caused the v2-workspace layout to render bare <Outlet /> during
route transitions. This removed the WorkspaceTrpcProvider from the
tree while TerminalPane was still mounted → crash.

Moved to /_dashboard/pending/$pendingId — completely outside the
v2-workspace layout. The layout reverts to main's version unchanged.

* docs: add comment explaining why pending page lives outside v2-workspace

* chore: remove instrumentation console.logs from workspaceCreation.create

* fix: always show dismiss on creating page, add TODO on v2-workspace layout bug

- Dismiss button always visible on pending page (not just when stale)
- Added TODO comment on v2-workspace layout explaining the bare
  Outlet bug that strips WorkspaceTrpcProvider during transitions
- Removed instrumentation console.logs

* fix: always create new branch, never try checkout existing

Create flow uses `git worktree add -b` directly. No try/catch
fallback to checkout. If branch exists despite dedup, the git
command errors and the create fails cleanly.

Checking out existing branches is a separate intent (createFromPr).
Updated decisions doc (decision #8).

* feat: use friendly two-word names for fallback branch/workspace names

Replace workspace-${uuid} with friendly-words pattern (e.g.
"cheerful-umbrella"). Generate once, use for both branch name and
workspace name when user typed neither. New shared util at
shared/utils/friendly-branch-name.ts.

* feat: wire up retry from pending page, move timer to end

- Extract useRetryCreate hook that re-fires createWorkspace with
  draft data from the pending collection row + attachments from IndexedDB
- Retry button calls the hook instead of inline logic
- Move elapsed timer to right-aligned end of status line

* refactor: rename compareBaseBranch to baseBranch in V2 create flow

V1 uses "compareBaseBranch" because it serves double duty as the
git fork point AND the diff comparison base. For V2's create flow
it's just the fork point — "baseBranch" is clearer. The workspace
view can derive its own compare base independently.

Renamed in: draft context, PromptGroup, useHandleCreate,
useCreateDashboardWorkspace, host-service create input schema,
pendingWorkspace collection schema, pending page retry.
V1 code untouched.

* refactor: split branch name handling into slugifyForBranch + sanitizeUserBranchName

Two clearly different operations:
- slugifyForBranch: turns arbitrary text (prompts) into a branch slug.
  Lowercases, strips special chars, collapses spaces to dashes.
- sanitizeUserBranchName: strips only what git forbids from a
  user-typed branch name. Preserves case, slashes, underscores.

Host-service no longer sanitizes — it only validates (non-empty) and
deduplicates. The renderer owns all sanitization/slugification.
Removed sanitizeBranchNameWithMaxLength from host-service utils.

* refactor: rename useHandleCreate → useSubmitWorkspace, extract pure functions

- resolveNames(draft) — pure. Computes branch + workspace names from
  draft state. User-typed → sanitizeUserBranchName, prompt → slugifyForBranch,
  empty → friendlyBranchName.
- mapLinkedContext(draft) — pure. Maps linked issues/PR to API payload shape.
- useSubmitWorkspace(projectId) — the hook. Orchestrates resolve → store →
  insert → close → navigate → fire create. Calls the pure functions.

Dependency array simplified: just draft object instead of 12 individual fields.

* fix: dedup suffix can no longer exceed max branch length

Truncates base name upfront to 94 chars (reserving 6 for suffix
like -99999) before appending dedup suffixes. Strips trailing .-
after truncation. Last-resort fallback uses base36 timestamp
instead of decimal for shorter output.

* lint
…#3347)

* feat(desktop): add local v1/v2 version toggle in top bar

When the v2 feature flag is enabled remotely, a segmented toggle appears
in the top bar (next to resource consumption) that lets you switch
between v1 and v2 locally without changing the PostHog flag. The
preference persists in localStorage across app restarts.

* lint
…ence (superset-sh#3346)

* feat(desktop): port browser pane to v2 workspaces with global persistence

- Port v1 browser pane (webview, URL toolbar, history, error overlay, new-window
  handler) into v2 workspace tree as a native implementation. Uses the v2
  Workspace component's renderToolbar slot for a Chrome-style URL bar in the
  pane header.
- Float-over webview: each <webview> lives at document.body under a fixed
  #browser-runtime-root, positioned via ResizeObserver on a per-pane placeholder
  div. Elements never reparent, so Electron's guest WebContents survives tab
  switches, pane drags, and workspace route remounts — no page reloads.
- Keep-alive tab rendering in @superset/panes Workspace.tsx: tabs that have
  been visited stay mounted behind visibility:hidden so their React state
  (and persistent DOM like webviews) survives tab switches. Also benefits
  terminal scrollback, chat subscriptions, editor state.
- BrowserRuntimeRegistry: module-level singleton keyed by paneId, modeled on
  terminalRuntimeRegistry. Owns webview lifecycle, state subscriptions via
  useSyncExternalStore, drag-passthrough listeners, equality-guarded setState
  to deduplicate webview event spam.
- Single-pane-browser tabs show the page favicon + live page title in the tab
  bar via a new optional renderTabLabel prop on the panes library.
- BrowserPane subscribes to the workspace store for activeTabId to drive
  webview visibility, so inactive-tab webviews don't paint on top of the
  active tab's content.
- Destroy path: diff the set of browser pane ids across all tabs each render,
  destroying any that disappeared. Correctly handles tab closes, intra-tab
  split closes, and pane drags between tabs (moved panes stay in the set).

Known limitation: dropping panes onto another browser pane's body doesn't
register — the webview compositor layer intercepts drag events even with
pointer-events:none/visibility:hidden. Drops on pane headers work. Deferred.

* refactor(desktop): co-locate browser pane integration, remove keep-alive

- Float-over webviews already preserve state across tab switches via the
  registry's attach/detach pair, so keep-alive tab rendering was redundant.
  Revert packages/panes Workspace.tsx to rendering only the active tab.
- Move all browser-specific wiring from page.tsx into a new
  useBrowserPaneIntegration hook co-located with BrowserPane. page.tsx now
  consumes a single hook call instead of owning tab title derivation, tab
  label rendering, and the destroy diff effect.
- Registry attach takes over the visibility flip directly; setVisibility
  method is no longer needed. Drop the rAF deferral — React useEffect fires
  after layout commit so getBoundingClientRect reads correct values
  synchronously.
- BrowserPane no longer subscribes to the workspace store for isTabActive.

* refactor(desktop): simplify browser pane integration, add onRemoved hook

- Add PaneDefinition.onRemoved(pane) lifecycle hook to @superset/panes.
  Workspace.tsx tracks a flat snapshot of panes across all tabs and fires
  onRemoved with the pre-removal Pane object when an id disappears. Pane
  moves between tabs keep the same id in the current set so moves correctly
  don't fire onRemoved.
- Wire browser cleanup declaratively via the new hook in usePaneRegistry.tsx:
  `onRemoved: (pane) => browserRuntimeRegistry.destroy(pane.id)`. Removes
  the need for useBrowserPaneDestroy in userland.
- Persist faviconUrl on BrowserPaneData alongside pageTitle. The registry's
  persist callback fires from handleDidStopLoading AND handlePageFaviconUpdated
  via a shared firePersist helper. Favicons now survive app restart.
- Replace renderTabLabel with renderTabIcon in @superset/panes. TabItem renders
  {icon}{title}{accessory} — icon leading, accessory trailing, native gap-2
  from the parent button. Drop redundant `| null` from the ReactNode types.
- Fix titleOverride precedence in Workspace.tsx: `tab.titleOverride ??
  getTabTitle(tab) ?? tab.id`. Renaming a browser tab now actually sticks.
- Empty tab rename clears titleOverride instead of being swallowed; thread
  `string | undefined` through TabItem → TabBar → Workspace so the derived
  title takes back over on clear.
- Collapse useBrowserPaneIntegration.tsx and BrowserTabLabel component into
  BrowserPane.tsx as pure functions (getBrowserTabTitle, renderBrowserTabIcon).
  Favicon is now a plain <img> reading from persisted pane data — no more
  subscribing component just for one field.
- page.tsx loses browser-specific imports, refs, effects, and callbacks. Just
  two pure helpers passed as props.

* refactor(desktop): use native webview back/forward + tighten sanitizeUrl

- Drop the custom history array and isHistoryNavigation flag. goBack/goForward
  now call webview.goBack()/goForward() directly, preserving scroll position,
  form state, and BFCache on back/forward navigation.
- Add refreshNavState helper that reads webview.canGoBack()/canGoForward() and
  writes them into runtime state. Called from did-navigate,
  did-navigate-in-page, did-stop-loading, and on re-attach of existing entries.
- The isHistoryNavigation guard was dead code: did-navigate fires before
  did-stop-loading, so the flag was always false by the time the guard ran,
  causing a redundant browserHistory.upsert IPC call on every back/forward nav.
- Clear faviconUrl in handleDidStartLoading so stale favicons don't persist
  when navigating to a page with no favicon.
- Tighten sanitizeUrl: reject dotted strings containing whitespace (e.g.
  "release v2.1") as URLs, trim input, tighten the localhost/127.0.0.1 regex
  to accept optional port and path. Dotted search queries now correctly fall
  through to Google search.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 11, 2026

Important

Review skipped

Too many files!

This PR contains 190 files, which is 40 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3359a959-317e-4e86-97a1-0bac924f688f

📥 Commits

Reviewing files that changed from the base of the PR and between 821a83d and 0664da2.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (190)
  • apps/api/src/app/api/cli/create-code/route.ts
  • apps/api/src/app/api/cli/exchange/route.ts
  • apps/desktop/plans/v1-create-scenario-analysis.md
  • apps/desktop/plans/v2-create-decisions-final.md
  • apps/desktop/plans/v2-workspace-init-status.md
  • apps/desktop/src/renderer/components/NewWorkspaceModal/components/PromptGroup/PromptGroup.tsx
  • apps/desktop/src/renderer/globals.css
  • apps/desktop/src/renderer/hooks/host-service/useGitStatus/index.ts
  • apps/desktop/src/renderer/hooks/host-service/useGitStatus/useGitStatus.ts
  • apps/desktop/src/renderer/hooks/host-service/useGitStatusMap/index.ts
  • apps/desktop/src/renderer/hooks/host-service/useGitStatusMap/useGitStatusMap.ts
  • apps/desktop/src/renderer/hooks/useIsV2CloudEnabled.ts
  • apps/desktop/src/renderer/lib/formatRelativeTime/formatRelativeTime.test.ts
  • apps/desktop/src/renderer/lib/formatRelativeTime/formatRelativeTime.ts
  • apps/desktop/src/renderer/lib/pending-attachment-store.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarCollapsedWorkspaceButton/DashboardSidebarCollapsedWorkspaceButton.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarExpandedWorkspaceRow/DashboardSidebarExpandedWorkspaceRow.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceIcon/DashboardSidebarWorkspaceIcon.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/utils/getCreationStatusText.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/types.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/TopBar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pending/$pendingId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/WorkspaceSidebar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/components/FilesTab/FilesTab.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/components/FilesTab/components/WorkspaceFilesTreeItem/WorkspaceFilesTreeItem.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/ChangesFileList.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/useChangesTab.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useDefaultContextMenuActions/useDefaultContextMenuActions.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/BrowserPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/browserRuntimeRegistry.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserErrorOverlay/BrowserErrorOverlay.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserErrorOverlay/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserOverflowMenu/BrowserOverflowMenu.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserOverflowMenu/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/BrowserToolbar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/components/UrlSuggestions/UrlSuggestions.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/components/UrlSuggestions/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/hooks/useUrlAutocomplete/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/hooks/useUrlAutocomplete/useUrlAutocomplete.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/components/BrowserToolbar/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/constants.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/hooks/usePersistentWebview/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/BrowserPane/sanitizeUrl.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/FilePane/FilePane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspaceHotkeys/useWorkspaceHotkeys.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/types.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/DashboardNewWorkspaceDraftContext.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/DashboardNewWorkspaceModal.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/DashboardNewWorkspaceForm.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/PromptGroup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/AttachmentButtons/AttachmentButtons.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/AttachmentButtons/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/CompareBaseBranchPicker/CompareBaseBranchPicker.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/CompareBaseBranchPicker/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/GitHubIssueLinkCommand/GitHubIssueLinkCommand.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/GitHubIssueLinkCommand/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/LinkedGitHubIssuePill/LinkedGitHubIssuePill.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/LinkedGitHubIssuePill/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/LinkedPRPill/LinkedPRPill.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/LinkedPRPill/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/PRLinkCommand/PRLinkCommand.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/PRLinkCommand/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/ProjectPickerPill/ProjectPickerPill.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/components/ProjectPickerPill/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useSubmitWorkspace/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useSubmitWorkspace/mapLinkedContext.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useSubmitWorkspace/resolveNames.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useSubmitWorkspace/useSubmitWorkspace.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/types.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/BranchesGroup/BranchesGroup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/BranchesGroup/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspaceFormHeader/DashboardNewWorkspaceFormHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspaceFormHeader/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspaceListTabContent/DashboardNewWorkspaceListTabContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspaceListTabContent/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspacePromptTabContent/DashboardNewWorkspacePromptTabContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/DashboardNewWorkspacePromptTabContent/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/IssuesGroup/IssuesGroup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/IssuesGroup/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/ProjectSelector/ProjectSelector.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/ProjectSelector/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/PromptGroup/PromptGroup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/PromptGroup/components/PromptGroupAdvancedOptions/PromptGroupAdvancedOptions.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/PromptGroup/components/PromptGroupAdvancedOptions/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/PullRequestsGroup/PullRequestsGroup.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/components/PullRequestsGroup/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useBranchContext/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useBranchContext/useBranchContext.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useDashboardNewWorkspaceProjectSelection/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useDashboardNewWorkspaceProjectSelection/useDashboardNewWorkspaceProjectSelection.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useResolvedLocalProject/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/hooks/useResolvedLocalProject/useResolvedLocalProject.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceModalContent/DashboardNewWorkspaceModalContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceModalContent/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/hooks/useCreateDashboardWorkspace/useCreateDashboardWorkspace.ts
  • apps/desktop/src/renderer/routes/_authenticated/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts
  • apps/desktop/src/renderer/routes/_authenticated/settings/agents/components/AgentsSettings/components/AgentCard/components/AgentCardHeader/AgentCardHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/TerminalSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/FilesView/constants.ts
  • apps/desktop/src/renderer/stores/new-workspace-modal.ts
  • apps/desktop/src/renderer/stores/v2-local-override.ts
  • apps/desktop/src/shared/tabs-types.ts
  • apps/desktop/src/shared/utils/branch.ts
  • apps/desktop/src/shared/utils/friendly-branch-name.ts
  • apps/web/src/app/cli/authorize/components/CliAuthorizeForm/CliAuthorizeForm.tsx
  • apps/web/src/app/cli/authorize/components/CliAuthorizeForm/index.ts
  • apps/web/src/app/cli/authorize/page.tsx
  • apps/web/src/app/device/page.tsx
  • docs/design/v2-host-project-paths.md
  • packages/auth/src/server.ts
  • packages/cli-framework/package.json
  • packages/cli-framework/src/bin.ts
  • packages/cli-framework/src/build.ts
  • packages/cli-framework/src/cli.ts
  • packages/cli-framework/src/command.ts
  • packages/cli-framework/src/config.ts
  • packages/cli-framework/src/dev.ts
  • packages/cli-framework/src/index.ts
  • packages/cli-framework/src/middleware.ts
  • packages/cli-framework/src/plugin.ts
  • packages/cli-framework/src/router.ts
  • packages/cli-framework/src/runner.ts
  • packages/cli/DISTRIBUTION.md
  • packages/cli/cli.config.ts
  • packages/cli/package.json
  • packages/cli/scripts/build-dist.ts
  • packages/cli/src/bin.ts
  • packages/cli/src/commands/auth/check/command.ts
  • packages/cli/src/commands/auth/login/command.ts
  • packages/cli/src/commands/auth/logout/command.ts
  • packages/cli/src/commands/auth/middleware.ts
  • packages/cli/src/commands/auth/whoami/command.ts
  • packages/cli/src/commands/devices/list/command.ts
  • packages/cli/src/commands/host/install/command.ts
  • packages/cli/src/commands/host/middleware.ts
  • packages/cli/src/commands/host/start/command.ts
  • packages/cli/src/commands/host/status/command.ts
  • packages/cli/src/commands/host/stop/command.ts
  • packages/cli/src/commands/index.ts
  • packages/cli/src/commands/middleware.ts
  • packages/cli/src/commands/org/list/command.ts
  • packages/cli/src/commands/org/switch/command.ts
  • packages/cli/src/commands/tasks/create/command.ts
  • packages/cli/src/commands/tasks/delete/command.ts
  • packages/cli/src/commands/tasks/get/command.ts
  • packages/cli/src/commands/tasks/list/command.ts
  • packages/cli/src/commands/tasks/update/command.ts
  • packages/cli/src/commands/workspaces/create/command.ts
  • packages/cli/src/commands/workspaces/delete/command.ts
  • packages/cli/src/commands/workspaces/list/command.ts
  • packages/cli/src/lib/api-client.ts
  • packages/cli/src/lib/auth.ts
  • packages/cli/src/lib/command.ts
  • packages/cli/src/lib/config.ts
  • packages/cli/src/lib/env.ts
  • packages/cli/src/lib/host/spawn.ts
  • packages/cli/src/lib/resolve-auth.ts
  • packages/cli/src/run-static.ts
  • packages/cli/tsconfig.json
  • packages/db/drizzle/0033_add_oauth_refresh_token_auth_time.sql
  • packages/db/drizzle/meta/0033_snapshot.json
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/schema/auth.ts
  • packages/host-service/src/events/event-bus.ts
  • packages/host-service/src/events/git-watcher.ts
  • packages/host-service/src/trpc/router/git/git.ts
  • packages/host-service/src/trpc/router/project/project.ts
  • packages/host-service/src/trpc/router/project/utils/git-remote.ts
  • packages/host-service/src/trpc/router/router.ts
  • packages/host-service/src/trpc/router/workspace-creation/index.ts
  • packages/host-service/src/trpc/router/workspace-creation/utils/sanitize-branch.ts
  • packages/host-service/src/trpc/router/workspace-creation/workspace-creation.ts
  • packages/panes/src/react/components/Workspace/Workspace.tsx
  • packages/panes/src/react/components/Workspace/components/TabBar/TabBar.tsx
  • packages/panes/src/react/components/Workspace/components/TabBar/components/TabItem/TabItem.tsx
  • packages/panes/src/react/types.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upstream-merge/pr8-new-upstream

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@MocA-Love MocA-Love merged commit 8bcf395 into main Apr 11, 2026
9 of 14 checks passed
@MocA-Love MocA-Love deleted the upstream-merge/pr8-new-upstream branch April 11, 2026 06:25
MocA-Love added a commit that referenced this pull request Apr 11, 2026
8 additional upstream commits cherry-picked via PR #149.

=== Cherry-picked (8 commits) ===
PR8 (#149): 23b53ed, 87b6fff, d7eed78, 1bdd700, bf07410,
            ec1bacc, a44108a, 2c67364
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.

4 participants