Commit Graph
10 Commits
Author SHA1 Message Date
Gadfly ea4fd9bbff feat(codex): carry editor context beside the user's words, not inside them
Changing editor state used to be pasted straight into the message text,
spending the user message's native budget and polluting history replay.
Each turn now freezes structured additionalContext fragments instead
(ide_context, open_tabs, workspace_context, referenced_files_<index>,
terminal_context_<index>), so every fragment enjoys its own native budget
and the request text stays pristine.

The service sniffs the selected CLI once per child process via
app-server generate-json-schema --experimental to learn whether
turn/start accepts additionalContext, and re-sniffs after a runtime
replacement; discovery never creates a thread or turn and cancels leave
it early. Older CLIs get the official desktop text envelope with UTF-8
text-element byte ranges shifted accordingly, and history replay strips
that envelope so users only ever see their own request.

Cover the flow with schema-probe, fallback, cancellation and daemon
tests on the bridge side plus context-budget, payload-copy and display
sanitizer tests on the Java side; document the contract in
docs/codex/app-server.md.
2026-10-25 21:37:23 -07:00
Gadfly e78a9ca897 fix(codex): preserve streamed messages and replay tool batches consistently
Codex streaming could omit commentary, reasoning, and edit cards between
batches until the conversation was reloaded. Historical exec wrappers also
collapsed supported parallel calls into generic exec cards and used command
labels that differed from live rendering.

Preserve snapshot ordering and complete message corrections:
- Compare complete raw message content when selecting the transported suffix;
  keep structural signatures limited to snapshot scheduling.
- Apply a buffered full snapshot before its dependent tail update advances
  the sequence barrier, retaining intermediate items during React batching
  and stream completion.

Restore recorded tool batches without guessing result ownership:
- Associate Promise.all and Promise.allSettled results with their original
  array slots, including independently printed index labels in forEach and
  bounded for loops.
- Retain labeled arrays, primitives, plain text, and label-like values.
- Restore mixed command and write_stdin batches while keeping polling tied
  to the original process card.
- Match identical commands through confirmed process identities or unique
  explicit absolute working directories, including file URIs and Windows
  paths, while preserving literal POSIX backslashes.
- Never assign unindexed parallel process receipts by arrival order; retain
  the original wrapper whenever ownership cannot be established.

Keep local Promise computations out of the visible tool timeline:
- Preserve Promise.resolve expressions and indexed results as internal data
  without executing historical source.
- Filter these entries through the shared rendering predicate so they neither
  create cards nor interrupt command groups in live or historical messages.
- Separate rejection metadata from result fields, distinguish Promise.all
  values from settled envelopes, and decode nested local receipts only when
  the source proves that the complete settled receipt was printed.
- Keep flattened local Promise.all output in its original wrapper rather
  than interpreting data fields named status or error as execution outcomes.

Align historical command rows with live presentation:
- Preserve recorded summaries, approval reasons, and parsed command actions.
- Accept both list_files and listFiles directory action names.
- Remove generated English command summaries and retain Bash tool identities
  for legacy reads and searches so the shared renderer controls row labels.

Extend Java, React, and browser regression coverage for snapshot ordering,
process ownership, mixed batches, local result preservation, command labels,
and continuous tool grouping. Update the Codex runtime documentation and
browser fixtures to describe the resulting behavior.

Validation:
- 199 Java tests passed across CodexKnownExecReplayTest,
  HistoryMessageInjectorTest, CodexHistoryPageIndexTest, and
  StreamMessageCoalescerStreamEndHookTest.
- Gradle checkstyleMain passed.
- 67 targeted frontend tests passed across snapshot callbacks, MessageItem,
  GenericToolBlock, tool constants, and command presentation.
- TypeScript test-project checking and git diff --check passed.
2026-10-25 21:37:23 -07:00
Gadfly fe95dd8ef4 fix: help CLI detection catch the standalone-installed codex and trust only proven versions
- Discover the CLI in the official standalone installer layouts on both
  the Java detector and the Node resolver: CODEX_INSTALL_DIR, Windows
  %LOCALAPPDATA%\\Programs\\OpenAI\\Codex\\bin, and
  ${CODEX_HOME:-~/.codex}/packages/standalone/current in both the
  bin/ and flat layouts, without scanning unselected releases/
- Mark Codex installed only when "codex --version" really prints
  "codex-cli <version>"; a half-installed npm launcher that still
  executes no longer poses as a working CLI (docs contract updated)
