Commit Graph
6852 Commits
Author SHA1 Message Date
Brennan Benson 3a40e8b88a test(codex): isolate hook lifecycle user data 2026-07-17 14:30:22 -07:00
Brennan Benson df38f66ddf fix(codex): bound validation harness shutdown 2026-07-17 13:47:06 -07:00
Brennan Benson f9aa83d8e5 fix(codex): finish C and E matcher composition 2026-07-17 13:32:37 -07:00
Brennan Benson 6272dba1d0 Merge branch 'brennanb2025/codex-ma-e-per-account-home' into brennanb2025/codex-ma-integration-validation
# Conflicts:
#	src/main/codex-accounts/runtime-home-service.ts
2026-07-17 13:30:55 -07:00
Brennan Benson f8c31bc3fd Merge branch 'brennanb2025/codex-ma-d-provider-guard' into brennanb2025/codex-ma-integration-validation
# Conflicts:
#	src/main/codex-accounts/service.test.ts
#	src/main/codex-accounts/service.ts
2026-07-17 13:27:14 -07:00
Brennan Benson 26635fc3c8 Merge branch 'brennanb2025/codex-ma-c-readback' into brennanb2025/codex-ma-integration-validation 2026-07-17 13:26:43 -07:00
Brennan Benson 0d45b45485 Merge branch 'brennanb2025/codex-ma-b-identity' into brennanb2025/codex-ma-integration-validation 2026-07-17 13:26:43 -07:00
Brennan Benson 3ff573a906 Merge branch 'brennanb2025/codex-ma-a-config-hygiene' into brennanb2025/codex-ma-integration-validation 2026-07-17 13:26:43 -07:00
Brennan Benson 0a4e1ba228 test(codex): add real-account validation harness 2026-07-17 13:26:30 -07:00
Brennan Benson bb9748439b test(e2e): isolate Electron from developer Codex home 2026-07-17 13:26:28 -07:00
Brennan Benson 7f4880380c fix(codex): migrate stranded shared auth on E takeover 2026-07-17 13:17:45 -07:00
Brennan Benson ac99e5f2b2 fix(codex): keep managed rollouts discoverable across real-home opt-out
WI-4 lossless migration/rollback validation for pre-E shared-mirror managed
accounts. Session discovery gated the per-account home scan on the real-home
flag, so opting back out (flag OFF) hid every rollout an account accumulated
while the flag was ON — the data stayed on disk but vanished from the AI Vault
until the flag flipped back on.

Scan a managed host home whenever it holds a sessions/ tree, independent of the
flag; a never-enabled install keeps its homes credential-only so opt-out stays
byte-identical to today. Forward migration was already lossless (the shared
mirror is always scanned) and the opt-out credential read-back already refuses
to overwrite a fresher per-account token; add tests locking all three
invariants. Sandboxed tests only; ~/.codex is never touched.
2026-07-17 13:01:34 -07:00
Brennan Benson 433356adcf fix(codex): validate per-account home ownership 2026-07-17 03:19:37 -07:00
Brennan Benson c6ab5195e7 feat(codex): give each managed account a self-contained CODEX_HOME; retire shared mirror (PR-E)
With the real-home flag ON, a host managed account now launches directly
against its own codex-accounts/<id>/home instead of the shared runtime
mirror + auth.json hot-swap:

- codex-home-paths: syncSystemCodexResourcesIntoManagedHome links system
  resources into any managed home (ownership-marker discipline; never
  symlinks into / mutates ~/.codex).
- runtime-home-service: prepareForCodexLaunch / prepareForRateLimitFetch /
  syncForCurrentSelection route the per-account home directly and skip the
  shared-home hot-swap + token read-back; each home keeps its own auth in
  place (fixes GAP-5 concurrent auth race). Session discovery scans every
  per-account home.
- hook-service / hook-trust-promotion: install/getStatus/refresh accept a
  runtimeHomePath so hooks + RPC-granted trust land in the per-account home.
- service: config mirror into a self-contained home uses the trust-
  preserving merge so granted hook/project trust survives account switches.
- codex-session-root-dedup: rank codex-accounts/<id>/home as canonical
  managed alongside the shared runtime home.

