Skip to content

feat(gui): native Kiro device login and auto-selection chips in the dashboard - #6016

Merged
lidge-jun merged 3 commits into
devfrom
codex/kiro-lb2-100-gui-device-login
Sep 27, 2026
Merged

lidge-jun merged 3 commits into
devfrom
codex/kiro-lb2-100-gui-device-login

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Summary

The dashboard could only add a Kiro account through kiro-cli, and nothing showed why the router skipped an account. Both already work on the server side: native device login landed in #6001, and per-account autoSelectable / skipReason in #6002. This PR exposes them in the GUI.

Login. Kiro's Add account and Login buttons now open a chooser:

  • Kiro CLI is listed first. It is the unchanged one-click import, and it still sends the same request.
  • Builder ID, Google and GitHub start a native device sign-in.

Dialog. The dialog shows the user code with a copy button and a status line. It also has an "Open verification page" link, rendered only for the exact verification hosts: device.sso.us-east-1.amazonaws.com, and kiro.dev or its subdomains. Any other URL is shown as plain text next to a warning.

Cancel and close. Cancel and ESC cancel the flow by flowId. The server can answer a cancel with done once the commit has begun, so that reply is treated as provisional, and success is shown only after a status reply confirms it.

Finishing after close. A module-level finalizer finishes any flow the dialog stops watching (close, unmount, or navigating to another provider). The cancel is sent first, then the finalizer reads status until the flow ends. That status read is also what makes the server reconcile its running config after a successful add. A 404 is treated as "login ended", not "expired", and never shows a success notice.

Account rows. Kiro rows now show "Not auto-selected: quota exhausted / suspended". Nothing extra is shown where an existing badge already says the same thing (reauth, cooldown).

Unchanged:

  • The existing kiro-cli and non-Kiro login loop keeps its guards, roster seed and notices. Only its refresh calls moved into two helpers, split at the existing guard.
  • The add-provider modal and the catalog rows still use kiro-cli.
  • Native login remains add-only: it never replaces an account and never signs kiro-cli out.
Chooser Device code Skip-reason chips
chooser device code chips

The screenshots were taken from a real proxy on an isolated OPENCODEX_HOME. A scratch shim sat in front of it and returned fixture replies for the device-login calls and the Kiro account roster, so no live Kiro or AWS call was made.

Known limit: if the whole browser tab is closed during the few seconds of a commit, the account is saved on disk, but the running config is not reconciled until the next reload. This existed before (#6001) and is recorded as a server follow-up in 000_plan.md.

Plan and audit trail: devlog/_plan/260926_kiro_lb_parity2/100_gui_device_login_and_skip_reason.md.

Verification

  • cd gui && bun test --isolate tests: 2,577 pass, 0 fail. The new kiro-device-login.test.tsx and kiro-account-skip-reason.test.tsx cover:
    • provisional done on cancel, then done or failed;
    • a lost done followed by 404;
    • a cancel that never resolves;
    • close during start or during body parsing;
    • request order (cancel before any status read);
    • a double start;
    • rejected roster reloads;
    • host spoofing (kiro.dev.evil.com, evilkiro.dev, x.awsapps.com, S3 hosts, userinfo, port, http, control characters);
    • the chip rules;
    • kiro-cli still sending no method.
  • GUI lint:i18n, lint, build, doctor (54 files, no issues): all pass.
  • Root checks all pass: typecheck, file-size-ratchet plus structure-ssot (60 pass), structure:check, privacy:scan, and the docs-site build (537 pages).
  • The plan went through an architect reflection and three audit rounds, ending GO-WITH-FIXES with 0 High. The code went through three independent review rounds, ending APPROVE.
  • Hosted CI: see the follow-up comment.

Checklist

  • Scope stays focused and avoids unrelated cleanup. (gui/, docs, structure only; no src/ change)
  • Docs or release notes were updated when needed. (guides/providers.md, reference/cli/providers-accounts.md, structure/gui-and-management-api.md)
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. (No codes, tokens or URLs are logged; the verification link uses an exact host allowlist with rel="noopener noreferrer"; cancel is scoped by flowId)

Summary by CodeRabbit

  • New Features
    • Kiro’s dashboard Login and Add account flows now offer Builder ID, Google, and GitHub device login alongside the Kiro CLI. Native sign-in adds an account without signing out of the CLI.
    • The device-login dialog displays the authorization code and progress, with copy, retry, and status messages. Verification links are provided only for recognized destinations.
    • Kiro accounts that aren’t automatically selectable can show a reason badge.
  • Documentation
    • Updated provider guides to explain Kiro login options and account-selection status.

…ashboard

Kiro's Add account and Login buttons open a chooser: Kiro CLI (unchanged
import), Builder ID, Google or GitHub device sign-in. The dialog shows the
user code, links only to the exact Kiro/AWS verification hosts, cancels by
flowId, and hands an unfinished flow to a module-scoped finalizer so the
server reconciles a committed login after the dialog closes. Kiro account
rows show why an account is not auto-selected (quota exhausted, suspended).

