Skip to content

Add Kagi search support with encrypted private session links#1434

Merged
Jinwoo-H merged 5 commits intostablyai:mainfrom
P-de-Jong:feat-kagi
May 7, 2026
Merged

Add Kagi search support with encrypted private session links#1434
Jinwoo-H merged 5 commits intostablyai:mainfrom
P-de-Jong:feat-kagi

Conversation

@P-de-Jong
Copy link
Copy Markdown
Contributor

@P-de-Jong P-de-Jong commented May 5, 2026

Summary

  • Adds Kagi as a default browser search engine option.
  • Adds an optional masked Kagi private session link field when Kagi is selected.
  • Uses the Kagi private session link for address-bar searches when configured.
  • Redacts Kagi token params from browser display, history, external-open URLs, and persisted browser tab state.
  • Encrypts the stored Kagi session link at rest using Electron safeStorage, matching the existing opencodeSessionCookie
    persistence pattern.

Screenshots / Recordings

image

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm exec vitest run --config config/vitest.config.ts src/shared/browser-url.test.ts src/renderer/src/store/slices/ui.test.ts src/renderer/src/store/slices/browser.test.ts src/main/persistence.test.ts
  • pnpm test
  • pnpm build

Notes: pnpm lint passes with existing unrelated React hooks warnings in GitHub project components. Full pnpm test currently shows
broad infrastructure failures across daemon/orchestration/git/runtime suites in this local environment before reaching completion.

Cross-Platform Review

This change is URL/settings/persistence logic only. It does not introduce platform-specific keyboard shortcuts, labels, filesystem
paths, or shell behavior. The feature should behave consistently on macOS, Linux, Windows, and SSH-backed workspaces.

Security Review

Kagi private session links contain bearer-style account tokens. The setting is masked in UI, validated to Kagi search session links,
redacted from display/history/tab persistence, and encrypted at rest with Electron safeStorage before being written to orca- data.json.

If safeStorage.isEncryptionAvailable() is false, Orca falls back to plaintext using the existing persistence helper behavior,
matching current handling for opencodeSessionCookie.

P-de-Jong and others added 3 commits May 6, 2026 13:06
# Conflicts:
#	src/renderer/src/store/slices/ui.test.ts
#	src/renderer/src/store/slices/ui.ts
- redact in setBrowserPageUrl normalizeUrl so CDP nav-update IPC cannot
  land tokens in BrowserPage.url (persisted to disk)
- redact pageUrl in setupGuestContextMenu before the context-menu IPC
- redact validatedUrl in sendGuestLoadFailure
- redact in popup shell.openExternal for target=_blank popups
- redact addressBarValue in submitAddressBar and chrome-error polling
- tighten normalizeKagiSessionLink (reject user-info/port, accept
  trailing slash, collapse duplicate token via set)
- align redactKagiSessionToken to also match /search/ trailing slash
- regression tests: setBrowserPageUrl redaction at slice boundary plus
  new normalize/redact cases

Co-authored-by: Orca <help@stably.ai>
@Jinwoo-H
Copy link
Copy Markdown
Contributor

Jinwoo-H commented May 7, 2026

Thanks for the feature! Pushed a few tweaks before merging:

  • redact in setBrowserPageUrl's normalizeUrl so the agent-browser CDP nav-update IPC (browser:navigation-update -> useIpcEvents -> setBrowserPageUrl) cannot land a token into BrowserPage.url, which is persisted to disk via the workspace session writer.
  • redact pageUrl in main inside setupGuestContextMenu before the browser:context-menu-requested IPC, so right-click "Copy Page URL" and "Open Page In Default Browser" never see the bearer token.
  • redact validatedUrl in sendGuestLoadFailure so a transient load failure on a Kagi page does not persist the token in BrowserPage.loadError.
  • redact in the popup shell.openExternal call inside browser-manager (target=_blank from a Kagi result was handing the token to the OS default browser).
  • redact addressBarValue in submitAddressBar's loadError path and in the chrome-error polling fallback (raw user paste was reaching loadError.validatedUrl).
  • tighten normalizeKagiSessionLink to reject user-info credentials and non-default ports, accept /search/ trailing slash, and collapse duplicate token params via set instead of preserving both. Mirror the trailing-slash acceptance in redactKagiSessionToken so a session link saved with a trailing slash still gets redacted on display.
  • regression tests: setBrowserPageUrl token-redaction at the slice boundary, plus the new normalize/redact cases.

Heads-up on one user-visible behavior shift these tweaks introduce: the Retry button on a failed Kagi page navigates to the redacted URL (no token), so a Kagi load failure needs to be re-submitted from the address bar to reattach the session link. The alternative is persisting the token in loadError.validatedUrl, which defeats the point. Worth a one-liner in the docs if Kagi ends up with one.

@Jinwoo-H Jinwoo-H merged commit 45d05c3 into stablyai:main May 7, 2026
2 checks passed
@P-de-Jong
Copy link
Copy Markdown
Contributor Author

@Jinwoo-H no problem, been loving Orca with the addition of the app!
If theres any help needed somewhere let me know, happy to help.

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