Skip to content

feat(agents): add Prime Agent as a supported TUI agent with session history - #12935

Merged
brennanb2025 merged 8 commits into
stablyai:mainfrom
smwbev:feat/prime-agent
Aug 9, 2026
Merged

brennanb2025 merged 8 commits into
stablyai:mainfrom
smwbev:feat/prime-agent

Conversation

@smwbev

@smwbev smwbev commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds Prime Agent — Prime Intellect's coding/research CLI, an open-source fork of Pi — as a supported TUI agent, and indexes its transcripts in Agent Session History. After this change prime-agent appears in the agent pickers and Agents settings on desktop and mobile, launches with a startup prompt, is recognized in the process table and tab titles, and its saved sessions list and resume from the history sidebar, locally and over SSH.

The integration follows the two established patterns end to end: registration mirrors Trae (#10763), session history mirrors OMP (#7618). Both fit because Prime Agent is Pi under the hood (@earendil-works/pi-coding-agent is its direct dependency), with three deliberate differences, each verified against the real CLI v0.7.0 rather than assumed:

Pi OMP Prime Agent
config root env PI_CODING_AGENT_DIR PI_CODING_AGENT_DIR PRIME_AGENT_CODING_AGENT_DIR
sessions ~/.pi/agent/sessions ~/.omp/agent/sessions (+ artifact dirs) ~/.prime/agent/sessions (flat)
resume --session <path> --resume <path> --resume <path|id>

What changed

  • Registration (types.ts, tui-agent-config.ts + the standard satellite tables): prompt injection is positional argv behind a -- separator — Prime Agent's help documents -- as "treat all following arguments as messages", and without it a prompt starting with help/agents/-… dispatches as one of its 16 subcommands or a flag (same rationale as Trae and Grok). windowsShiftEnterEncoding: 'csi-u' matches the Pi TUI it embeds. No YOLO entry: the CLI has no permissions-bypass flag, so it stays out of the permission-mode summary by design.
  • Recognition: the npm shim resolves to node …/node_modules/prime-agent/dist/bundle/cli.js, a generic script name, so recognition needs the exact package path — the same situation as Pi and cursor-agent. The three per-agent regex branches became one table (agent-node-entrypoint-identities.ts); the module sat at its max-lines budget, and a table makes the next agent one entry instead of a fourth branch. -p/--print one-shots reuse the shared print-mode headless matcher so they are not mistaken for live panes.
  • Agent Session History: transcripts are Pi's append-only message-graph JSONL (v3 tree headers, Pi's model_change.modelId key), so the existing parser and incremental append-resume are reused as-is — the diff adds discovery (local, WSL homes, remote SSH), routing, and resume. Resume uses the absolute transcript path like OMP, so it resolves regardless of which session-dir root the file was discovered under, with session-id fallback.
  • Skills: ~/.prime/agent/skills joins the home skill-discovery sources (global skills root per Prime Agent's docs, same shape as Pi/OMP).
  • Test plumbing: every test with its own isolated scan-roots object now injects primeAgentSessionsDir so a real ~/.prime on a dev machine cannot pollute assertions; the OMP and Prime Agent scanner fixtures moved into session-scanner-test-fixtures.ts and the incremental fixture into its own module, keeping each touched file inside its max-lines budget without ratchet bumps.

Deliberately out of scope for this PR (planned follow-up): the Pi-family managed extensions (status/titlebar/prefill), /hook/* wiring, and the ompResumeFilePath RPC generalization. Those require widening the two-element PiAgentKind machinery and a capability-negotiated relay field, and none of them block launch, recognition, or history.

Screenshots

New rows only, no existing UI changes: Prime Agent appears in the new-tab agent picker, the Agents settings pane, and the Agent Session History agent filter/groups, rendering the bundled 64×64 favicon (fetched from primeintellect.ai, required by mobile's offline-icon invariant). All labels come from the localized catalog entry added to all five locales.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions

New tests: process recognition (binary path, npm entrypoint on posix and Windows, headless -p/--print exclusion, -- guard), startup plan (argv + separator, subcommand-shaped prompts), status label/icon mapping, resume command (path form, id fallback), the all-agents scanner test (which fails if any AI_VAULT_AGENTS member goes undiscovered — it now asserts Prime Agent's title, pre-reply modelId, and path-based resume command), and an incremental parse-parity fixture exercising the 'prime-agent' registry branch with the v3 tree-session header.

Beyond fixtures, the parser was verified against a real ~/.prime/agent/sessions transcript written by prime-agent v0.7.0 (22 messages, 241k tokens): title, cwd, model, message/token counts, and the generated prime-agent --resume '<path>' command all resolve correctly. prime-agent --help output was used as ground truth for the launch contract ([@files...] [message...], --, -p/--print, -r/--resume <path|id>).

Full suite on this branch: 47,061 passed, 7 failures across 4 files. Every deterministic failure (agent-exec-handler.test.ts, ssh-posix-command-wrapper.test.ts) fails identically on a clean upstream/main checkout (f71373953) on this machine — verified by stashing the diff and re-running; the remaining two (project-view-wrapper-source-context-boundary, worktree-base-directory-poller) are timeouts that pass in isolation. None touch agent registries. Mobile: tsc --noEmit clean, 3,371 tests passed; the parity tests that diff the mobile catalog against the desktop source accept the new agent.

AI Review Report

An automated multi-dimension review ran over the staged diff (registry-convention completeness against the Trae and MiMo integration commits, session-history correctness, cross-platform behavior, test adequacy), with each finding adversarially re-verified against the code. No finding survived verification; three test-coverage suggestions were assessed as pre-existing patterns rather than regressions (remote sources for pi/droid/kimi are equally fixture-untested; the scope test's roots omission predates this PR for ompSessionsDir), and one — the missing skills home source — was accepted and folded into the diff.

Cross-platform was checked explicitly: all new paths go through path.join/joinRemotePath; resume commands reuse the existing per-shell quoting (posix/pwsh/cmd) and are covered by the OMP-shaped tests; WSL homes get .prime/agent/sessions roots the same way .pi/.omp do; Windows recognition of the node.exe …\node_modules\prime-agent\… command line has a dedicated test; no shortcuts, labels, or Electron platform surfaces are touched.

Security Audit

  • Input handling: PRIME_AGENT_CODING_AGENT_DIR is user-owned env, normalized through the same normalizeAgentSessionsDir path-shape guard Pi and OMP use; transcript contents are parsed line-by-line as JSON with the existing tolerant parser and never executed or interpolated unquoted.
  • Command construction: resume commands pass the transcript path through the existing per-shell quoting helpers (quoteStartupArg/quoteWindowsCmdArg); startup prompts go through the established argv quoting with the -- separator preventing flag/subcommand injection via prompt text.
  • No new surface: no new IPC channels, no new RPC methods, no network access, no dependencies. The remote scanner entry reuses the read-only SSH source pipeline.
  • Mixed versions (corrected after review): an older client's z.enum(AI_VAULT_AGENTS) result validation drops unknown-agent rows per-row, but not additively: dropped rows surface a "Skipped N invalid Agent Session History result entries." notice hardcoded to agent: 'codex', and when every row is unknown the parser throws — zero sessions locally, and over SSH the throw falls through to the full SFTP crawl. The same property holds for every previously added agent; making the shared reader tolerant of unknown agents is tracked in AI Vault: session-list validation should tolerate agents unknown to the client #12958.
  • Follow-up: none identified.

Notes

  • The '.prime' widening of normalizeAgentSessionsDir keeps the same prefix-acceptance semantics; OMP_CODING_AGENT_DIR-style scanner-only overrides get their Prime Agent counterpart through the standard primeAgentSessionsDir scan option.
  • Prime Agent's rlm(...) child agents save ordinary session files in the same flat directory (only an rlmDepth header field distinguishes them), so they list as regular sessions — the OMP artifact-dir pruning does not apply and no subagent partitioning is needed.
  • Draft-prompt injection (no-submit) currently uses the default paste path: the Pi-family ORCA_*_PREFILL env contract needs the managed prefill extension, which is part of the deferred extensions follow-up.

…istory

Wire Prime Intellect's prime-agent CLI (a Pi fork) into the desktop and
mobile agent catalogs following the Trae registration pattern, and into
the Agent Session History browser following the OMP pattern:

- types.ts, tui-agent-config.ts: register 'prime-agent' with argv prompt
  injection behind a `--` separator (its own help documents `--` as
  "treat all following arguments as messages"; without it, prompts
  starting with `help`/`agents`/`-…` dispatch as subcommands or
  flags), plus csi-u Shift+Enter encoding matching the Pi TUI it embeds.
- agent-kind.ts, telemetry-events.ts, agent-status-types.ts,
  agent-type-label.ts, tui-agent-display-names.ts,
  tui-agent-selection.ts, skills-cli-agent-keys.ts: standard per-agent
  registrations.
- agent-headless-command.ts: `-p/--print` one-shot runs share the
  print-mode matcher with Claude/Trae so they are not mistaken for live
  interactive panes.
- agent-process-recognition: the npm shim launches a generic bundled
  cli.js, so only the exact package path is an authoritative identity
  (same as Pi and cursor-agent). The three per-agent regex branches are
  now one table in agent-node-entrypoint-identities.ts — the module was
  at its max-lines budget and a table makes the next agent one entry.
- AI Vault: sessions are Pi's message-graph JSONL under
  ~/.prime/agent/sessions (override PRIME_AGENT_CODING_AGENT_DIR —
  Prime Agent brands Pi's env contract instead of sharing
  PI_CODING_AGENT_DIR); parsed by the shared message-graph parser with
  incremental append-resume; discovered locally, in WSL homes, and over
  remote SSH; resumes by absolute transcript path
  (`prime-agent --resume <path>`) like OMP, with session-id fallback.
- skill-discovery-sources.ts: ~/.prime/agent/skills home source.
- Catalog, i18n (en/es/ja/ko/zh), mobile registries, and a bundled
  64x64 favicon (required by mobile's offline-icon invariant).

Scanner-test fixtures for OMP and Prime Agent move into
session-scanner-test-fixtures.ts and the incremental fixture into its
own module, keeping every touched file inside its max-lines budget
without ratchet bumps.
@smwbev
smwbev requested a review from brennanb2025 as a code owner August 6, 2026 17:31
@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added Prime Agent as a supported agent across shared types, telemetry, process recognition, launch configuration, automatic selection, and UI catalogs. Added Prime Agent icons, favicon assets, localized labels, and mobile mappings. Added local, WSL, and remote session discovery for .prime/agent/sessions, message-graph parsing, incremental fixtures, resume commands, and skills discovery. Added tests for process recognition, startup arguments, session parsing, model and title extraction, and resume behavior.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding Prime Agent as a supported TUI agent with session history.
Description check ✅ Passed The description covers all required sections with detailed scope, testing, AI review, security audit, and platform notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 08d27e8c-bab7-457b-896f-6d6eb002c313

📥 Commits

Reviewing files that changed from the base of the PR and between f713739 and c4db50e.

⛔ Files ignored due to path filters (2)
  • mobile/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/shared/agent-icons/prime-agent.png is excluded by !**/*.png
📒 Files selected for processing (42)
  • mobile/src/components/mobile-agent-icon-assets.ts
  • mobile/src/tasks/mobile-tui-agents.ts
  • src/main/ai-vault/remote-session-scanner-sources.ts
  • src/main/ai-vault/session-scanner-agent-parser.ts
  • src/main/ai-vault/session-scanner-codex-workers.test.ts
  • src/main/ai-vault/session-scanner-graph-parsers.ts
  • src/main/ai-vault/session-scanner-incremental-fixtures.ts
  • src/main/ai-vault/session-scanner-opencode-sqlite-coexistence.test.ts
  • src/main/ai-vault/session-scanner-parse-cache.ts
  • src/main/ai-vault/session-scanner-prime-agent-fixtures.ts
  • src/main/ai-vault/session-scanner-source-discovery.ts
  • src/main/ai-vault/session-scanner-test-fixtures.ts
  • src/main/ai-vault/session-scanner-types.ts
  • src/main/ai-vault/session-scanner-values.ts
  • src/main/ai-vault/session-scanner.test.ts
  • src/main/skills/skill-discovery-sources.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/lib/agent-catalog.tsx
  • src/renderer/src/lib/agent-favicon-assets.ts
  • src/renderer/src/lib/agent-status.test.ts
  • src/renderer/src/lib/agent-status.ts
  • src/renderer/src/lib/tui-agent-startup.test.ts
  • src/shared/agent-headless-command.ts
  • src/shared/agent-kind.ts
  • src/shared/agent-node-entrypoint-identities.ts
  • src/shared/agent-process-recognition.test.ts
  • src/shared/agent-process-recognition.ts
  • src/shared/agent-status-types.ts
  • src/shared/agent-type-label.ts
  • src/shared/ai-vault-resume-command.test.ts
  • src/shared/ai-vault-resume-command.ts
  • src/shared/ai-vault-types.ts
  • src/shared/skills-cli-agent-keys.ts
  • src/shared/telemetry-events.ts
  • src/shared/tui-agent-config.ts
  • src/shared/tui-agent-display-names.ts
  • src/shared/tui-agent-selection.ts
  • src/shared/types.ts

Comment thread src/main/ai-vault/session-scanner-source-discovery.ts Outdated
Comment thread src/shared/agent-node-entrypoint-identities.ts
PRIME_AGENT_CODING_AGENT_DIR is consumed verbatim by the CLI as its agent
config dir, with transcripts always in <agentDir>/sessions — unlike
PI_CODING_AGENT_DIR's <home>/agent/sessions shape the shared normalizer
models. A custom root with a non-special basename (or a `.prime` leaf)
was therefore scanned as-is instead of its sessions child. Dedicated
normalizePrimeAgentSessionsDir appends `sessions` to every configured
root, taking only an explicit `.../sessions` path as-is; the shared
Pi/OMP normalizer drops the `.prime` widening it no longer needs.

Raised in review on stablyai#12935.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 969ec4b2-6cf4-465e-8ddf-d23762120a09

📥 Commits

Reviewing files that changed from the base of the PR and between c4db50e and e75aa04.

📒 Files selected for processing (4)
  • src/main/ai-vault/remote-session-scanner-sources.ts
  • src/main/ai-vault/session-scanner-source-discovery.ts
  • src/main/ai-vault/session-scanner-values.test.ts
  • src/main/ai-vault/session-scanner-values.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/ai-vault/remote-session-scanner-sources.ts
  • src/main/ai-vault/session-scanner-source-discovery.ts

Comment thread src/main/ai-vault/session-scanner-values.ts Outdated
…e source

normalizePrimeAgentSessionsDir stripped a filesystem-root value ('/' or '//')
to '', which then joined into the relative root 'sessions' and would walk the
main-process cwd. session-scanner-roots.ts already carries this guard for the
OMP variant; apply the same fallback here.

The remote SSH source had no test: deleting jsonlSource('prime-agent', ...)
left the suite green, unlike the local path which is pinned by the
AI_VAULT_AGENTS exhaustiveness assertion in session-scanner.test.ts. Add a
case that fixes the .prime/agent/sessions root segments, the .jsonl
extension, and parser routing.

Raised in review on stablyai#12935.
@brennanb2025

Copy link
Copy Markdown
Contributor

Electron QA — PR #12935 (Prime Agent + Agent Session History)

Environment: Dev app from worktree head e75aa049e, CDP attach to this worktree only (pr12935-electron-qa), PRIME_AGENT_CODING_AGENT_DIR → scratch under /tmp with seeded sessions/*.jsonl (fixture shape). No source changes; QA only.

Verdicts

Item Result Notes
A New-tab agent picker PASS Prime Agent selectable row; icon renders (prime-agent.png, 64×64)
B Agents settings pane PASS Prime Agent in Installed (8 detected) with icon and prime-agent command
C Agent Session History seed PASS Group repo/app, title prime-agent seed question, agent Prime Agent, model inference/big-model
D Resume command PASS Resume in New Tab typed a prime-agent resume command (see below)
E Negative control PASS Pre-existing agents still present and unchanged in picker + settings

D — Observed resume command

cd '/repo/app' && prime-agent --resume '/tmp/prime-agent-qa.3p3Esd/sessions/dddddddd-eeee-4fff-8aaa-111111111111.jsonl'

(Resume path form matches absolute transcript resume for this agent.)

E — Comparison

Baseline installed set (before Prime detection): Claude, Claude Agent Teams, Codex, Grok, OMP, Gemini, Antigravity.

After: same seven rows still present with the same labels/commands; Prime Agent added (Installed went 7 → 8). Picker shows the same existing agents plus Prime Agent. No renames, drops, or command-string changes observed on existing rows.

Screenshots

A — New-tab picker (Prime Agent + icon)

A-new-tab-picker-prime-agent.png

B — Agents settings (Prime Agent installed)

B-agents-settings-prime.png

C — Session History seeded session

C-session-history-prime-seed.png

D — Resume action (terminal shows prime-agent --resume …)

D-resume-command-terminal.png

D (menu) — Copy Resume Command available

D-resume-actions-menu.png

E — Picker negative control (existing agents retained)

E-picker-all-agents-negative-control.png

E — Settings negative control (existing agents retained)

E-settings-installed-agents-negative-control.png

Gaps / notes

  • Prime Agent was not on PATH in the QA host; a local detection stub was used so the picker/settings “Installed” path could be exercised. Session History scan used the env-rooted scratch transcript only.
  • Seeded session cwd is /repo/app (fixture), so worktree matching shows “Unavailable worktree” — expected for this seed; resume still emits the correct command.
  • Default Session History list is recency-capped (~250); seed required recent timestamps / search to surface in the UI among large local history.

@brennanb2025

Copy link
Copy Markdown
Contributor

Review pass — 2 fixes pushed (95499b6), 1 doc correction requested

Reviewed with adversarial subagent lanes plus live Electron QA. Nice work — the registration is genuinely complete, and I could not break the recognition refactor. Two real issues found and fixed; one claim in the PR body needs correcting.

Fixed in 95499b6

1. Degenerate PRIME_AGENT_CODING_AGENT_DIR yields a relative scan root.
normalizePrimeAgentSessionsDir strips trailing separators, so '/' and '//' strip to '' and then join into the relative root 'sessions' — discoverFiles would walk <main-process cwd>/sessions. Verified with the repo's Node: '/' -> "sessions", '//' -> "sessions".

The codebase already guards this exact hazard for the OMP variant at session-scanner-roots.ts:37-40 ("OMP_CODING_AGENT_DIR='/' normalizes to '', which resolve()s to the process cwd"). Applied the same fallback, with a test that fails when the guard is removed.

2. The remote SSH source had no test coverage.
Deleting jsonlSource('prime-agent', ...) from remote-session-scanner-sources.ts left the whole suite green. That is an asymmetry rather than a nit: the local path is pinned by the AI_VAULT_AGENTS exhaustiveness assertion in session-scanner.test.ts, which is why local discovery could not have been added without a working fixture — the remote path has no equivalent gate. Added a case fixing the .prime/agent/sessions root segments, the .jsonl extension, and parser routing. Confirmed it fails when the source is removed.

Please correct in the PR body

The Security Audit section states that z.enum(AI_VAULT_AGENTS) result validation "degrades additively (an older client skips unknown-agent rows per the existing per-row safeParse)". That is only half the behavior. In session-list-result-validation.ts:

  • L98-106: dropped rows push a synthetic issue hardcoded to agent: 'codex', so an old client renders a user-visible "Skipped N invalid Agent Session History result entries." notice, misattributed to Codex, on every rescan.
  • L91-93: if every row is invalid it throws. On a host running only Prime Agent, an old client shows zero sessions; on SSH the throw is swallowed into relayError and falls through to the full SFTP crawl, turning one relay RPC into a 16-root remote directory walk per scan.

This is not a blocker for this PR — the same property holds for every previously added agent, and making the reader tolerant of unknown enum values is a shared-validation change that deserves its own PR. But the body should not claim additive degradation. Worth a follow-up issue.

Verified, no action needed

  • Recognition refactor (three per-agent branches to EXACT_NODE_ENTRYPOINT_IDENTITIES): faithful. Same patterns, same order, same return values, no g flag, so no lastIndex state bug. No divergence found against posix, Windows-backslash, quoted, or headless -p/--print command lines.
  • Registry completeness: every source file that registers a comparable recent agent also registers prime-agent — no missed satellite table. The omp-only files are the Pi-family managed-extension and ompResumeFilePath machinery your body already declares as deferred follow-up.
  • Unbounded walk depth: primeAgentDiscoveries omitting a directoryPredicate matches piDiscoveries byte-for-byte; OMP is the exception that added one for [Bug]: OMP task subagent transcripts are flattened into top-level Agent Session History #9330. Following Pi is the right precedent here, and the walk is limit-bounded.
  • mobile/pnpm-lock.yaml: I initially flagged the churn, then disproved it. CI=true pnpm@10.24.0 install --frozen-lockfile (the pinned pnpm, the exact command in the mobile workflow) accepts it, and mobile/package.json already pins typescript: 6.0.3, so the peer re-resolution corrects a stale key. Leaving it alone.
  • Perf: +1 SSH readDir per scan (15 to 16 sources, ~+12/min/host, inside the existing 8-in-flight ceiling), +1 stat for skill discovery, 0 extra WSL process boots. Parse cache participates rather than bypasses. No timers, listeners, or IPC added.
  • Tests are not vacuous: I mutation-tested the new suite — breaking the prime-agent entrypoint regex, and reverting normalizePrimeAgentSessionsDir to return the raw root, each fail their specific test.

Gates on the pushed head: pnpm lint, pnpm typecheck, and the changed-code quality / type-aware / React Doctor gates all clean (0 new findings across 39 files). Mobile tsc --noEmit and suite clean.

Electron QA screenshots posted separately.

@smwbev

smwbev commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough pass — the QA matrix, the mutation-testing of the new suites, and both fixes in 95499b6 (the / root guard mirroring the OMP precedent, and pinning the remote source with a test that fails when it's removed) are exactly right, and the branch is pulled locally on my side.

PR body corrected as requested: the Security Audit no longer claims additive degradation and now states the actual mixed-version behavior (per-row drops with the codex-misattributed notice, and the all-rows-unknown throw with the SSH SFTP-crawl fallback). Filed the shared-validation follow-up as #12958.

…ive modes

Verified against upstream PrimeIntellect-ai/prime-agent source rather than
inferred from the CLI's help text.

config.ts getSessionsDir() reads PRIME_AGENT_SESSION_DIR (and its legacy
PRIME_AGENT_CODING_AGENT_SESSION_DIR alias) ahead of the agent dir and uses it
verbatim; setting either left the vault silently empty. It also appends
`sessions` to the agent dir unconditionally, with no basename escape hatch, so
PRIME_AGENT_CODING_AGENT_DIR=/data/sessions writes to /data/sessions/sessions
while Orca scanned /data/sessions. getAgentDir() and the session-dir override
both run through expandTildePath, so a `~` value set outside a shell resolves.

cli/args.ts also spells the non-interactive runs `--mode json|rpc|acp|daemon`,
which the shared print-mode matcher does not know, so those panes were counted
as live interactive agents and the paste-submit path would write user text into
a JSON-RPC/ACP stream. Match upstream exactly: only the space-separated form,
since `--mode=json` is not parsed by the CLI and does start the TUI.

Raised in review on stablyai#12935.
@brennanb2025

Copy link
Copy Markdown
Contributor

Round 2 — 3 more fixes pushed (906fdac)

Two further review lanes reported after my last comment, and both landed real findings. I verified every claim against upstream PrimeIntellect-ai/prime-agent source directly before touching code — the CLI is not installed on my QA host, so help-text and inference were not good enough here.

Fixed in 906fdac

1. PRIME_AGENT_SESSION_DIR was ignored — silently empty vault.
packages/coding-agent/src/config.ts:635-646:

export function getSessionsDir(agentDir = getAgentDir()): string {
	const envDir = getSessionDirEnvOverride();   // PRIME_AGENT_SESSION_DIR ?? PRIME_AGENT_CODING_AGENT_SESSION_DIR
	if (envDir) return envDir;
	return join(agentDir, "sessions");
}

Both variables outrank the agent dir and point straight at the transcripts root. Orca read only PRIME_AGENT_CODING_AGENT_DIR, so anyone who set either got zero sessions with no error. Now honored verbatim, in upstream's precedence order.

2. The basename === 'sessions' escape hatch contradicts the CLI.
The same function appends sessions unconditionally — there is no as-is branch. So PRIME_AGENT_CODING_AGENT_DIR=/data/sessions has the CLI writing to /data/sessions/sessions/ while Orca scanned /data/sessions → zero sessions. Dropped the conditional; the default now feeds the agent dir (~/.prime/agent) rather than a pre-joined sessions path. Remote segments still resolve to ['.prime','agent','sessions'], unchanged.

3. --mode json|rpc|acp|daemon panes were counted as live interactive agents.
agent-headless-command.ts mapped prime-agent to the shared print-mode matcher, which only knows --print/-p and --output-format. But cli/args.ts:8,102-106 defines Mode = "text" | "json" | "rpc" | "acp" | "daemon" as a separate flag. prime-agent --mode rpc was recognized as a running interactive agent, so Orca rendered agent status for it and the paste-submit path would write user text into a JSON-RPC/ACP stream; --mode daemon gave a pane Orca believed was working and that never completes.

One detail worth flagging, because the obvious fix over-matches: upstream parses --mode only in the space-separated form (arg === "--mode" && i + 1 < args.length), so --mode=json is ignored by the CLI and does start the interactive TUI. The new matcher mirrors that exactly, and there is a test pinning it.

Also: a ~ prefix is now expanded (config.ts:502-506 — upstream runs expandTildePath on both the agent dir and the session-dir override), so a value set outside a shell resolves instead of scanning a literal ~/… path.

Not changed, deliberately

  • Tilde/root handling for pi and omp has the same shape, but that is a shared function used by other agents — separate PR.
  • The 9 optional per-agent capability tables (RESUMABLE_TUI_AGENTS, YOLO permissions, model picker, PiAgentKind, …). Trae is absent from most of them too, so this is the normal support level for a newly added agent.
    One is worth a conscious product call rather than deciding it by omission: because prime-agent is not in PiAgentKind, Orca never installs its titlebar/status extension, so Prime Agent panes get no agent status — while the PR does add it to TUI_AGENT_AUTO_PICK_ORDER, so it can become a worktree's auto-picked default and then show nothing. Not a regression and nothing is mislabeled, but someone should decide it intentionally.
  • Legacy sub-xxxxxxxx/ child-session dirs. Older releases nested child sessions inside the scanned root (session-manager.ts:749-758), so pre-migration history could surface as top-level rows. Current releases write artifacts to <agentDir>/session-artifacts/ — a sibling of sessions/, confirmed at session-manager.ts:347 — so your no-directoryPredicate decision is correct for current versions. Flagging only as optional hardening.

Verification

Full src/shared + src/main/ai-vault surface: 4,333 passed, 16 skipped. pnpm lint (incl. max-lines ratchet), pnpm typecheck, and the changed-code quality / type-aware / React Doctor gates all clean — 0 new findings across 40 files.

Each fix is mutation-proven, not just covered: gutting the --mode matcher, the session-dir override, and the degenerate-root guard each fails its specific test. The remote-source test added in the previous commit earned its keep immediately — it caught an incomplete edit of mine where the remote segments would have resolved to .prime/agent/sessions/sessions.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5824e9dc-e4b2-4d44-846d-652b2edaf2b6

📥 Commits

Reviewing files that changed from the base of the PR and between 95499b6 and 906fdac.

📒 Files selected for processing (7)
  • src/main/ai-vault/remote-session-scanner-sources.ts
  • src/main/ai-vault/session-scanner-source-discovery.ts
  • src/main/ai-vault/session-scanner-values.test.ts
  • src/main/ai-vault/session-scanner-values.ts
  • src/shared/agent-headless-command.ts
  • src/shared/agent-process-recognition.test.ts
  • src/shared/prime-agent-headless-command.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/ai-vault/remote-session-scanner-sources.ts
  • src/main/ai-vault/session-scanner-source-discovery.ts

Comment thread src/main/ai-vault/session-scanner-values.ts Outdated
Two holes in the previous commit.

The degenerate-root guard only rejected pure-separator values, so a relative
env value still resolved against the main-process cwd:
PRIME_AGENT_CODING_AGENT_DIR='.' scanned '<cwd>/sessions' and, worse,
PRIME_AGENT_SESSION_DIR='.' scanned the cwd itself. Require an absolute path in
both branches and fall back to the default otherwise.

remotePrimeAgentSessionsSegments() built its segments with the local-platform
join, so on a Windows client scanning a posix SSH host it produced
'\.prime\agent\sessions' and split('/') collapsed it to one bogus segment —
remote discovery would have found nothing. Remote roots are posix regardless of
client platform, so keep them literal. Pi and OMP are unaffected: their
normalizer returns a '.../sessions' input unchanged and never joins.

Raised in review on stablyai#12935.
@brennanb2025

Copy link
Copy Markdown
Contributor

Round 3 — self-inflicted regression caught and fixed (f7d29c1)

Two holes, both in my own previous commit rather than in the original PR.

1. Windows-client remote discovery was broken by my last change. In 906fdac I changed remotePrimeAgentSessionsSegments() to pass /.prime/agent through normalizePrimeAgentSessionsDir, which now joins. On a Windows client scanning a posix SSH host that produces:

win32.join('/.prime/agent', 'sessions')  ->  '\.prime\agent\sessions'
  .split('/').filter(Boolean)            ->  ['\.prime\agent\sessions']    // one bogus segment

so remote Prime Agent discovery from a Windows client would have found nothing. The pre-existing code survived only by accident: the old escape hatch returned a .../sessions input unchanged, so it never hit a join. Remote roots are posix regardless of client platform, so they are literal now with no platform-dependent path call. Pi and OMP are unaffected — their normalizer also returns such an input unchanged.

Worth noting this class does not show up in CI or in the test I added, because the suite runs on posix and the bug is in the local platform's join. I found it by explicitly evaluating win32.isAbsolute/win32.join on the remote-segment input.

2. The degenerate-root guard was incomplete. It rejected pure-separator values but not relative ones, so the exact class it was added to close was still open:

value before now
PRIME_AGENT_CODING_AGENT_DIR='.' sessions (walks <cwd>/sessions) default root
PRIME_AGENT_CODING_AGENT_DIR='..' ../sessions default root
PRIME_AGENT_SESSION_DIR='.' . — scans the cwd itself default root

Both branches now require an absolute path and fall back to the default otherwise.

Verification

src/main/ai-vault + src/shared: 4,333 passed, 16 skipped, 0 failures. pnpm lint, pnpm typecheck, and the changed-code quality / type-aware / React Doctor gates all clean across 40 files.

Independent verification of the earlier rounds

A separate adversarial pass confirmed, with execution rather than reasoning:

  • Resume-command quoting: no breakout. 16 hostile payloads × 2 branches (path and session-id fallback) × 4 POSIX shells = 128 real executions against a recorder that dumps argv. Injected: 0. Argv mismatches: 0. Payloads included $(touch MARKER), `, ;touch MARKER;, &&, |, embedded newlines, and two deliberate breakout strings — none created the marker. PowerShell and cmd were checked at string level only (no pwsh/cmd on this host); stated as the weaker evidence it is.
  • The round-1 guard is correctly scoped. normalizeAgentSessionsDir (the shared pi/omp function) is byte-identical to the base — the whole-file diff has zero deletion lines. Differential test over 26 inputs: only the 8 degenerate pure-separator values changed behavior.
  • A relevant safety property: for a remote session the platform comes from session.executionHostPlatform, so a Linux-SSH transcript path can never reach the cmd or pwsh quoter. That was the one route by which a "-bearing or newline-bearing path could have met the cmd quoter.

The %VAR% expansion in quoteWindowsCmdArg remains pre-existing and shared with OMP — wrong path, not injection — and is out of scope here.

…llback

'C:\' and 'C:/' strip to the drive-relative 'C:', which isAbsolute
rejects on every platform — assert they land in the default fallback so
a looser truthiness check can't reintroduce a 'C:sessions' scan root.

Raised in review on stablyai#12935.
@brennanb2025

Copy link
Copy Markdown
Contributor

Final verdict — CLEAN at a094036

Adversarial verification is done. No correctness defects survive. One non-blocking coverage gap, called out below as a conscious decision rather than an oversight.

Thanks for a094036d14 — pinning C:\/C:/ to the fallback is the right instinct, and it independently reproduced a probe result from the verification lane. On your implicit question there: yes, falling back diverges from the CLI, which would write to C:\sessions. For a drive-root agent dir that trade is correct — the fallback is safe and the config is pathological — but it is a divergence, so the comment you added earning its place is the right outcome.

What was checked, and how

Path resolution — 48-value matrix run under both path.posix and path.win32, for the agent-dir and sessions-dir branches: empty/whitespace/tab, ./.., bare and trailing separators, \\server\share, \\?\C:\x, \\.\pipe\x, C:, C:foo, C:\, C:/, ~ in every position, ~foo, NUL and newline bytes, file://, $HOME, %USERPROFILE%, -, --.
Non-absolute results: none on posix, none on win32. UNC paths are accepted and join correctly. ~ is expanded only at position 0 and only before a separator. NUL/newline roots are caught by the existing readdir try/catch, so nothing throws.

--mode matcher — differential over 36 agents × 7,239 token vectors = 260,604 checks: 2,974 behavior differences, all on prime-agent, zero on any other agent. --mode RPC and --mode Json correctly stay interactive (upstream compares case-sensitively). --mode as last token, --modem, ---mode, --mode=json, and --mode after -- all stay interactive. Repeat scanning works.

Resume quoting — 128 executed POSIX runs (16 hostile payloads × 2 branches × 4 shells) against an argv recorder: 0 injections, 0 argv mismatches, no marker file created by any breakout string. PowerShell and cmd were string-level only, since neither exists on the verification host — stated plainly as the weaker evidence it is.

Regression sweep — src/main src/shared src/renderer: 44,282 passed / 10 failed. All 10 are in files this diff does not touch. The two with any plausible connection (pty-subprocess.test.ts, which does import agent-process-recognition) were proven pre-existing by reverting agent-process-recognition.ts, tui-agent-config.ts and types.ts to base and re-running — still 2 failed. The rest are load flakes that pass in isolation, plus real-FSEvents tests with no import path to this diff.
Everything the diff actually touches: 70 files / 664 tests, all passing.

Mutation checks — three of the four review fixes are pinned: removing the --mode branch, the sessions-root env override, or the remote jsonlSource each fails its specific test.

Accepted gap (conscious call, not an oversight)

The fourth fix — remotePrimeAgentSessionsSegments() returning literal segments instead of a local-platform join — is not pinned by a test. Reverting it to the pre-fix body leaves src/main/ai-vault fully green (50 files / 297 tests), because the bug only manifests when the local platform is win32 and CI runs posix.

I am accepting that rather than papering over it. The code is now platform-independent by construction — there is no join left to go wrong — and the only clean way to pin it would be stubbing node:path, which buys less than it costs. The // Why: comment on the helper is the durable guard. Flagging it so the next person who touches that function knows CI will not catch a regression there.

Still with you, not blocking

  1. The Security Audit section's "degrades additively" claim is inaccurate — session-list-result-validation.ts:91-93 throws when every row is unknown, and :98-106 misattributes the synthetic issue to Codex. Same property holds for every previously added agent, so it is a follow-up, but the body should not assert it.
  2. PiAgentKind omission. Prime Agent panes get no agent status at all, while the agent is in TUI_AGENT_AUTO_PICK_ORDER and so can become a worktree's auto-picked default. Trae ships the same way, so it is not a regression — but right now it is decided by omission rather than deliberately.

Correction to my own round-3 comment

I understated one thing. The relative-root issue was not just untidy — it was demonstrated live. With PRIME_AGENT_SESSION_DIR='.' the verification lane ran the real discoverFiles and watched the scanner resolve root=".", walk into a nested directory, and ingest an unrelated .jsonl as a Prime Agent session with issues: [] — no error surfaced. An exhaustive matrix found 3,096 of 5,832 env combinations returning a non-absolute root. That was a data-exposure path, and it was mine — introduced in 906fdac, closed in f7d29c1. Re-run after the fix at 13,824 combinations: zero non-absolute.

@brennanb2025

Copy link
Copy Markdown
Contributor

Small follow-up on a094036 — right behavior, wrong stated reason

Verdict unchanged: CLEAN, and this commit is not a blocker. The behavior it pins is correct. But two details in it are worth fixing before merge, because as written the comment will mislead the next reader.

The stated hazard is unreachable

The message says the pin stops a looser truthiness check from reintroducing a C:sessions scan root. Node normalizes a bare drive designator when joining, so that string cannot be produced by this code:

path.win32.join('C:', 'sessions')  // => 'C:\\sessions'   (not 'C:sessions')

The code only ever uses join, never concatenation. Under the loose variant C:\ would yield C:\sessions — which is the CLI-correct answer, not a cwd leak.

The two new cases add no coverage

node:path is host-bound, so on a posix CI runner 'C:\' strips to 'C:' and posix.isAbsolute('C:') is false. The assertion is indistinguishable from asserting 'rel/path' — it carries no Windows semantics at all.

Proven by mutation, three ways:

Mutation Result
Drop the isAbsolute gate (the "looser check" the message names) fails at '.' — the loop aborts before reaching 'C:\'
Treat any fs/drive root as absolute fails at '/' — the first loop value
Windows-drive-root-only parity (C:\ → C:\sessions) — i.e. exactly what the test claims to block 15/15 green

That third one is decisive: the change the test says it prevents passes the test.

The shape that is actually dangerous on Windows

Not the drive root — the drive-relative form, which is absent from both loops:

path.win32.isAbsolute('C:foo')            // false
path.win32.resolve('C:foo', 'sessions')   // => '<cwd-on-C:>\\foo\\sessions'

Your isAbsolute gate already handles it correctly; it just isn't pinned.

Suggested (all optional, none blocking)

  1. Add 'C:foo' to the loop at session-scanner-values.test.ts:124, and to the sessions-dir loop at :170. On a posix runner it is exactly as meaningful as 'C:\' — but it names the shape that actually leaks on Windows.
  2. Reword the comment at :118-121 to say what it really asserts: a drive-shaped value is non-absolute on posix too, so it takes the same fallback. Drop the C:sessions claim.
  3. Real Windows drive-root pinning would need path.win32 explicitly (inject the path flavor or stub node:path). No assertion on a posix runner can do it — worth skipping.

On the divergence question

Falling back rather than matching the CLI's C:\sessions is the right call, for a reason beyond "pathological config": it is already the shipped behavior for the posix twin. PRIME_AGENT_CODING_AGENT_DIR='/' falls back too, pinned by the '/' and '//' entries in that same loop. Treating C:\ differently from / would be the inconsistency. It also matches the existing OMP posture at session-scanner-roots.ts:37-40.

One thing for a separate PR

The pre-existing pi/OMP normalizer still has the Windows drive-relative leak that prime-agent now blocks:

OMP_CODING_AGENT_DIR='C:\'    -> 'C:'      non-absolute -> resolves against the process cwd
OMP_CODING_AGENT_DIR='C:foo'  -> 'C:foo'   non-absolute -> resolves against the process cwd

Out of scope here — flagging it so it isn't lost.

Standing caveat

This PR now has two Windows-only behaviors that no posix CI run can observe: the drive-root env handling above, and the remote posix-segments fix at remote-session-scanner-sources.ts:309-311 (reverting it leaves all of src/main/ai-vault green). Both are correct at this head. Neither is guarded by CI.

Regression sweep at a094036d14: 44,284 passed / 8 failed, all 8 in files this diff does not touch — load flakes that pass in isolation, plus macOS-native FSEvents and pty tests already proven pre-existing by reverting the diff's files. Everything the diff touches: 51 files / 321 tests, all passing.

@smwbev

smwbev commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Both suggestions applied in 7b74ad7:

  1. 'C:foo' is now pinned in both loops — the agent-dir fallback matrix and the sessions-root override rejection — naming the drive-relative shape that actually resolves against a per-drive cwd on Windows.
  2. The comment now states what the posix runner actually asserts: drive-shaped values are non-absolute on posix too, so they take the same fallback; real win32 semantics cannot be pinned there. The unreachable C:sessions claim is gone — you're right that join normalizes a bare drive designator, so that string was never producible from this code, and the same correction applies to my earlier reply in the review thread.
  3. Skipped the explicit path.win32 pinning per your third point.

On the two standing items from the final verdict: the Security Audit section was already reworded after your first pass — the “Mixed versions (corrected after review)” bullet states the all-rows-unknown throw and the codex misattribution outright, with the shared-reader tolerance tracked in #12958. The PiAgentKind status-extension question is noted so it gets decided deliberately rather than by omission.

Verification: full src/main/ai-vault suite green (50 files / 297 tests), pnpm lint clean; the only tsc finding on my run is the pre-existing psl types-resolution failure that reproduces on clean upstream/main unmodified.

@brennanb2025

brennanb2025 commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Thanks for this — really nice work, and you turned around every review point precisely.

I'm going to hold off merging for now, and it's not the code. Prime Agent is moving fast at the moment (~3 releases a week), and our integration leans on its launch, resume, and transcript contracts staying put. Supporting an agent is an ongoing commitment on our side, so I'd rather pick this up once the CLI surface settles. We also tend to wait for a bit more adoption before taking one on, and that's a factor here too.

Happy to revisit on both counts — the branch is in good shape. Thanks again for the effort here.

@smwbev

smwbev commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Completely fair on both counts, and thanks for the thorough rounds — the branch will stay ready either way.

On contract stability: that concern is exactly why PrimeIntellect-ai/prime-agent#808 exists — it asks upstream directly whether the session-file format and the launch/env/CLI contracts this integration leans on are stable across releases, and which surface they intend for host-IDE integrations long-term. I'll relay their answer here when it lands.

On the ongoing-commitment side: I run an automation that checks every prime-agent release against precisely the contracts this PR consumes (the npm entrypoint path, --resume/-p/--mode/--, PRIME_AGENT_CODING_AGENT_DIR/PRIME_AGENT_SESSION_DIR, the transcript format), and I'll keep this branch green against main while it waits — contract drift shows up as a diff on this branch, not as a surprise after merge. The pi/OMP normalizer leak you flagged for a separate PR is up as #13020.

On adoption, for what it's worth: #12892 requested this agent before this PR existed.

What signal would make this worth picking back up for you — some number of prime-agent releases without a breaking change to those contracts, a stability statement from upstream in #808, an adoption bar, or something else? Happy to track whichever and ping only when it's met.

@AmethystLiang

Copy link
Copy Markdown
Contributor

thanks for reporting. looking into it

@AmethystLiang AmethystLiang self-assigned this Aug 7, 2026
Resolves the conflict with stablyai#10249's table refactor: per-agent discovery
moved from session-scanner-source-discovery.ts into the
AI_VAULT_AGENT_SOURCES table, so the Prime Agent source becomes a table
entry following the Pi shape (env resolution via
primeAgentSessionsDirFromEnv unchanged). Prime Agent stays out of
AI_VAULT_DELETABLE_AGENTS. Also picks up stablyai#12999 (unknown-agent
tolerance in session-list validation) with no overlap.
@brennanb2025

brennanb2025 commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Update: taking this off hold — we're moving to merge.

Two things changed the calculus:

  1. We audited upstream contract drift across the launch-week releases (v0.7.0 → current main): the CLI args parser and session serializer this integration depends on are byte-identical across that window. The fast release cadence lives almost entirely in Prime's RLM/daemon layer, not in the surfaces Orca consumes.
  2. The reason is structural. prime-agent's coding agent is the Pi chassis — @earendil-works/pi-coding-agent, rebranded to prime-agent / .prime/agent at pack time. The launch, session-dir, and transcript contracts we integrate against are Pi's, the same mature contracts we already ship for pi and omp. That's a bet we've effectively already made twice.

One known cosmetic quirk to be aware of: prime-agent's daemon mode currently leaves zero-message draft session files on shutdown (upstream PrimeIntellect-ai/prime-agent#1078, fix pending in PrimeIntellect-ai/prime-agent#1079), which will show as empty rows in Session History until that lands. Since it's an upstream bug with an active fix, we're deliberately not adding a scanner-side workaround.

Follow-up tracked separately: register prime-agent as a third Pi-family kind so the managed extension installer can deliver live agent status — deliberately kept out of this PR, since the extension API is the one genuinely churn-exposed surface.

@smwbev — thanks for the quality of this contribution and for keeping the branch current through the hold.

smwbev added a commit to smwbev/orca that referenced this pull request Aug 11, 2026
Prime Agent (stablyai#12935) landed in main and added its own cases to
session-scanner-values.test.ts at the same insertion point; both suites
are kept side by side. The pi/OMP normalizer guard this PR adds is
untouched by the merge.
@smwbev

smwbev commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Thank you — and for the audit itself, which answered the contract question far more rigorously than the guarantee I went looking for upstream.

On the two follow-ups you named:

Also, unrelated to this PR but in the same area: #13020 (the pi/OMP normalizer leak this review surfaced) is green and waiting, and #13118 implements the #13082 sweep across the other six agents using it as the template. I checked they don't conflict with each other, in case that helps sequencing.

trs-80 added a commit to trs-80/orca that referenced this pull request Sep 2, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Sep 15, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 5, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 8, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 9, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 9, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 10, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 11, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 13, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 15, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
…istory (stablyai#12935)

* feat(agents): add Prime Agent as a supported TUI agent with session history

Wire Prime Intellect's prime-agent CLI (a Pi fork) into the desktop and
mobile agent catalogs following the Trae registration pattern, and into
the Agent Session History browser following the OMP pattern:

- types.ts, tui-agent-config.ts: register 'prime-agent' with argv prompt
  injection behind a `--` separator (its own help documents `--` as
  "treat all following arguments as messages"; without it, prompts
  starting with `help`/`agents`/`-…` dispatch as subcommands or
  flags), plus csi-u Shift+Enter encoding matching the Pi TUI it embeds.
- agent-kind.ts, telemetry-events.ts, agent-status-types.ts,
  agent-type-label.ts, tui-agent-display-names.ts,
  tui-agent-selection.ts, skills-cli-agent-keys.ts: standard per-agent
  registrations.
- agent-headless-command.ts: `-p/--print` one-shot runs share the
  print-mode matcher with Claude/Trae so they are not mistaken for live
  interactive panes.
- agent-process-recognition: the npm shim launches a generic bundled
  cli.js, so only the exact package path is an authoritative identity
  (same as Pi and cursor-agent). The three per-agent regex branches are
  now one table in agent-node-entrypoint-identities.ts — the module was
  at its max-lines budget and a table makes the next agent one entry.
- AI Vault: sessions are Pi's message-graph JSONL under
  ~/.prime/agent/sessions (override PRIME_AGENT_CODING_AGENT_DIR —
  Prime Agent brands Pi's env contract instead of sharing
  PI_CODING_AGENT_DIR); parsed by the shared message-graph parser with
  incremental append-resume; discovered locally, in WSL homes, and over
  remote SSH; resumes by absolute transcript path
  (`prime-agent --resume <path>`) like OMP, with session-id fallback.
- skill-discovery-sources.ts: ~/.prime/agent/skills home source.
- Catalog, i18n (en/es/ja/ko/zh), mobile registries, and a bundled
  64x64 favicon (required by mobile's offline-icon invariant).

Scanner-test fixtures for OMP and Prime Agent move into
session-scanner-test-fixtures.ts and the incremental fixture into its
own module, keeping every touched file inside its max-lines budget
without ratchet bumps.

* fix(ai-vault): map custom Prime Agent roots to their sessions child

PRIME_AGENT_CODING_AGENT_DIR is consumed verbatim by the CLI as its agent
config dir, with transcripts always in <agentDir>/sessions — unlike
PI_CODING_AGENT_DIR's <home>/agent/sessions shape the shared normalizer
models. A custom root with a non-special basename (or a `.prime` leaf)
was therefore scanned as-is instead of its sessions child. Dedicated
normalizePrimeAgentSessionsDir appends `sessions` to every configured
root, taking only an explicit `.../sessions` path as-is; the shared
Pi/OMP normalizer drops the `.prime` widening it no longer needs.

Raised in review on stablyai#12935.

* fix(ai-vault): guard degenerate Prime Agent roots and cover the remote source

normalizePrimeAgentSessionsDir stripped a filesystem-root value ('/' or '//')
to '', which then joined into the relative root 'sessions' and would walk the
main-process cwd. session-scanner-roots.ts already carries this guard for the
OMP variant; apply the same fallback here.

The remote SSH source had no test: deleting jsonlSource('prime-agent', ...)
left the suite green, unlike the local path which is pinned by the
AI_VAULT_AGENTS exhaustiveness assertion in session-scanner.test.ts. Add a
case that fixes the .prime/agent/sessions root segments, the .jsonl
extension, and parser routing.

Raised in review on stablyai#12935.

* fix(ai-vault): honor Prime Agent's sessions-root env and non-interactive modes

Verified against upstream PrimeIntellect-ai/prime-agent source rather than
inferred from the CLI's help text.

config.ts getSessionsDir() reads PRIME_AGENT_SESSION_DIR (and its legacy
PRIME_AGENT_CODING_AGENT_SESSION_DIR alias) ahead of the agent dir and uses it
verbatim; setting either left the vault silently empty. It also appends
`sessions` to the agent dir unconditionally, with no basename escape hatch, so
PRIME_AGENT_CODING_AGENT_DIR=/data/sessions writes to /data/sessions/sessions
while Orca scanned /data/sessions. getAgentDir() and the session-dir override
both run through expandTildePath, so a `~` value set outside a shell resolves.

cli/args.ts also spells the non-interactive runs `--mode json|rpc|acp|daemon`,
which the shared print-mode matcher does not know, so those panes were counted
as live interactive agents and the paste-submit path would write user text into
a JSON-RPC/ACP stream. Match upstream exactly: only the space-separated form,
since `--mode=json` is not parsed by the CLI and does start the TUI.

Raised in review on stablyai#12935.

* fix(ai-vault): keep Prime Agent roots absolute and remote segments posix

Two holes in the previous commit.

The degenerate-root guard only rejected pure-separator values, so a relative
env value still resolved against the main-process cwd:
PRIME_AGENT_CODING_AGENT_DIR='.' scanned '<cwd>/sessions' and, worse,
PRIME_AGENT_SESSION_DIR='.' scanned the cwd itself. Require an absolute path in
both branches and fall back to the default otherwise.

remotePrimeAgentSessionsSegments() built its segments with the local-platform
join, so on a Windows client scanning a posix SSH host it produced
'\.prime\agent\sessions' and split('/') collapsed it to one bogus segment —
remote discovery would have found nothing. Remote roots are posix regardless of
client platform, so keep them literal. Pi and OMP are unaffected: their
normalizer returns a '.../sessions' input unchanged and never joins.

Raised in review on stablyai#12935.

* test(ai-vault): pin Windows drive roots to the Prime Agent default fallback

'C:\' and 'C:/' strip to the drive-relative 'C:', which isAbsolute
rejects on every platform — assert they land in the default fallback so
a looser truthiness check can't reintroduce a 'C:sessions' scan root.

Raised in review on stablyai#12935.

* test(ai-vault): pin the drive-relative root form and state what the posix runner can assert

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 16, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
trs-80 added a commit to trs-80/orca that referenced this pull request Oct 17, 2026
Rebase of stablyai#7698 (by @kiyeonjeon21) onto current main, which had drifted
1102 commits since the original merge base. Agent behavior is unchanged
from the original PR; only the landing sites moved.

Relocations forced by two refactors on main:

- stablyai#14447 dropped the src/shared/types.ts barrel, so the TuiAgent union
  member moves to src/shared/tui-agent.ts and bobDefaultDisabledMigrated
  moves to src/shared/global-settings-types.ts.
- src/main/persistence.ts is now an 8-line barrel; the three opt-in
  migration hunks move to persistence/loading-store/store.ts.
- stablyai#14728 split the oversized test files, so the Bob detection test moves
  to preflight-agent-detection.test.ts and the disabledTuiAgents tests
  move to persistence-settings-update.test.ts.
- i18n locales and agent-headless-command.ts took both sides of the
  collision with Prime Agent (stablyai#12935).

Co-Authored-By: Kiyeon Jeon <kiyeon.jeon.21@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

3 participants