Skip to content

feat(hooks): support multiple client-scoped commands - #758

Merged
1jehuang merged 1 commit into
masterfrom
fix/herdr-client-hooks
Aug 6, 2026
Merged

feat(hooks): support multiple client-scoped commands#758
1jehuang merged 1 commit into
masterfrom
fix/herdr-client-hooks

Conversation

@1jehuang

@1jehuang 1jehuang commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • accept either a string or an array for Jcode lifecycle hooks while preserving string compatibility
  • execute each configured hook directly and independently
  • propagate the initiating client's terminal environment into hook processes, including shared-server sessions
  • clear stale terminal environment state when no client context exists

This enables Herdr to append its lifecycle observer without wrapping or replacing an existing user hook. It also lets multiple Jcode clients sharing one server report the correct pane-local identity.

Closes #759.

Validation

  • focused Jcode hook suite: 11 passed
  • concurrent two-client shared-server environment isolation test passed
  • direct multiple-hook execution test passed
  • cargo check -p jcode-app-core passed
  • validated live with two Jcode panes in Herdr on one shared socket, each mapped to a distinct native session ID

Downstream

Required by herdrdev/herdr#2248 for native lifecycle hook composition and correct multi-pane routing.

@1jehuang
1jehuang force-pushed the fix/herdr-client-hooks branch from 577053c to 3c57514 Compare August 3, 2026 23:19
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds native support for multiple lifecycle hook commands and client-scoped terminal identity. The main changes are:

  • Hook config now accepts either a single command string or an ordered command array.
  • Env overrides can disable hooks, preserve legacy string behavior, or provide multiple commands.
  • Observer hooks and pre_tool gates now execute each configured command independently.
  • Client terminal environment snapshots are applied to hook processes during shared-server sessions.

Confidence Score: 5/5

Safe to merge with low risk.

The changes preserve legacy hook behavior, add ordered multi-command execution, and include focused tests for config parsing and hook execution.

Files Needing Attention: No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for the posted P1 finding and linked it to the corresponding review comment.
  • T-Rex ran cargo test -p jcode-app-core client_lifecycle from /home/user/repo and captured the full log.
  • Two tests in server::client_lifecycle::tests failed: cancel_without_local_task_still_signals_session_control and deferred_cancel_reset_does_not_erase_newer_cancel.
  • A log artifact containing the full test run was uploaded to support validation of the failing tests.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
crates/jcode-app-core/src/server/client_lifecycle.rs Propagates the active client terminal environment through session creation/resume, message processing, clear-session, and cleanup hook execution.
crates/jcode-base/src/hooks.rs Adds task-local client terminal env propagation and executes every configured observer/pre-tool hook independently in declaration order.
crates/jcode-config-types/src/lib.rs Implements backward-compatible hook config deserialization/serialization for either a string or array of command strings.
crates/jcode-terminal-launch/src/lib.rs Adds helper to replace inherited terminal-identifying environment variables with a client-authoritative snapshot and aliases.
crates/jcode-base/src/config/env_overrides.rs Extends lifecycle hook env overrides to accept empty disables, legacy strings, or TOML-style arrays of command strings.
crates/jcode-base/src/config_tests.rs Adds config tests for hook command arrays, legacy first-command compatibility, serialization round trips, and env array overrides.
crates/jcode-app-core/src/server/client_lifecycle_tests.rs Updates lifecycle tests for the new terminal environment parameter on message processing helpers.
crates/jcode-base/src/terminal_launch.rs Re-exports terminal environment application support from the terminal launch crate.

Sequence Diagram

sequenceDiagram
participant Client
participant Server as handle_client
participant Hooks as hooks task-local
participant Config as HooksConfig
participant Proc as Hook processes

