merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

merge: sync upstream through 083fa4ab2 (15 commits) - #396

Merged
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2
Aug 11, 2026
Merged

merge: sync upstream through 083fa4ab2 (15 commits)#396
omegent-app[bot] merged 18 commits into
fork/devfrom
sync/upstream-083fa4ab2

Conversation

@omegent-app

@omegent-appomegent-appBot commented Aug 11, 2026

Copy link
Copy Markdown

Adopts upstream through 083fa4ab2 — the 15 commits after 9c7622dac. Fourteen conflicted
files
, the largest batch this fork has taken.

Important

Merge with a merge commit, not squash. Squashing collapses the second parent and discards
upstream's commits as ancestors — the thing that keeps "commits behind upstream" honest.

Upstream commits entering the product

Commit
083fa4ab2feat(web): use OKLCH for theme palettes (pingdotgg#6036)
35172010bfix(web): use a clearer pull action icon (pingdotgg#6194)
57b105267fix(web): thread error banner dismiss survives reconnect and rerenders (pingdotgg#6123)
1e355a2a3fix(web): render dropdowns above toasts (pingdotgg#6165)
44621c345feat(web): back buttons for the pull requests and usage pages (pingdotgg#6031)
220e573b1fix(shared): detect Azure DevOps SSH remotes (pingdotgg#6187)
6befe42ebfix(shared): normalize a bare Windows drive root (pingdotgg#6189)
b30a9bc41feat(web): make environment artwork theme aware (pingdotgg#6183)
ac4780f45fix(web): restore typography font sizes to defaults (pingdotgg#6172)
3da7f9c5cfix(mobile): guard App Store release versions (pingdotgg#6177)
c842c6f5bAdd hourly past-24-hour usage view (pingdotgg#6170)
6676f9c83fix(mobile): stabilize thread composer and interactions (pingdotgg#5986)
65b005f1efeat(web): add Copy Thread ID to the thread context menus (pingdotgg#5574)
752acbf65feat: shift+click to create a thread in the current project (pingdotgg#5994)
f5fce7416fix(pull-requests): route self-hosted GitLab remotes (pingdotgg#6061)

The four that needed judgement

Copy Thread ID (pingdotgg#5574) — upstream shipped a feature the fork already had. The merge produced
two "Copy thread ID" entries in the thread action menu, and the fork's own menu test caught
it
rather than it reaching a user. One entry survives, in upstream's position, with the state and
handlers collapsed onto upstream's naming — which is also better typed (ThreadId rather than
string, no String() coercion).

Thread error dismissal (pingdotgg#6123) — supersession, not duplication. The fork had its own dismissal
(a dismissedServerErrorsByThreadKey map feeding resolveServerThreadError). Upstream's
session-scoped masking fixes the same bug the fork's version had: a dismissal that did not survive
a reconnect. So upstream's is adopted, the fork's map and the now-dead arm of the resolver are
removed, and the fork's dismissal tests are retargeted at upstream's helpers rather than deleted
— upstream ships those helpers untested, so deleting would have quietly dropped the coverage.

Mobile composer (pingdotgg#5986) — upstream's overlay rewrite, with the fork's chips inside it. Upstream
restructures KeyboardStickyView, adds the scroll-to-end pill and keyboard-visibility gating; the
fork's overlay carried ComposerQueuedMessages (steering-queue chips). Upstream's structure is taken
whole and the chips moved inside it. Two follow-on repairs: the fork's copy of
use-thread-composer-state predates upstream's activeThreadBusy / selectedThreadQueueCount, so
both are computed there and threaded through — which also brings the fork upstream's honest "Queue"
vs "Send"
label, where the fork had hard-coded "Send".

ThreadFeed keeps the fork's sticky empty→filled mount key over upstream's plain toggle:
remounting a feed that briefly empties mid-sync reads as the conversation reloading. The fork's
unread-activity latch is woven into upstream's rebuilt setEndFollow.

Smaller: app.config.ts takes upstream's 1.0.3 bump with the fork's MOBILE_RUNTIME_VERSION_OVERRIDE;
the mobile home screen keeps its single title, since upstream's native-stack title would render the
connection status twice against the fork's header; the release workflow stays fork-owned.

Checks I ran rather than assumed

  • No test was silently nested by my re-bracing. Three conflict hunks were cut mid-function, so
    closing braces went back by hand — the exact shape that can bury a describe inside another and
    stop it running. Sidebar.logic.test.ts goes 129 fork + 3 upstream = 132 it( blocks, all
    executing
    ; threadActivity.test.ts runs 22.
  • Exactly one copy-thread-id entry remains, verified against the menu test.
  • Typecheck clean across 18 packages, vp build passes.

Adversarial review

Both reviewers went through all seven resolutions. Neither found a HIGH in the conflict
resolutions themselves
, but between them they found two real defects I introduced — both fixed.

FindingDisposition
grok-4.5, HIGHtwo scroll-to-end controls.pingdotgg#5986removed the feed-local "Scroll to latest" chip and replaced it with the composer-overlay pill; the fork had built its own chip, and the merge kept both. Two chevrons in the same band, two controls for VoiceOver, and only one of them re-arming follow on press. Worse, the fork's chip positions against an estimated overlay height that excludes the queued-message chips, so with a queue it could sit under the overlay while the pill stayed correctFixed in e5b838f94. This is the failure class exactly — two implementations, both live, fighting. Upstream's pill wins since the rest of pingdotgg#5986's geometry is built around it. What the fork's chip had that upstream's lacks is the difference between "you scrolled up" and "you are missing something", so the feed now reports unread activity upward the same way it reports follow state, and the pill carries the dot and reads "New activity. Scroll to end". The chip's helpers went with it rather than lingering
gpt-5.6-sol, MEDIUM — the sticky mount latch tracked the bare thread id while the mount key it drives is environment-scoped. Two environments holding the same id would carry "already filled" across a switch, so the new feed skips its remount and computes the initial scroll against a zero composer inset — the positioning bug upstream's key exists to preventFixed in 17adee9de. The fork's recurring shape: single-environment reasoning in a deliberately multi-environment client. Nothing typechecks differently and no test covers two environments sharing a thread id, so it would have shipped green
gpt-5.6-sol, LOW — the retargeted dismissal tests exercise upstream's helpers but not ChatView's integration; they would still pass if ChatView stopped consulting the session setAcknowledged, not fixed. A component-level test is a bigger piece of work than belongs in a sync PR. It verified the wiring itself is correct at ChatView.tsx:1592 and :6745
grok-4.5, MEDIUM — board context menu ordering differs from the shared action menu builderPre-existing fork divergence, untouched by this merge

Confirmed sound by both: exactly one copy-thread-id entry in upstream's position, dispatched
through the typed handler from both call sites; resolveServerThreadError keeps local-over-server
precedence with no dismissal path left behind; the three useState declarations my removal regex ate
are restored correctly with all consumers intact; the queue chips sit inside the measured
composerOverlayRef so their height still feeds the list inset, with the fork's steering, editing
and start-new-thread plumbing whole; activeThreadBusy / queue count / the Queue-vs-Send label match
upstream; keeping the mobile route title out is right because HomeHeader already owns it on both
platforms; and the hand-restored braces close the intended blocks — no test is accidentally nested
or skipped
.

Verification

  • 2,763 tests pass; the only failure is the pre-existing CodexTextGeneration launch-args one,
    which reproduces on unmerged fork/dev.
  • pnpm-lock.yaml regenerated rather than hand-merged.

Note

One full-suite run surfaced the pre-existing browserHistoryStore.test.ts flake (~1 run in 3).
It is not from this branch — I reproduced it earlier on clean fork/dev and at f067b34a1,
before any of this work. It passes in isolation.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

GuilhermeVieiraDevand others added 16 commits August 11, 2026 13:11
…shift+click and show shortcut in tooltip (pingdotgg#5994)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…ontext menu (pingdotgg#5574)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Thuong Tin <thuongtin@gmail.com>
Co-authored-by: Kapish14 <kapishnarang01@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
pingdotgg#6189)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gdotgg#6187)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the sidebar footer (pingdotgg#6031)
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adopts the 15 upstream commits that landed after 9c7622d, headlined by OKLCH
theme palettes (pingdotgg#6036), Copy Thread ID in the thread menus (pingdotgg#5574), shift+click
to create in the current project (pingdotgg#5994), sidebar back buttons for the pull
requests and usage pages (pingdotgg#6031), an hourly past-24-hour usage view (pingdotgg#6170) and
mobile composer stabilization (pingdotgg#5986).
Fourteen conflicts. What needed judgement:
Copy Thread ID arrived upstream as pingdotgg#5574, which the fork had already built. The
fork's own menu test caught the result: two "Copy thread ID" entries in the
thread action menu. One entry survives, in upstream's position, and the
duplicated state and handlers collapse onto upstream's naming, which is also
better typed (ThreadId rather than string, no String() coercion).
pingdotgg#6123 replaces the fork's thread-error dismissal with session-scoped banner
masking. That supersedes rather than duplicates: it fixes the same bug the
fork's version had — a dismissal that did not survive reconnects. The fork's
dismissal map is removed along with the now-dead arm of resolveServerThreadError,
and its dismissal tests are retargeted at upstream's helpers, which upstream
ships untested.
pingdotgg#5986 rewrites the mobile composer overlay. Upstream's structure is adopted
whole, with the fork's queued-message chips moved inside it, and the fork's
sticky empty-to-filled mount key kept over upstream's plain toggle: remounting
a feed that briefly empties mid-sync reads as the conversation reloading. The
fork's copy of use-thread-composer-state predates upstream's queue count and
busy flag, so both are computed there and threaded through, which also brings
upstream's honest "Queue" send label to the fork.
The mobile home screen keeps its single title: upstream re-adds a native-stack
title that would render the connection status twice against the fork's header.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@github-actionsgithub-actionsBot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 11, 2026
omegent-appBotand others added 2 commits August 11, 2026 18:42
The sticky empty-to-filled latch tracked the bare thread id while the mount key
it drives is environment-scoped. Two environments can hold the same thread id,
so switching between them carried "already filled" across the switch: the new
feed skipped the remount it needs, and its list computed the initial
scroll-to-end against a zero composer inset — the positioning bug upstream's
key exists to avoid.
Both now key on feedThreadKey.
This is the fork's usual shape of bug: single-environment reasoning applied to
a client that is deliberately multi-environment. Nothing typechecks differently
and no test covers two environments sharing a thread id, so it would have
shipped green.
Found by the gpt-5.6-sol adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
pingdotgg#5986 removed the feed-local "Scroll to latest" chip and put a pill on the
composer overlay. The fork had built its own chip with an unread-activity
signal, and the merge kept both: two chevrons in the same band, two controls
for VoiceOver, and only one of them re-arming follow on press. The fork's chip
was also positioned against an estimated overlay height that does not include
the queued-message chips, so with a queue it could sit underneath the overlay
while the other stayed correct.
Upstream's pill wins — it is the one the rest of pingdotgg#5986's geometry is built
around. What the fork's chip had and upstream's does not is the distinction
between "you scrolled up" and "you are missing something", so the feed now
reports unread activity upward the same way it reports follow state, and the
pill carries the dot and says "New activity. Scroll to end".
The chip's helpers went with it rather than lingering as dead code.
Found by the grok-4.5 adversarial review.
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-appBot merged commit 0eeb397 into fork/devAug 11, 2026
6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@GuilhermeVieiraDev@UtkarshUsername@juliusmarminge@StiensWout@arhxam@Brechard@myacoub91@extoci