- Point the chat diagnostics card and the CLI install dialog at the
  official per-platform install/update instructions instead of the
  old npm-first recipe, and sync the new wording across all ten UI
  languages (zh also aligns 供应商管理 with the settings label)
2026-10-16 16:32:39 +08:00
Gadfly d21a8f4ed7 fix(codex): count history list messages through a native tally pipeline
The history list could not say how many messages each Codex thread
holds, because the thread listing only summarizes turns and the webview
had to guess from whatever fragment happened to be loaded. Add a
codex.countThreadMessages daemon method that walks the native history
pages, dedupes messages by uuid, and caches each tally per thread
revision, and give the webview a concurrency-capped queue that counts
the visible sessions and merges the results into paginated publishes
without losing edits or deletions made in between. Item reads that
return incomplete without a continuation cursor now fail loudly instead
of collapsing a partially hydrated turn into an empty transcript.
2026-10-09 16:49:16 +08:00
Gadfly 6c3632fc6e fix(codex): retire auxiliary title work on turn abort and keep it out of transport tests
The Linux CI job failed on stopBeforeNativeTurnIdentityDoesNotReplayAndConfirmsProcessExit:
the fixture's isolated HOME has no config, so title generation defaulted on and its
thread/read RPC plus auxiliary app-server child raced the abort's process-exit
assertion.

- codexAbortTurnPersistent cancels the session's titleAbort alongside the turn
  stop: a user-requested stop retires the naming work instead of leaving a
  lingering title child alive for up to 15 seconds.
- CodexFixtureDaemon writes aiTitleGenerationEnabled=false into the isolated
  home so transport integration tests never depend on the global title setting.
2026-10-09 13:59:27 +08:00
Gadfly ff871138c4 Merge remote-tracking branch 'zhukunpenglinyutong/feature/v0.6.0' into fix/clipboard-image-paste-lifecycle
# Conflicts:
#	ai-bridge/services/codex/persistent-codex-service.js
2026-10-09 13:44:44 +08:00
Gadfly 441368d04d fix(codex): name new threads mid-turn and keep reload batches intact
- Start the auxiliary title request as soon as the native threadStarted
  event announces the thread instead of after the whole turn settles.
  Only the first created thread claims the attempt, a failed bootstrap
  leaves retried or queued sends eligible, and teardown cancels and
  awaits every pending listener.
- Register the persistent app-server daemon in the Node process panel
  and keep its descendants off the orphan list; panel restart stops only
  the daemon so multi-turn session state survives.
- Group consecutive same-page history slices into one pending queue
  entry so backpressure cannot drop a middle batch and split reloaded
  tool cards with separators; failed scripts requeue with their
  grouping and order intact.
- Carry recorded turn/thread ownership onto replayed legacy messages and
  recover agentMessage items whose body is a plain content string, so
  reloaded transcripts merge each tool batch into a single card.
- Pair legacy wrapper commands with native receipts by process id and
  keep ambiguous same-text commands as wrappers instead of guessing
  their outcomes.
2026-10-09 13:34:08 +08:00
zhukunpenglinyutong d5b153f8c0 fix(codex): fall back to the next Codex CLI when the chosen install cannot start
A machine commonly carries several `codex` installs (version managers, npm
global prefixes, a manual download) and only some of them are complete.
Discovery returned the first match, so an incomplete copy - typically an
`@openai/codex` npm launcher whose platform package is missing - was picked,
died with `spawn ... ENOENT` before READY, and took the whole turn down with
a bare exit code.

- listCliCandidates() keeps every PATH match (`which -a` / `where`), the env
  override, home candidates, well-known bin dirs and the login shell, then
  dedupes by real path; resolution still spawns no child process, since CLI
  version probing belongs to the settings page.
- classifyCodexCli() judges a candidate from filesystem facts only: the npm
  launcher is resolved through its symlink to its `@openai/codex` package,
  and an install whose platform binary cannot be confirmed is demoted behind
  every confirmed candidate rather than dropped, so a heuristic can never
  take away a working CLI.
- resolveCodexCli() returns the ordered `candidates` plus the `rejected`
  entries with a concrete reason; the full candidate list survives as startup
  fallbacks, and an explicit override that only looks incomplete is honoured.
- CodexAppServerService gains a bounded `startupAttempts`: a death before
  READY advances to the next candidate, emits `runtimeFallback`, and only
  fails when every candidate is exhausted. Exits after READY never retry,
  because nothing was dispatched before the handshake completed. Transport
  events during a start in flight are deferred to the startup loop so their
  synchronous `exited`/`processError` cannot pre-empt the fallback.
