Skip to content

chore(release): prepare v4.0.0 stability release - #46

Merged
muggle-stack merged 11 commits into
masterfrom
dev
Sep 22, 2026
Merged

muggle-stack merged 11 commits into
masterfrom
dev

Conversation

@muggle-stack

@muggle-stack muggle-stack commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

Claude background task returns could keep a finished session running, move replies into the wrong timeline, or hide consumed queued prompts. This PR brings the remaining session stability fixes onto master and prepares product v4.0.0, using wire protocol v72.

Changes

  • Keep newly accepted Claude queries separate from buffered autonomous responses until native input is consumed. Preserve pre-echo ownership through service reconnects so an older background Result cannot finish the new question.
  • Match native UTF-16 project bucket names for long paths containing non-BMP characters. Accept legacy hash suffixes only from explicit native root messages so a later cwd with the same prefix cannot replace the original directory.
  • Recover Claude session cwd from full-size accepted image records, allowing the base64-expanded attachment set and preceding queue copies while keeping reads bounded. Regression cases cover 3 MiB and 6 MiB images, two 4 MiB images, and eight 1 MiB images in both account modes.
  • Drain injected Claude callbacks through the real terminal boundary. Keep running children independent of the main response and recognize native continuations even without an internal user echo.
  • Preserve reply ownership and consumed queued prompts across live/history recovery; recover cwd when a leading image exceeds the SDK catalog window; deduplicate manual compaction by its native receipt.
  • Let iOS touch and keyboard interactions retain scroll ownership, and suppress duplicate keyboard paste deliveries without blocking deliberate repeated pastes. Deduplicate successful attachments even when other pasted items fail, across main chat, side chat and new-session composers.
  • Align backend, Web, lockfile, build manifest and bootstrap versions at 4.0.0. Add bilingual release highlights and upgrade requirements; release creation uses the versioned notes file when present.

The release notes cover accumulated changes since v3.0.0. Most of those features are already on master; this PR adds the remaining session stability fixes and the release metadata. DSH, Electron and managed-browser/MCP computer-use experiments remain outside this release.

Validation

  • Full Python suite: 4,808 passed, 4 expected skips, with 14 SDK permission warnings. Skips cover two Linux-only checks, the optional live-model E2E probe, and an unavailable optional fzf executable.
  • Node 24: Web production build, reliability tests and lint passed. Clipboard regressions cover mixed valid/invalid attachments, fully failed retries, explicit repeated pastes and replay expiry.
  • Ruff 0.15.13, deployment shell syntax/ShellCheck, protocol bundle validation, and git diff --check passed.
  • Release publishing step passed ShellCheck and four offline mocked-gh scenarios: curated notes, generated-note fallback, an existing draft, and refusal to overwrite a published release.
  • The full required local gate ran against the updated committed tree. No live-model calls, real-device iOS acceptance or deployment was performed for this PR.

Release sequence

  1. Review this PR and require GitHub CI to pass before merging into master.
  2. Verify the merged revision, then push the v4.0.0 tag when ready to publish. The existing release workflow re-runs source CI and builds six Relay/Wrapper platform archives before publishing checksums and attestations.
  3. Upgrade Relay, Wrapper, Web and TUI together. Preserve private state and follow the independent Claude service drain procedure when upgrading that service.

This PR does not create a release tag, publish artifacts, merge itself, or change a running deployment.

- Settle merged task notifications at native terminal boundaries without blocking new prompts.
- Recover original working directories and consumed human prompts from native transcripts.
- Preserve continuation order and omit empty process disclosures.
- Match live and historical compactions by native receipts and completed boundary identities.
- Heal cached duplicates while retaining canonical details and distinct executions.
- Yield streamed scroll corrections to touch and scrollbar ownership, including keyboard resize.
- Suppress immediate native paste replays without blocking intentional repeat pastes.
- Cover conversation, new-chat, and side-chat composers with regression tests.
- Merge session fixes for Claude background continuations, history and compaction.
- Include iOS scrolling and keyboard paste corrections.
- Keep browser, Electron and MCP computer-use feature development outside dev.
- Align backend, Web and bootstrap versions while retaining wire protocol v72.
- Document release scope, stability fixes and coordinated upgrade requirements.
- Publish versioned bilingual release notes when the release workflow creates a draft.
@muggle-stack
muggle-stack marked this pull request as ready for review September 21, 2026 09:21

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6db1ebd5f1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +203 to +204
limit = min(_CWD_RECORD_BYTES, remaining)
line = stream.readline(limit)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Read allowed image-sized records when recovering cwd

