Files
orca/docs/site
Brennan Benson 6b43714c54 feat(agent-sessions): rename "Continue in New Session" to "Hand Off to Another Agent" (#26375)
* feat(session-history): resume a native chat's conversation in a new CLI session

Agent Session History offered "Resume in New Chat" to move a terminal session
into native chat, but nothing went the other way: once a native chat owned a
conversation, its row only reopened the chat, and Orca refused any terminal
resume of it so two programs never write one conversation.

Rows a native chat owns (Claude, Codex) now offer "Resume in New CLI". It forks:
the terminal runs `claude --resume <id> --fork-session` or `codex fork <id>`,
so the CLI gets the full history under a new id and the chat is unchanged. The
host's resume guard lets a Claude fork through, and the fork tab records no
provider session, so a restart never re-enters the chat's conversation.
"Resume in New Chat" is renamed "Resume in New Native Chat".

* fix(session-history): size the Resume in New CLI tooltip to its text

The tooltip balanced one wrapped string inside a box sized before balancing,
leaving a gap beside its lines. It is now two block lines with no fixed width.

* feat(agent-sessions): rename "Continue in New Session" to "Hand Off to Another Agent"

Agent Session History rows now offer "Resume in New Native Chat", "Resume in
New CLI" and "Continue in New Session…", which read as three versions of one
action. Only the first two carry the same conversation; the third starts a new
session, often with another agent, seeded with a summary or the transcript.

Rename it everywhere it appears (history sidebar, terminal pane header and
menu, native chat menu, the dialog title) and, in the history row menus, move
it below "Copy Resume Command" behind a separator so the Resume items read as
one group.

* fix(session-history): run a CLI fork under the selected Codex account and tighten the fork guard

- Resume in New CLI now asks the host for the same Codex account home plain
  Resume uses, so a fork no longer starts under whichever account's copy of the
  rollout sorted first. The preparation call carries an optional `fork` flag
  that skips only the owned-conversation refusal; plain resume still refuses.
- An older paired host that refuses the fork now shows "Update Orca on the host
  that runs this chat to resume it in a new CLI." instead of a raw error code.
- The host guard admits `--fork-session` only before a `--` terminator and
  never alongside `--session-id`, since either shape lets Claude write the
  owned conversation.
- Tests for the click path, the menu item's eligibility, the fork home
  preparation, and the tightened guard.

* fix(session-history): read a Codex rollout's identity from its first session record

A fork of an older (non-paginated) Codex thread writes its own session record
first and then copies the parent's history, the parent's session record
included. The history scanner kept the last one it saw, so the fork's row took
the parent's id, title, folder and branch: on a native chat's fork it looked
like the chat itself, and Resume on it opened the chat instead of the fork.
Codex itself treats the first session record as the thread's own and ignores
later ones; the scanner now does the same, as Orca's duplicate-rollout check
already did.

* fix(session-history): set up status hooks in the Codex home a CLI fork keeps

When Resume in New CLI can't move a Codex fork to the selected account (that
account has no copy of the conversation yet, or the system default is
selected), the fork runs in the account home the history row came from. A new
Codex tab only gets Orca's status hooks in the selected account's home, and the
fork carries no provider session, so nothing set up the hooks in that row home.
In a home only native chat had used, the fork tab could show no working or
idle status.

The fork's home preparation now readies that home the same way a resumed
session's home is readied (hook install or refresh, plus the daemon-socket
guard). That code is moved into prepareCodexPinnedLaunchHome and shared by both
paths. The fork tab still carries no provider session, so it never reopens the
chat's conversation on restart.

* fix(session-history): ready only a host-verified Codex home for a CLI fork

The fork's hook setup ran in whatever Codex home the request named, so a paired
client could have Orca write hook and config files into any directory. Plain
Resume only readies a home it has verified: one this host lists for Codex
sessions that actually holds the rollout. The fork now uses that same check,
through a shared trustedCodexResumeHomes list, and readies the home only when
the verified home is the one the fork will run in. With no Codex runtime home
service it does nothing, as plain Resume does. A failed check or setup is
logged and never stops the fork from launching.

Tests cover the untrusted home, a missing runtime home service, a rollout on
another host, a WSL home, a fork moved into the real home, and a failed setup.

* fix(session-history): show the host-update message when the desktop wraps the fork refusal

When the local preparation step for Resume in New CLI is refused, Electron
hands the renderer the error as "Error invoking remote method '…': Error:
agent_session_conflict". The fork's failure text matched only the bare code,
so the toast showed that raw line instead of asking the user to update Orca on
the host. It now unwraps the message with the shared IPC error helper before
matching.

* test(agent-session-history): cover Hand Off placement and separator; rename Codex docs heading

* fix(agent-session-history): drop the ellipsis from the Hand Off to Another Agent label
2026-10-08 10:39:19 -07:00
..

@orca/docs

This package contains the product documentation and public media intended to ship alongside Orca's source code.

Open-source product documentation for Orca, served at /docs (same URL shape as https://www.onorca.dev/docs).

This package is a self-contained Next.js app. It is intentionally not a root monorepo workspace member, so installing Electron app dependencies does not pull Next/fumadocs.

Local development

cd docs/site
pnpm --ignore-workspace install
pnpm --ignore-workspace dev

Open http://localhost:3004/docs.

Production build

cd docs/site
pnpm --ignore-workspace install
pnpm --ignore-workspace build
pnpm --ignore-workspace start

pnpm start serves the production build on port 3004. Paths:

Path Purpose
/ Redirects to /docs
/docs Docs index
/docs/... Nested doc pages from content/docs
/docs/api/search Fumadocs search index
/docs/og/... Per-page Open Graph image route

Layout

  • content/docs/ — MDX pages + meta.json navigation
  • public/docs/ — docs-only media, logo, and favicon (GIFs, posters, screenshots)
  • src/app/docs/ — fumadocs routes, OG images
  • src/components/ — docs-scoped chrome (header/footer/search), not marketing site

Updating content

Treat the documentation tree as a deliberate publication boundary. Before importing source material, review the diff for internal references, credentials, third-party media rights, and feature/version claims, then copy only approved pages and assets. Keep the app shell and deployment configuration in this repository so a docs-only pull request can be reviewed and built independently.

Same-domain routing

The docs app is a separate Vercel project (the docs zone) and keeps the public /docs URL namespace. The marketing site remains the default zone for www.onorca.dev; configure its Next/Vercel proxy with these beforeFiles rewrites, replacing DOCS_ORIGIN with the docs project's production URL:

return {
  beforeFiles: [
    {
      source: '/docs',
      destination: `${DOCS_ORIGIN}/docs`
    },
    {
      source: '/docs/:path*',
      destination: `${DOCS_ORIGIN}/docs/:path*`
    },
    {
      source: '/docs-static/:path*',
      destination: `${DOCS_ORIGIN}/docs-static/:path*`
    }
  ]
}

/docs-static is the docs zone's assetPrefix; it prevents _next asset collisions with the marketing zone. Keep the rewrites in the default zone and use ordinary <a> links when navigating between zones. Do not add basePath: '/docs' to this app: its route tree and Fumadocs baseUrl already include /docs, so doing so would publish /docs/docs/... URLs. If a future deployment needs basePath, first move the route tree to an unprefixed src/app/[[...slug]] shape and update every generated/link URL together.

Deploy (Vercel)

  1. Create a Vercel project with Root Directory unset (.). The workflow invokes Vercel from docs/site, so that directory is already the deployment root; setting it again would resolve docs/site/docs/site. Leave automatic Git deployments disabled so this workflow remains the only deployment path.
  2. Framework preset: Next.js. Use pnpm --ignore-workspace install --frozen-lockfile for install and pnpm --ignore-workspace build for build; this package has its own lockfile beside the root workspace.
  3. Set GitHub Actions secrets (required by the production deploy job):
    • VERCEL_TOKEN
    • VERCEL_ORG_ID
    • VERCEL_PROJECT_ID (docs project, not the marketing site)
  4. Protect the docs-production GitHub environment with required reviewers and custom deployment branch policies for main and v* tags. The release-cut dispatch runs from main; the direct published-release fallback runs from a stable tag, while the workflow still authorizes only exact stable tags.
  5. Prepare the three rewrites above in the www.onorca.dev marketing project, but leave them disabled until the docs deployment is verified. A Vercel custom domain cannot delegate only /docs by itself; the default zone must proxy both page/API/media requests and /docs-static assets. Keep the marketing project's old docs routes available for rollback during the transition; putting the proxy rules in beforeFiles ensures they win once enabled.
  6. Deploy a stable desktop tag that contains docs/site, verify the docs origin, then enable the marketing rewrites. Tags cut before this package was added cannot bootstrap the docs project because production intentionally checks out the tag's exact commit. Remove the old marketing docs routes in a follow-up after the proxy is stable.

.github/workflows/docs.yml runs credential-free checks for every pull request. It intentionally does not deploy PR previews: a PR-controlled build must not receive Vercel credentials. A maintainer can add a separate trusted preview workflow later. Production deploys only from an authorized stable desktop release: an exact vX.Y.Z tag, a published non-prerelease release, and the github-actions[bot] release author. Manual dispatch must run from the default branch and name an existing release that meets the same checks. Mobile, prerelease, draft, and human-authored releases are skipped. Fork pull requests remain build-only because GitHub does not expose deployment secrets to fork jobs.

Versioning

versioning.config.ts keeps the current unversioned /docs URLs stable while reserving content/versions/<id> for future snapshots. Versioned routes are not live yet; when they are needed, add the corresponding loader/routes and a version entry. The release workflow can then deploy them without a trigger change.

Isolation from the desktop app

  • Own package.json + pnpm-lock.yaml under docs/site/
  • Not listed in the root pnpm-workspace.yaml; install with pnpm --ignore-workspace
  • Engineering notes remain in repo-root docs/ — do not confuse with this package