- The client keeps a bounded, sanitized stderr tail and attaches the launch
  command and that tail to `err.details` when a start dies, so a startup
  death is no longer only an exit code. The canonical message is unchanged
  for existing consumers; the runtime failure text appends the per-CLI
  attempt results and an actionable hint.
- CodexNativeHistoryReader matches the exit line by prefix (not `matches`),
  so a wrapped line with diagnostics still permits the read-only history
  fallback.
- webview: a `codexCliUnavailable` error pattern with reinstall / `CODEX_BIN`
  guidance, localized in all ten locales.

Also bump the version to 0.6.0-beta1.
2026-10-09 13:02:28 +08:00
Gadfly 74d7cd255f fix(codex): address remaining review findings across daemon, plugin and webview
- Return NO_THREAD from compact/review before enqueueing a threadless
  operation, matching the daemon's public guard.
- Cache Codex CLI status for 30s per dependencies root: the discovery
  chain shells out a login shell when nothing resolves and ran on every
  request.
- Give an acked compaction its own 60s announcement budget before the
  uncertainty watchdog retires the runtime, since capture_step_context
  can outlast the 10s stop budget.
- Drop dead codex.listTurns/listItems plumbing (daemon, handler map,
  app-server doc) and the legacy cross-package SDK fallback in
  DependencyManager/SdkDefinition.
- webview: reset hunk state at each file header in multi-file unified
  diffs, key the edit preview by item instead of drifting index, unlock
  threadless compaction echoes whose threadId arrives omitted, and
  localize the plan-refinement prompt in all ten locales.
2026-10-06 04:18:48 +08:00
Gadfly 983705f5d0 feat(codex): migrate Codex runtime to persistent app-server
Replace the per-turn `codex exec` TypeScript SDK path with a persistent
`codex app-server --listen stdio://` JSON-RPC connection managed by the
Node daemon: Java -> DaemonBridge -> persistent CodexAppServerService ->
native app-server, one initialized child per chat host with native
thread/turn lifecycle.

Node (ai-bridge):
- Add app-server stdio client (handshake, request/reply registries,
  classified errors, uncertainty budget) and the operation service
  (session FIFO, frozen settings revisions, reverse interactions,
  item/plan/compaction projections, launch-config rebuild at idle).
- Add persistent per-session service wrapper, CLI resolver with legacy
  dependency fallback, sanitized runtime environments, native history/
  subagents/catalog readers, privacy journal, and ephemeral text
  requests for prompt enhancement, commit generation and session titles.
- Remove the TypeScript SDK load path and JSONL re-read from live turns.

Java:
- Rewrite CodexSDKBridge on the provider facade: structured daemon
  routing with channel/epoch/runtime-generation gates, thread ownership
  registry, interaction registry with page tokens, native history
  reader with offline-only legacy fallback, and daemon lifecycle
  coordination.
- Add interaction/data/workspace-diff handlers, file navigation helper,
  native file-change undo plan (patch reversal, rename baselines), and
  Codex history merger for restored sessions.
- Route Codex runtime management to the shared CLI detection page;
  drop the Codex SDK dependency definition and install entries.
- Wire send identity (clientMessageId), stream-end release on startup
  errors, and per-origin diff/undo receipt routing.

Webview:
- Add native plan state, compaction status, turn activity, session edit
  ledger, workspace diff dialog, patch/file-change cards, command
  presentation, desktop attachment envelope handling, and Codex command
  dispatch (/compact, /diff, /approvals, execute plan).
- Align skill filtering with the native `enabled` field, complete the
  codexQuota locale block for all 10 languages, and keep cached
  normalization for high-volume message rendering.

BREAKING CHANGE (internal): Codex approvals switch from boolean file
IPC to structured bidirectional events carrying runtime/thread/turn/
item/RPC identity. Other providers keep their existing protocols.
Approval requests now follow Codex native policy instead of treating
every started tool as pending.

Verified: Node 1142 tests (1139 passed / 3 platform skips), Java 1655
tests across 204 suites plus Checkstyle/JaCoCo, webview 2178 vitest
tests and tsc, four-viewport Playwright suites, openspec strict
validation (71 requirements / 392 scenarios), JDK21 buildPlugin.
2026-10-05 03:18:18 +08:00