Client->>Server: Subscribe(terminal_env)
Server->>Server: store active_terminal_env
Server->>Hooks: with_client_terminal_env(active_terminal_env)
Server->>Config: hook_commands(event)
Config-->>Server: command list
loop each configured command
    Server->>Proc: build process with client terminal env + hook env
    alt observer hook
        Server->>Proc: spawn detached
    else pre_tool gate
        Server->>Proc: wait for exit status
        Proc-->>Server: allow/block/other
    end
end
Loading

Comments Outside Diff (1)

  1. General comment

    P1 Focused client lifecycle Rust test suite fails

    • Bug
      • cargo test -p jcode-app-core client_lifecycle fails with 2 failing tests out of 19 selected tests. Both failures assert that stop_signal.is_set() should be true but it is not.
    • Cause
      • The client lifecycle cancel/session-control behavior under test is not setting the stop signal in the failing scenarios: cancel_without_local_task_still_signals_session_control at crates/jcode-app-core/src/server/client_lifecycle_tests.rs:323 and deferred_cancel_reset_does_not_erase_newer_cancel at line 387.
    • Fix
      • Investigate the cancel/session-control signal path in crates/jcode-app-core/src/server/client_lifecycle.rs and restore the expected behavior so cancellation without a local task and deferred cancel reset handling both leave the relevant stop signal set as the tests expect.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(hooks): support multiple client-sco..." | Re-trigger Greptile

@1jehuang

1jehuang commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

CI note: the remaining failing all-target/build jobs reproduce on the unchanged base commit 156ae4092.

Both fail in the pre-existing CLI confidence migration (src/cli/commands/menubar.rs and src/cli/commands_tests.rs). This PR changes only eight hook/config/lifecycle files and is reported mergeable by GitHub. Its formatting, linked-issue, PowerShell, installer, TypeScript SDK, release automation, and Windows cross-target checks pass.

The integration-specific local suite and live two-pane Herdr validation are documented in the PR body.

@factnest365-ops

Copy link
Copy Markdown

Independent verification of this PR (2026-08-04), run against a fresh clone on macOS aarch64 with cargo 1.96.0.

Verdict: no PR-introduced test failures. Every failing test in the crates this PR touches fails identically on the base commit (156ae4092, v0.67.0).

Test matrix (head 3c5751474 vs base 156ae4092):

Crate / suite Head Base
jcode-app-core client_lifecycle (19 tests) 17 pass, 2 fail 17 pass, 2 fail — identical tests, identical lines (323 / 387), identical stop_signal.is_set() assertion
jcode-base hooks 11/11 pass 8/8 pass — the PR adds 3 new hook tests, all pass
jcode-config-types (14 tests) 14/14 pass 14/14 pass
jcode-terminal-launch (22 tests) 19 pass, 3 fail 19 pass, 3 fail — identical 3 tests

The two failures flagged by automated review (cancel_without_local_task_still_signals_session_control, deferred_cancel_reset_does_not_erase_newer_cancel) are pre-existing on master, not introduced here. The three terminal-launch failures are also pre-existing and environment-sensitive (ghostty detection resolves to the host terminal; the two PoisonErrors are a cascade from the first panic on a shared lock).

Separate note for maintainers: the remaining red CI (Build & Test + Quality Guardrails on all three OSes) comes from a pre-existing src/cli/commands/menubar.rs / src/cli/commands_tests.rs compile mismatch that reproduces on the base commit too. It is unrelated to this PR's eight files. Once that is fixed on master, this PR should show green.

This PR is merge-ready from a test standpoint; the pre-existing failures should be tracked separately.

@factnest365-ops

Copy link
Copy Markdown

Addendum — root causes of the 5 pre-existing test failures (follow-up to the verification comment above; same 2026-08-04 run, head 3c5751474).

The two jcode-app-core failures are a stale test contract, not a runtime cancel bug:

  • Both tests build a bare SessionControlHandle::cancel_only with an empty turn_cancel_registry and call cancel_processing_message with task: None.
  • Since commit 9ee29b66 ("fix(interrupt): make an idle cancel a true no-op instead of arming the next turn"), that path deliberately does not arm the stop signal (has_active_turn false → IDLE_NOOP, client_lifecycle.rs:3073) — arming it would only kill the next turn during the 500ms deferred-reset window.
  • The failing assertions (lines 323/387) date from the app-core crate extraction (4dd91a9c, 2026-05-29) and predate that fix.
  • Fix (15 min, separate PR): register an active turn so the tests exercise the "cancel a turn owned elsewhere" path, or assert the noop contract — signal NOT set, Interrupted + Done events still emitted.

The three jcode-terminal-launch failures are environmental + cascade:

  • detected_resume_terminal_recognizes_ghostty_env panics at lib.rs:906 with left: Some("herdr"), right: Some("ghostty") — this host runs inside herdr, and herdr context is preferred over outer-emulator detection by design. Test assumes a non-herdr host.
  • The panic happens while holding the shared ENV_LOCK: Mutex<()> (lib.rs:825), poisoning it; the other two tests then fail at their .lock().unwrap() (lines 875/989) with PoisonError. Both pass in isolation.

None of the five touches this PR's eight files.

@factnest365-ops

Copy link
Copy Markdown