Flag-OFF and the system-default real-home (null) lane are unchanged; the
nested-Orca CODEX_HOME===ORCA_CODEX_HOME daemon strip (#5370) is preserved.
Sandboxed tests only; ~/.codex is never mutated.
2026-07-17 03:17:08 -07:00
Brennan Benson 9c20fd301b fix(codex): harden system-default identity rendering 2026-07-17 02:47:21 -07:00
Brennan Benson efaa61d596 fix(codex): harden managed trust sanitization 2026-07-17 02:39:16 -07:00
Brennan Benson 1c328c56cb fix(codex): parse multiline provider pins in OAuth guard 2026-07-17 02:37:30 -07:00
Brennan Benson 7f3f676f1c feat(codex): show system-default/real-home account identity in switcher (PR-B)
The account switcher modeled the system-default Codex account as
activeAccountId:null with no identity fields, so the null row rendered
blank ("System default" / generic subtitle) even though its effective
login is whatever ~/.codex/auth.json currently is.

Add a CodexSystemDefaultIdentity descriptor {hasAuth, authKind, email,
providerAccountId, workspaceLabel} to CodexRateLimitAccountsState,
resolved live and READ-ONLY from ~/.codex by the accounts service and
returned from listAccounts()/getSnapshot(). The settings switcher now
renders the null (system-default) row as that real identity: the OAuth
email when signed in, "Custom provider — no usage tracked." for
env-key/custom-provider logins (auth.json with OPENAI_API_KEY, or an
OPENAI_API_KEY env with no auth.json), and the generic fallback when
signed out. Identity is host-scoped (per-distro WSL keeps the generic
label). Orca never writes ~/.codex; managed-account switches only touch
Orca-owned homes, so the system-default identity stays a stable,
displayed source of truth. Usage already routes to the real home via
getSystemCodexHomePath, so the switcher now attributes it to a real face.

Tests (sandboxed temp homes only): OAuth email/provider resolution,
api-key auth.json and env-key (no auth.json) as custom-provider,
signed-out, and select/deselect of a managed account never mutating
~/.codex/auth.json.
2026-07-17 02:36:54 -07:00
Brennan Benson 0f125eb93c fix(codex): preserve refreshes across all default transitions 2026-07-17 02:36:38 -07:00
Brennan Benson bde30e38a2 fix(codex): persist outgoing managed tokens before real-home lane takeover (PR-C)
prepareForCodexLaunch returns null early for the real-home / system-default
lane before syncForCurrentSelection runs. If a managed account is still
recorded as synced when the selection has dropped to the system default
(nulled without a sync pass, or auto-deselect on missing managed auth), a
Codex-refreshed token stranded in the shared runtime home is never persisted
to its canonical per-account home -> token loss.

Read the outgoing managed account's refreshed token back before the real home
takes over. The real-home lane implies host === null, so running the
managed->system-default transition restores only Orca's runtime mirror from
~/.codex and never writes the real ~/.codex. It is a no-op once the selection
has already been reconciled, so the normal select path does not double-write.
2026-07-17 02:26:51 -07:00
Brennan Benson 13f32d4965 fix(codex): guard OAuth add for custom providers 2026-07-17 02:26:38 -07:00
Brennan Benson bfea35fbb5 fix(codex): sanitize managed account config trust 2026-07-17 02:22:14 -07:00
Brennan Benson 5880c6ad65 Merge commit '44686f324ce6ced7e976555031471940b24de9d6' into brennanb2025/codex-home-consolidation 2026-07-17 00:36:28 -07:00
Brennan Benson d76d955dec fix(codex): snapshot hooks.json bytes+parse in one read to close real-home clobber race
The install/sweep/legacy-cleanup paths parsed hooks.json, then did a separate
later read to capture the previous bytes for the pre-write generation guard.
A concurrent save (second Orca instance or the user editing the file) could
land between the parse and that second read and be silently overwritten.
readHooksJsonWithRaw returns the raw bytes and parse from a single read so the
guard compares against exactly what it parsed. Adds a regression test that
mutates hooks.json mid-RPC and asserts the sweep aborts without clobbering.
2026-07-17 00:36:06 -07:00
Brennan Benson 44686f324c feat(native-chat): add mobile default-view toggle for native chat (#9084)
* feat(native-chat): add mobile default-view toggle for native chat

Adds a per-device "Native chat" setting on mobile (Settings → Native chat)
that controls whether supported agent sessions open in the native chat view
or the raw terminal. Default stays terminal; flipping it on makes eligible
sessions render as native chat, mirroring the desktop default-view control.

- New orca:defaultSessionView preference (loadDefaultSessionView/save).
- Per-tab chat set refactored into a tri-state override map so a session can
  be pinned to terminal or chat regardless of the default; the legacy array
  format migrates to chat overrides on load.
- useMobileSessionViewMode resolves each tab as override ?? default and
  reloads the default on focus so a Settings change applies without remount.
- Toggle/action-sheet builders take an isTabChatView predicate.

* chore(skills): refresh skill bundle manifest for v1.4.144-rc.2

The v1.4.144-rc.2 release bump left resources/skills/current-manifest.json
pointing at rc.1, so verify:skill-bundle-manifest fails on any branch that
reaches it. Regenerated (appVersion only; no skill content changed) to
unblock CI. Unrelated to the native-chat toggle in this PR.

* fix(native-chat): harden mobile view preferences

* fix(native-chat): harden default view persistence

* fix(native-chat): serialize mobile view persistence

* fix(native-chat): reconcile failed mobile view saves

* fix(native-chat): fail closed on unreadable view overrides

* fix(native-chat): honor fail-closed view races
2026-07-17 00:34:46 -07:00
Brennan BensonandOrca c5d2275c35 Add preference to show pinned worktrees in original lists (#6216)
* Add setting for pinned worktree group display

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

* Fix pinned worktree host metadata

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

* Polish pinned worktree setting copy

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

* Clarify pinned worktree setting copy

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

* Use original lists in pinned setting copy

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

* Fix pinned sidebar order and render churn

* Fix pinned host and inbox placement

* Fix worktree host ownership consistency

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-17 00:21:42 -07:00
Jinwoo HongandOrca d0b090b0ff fix(main): cancel unread fetch response bodies so a peer socket close cannot crash the app (#9142)
Co-authored-by: Orca <help@stably.ai>
2026-07-16 23:10:40 -07:00
Neilandgatsby74 23368ee9da fix(shortcuts): preserve native input-source switching (#9108)
* fix(shortcuts): preserve native input-source switching

* fix(shortcuts): harden native input-source switch companions

Build on #8305 (@gatsby74): normalize Space key identities so Chromium
keypress without code still cancels companions, clear stale pending on
blur/next keydown, and block insertText beforeinput while a native-only
chord is live. Add #8299 regression coverage.

Co-authored-by: gatsby74 <166927047+gatsby74@users.noreply.github.com>

* fix(shortcuts): harden native-only event tracking

---------

Co-authored-by: gatsby74 <166927047+gatsby74@users.noreply.github.com>
2026-07-16 22:49:28 -07:00
Neil 0cd50eecdb fix(pet): key sprite keyframes on the resolved track; cap render durations (#9140)
Follow-up polish to #8730: key @keyframes on the resolved row/frames (so a same-row fallback like hover on a jumping-less pet doesn't restart idle), mirror the importer's 60s per-frame cap at render, and trim comments to the 1-2 line convention.
2026-07-16 22:21:58 -07:00
Jinho Choiandnasagong 13c690b05a fix(pet): match Codex's per-frame pacing and pointer interactions for imported pets (#8730)
Imported .codex-pet bundles played every animation at a flat 8 fps (~9x too
fast). Mirror Codex's exact per-frame duration tables, render uneven holds as
step-end keyframes, upgrade legacy-persisted pets at render, and add the Codex
mascot's pointer interactions (hover, grab-and-hold on frame 0, horizontal-drag
running). Hardened over several adversarial review rounds: honor explicit fps,
start each row/pet from frame 0, scope drag to its pointer, and guard untrusted
persisted data.

Fixes #8729

Co-authored-by: nasagong <zinho2000@gachon.ac.kr>
2026-07-16 21:59:44 -07:00
fsdwenandJinjing 8ec050a875 fix(i18n): 修复 zh.json 分页翻译错误和 9 处未翻译文案 (#8990)
- 分页按钮文字修正:Next→下一页, Next page→前往下一页, Previous page→前往上一页
- 翻译 4 处 Jira 连接对话框未翻译描述文案
- 翻译 2 处 Jira 集成卡片描述(远程存储/本地存储)
- 翻译 2 处文件删除确认混合场景文案
- 翻译 Grok 统一计费账户月度已用额度说明

Closes #8988

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-16 21:39:13 -07:00
fa85536f3a fix(ssh): repair unbuilt relay native deps (#8686)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-16 21:32:13 -07:00
Brennan Benson 1284a00e93 fix(native-chat): don't force a default model/effort on agent spawn (#9134)
#9085 made resolveNativeChatSessionOptionDefaults fall back to the catalog
default model (sonnet) and effort (high) whenever the user had not explicitly
picked one, injecting `--model sonnet --effort high` (and codex `-m`/`-c`
equivalents) onto every agent spawn: composer, worktree activation,
source-control agents, onboarding, work-item launch, floating terminal, and
new-tab launch. That silently overrode each user's own CLI-configured default
model.

Return undefined (spawn the agent exactly as its own CLI would) unless the user
has explicitly selected a model, and carry only explicitly stored option
values. An explicit model selection still applies that model and its catalog
option defaults via resolveAgentSessionOptionLaunch.
2026-07-16 21:29:17 -07:00
1b331f282c feat(editor): bindable keyboard shortcut to add a markdown review note (Mod+Alt+N) (#8250)
* feat(editor): bindable shortcut to add a markdown review note

Adds editor.addReviewNote (default Mod+Alt+N) to the shared keybinding
registry and wires it into all three markdown surfaces: the rich editor
key handler invokes the annotation popover opener, the Monaco editor
installs a keydown listener that opens the composer for the tracked
selection target, and the preview maps the DOM selection to its
annotation block. openAnnotationPopover now prefers the live selection
target over synced state so the shortcut works even before the sync
render lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYtipbTz8N4woN1sxTK1ia

* fix(editor): cover list items and Monaco path for add-review-note shortcut

Tag the preview's list-item annotation blocks with data-annotation-block-key
so the shortcut resolves selections inside li blocks (review feedback), and
extend the e2e spec to drive the Monaco source-editor wiring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYtipbTz8N4woN1sxTK1ia

* docs(e2e): explain store-driven view-mode switch in add-review-note spec

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYtipbTz8N4woN1sxTK1ia

* refactor(editor): extract add-review-note + selection-flush modules to satisfy max-lines after rebase

* refactor(editor): spread key-handler params and extract TOC hook to satisfy max-lines

* test(editor): move add-review-note installer test into its own describe

* fix(editor): pass add-review-note chord through when Monaco cannot act; cover preview surface e2e

* fix(editor): unify add-review-note chord consumption — consume only when a composer opens

* fix(editor): gate list-item annotation block key on composer availability

* fix(editor): require live selection for keyboard add-review-note

* chore: retrigger CI against current main (merge ref built during transient main breakage at 6e91ca6c0)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-16 21:10:15 -07:00
Brennan Benson cc1ad064d7 fix(skills): decouple bundled skill artifacts from the release train (#9119)
The current manifest stamped package.json's version into itself (9 lines),
so every RC/stable version bump made the committed artifact stale on every
open branch: lint failed until authors committed content-free regeneration
diffs, which also dragged the resources/skills-filtered update-roundtrip
matrix onto unrelated PRs. Cutting a release tag whose skills tree changed
had the same effect through release-mapping.json.

- current-manifest.json is now schema 2 and content-only; the generator no
  longer reads package.json. Registry and mapping stay schema 1 so the
  append-only released-history guard keeps its schema gate.
- The running build's version enters at the IPC boundary
  (skills:freshnessInventory passes app.getVersion()) and threads through
  the inventory to placement observation; current-revision placements are
  labeled with it while historical revisions keep resolving through the
  release mapping. The artifact loader and its cache stay content-only.
- verify tolerates a committed release mapping that is a byte-exact prefix
  of the derived one when every missing trailing row's revisions equal the
  current manifest (a just-cut tag over unchanged-since bytes); such rows
  are provably redundant until the next real regeneration adds them.

Artifacts now change only when skills/ content changes.
2026-07-16 20:02:01 -07:00
Neil 5ee90c8d59 fix(agents): recognize OpenCode native OC | tab titles (#9102)
* fix(agents): recognize OpenCode native OC | tab titles

OpenCode's native OSC titles use `OC | <task>` without an `opencode`
token, so title classifiers left tabs as Claude/unknown. Map the native
marker (optional mux prefix) to OpenCode identity in both title
classifiers, exclude it from isClaudeAgent, and cover lookalikes plus
stale Claude launch reclaim.

Builds on and supersedes #8590 (credit @gatsby74). Fixes #8478.

* fix(agents): drop renderer import from #8478 shared repro

tsconfig.node includes src/shared tests; importing agent-status pulled
renderer modules outside the node project and failed typecheck. Assert
opencode identity via shared title classifiers only (OpenCode TUI sets
"OpenCode" and `OC | ${title}`).

* fix(runtime): fill browser cert failure map in mobile snapshot fixtures

Main's #9104 reads browserCertificateFailuresByPageId in buildMobileBrowserTab
but left partial AppState test helpers without the field, breaking PR Checks
merge commits. Default the map in fixtures and use optional chaining so partial
state cannot throw.
2026-07-16 19:53:18 -07:00
Neilandbbingz e01f3f474c fix(sidebar): preserve Project Group members under Hide sleeping (#9101)
* fix(sidebar): preserve grouped projects under sleep filter

* test(sidebar): harden #8865 project-group sleep-filter coverage

Add adversarial cases for explicit project filters, multi-member groups,
ungrouped neighbors, and buildRows membership/count preservation.

Co-authored-by: bbingz <zzb@gxsmjx.com>

---------

Co-authored-by: bbingz <zzb@gxsmjx.com>
2026-07-16 19:38:13 -07:00
539e0601d5 fix(github): render GitHub Enterprise PR avatars via API avatar_url (#9107)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: davkim1030 <davkim1030@gmail.com>
2026-07-16 19:24:10 -07:00
Neil a7c40cd89b fix(terminal): stop gluing the next line onto a modifier-clicked URL (#9100)
Fixes #8832.

HTTP hit-testing no longer consumes path hard-wrap candidates that poisoned mid-row URLs with next-line labels. Uses soft-wrap, framed hard-wrap HTTP, and dedicated edge-wrap reconstruction instead.

Supersedes #8852 (edge-wrap approach credit: @xianjianlf2).
2026-07-16 19:21:09 -07:00
Neiland조재중 53af61160a fix(settings): keep Shortcuts rows visible on pane-title-only search (#9097)
Co-authored-by: 조재중 <126754298+m-a-king@users.noreply.github.com>
2026-07-16 19:20:05 -07:00
d363c83ae3 fix(worktrees): force-remove clean worktree with initialised submodule (#9096)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: MarkXian <mark-xian@foxmail.com>
2026-07-16 19:15:40 -07:00
NeilandJinjing 6e91ca6c0e fix(browser): local HTTPS Try HTTPS + cert proceed (#8454) (#9104)
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-16 19:11:34 -07:00
github-actions[bot] 3b227d06e8 release: v1.4.144-rc.4 v1.4.144-rc.4 2026-07-17 01:52:57 +00:00
Brennan Benson 91ece6ca7e fix(terminal): tear down runtime-owned headless PTYs on whole-tab close (#9114)
* fix(terminal): tear down runtime-owned headless PTYs on whole-tab close

#8958 placed the closeTerminalTab renderer relay ahead of the authoritative
headless teardown in closeMobileSessionTab. Production always wires
closeTerminalTab, so the teardown became dead code for whole-parent closes
whenever a window is attached. The relay resolves close targets only from
renderer state (resolveTerminalCloseTarget), which never contains a
runtime-owned headless tab, so it acks success without killing the PTY —
leaking SSH-durable/serve PTYs and letting syncMobileSessionTabs republish
the "closed" tab (the exact case the removed comment warned about).

Run the isRuntimeOwnedHeadlessMobileTab teardown before the relay so headless
tabs are killed and pruned authoritatively even with a renderer attached;
normal adopted tabs still take the durable closeTerminalTab path. Add a
regression test that wires both notifiers (prior tests covered only the
no-notifier and in-graph cases).

* fix(terminal): preserve adopted tab close guards

* fix(runtime): preserve headless close durability on notifier failure
2026-07-16 18:41:49 -07:00
Brennan Benson f6f2561623 ci(release): regenerate skill manifest on version bump (#9117)
* ci(release): regenerate skill manifest on version bump

The release-cut "Bump package.json and tag" step bumped package.json but
never regenerated resources/skills/current-manifest.json, so its appVersion
stayed at the prior release. That drift shipped in v1.4.144-rc.1, rc.2, and
rc.3 (all carried an rc.1 manifest) and turns verify:skill-bundle-manifest
red on every branch after a cut, since that check runs in `pnpm lint` and
the PR `verify` job.

Regenerate the manifest right after `npm version` and stage resources/skills
into the release commit so the bundled manifest always matches the shipped
version. The generator is dependency-free (node builtins + git), so it runs
without a pnpm install, and the step's fetch-depth:0 checkout supplies the
tag history it reads.

* test(release): guard skill manifest regeneration

* test(release): require full history for skill manifest
2026-07-16 18:39:11 -07:00
Brennan Benson 900397369c fix(settings): show "Up to date" for current skills in settings sidebar (#9086)
* fix(settings): show "Up to date" for current skills in sidebar

Orchestration and Computer Use showed a green "Installed" badge in the
settings sidebar even when freshness tracking knows the copy is current.
Add an "up-to-date" nav status so a present, no-update skill reads
"Up to date" (pairing with the existing "Update available" state), while
Voice — which tracks model readiness, not skill freshness — keeps
"Installed".

* fix(settings): require freshness proof for current badge

Only label a skill Up to date when every discovered placement is current. Keep Installed for unloaded, blocked, inaccessible, or unrecognized inventories, and share the classifier with the existing freshness pill. Regenerate the current skill manifest so its app version matches the package release and the required verification gate passes.
2026-07-16 18:33:48 -07:00
Brennan Benson ce910e5d52 fix(naming): keep the built-in branch-name prompt general (#9088)
* fix(naming): keep the built-in branch-name prompt general

The shipped auto-rename prompt no longer hard-codes style rules (word
count, kebab-case, no prefixes). Users can already override naming via
Source Control AI instructions and the branch-name command template; a
prescriptive default fought those overrides. Git-safe sanitization still
runs after generation.

* fix(naming): preserve branch prompt overrides

* chore(skills): refresh rc.2 manifest version
2026-07-16 18:33:34 -07:00
JinjingandOrca a03a3dd51b Render png on mobile (#9087)
* Add mobile image-diff previews via shared data-URI builder

- Extracts a `buildImageDataUri` helper (src/shared/image-data-uri.ts) shared by
  the desktop ImageViewer and mobile, so both trim whitespace-wrapped base64 and
  skip non-previewable mimes (e.g. application/pdf) the same way.
- Adds mobile-diff-image-preview.ts to render binary git.diff results (add/modify/
  delete) as images instead of falling back to "Binary preview unavailable".
- Extracts resolveMobileFileTabDoc to consolidate the session file-tab loading
  logic (diff/image/html/text) out of the route file for testability.

* Fix stale binary image fallback for empty modified diffs and relay reads

- mobileDiffImageDataUri now distinguishes a true deletion (modified
  side absent) from a modify whose binary bytes arrived empty
  (relay/size-cap cases), returning null instead of the stale
  pre-change image
- readWorkingDiffFile passes the file path to bufferToBlob so relay
  working-tree reads can detect previewable image extensions instead
  of always reporting empty binary content
- add mobile-file-tab-doc.test.ts covering diff/image/binary/text
  resolution paths

* Regenerate skill bundle manifest for 1.4.144-rc.2

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

* fix(review): trim comments to AGENTS.md's one/two-line why-only rule

Comments in mobile-diff-image-preview.ts and mobile-file-tab-doc.ts ran
3-6 lines and narrated mechanism instead of stating only the non-obvious
reason, per AGENTS.md's "Code Comments: Document the Why, Briefly" rule.

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

* Distinguish read failures from true deletions in binary diff results

- Working-tree stat/readFile errors and relay reads previously collapsed
  onto the same empty-content signal as a genuine deletion, letting
  previewers fall back to stale original bytes on a failed read.
- Add modifiedDeleted/missing flags through status.ts, git-handler-ops,
  and git-working-file-read so only proven deletions trigger the
  original-bytes fallback; failed reads now return null.
- Tighten buildImageDataUri to accept only image/* mimes instead of
  special-casing application/pdf.

* fix(relay): expect missing:false on index blob maxBuffer overflow

readBlobAtIndex now returns a missing flag so staged deletions are
distinct from size-capped binary reads; update the overflow test.

* Allow opening deleted files to show pre-delete text or image diffs

Deleted files can now be opened to view their pre-delete content via
git.diff (including images via modifiedDeleted). Only unresolved conflicts
remain unopenable. Centralizes the canOpen rule in canOpenMobileGitStatusEntry()
to keep opener guards consistent across the mobile source control UI.

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-16 18:21:08 -07:00
JinjingandOrca cdc7a5ca46 Relay ssh image diff (#9112)
Co-authored-by: Orca <help@stably.ai>
2026-07-16 18:08:47 -07:00
OrcaWin f10c40591c fix(win): set UTF-8 console code page for Git Bash terminals (#9054)
Launch Windows Git Bash as `bash -c 'chcp.com 65001 >/dev/null 2>&1; exec "$BASH" --login -i'` so the ConPTY console is UTF-8 before a byte-writing UTF-8 TUI runs, matching what cmd.exe and PowerShell already do. Fixes CP437 mojibake for byte-writing agents in Git Bash tabs. Scoped to Git Bash; does not address PowerShell-reported mojibake.
2026-07-16 18:05:38 -07:00