Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
c2c4bfe
feat(servers): add cache integrity alert resolution
RonenMars Jul 18, 2026
a784e01
fix(cache): clear server state after destructive actions
RonenMars Jul 18, 2026
5d38e1f
test(cache): extend modal render timeout in CI
RonenMars Jul 18, 2026
9aea13b
fix(cache): handle explicit server warm-up states
RonenMars Jul 18, 2026
1a7cbc1
feat(servers): show warm-up progress for every server
RonenMars Jul 18, 2026
0eb8987
feat(privacy): align feedback Sentry path with one-shot crash consent
RonenMars Jul 18, 2026
fdd9928
fix(i18n): add ar/he/ru translations for feedback success keys
RonenMars Jul 20, 2026
f39db81
fix(composer): escape spaces in attachment @path payloads
RonenMars Jul 18, 2026
f4233cf
fix(session): stop unused fresh sessions on back navigation
RonenMars Jul 18, 2026
a831884
docs: refresh pre-release status for in-flight PRs [skip-ci]
RonenMars Jul 18, 2026
cd3aac0
chore(deps): bump shell-quote
dependabot[bot] Jul 21, 2026
34e4c7e
feat(sessions): add read-only live view for external sessions
RonenMars Jul 21, 2026
aa5b511
fix(i18n): add ar/he/ru translations for resume take-over keys
RonenMars Jul 22, 2026
16546ee
feat(servers): add cache integrity alert resolution
RonenMars Jul 18, 2026
8b3ae2f
fix(cache): clear server state after destructive actions
RonenMars Jul 18, 2026
bd020e2
test(cache): extend modal render timeout in CI
RonenMars Jul 18, 2026
e542d56
fix(cache): handle explicit server warm-up states
RonenMars Jul 18, 2026
9f9387a
feat(servers): show warm-up progress for every server
RonenMars Jul 18, 2026
277584e
chore(ios): bump build number to 165 [skip-ci] (#352)
github-actions[bot] Jul 21, 2026
77082f4
feat(sessions): add read-only live view for external sessions
RonenMars Jul 21, 2026
b75dfb8
test(i18n): gate unused translation keys and prune dead ones
RonenMars Jul 22, 2026
5fb9a92
fix(servers): use translated remove-dialog message
RonenMars Jul 22, 2026
73cdc04
docs: sync backlog and roadmap with pre-release PR state [skip-ci]
RonenMars Jul 22, 2026
10a953b
test(e2e): grant speech-recognition before Maestro mock suite
RonenMars Jul 22, 2026
2c574ac
feat(onboarding): ship Feature 5 top polish wins
RonenMars Jul 22, 2026
d1ca430
fix(onboarding): type skipLabelKey as an onboarding i18n key
RonenMars Jul 22, 2026
56d503b
test(onboarding): match manual-mode header copy change
RonenMars Jul 22, 2026
10786a8
fix(e2e): harden browse flake reporting and fix feat1 tree switch
RonenMars Jul 22, 2026
584d464
fix(onboarding): exchange tb pair tokens on the manual connect path
RonenMars Jul 22, 2026
d0ced52
test(e2e): wire server drag-reorder into the mock Maestro suite
RonenMars Jul 22, 2026
0f96537
feat(onboarding): re-wire NotificationsStep into the navigator
RonenMars Jul 22, 2026
e92b08a
ci: gate locale parity and dead keys with an i18n job
RonenMars Jul 22, 2026
3fcf3b3
docs: log run 2 of the open-PR integration snapshot [skip-ci]
RonenMars Jul 22, 2026
ee659db
fix(i18n): drop unused manualServerUrl onboarding key
RonenMars Jul 22, 2026
650578c
docs: record the #362 dead-key fix in the run log [skip-ci]
RonenMars Jul 22, 2026
ac58dfe
test(session): mock navigation and stopSession for the session screen
RonenMars Jul 22, 2026
8429fee
fix(types): type the __DEV__ global alias in useTBPair tests
RonenMars Jul 22, 2026
ed1a712
test(session): mock useNavigation in the external-gate suite
RonenMars Jul 22, 2026
8843186
docs: record the #346, #354 and #362 fixes in the run log [skip-ci]
RonenMars Jul 22, 2026
cfe45c0
docs: document jest suite load-flakiness and worktree test gotchas [s…
RonenMars Jul 22, 2026
0cd1b25
docs: point the run log at the permanent jest troubleshooting entries…
RonenMars Jul 22, 2026
497d82b
docs: record that origin/main is fully contained in the snapshot [ski…
RonenMars Jul 22, 2026
01b0968
docs(runbooks): add landing-runbook format and mobile kick-off
RonenMars Jul 22, 2026
68e71ef
chore: update Podfile.lock following deps updates
RonenMars Jul 22, 2026
4d191dc
docs(runbook): append session-name follow-up PR chain [skip-ci]
RonenMars Jul 22, 2026
6ba4a70
docs(runbooks): add mobile land-open-prs runbook with session-name fo…
RonenMars Jul 23, 2026
7f17104
fix(sessions): display JSONL-derived session name across all views
RonenMars Jul 22, 2026
9c79749
feat(conversation): stabilize live reload, animate new messages, add …
RonenMars Jul 23, 2026
c849c6a
chore(ios): refresh Podfile.lock for the 2026-07-22 snapshot
RonenMars Jul 22, 2026
d78e6af
feat(conversation): stabilize live reload, animate new messages, add …
RonenMars Jul 23, 2026
ff28c60
feat(conversation): add in-chat search entry on detail screen
RonenMars Jul 23, 2026
0e82fa8
fix(conversation): anchor live message list scroll natively (#382)
RonenMars Jul 23, 2026
2c3aee8
fix(conversation): drop duplicate margin on nested text bubbles (#384)
RonenMars Jul 23, 2026
32548e7
fix(terminal): fall back to HTTP output when WS replay is blank
RonenMars Jul 23, 2026
2956b48
fix(session): freeze hidden session screens to stop cumulative slowdown
RonenMars Jul 23, 2026
7efa0b5
fix(terminal): cap VirtualTerminal scrollback to bound memory and ren…
RonenMars Jul 23, 2026
a03138f
docs(runbook): append session-load and slowdown follow-up PR chain [s…
RonenMars Jul 23, 2026
a1e263c
feat(conversation): stabilize live reload, animate new messages, add …
RonenMars Jul 23, 2026
3b687f7
feat(conversation): stabilize live reload, animate new messages, add …
RonenMars Jul 23, 2026
d05b521
docs(runbook): record local merge of missing PRs [skip-ci]
RonenMars Jul 23, 2026
0ff0531
fix(terminal): drop the frozen status-line counter from rendered output
RonenMars Jul 23, 2026
b034fdd
feat(conversation): show a progress skeleton while the agent thinks s…
RonenMars Jul 23, 2026
4ca2711
feat(servers): manage per-server Claude CLI flags from the app
RonenMars Jul 23, 2026
18f4276
docs(session): correct hold_session comments to describe grace-timer …
RonenMars Jul 23, 2026
6a6370b
fix(session): harden lifecycle not-found, reconnect, and e2e coverage
RonenMars Jul 23, 2026
c995b54
feat(onboarding): prioritize QR pairing and harden connect UX
RonenMars Jul 23, 2026
5feb7bb
feat(hub): harden multi-server resilience and project disambiguation
RonenMars Jul 23, 2026
4bd8fe5
fix(session): unblock lifecycle CI typecheck and SessionScreen mocks
RonenMars Jul 23, 2026
a344ad9
fix(hub): portable server-empty warming status check
RonenMars Jul 23, 2026
c0b1a5f
feat(session): unify session presentation kinds and capabilities
RonenMars Jul 24, 2026
6ebd420
refactor(session): keep presentation helper free of externalSession i…
RonenMars Jul 24, 2026
428ba13
test(session): expect Waiting label for waiting_input status
RonenMars Jul 24, 2026
2155221
[feat][terminal-conversation-rendering] (#403)
RonenMars Jul 24, 2026
a1f6950
docs: codify PR title and branch naming from recent history (#404)
RonenMars Jul 24, 2026
ad95c23
feat(session): add conversation-derived mobile review sheet
RonenMars Jul 24, 2026
5ece123
feat(a11y): harden reduce-motion, touch targets, and terminal labels …
RonenMars Jul 24, 2026
c87ebce
feat(servers): add streamer diagnostics health and remediation screen…
RonenMars Jul 24, 2026
c9a4880
feat(browse): gate session start on streamer provider capabilities (#…
RonenMars Jul 24, 2026
ec2ee36
feat(settings): add per-server push notification health (#409)
RonenMars Jul 24, 2026
3f0349c
feat(settings): add paired-device list and revoke management (#410)
RonenMars Jul 24, 2026
af062f0
feat(settings): add metadata backup export and dry-run restore (#411)
RonenMars Jul 24, 2026
f2242bc
fix(android): pin expo-modules-core for R8 ColorCompat
RonenMars Jul 24, 2026
597f029
feat(browse): preview 3 recent dirs with searchable Display all modal
RonenMars Jul 25, 2026
b45cf7d
fix(conversation): restore in-chat search button and repair locale drift
RonenMars Jul 25, 2026
d10889b
fix(ios): align expo module set to SDK 57.0.8 and gate dyld symbols
RonenMars Jul 25, 2026
386bda8
chore: remove local crash and mobile log dumps
RonenMars Jul 25, 2026
a2e9400
Merge remote-tracking branch 'origin/main' into integration-merge-354…
RonenMars Jul 25, 2026
50a81df
fix(ios): patch expo-modules-jsi Swift 6 abs() overload ambiguity
RonenMars Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ jobs:
# needs Xcode 26+. The macos-15 runner defaults to Xcode 16.4 (Swift 6.1),
# so the archive fails at SPM resolution. Point the whole toolchain at the
# Xcode 26.3 that's preinstalled on the image.
# Xcode 26.3's Swift 6 compiler also hits an abs() overload-ambiguity bug in
# expo-modules-jsi (patched via patches/expo-modules-jsi+*.patch — see Expo
# issue #47875). Expo's real fix is Xcode 26.4, not preinstalled on macos-15
# yet; bump this to 26.4 and drop the patch once the runner image has it.
DEVELOPER_DIR: /Applications/Xcode_26.3.app/Contents/Developer
steps:
- name: Warn when building a non-main ref
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,47 @@ jobs:
with:
run: npm run lint

# ── i18n ─────────────────────────────────────────────────────────────────────
# The locale gates (`i18n-completeness`, `i18n-unused-keys`, `i18n`) live at the
# root of `__tests__/`, so neither `test:unit` (`__tests__/unit`) nor
# `test:integration` (`__tests__/integration`) matches them and they never ran
# on a PR. An English-only key therefore shipped green: Type check only catches
# a *missing key* (t() is typed against the locale JSON), never a *missing
# translation*, which reaches users as silent English fallback mid-RTL layout.
i18n:
name: i18n
runs-on: ubuntu-latest
needs: [gate, setup]
steps:
- uses: actions/checkout@v5

- name: i18n
if: needs.gate.outputs.skip != 'true'
uses: ./.github/actions/run-ci
with:
run: npm run test:i18n

# ── Native dependency coherence ──────────────────────────────────────────────
# Two versions of one native module resolve fine for npm and compile fine for
# Xcode, then abort at launch in dyld with "Symbol not found" — a pod built
# against one version of a shared dependency against a different version of it
# bundled. TestFlight build 173 shipped that way (expo-camera 57.0.1 against
# expo-modules-core 57.0.7) and crashed on every launch with a green CI.
# `expo-doctor` catches the duplicate at the npm level in seconds, on Linux;
# `scripts/verify-dyld-symbols.sh` is the belt-and-braces check at ship time.
native-deps:
name: Native deps
runs-on: ubuntu-latest
needs: [gate, setup]
steps:
- uses: actions/checkout@v5

- name: Duplicate native modules
if: needs.gate.outputs.skip != 'true'
uses: ./.github/actions/run-ci
with:
run: npm run check:native-deps

# ── Maestro E2E (iOS sim, monthly schedule only) ─────────────────────────────
# Runs once per month (00:00 UTC on the 1st) via the schedule trigger above.
# The macOS runner + iOS app build is ~15 minutes and ~$3/run, so this acts
Expand Down
54 changes: 54 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,60 @@ The `[skip-ci]` suffix keeps CI from re-triggering on the bump-only commit. Neve
- Before running any EAS build or submit command, stop and ask the user to confirm — do not proceed automatically
- Never trigger it as a side-effect of a "ship" or "commit and ship" request

---

## PR Titles & Branches

Derived from the dominant pattern in PRs created 2026-07-19 → 2026-07-24
(e.g. `#348`–`#394`, `#368`, `#376`, `#378`–`#393`). Prefer this over ad-hoc
formats. Never mention Cursor, Codex, Claude, or other AI tooling in the title,
branch name, body, or commit message.

### Title format

```
type(scope): imperative summary
```

- **type** — one of: `feat`, `fix`, `chore`, `docs`, `test`, `ci`, `perf`, `refactor`
- **scope** — optional but preferred when clear (`session`, `terminal`, `conversation`,
`onboarding`, `servers`, `ios`, `ci`, `deps`, `e2e`, `i18n`, …)
- **summary** — imperative, lowercase start, no trailing period; describe the
user-visible or operational change, not the implementation dump

Examples from recent history:

- `feat(conversation): add in-chat search entry on detail screen`
- `fix(terminal): fall back to HTTP output when WS replay is blank`
- `chore(ios): bump build number to 171 [skip-ci]`
- `docs(session): correct hold_session comments to describe grace-timer behavior`
- `test(e2e): wire server drag-reorder into the mock Maestro suite`
- `ci: gate locale parity and dead keys with an i18n job` (scope may be omitted)

Version-bump PRs keep the `[skip-ci]` suffix. Dependabot-style titles stay as
`chore(deps): …`.

Do **not** use bracket-slug titles like `[feat][task-name]` for new PRs — that
was a short-lived experiment and does not match the repo’s established style.

### Branch format

```
type/kebab-case-summary
```

Match the title’s type. Examples: `feat/in-chat-search`,
`fix/terminal-empty-replay-fallback`, `chore/bump-ios-version-171`,
`docs/hold-session-comments`. Never prefix with tool names (`cursor/…`, `cc/…`).

### Base branch (this integration wave)

For work targeting the current integration line, open PRs against
`integration-merge-354-355-376` (not `main`). Rebase onto the latest tip of that
branch before merge. Squash title must still follow `type(scope): summary`.

---

## Merging PRs — Rebase + Squash, Linear History

Keep `main` a straight line — one commit per PR, no merge commits. Every PR follows the same two operations, in this order:
Expand Down
68 changes: 68 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ When adding new Maestro flows:

---

## Jest — Confirm Suite Failures in Isolation

The `SessionScreen.*` suites are heavy enough that jest's parallel workers oversubscribe some machines, so a batch run can report failures that aren't real. Verify them serially:

```bash
npx jest --ci --runInBand --testPathPattern "SessionScreen"
```

**Never classify a batch failure without re-running that suite alone** — a load artifact and a genuine defect are indistinguishable in batch output. Passes alone → artifact. Fails alone → real, fix it. Both mistakes are easy: during the 2026-07-22 integration snapshot four genuinely broken suites were nearly dismissed as flakes, while two others really were artifacts.

The load-sensitive suites, the `.claude/` worktree gotcha (`npx jest` finds **0 tests** there), and their fixes are documented in [`docs/troubleshooting.md`](./docs/troubleshooting.md) → "Jest test suites".

---

## Comments — Non-Trivial Only

Never add comments that restate what the code already says. Only comment when the code is complex, non-obvious, or would surprise a reader without context.
Expand Down Expand Up @@ -173,6 +187,60 @@ To validate a build from one of these tags before merging, run the `Deploy` work

---

---

## PR Titles & Branches

Derived from the dominant pattern in PRs created 2026-07-19 → 2026-07-24
(e.g. `#348`–`#394`, `#368`, `#376`, `#378`–`#393`). Prefer this over ad-hoc
formats. Never mention Cursor, Codex, Claude, or other AI tooling in the title,
branch name, body, or commit message.

### Title format

```
type(scope): imperative summary
```

- **type** — one of: `feat`, `fix`, `chore`, `docs`, `test`, `ci`, `perf`, `refactor`
- **scope** — optional but preferred when clear (`session`, `terminal`, `conversation`,
`onboarding`, `servers`, `ios`, `ci`, `deps`, `e2e`, `i18n`, …)
- **summary** — imperative, lowercase start, no trailing period; describe the
user-visible or operational change, not the implementation dump

Examples from recent history:

- `feat(conversation): add in-chat search entry on detail screen`
- `fix(terminal): fall back to HTTP output when WS replay is blank`
- `chore(ios): bump build number to 171 [skip-ci]`
- `docs(session): correct hold_session comments to describe grace-timer behavior`
- `test(e2e): wire server drag-reorder into the mock Maestro suite`
- `ci: gate locale parity and dead keys with an i18n job` (scope may be omitted)

Version-bump PRs keep the `[skip-ci]` suffix. Dependabot-style titles stay as
`chore(deps): …`.

Do **not** use bracket-slug titles like `[feat][task-name]` for new PRs — that
was a short-lived experiment and does not match the repo’s established style.

### Branch format

```
type/kebab-case-summary
```

Match the title’s type. Examples: `feat/in-chat-search`,
`fix/terminal-empty-replay-fallback`, `chore/bump-ios-version-171`,
`docs/hold-session-comments`. Never prefix with tool names (`cursor/…`, `cc/…`).

### Base branch (this integration wave)

For work targeting the current integration line, open PRs against
`integration-merge-354-355-376` (not `main`). Rebase onto the latest tip of that
branch before merge. Squash title must still follow `type(scope): summary`.

---

## Merging PRs — Rebase + Squash, Linear History

Keep `main` a straight line — one commit per PR, no merge commits. Every PR follows the same two operations, in this order:
Expand Down
71 changes: 71 additions & 0 deletions KICKOFF-landing-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Kick-off — build the landing runbook for the mobile PR chain

**Run this from the `merge-prs-v2` worktree** (`integration-dev/v1.0.0-2026-07-22`) so every path below is relative. Paste the section below into a fresh session.

---

Create a landing runbook for this repo's open PR chain — the procedure for merging the 20 open PRs onto `main` one at a time, without re-hitting the documented conflicts or the traps that produce a green signal.

**Format to follow:** `docs/runbooks/_template.md`. Read it first; it opens with the seven rules its sections encode. `docs/runbooks/_example-streamer-land-open-prs.md` is the same template filled in for another repo — use it to see the shape of a finished runbook, but its PR numbers and paths are not ours. `docs/runbooks/README.md` explains why runbooks and merge reports are separate files.

**Source material:** `docs/integration-merge-report-2026-07-22.md`. It is a **run log**: Run 2 is current, **Run 1 is superseded** — do not carry Run 1's resolutions forward. Link to the report by conflict letter (A–I); do not restate it.

**Write to** `docs/runbooks/2026-07-22-land-open-prs.md`.

## Decide these before writing the order

**`#355` — close as superseded by `#354` (investigated, not an open question).** Both PRs are the mobile counterpart to streamer #253 and deliver the **same** live-session capability — the core feature files (`useConversationStream.ts`, `mergeLiveMessages.ts`, `lib/externalSession.ts`, `app/conversation/[id].tsx`) are byte-identical between the two tips. #355 is the *integration-testing twin*: authored on the superseded `bfc800d-2026-07-20` snapshot, so it carries pre-formed cross-PR glue — the #341∪#354 union in `services/api-client.ts` (conflict A) and #339/#341's `cache_alert` frames in `services/ws-client.ts` — that #354 lacks. That glue is only valid on a base that already has #341, and re-forms as conflict A when #341 and #354 both land on `main`; it is **not** live-session functionality. #354 is the one to land: it targets `main` and additionally carries the ar/he/ru take-over translations #355 is missing (`takeOver` keys in `locales/ar/conversation.json`: #354 has 2, #355 has 0). Closing #355 loses no capability — verified by an end-to-end contract trace: every WS event (`conversation_event`, `conversation_events`, `conversation_updated`), type (`ownership`, `processLiveness`) and error code (`CONVERSATION_BUSY`) that streamer #253 emits is consumed by #354. Re-verify before acting: if #355 has been rebased since, re-run the comparison.

**`#291`** (typescript 6→7) is excluded by request.

**Count:** 21 PRs are open and **20** are merged into the snapshot. The report's merge-log table lists only **19** — `#372` (`docs/jest-suite-verification`) is merged and named in the prose but missing from the table. Confirm against `git log --merges origin/main..HEAD` and make the runbook authoritative.

## Stacked pairs

`#341` is based on `#339`, not `main` — identify this from `baseRefName`, never from PR number. The runbook needs both `--onto` rebases and the distinction between them: the one required whenever the parent is force-pushed or gains a commit, and the one required after the parent squash-merges (because the squash produces a commit git cannot match against the originals). Note that a stacked PR may not get full CI until its base is `main`.

## Treat every recorded resolution as perishable

The report demonstrates this itself: `#341`'s run-1 conflict across six files **disappeared** once its branch was rebased onto `#339`. Re-verify preconditions rather than applying resolutions blind — conflict A's resolution in particular depends on a byte-identical precondition the report states explicitly.

The same applies to the fixes pushed upstream during the run — `#346 b84f18c`, `#354 25c83b6` / `5b26bf7`, `#362 ec5260f` / `4c6a275`, `#343 393b9ca`. The runbook's correctness depends on them still being on those branches. Verify, and say in the runbook how to re-check.

## The centrepiece: traps that produce a green signal

**`#356` × `#360`** — a locale-key deletion git applies with **no conflict marker**. The report proves with `git merge-tree` in both directions that reordering does not help, and that the merge hands you a conflict *in the very file silently losing keys*, so it looks handled. What works: rebase, then merge only on a **fresh post-rebase green**, because Type check catches it (`lib/i18n.types.ts` makes a missing key a `TS2345`). This needs its own "Known traps" subsection with the exact post-merge check.

**`#354` × `#346`** — `#354`'s suite omits `useNavigation`; the screen only calls it once `#346` is present. Neither PR is wrong alone.

## Mechanics that must be stated

Worktree **outside `.claude/`** or jest silently finds 0 tests. Each worktree needs its own `npm ci` (~3 min). Verify heavy `SessionScreen` suites with `--runInBand`, and **re-run any single failure in isolation before calling it a flake** — this run had four genuine failures nearly dismissed as flakes and two real load artifacts, and batch output cannot distinguish them.

One post-merge action that is not a merge: **after `#368` lands, add `i18n` to the required status checks**, or the new job runs without being able to block anything.

## Also derive

- **Who should run it** — model *and* reasoning effort per phase, justified by what failure looks like rather than command difficulty. Raise effort where the failure mode is *absence*: the locale cluster (`#356`, `#357`, `#360`, `#362`) is where a clean merge silently deletes keys.
- **Stop points** — three lists: always-stop (irreversible/outward-facing), stop-because-this-isn't-the-described-situation, and explicitly **do-not-stop**. The third is what keeps the first two credible.
- **Pre-flight** — sweep all 21 PRs for `CONFLICTING` and red checks, and record what it catches. `gh pr view` must run **twice**: GitHub computes mergeability lazily and the first call only triggers it.

## Done when

Someone who has not read the merge report can land the chain from the runbook alone, and every trap that produces a green signal has an explicit "after merging X, check Y" step.

---

## Follow-up PRs opened after this kick-off (session-name display)

These are **not** part of the 20-PR chain this kick-off builds a runbook for — they are new work opened after, targeting `main` directly.
When you write `docs/runbooks/2026-07-22-land-open-prs.md`, carry this cross-repo chain into it as a separate "Follow-up PRs" section (do not fold them into the main order — different base, different set).

Fix: interactive Claude Code conversations carried no session name (the scanner only read the `slug` field, which the human REPL never writes), so mobile showed the project name in the list, the conversation view, and the live-session view instead of a real title.

| Order | Repo | PR | Branch | What it does |
|---|---|---|---|---|
| 1 | tb-scanner | [#53](https://github.com/RonenMars/threadbase-scanner/pull/53) | `fix/session-name-from-first-message` | Derive session name from the first user message when no `slug`. The data source. |
| 2 | tb-streamer | [#267](https://github.com/RonenMars/threadbase-streamer/pull/267) | `fix/emit-session-name` | Emit `session_name` in the conversation detail `meta` block. |
| 3 | tb-mobile | [#376](https://github.com/RonenMars/threadbase-mobile/pull/376) | `fix/session-name-display` | Read `session_name` in the list, conversation, and live-session views (user rename → session name → project name). |

**The mobile PR (#376) is safe to land alone** — it is additive and shows nothing new until the server pipeline (scanner #53 → scanner release → streamer dep bump → streamer #267) lands.
So the *visible* result is gated on the server side, but the merge order for correctness is only: land #376 whenever; the name simply stays blank until the upstream chain completes.
4 changes: 2 additions & 2 deletions __tests__/e2e/onboarding-flow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ describe('Onboarding – error handling', () => {
// ── First-launch flow ─────────────────────────────────────────────────────────

describe('Onboarding – first-launch flow', () => {
it('TOTAL_STEPS is 3', () => {
it('TOTAL_STEPS is 4', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { TOTAL_STEPS } = require('@/components/onboarding/OnboardingNavigator')
expect(TOTAL_STEPS).toBe(3)
expect(TOTAL_STEPS).toBe(4)
})
})
Loading
Loading