Ready-to-merge fix for the master CI break (issue #768) — a one-command PR request.

The menubar compile fix is complete, verified, and pushed to my fork. It's currently blocked from PR creation only because my account (factnest365-ops) is pull-only on 1jehuang/jcode — GitHub returns FORBIDDEN on CreatePullRequest. Requesting the PR be opened from a write-capable account.

Branch: factnest365-ops:fix/menubar-ci (commit 93c5cc9)
Baseline: 156ae4092 (v0.67.0) — pre-existing compile break, exactly the 7 errors documented in #768
Verification: cargo check --all-targets passes with the fix

One command to open it (run as any maintainer):

gh pr create --repo 1jehuang/jcode --base master --head factnest365-ops:fix/menubar-ci \
  --title "fix(cli): correct menubar command type mismatches on master" \
  --body "Fixes the pre-existing master compile break (#768). Replaces legacy ConfidenceState numeric scores with the current enum construction in menubar.rs and commands_tests.rs. cargo check --all-targets verified. Independent of PR #758; unblocks its CI."

This unblocks PR #758's red Build & Test and lets the jcode-herdr integration ship.

@factnest365-ops

Copy link
Copy Markdown

Done on our side. Independent verification (fresh clone, macOS aarch64, cargo 1.96.0) confirms this PR introduces zero new test failures — every failure in the touched crates reproduces identically on the base commit (v0.67.0). Ready for merge whenever you are. Note: the separate pre-existing master compile break (#768) has a verified fix ready at factnest365-ops:fix/menubar-ci (one-command PR open posted above) that will turn this PR's CI green once landed.

@1jehuang
1jehuang merged commit 0827a9d into master Aug 6, 2026
8 of 12 checks passed
1jehuang added a commit that referenced this pull request Aug 6, 2026
This reverts commit 0827a9d, reversing
changes made to cebff22.
yjuyjuy added a commit to yjuyjuy/jcode that referenced this pull request Aug 15, 2026
#24)

* Revert "Merge PR 1jehuang#758"

This reverts commit 0827a9d, reversing
changes made to cebff22.

* fix: resolve merged confidence fixture types

* fix(provider): filter images for text-only requests

* fix(tui): replay history after explicit session resume

* feat(acp): surface model/effort selectors and token usage over ACP

ACP clients (Zed's Agent Panel etc.) previously saw none of jcode's
model switching, reasoning effort, or token usage even though the TUI
supports all three (issue 1jehuang#765).

- session/new and session/load responses now include configOptions:
  a model selector (category: model) built from the daemon's history
  snapshot, plus a reasoning-effort selector (category: thought_level)
  from the shared provider-core effort ladder (swarm sentinels are
  filtered out since they are TUI-only).
- session/set_config_option applies model or effort changes via the
  daemon's set_model / set_reasoning_effort requests and re-broadcasts
  a config_option_update session update on success.
- Token usage events from the daemon now map to usage_update session
  updates using the shared effective-context heuristic and the model's
  context limit.
- Mid-prompt ModelChanged events (provider failover) also refresh the
  advertised config options.

Closes 1jehuang#765

* fix(acp): include configOptions in session/set_config_option response

The ACP schema marks configOptions as required on
SetSessionConfigOptionResponse; validating live output against the
official v1 schema caught the empty-object response. Also keeps the
config_option_update broadcast for other attached clients.

* feat(macos): add turn notification broker

* fix integration discovery response compatibility

* Replace subscription UX with metered hosted billing

* Fix remote todo ownership gate session lookup

* fix(tui): avoid duplicated discovery selection label

* chore(release): v0.69.0

* desktop2: advertise model picker shortcut

* feat(hooks): restore multiple client-scoped commands

* Make todo follow-ups neutral and targeted

* docs(prompt): add batch tool call example

* docs(tools): move batch example to tool description

* feat(todo): gate feedback loop relevance and coverage

* Nudge sequential tool use toward batch

* Test batch nudge injection conditions

* Improve terminal launch detection and spawning

* feat(desktop): move model picker into transcript

* fix(agent): hide synthetic recovery prompts

* chore(release): v0.70.0

* style(desktop): format inline model picker

* chore(release): v0.70.1

* fix(desktop2): gate builds on runtime connection

* fix: update Claude memory sidecar model (fixes 1jehuang#798)

* fix: wait for daemon registration during SDK close (fixes 1jehuang#818)

* style: satisfy current clippy guardrail

* style: remove obsolete auth token helper

* test: make strict schema fixture fully typed

* style: satisfy Rust 1.97 app-core lints

* Improve todo quality gate rendering

* feat(todo): distinguish synthetic validation

* fix(memory): distinguish permanent sidecar failures

* feat(providers): support Meta Muse and DeepSeek passback

* docs(providers): add Meta Model API setup

* feat(todo): require requirement traceability

* fix: prevent empty transcript checkpoints (fixes 1jehuang#814)

* log cargo action durations

* fix(discovery): restore explicit select guidance

* test(todo): cover traceability in TUI fixtures

* route bash cargo commands through timing logger

* fix: fall back when spawn hooks reject launch (fixes 1jehuang#792)

* fix(ci): satisfy TUI quality guardrails

* fix(schedule): keep scheduled turns out of user prompt history

* test(todo): align TUI gate fixtures

* test(todo): expect generic completion follow-up wording

* test(todo): assert compact batched card contract

* test(todo): cover compact narrow card rendering

* chore(ci): refresh quality ratchets

* test(todo): assert hidden passing card gates

* Offer Jcode subscription during onboarding

* fix(discovery): validate selection receipts and benchmark identity

* fix(ci): compile macOS notification broker

* Open pricing from onboarding subscription choice

* fix(discovery): enforce provenance report contract

* style: apply current rustfmt

* fix(benchmark): identify dirty self-dev binaries

* Expose full GPT-5.6 OpenAI model family

* chore(ci): advance quality ratchets

* Advertise hosted model discount in onboarding

* test(discovery): verify off-catalog select receipt

* Include GPT-5.6 Terra in OpenAI fallback catalog

* test(tui): align fixtures with semantic gates

* chore(ci): sync TUI fixture ratchets

* Default onboarding to Jcode subscription

* test(security): avoid secret-shaped source literal

* chore(ci): sync onboarding test ratchet

* test(tui): align onboarding fixtures with subscription default

* chore(release): prepare v0.71.0

* fix(provider): pin subscription picker routes

* Correct subscription inference allowance semantics

* fix(telemetry): update paid D1 storage guardrail

* fix(tui): support cmd-enter queue shortcut on macOS

* Reframe tool discovery as seamless integrations

* Guard integration discovery framing

* fix: unblock SDK 1.2.0 runtime refresh (1jehuang#842)

* fix(desktop2): gate builds on runtime connection

* fix: update Claude memory sidecar model (fixes 1jehuang#798)

* fix: wait for daemon registration during SDK close (fixes 1jehuang#818)

* style: satisfy current clippy guardrail

* style: remove obsolete auth token helper

* test: make strict schema fixture fully typed

* style: satisfy Rust 1.97 app-core lints

* Improve todo quality gate rendering

* feat(todo): distinguish synthetic validation

* fix(memory): distinguish permanent sidecar failures

* feat(providers): support Meta Muse and DeepSeek passback

* docs(providers): add Meta Model API setup

* feat(todo): require requirement traceability

* fix: prevent empty transcript checkpoints (fixes 1jehuang#814)

* log cargo action durations

* fix(discovery): restore explicit select guidance

* test(todo): cover traceability in TUI fixtures

* route bash cargo commands through timing logger

* fix: fall back when spawn hooks reject launch (fixes 1jehuang#792)

* fix(ci): satisfy TUI quality guardrails

* fix(schedule): keep scheduled turns out of user prompt history

* test(todo): align TUI gate fixtures

* test(todo): expect generic completion follow-up wording

* test(todo): assert compact batched card contract

* test(todo): cover compact narrow card rendering

* chore(ci): refresh quality ratchets

* test(todo): assert hidden passing card gates

* Offer Jcode subscription during onboarding

* fix(discovery): validate selection receipts and benchmark identity

* fix(ci): compile macOS notification broker

* Open pricing from onboarding subscription choice

* fix(discovery): enforce provenance report contract

* style: apply current rustfmt

* fix(benchmark): identify dirty self-dev binaries

* Expose full GPT-5.6 OpenAI model family

* chore(ci): advance quality ratchets

* Advertise hosted model discount in onboarding

* test(discovery): verify off-catalog select receipt

* Include GPT-5.6 Terra in OpenAI fallback catalog

* test(tui): align fixtures with semantic gates

* chore(ci): sync TUI fixture ratchets

* Default onboarding to Jcode subscription

* test(security): avoid secret-shaped source literal

* chore(ci): sync onboarding test ratchet

* test(tui): align onboarding fixtures with subscription default

* chore(release): prepare v0.71.0

* fix(provider): pin subscription picker routes

* Correct subscription inference allowance semantics

* fix(telemetry): update paid D1 storage guardrail

* fix(tui): support cmd-enter queue shortcut on macOS

* Reframe tool discovery as seamless integrations

* Guard integration discovery framing

* fix: tolerate Windows short temp paths (fixes 1jehuang#838)

* fix: meter compatible remote providers (fixes 1jehuang#831)

* fix: route slash models through compatible profiles (fixes 1jehuang#840)

* fix: honor Ctrl-K in remote drafts (fixes 1jehuang#832)

* fix: exclude multiline tool errors from memory focus (fixes 1jehuang#824)

* fix: cancel pending rate-limit retries (fixes 1jehuang#826)

* Expose Fable 5 to hosted subscribers

* tui: place pinned todos below prompt preview

* Render server reload progress without card

* Make client updates unobtrusive during typing

* chore(sdk): prepare 1.2.0 runtime refresh

* fix: use platform c_char for tty lookup

* chore(release): prepare v0.71.1 (1jehuang#843)

* style: format reload message assertions

* chore(release): prepare v0.71.1

* fix: preserve Homebrew launcher arguments (fixes 1jehuang#852)

* fix: default custom model input to text only (fixes 1jehuang#847)

* fix: clarify missing swarm server errors (fixes 1jehuang#854)

* fix: normalize Copilot tool schemas (fixes 1jehuang#855)

* fix: preserve active catalog profile for model switches (fixes 1jehuang#849)

* fix: satisfy quality guardrails for connection rendering

* perf(tui): avoid full repaint on tab focus

* feat(desktop2): resize focused session panel

* Fix duplicated thinking text for OpenAI models

OpenAI Responses streams the reasoning summary twice: live via
response.reasoning_summary_text.delta, then again inside the
reasoning item on response.output_item.done. We replayed the
item.done summary as ThinkingStart/Delta/End, so the TUI rendered
the full thinking block a second time.

Track saw_thinking_delta per stream and skip the item.done summary
replay when live deltas were already streamed. The OpenAIReasoning
event (encrypted content for history/replay) is still emitted.

* test(desktop2): cover panel width across focus changes

* chore(release): prepare v0.72.0

* chore(release): prepare v0.73.0

* Add conversational guidance to plan command

* perf(reload): minimize terminal interaction gap

* Open repository markdown links in side panel

* docs: add Trendshift achievement badge

* docs: fix README tagline typo

* fix: refresh installed binary git metadata (fixes 1jehuang#799)

* fix: avoid confirming unmatched model favorite (fixes 1jehuang#807)

* fix: scope DeepSeek reasoning passback (fixes 1jehuang#815)

* fix: distinguish native OpenRouter credentials (fixes 1jehuang#795)

* fix: reset swarm plan state on clear (fixes 1jehuang#816)

* chore: satisfy workspace rustfmt

* chore: keep injected link opener test-only

* test: align provider matrix and size baseline

* test: refresh stale test-size baseline

* test: refresh stale swallowed-error baseline

* test: repair stale TUI expectations

* fix(command-risk): avoid redirect operand false positives

* fix(tui): keep pinned todos out of transcript

* test: keep catalog regression within size budget

* chore: satisfy workspace rustfmt

* fix(tui): prevent theme query replies entering composer

* test: refresh integrated code-size baseline

* desktop2: model and profile session transitions

* sdk: remove runtime readiness polling delay

* fix(tui): open markdown links from rendered labels

* desktop2: create new sessions on fresh connections

* fix(ollama): trust cloud model context metadata

* fix(antigravity): reject imitated tool calls

* fix(command-risk): parse nested shell constructs safely

* refine(command-risk): allow concrete outside paths

* fix(openrouter): preserve explicit provider pins

* fix(desktop2): unblock live new-session transitions

* feat(tui): pin todos by default

* feat(tui): filter sessions by current directory

* fix(tui): suspend terminal while editing config

* fix(tui): deliver staged prompts after headed forks

* fix(swarm): isolate plans by root session

* feat(acp): expose model controls and slash commands

* chore(command-risk): apply rustfmt

* feat(tools): bundle searchable jcode documentation

* refactor(tools): hide selfdev outside development mode

* fix(acp): allow configured MCP server tools

* test(swarm): cover session-scoped identities

* perf(cargo): serialize local compile actions

* test(tools): verify regular-session visibility

* test(tui): cover interactive editor handoff

* fix(tui): avoid duplicate pinned todos

* chore(release): prepare v0.74.0

* test(tui): cover editor terminal handoff

* fix(acp): enforce dynamic MCP tool policy

* ci(windows): verify installer against artifact version

* fix(tui): accept meta new-session shortcut

* fix(tui): normalize shifted semicolon bindings

* fix(provider): preserve explicit route pins

* fix(desktop): reconnect cleanly after daemon reloads

* feat(desktop): add project file explorer

* style(tui): apply rustfmt

* desktop2: show activity before first event

* desktop2: capture immediate thinking state

* fix(desktop2): keep windows visible during reload

* fix(desktop2): isolate session polling from live requests

* desktop2: add vim resume navigation chords

* feat(desktop2): add local help overlay

* desktop2: bind manual reload to ctrl-shift-r

* desktop2: hot-reload app code in stable window host

* feat(desktop2): create sessions as spatial panels

* fix(desktop2): close gaps between diff rows

* feat(desktop2): show full reasoning by default

* refactor(desktop2): report skipped surface frames

* style(desktop2): format delivery assertions

* chore(release): prepare v0.75.0

* fix: restore swarm membership after clear (fixes 1jehuang#874)

* fix: propagate active skills to remote sessions (fixes 1jehuang#873)

* fix: isolate pinned todos config-off test (fixes 1jehuang#877)

* fix: report alternate keys for shifted symbols (fixes 1jehuang#870)

* fix: avoid duplicate Codex quota windows (fixes 1jehuang#869)

* style: format quota regression test

* style: apply workspace formatting

* style: apply workspace formatting

* style: apply workspace formatting

* ci: validate integrated branch

* ci: validate integrated branch

* desktop2: show provider request lifecycle status

* sdk: expose connection phase events in TypeScript

* test: cover desktop connection phase labels

* feat: add Grok Build ACP provider

* fix(todo): normalize completed statuses for auto-poke

* chore(release): prepare v0.75.1

* fix(todo): reject unknown status values

* chore(release): prepare v0.75.2

* fix: recognize stream_read_error as transient transport error (fixes 1jehuang#885)

OpenAI-compatible endpoints may emit structured stream failures with
type: upstream_error and code: stream_read_error. These should be
treated as transient stream/transport failures, entering the bounded
retry loop with rollback of partial output.

Added stream_read_error to the shared is_transient_transport_error
classifier and added regression test covering the structured error
payload as suggested in the issue.

* fix: tolerate ACP mcpServers during session creation (fixes 1jehuang#887)

* fix: generate unique fallback tool call IDs (fixes 1jehuang#884)

* fix: recognize stream_read_error as transient transport error (fixes 1jehuang#885)

OpenAI-compatible endpoints may emit structured stream failures with
type: upstream_error and code: stream_read_error. These should be
treated as transient stream/transport failures, entering the bounded
retry loop with rollback of partial output.

Added stream_read_error to the shared is_transient_transport_error
classifier and added regression test covering the structured error
payload as suggested in the issue.

* desktop2: restore Super session overview

* desktop2: add compositor-safe overview shortcut

* desktop2: make session strip clickable

* chore(release): prepare v0.75.3

* fix(ci): allow release workflow to close shipped issues

* fix: size dev builds from macOS memory (fixes 1jehuang#891)

* fix: report ACP turn token usage (fixes 1jehuang#906)

* fix: isolate telemetry tests from user config (fixes 1jehuang#892)

* fix: null background command stdin (fixes 1jehuang#903)

* fix: honor telemetry opt-out before install event (fixes 1jehuang#893)

* test: cover structured stream_read_error extraction

* style: format integrated pull requests

* chore(release): prepare v0.75.4

* fix(acp): include active skill in prompt requests

* chore(release): prepare v0.75.5

* feat(config): allow disabling startup update checks

* Refresh swarm prompt for new agents

* Clarify Z.AI Coding Plan login

* Test Z.AI Coding Plan metadata

* fix(auth): provision Grok Build through jcode

* fix(grok): support current managed ACP backend

* fix(zai): support effort and text-only image safety

* fix(auth): distinguish Grok backend from login

* fix(provider): make transient retries resilient and configurable

* fix(auth): clarify Grok login readiness

* feat(auth): run Grok login inside TUI

* test(auth): cover TUI Grok login routing

* fix(auth): refresh Grok models after TUI login

* feat: add opt-in transcript telemetry pipeline

* feat: redact secrets from transcript telemetry

* docs: add transcript deletion runbook

* docs: refresh README social proof and launch video

* docs: refresh README social proof and launch video

* Add headless onboarding screenshot generator

* fix: repair self-dev build promotion paths (fixes 1jehuang#914, fixes 1jehuang#917)

* fix: expand repeated paste placeholders (fixes 1jehuang#916)

* fix: invalidate animation seed after buffer swap (fixes 1jehuang#913)

* fix: deduplicate prompt files and clip skills (fixes 1jehuang#910, fixes 1jehuang#911)

* fix: preserve orphaned OpenRouter tool outputs (fixes 1jehuang#908)

* Render every onboarding graph state as a headless screenshot artifact

The artifact generator now covers all resting states in onboarding_graph.rs:
welcome-card states render via the onboarding layout, and picker-overlay and
session states (start choice, suggestions, accepted review turn) render the
full app frame via ui::draw. Also update the telemetry golden assertions to
the copy introduced by the transcript-telemetry pipeline.

* Make the review-turn onboarding artifact deterministic

Two sources of run-to-run drift leaked into the full-frame render: the
Updates box (unseen changelog entries from the generating machine) and the
randomly drawn session mascot name. Pin both. Two consecutive generator
runs now produce byte-identical SVGs for all 12 states.

* style: apply rustfmt to recent changes

* Pin the git widget in the review-turn onboarding artifact

The recheck found the render still captured the generating repo's live
ahead/behind/dirty counts, which change with every commit. Add a test-only
git-info cache seed and pin the widget to a clean fixture branch. The
version label is compile-time build meta and is left as is.

* feat(providers): support Anthropic-compatible profiles

* Fix merge-surfaced build/clippy issues and refresh ratchet baselines

- usage/accessors.rs: remove the duplicate fetch_usage_for_access_token the
  merge kept from both sides, and pass the fork's l2_label argument.
- provider-anthropic-runtime: move the account_pin field into the struct
  initializer (the union misplaced it into an adjacent match arm), and add a
  too_many_arguments expect plus a let-else -> ? rewrite for the two upstream
  lints the fork's -D warnings gate surfaces.
- server/client_lifecycle.rs: drop the merge-introduced duplicate
  active_terminal_env assignment (use-after-move).
- tests/e2e/test_support: the e2e harness uses the protocol Request, so its
  Message needs both active_skill and submission_nonce.
- harness-api-server/Cargo.toml: reset the git-duplicated cfg(unix) block to
  upstream's single copy so the workspace manifest loads.
- Cargo.lock regenerated via cargo update --workspace (0 net dep changes).
- scripts/*_budget.json refreshed to the merged tree.

Validated: cargo build --workspace, cargo clippy --all-targets --all-features
-D warnings, cargo fmt --all --check, and every ratchet all pass;
jcode-protocol/jcode-config-types tests pass. The only jcode-base test
failures are pre-existing upstream (6 vscdb tests need the sqlite3 CLI absent
here; grok-build lifecycle normalization is an upstream-only gap in
unconflicted files).

* Add active_skill to the nonce-dedup test's ProcessingMessage

The merged ProcessingMessage struct carries both active_skill (upstream)
and submission_nonce (fork). The fork-only submission-nonce dedup test
constructed it with submission_nonce only, breaking the app-core lib test
compile (the CI retention-readiness cohort that builds -p jcode-app-core
--lib). Add active_skill: None.

* Refresh test-size baseline after the ProcessingMessage active_skill line

* Add submission_nonce to issue_496 rate-limit test constructor

The upstream sync surfaced another PendingRemoteMessage constructor missing the
fork's submission_nonce field, in a Linux-only TUI test that the ubuntu Build &
Test cohort compiles. Add submission_nonce: None to match every other
constructor, fixing the E0063 that failed the ubuntu job.

* Assemble AWS key redaction fixture at runtime to pass secret scanner

The upstream sync brought in a redaction test whose fixture embeds a literal
AKIA-prefixed access key, plus the security preflight (scripts/security_preflight.sh)
whose secret scan rejects any tracked line matching AKIA[0-9A-Z]{16}. The two
collided and failed the ubuntu Security preflight step (upstream never runs that
step on master pushes, so it only surfaces on a PR).

Build the fixture from two string halves at runtime so no single tracked source
line matches the scanner, while redact_secrets() still receives the full key and
the assertions are unchanged.

* Refresh code-size baseline after merging #25/#26 into sync branch

---------

Co-authored-by: jeremy <94247773+1jehuang@users.noreply.github.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.

Support composable client-scoped lifecycle hooks

2 participants