Skip to content

Feature Stack: Lopu auto stack merge test 1 -> main - #566

Merged
lopugit merged 1048 commits into
mainfrom
lopu/feature-stack-ci-feature-stack-98c30439-8739-4acb-8dfa-2dc4e0f780aa-to-main
Sep 1, 2026
Merged

Feature Stack: Lopu auto stack merge test 1 -> main#566
lopugit merged 1048 commits into
mainfrom
lopu/feature-stack-ci-feature-stack-98c30439-8739-4acb-8dfa-2dc4e0f780aa-to-main

Conversation

@lopugit

@lopugit lopugit commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Lopu combined this immutable Feature Stack in the requested order:

Target snapshot: 53c461c71047f1ad6bab6b952b7c7f22dbd5f49a
Feature Stack id: ci-feature-stack-98c30439-8739-4acb-8dfa-2dc4e0f780aa

Every merge commit was mechanically verified for exact parents and conflict-only AI edits. Branch protection and required checks remain the final merge gate.

Lopu added 30 commits August 28, 2026 19:08
… more incoming)

PR #315 adds a poll compose mode; main had meanwhile rebuilt the composer from
an exclusive `type` state machine into additive toggles (photosOn/marketOn/
thingOn) with an Editor.js rich-text value, and replaced URL-linked images with
attachments. Four conflicted paths, 17 blocks.

remix/app/components/Feed/PostComposer.tsx (11 blocks) — kept main's toggle
architecture and carried the poll feature onto it:
  - added a `pollOn` toggle beside the others and widened the derived `type` to
    ComposeMode. The auto-merged body already contained #315's
    `apiType = type === 'poll' ? 'thingtime' : type` and a
    Record<ComposeMode, string> placeholder map, so `type` had to admit 'poll'
    for the merged file to be coherent at all.
  - poll is the one EXCLUSIVE badge (its thing IS the poll, so it owns the slot
    the other groups build into) and stays compose-only, matching #315's note
    that an existing poll edits as its thing.
  - both sides declared `canonicalText`; folded them into one definition that
    keeps main's submit-time editor capture and #315's empty-text-for-polls
    rule, and sourced the poll question from that same snapshot.
  - dropped #315's linkedImages/validImages: main removed the URL-image flow in
    favour of attachments, and its helpers are no longer imported.
  - payloads now send `type: apiType` (#315) together with `richText` (main).

remix/app/components/Feed/PostCard.tsx (3) — unioned PostBodyShape ('richText'
from main, 'tags' from #315), kept main's PostTextBody and taught it #315's
HashtagText linkification, and kept the `poll` prop. Both are load-bearing: the
auto-merged body already renders `poll={poll}` and `<TagChipRow tags={post.tags}>`.
The inline-edit save now clears richText (main) and re-syncs tags (#315).

remix/scripts/verify-vercel-output.mjs (2) — main renamed chatGptDiscoveryIndex
to wellKnownDiscoveryIndex (used by auto-merged checks) while #315 added the
permalink route indices (also used by auto-merged checks); kept both, under
main's name.

remix/package.json (1) — ordered union of the test:unit aggregate.

Verified: no conflict markers, no dangling references to the dropped
linked-image helpers, both TSX files parse under tsc, and the verifier script
passes node --check.

Feature-Stack-Source: pr=315 head=cad6286f20fd679641cf5bc01295bc8cfa258f2c
…e app says to the API (claude-todo/10 ⌨️)

One conflicted path, remix/package.json: the routine collision of parallel
branches registering new test suites. Kept both sides' script definitions and
took the ordered union of the "test:unit" aggregate, so no branch's suite stops
running and each side's relative ordering survives.

Verified after resolution: the file parses, has no duplicate keys, and every
`npm run test:*` the aggregate names resolves to a defined script.

Feature-Stack-Source: pr=137 head=277978f52b1e0b755e8e24157b78df8838d585bd
…s a try-on chip (claude-todo/10 ✨)

Two conflicted paths:

- remix/app/docs/apiDocs.ts, the users-profile `detail` prose: #180 (already in
  this stack) had documented the private birthday field and #132 documents the
  new wornTheme projection, both by rewriting the same string. Combined both
  descriptions; verified wornTheme really is in the merged GET projection
  (routes/api/v1/users/profile/_profile.tsx) so the doc matches the endpoint.
- remix/package.json: the usual parallel test-suite registration. Here both
  sides also redefined "test:things", so its `--test` file list was unioned
  rather than duplicated (main's list is a superset of #132's), and #132's new
  "test:theme" was added. The test:unit aggregate took the ordered union.

Verified: package.json parses with no duplicate keys and no dangling script
references; apiDocs.ts parses.

Feature-Stack-Source: pr=132 head=c8e427243a1d513170429c475e319223df5534ab
…lly bails (TODO #12)

PR #107 changes PostCard's onChanged to (id, change) so the parent can hand
down one useCallback-stable handler and React.memo actually bails.

- remix/app/components/Feed/PostCard.tsx: took #107's two-argument call form
  with main's richer optimistic payloads (richText + tags on the inline-edit
  save and its rollback). The merged file had already picked up #107's new
  prop type and most of its call sites by auto-merge, which left five call
  sites added by later-merged branches — the poll vote apply/confirm/rollback
  from #315 and the three save-toggle writes — still on the old one-argument
  form. Those now pass post.id too; left as-is they would have shipped the
  updater function in the id parameter.
- remix/app/components/Feed/PostList.tsx: kept main's j/k focus-ring wrapper
  Box and #107's direct `onChanged={onPostChanged}` pass-through. The
  auto-merged PostRow already declares the two-argument onPostChanged and the
  `focused` prop, and #107 deleted the per-row handleChanged closure that
  main's side still referenced — keeping it would not have compiled.
- remix/package.json: ordered union of the test:unit aggregate plus the new
  suite definitions.

Verified: every onChanged call site in PostCard now passes an id; the external
handlers in routes/post.tsx, routes/media.tsx, routes/thing.tsx and
SearchPage.tsx already take (id, change); both TSX files parse.

Feature-Stack-Source: pr=107 head=fafd0e4d0c7332ada66aaa0937e9977c8ab771bc
…back (TODO 2)

Three conflicted paths, all bookkeeping around the fix this PR lands:

- TODO/TODO.md item 2: main's text says the item is only "MOSTLY FIXED" and
  names PR #105 as the owner of the remaining fallback hardening. That is this
  source, so its "FIXED" text is the accurate one. Confirmed before accepting
  it: the merged remix/app/api/utils/auth/appOrigin.ts carries the platform
  origin resolution and the narrow Host allowlist (with *.vercel.app
  deliberately excluded), and test:auth-origin is both defined and wired into
  the test:unit aggregate.
- TESTING.md: pure add/add — main appended the social-meta unfurl checklist and
  #105 appended the emailed-link origin trust checklist at the same anchor.
  Kept both.
- remix/package.json: ordered union of the test:unit aggregate.

Feature-Stack-Source: pr=105 head=7281bba341411b09a1223be3ab65b75f7efc3e75
…rl+Z listener; make redo reachable (TODO 13)

One conflicted path, remix/package.json: the routine collision of parallel
branches registering new test suites. Kept both sides' script definitions and
took the ordered union of the "test:unit" aggregate, so no branch's suite stops
running and each side's relative ordering survives.

Verified after resolution: the file parses, has no duplicate keys, and every
`npm run test:*` the aggregate names resolves to a defined script.

Feature-Stack-Source: pr=101 head=d3f81ae31e0e85d0cdcd6a45043d79506a1e418c
… — ranked-mode duplicate posts)

- remix/app/components/Profile/ProfilePage.tsx: add/add on the import block —
  main's theme try-on helpers and #93's appendPostsDeduped landed on the same
  line. Kept both; every imported symbol is used in the merged file.
- remix/package.json: ordered union of test:unit, and both sides had extended
  "test:feed", so its --test file list was unioned rather than duplicated.

Feature-Stack-Source: pr=93 head=5ddc3ecde69eb1b4a8e48dfeb219dc2d34030257
PR #68 adds a persistent desktop device mesh and live AI chat connectors; ten
paths collided with main's parallel work. Every conflict was additive — both
sides extending the same list, type, or index set — except the two noted below.

Unions (kept both sides):
- auth/sessions.ts: the session `purpose` union gains #68's 'device-pairing'
  and 'device' beside main's 'deployment-link'.
- mongodb/collections.ts: both sides' imports, and #68's eight device index
  definitions alongside main's note on the retired vote unique index.
- storage/storageCore.ts: DEVICE_CONTROL_THINGTIME joins 'vote' and
  MESSENGER_THINGTIME in the non-billable kind list.
- schemas/registry.ts: DEVICE_THINGTIME joins EMBEDDED_THINGTIME.
- Nav.tsx imports: ArrowLeft/ArrowRight (#68) plus Command (main).
- remix/CHANGELOG.md: three add/add entry blocks, all kept.
- remix/package.json: ordered union of test:unit plus #68's new suites.

Superset wins (one side already contained the other):
- ThingsViews.tsx: main's import list and ThingsItemAction union both strictly
  contain #68's, adding isDuplicable / 'duplicate'.
- rateLimit/config.ts: both blocks were identical code differing only in
  indentation; kept main's tabs.

Judgement calls:
- server/routes/[...].ts: #68's whole change here was swapping the shell's
  storage mount from assets:server to assets:client, while main had rewritten
  the handler to inject social meta and read assets:shell with an assets:server
  fallback. Kept main's handler and added assets:client as a third fallback, so
  #68's fix still applies to layouts where nitro mounts the shell there.
- Nav.tsx nav-right-section: main added the ⌘K quick-switcher button inside the
  container; #68 reflowed the same opening tag to one line and changed
  height="100%" to "36px". Kept main's version — the height change is incidental
  to #68's feature, whose Electron back/forward buttons live in the titlebar
  block (auto-merged, untouched) and carry their own 36px sizing.

Verified: no markers left, every touched TS/TSX file parses, and package.json
has no duplicate keys or dangling script references.

Feature-Stack-Source: pr=68 head=17f3affdcf2469e35ad39fb346a905d64aeb60ba
…T /api/v1/auth/introspect (TODO item 4)

- remix/app/api/utils/rateLimit/config.ts: both sides appended entries to
  RATE_LIMIT_DEFAULTS — main's networkProbe.* trio and #116's 'auth.introspect'.
  Kept both, with the separating comma added at the seam. RATE_LIMIT_ENDPOINTS
  derives from the object's keys, so dropping either side would have silently
  unbounded that surface.
- remix/package.json: ordered union of test:unit plus #116's new suite.

Feature-Stack-Source: pr=116 head=4c27dcbc50d2981c10ca434c2eef1a1126c33cee
…local speed, single source of truth

Clean three-way auto-merge with no conflicted paths; Git's merge result is preserved exactly as produced.

Feature-Stack-Source: pr=185 head=c7c5f7a71362c6d7dc3bd26da613282460973423
…itations via /feed?algorithm=<id> (claude-todo/10 ✨)

- remix/app/api/utils/rateLimit/config.ts: another append collision on
  RATE_LIMIT_DEFAULTS; #133's 'algorithms.shared' now sits after main's
  'auth.introspect', with the seam comma added.
- remix/app/docs/apiDocs.ts: main's 'embed-things' entry and #133's
  'algorithms-shared' entry were added at the same array slot, and Git
  interleaved them through the identical skeleton lines they share
  (`}`, `],`, `responseExamples: [`, `{`, `status: 200,`). Rebuilt them as two
  complete, separate endpoint({...}) entries rather than letting either be
  swallowed — each keeps its own requestExamples, responseExamples and notes.
  Documenting the endpoint IS its Nitro route registration here, so losing
  either would 404 that route and drop its generated -docs smoke tests.

Verified: no markers left, file parses, and all three endpoint ids
(embed-things, algorithms-shared, apps) are present and distinct.

Feature-Stack-Source: pr=133 head=597c15eb14911253104bdc0d608bb16bf7698d88
…— browse, apply, share (claude-todo/10 ✨)

Single conflict in
Commander/extensions/raycast/src/commands/regexToReplacementConverter.tsx: this
branch predates the file's move under Commander/extensions/ and carries the
same single-pass unescape fix inline, while main had already extracted it into
the exported, unit-tested unescapeRegexReplacementText() helper. Identical
semantics over the same escape set ({, [, \, ], }, .); resolved to the helper
so the extraction and Commander/tests/regexToReplacementConverter.test.ts
coverage are kept. The branch's own feature changes auto-merged untouched.

Feature-Stack-Source: pr=131 head=0b56e3df4e478dbf4a328dedd68047200ed7e07d
…`>` command registry (claude-todo/10 ⌨️)

One conflicted path, remix/app/components/Commander/CommanderV2.tsx: #130 adds
a `>` command mode that must hide the people/things suggestion lists, while main
had rebuilt the remote-result row into a richer layout (avatar circle with a
result-type badge, title over context).

Kept main's markup and applied #130's gate inline —
`{!commandMode && remoteResults.map(...)}` and
`{!commandMode && suggestions?.length ? ...}` — rather than #130's wrapper form,
which would have re-indented main's whole block and dropped its new row design.
Same rendering behaviour, and it matches the `!commandMode &&` gates already
present on the neighbouring loading/empty/local-suggestion branches.

Feature-Stack-Source: pr=130 head=b3d552899ec5c3f17d77c93fb434805d4da50146
… key-path hover context (claude-todo 08)

One conflicted path, TODO/claude-todo/README.md: #127 flips item 14's status to
"Built (phase 1)" on the same table row where main had added item 16. Kept
#127's updated row 14 and main's row 16. Checked that the status is earned —
#127 ships the implementation it describes (editorJsBlockDragDrop.ts,
editorJsBlockReorder.ts and its test, plus the LongTextEditor wiring), so this
is not a status claim running ahead of the code.

Feature-Stack-Source: pr=127 head=f53256fe665c3249ef5ed0d9da819cda6f992ee7
…press, Alt+arrows (claude-todo 14, phase 1)

One conflicted path, TODO/claude-todo/README.md status board. Item 14's row
auto-merged (the previous stack commit already carries #127's "Built (phase 1)"
status for the same work), leaving only main's item 16 row against this older
branch's absence of it. Kept row 16; no status claim changed.

Feature-Stack-Source: pr=124 head=086204e4778082c640991af105ced78c7bddad18
…solete — no SSR in current architecture

Two conflicted paths, both duplicate work:

- deprecated/api/src/index.js: both sides replaced the wildcard CORS default
  with the same explicit-allowlist comment and closed default. main's version
  is a strict superset — it adds the paragraph explaining that the package is
  no longer built or deployed, so the wildcard was unexploitable today but
  would go live on any revival. Kept main's.
- Commander/extensions/raycast/src/commands/regexToReplacementConverter.tsx:
  the recurring duplicate unescape fix; resolved to the tested helper as before.

Feature-Stack-Source: pr=97 head=068a1a95cec60cb50000daa70a8d32a9d56badd9
…ive vocabulary

One conflicted path, TODO/claude-todo/README.md status board: this branch adds
roadmap rows 15 and 23 in the same table slots where main had added rows 16 and
22. Unioned by item number (14, 15, 16 and 22, 23) so no roadmap entry is lost.

Row 14 appears on both sides: kept main's "Built (phase 1), live-tested locally"
over this older branch's stale "Not started" — the implementation is already in
this stack (PRs #127 and #124, merged above).

Feature-Stack-Source: pr=78 head=8b11fced114ad0fd972d0f63ca7d2e2691ff3d8c
…review c16)

Two conflicted paths, both the same duplicate work seen earlier in this stack:

- deprecated/api/src/index.js: the explicit-CORS-allowlist comment landed on
  several branches independently; main's version is a strict superset (it adds
  why the old wildcard was unexploitable while the package stays undeployed).
  Kept main's.
- Commander/extensions/raycast/src/commands/regexToReplacementConverter.tsx:
  the recurring duplicate unescape fix; resolved to the tested helper as before.

The batched collectionToThingsMigration change this PR is actually about
auto-merged untouched.

Feature-Stack-Source: pr=74 head=dab1a3510334b695a34862d64786d62bec169bdc
@lopugit
lopugit enabled auto-merge September 1, 2026 11:43
@lopugit
lopugit merged commit 4adda98 into main Sep 1, 2026
77 of 79 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 1, 2026
@lopugit
lopugit deleted the lopu/feature-stack-ci-feature-stack-98c30439-8739-4acb-8dfa-2dc4e0f780aa-to-main branch September 3, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant