Commit Graph
521 Commits
Author SHA1 Message Date
Brennan Benson 2d3b082ab2 fix(native-chat): harden shared handoff recovery 2026-08-12 18:36:05 -07:00
Brennan Benson 8b2601b2f2 fix mobile structured first-send hydration race 2026-08-12 18:26:18 -07:00
Brennan Benson 2355a20b29 fix(native-chat): rotate refused send operations 2026-08-12 17:21:10 -07:00
Brennan Benson d82d807180 fix(native-chat): rotate settled handoff operations 2026-08-12 17:04:49 -07:00
Brennan Benson 7f4a1d13f7 fix(native-chat): replay pending option mutations 2026-08-12 16:54:16 -07:00
Brennan Benson 973dd58aba fix(native-chat): preserve options across structured handoffs 2026-08-12 16:40:09 -07:00
Brennan Benson 5971fcb437 fix(native-chat): persist structured session options 2026-08-12 13:58:48 -07:00
Brennan Benson 1cf45caa24 fix(native-chat): route structured Codex options directly 2026-08-12 12:43:24 -07:00
Brennan Benson 7b3144c037 Merge remote-tracking branch 'origin/brennanb2025/native-chat-toggle' into brennanb2025/codex-structured-mobile-write 2026-08-11 22:57:35 -07:00
Brennan Benson c18e81c8d2 fix(native-chat): clear sticky handoff recovery 2026-08-11 19:46:33 -07:00
Brennan Benson 438d256ef5 Merge remote-tracking branch 'origin/main' into brennanb2025/codex-structured-mobile-write
# Conflicts:
#	mobile/app/h/[hostId]/session/[worktreeId].tsx
#	mobile/src/session/MobileMarkdownReader.tsx
#	src/renderer/src/components/native-chat/NativeChatView.tsx
#	src/renderer/src/components/native-chat/native-chat-view-types.ts
#	src/renderer/src/components/tab-bar/TabBar.tsx
#	src/renderer/src/runtime/web-session-tabs-sync.ts
2026-08-11 13:16:52 -07:00
Jinjing 2b1e69d4b0 Add keyboard dismissal for mobile markdown editor (#13856)
* fix(mobile-markdown): enable keyboard dismissal while editing

Allow users to dismiss the soft keyboard while composing markdown content. Extract the MarkdownReader component into its own file and add WebView-based caret preservation to restore the cursor position after the keyboard closes. This prevents the editor from losing focus and erasing the user's selected caret location when the keyboard hides.

* improve test
2026-08-11 13:08:50 -07:00
Brennan Benson 827e4a1c6c feat: toggle structured sessions between chat and TUI 2026-08-11 03:01:11 -07:00
NeilandOrca b3965f3205 perf(native-chat): suspend hidden transcript streams (#13622)
* perf(native-chat): suspend hidden transcript streams

* fix(native-chat): keep assembly renders pure

* fix(native-chat): keep a transient error from stranding a revealed chat

- An error snapshot frame no longer latches frameArrived, so the in-flight
  read can still seed the pane instead of leaving it on the error surface.
- Retained history is shown over a full-pane read error for the same source.
- The paged read window survives a hide/reveal; only a source change resets it.

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): match the trimmed native-chat retention signature

The shared retention type no longer takes `loading`, so mobile's call was an
excess-property error that broke the mobile typecheck job. Dropping it also
lets mobile inherit the desktop behavior: a stream error or dropped client
keeps the last transcript instead of swapping it for the error empty state.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-11 01:27:25 -07:00
Jinjing 9b79cc1b9e Add copy button for quick command (#13768)
* Add copy button to quick commands with visual feedback

Quick command rows now display a copy button that copies the command body to clipboard. The button shows brief visual feedback ("Copied" or "Couldn't copy") and is disabled when the command body is empty. Includes desktop and mobile UI, tests, and full i18n support.

* fix(ci): unblock verify for quick-command copy button

Key feedback to the copied body so prop changes drop stale labels without
setState-in-effect, and mock expo-clipboard in the mobile list test.
2026-08-11 01:06:03 -07:00
Brennan Benson 03d5373071 fix: fence structured AI Vault resumes 2026-08-11 00:54:48 -07:00
Brennan Benson e504fb44d3 Merge codex structured stack tip into desktop 2026-08-10 23:33:47 -07:00
Brennan Benson 75b3a209e6 Merge remote-tracking branch 'origin/main' into brennanb2025/codex-structured-mobile-write 2026-08-10 22:03:55 -07:00
Brennan Benson 93e08115d0 fix(native-chat): type Codex slash commands (#13685)
* fix(native-chat): type Codex slash commands

* fix(native-chat): keep Codex skill sends pasted
2026-08-10 22:02:46 -07:00
Neil 9796f7dc5f refactor(mobile): use shared GitHub Project sorting (#13459) 2026-08-10 20:41:34 -07:00
Neil a321ac3c8f refactor(mobile): use shared source-control decisions (#13453) 2026-08-10 20:41:31 -07:00
Neil af47fa10ac refactor(comments): share PR comment core (#13457) 2026-08-10 20:40:57 -07:00
Neil 556f469b0b refactor(mobile): remove orphaned PR composer (#13450) 2026-08-10 20:25:54 -07:00
Neil 75c6efd48b Remove obsolete pairing connection attempt (#13460) 2026-08-10 20:25:51 -07:00
Brennan Benson 3e3f48fe89 fix(native-chat): restore Codex model picker dispatch (#13669)
* fix(native-chat): restore Codex model picker dispatch

* fix(native-chat): type Codex effort picker command
2026-08-10 20:03:48 -07:00
Neil 96c2cebfa6 refactor(mobile): extract terminal settings styles (#13706) 2026-08-10 17:52:45 -07:00
Brennan Benson 398d3807e5 Merge remote-tracking branch 'origin/main' into brennanb2025/codex-structured-mobile-write
# Conflicts:
#	mobile/src/session/MobileNativeChatMessage.tsx
2026-08-10 16:17:25 -07:00
Brennan Benson de1b119141 fix(mobile): stop labeling accepted messages queued (#13658) 2026-08-10 16:09:17 -07:00
Brennan Benson 3a6eb1ee72 feat(native-chat): add desktop structured sessions 2026-08-10 14:45:48 -07:00
Brennan Benson c62f782554 Merge remote-tracking branch 'origin/main' into brennanb2025/codex-structured-mobile-write 2026-08-10 12:01:26 -07:00
Neil bbcf89e221 chore(mobile): prepare 0.0.43 releases (#13549) 2026-08-10 01:49:33 -07:00
Jinjing 418fbb3192 fix(mobile-ios): gate release on TestFlight distribution (#13419) 2026-08-10 01:47:36 -07:00
Brennan Benson 9202192f10 fix: restore structured chat parity 2026-08-10 01:37:59 -07:00
Brennan Benson 8623f12957 Fix paired mobile structured session creation 2026-08-09 22:34:13 -07:00
Brennan Benson cbd79a61e9 Keep mutation context updates out of render 2026-08-09 21:39:10 -07:00
Brennan Benson dcd26ef677 Close remaining structured mobile RC blockers 2026-08-09 21:35:24 -07:00
Brennan Benson ec917184c3 Satisfy the changed-line React Doctor gate 2026-08-09 20:18:43 -07:00
Brennan Benson 8778fdedad Harden structured mobile writes before RC 2026-08-09 19:58:58 -07:00
Brennan Benson bbc6aba927 Resolve structured mobile read review blockers 2026-08-09 19:58:23 -07:00
Neil 6c765d5ad3 refactor(mobile): remove native chat re-export facades (#13436) 2026-08-09 19:25:28 -07:00
Neil faaf3d2588 refactor(mobile): use shared diff and OSC implementations (#13433) 2026-08-09 19:16:26 -07:00
Brennan Benson 59ad53fecf Add mobile structured session write flow 2026-08-09 19:11:12 -07:00
Neil 403c60bbad refactor(mobile): remove unused review code (#13421) 2026-08-09 18:55:36 -07:00
Neil c56ff58dd7 test(mobile): centralize renderer setup (#13408) 2026-08-09 18:31:00 -07:00
Neil 954de38507 refactor(mobile): remove unused PR and review code (#13404) 2026-08-09 18:30:44 -07:00
Brennan Benson b4bcd20caa Add mobile structured session read flow 2026-08-09 18:22:23 -07:00
Jinwoo Hong 427f178a75 fix(mobile): load the repo list in GitHub Project mode (#12972) 2026-08-09 14:55:31 -07:00
EvgeniiandBrennan Benson 63af0bdd24 feat(agents): add Prime Agent as a supported TUI agent with session history (#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 #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 #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 #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 #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 #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>
2026-08-09 14:50:02 -07:00
NeilandOrca 17cfc968cf Revert the terminal IME composition-ownership change (#13282)
* Revert "test(ime): restore coverage the composition-ownership change removed (#13168)"

This reverts commit 25a8c517e1.

* Revert "refactor(terminal): return IME composition ownership to xterm (#13128)"

This reverts commit 17b3dff3c4.

* test(ime): keep the architecture-neutral Korean trace coverage

The recorded IBus/fcitx5 and Windows MS-Korean traces from #13168 assert PTY
byte order, not composition ownership, so they still hold once the terminal
composition layer is restored. The mobile accessory-order test pinned the new
handleLiveInputChange signature and does not.

Co-authored-by: Orca <help@stably.ai>

* fix(terminal): keep the macOS Backslash bypass through the revert

The restored native-text forwarder only claims keys for input sources in its
hardcoded CJK allowlist, so third-party IMEs off that list (Qingg, #10896) still
get a raw backslash. #13128 added this bypass as a partial replacement; keep it
rather than trade the open issue back.

Scoped to the bare backslash key. The rest of shouldBypassXtermForMacNativeText
bypassed all unmodified non-ASCII text, which would race the restored forwarder.

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): move the mirror-step ref write out of render

The restored hook assigned runMirrorStepRef during render, which is not
replay-safe — React can discard render work, so the mutation can leak from UI
that never commits. Its only read is inside the held-commit timer, which fires
long after commit, and the ref has a safe default, so an effect is soon enough.

Surfaced by the changed-lines React Doctor gate: the rule postdates this code,
so restoring the file re-introduced it as a new violation.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-08 19:06:50 -07:00
NeilandOrca 25a8c517e1 test(ime): restore coverage the composition-ownership change removed (#13168)
* test(terminal): pin the recorded Korean commit-before-newline order (STA-3132)

Recorded first-party on Windows 11 + Microsoft Korean (HKL 0412) against the
defect-era v1.4.164 build, with bytes read on the far side of the PTY: the
terminal received ea b0 80 0d, the syllable strictly before the CR.

The capture did not reproduce the suspected deferred-newline inversion. That
route needed a session end carrying dataPendingReconciliation, which plain
compose-then-Enter cannot produce because the IME finalizes first and the
newline is never held; back-to-back arms at 25/60/120 ms did not reach it
either. The test therefore pins the ordering rather than discriminating a fix.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): restore Hangul back-to-back flush coverage deleted with the composition layer

#12278 fixed a Hangul syllable that was not flushed before the next
composition began — the force-end path, and the one that leaves stale glyphs
behind. Returning composition ownership to xterm deleted both that patch and
its test, so nothing guarded the behavior any more.

Replays the recorded back-to-back arms (25/60/120 ms, read as 가\r나 at the
PTY) against a real xterm Terminal. It passes on main: stock xterm flushes the
committed syllable natively, so the removal was safe rather than a silent
regression.

Co-authored-by: Orca <help@stably.ai>

* test(mobile): pin accessory-byte ordering behind a Hangul commit

Returning composition ownership to xterm deleted the accessory-input commit
tests along with the hook they targeted, but the guarantee they protected is
user-visible and still applies: an accessory-bar keystroke must not overtake
the syllable being committed, and must be suppressed when that commit fails.

Drives the current hook with an Android composing-region trace rather than
reconstructing the deleted coordinator.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): replay recorded IBus and fcitx5 Hangul traces offline

Commits interleaved with ASCII (한abc글) are the Linux IME gesture users report
on, and its failure modes are a lost syllable and a doubled one. That gesture
was only covered by tests/e2e/terminal-linux-ime-native.spec.ts, which needs a
Linux host running a real input framework.

Fixtures are the recorded captures from the sealed linux-final evidence run,
replayed against a real xterm Terminal: exact onData, exactly-once counts across
five repetitions, and the PTY bytes the recorded run actually received.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-08 02:29:40 -07:00