Raise the per-record limit or extract cwd without discarding oversized rows. An allowed image above roughly 3 MiB expands past this 4 MiB JSONL cap after base64 encoding (MAX_SINGLE_ATTACHMENT_BYTES is 6 MiB), so both the leading queue record and the actual user record containing cwd can be skipped. If the session has no later message in the original directory—or later messages reflect a changed directory—recover_session_cwd() returns no cwd and the otherwise valid session is rejected on resume.

AGENTS.md reference: AGENTS.md:L66-L68

Useful? React with 👍 / 👎.

- Size bounded transcript reads for expanded attachments and preceding queue copies.
- Cover accepted image size and count limits across both account catalog paths.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05972c766d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread cc_remote/wrapper/claude_catalog.py Outdated
cwd = row.get("cwd")
if (isinstance(cwd, str) and os.path.isabs(cwd)
and "\x00" not in cwd
and _sanitize_path(cwd) == source.parent.name):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Accept hashed project buckets when recovering cwd

Handle cwd values whose sanitized form exceeds MAX_SANITIZED_LENGTH. Claude stores these transcripts in a prefix-plus-hash project directory (the same case _directory_candidates() handles via startswith(prefix)), so this exact equality can never succeed for a long cwd. If a leading image also causes the SDK lite read to omit cwd, recover_session_cwd() leaves the cwd empty and the otherwise resumable session is rejected. Validate the long-path bucket form while still returning the full cwd recorded in the transcript.

AGENTS.md reference: AGENTS.md:L66-L68

Useful? React with 👍 / 👎.

- Match native UTF-16 project keys alongside the Python SDK catalog keys.
- Recover legacy hashes only from explicit native roots to reject later cwd collisions.
- Cover native and legacy long paths, malformed buckets and source preservation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a91c6999d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread cc_remote/wrapper/sdk.py Outdated
)
if parse_raw and isinstance(data, dict):
data = self._steers.annotate(data)
data = self._steers.annotate(data, managed_active=self._turn_active)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep pre-echo activity out of the pending human route

When a browser query sets _turn_active before the pump consumes an already-buffered autonomous assistant/message_start whose internal user echo was omitted, this passes managed_active=True, so the new _main_activity fallback refuses to establish a background boundary. Although that assistant is routed as background while the human echo is pending, its following unattributed Result then takes the self._turn_active managed branch and terminates the newly submitted browser turn before its exact human echo; the accepted prompt's later output is consequently attached to the wrong lifecycle. The persistent service makes the equivalent assumption in claude_service/server.py:201-203; background detection should be gated by an observed managed human input, not merely query submission.

AGENTS.md reference: AGENTS.md:L60-L65

Useful? React with 👍 / 👎.

- Classify autonomous activity by consumed native input instead of query submission.
- Keep pre-echo background terminals and replay ownership separate from the accepted human turn.
- Cover pending queries, steering, service recovery and command completion without model calls.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 15d171f048

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread web/src/clipboard-paste-guard.ts Outdated
Comment on lines +101 to +102
if (!this.recent(receipt) || batch.errors.length
|| (!batch.images.length && !batch.files.length)) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Deduplicate successful files in partial imports

When an iOS clipboard import contains both a valid attachment and an invalid or oversized one, pickFiles returns the successfully decoded attachment together with a nonempty errors array. This branch accepts every replay without recording or comparing those successful bytes, so a duplicate paste delivery that arrives after the first import completes but within the replay window appends the valid attachment twice. Keep the successful subset eligible for replay deduplication even when other items report errors; a later explicit paste gesture already clears the receipt.

Useful? React with 👍 / 👎.

- Retain successful attachment receipts when other clipboard items fail.
- Apply replay checks to main, side-chat and new-session composers.
- Cover partial imports, failed retries, deliberate repeats and replay expiry.
@TroyMitchell911

Copy link
Copy Markdown
Collaborator

LGTM. no P1. Thanks.

@muggle-stack
muggle-stack merged commit 539c4d4 into master Sep 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants