Skip to content

fix: integrate upstream checkpoint 0a0b6be96833 - #20

Merged
Nurozen merged 22 commits into
mainfrom
upstream/batch-0a0b6be96833-d22562
Sep 12, 2026
Merged

Nurozen merged 22 commits into
mainfrom
upstream/batch-0a0b6be96833-d22562

Conversation

@Nurozen

@Nurozen Nurozen commented Sep 12, 2026 •

Copy link
Copy Markdown
Owner

Problem

Lecturn was 19 upstream commits behind the accepted checkpoint ef4cc60. The missing range adds desktop browser cookie import, Codex async questions, Antigravity sign-in and subagent handling, a pairing-credential security fix, and several web composer/panel fixes.

Result

Merges upstream 0a0b6be ("fix(web): keep right panel controls clickable (pingdotgg#9517)") into Lecturn as a two-parent merge, preserving thread forking, Stave staging, Lecturn branding, and the fork's CI/release workflows. Current main (controller check-path tooling under .github/upstream-integration/) is merged in with no conflicts and no overlap with the batch.

Desktop browser cookie import (pingdotgg#7255, pingdotgg#7260, pingdotgg#7261, pingdotgg#9516): Settings > Integrations now offers "Add profile" as a menu (Blank profile / Import from) that imports cookies from Chrome, Edge, Brave, Vivaldi, Opera, Arc and Firefox into a preview browser profile. Profile rows gain a Default badge and a per-row menu (Set as default / Clear cookies and cache / Remove profile and data); the separate "Default browser profile" select is gone. New @napi-rs/keyring dependency, a Linux libsecret helper (native/browser-secret, built by apps/desktop/scripts/build-browser-secret.mjs, staged as lecturn-browser-secret), schema-validated IPC, and docs/user/browser-import.md. Linux desktop dev/pack now requires libsecret-1-dev and pkg-config; ci.yml and release.yml install them on the Linux legs only.

Codex async questions (pingdotgg#9512): user-input.requested activities in message mode can be answered after the turn ends. The decider rejects incomplete or duplicate replies, and the answer becomes a user message plus a new turn. Adds getUserInputActivity to ProjectionSnapshotQuery and docs/user/providers-codex.md.

Pairing credentials (pingdotgg#9523): pairing-link lists and access-stream read models no longer carry the raw credential; only the creation response does. Connections settings keeps created credentials in memory for sharing. Clients built before this change that require credential on AuthPairingLink will fail to decode pairing lists from a newer server.

Antigravity: sign-in URLs are accepted from stderr with a bounded, validated handler (pingdotgg#9425, pingdotgg#9514); slow runtime startup is tolerated (pingdotgg#9510); model choices refresh on config_option_update (pingdotgg#9511); managed runtime pinned to 1.1.1 (pingdotgg#9509); subagent calls and results show in the Agents panel and mobile work log (pingdotgg#9515).

Web: paste with nothing focused routes into the composer and expands it (pingdotgg#9498); a timeline text selection holds the resting composer open (pingdotgg#9499); closing the media preview returns focus to its opener (pingdotgg#9513); right-panel controls render inline in the tab strip (pingdotgg#9517). Server: thread subscription forks the live forwarder with startImmediately so no events drop between subscribe and replay (pingdotgg#9521).

Fork-only interplay fix: thread fork and open async questions

Thread fork copies every source activity through the fork turn with a fresh id but the same payload. With async questions, an open message-mode user-input.requested (which stays pending after its turn completes) would be duplicated into the child under the same requestId. The upstream decider mints the answer's activity id and message id from that request id alone (async-answer:<requestId>), so answering the question in both threads would re-parent the first answer's activity and reply message onto the second thread through the projection upserts. Upstream cannot hit this because request ids are thread-unique there.

assembleThreadFork now leaves open async questions with the source thread (same pending-question definition as the projector: a message-mode request with no later user-input.resolved in the copied range). Answered questions still copy as request/resolution pairs, so the fork rejects a second answer as already answered, just like the source. decider.ts stays identical to upstream. Covered by a new threadFork test (fails on the previous assembler) and documented in docs/internals/thread-forking.md and docs/user/forking-threads.md.

Conflict resolutions and deviations

  • 20 conflicted files resolved as unions: ProjectionSnapshotQuery interface and its test stubs (fork lifecycle queries + upstream getUserInputActivity), makeOrchestrationLayer(admission, databasePath?), Antigravity files (fork's earlier port of fix(antigravity): forward Google sign-in URLs from browser helper pingdotgg/t3code#9425 replaced by upstream's newer version with Lecturn identifiers), scripts/build-desktop-artifact.ts (Stave staging + browser-secret/keyring staging), desktop package.json/vite.config.ts, and docs.
  • server.test.ts layer chain split into two .pipe() calls to stay under the 20-overload limit; semantics unchanged.
  • pnpm-lock.yaml regenerated; the only delta is @napi-rs/keyring, alchemy patch unchanged.
  • .github/workflows/cursor-hygiene-webhook.yml deliberately not taken: it posts repository events to an upstream-controlled Cursor endpoint using secrets the fork does not have.
  • schema.gen.ts taken from upstream rather than regenerated, because the generator fetches the live openai/codex protocol and would pull a newer version than upstream pinned.
  • Branding sweep over all touched files (@lecturn/*, lecturn-browser-secret, LECTURN_ACP_FLOOD_STDERR, Lecturn.app path, doc prose).

Verification

Focused tests pass in server (608), web (151), desktop (98, 10 Linux-only skips), mobile (78), client-runtime, codex schema, contracts, and scripts (81, one pre-existing cross-architecture test excluded). Typechecks pass for server, web, desktop, mobile, contracts, shared, client-runtime, effect-codex-app-server and scripts. Lint, format check, git diff --cached --check, and pnpm install --frozen-lockfile pass. The controller's hermetic Python tests (40) pass on the merged tree.

UI evidence (isolated web stacks, fork base vs integrated)

Settings > Integrations > Browser profiles (seeded with "Work" and "Personal" profiles, "Work" as default; controls are disabled in the web build):

Before After
before after

Settings > Connections pairing rows after creating a link and reloading (before still offers "Copy code" from the list; after no longer exposes the credential):

Before After
before after

Paste into a resting composer with nothing focused (before: nothing happens; after: composer expands with the text):

Before After
before after

Right-panel tab strip with overflow at 1000px (web build; the desktop title-bar overlay case is not reproducible in web):

Before After
before after

Selection hold video (left fork base, right integrated): https://github.com/user-attachments/assets/1719829b-442f-43b0-bfdc-ae43f28121ae

Not exercised in a client: the browser import wizard and enabled profile menus (desktop-only bridge; covered by desktop unit tests and web logic tests), media-preview focus return, Antigravity sign-in and subagent flows, live Codex async questions, mobile changes, and the Linux libsecret helper build.

🤖 Generated with Claude Code

Integrates 19 upstream commits through 0a0b6be96833adae68b36540c00d347eda278736. Checkpoint = upstream commit 19 of 30, "fix(web): keep right panel controls clickable (pingdotgg#9517)". The range accepted..0a0b6be is a linear first-parent chain of 19 commits (all 30 candidates are single-parent, linear), and the cumulative diff excluding .repos is 110 files, 10036 insertions / 357 deletions (~10.4k lines), inside the 50-commit and 15000-line limits.

Why this cut and not later: through 19d8ab2 (20 commits) is 13937 lines, and through 343db2c (21) is 15373, so 19d8ab2 is the only other in-budget option. It is a 3.5k-line, 56-file cross-surface feature (Codex/Claude usage limits with a new Limits tab on web + mobile, new server settings, CLIProxyAPI sources) that edits fork-diverged files (ws.ts, server.ts, contracts/settings.ts, client-runtime server state) and whose immediate upstream follow-ups (pingdotgg#9534 redeem credits, pingdotgg#9584 dedupe accounts, pingdotgg#9599 move controls to settings, and regression fix pingdotgg#9784) all sit outside this batch. Cutting at 0a0b6be lets the next batch land 19d8ab2 together with 343db2c (settings reorg) and those usage follow-ups instead of splitting them. Cutting earlier (e.g. 3653cb2, 9 commits / ~8.1k lines) would waste budget and strand the codex async-questions feature (d76b24d) and the pairing-credential fix (9d28c21).

Coherence of the chunk: every multi-commit stack inside closes: (a) browser cookie import stack pingdotgg#7255→pingdotgg#7260→pingdotgg#7261 plus its review-fix pingdotgg#9516 (3653cb2) all included; (b) antigravity sign-in URL forwarding e01c153 plus its follow-up eb334ca (stderr URLs), model refresh, slow-startup, runtime 1.1.1 bump, and subagent display; (c) cursor-hygiene workflow add (44701ef) and trim (e3723e0) both included; (d) composer fixes (6382268, 522ebe6, c0ebc88) and 0a0b6be are small web-only fixes. Later upstream follow-ups (pingdotgg#9579 antigravity subagent batches, ~22 commits past the candidate window; pingdotgg#10667 macOS keyring for cookie import) are improvements, not fixes for a broken build, and are unreachable from this candidate list anyway.

Fork overlap / risk to plan for: (1) 498ab9c adds native/browser-secret/*.c and an apt-get libsecret step in ci.yml and release.yml. Both workflows are fork-owned: keep ours, port the "Install browser secret helper build libraries" step by hand (ci.yml typecheck/test jobs and release.yml Linux desktop build), keep ubuntu-24.04/macos-26 runners; review native/ for Lecturn identity. (2) scripts/build-desktop-artifact.ts is heavily fork-diverged (507/87) and gets +151 upstream lines across three commits; expect a manual union. (3) apps/desktop/package.json + pnpm-lock.yaml gain a new desktop dependency; regenerate the lockfile, preserve the alchemy patch. (4) d76b24d (codex async questions) edits thread-forking hot files decider.ts (+77/-7), projector.ts (+29/-6), ProjectionSnapshotQuery.ts (+36), ProviderRuntimeIngestion.ts, CodexAdapter.ts, OrchestrationEngine.ts; resolve as union per the guide, and regenerate packages/effect-codex-app-server/src/_generated/schema.gen.ts from the updated generate.ts rather than hand-merging. (5) 9d28c21 changes packages/contracts/src/auth.ts and ConnectionsSettings.tsx (fork 83/28) and ws.ts (fork +556); small upstream deltas, union. (6) .github/workflows/cursor-hygiene-webhook.yml is upstream-only tooling posting to Cursor via CURSOR_T3CODE_* secrets; it no-ops without secrets, so either drop it or take it with Lecturn naming, integrator's call. (7) apps/web/src/components/ChatView.tsx gets +57/-8 across 6382268 and 0a0b6be against a fork diff of 312/66 (thread forking UI), expect small conflicts. (8) UI evidence needed for browser import wizard (Settings > Integrations), pairing-credential UI in Connections settings, and composer paste/selection behaviors.

Fresh independent review approved tree 6418d910853bde764dfd9179d440a0f8588eb249 after controller-rerun focused checks. Merge commit required; no squash/rebase.

Before:
Before

After:
After

composer-before-after.mp4

Implemented and independently reviewed by fresh Claude Code agents (claude-fable-5-1 top-level, claude-opus-5 subagents).

WellyngtonF and others added 22 commits September 3, 2026 16:19
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nd Firefox (pingdotgg#7260)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ack (pingdotgg#9516)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
…g#9518)

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
@Nurozen
Nurozen merged commit 86faca1 into main Sep 12, 2026
9 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.

5 participants