Skip to content

Agent follow-ups: bridge login, unlock prompt, quick window, recent chats - #131

Merged
its-janghoon merged 6 commits into
developfrom
feat/agent-followups
Oct 19, 2026
Merged

its-janghoon merged 6 commits into
developfrom
feat/agent-followups

Conversation

@its-janghoon

Copy link
Copy Markdown
Member

What's done

  • Agent login on the app bridge: the phone/daemon can ask the browser to sign in. Same VaultPolicy, fill path and audit log as the in-browser tool; the model never sees the password.
  • Only the app bridge may call Browser.redrobLogin: per-run secret, handed only to the agent server the browser launches (child environment, not argv), constant-time check.
  • Unlock from the task flow: a task blocked on a locked store gets an Unlock button in its notification (OS re-auth), then the fill retries.
  • Quick window keeps the process alive while it is open.
  • Horizontal-tab mode: a recent-chats button next to account/settings on the toolbar.
  • redrob.py export normalisation of the hand-edited patches.

What's not done

  • A chat item still opens the new tab (same as the sidebar's OpenChat); it does not jump into the chat.
  • If the user cancels the OS unlock prompt, the notification is not shown again; Settings is the fallback.

What to review

  • sources/chrome/browser/redrob/app_bridge_token.h and the two server_process_launcher*.cc patches (Windows environment block via AlterEnvironment + CREATE_UNICODE_ENVIRONMENT).
  • browser_handler.cc RedrobLogin: the token check runs before any tab lookup.

Intentions

Close the gaps v0.3.0 shipped with. Built once locally (linux release, 0 failures); the binary started, the agent server got the bridge secret in its environment and the browser process itself did not.

The app bridge's tool list (browser-bridge.ts) gains `login`. It calls a new
async CDP command, Browser.redrobLogin, whose handler finds the tab and hands
it to TaskStore::LoginFromBridge in the browser process. That runs the same
CredentialTools gate (policy, per-site list, unlock window), the same
password-manager fill and the same audit log as the in-browser agent's tool,
recorded under task id "app-bridge". The answer is CredentialTools'
model-facing text, so no password can reach the bridge. A locked store
answers at once ("ask the user to unlock") since the bridge has no task to
park.

Hand patches edited: Browser.pdl, inspector_protocol_config.json,
browser_handler.{h,cc}, devtools/BUILD.gn (dep on //chrome/browser/redrob:sidecar).
A task parked on a locked store (While unlocked policy, credential wait with
needs_unlock) now raises the same "Task needs you" OS notification a guarded
click does, with the waiting-unlock text and one Unlock button. The button
reveals the task's tab and calls TaskStore::UnlockCredentials anchored to it:
the same DeviceAuthenticator re-auth Settings uses, and on success
OnCredentialsUnlocked resumes every waiting task and retries the fill.

No unlock is attempted without an anchor tab, because CredentialTools::Unlock
treats a null anchor as "no authenticator" and would skip the OS prompt on
macOS/Windows. New string: taskNotifyUnlock.
With no browser window open, the quick window was the only thing on screen
and nothing held the process, so it could exit under it. QuickWindowService
now holds a ScopedKeepAlive and a ScopedProfileKeepAlive (the same
BACKGROUND_MODE_MANAGER / kBackgroundMode origins TaskStore::UpdateKeepAlive
uses for surviving tasks) from Show() until Close(). Close releases them with
DeleteSoon after the widget's own deletes, so shutdown cannot start while the
window's WebContents is still alive; Shutdown() drops them synchronously.
With tabs across the top the sidebar column, and its recent-chats section,
is hidden. AttachToolbarAccess now adds a chats button (chat_spark icon,
"Chats" name/tooltip) between the avatar and Settings; it opens a menu of
the same rows the sidebar shows. RecentChats() is factored out of
RebuildChats so both surfaces read one list (TaskStore::ListTasks, newest
first, kMaxChatRows), and a menu item goes through the same OpenChat. Empty
state is the sidebar's own note as a disabled item. Menu commands use their
own id range in the shared ExecuteCommand. History (Ctrl+H) untouched.
Any CDP client on the debugging port could ask the agent to sign in. The
browser now makes a per-run secret (app_bridge_token.h), gives it only to the
agent server it launches, in that child's environment (POSIX LaunchOptions,
Windows CreateProcessW environment block), and Browser.redrobLogin refuses a
call without it (constant-time compare). The bridge's login tool reads
REDROB_APP_BRIDGE_TOKEN and sends it as bridgeToken.
…_token.h

redrob.py export over the applied checkout: index hashes and hunk headers of
the hand-edited patches now match the tree they were built from. Adds the
new app_bridge_token.h to sources/manifest so apply copies it.
@its-janghoon
its-janghoon merged commit 052e112 into develop Oct 19, 2026
5 checks passed
@its-janghoon its-janghoon mentioned this pull request Oct 19, 2026
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