* 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
@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.jsonnavigationpublic/docs/— docs-only media, logo, and favicon (GIFs, posters, screenshots)src/app/docs/— fumadocs routes, OG imagessrc/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)
- Create a Vercel project with Root Directory unset (
.). The workflow invokes Vercel fromdocs/site, so that directory is already the deployment root; setting it again would resolvedocs/site/docs/site. Leave automatic Git deployments disabled so this workflow remains the only deployment path. - Framework preset: Next.js. Use
pnpm --ignore-workspace install --frozen-lockfilefor install andpnpm --ignore-workspace buildfor build; this package has its own lockfile beside the root workspace. - Set GitHub Actions secrets (required by the production deploy job):
VERCEL_TOKENVERCEL_ORG_IDVERCEL_PROJECT_ID(docs project, not the marketing site)
- Protect the
docs-productionGitHub environment with required reviewers and custom deployment branch policies formainandv*tags. The release-cut dispatch runs frommain; the direct published-release fallback runs from a stable tag, while the workflow still authorizes only exact stable tags. - Prepare the three rewrites above in the
www.onorca.devmarketing project, but leave them disabled until the docs deployment is verified. A Vercel custom domain cannot delegate only/docsby itself; the default zone must proxy both page/API/media requests and/docs-staticassets. Keep the marketing project's old docs routes available for rollback during the transition; putting the proxy rules inbeforeFilesensures they win once enabled. - 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.yamlunderdocs/site/ - Not listed in the root
pnpm-workspace.yaml; install withpnpm --ignore-workspace - Engineering notes remain in repo-root
docs/— do not confuse with this package