Skip to content

feat(cli): add tab profile controls and automation primitives#1396

Merged
Jinwoo-H merged 7 commits intostablyai:mainfrom
Nikolatesla-lj:feat/cli-browser-profiles
May 5, 2026
Merged

feat(cli): add tab profile controls and automation primitives#1396
Jinwoo-H merged 7 commits intostablyai:mainfrom
Nikolatesla-lj:feat/cli-browser-profiles

Conversation

@Nikolatesla-lj
Copy link
Copy Markdown
Contributor

@Nikolatesla-lj Nikolatesla-lj commented May 4, 2026

Summary

  • add browser tab profile controls to the Orca CLI
  • add browser tab inspection and profile automation primitives
  • keep the command surface under tab / tab profile

What changed

  • added orca tab create --profile <id>
  • added orca tab list --show-profile
  • added orca tab profile set --page <id> --profile <id>
  • added orca tab show --page <id>
  • added orca tab current [--worktree <selector|all>]
  • added orca tab profile show --page <id>
  • added orca tab profile use-default --page <id>
  • added orca tab profile clone --profile <id> [--page <id>] [--worktree <selector>]
  • threaded sessionProfileId through guest registration so tab profile state is visible to CLI automation

Why

Orca already has browser session profile support in the UI and runtime state, but the CLI could not reliably control or inspect that state.

This PR focuses on the tab-scoped controls that automation needs:

  • choose a profile when opening a tab
  • inspect the current tab and its bound profile
  • switch a tab back to the default profile
  • clone the current page into a different profile without mutating the original tab

It intentionally does not add profile lifecycle commands or any round-robin policy layer.

Tests

  • ./node_modules/.bin/vitest run src/cli/browser.test.ts src/cli/index.test.ts src/main/browser/browser-manager.test.ts src/main/browser/agent-browser-bridge.test.ts
  • ./node_modules/.bin/tsc --noEmit -p config/tsconfig.cli.json --composite false
  • ./node_modules/.bin/tsc --noEmit -p config/tsconfig.node.json --composite false

@Nikolatesla-lj Nikolatesla-lj changed the title feat(cli): add browser tab profile controls feat(cli): add tab profile controls and automation primitives May 4, 2026
@Jinwoo-H Jinwoo-H self-requested a review May 5, 2026 05:33
@Jinwoo-H Jinwoo-H self-assigned this May 5, 2026
@Jinwoo-H Jinwoo-H force-pushed the feat/cli-browser-profiles branch from d6a5630 to 2b7ce36 Compare May 5, 2026 05:45
@Jinwoo-H
Copy link
Copy Markdown
Contributor

Jinwoo-H commented May 5, 2026

Nice! Rebased onto main (one tiny conflict in useIpcEvents.ts, kept both imports) and pushed a small hardening commit on top.

couple of real fixes:

  • tab profile set now waits for the tab to re-register before returning, otherwise a follow-up tab list --show-profile could read the old profile
  • tab profile clone does the same wait, matching tab create — was returning a page id that wasn't operable yet
  • short-circuits when you set a tab to the profile it's already on so we don't tear down and remount the webview for nothing
  • tiny schema fix: TabShow.worktree was OptionalPlainString while every other tab schema uses OptionalString

@Jinwoo-H Jinwoo-H force-pushed the feat/cli-browser-profiles branch from 4d9803c to e690b85 Compare May 5, 2026 06:10
Nikolatesla-lj and others added 7 commits May 5, 2026 02:40
- Wait for tab re-registration after browser.tabSetProfile so a follow-up tab list --show-profile reads the new sessionProfileId from BrowserManager instead of the stale one from the previous webview
- Wait for tab registration after browser.tabProfileClone, matching browser.tabCreate, so the cloned browserPageId is operable when the CLI returns
- Short-circuit browser.tabSetProfile when the tab is already on the requested profile so we do not tear down and remount the webview for a no-op switch
- Switch TabShow.worktree from OptionalPlainString to OptionalString to match every other tab schema; empty --worktree should fall back to the active worktree, not pass through as the empty string
- Add max-lines disable to browser.test.ts (file grew past 300 lines after adding the new tab-profile and tab-show tests)
CI failure: useIpcEvents.test.ts threw at module load with TypeError: window.addEventListener is not a function. The chain: the rebased useIpcEvents.ts imports destroyPersistentWebview from webview-registry, which calls window.addEventListener at module load. The test stubs window via vi.stubGlobal as a plain object without addEventListener, so the typeof window check passes but the call throws.

- webview-registry.ts: tighten the module-load guard to also check that window.addEventListener is callable, so importing this module from a non-DOM-ish test env (vitest node env with stubbed window) does not throw at module load
- useIpcEvents.test.ts: add the new onRequestTabSetProfile and replyTabSetProfile stubs to all 8 window.api.ui mocks so the new IPC subscription registered by useIpcEvents resolves
The rebase brought commit 3242aa2 (refactor: narrow tab profile automation scope) onto a main that already had the lifecycle CRUD from 1397. The refactor commit removes BrowserProfileList/Create/Delete types, runtime methods, RPC registrations and schemas, plus the help/specs entries, because those were the precursor versions in commit 1 of this branch. Post-rebase those removals land on the hardened versions inherited from main, breaking 1397.

Restore:
- runtime-types.ts: BrowserSessionProfile import; ProfileList/Create/Delete result types
- orca-runtime.ts: ProfileList/Create/Delete result type imports; browserProfileList/Create/Delete methods
- browser-core.ts: ProfileCreate, ProfileDelete schema imports; browser.profileList/profileCreate/profileDelete RPC registrations
- browser-schemas.ts: ProfileCreate, ProfileDelete zod schemas
- help.ts: list/create/delete subcommand lines under Browser Automation
- specs/browser-basic.ts: list/create/delete spec entries
@Jinwoo-H Jinwoo-H force-pushed the feat/cli-browser-profiles branch from e690b85 to d9e5cc8 Compare May 5, 2026 06:41
@Jinwoo-H Jinwoo-H merged commit e623372 into stablyai:main May 5, 2026
2 checks passed
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.

2 participants