Skip to content

feat: provider sign-in status with one-click Sign in; onboarding finds recent repos (#1501 G1) - #1505

Merged
currentbits merged 6 commits into
mainfrom
coder/1501-g1-sign-in-status-first-run-discove-b9aca6
Oct 6, 2026
Merged

currentbits merged 6 commits into
mainfrom
coder/1501-g1-sign-in-status-first-run-discove-b9aca6

Conversation

@currentbits

Copy link
Copy Markdown
Owner

Item G1 of #1501.

Sign-in status

  • Probes: read-only status commands, each verified on a real machine signed in and signed out (scratch HOME):
    • claude auth status --json (loggedIn, counts API keys);
    • codex login status, which prints to stderr;
    • cursor-agent status --format json (isAuthenticated);
    • opencode auth list.
  • No status command (grok, kimi, muse): shown as "unknown". A set API-key env var turns a codex or cursor "signed out" into "unknown".
  • Timing: background probe at boot, never blocking. Re-probed when the picker or Settings › Agents opens, at most once per 30 s.
  • Where it shows: a Providers section in Settings › Agents, and a "Signed out" line with Sign in in the model picker.
  • Sign in (terminal:signIn) opens a fresh PTY with that provider's login command typed. The command comes from a fixed table, an unknown provider is rejected (tested with rm -rf), and binary paths are quoted. With a thread open it uses that thread's Terminal pane; otherwise a separate terminal in the home folder, closing Settings first.

First-run discovery: the onboarding Project step lists repos recently used with claude, codex, grok, kimi or opencode, read-only.

  • Worktrees map back to their main checkout, and repos are grouped by remote.
  • The most recent checkout in the 3 most recent groups is pre-ticked (≤14 days old), and one click adds them all.
  • About 340 ms on a real machine. Cursor and Muse aren't covered: their session paths can't be recovered reliably.

Merge with #1502: one import conflict in ipc-devserver.js (G1 added os and path; only os is used), resolved.

Verified independently, on main merged with this branch and #1502:

  • typecheck exits 0 and vite build passes.
  • test:electron passes 4207 of 4207.
  • test:renderer: 2796 passed and 1 failed. The failure was the markdownStream fuzz under load, which passes alone (19 of 19).
  • Read the terminal:signIn handler and its rejection test.

🤖 Generated with Claude Code

Willem and others added 6 commits October 6, 2026 16:17
Each provider's own read-only status command, verified on this machine
against the installed CLIs: claude auth status --json, codex login status
(stderr), cursor-agent status --format json, opencode auth list. grok,
kimi and muse have no status command and report unknown. An API key in
the env turns a codex/cursor 'signed out' into unknown.

The boot providers:list kicks the probe in the background; later lists
(picker, Settings > Agents) await a 30s rate-limited re-probe.
ProviderInfo.auth carries the result.

terminal:signIn types the login command from a fixed table into a fresh
'signin' shell: the thread's, or a dedicated home-directory shell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…icker (#1501)

Settings > Agents gets a Providers section (installed, signed in, Sign
in). The model picker flags a signed-out harness under its group label.
Sign in opens the open thread's Terminal pane on the login shell, or a
dedicated terminal sheet when no thread is on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1501)

projects:discoverRecent reuses the cli-sessions walkers (claude, codex,
grok, kimi) and the OpenCode db (read-only) to find where the user worked
lately, maps linked worktrees to their main checkout, and groups the
checkouts by git remote. The newest checkout of the three most recent
groups active in the last 14 days is pre-selected. Already-added projects,
the home dir and temp dirs are left out. Cursor (lossy dir names) and Muse
(cwd buried in nested records) are not scanned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Project step lists discovered repos by remote, recent ones ticked,
with one Add button; the folder picker becomes the secondary action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…irst (#1501)

A reveal that lands before terminal.list now still adds its split, is
bound to its thread, and an empty list opens only the revealed shell.
Sign in closes Settings before the dedicated sheet opens: two modal focus
traps recursed. The dev fixture seeds mixed sign-in states.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inal-cleanup-ebd61c' into g1-resolve

# Conflicts:
#	electron/ipc-devserver.js
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T14:49:17.863989Z 1c62e01 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c62e01802

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread electron/ipc-devserver.js
Comment on lines +191 to +192
terminal.open(threadId, root, { project, termId, logDir, broadcast: ctx.broadcast });
terminal.write(threadId, `${command}\r`, termId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fall back to local sign-in for SSH threads

When the visible thread belongs to an SSH project, terminalRoot passes that remote project to terminal.open, whose remote-project branch creates a dead session saying that terminals are unavailable and returns before spawning a shell. The following terminal.write is therefore ignored, but this handler still reports success and the UI reveals a terminal in which the login command never ran. Use the dedicated local sign-in terminal for remote threads or return an explicit error.

Useful? React with 👍 / 👎.

Comment thread src/App.tsx
Comment on lines +1107 to +1109
const closeSignInShell = useCallback(() => {
setSignInShell(null);
void refreshProviders();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Close the dedicated sign-in PTY with its modal

When sign-in starts without an open thread, closing the modal via Done, Escape, or the backdrop only hides it and refreshes providers. TerminalPane cleanup disposes the renderer-side xterm but intentionally leaves the main-process terminal session running, so an in-progress login becomes unreachable and a completed login leaves an invisible shell alive until another sign-in or application exit. Close the SIGNIN_TERMINAL_ID/signin terminal before clearing the modal.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant