Skip to content

feat(claude-accounts): per-project Claude account (ask on launch, remember per project) - #23228

Open
Ethan-Rivas wants to merge 75 commits into
stablyai:mainfrom
Ethan-Rivas:feat/per-project-agent-account
Open

Ethan-Rivas wants to merge 75 commits into
stablyai:mainfrom
Ethan-Rivas:feat/per-project-agent-account

Conversation

@Ethan-Rivas

@Ethan-Rivas Ethan-Rivas commented Sep 26, 2026 •

Copy link
Copy Markdown

Builds on #22691's --account launch. The first 16 commits are #22691's. After main's per-account Claude folders landed (#24434, which removed credential replay), this branch rebuilt the pinned launch on those folders, so it no longer copies or refreshes any login. This PR's own changes start at 4f038e1; the rebuild is in the merge 8780cbc830.

ELI5

If you use Claude with more than one account (say work and personal), Orca today has one "active" account for everything, so you have to remember to switch before working in each project, and switching affects every project at once. This PR lets each project remember its Claude account. Optionally, Orca asks the first time you start Claude in a project and remembers your choice, so work repos always start on the work account and personal repos on the personal one, even side by side. If the saved account can't be used, Claude doesn't quietly start on a different account; the pane explains why and lets you start on the active account for that one launch.

What Changed

Before: one global Claude account per machine. Every Claude tab, workspace and resume used whichever account was selected when it started. #22691 adds --account for the CLI and RPC only; the desktop app's launches (new tab, ⌘⌥T, New Workspace, resume) can't use it.

After, for the user:

  • Settings → Repository → Claude Account (next to GitHub Account): Default · Ask every time · each signed-in Claude account. Disabled for SSH and WSL projects, with a note.
  • Settings → Accounts → "Ask which Claude account to use for each project", off by default. When it's on, projects without a saved account show a small prompt (account dropdown + "Remember for this project") when you start Claude from New Workspace, a new agent tab / ⌘⌥T, quick launch or the tab-bar menu.
  • A pinned tab's tooltip shows its account email.
  • If the saved account can't be used (it was removed, the project runs in WSL, or Orca couldn't confirm the account it prepared), the pane explains why, with Start on active account where that helps (restarts just that pane, this launch only).
  • Resume and restore bring a session back on the account it started on, not the project's current setting.
  • Switching the selected account later doesn't move a pinned tab: it stays on its account.

Mechanism:

  • Repo.agentAccounts.claude = { mode: 'ask' } | { mode: 'account', accountId }, round-tripped like ghAccount (feat(github): bind projects to a specific gh account #13664): persistence, IPC, the repo.update schema (null clears).
  • SleepingAgentLaunchConfig.claudeAccountId carries a launch's account (or an "active this time" sentinel), so resume and restore replay it.
  • One main-process resolver decides the pinned account in both spawn lanes: explicit choice → the launch's recorded account → project setting → selected account. SSH and reattached panes are never pinned.
  • A pinned launch runs from the account's own folder. For an account other than the selected one, prepareForClaudeLaunch(target, { accountId }) sets up that account's folder (claude-profiles/<id>/home, via the router's new prepareAccountLaunch) and points CLAUDE_CONFIG_DIR at it. The pane gets no which-account pointer, so main's claude shell function isn't defined there and a later switch can't redirect it. The selected account takes main's normal path. Because nothing is copied, there are no reservations, Keychain seeding, read-back or switch guards.
  • Refusals carry a trailing [claude_pinned:<code>] token (account-missing, provenance, unsupported-host) so the renderer can localize them; the CLI and mobile strip it from human output (--json keeps it).
  • A small registry records which PTY runs which pinned account (ids only, persisted so labels survive a restart). Main stamps an optional claudeAccountId onto agent-status rows from it, and the tab label reads that.
  • Paired hosts: terminal.createAgentSession / ensureAgentSession carry the account only to hosts advertising the new agent-session.claude-account.v1 capability (their params are strict, so older hosts would otherwise reject the launch).
  • Host-side structured (native chat) Claude launches for a project with a saved account run as a terminal (pinned_claude_account reason), and a structured → terminal handoff keeps the session's own account. A pinned launch also skips the new-tab wait for a host's agent list, since it is a terminal whatever the host answers.

Why

Linked Issue

Fixes #23227

Visual Proof

Before After
before-a1-settings-repository
Settings → Repository has no Claude account choice
a1-settings-repository-claude-account-options
New "Claude Account" section: Default / Ask every time / each account
before-b-new-claude-tab
"+ → Claude" starts on the global account with no choice
b-choose-claude-account-prompt
With "ask" on, a prompt picks the account (Remember for this project)
before-d-tab-tooltip
Tab tooltip shows no account
d-tab-tooltip-pinned-account
A pinned tab shows its account email
n/a (new) e1-refusal-toast-account-missing
If the saved account can't be used: explanation + Start on active account
n/a (new) e2-started-on-active-account
The refused pane restarted in place on the active account

Testing

  • I manually tested these changes locally

  • Automated tests added/updated

  • Unit and integration tests:

    • persistence and RPC round-trip;
    • the resolver's rule order;
    • the account service: a non-selected account runs from its own folder with no pointer, the selected account takes the normal path, a missing or WSL account is refused before any folder is touched;
    • both spawn lanes: pinning, the pinned pane never getting the selected account's pointer while an unpinned one does, non-Claude, SSH and reattach unchanged;
    • the pinned PTY registry: labels, persistence, and dropping restored PTYs the daemon no longer runs;
    • refusal codes and copy;
    • settings section, toggle and prompt, including over the New Workspace composer;
    • cold resume, sleep/wake and restart after daemon death, replaying the original account and keeping "active this time" unpinned;
    • paired-host capability negotiation;
    • main's credential-persistence ratchet, with the registry's id-only file added as a reviewed surface.
  • e2e: tests/e2e/per-project-claude-account.spec.ts runs the real app hidden, with fake managed accounts and a stand-in claude. It checks the settings options, the prompt, Remember, that the pinned CLAUDE_CONFIG_DIR is the account's own folder (set up on first use), no re-prompt plus the tab label, and a refusal restarting in place on the active account. It runs on Linux CI and skips on macOS and Windows. Screenshots are written only when ORCA_PER_PROJECT_CLAUDE_ACCOUNT_SCREENSHOT_DIR is set.

  • Manual: to re-run on the account-folder rebuild (the earlier manual runs were on the credential-copying design): two projects on two accounts at once with /status confirming each, a one-time pick versus Remember, the prompt over New Workspace and Cancel creating nothing, a refusal and in-place restart, switching the selected account while a pinned tab runs, and an app restart bringing pinned tabs back on their accounts with labels.

  • Platforms: macOS (manual, to re-run). Linux runs in CI (e2e). Windows: unit tests only; the e2e skips there (the stand-in claude is POSIX). WSL projects are deliberately not pinned. SSH projects are never pinned (covered by tests).

  • pnpm tc passes. pnpm test over the account, terminal, launch, CLI and worker suites: every failure also fails on a clean main in the same environment.

AI Disclosure

Built with Claude Code (Claude Opus 5.5, with Sonnet 5 / Haiku 4.5 sub-agents for smaller tasks): design, implementation, tests and reviews, including the rebuild on main's account folders. Every change was reviewed and tested by me.

Review

AI review summary:

  • Cross-platform: path utilities only; logins live in main's account folders on every platform, and this PR adds no credential handling of its own; no platform-specific UI.
  • SSH / remote / local: SSH is never pinned, and the Settings section is disabled with a note. Remote runtimes and paired hosts get the account only through capability-gated optional fields. Older clients and hosts behave exactly as before.
  • Agents / integrations: Claude only. Storage is keyed per agent (agentAccounts.claude) for later agents. Non-Claude terminals take the same code path as before.
  • Performance: the resolver is one repo lookup per fresh local Claude spawn; an account folder is set up once, on first use; the prompt only fetches accounts when it will actually be shown.
  • Security: untrusted IPC, RPC and persisted ids resolve only to known managed accounts, never to a path. The "active this time" sentinel never pins. No login is copied, read back or written by this PR.
  • UI: shadcn Dialog/Select/Checkbox/Switch; strings through translate in all 5 locales; design-system lint clean on changed lines.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Known limitations

  • Split tabs: after splitting a tab whose pane was refused, the refusal message shows again once that pane is clicked (existing per-pane error behavior).
  • Older paired hosts (without the capability) can't honor a one-time pick. On a capable host, an agent-only launch that falls back to the legacy create path silently runs on the project's saved account instead of a one-time pick.
  • WSL: WSL projects aren't pinned yet. Main now has WSL account folders, so this is a follow-up rather than a blocker.
  • Removing an account a pinned tab is using deletes its folder, as it does for the selected account on main.

Related: #22893 (opt-in isolation from external agent config) is complementary: pinned sessions run in their account's own folder and never write to ~/.claude.

Follow-ups: WSL pinning on main's WSL account folders, per-worktree overrides, project-group inheritance (#6921 discussion), per-account usage bars, and Codex once it has a per-launch account primitive.

Checklist

  • This PR is small and focused. (Focused on one feature, but not small: it includes tests and 5-locale i18n, and the account-folder rebuild of feat(claude-accounts): launch a Claude agent on a specific managed account with --account #22691's pinned launch.)
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred) (the full pnpm lint and pnpm build weren't run locally: dependencies main added since can't be installed in this environment; CI will cover them)

Selection and removal checked for pinned terminals before the pinned launch's
reservation existed, and a usage fetch could stage or refresh an account while a
pinned launch seeded the same Keychain item. Host mutations, usage fetches and
pinned reservations now claim an account with one synchronous check-and-set and
hold it until they finish; a pinned launch waits out a usage fetch and refuses a
switch or removal in progress.
…queue

A pinned launch that met an in-flight usage fetch waited up to 40s inside the
process-wide auth mutation queue, stalling every Claude launch and sync. The
reservation is now taken (and waited for) before entering the queue; the queued
part re-validates the account and the reservation is released on every failure.
… writes

Re-auth replaced an account's managed credentials without the host-mutation
claim, so it could overwrite the store a pinned --account Claude refreshes. It
now refuses up front while pinned terminals hold the account and claims the
account from the credential write through rollback.
…als still run on

A host Claude keeps the account it started on and refreshes it through
~/.claude after the host switches away, so pinning that account with --account
gave one single-use refresh chain two owners. Unpinned host Claude PTYs and
structured children now record the account they started on (from the prepared
auth provenance, else the host selection), restored across restarts, and a
pinned reservation refuses while any of them is still live.
Store an optional Claude account choice on each repo, next to the
GitHub account: the default (active) account, a saved managed account,
or "ask every time". It is normalized on load and update, and travels
over repo.update as a new optional field.
Add an optional claudeAccountId to the sleeping-agent launch config so a
launch can record which Claude account it ran on. Recovery equivalence
and sleeping records keep the field; nothing reads it yet.
Move the pinned-account preparation, reservation release and spawn
registration out of the runtime spawn lane into claude-pinned-spawn so
the IPC lane can reuse them. No behavior change.
Pinned launch refusals now end with a [claude_pinned:<code>] token.
Errors cross IPC as plain strings, so the token lets the renderer map a
refusal to localized copy without parsing the English message.
…anes

Resolve the account a fresh Claude launch must run on (explicit
--account, then the launch config, then the project's saved account)
and pin it on both the renderer IPC lane and the runtime lane. SSH and
pre-adopted panes never pin, and host-side agent.launch falls back to a
terminal instead of a structured session when the project pins one.
New-tab and New Workspace launches resolve the project's saved account
in the renderer and record it in the launch config. A launch that pins
an account is routed to a terminal, since a structured session has no
way to run on a pinned account.
Add a Claude account picker to repository settings (also for folder
projects) and an opt-in "ask per project" toggle under Accounts, both
reachable from settings search. The repository project sections move
into their own component to keep RepositoryPane under the size limit.
When the ask setting is on and a project has no saved account, Claude
launches from the tab bar, quick launch and New Workspace first show a
prompt to pick an account, with an option to remember the choice for
the project.
…tive account

Map pinned-launch refusal codes to localized copy in the terminal error
toast, naming the account and terminal count when an account is still
in use. Offer "Start on active account" to restart only the refused
pane, or Retry for refusals that clear on their own. CLI and mobile
error text strips the refusal tag; --json output keeps it.
A pinned account cannot run inside WSL yet. Tag that refusal with a new
unsupported-host code so the terminal toast explains it and offers the
active account, and disable the Settings picker and the account prompt
for WSL projects.
Main reads each pinned PTY's account from the pinned registry and adds
it to the agent-status push, so the tab can show which account a
Claude terminal runs on. The live-entry history helpers move to their
own file to keep the builder under the size limit.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed the single commit that landed since the prior pullfrog review (50941704): an origin/main merge (0f88550, main at 564f4d0). Its only conflict was src/shared/global-settings-types.ts, resolved as a clean union plus one type extraction.

  • Unioned the settings type — the branch's askClaudeAccountPerProject now sits alongside main's new agentStateRulesPath / agentStateRulesLiveUpdates, with agentWorkspaceTrustEnabled retained. Neither side's field was dropped.
  • Extracted WorktreeVisibilityDefaults into a new src/shared/worktree-visibility-defaults.ts and re-exported it from global-settings-types.ts; the union had pushed that file past the .ts 300-line max-lines cap. Type-only, and every existing importer still resolves through the original entry point.

Verified two ways: git diff 564f4d0 HEAD over the merge shows only the branch's field and the extraction, and git diff 5094170 HEAD shows only main's fields — no feature line lost, no main change dropped. The merge touched none of the branch's feature files. pnpm tc:node is clean.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/main/runtime/rpc/methods/orchestration/worker/local-worker-start.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed what landed since the prior pullfrog review (0f88550): a single origin/main merge (0fab477, main at e80b550, ~50 main commits) plus one merge-only refactor. tsc -p config/tsconfig.node.json is clean, oxlint is clean on all three touched files, and the 25 tests over the merge-touched runtime paths pass.

  • Merged origin/main (0fab477), resolving one textual conflict plus two files that differ from both parents:
    • local-worker-start.ts — union of main's new resolveWorkerConfiguredAgentParams (configured alias → TUI agent preflight, with launchParams fed to prepareLocalWorkerStart) and the branch's claudeAccount destructure, its assertClaudeAccountWorktreeIsLocal guard, and the claudeAccountId passed to placeWorkerAgent.
    • orca-runtime-create-managed-worktree.ts + new runtime-worktree-create-requested-agent.ts — a merge-only extraction of the inline requested-agent resolution into resolveRequestedStartupAgent(args, disabledTuiAgents), moved verbatim. Main's trackRuntimeWorkspaceCreate/events/timing and the branch's startupClaudeAccountId both survive.

The merge holds under a two-way check: git diff e80b550 HEAD over the touched files contains only the branch's additions, and git diff 0f88550 HEAD contains only main's, so no branch line was lost and no main change was dropped.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/shared/global-settings-types.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed what landed since the prior pullfrog review (0fab477): a single origin/main merge whose only textual conflict was global-settings-types.ts. git diff-tree --cc shows the full both-parents set is seven files; every resolution is a clean union that preserves the branch's feature. pnpm tc:node, tc:web, and tc:cli are clean, oxlint reports zero findings on all seven files, and the affected settings tests pass (18).

  • Merged origin/main (9432b51, main tip b032867), resolving one conflict plus a merge-only refactor:
    • accounts-claude-search.ts (new) — main still had getAccountsClaudeSearchEntries inline in accounts-search.ts; the branch added the ask-per-project entry and its keyword accessor. Merging main's additional provider entry groups would push the file past the 300-line cap, so the Claude entries were extracted here — main's getAccountsClaudeSearchEntries with the branch's ask entry appended, plus getAskClaudeAccountPerProjectSearchKeywords.
    • accounts-search.ts / AccountsPane.tsx — now import the Claude entries and the keyword accessor from the new module; the pane roll-up still includes the Claude entry exactly once, and no consumer still imports either symbol from ./accounts-search.
    • accounts-search.test.ts — main's new pane-order test and the branch's ask-per-project test both survive, with imports repointed.
    • global-settings-types.ts — type-only: adopted main's OrcaWorkspaceLayout re-export (./orca-workspace-layout) alongside the branch's WorktreeVisibilityDefaults re-export.
    • protocol-version.ts — main's ANTIGRAVITY_ACCOUNTS_RUNTIME_CAPABILITY and ...SKILL_RUNTIME_CAPABILITIES sit alongside the branch's CLAUDE_LAUNCH_ACCOUNT_RUNTIME_CAPABILITY and AGENT_SESSION_CLAUDE_ACCOUNT_RUNTIME_CAPABILITY, both retained.

The merge holds under a two-way check: git diff b032867 HEAD over the touched files contains only the branch's additions, and git diff 0fab477 HEAD contains only main's, so no branch line was lost and no main change was dropped.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/cli/specs/core.ts
#	src/cli/specs/orchestration-worker-specs.ts
#	src/main/agent-launch/agent-launch-mode.ts
#	src/renderer/src/components/settings/RepositoryPane.tsx
#	src/renderer/src/components/terminal-pane/TerminalErrorToast.tsx
#	src/renderer/src/lib/agent-session-launch-plan.ts
#	src/renderer/src/lib/launch-agent-in-new-tab.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed the single commit since the prior pullfrog review (9432b51): an origin/main merge (0aac4c7, main tip 62451920ed; ~30 main commits including #24205 structured chats on the paired server, #24945 SSH review context, #24998/#24997 jcode, #24923 git catalog reuse, bde1c09866 external worktree visibility, 2fc517c1c6 worktree set --unread/--read). Seven conflicts all resolved as clean unions, and pnpm tc:node, tc:web, and tc:cli are clean.

  • Merged origin/main and resolved all seven conflicts as unions, verified two ways (git diff 62451920ed 0aac4c7 over the conflict files contains only branch additions, so no main line was dropped; git diff 9432b51 0aac4c7 contains only main's changes, so no branch line was lost):
    • agent-launch-mode.ts — main's placement.on early return (remote_execution_host) and client-capability blocker sit alongside the branch's placement.claudeAccount early return and its host-side downgradeAgentLaunchModeForProjectClaudeAccount. The merge keeps executionHostId: 'local' because the on early return supersedes main's runtime:${on} support-probe path.
    • agent-session-launch-plan.ts — main's executionHostId/parseExecutionHostId verdict field and owner-unresolved catch-toast sit alongside the branch's launchPinsClaudeAccount/resolvePlannedRoute; buildAgentLaunchRouteInput is built once and shared.
    • launch-agent-in-new-tab.ts — main's structured-route-first block (launchStructuredAgentFromNewTab with its openTerminal recursion, before the web-runtime check) sits alongside the branch's stampClaudeLaunchAccount and claudeAccountId threading.
    • TerminalErrorToast.tsx — main's humanizeFolderWorkspacePathErrors and conditional issue link (isFolderWorkspacePathOnlyError) sit alongside the branch's describeClaudePinnedLaunchError short-circuit.
    • RepositoryPane.tsx — main's RepositoryRemoveProjectButton extraction and settingsSelectionKey/settingsEntryRepoIds threading sit alongside the branch's RepositoryClaudeAccountSection and RepositoryProjectSettingsSections.
    • core.ts / orchestration-worker-specs.ts — main's worktree-set.ts / repo.ts spec extractions and OMP note sit alongside the branch's --account flag/note and its worktree-create.ts extraction.

Verified: no conflict markers anywhere in src/; the src/main/claude-accounts suite (283 tests), the renderer routing/plan/launch and conflict-file suites (147 + 69 tests) are green. check:code-quality:changed reports zero design-system, focused-plugin, and type-aware findings; its 14 casting/React-Doctor findings are all pre-existing branch test-file casts (for example #22691's pinned-launch tests) untouched by this merge.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/cli/specs/orchestration-worker-specs.ts
#	src/main/agent-launch/agent-launch-executor.test.ts
#	src/main/runtime/orca-runtime-create-managed-worktree.ts
#	src/main/runtime/rpc/methods/orchestration/worker/local-worker-start.ts
#	src/main/runtime/rpc/methods/orchestration/worker/worker-start-validation.ts
#	src/renderer/src/components/tab-bar/QuickLaunchButton.tsx
#	src/renderer/src/components/tab-bar/use-tab-bar-create-menu-controller.ts
#	src/renderer/src/components/use-terminal-create-actions.ts
#	src/renderer/src/hooks/composer-state/quick-creation-execution.ts
#	src/renderer/src/lib/agent-session-launch-plan.ts
#	src/renderer/src/lib/launch-agent-in-new-tab.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed the single commit since the prior pullfrog review (0aac4c7): an origin/main merge (2c094bc, main tip d518d4a546). Eleven conflicts were all resolved as clean unions, and a git merge-tree comparison confirms no other file diverges from the automatic 3-way merge. pnpm tc:node, tc:web, and tc:cli are clean; the focused conflict-file tests (80) and the claude-accounts + pty suites (1267 pass / 6 skipped) are green.

  • Merged origin/main and resolved all eleven conflicts as unions, verified two ways (git diff d518d4a546 2c094bc over the conflict files contains only the branch's additions, so no main line was dropped; git diff 0aac4c7 2c094bc contains only main's changes, so no branch line was lost):
    • orchestration-worker-specs.ts — main's OpenCode --model note rides alongside the branch's --account flag and note.
    • agent-launch-executor.test.ts — the branch's saved-account describe block sits next to main's lineCarriesPrompt / agent / freshLaunch prompt-transport tests.
    • orca-runtime-create-managed-worktree.ts — the branch's resolveRequestedStartupAgent and startupClaudeAccountId sit alongside main's resolveWorktreeCreateAgentStartup and assertOpenCodeModelLaunchPreferencesAbsent.
    • local-worker-start.ts — the branch's assertClaudeAccountWorktreeIsLocal / claudeAccount sit alongside main's OpenCode probe and waitForWorkerAgentReady.
    • worker-start-validation.ts — the branch's withWorkerLaunchAccount / --account validation sit alongside main's openCodeModelLaunchSupported threading.
    • QuickLaunchButton.tsx — the branch's launchWithClaudeAccountChoice wrapper and deferred focus sit alongside main's onPromptHandedOff / disabled / newAgentPromptOutcome (main's onPromptHandedOff call survives).
    • use-tab-bar-create-menu-controller.ts, use-terminal-create-actions.ts, quick-creation-execution.ts, agent-session-launch-plan.ts, launch-agent-in-new-tab.ts — the branch's account routing and requestId additions unioned with main's resolveAgentSessionLaunchRoute / hookPreparation / targetGroupId.
  • Merge-only edits (5) — all benign: an oxfmt line-wrap in use-native-chat-draft.ts; the extraction of focusNewActiveTerminalWhenReady into a new new-tab-menu-terminal-focus.ts (keeps the controller under the 300-line cap at 290); and TerminalPaneSurface.tsx, agent-session-launch-plan.test.ts, and launch-agent-in-new-tab-claude-account.test.ts each adding main's now-required requestId to the branch's existing launch call sites.

Verified: no conflict markers in src/; all seven locale JSONs plus en-runtime-required.json parse with the ClaudePinnedLaunch block intact. All prior pullfrog threads were already [RESOLVED].

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/renderer/src/components/tab-bar/SortableTab.tsx

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

This run reviewed the single commit since the prior pullfrog review (2c094bc): an origin/main merge (8862679, main tip 10bea3a8fa) whose only conflict was in the renderer tab bar. git merge-tree confirms it is the sole content conflict, and diffing the result against the reconstructed auto-merge tree shows no other manual edit.

  • Merged origin/main (8862679), resolving the one conflict in src/renderer/src/components/tab-bar/SortableTab.tsx by adopting main's shared CLOSE_ALL_CONTEXT_MENUS_EVENT import from the new @/lib/close-all-context-menus module and dropping the branch's local export const, while keeping the branch's useClaudeTabAccountLabel tooltip suffix and onTooltipOpenChange wiring. No consumer imported the constant from ./SortableTab, so dropping the local export is safe, and main's extraction is a pure consolidation (same event string).
  • Verified the merge is otherwise mechanical — git diff <auto-merge-tree> 8862679 is limited to the three conflicted SortableTab.tsx lines, so no main change was dropped and no branch line was lost.

Verified: pnpm tc:web clean; the SortableTab render, tab-context-menu consistency, and claude-tab-account-label suites pass (20 tests).

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

…t-account

# Conflicts:
#	src/renderer/src/components/native-chat/use-native-chat-draft.ts
…t-account

# Conflicts:
#	src/shared/global-settings-types.ts
…t-account

# Conflicts:
#	src/shared/protocol-version.ts
…t-account

# Conflicts:
#	src/renderer/src/lib/launch-agent-in-new-tab.ts
…t-account

# Conflicts:
#	src/renderer/src/components/terminal-pane/use-terminal-pane-title-state.ts
…t-account

# Conflicts:
#	src/main/runtime/rpc/methods/orchestration/worker/local-worker-start.ts
#	src/main/runtime/rpc/methods/orchestration/worker/workers.ts
…t-account

# Conflicts:
#	src/cli/handlers/worktree.ts
…t-account

# Conflicts:
#	src/main/claude-accounts/runtime-auth-service.ts
#	src/main/ipc/pty/ipc/spawn-preflight.ts
#	src/main/ipc/pty/runtime/spawn-preflight.ts
…t-account

# Conflicts:
#	src/main/agent-launch/agent-launch-mode.ts
#	src/renderer/src/lib/agent-session-launch-plan.ts
…t-account

# Conflicts:
#	src/main/claude-accounts/runtime-auth-service.ts
…t-account

# Conflicts:
#	src/cli/handlers/worktree.ts
…t-account

# Conflicts:
#	src/main/runtime/orca-runtime-get-worktree-terminal-provisioning-host.ts
…t-account

# Conflicts:
#	src/renderer/src/components/tab-bar/QuickLaunchButton.tsx
#	src/renderer/src/lib/launch-agent-in-new-tab.ts
…t-account

# Conflicts:
#	src/renderer/src/components/native-chat/NativeChatComposer.tsx
…t-account

# Conflicts:
#	docs/reference/agent-status-store.md
…t-account

# Conflicts:
#	src/renderer/src/lib/agent-session-launch-plan.ts
#	src/renderer/src/lib/launch-agent-in-new-tab.ts
…t-account

Rebuilds pinned Claude launches on main's per-account folders (stablyai#24434, Step 4),
which removed credential replay.

A `--account` (or project-saved) launch on an account that is not the selected
one now runs Claude straight from that account's own folder: CLAUDE_CONFIG_DIR
points at it and the pane gets no which-account pointer, so a later switch of the
selected account never moves it. The selected account still takes main's normal
path.

Because no login is copied anywhere any more, the credential seeding, Keychain
read-back, per-account reservations, usage-fetch and account-switch guards, and
the host-terminal account tracking are removed. The pinned PTY registry keeps only
which PTY runs which account, for the tab and status labels, and the refusal codes
those guards produced (and the toast's Retry) are pruned.
…t-account

# Conflicts:
#	src/shared/protocol-version.ts

This branch has not been deployed

No deployments
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.

[Feature]: Per-project Claude account (ask on launch, remember per project)

2 participants