Plan: devlog/_plan/260926_kiro_lb_parity2/100_gui_device_login_and_skip_reason.md
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 27, 2026 00:11
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 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-09-27T00:15:09.619039Z de640c3 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.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Sep 27, 2026
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: b0aa85f1-811f-445b-b5d4-e93883726608

📥 Commits

Reviewing files that changed from the base of the PR and between e69347a and ab10748.

📒 Files selected for processing (28)
  • devlog/_plan/260926_kiro_lb_parity2/000_plan.md
  • devlog/_plan/260926_kiro_lb_parity2/100_gui_device_login_and_skip_reason.md
  • docs-site/src/content/docs/guides/providers.md
  • docs-site/src/content/docs/reference/cli/providers-accounts.md
  • gui/src/components/KiroDeviceLoginDialog.tsx
  • gui/src/components/KiroLoginChooser.tsx
  • gui/src/components/provider-workspace/ProviderAuthPanel.tsx
  • gui/src/components/provider-workspace/types.ts
  • gui/src/components/use-kiro-device-login.ts
  • gui/src/hooks/useProviderAccountPools.ts
  • gui/src/i18n/de.ts
  • gui/src/i18n/en.ts
  • gui/src/i18n/fr.ts
  • gui/src/i18n/ja.ts
  • gui/src/i18n/ko.ts
  • gui/src/i18n/ru.ts
  • gui/src/i18n/tr.ts
  • gui/src/i18n/vi.ts
  • gui/src/i18n/zh-TW.ts
  • gui/src/i18n/zh.ts
  • gui/src/kiro-device-login-finalizer.ts
  • gui/src/kiro-device-login-helpers.ts
  • gui/src/pages/Providers.tsx
  • gui/src/pages/use-providers-oauth.ts
  • gui/src/styles/kiro-device-login.css
  • gui/tests/kiro-account-skip-reason.test.tsx
  • gui/tests/kiro-device-login.test.tsx
  • structure/gui-and-management-api.md
 __________________________________________________________
< Sometimes, I pretend to be a compiler to feel important. >
 ----------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

@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: de640c340e

ℹ️ 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 on lines +205 to +207
const openLogin = (addAccount: boolean) => {
if (item.name === "kiro") setKiroChooser({ addAccount });
else void authHandlers?.onLogin(item.name, addAccount);

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 Route the add-provider Kiro buttons through the chooser

This interception covers only the workspace ProviderAuthPanel. In the Add provider modal's Accounts tab, CatalogAccountRow.tsx still sends Kiro's Login/Add account buttons through Providers.onAccountLogin, which calls requestLoginOAuth directly. Those dashboard buttons therefore bypass the new chooser and immediately launch the legacy Kiro CLI flow; Add account can even sign the CLI out temporarily. Route the modal's Kiro actions through the same chooser.

Useful? React with 👍 / 👎.

Comment on lines +66 to +70
const refreshDerivedAfterLogin = useCallback(() => {
void fetchConfig();
void fetchProviderQuotas(true);
bumpModelsRefresh();
}, [fetchConfig, fetchProviderQuotas, bumpModelsRefresh]);

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 Refresh OAuth status after native login

When a native login adds an account, this refresh path updates the roster, config, quotas, and models but never calls fetchOauth or updates oauthStatus. Since accountLoginStatus is derived solely from oauthStatus, reopening the Add provider Accounts tab can continue showing Kiro as logged out and offer Login rather than Add/Manage until the page is reloaded. Refresh OAuth status here as the other login/logout paths do.

Useful? React with 👍 / 👎.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 63 / 80

이 PR은 대시보드의 Kiro 로그인에 기기 로그인을 붙입니다. 공급자 화면의 로그인 버튼과 계정 추가 버튼이 선택 창을 엽니다. 맨 위는 Kiro CLI입니다. 이 버튼은 예전과 같은 가져오기 요청을 보냅니다. Builder ID, Google, GitHub는 서버에 기기 로그인을 시작합니다. 창에는 사용자 코드와 복사 버튼이 있습니다. 확인 페이지로 가는 링크는 두 종류의 주소만 됩니다. device.sso.us-east-1.amazonaws.com, 그리고 kiro.dev와 그 하위 주소입니다. 다른 주소는 글자로만 나옵니다. 옆에 이상한 주소라는 경고가 붙습니다. 취소와 ESC는 그 로그인 번호(flowId)로 서버에 취소를 보냅니다. 창을 닫아도 페이지 밖에 있는 마무리가 상태 조회를 이어 갑니다. 저장이 끝난 계정은 목록에 다시 읽어 옵니다. Kiro 계정 줄에는 자동으로 고르지 않는 이유가 붙습니다. 한도를 다 썼거나, 계정이 정지된 경우입니다. 다시 로그인 배지나 쿨다운 배지가 이미 있으면 같은 말은 또 쓰지 않습니다. 베이스는 dev입니다. 이 화면을 겹쳐 고치는 다른 열린 PR은 없습니다.

라인 - gui/src/pages/use-providers-oauth.ts 66행. 네이티브 로그인이 끝나면 refreshDerivedAfterLogin이 설정과 할당량과 모델만 다시 읽습니다. fetchOauth는 여기서 호출되지 않습니다. CLI 로그인 루프는 182행에서 상태 응답을 oauthStatus에 넣습니다. gui/src/pages/Providers.tsx 534행은 그 oauthStatus로 공급자 추가 창의 로그인 표시를 만듭니다. 작업 공간의 계정 목록은 fetchAccountSets로 새 계정을 보여 줍니다. 공급자 추가 창은 로그인 전으로 남습니다. 로그인 버튼이 그대로 있고, 그 버튼은 Kiro CLI 가져오기를 시작합니다.

라인 - gui/src/components/use-kiro-device-login.ts 107행. 창이 열린 채로 코드 만료 시각이 되면 세션을 끝내고 상태 조회를 멈춥니다. finalizeKiroDeviceFlow로 넘기지 않습니다. 성공·실패 콜백도 호출하지 않아서 계정 목록을 다시 읽지 않습니다. gui/src/kiro-device-login-finalizer.ts 54행은 만료 시각 뒤로 60초 동안 상태 조회를 계속합니다. 창이 열려 있으면 그 조회가 시작되지 않습니다. 서버가 그 60초 안에 계정을 저장해도 목록은 그대로입니다. 그 뒤에 취소를 눌러도 세션이 이미 비어서 마무리로 넘어가지 않습니다.

라인 - gui/src/pages/use-providers-oauth.ts 81행. 사용자가 취소를 눌러 서버가 cancelled로 끝내면 결과는 ended가 됩니다. 알림 문구는 "Login ended. Check the account list."입니다. 취소를 마친 사람에게도 목록을 확인하라는 경고가 뜹니다.

메인테이너의 판단이 필요한 지점

공급자 추가 창의 Kiro 버튼을 이번 선택 창에 연결할지 정해야 합니다. 이번 PR은 그 버튼을 Kiro CLI로 남겨 두었습니다. 534행의 로그인 표시가 옛 값이면, 방금 계정을 넣은 뒤에도 그 버튼은 첫 로그인으로 보입니다.

81행 알림을 취소에는 끌지 정해야 합니다. 저장이 겹쳤을 때를 위해 목록 확인 문구를 남길 수도 있습니다.

너의 추천

onNativeLoginSettled에서 계정 목록을 다시 읽은 다음 fetchOauth()를 호출하세요. 공급자 추가 창의 로그인 표시가 새 계정을 따라갑니다. 107행에서는 시간만 보고 세션을 끝내지 마세요. 창을 닫을 때와 같이 finalizeKiroDeviceFlow에 넘기세요. 그 결과가 added일 때만 성공 알림을 띄우세요. 서버가 cancelled로 끝나면 81행 알림은 띄우지 마세요. 베이스는 dev로 두세요. 닫을 중복 PR은 없습니다.

이 댓글은 grok-bot이 작성했습니다

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Requesting one P2 lifecycle correction on exact head ab107482b9.

use-kiro-device-login.ts sends the status fetch without an abort signal and hands Response.clone() to the finalizer. In kiro-device-login-finalizer.ts, the current bounded wrapper ends as soon as it obtains that Response; the following response.json() has no deadline. If headers arrive but the body never finishes, then close/unmount hands off a permanently pending stream: the stated 45-second read bound and 16-minute finalizer bound are bypassed, subsequent reconciliation/terminal notice/roster refresh never run, and the active entry is never released.

Please bound both obtaining and consuming inherited responses, then add a regression using a real never-closing ReadableStream handed off by close/unmount. The current parsing test delays only the original Response's overridden json() while its clone already has a complete fixture body, so it does not exercise this transport stall.

The rest of the reviewed auth/verification-link boundaries are coherent; do not weaken exact flow-id ownership or the existing HTTPS/hostname restrictions while fixing this.

@lidge-jun
lidge-jun enabled auto-merge (squash) September 27, 2026 00:35
@lidge-jun

Copy link
Copy Markdown
Owner Author

Exact-head CI on ab10748: test 1-4/4, gates, react-doctor, structure gate, docs site build, docker smoke, npm-global (ubuntu/windows), keyring, desktop shell all pass; remaining jobs skipped by path filter. Local receipt at the same head: GUI 2,577 pass / 0 fail, ratchet + structure 60 pass, structure:check and privacy:scan pass.

@lidge-jun
lidge-jun merged commit d8b85ad into dev Sep 27, 2026
34 of 35 checks passed
@lidge-jun
lidge-jun deleted the codex/kiro-lb2-100-gui-device-login branch September 27, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants