You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -168,6 +168,20 @@ The same applies to `py-*` vs `pt-*`/`pb-*`.
168
168
169
169
Use these as implementation references when designing protocol handling, UX flows, and operational safeguards.
170
170
171
+
## Upstream Merge: Divergence Ledger
172
+
173
+
Before starting any upstream sync, read [`UPSTREAM_DIVERGENCE.md`](./UPSTREAM_DIVERGENCE.md). It is the audit trail of which upstream PRs are already ported (under possibly-different MarCode SHAs), which are already behaviorally equivalent and must NOT be re-ported, which are intentionally skipped, and what is genuinely pending. Its sister doc [`FEATURES.md`](./FEATURES.md) lists MarCode-exclusive features that must be preserved through any merge.
174
+
175
+
The ledger's own preamble describes the exact `git cherry origin/main upstream/main` workflow for computing real pending work. Always subtract the "Already equivalent" and "Intentionally skipped" sets before scoping a cycle — re-porting an already-equivalent PR creates pointless conflicts on FEATURES.md-protected files.
176
+
177
+
**After a cycle:**
178
+
179
+
1. Add new rows to the "Ported in the current cycle" section (upstream PR number + new MarCode SHA + conflict-resolution notes, especially any FEATURES.md-protected substitutions like `AnalyticsServiceNoopLive` in place of upstream `AnalyticsService.layerTest`).
180
+
2. Move finished rows out of "Pending real work".
181
+
3. Advance "Baseline after cycle" to the last merge SHA of the cycle.
182
+
4. Record any data-migration smoke results (real DB rows migrated, legacy shapes surviving / none).
183
+
5. Run `bun run fmt` — CI enforces `oxfmt --check` on markdown, so unformatted table column widths will fail the Format step.
184
+
171
185
## Upstream Merge: Migration Ordering
172
186
173
187
MarCode has its own database migrations that were added at specific IDs. When merging upstream changes that introduce NEW migrations, **never renumber existing MarCode migrations** — existing users already have them applied at their original IDs. The Effect SQL migrator tracks migrations by numeric ID in the `effect_sql_migrations` table; renumbering causes it to skip the new upstream tables (thinking those IDs are done) and attempt to re-create existing tables at the new IDs.
Copy file name to clipboardExpand all lines: UPSTREAM_DIVERGENCE.md
+30-5Lines changed: 30 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,7 +37,7 @@ Sections are ordered by action:
37
37
38
38
## Ported in the current cycle
39
39
40
-
**Cycle:** 2026-04-24 · Baseline before cycle: `7c430aece` · Baseline after cycle: `9f6411d17`
40
+
**Cycle:** 2026-04-24 · Baseline before cycle: `7c430aece` · Baseline after cycle: `ececcdcb1`
41
41
42
42
### Direct-to-main (no PR, user-approved)
43
43
@@ -82,13 +82,19 @@ Sections are ordered by action:
82
82
-`toast.tsx` — took upstream's version wholesale (492 → 719 lines). Upstream already bundled `CopyErrorButton` at line 93, so no manual re-integration needed.
83
83
-`Sidebar.tsx` — preserved MarCode's "Delete anyway" warning toast flow (action button → deferred close → `api.dialogs.confirm` with thread-count messaging → `removeProject({ force: true })` → inline error toast). Wrapped all toast calls via the new `stackedThreadToast(...)` helper for layout consistency.
84
84
85
+
### PR #68 — cycle ledger bootstrap
86
+
87
+
Introduced this doc. No upstream PR; meta-work that codifies the "Already equivalent" / "Intentionally skipped" sets so future cycles don't re-derive them.
|[#1996](https://github.com/pingdotgg/t3code/pull/1996)| Use latest user message time for thread timestamps (row) |`524e93afd`|
90
96
91
-
Narrow behavioral port: `Sidebar.tsx:715` thread-row label now falls back `thread.latestUserMessageAt ?? thread.updatedAt ?? thread.createdAt`. Matches the helper already in `CommandPalette.logic.ts:161`.
97
+
Narrow behavioral port: `Sidebar.tsx:715` thread-row label now falls back `thread.latestUserMessageAt ?? thread.updatedAt ?? thread.createdAt`. Matches the helper already in `CommandPalette.logic.ts:161`. Preserves MarCode's structural-sharing event handling ([FEATURES.md §"Incremental Event Handling"](./FEATURES.md#incremental-event-handling--structural-sharing)).
92
98
93
99
### PR #70 — shell-stream authority for sidebar summary (part 2 of upstream #1996)
94
100
@@ -100,6 +106,27 @@ Narrow behavioral port: `Sidebar.tsx:715` thread-row label now falls back `threa
100
106
101
107
What we deliberately did NOT port from upstream #1996: structural reorganization of `store.ts` (commentary, `ensureThreadRegistered` extraction, `retainThreadScopedRecord` changes). MarCode's Incremental Event Handling & Structural Sharing (FEATURES.md §1) already covers the functional behavior; upstream's cosmetic reshuffle is net risk for no gain.
**Why ported:** forward compatibility with upstream's `provider-instance-registry` branch (`ceddb40 / 7a466f / 8a82b53 / 84b0d74`), which extends the new option-array shape. Any future sync that touches provider identity assumes #2246 is in.
116
+
117
+
**Key deviations from upstream:**
118
+
119
+
- Migration id renumbered `026 → 030` because MarCode already uses `26_AuthSessionLastConnectedAt`. Current head after port: `030_CanonicalizeModelSelectionOptions`.
120
+
-`RoutingTextGeneration.ts` — kept MarCode's Claude→Codex fallback branching intact (FEATURES.md §"Claude-Powered Text Generation"); only the option access was retrofitted with `getModelSelectionStringOptionValue` / `getModelSelectionBooleanOptionValue` helpers.
-`composerProviderRegistry.tsx` (deleted upstream) — local additions hand-ported into the new `composerProviderState.tsx` rather than deleted.
123
+
-`ProviderModelPicker.browser.tsx` + `composerDraftStore.ts` — near-total hand-rebuild since upstream ±399 LoC collides with MarCode's +397 LoC delta.
124
+
- All new test layers routed through `AnalyticsServiceNoopLive` (no upstream `AnalyticsService.layerTest`).
125
+
126
+
**Post-merge hotfix** (on main, direct commits): `composerDraftStore.ts` gained `normalizeModelSelectionByProviderMap` to coerce legacy object-shape `options` blobs in pre-existing v5 localStorage (migration 030 only touches SQLite — persisted drafts in the browser store needed a separate runtime normalizer). Regression guard in `composerDraftStore.test.ts` under `describe("composerDraftStore legacy modelSelection options migration")`.
127
+
128
+
**Phase 4 smoke** (real dev DB, 2026-04-24): migration 030 applied cleanly — 155 `projection_threads` rows canonicalized, 0 legacy-shape survivors across `projection_threads`, `projection_projects`, and `orchestration_events` (`project.{created,meta-updated}`, `thread.{created,meta-updated,turn-start-requested}`).
|[#2246](https://github.com/pingdotgg/t3code/pull/2246)| Refactor provider model selections to option arrays | High | Adds migration `026_CanonicalizeModelSelectionOptions` (renumber to `030` — MarCode's `26_AuthSessionLastConnectedAt` already owns that id). Touches every `*TextGeneration.ts` (collides with FEATURES.md §"Claude-Powered Text Generation") and the MarCode provider instance registry work (`0e71e3023`, `42b428826`, `4da47be23`). 67 files, +3403/-3828. Plan: `/Users/tyulyukov/.claude/plans/cached-napping-sundae.md`. |
190
+
_None as of 2026-04-24._ Both previously-listed rows (#1996 and #2246) landed in this cycle — #1996 across PRs #69 + #70, #2246 via PR #71. Re-run the `git cherry origin/main upstream/main` workflow at the top of this doc when starting a new cycle to populate this section.
0 commit comments