happy-stacks 0.6.8 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/commit-audits/happy/leeroy-wip.commit-inventory.md +1 -1
- package/docs/commit-audits/happy/leeroy-wip.commit-manual-review.md +140 -69
- package/docs/isolated-linux-vm.md +58 -12
- package/package.json +1 -1
- package/scripts/provision/linux-ubuntu-review-pr.sh +6 -2
- package/scripts/provision/macos-lima-happy-vm.sh +142 -0
- package/scripts/setup.mjs +25 -32
- package/scripts/stack.mjs +31 -18
|
@@ -45,7 +45,7 @@ Progress tracking (update manually while auditing):
|
|
|
45
45
|
- Next unreviewed commit: n/a (complete)
|
|
46
46
|
- Pass 2 full-diff verification markers: `249/249` (each `## NNN` has a `Pass2FullDiff:` line; patch artifacts under `/tmp/leeroy-wip-pass2/NNN.patch`)
|
|
47
47
|
- Pass 2 diff capture: `249/249` (`/tmp/leeroy-wip-pass2/NNN.patch` exists; hash/size recorded in each `Pass2FullDiff:` line)
|
|
48
|
-
- Pass 2 notes verification (manual): `
|
|
48
|
+
- Pass 2 notes verification (manual): `83/249` (this requires reading the patch and confirming/updating `### Manual Review Notes`)
|
|
49
49
|
|
|
50
50
|
Current state (2026-01-24):
|
|
51
51
|
|
|
@@ -896,7 +896,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=21cc6df79f50 patchFile=/
|
|
|
896
896
|
---
|
|
897
897
|
|
|
898
898
|
## 026 2026-01-18 ce9cd74d408a `machine`
|
|
899
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ce9cd74d408a patchFile=/tmp/leeroy-wip-pass2/026.patch patchSha256=9eb86cc637175c0ef4d31c6afa1cf75fd4466f1102c09b699aa4575dc94609a8 patchBytes=56472 patchLines=1341 notesReviewed=
|
|
899
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ce9cd74d408a patchFile=/tmp/leeroy-wip-pass2/026.patch patchSha256=9eb86cc637175c0ef4d31c6afa1cf75fd4466f1102c09b699aa4575dc94609a8 patchBytes=56472 patchLines=1341 notesReviewed=yes reviewedAt=2026-01-24T18:37:32+0100 notesUpdated=no
|
|
900
900
|
|
|
901
901
|
- Subject: feat(machine): surface detected CLI status
|
|
902
902
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -935,7 +935,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ce9cd74d408a patchFile=/
|
|
|
935
935
|
---
|
|
936
936
|
|
|
937
937
|
## 027 2026-01-18 7899bbd8433e `profiles`
|
|
938
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7899bbd8433e patchFile=/tmp/leeroy-wip-pass2/027.patch patchSha256=1d66ea8afae399b1edfb23f0f1eba7203a6aed9c625784e90764da0c29ddaeab patchBytes=95110 patchLines=1988 notesReviewed=
|
|
938
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7899bbd8433e patchFile=/tmp/leeroy-wip-pass2/027.patch patchSha256=1d66ea8afae399b1edfb23f0f1eba7203a6aed9c625784e90764da0c29ddaeab patchBytes=95110 patchLines=1988 notesReviewed=yes reviewedAt=2026-01-24T18:40:29+0100 notesUpdated=yes
|
|
939
939
|
|
|
940
940
|
- Subject: feat(profiles): add API key requirements flow
|
|
941
941
|
- Reasons: safety/security-sensitive area
|
|
@@ -964,6 +964,11 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7899bbd8433e patchFile=/
|
|
|
964
964
|
- Adds `ProfileRequirementsBadge.tsx` and `useProfileEnvRequirements` integration in profile list UIs.
|
|
965
965
|
- Updates `ProfilesList` / `profileListModel` to show requirement state and open the modal.
|
|
966
966
|
- Updates profiles settings screen to use `ProfilesList` and pass `onApiKeyBadgePress`.
|
|
967
|
+
- Adds profile-side authoring UI for requirements:
|
|
968
|
+
- Introduces a reusable tile selector (`OptionTiles.tsx`) and uses it in `ProfileEditForm.tsx` to edit `authMode` (`none|apiKeyEnv|machineLogin`).
|
|
969
|
+
- For `authMode=apiKeyEnv`, allows editing the required secret env-var name (uppercased, validated against `^[A-Z_][A-Z0-9_]*$`).
|
|
970
|
+
- For `authMode=machineLogin`, integrates `useCLIDetection(..., { includeLoginStatus: true })` so the UI can display machine login state per backend when a preview machine is selected.
|
|
971
|
+
- Note: the current “Logged in / Not logged in” text is hardcoded (not `t(...)`) and should be localized in a clean history rewrite.
|
|
967
972
|
- Security note: the design intentionally avoids fetching or displaying secret values when checking machine readiness; the only time a raw value enters UI memory is the “enter once” path, which uses `secureTextEntry` and returns the value to the caller.
|
|
968
973
|
|
|
969
974
|
### Verdict
|
|
@@ -981,7 +986,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7899bbd8433e patchFile=/
|
|
|
981
986
|
---
|
|
982
987
|
|
|
983
988
|
## 028 2026-01-18 0023ba1ea5aa `i18n`
|
|
984
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=0023ba1ea5aa patchFile=/tmp/leeroy-wip-pass2/028.patch patchSha256=81df78affd393e71a4019a9053bb8432ff7bc0689c208e6e45b9d291f6fbdcc3 patchBytes=245409 patchLines=4739 notesReviewed=
|
|
989
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=0023ba1ea5aa patchFile=/tmp/leeroy-wip-pass2/028.patch patchSha256=81df78affd393e71a4019a9053bb8432ff7bc0689c208e6e45b9d291f6fbdcc3 patchBytes=245409 patchLines=4739 notesReviewed=yes reviewedAt=2026-01-24T18:44:46+0100 notesUpdated=yes
|
|
985
990
|
|
|
986
991
|
- Subject: refactor(i18n): update translations and tooling
|
|
987
992
|
- Reasons: large change (+2913/-143)
|
|
@@ -989,10 +994,22 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=0023ba1ea5aa patchFile=/
|
|
|
989
994
|
### Manual Review Notes
|
|
990
995
|
|
|
991
996
|
- Expands translation coverage and improves i18n tooling:
|
|
992
|
-
- Updates `expo-app/sources/text/translations/*` across
|
|
993
|
-
- Updates
|
|
994
|
-
|
|
995
|
-
-
|
|
997
|
+
- Updates `expo-app/sources/text/translations/*` across many locales with a large batch of keys (net +2913/-143).
|
|
998
|
+
- Updates `expo-app/sources/scripts/compareTranslations.ts`:
|
|
999
|
+
- includes `it` + `ja` in the translation set and language name map
|
|
1000
|
+
- fixes missing newline at EOF
|
|
1001
|
+
- Adds `expo-app/sources/scripts/findUntranslatedLiterals.ts` (AST-based, `tsx` shebang):
|
|
1002
|
+
- Walks `expo-app/sources/**` and parses files via TypeScript compiler API.
|
|
1003
|
+
- Reports likely user-facing string literals in:
|
|
1004
|
+
- JSX text nodes (`<Text>Some string</Text>`)
|
|
1005
|
+
- selected JSX attributes (e.g. `title`, `description`, `placeholder`, etc.)
|
|
1006
|
+
- string args to likely UI calls (heuristic: `*.alert|confirm|prompt`, `Toast*`, `*Modal*`), excluding `t(...)` calls
|
|
1007
|
+
- Uses ignore heuristics to suppress likely non-user-facing strings (URLs, env keys, ids/paths, hex colors, numeric strings, punctuation-only).
|
|
1008
|
+
- Ignores translation files and scripts as scan targets to keep noise down; groups results by kind + literal and prints occurrences with context.
|
|
1009
|
+
- Translation content notes (from full diff):
|
|
1010
|
+
- Adds UI copy for a lot of new surface area: machine refresh/rename/stop-daemon flows, session-type + profile selection flows, CLI-not-detected banners, action menu labels, voice assistant states, Zen screens, artifacts errors, API keys UI, and profile requirements/machine-login help text.
|
|
1011
|
+
- Many locales still leave some newly introduced experimental feature subtitles in English (e.g. `expGeminiSubtitle`, `expUsageReporting*`, etc.). This commit improves coverage overall, but does not fully localize those strings.
|
|
1012
|
+
- This commit is large but remains “content + dev tooling”; runtime behavior changes are limited to updated strings and additional translation keys.
|
|
996
1013
|
|
|
997
1014
|
### Verdict
|
|
998
1015
|
|
|
@@ -1008,7 +1025,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=0023ba1ea5aa patchFile=/
|
|
|
1008
1025
|
---
|
|
1009
1026
|
|
|
1010
1027
|
## 029 2026-01-18 12e75a3b36fa `autocomplete`
|
|
1011
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=12e75a3b36fa patchFile=/tmp/leeroy-wip-pass2/029.patch patchSha256=57c5e6fd7a385743a42b43fa45b1e5f0c44b6838324c98a2ce1bdba1b065b90b patchBytes=1469 patchLines=29 notesReviewed=
|
|
1028
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=12e75a3b36fa patchFile=/tmp/leeroy-wip-pass2/029.patch patchSha256=57c5e6fd7a385743a42b43fa45b1e5f0c44b6838324c98a2ce1bdba1b065b90b patchBytes=1469 patchLines=29 notesReviewed=yes reviewedAt=2026-01-24T18:45:28+0100 notesUpdated=no
|
|
1012
1029
|
|
|
1013
1030
|
- Subject: fix(autocomplete): remove debug suggestion logs
|
|
1014
1031
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1032,7 +1049,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=12e75a3b36fa patchFile=/
|
|
|
1032
1049
|
---
|
|
1033
1050
|
|
|
1034
1051
|
## 030 2026-01-18 679877c26ea9 `settings`
|
|
1035
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=679877c26ea9 patchFile=/tmp/leeroy-wip-pass2/030.patch patchSha256=66c3233690e649ede180f88795c4c1bf4f37c94fc7002111fe2d562f01e2cfd1 patchBytes=7337 patchLines=136 notesReviewed=
|
|
1052
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=679877c26ea9 patchFile=/tmp/leeroy-wip-pass2/030.patch patchSha256=66c3233690e649ede180f88795c4c1bf4f37c94fc7002111fe2d562f01e2cfd1 patchBytes=7337 patchLines=136 notesReviewed=yes reviewedAt=2026-01-24T18:46:01+0100 notesUpdated=no
|
|
1036
1053
|
|
|
1037
1054
|
- Subject: feat(settings): expose per-experiment toggles
|
|
1038
1055
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1060,7 +1077,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=679877c26ea9 patchFile=/
|
|
|
1060
1077
|
---
|
|
1061
1078
|
|
|
1062
1079
|
## 031 2026-01-18 4dc9c7f8759c `agent-input`
|
|
1063
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4dc9c7f8759c patchFile=/tmp/leeroy-wip-pass2/031.patch patchSha256=c738387880e6ad1b5393546c91d12cfe32ba1a05595053edbe8949de232e8e11 patchBytes=51158 patchLines=831 notesReviewed=
|
|
1080
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4dc9c7f8759c patchFile=/tmp/leeroy-wip-pass2/031.patch patchSha256=c738387880e6ad1b5393546c91d12cfe32ba1a05595053edbe8949de232e8e11 patchBytes=51158 patchLines=831 notesReviewed=yes reviewedAt=2026-01-24T18:47:29+0100 notesUpdated=yes
|
|
1064
1081
|
|
|
1065
1082
|
- Subject: feat(agent-input): add configurable action bar layout
|
|
1066
1083
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1069,12 +1086,20 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4dc9c7f8759c patchFile=/
|
|
|
1069
1086
|
|
|
1070
1087
|
- Adds user-configurable “action bar layout” and “chip density” controls and wires them into the AgentInput layout:
|
|
1071
1088
|
- `settings/appearance.tsx`:
|
|
1089
|
+
- wraps screen in `React.memo(...)` (adds missing `React` import) and fixes missing newline at EOF.
|
|
1072
1090
|
- adds UI rows that cycle through `agentInputActionBarLayout` (`auto|wrap|scroll|collapsed`) and `agentInputChipDensity` (`auto|labels|icons`).
|
|
1073
1091
|
- `components/AgentInput.tsx`:
|
|
1074
1092
|
- reads the new settings and derives effective layout based on screen width when `auto`.
|
|
1075
1093
|
- adds support for “collapsed” layout mode (moves shortcuts into a compact row).
|
|
1076
|
-
-
|
|
1094
|
+
- for “scroll” layout:
|
|
1095
|
+
- always renders a horizontal `ScrollView` (even if not scrollable) so it can measure viewport/content widths (avoid “measurement deadlock”)
|
|
1096
|
+
- enables/disables scrolling based on whether the chips overflow
|
|
1097
|
+
- adds left/right gradient fades based on scroll position using `expo-linear-gradient` and `color` (computes a transparent version of the input background color)
|
|
1077
1098
|
- adjusts rendering based on chip density to reduce width pressure.
|
|
1099
|
+
- collapses action shortcuts into the settings overlay when `actionBarLayout=collapsed`, including:
|
|
1100
|
+
- profile/env/agent/machine/path shortcuts
|
|
1101
|
+
- file viewer (`agentInput.actionMenu.files`) and abort (`agentInput.actionMenu.stop`)
|
|
1102
|
+
- removes the `connectionStatus.cliStatus` UI “CLI: claude✓ …” line (and removes `cliStatus` from the `connectionStatus` prop type).
|
|
1078
1103
|
- Coherence: fits the subject (action bar layout + chip density).
|
|
1079
1104
|
|
|
1080
1105
|
### Verdict
|
|
@@ -1091,7 +1116,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4dc9c7f8759c patchFile=/
|
|
|
1091
1116
|
---
|
|
1092
1117
|
|
|
1093
1118
|
## 032 2026-01-18 e8e42a6087ad `modal`
|
|
1094
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e8e42a6087ad patchFile=/tmp/leeroy-wip-pass2/032.patch patchSha256=5e703a80cc8f7735a4b497cdcf15c3bcfb494780b2384d8980eb5c6133b8f00b patchBytes=10216 patchLines=231 notesReviewed=
|
|
1119
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e8e42a6087ad patchFile=/tmp/leeroy-wip-pass2/032.patch patchSha256=5e703a80cc8f7735a4b497cdcf15c3bcfb494780b2384d8980eb5c6133b8f00b patchBytes=10216 patchLines=231 notesReviewed=yes reviewedAt=2026-01-24T18:48:18+0100 notesUpdated=yes
|
|
1095
1120
|
|
|
1096
1121
|
- Subject: fix(modal): prevent stacked modal touch-blocking on iOS
|
|
1097
1122
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1109,6 +1134,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e8e42a6087ad patchFile=/
|
|
|
1109
1134
|
- `ModalManager.show(...)` accepts `closeOnBackdrop`
|
|
1110
1135
|
- `CustomModalConfig` documents it
|
|
1111
1136
|
- `CustomModal` passes it to `BaseModal` and invokes an optional `onRequestClose` callback for cleanup before closing (safe dynamic check).
|
|
1137
|
+
- Minor cleanup note (for rewritten history): `BaseModal` uses `behavior={Platform.OS === 'web' ? undefined : ((Platform as any).OS === 'ios' ? 'padding' : 'height')}` which could likely be simplified to avoid the `(Platform as any)` escape hatch.
|
|
1112
1138
|
- Coherence: strong; the subject matches and the changes are directly tied to stacked modal reliability.
|
|
1113
1139
|
|
|
1114
1140
|
### Verdict
|
|
@@ -1123,7 +1149,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e8e42a6087ad patchFile=/
|
|
|
1123
1149
|
---
|
|
1124
1150
|
|
|
1125
1151
|
## 033 2026-01-18 daa0b4527d7f `new-session`
|
|
1126
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=daa0b4527d7f patchFile=/tmp/leeroy-wip-pass2/033.patch patchSha256=df9457db150e945395c07246fa6b0e64771d9fbdd764092e42dbaaeefb97fb36 patchBytes=187624 patchLines=3256 notesReviewed=
|
|
1152
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=daa0b4527d7f patchFile=/tmp/leeroy-wip-pass2/033.patch patchSha256=df9457db150e945395c07246fa6b0e64771d9fbdd764092e42dbaaeefb97fb36 patchBytes=187624 patchLines=3256 notesReviewed=yes reviewedAt=2026-01-24T18:52:09+0100 notesUpdated=yes
|
|
1127
1153
|
|
|
1128
1154
|
- Subject: feat(new-session): add api key selection and wizard extraction
|
|
1129
1155
|
- Reasons: large change (+1719/-1116)
|
|
@@ -1134,15 +1160,26 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=daa0b4527d7f patchFile=/
|
|
|
1134
1160
|
- Adds `expo-app/sources/app/(app)/new/NewSessionWizard.tsx`:
|
|
1135
1161
|
- Large extracted component with explicit prop groups (`layout`, `profiles`, `agent`, `machine`, `footer`) to separate rendering from orchestration/state in `new/index.tsx`.
|
|
1136
1162
|
- Adds props for API key resolution state (`sessionOnlyApiKeyValue`, `selectedSavedApiKeyValue`, `apiKeyPreflightIsReady`) and a callback to open the requirement modal.
|
|
1163
|
+
- Adds “missing CLI” banners (claude/codex/gemini), model selection, machine/path/permission selection, and optional session-type section; keeps `AgentInput` sticky with a top fade divider gradient.
|
|
1137
1164
|
- Updates `expo-app/sources/app/(app)/new/index.tsx` to:
|
|
1138
1165
|
- Own API key selection state (session-only vs saved key) and drive the wizard via props.
|
|
1139
1166
|
- Provide `openApiKeyRequirementModal(...)` and manage “auto-prompt suppression” to avoid repeatedly nagging.
|
|
1167
|
+
- Adds persisted `selectedApiKeyId` to the draft and introduces `apiKeys` + `defaultApiKeyByProfileId` settings usage; uses `selectedApiKeyId === ''` as an explicit “do not auto-apply default key” sentinel when the user chooses machine env / session-only.
|
|
1168
|
+
- Adds spawn-time secret overlay injection: for `authMode=apiKeyEnv` profiles, if a saved key or session-only key is selected, injects it into `environmentVariables[requiredSecretEnvVarName]` before creating the session; errors if neither injected key nor machine env satisfies requirements.
|
|
1169
|
+
- Improves iOS responsiveness:
|
|
1170
|
+
- defers synchronous MMKV draft writes via `InteractionManager.runAfterInteractions` (and longer debounce delay on native)
|
|
1171
|
+
- refreshes machines on focus (throttled) after interactions
|
|
1172
|
+
- switches `useCLIDetection(selectedMachineId, { autoDetect: false })` and uses cache-prefetch helpers to avoid network work on tap handlers
|
|
1173
|
+
- Removes `connectionStatus.cliStatus` usage (aligns with AgentInput removing that UI in commit 031).
|
|
1140
1174
|
- Upgrades the profile picker `expo-app/sources/app/(app)/new/pick/profile.tsx` to support API-key gating:
|
|
1141
1175
|
- Adds route-param plumbing to return `{ profileId, apiKeyId?, apiKeySessionOnlyId? }` to the previous screen.
|
|
1142
1176
|
- For `authMode === 'apiKeyEnv'` profiles, it preflights the required secret on the selected machine using `machinePreviewEnv(...)` with `extraEnv` and `sensitiveKeys`.
|
|
1143
1177
|
- If the machine lacks the key and no default saved key exists, it opens `ApiKeyRequirementModal`.
|
|
1144
1178
|
- If a default saved key exists, it auto-applies it (still overrideable later).
|
|
1145
1179
|
- For session-only keys, it stores the entered secret in temp storage and passes back a temp id.
|
|
1180
|
+
- Refactors profile picker UI to reuse `ProfilesList` (instead of re-implementing favorites/custom/built-in grouping and row actions inline).
|
|
1181
|
+
- Adjusts `expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx` so Gemini glyphs depend on `experiments && expGemini` (not just the master experiments toggle).
|
|
1182
|
+
- i18n/reliability note (for rewritten history): some user-facing strings in the extracted wizard remain hardcoded English (e.g. `MachineSelector` search placeholder `"Search machines..."`, permission-mode descriptions like `"Read-only mode"`, and the missing API key alert text). These should be moved to `t(...)` keys in the final cleaned history.
|
|
1146
1183
|
- Coherence note: this commit logically stacks on top of the “profile requirements” work (required env var metadata, preview-env support, and ApiKeyRequirementModal).
|
|
1147
1184
|
|
|
1148
1185
|
### Verdict
|
|
@@ -1160,7 +1197,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=daa0b4527d7f patchFile=/
|
|
|
1160
1197
|
---
|
|
1161
1198
|
|
|
1162
1199
|
## 034 2026-01-18 94814465bf81 `sync`
|
|
1163
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=94814465bf81 patchFile=/tmp/leeroy-wip-pass2/034.patch patchSha256=09e85cfc752e6ba9790b2a35f926bc0242b79eeba4b258d26079e985caece0a7 patchBytes=5326 patchLines=136 notesReviewed=
|
|
1200
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=94814465bf81 patchFile=/tmp/leeroy-wip-pass2/034.patch patchSha256=09e85cfc752e6ba9790b2a35f926bc0242b79eeba4b258d26079e985caece0a7 patchBytes=5326 patchLines=136 notesReviewed=yes reviewedAt=2026-01-24T18:53:41+0100 notesUpdated=no
|
|
1164
1201
|
|
|
1165
1202
|
- Subject: perf(sync): debounce pending settings writes
|
|
1166
1203
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1191,7 +1228,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=94814465bf81 patchFile=/
|
|
|
1191
1228
|
---
|
|
1192
1229
|
|
|
1193
1230
|
## 035 2026-01-18 7ffd0c3428cb `ui`
|
|
1194
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7ffd0c3428cb patchFile=/tmp/leeroy-wip-pass2/035.patch patchSha256=80e3faea4b996f40de251ffcb9a01d834711f4f7cd547a039bfff2017d11f59c patchBytes=1771 patchLines=39 notesReviewed=
|
|
1231
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7ffd0c3428cb patchFile=/tmp/leeroy-wip-pass2/035.patch patchSha256=80e3faea4b996f40de251ffcb9a01d834711f4f7cd547a039bfff2017d11f59c patchBytes=1771 patchLines=39 notesReviewed=yes reviewedAt=2026-01-24T18:54:29+0100 notesUpdated=no
|
|
1195
1232
|
|
|
1196
1233
|
- Subject: fix(ui): localize error alerts
|
|
1197
1234
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1216,7 +1253,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7ffd0c3428cb patchFile=/
|
|
|
1216
1253
|
---
|
|
1217
1254
|
|
|
1218
1255
|
## 036 2026-01-18 97ca69e0a735 `i18n`
|
|
1219
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=97ca69e0a735 patchFile=/tmp/leeroy-wip-pass2/036.patch patchSha256=d4e60307db035e91b99d59b7b132811586a8129b313005bf226fb69356c692b8 patchBytes=26606 patchLines=559 notesReviewed=
|
|
1256
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=97ca69e0a735 patchFile=/tmp/leeroy-wip-pass2/036.patch patchSha256=d4e60307db035e91b99d59b7b132811586a8129b313005bf226fb69356c692b8 patchBytes=26606 patchLines=559 notesReviewed=yes reviewedAt=2026-01-24T18:55:47+0100 notesUpdated=yes
|
|
1220
1257
|
|
|
1221
1258
|
- Subject: refactor(i18n): replace remaining UI literals
|
|
1222
1259
|
- Reasons: safety/security-sensitive area
|
|
@@ -1226,6 +1263,9 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=97ca69e0a735 patchFile=/
|
|
|
1226
1263
|
- Replaces remaining hard-coded UI strings with translation keys across multiple screens/components (19 files; small diff):
|
|
1227
1264
|
- General UI empty states / connect flows / command palette / message view / voice status bar / markdown renderers / usage chart.
|
|
1228
1265
|
- Notable safety-adjacent change: `expo-app/sources/utils/microphonePermissions.ts` now uses `t(...)` for permission-denied alerts (titles, body, and button labels) including web-specific instructions.
|
|
1266
|
+
- Coherence note: despite the i18n-only subject, this commit also changes behavior in `expo-app/sources/components/MessageView.tsx`:
|
|
1267
|
+
- thinking messages are now hidden unless `experiments && expShowThinkingMessages` (previously gated only by `experiments`).
|
|
1268
|
+
- In a rewritten history, this should likely be split so the per-experiment gating change lands with the rest of the experiments-toggle wiring (e.g. commits 024/030), not inside an i18n sweep.
|
|
1229
1269
|
- No functional behavior change intended beyond string sources; correctness depends on translation keys existing and being accurate.
|
|
1230
1270
|
|
|
1231
1271
|
### Verdict
|
|
@@ -1240,7 +1280,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=97ca69e0a735 patchFile=/
|
|
|
1240
1280
|
---
|
|
1241
1281
|
|
|
1242
1282
|
## 037 2026-01-18 5f5b57df5181 `ui`
|
|
1243
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=5f5b57df5181 patchFile=/tmp/leeroy-wip-pass2/037.patch patchSha256=61cb1063e70f82b42af8fb8dfedb96e14fb3153f000de76a2ccbd9dabbc5c326 patchBytes=6661 patchLines=145 notesReviewed=
|
|
1283
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=5f5b57df5181 patchFile=/tmp/leeroy-wip-pass2/037.patch patchSha256=61cb1063e70f82b42af8fb8dfedb96e14fb3153f000de76a2ccbd9dabbc5c326 patchBytes=6661 patchLines=145 notesReviewed=yes reviewedAt=2026-01-24T18:57:14+0100 notesUpdated=no
|
|
1244
1284
|
|
|
1245
1285
|
- Subject: refactor(ui): improve item rendering and action menu timing
|
|
1246
1286
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1271,7 +1311,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=5f5b57df5181 patchFile=/
|
|
|
1271
1311
|
---
|
|
1272
1312
|
|
|
1273
1313
|
## 038 2026-01-18 7976b877259c `experiments`
|
|
1274
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7976b877259c patchFile=/tmp/leeroy-wip-pass2/038.patch patchSha256=81f96664a2da5fe1b098d2d3765dea96084948a68ec8bbd952ae7cd9b553a03a patchBytes=12038 patchLines=243 notesReviewed=
|
|
1314
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7976b877259c patchFile=/tmp/leeroy-wip-pass2/038.patch patchSha256=81f96664a2da5fe1b098d2d3765dea96084948a68ec8bbd952ae7cd9b553a03a patchBytes=12038 patchLines=243 notesReviewed=yes reviewedAt=2026-01-24T19:02:45+0100 notesUpdated=no
|
|
1275
1315
|
|
|
1276
1316
|
- Subject: feat(experiments): gate Zen, file viewer, and voice auth flow
|
|
1277
1317
|
- Reasons: safety/security-sensitive area
|
|
@@ -1316,7 +1356,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7976b877259c patchFile=/
|
|
|
1316
1356
|
---
|
|
1317
1357
|
|
|
1318
1358
|
## 039 2026-01-21 6ed379f82c34 `ui`
|
|
1319
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=6ed379f82c34 patchFile=/tmp/leeroy-wip-pass2/039.patch patchSha256=3ae4cad6fe7c831b911c1cb57135fbc7f0688022de1a42e0249e1980bb3e81da patchBytes=260667 patchLines=6344 notesReviewed=
|
|
1359
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=6ed379f82c34 patchFile=/tmp/leeroy-wip-pass2/039.patch patchSha256=3ae4cad6fe7c831b911c1cb57135fbc7f0688022de1a42e0249e1980bb3e81da patchBytes=260667 patchLines=6344 notesReviewed=yes reviewedAt=2026-01-24T19:06:52+0100 notesUpdated=no
|
|
1320
1360
|
|
|
1321
1361
|
- Subject: refactor(ui): add modal + popover overlay primitives
|
|
1322
1362
|
- Reasons: too many files (43)
|
|
@@ -1383,7 +1423,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=6ed379f82c34 patchFile=/
|
|
|
1383
1423
|
---
|
|
1384
1424
|
|
|
1385
1425
|
## 040 2026-01-21 f0787de5308e `sync`
|
|
1386
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f0787de5308e patchFile=/tmp/leeroy-wip-pass2/040.patch patchSha256=33c95731c921933829af09309c46e15d2de6d068618cf82ec5d1088cba2d8d84 patchBytes=184734 patchLines=4333 notesReviewed=
|
|
1426
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f0787de5308e patchFile=/tmp/leeroy-wip-pass2/040.patch patchSha256=33c95731c921933829af09309c46e15d2de6d068618cf82ec5d1088cba2d8d84 patchBytes=184734 patchLines=4333 notesReviewed=yes reviewedAt=2026-01-24T19:11:23+0100 notesUpdated=yes
|
|
1387
1427
|
|
|
1388
1428
|
- Subject: feat(sync): add secrets + terminal settings primitives
|
|
1389
1429
|
- Reasons: too many files (60); safety/security-sensitive area
|
|
@@ -1418,13 +1458,26 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f0787de5308e patchFile=/
|
|
|
1418
1458
|
- **Cross-platform crypto shims (node/vitest-safe)**
|
|
1419
1459
|
- Adds `platform/*.{ts,node.ts}` shims for `cryptoRandom`, `digest`, `hmacSha512`, and `randomUUID` so code can run in vitest/node without static `expo-crypto` imports.
|
|
1420
1460
|
- Updates `utils/oauth.ts` PKCE generation to use the shims (`digest('SHA-256', ...)` etc).
|
|
1461
|
+
- Migrates several existing crypto call sites (AES/Base64 app specs, libsodium helper, artifact encryption) from `expo-crypto` static imports to the platform shims.
|
|
1462
|
+
- **API/client error typing (HappyError)**
|
|
1463
|
+
- Extends `utils/errors.ts` (`HappyError`) with optional `status` and `kind` to support richer UX + sync retry policy.
|
|
1464
|
+
- Updates multiple API modules (`apiArtifacts`, `apiFeed`, `apiFriends`, `apiGithub`, `apiKv`, `apiPush`, `apiServices`, `apiUsage`) to throw non-retryable `HappyError(...)` for most 4xx responses (excluding `408` and `429`), and to preserve “auth/config” kinds where it’s known (notably GitHub + usage endpoints).
|
|
1421
1465
|
- **Sync reliability / observability additions**
|
|
1422
1466
|
- `sync/sync.ts` + `sync/storage.ts`: adds `syncError` state, socket error fields, and a `lastSyncAt` timestamp; wires `InvalidateSync` hooks to set/clear error state and retry metadata.
|
|
1423
1467
|
- `sync/debugSettings.ts` + settingsParse logging: adds optional debug logging for settings parse/apply flows.
|
|
1424
1468
|
- `applySettings` now avoids no-op writes by shallowly checking whether the delta changes references/scalars before persisting.
|
|
1469
|
+
- `apiSocket`: adds explicit `onError` listeners and clears last error on successful connect; `syncInit` wires socket errors into `syncError`.
|
|
1470
|
+
- `utils/time.ts` + `utils/sync.ts`: extends `createBackoff` with `shouldRetry` + `onRetry` hooks (and safer backoff math), and reworks `InvalidateSync` / `ValueSync` to use backoff with explicit onSuccess/onError/onRetry reporting (avoids deadlocking the invalidation queue on non-retryable errors).
|
|
1471
|
+
- **Terminal metadata + helpers**
|
|
1472
|
+
- `storageTypes.ts`: extends `MetadataSchema` with a `terminal` payload (`plain|tmux`, requested mode, fallback reason, tmux target/tmpDir) and adds a parsing test.
|
|
1473
|
+
- Adds `utils/terminalSessionDetails.ts` (+ tests) for deriving attach commands and tmux-specific metadata in the UI.
|
|
1425
1474
|
- **Notable schema/migration shifts**
|
|
1426
1475
|
- `sync/settings.ts`: drops support for legacy provider config objects (e.g. `openaiConfig`, `anthropicConfig`) by removing the normalization/migration step; profiles are expected to use `environmentVariables` + `envVarRequirements`.
|
|
1427
1476
|
- `getProfileEnvironmentVariables` no longer injects tmux env vars; terminal spawning is now driven by terminal settings (global/per-machine), not profile tmux config.
|
|
1477
|
+
- `AIBackendProfileSchema`: removes the `apiKeyEnv` authMode and drops per-profile `tmuxConfig`; profiles now express runtime requirements only via `envVarRequirements` (with `required`), and terminal spawning is controlled by the terminal settings primitives.
|
|
1478
|
+
- **Misc wiring changes**
|
|
1479
|
+
- `profileRouteParams.ts`: renames `consumeApiKeyIdParam` → `consumeSecretIdParam` to match the secrets UI routing.
|
|
1480
|
+
- `sync/reducer.ts`: compares `allowedTools` arrays with “empty-equivalence” semantics (`undefined` / `null` / `[]`) to reduce false-positive updates; tests updated to assert “no duplicates” instead of “no updates”.
|
|
1428
1481
|
- Risk notes:
|
|
1429
1482
|
- Secrets safety hinges on `settingsSecretsKey` being available: `sealSecretsDeep` is a no-op when the key is null. This is probably correct for “not authenticated yet” states, but it means UI flows should avoid accepting/committing secrets until the key exists (or ensure key derivation always succeeds for authenticated users).
|
|
1430
1483
|
- The removal of legacy provider config migration should be validated against any existing persisted settings formats before upstreaming (it’s a behavior compatibility change).
|
|
@@ -1452,7 +1505,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f0787de5308e patchFile=/
|
|
|
1452
1505
|
---
|
|
1453
1506
|
|
|
1454
1507
|
## 041 2026-01-21 66ee1eaf88a6 `secrets`
|
|
1455
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66ee1eaf88a6 patchFile=/tmp/leeroy-wip-pass2/041.patch patchSha256=afe787a1ab3f76435191f29d469da5336cc1cdbd7be45b44dbf894bd27538a4e patchBytes=285675 patchLines=5209 notesReviewed=
|
|
1508
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66ee1eaf88a6 patchFile=/tmp/leeroy-wip-pass2/041.patch patchSha256=afe787a1ab3f76435191f29d469da5336cc1cdbd7be45b44dbf894bd27538a4e patchBytes=285675 patchLines=5209 notesReviewed=yes reviewedAt=2026-01-24T19:17:58+0100 notesUpdated=yes
|
|
1456
1509
|
|
|
1457
1510
|
- Subject: feat(secrets): add secrets management + requirement resolver
|
|
1458
1511
|
- Reasons: too many files (29); safety/security-sensitive area
|
|
@@ -1491,6 +1544,8 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66ee1eaf88a6 patchFile=/
|
|
|
1491
1544
|
- Minor theme token tweaks to support the new UI.
|
|
1492
1545
|
- **Other notable changes mixed in**
|
|
1493
1546
|
- `settings/features.tsx` is reorganized (standard toggles first, experiments last) and introduces web-only toggles for “enter to send” and “command palette”. This is plausibly related, but it’s still a separate “settings UX” concern that may be worth splitting during rewrite.
|
|
1547
|
+
- `hooks/useEnvironmentVariables.ts` switches to `useLayoutEffect` (web) to ensure `isLoading=true` flips before consumer `useEffect` runs, preventing a “missing secret” race; adds a focused hook test.
|
|
1548
|
+
- `components/profiles/*`: adds `getProfileDisplayName` (built-in profiles use localized names), changes badge behavior via `ProfileRequirementsBadge` overrides, and updates row actions/popovers (`pinnedActionIds`, `popoverBoundaryRef`) plus item-actions type imports (`components/itemActions/types`).
|
|
1494
1549
|
- Risk notes:
|
|
1495
1550
|
- This is security-sensitive UX: it must uphold the invariant “never re-display secret values after entry” and avoid persisting plaintext. The design pushes toward that (vault disables fallback entry; machine presence checks are value-free), but it’s worth keeping this commit tightly grouped with the underlying secret-sealing primitives and any follow-up bugfixes (there are several later fixes in the queue).
|
|
1496
1551
|
- The new requirementVarName logic in `EnvironmentVariableCard` correctly applies requirements to the *source* env var when using template indirection (e.g. `${SOURCE_VAR}`), which is subtle and important for correctness.
|
|
@@ -1517,7 +1572,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66ee1eaf88a6 patchFile=/
|
|
|
1517
1572
|
---
|
|
1518
1573
|
|
|
1519
1574
|
## 042 2026-01-21 bdaf6913141f `terminal`
|
|
1520
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bdaf6913141f patchFile=/tmp/leeroy-wip-pass2/042.patch patchSha256=87ea409cf0f61ce99cb5597c0bf5cd02cdf225bfe9bea9f1451c10ea3bc92986 patchBytes=39225 patchLines=826 notesReviewed=
|
|
1575
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bdaf6913141f patchFile=/tmp/leeroy-wip-pass2/042.patch patchSha256=87ea409cf0f61ce99cb5597c0bf5cd02cdf225bfe9bea9f1451c10ea3bc92986 patchBytes=39225 patchLines=826 notesReviewed=yes reviewedAt=2026-01-24T19:20:11+0100 notesUpdated=yes
|
|
1521
1576
|
|
|
1522
1577
|
- Subject: feat(terminal): add Terminal settings + tmux metadata
|
|
1523
1578
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1532,6 +1587,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bdaf6913141f patchFile=/
|
|
|
1532
1587
|
- Updates `SettingsView`:
|
|
1533
1588
|
- replaces/renames the entry to “Terminal”
|
|
1534
1589
|
- shows an enabled/disabled subtitle driven by `terminalUseTmux`.
|
|
1590
|
+
- Also tightens GitHub connect UX: when `getGitHubOAuthParams` throws a non-retryable `HappyError`, it surfaces the message as the subtitle and disables the connect action.
|
|
1535
1591
|
- Extends CLI detection and machine details to include tmux:
|
|
1536
1592
|
- `hooks/useCLIDetection.ts` now includes `tmux` availability (boolean|null) and can surface tmux in the `detect-cli` response when present; older daemons treat missing tmux as unknown.
|
|
1537
1593
|
- Adds `useCLIDetection.hook.test.ts` to validate:
|
|
@@ -1540,6 +1596,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bdaf6913141f patchFile=/
|
|
|
1540
1596
|
- fallback bash probing includes a tmux `command -v tmux` check.
|
|
1541
1597
|
- `components/machine/DetectedClisList.tsx` is updated to render tmux as an entry when provided.
|
|
1542
1598
|
- Machine details screen adds tmux visibility/override controls (including a machine-specific override map keyed by machine id) and guards enabling tmux when it is not detected.
|
|
1599
|
+
- Machine details “spawn session” now passes `terminal` spawn options via `resolveTerminalSpawnOptions({ settings, machineId })` into `machineSpawnNewSession(...)` (so machine-scoped overrides actually affect session creation from this screen).
|
|
1543
1600
|
- Surfaces tmux spawn/attach metadata in session details:
|
|
1544
1601
|
- Session info UI adds fields to display tmux attach target and a fallback reason (useful for debugging resume workflows).
|
|
1545
1602
|
- Coherence: the commit body accurately describes the changes; most changes are within the terminal/tmux feature area.
|
|
@@ -1559,7 +1616,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bdaf6913141f patchFile=/
|
|
|
1559
1616
|
---
|
|
1560
1617
|
|
|
1561
1618
|
## 043 2026-01-21 bc779e4f7909 `new-session`
|
|
1562
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bc779e4f7909 patchFile=/tmp/leeroy-wip-pass2/043.patch patchSha256=056ec1d2a238bf9e0dcebd172b7a1ee7e61faa2f118f3b8c21a224abf61de5f2 patchBytes=135229 patchLines=2803 notesReviewed=
|
|
1619
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bc779e4f7909 patchFile=/tmp/leeroy-wip-pass2/043.patch patchSha256=056ec1d2a238bf9e0dcebd172b7a1ee7e61faa2f118f3b8c21a224abf61de5f2 patchBytes=135229 patchLines=2803 notesReviewed=yes reviewedAt=2026-01-24T19:27:57+0100 notesUpdated=yes
|
|
1563
1620
|
|
|
1564
1621
|
- Subject: refactor(new-session): integrate secrets + terminal spawn options
|
|
1565
1622
|
- Reasons: safety/security-sensitive area
|
|
@@ -1599,6 +1656,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bc779e4f7909 patchFile=/
|
|
|
1599
1656
|
- `useSearch` now returns `{ error }` and uses bounded retries with requestId cancellation to avoid infinite background retries; friends search surfaces the error message.
|
|
1600
1657
|
- Auth helpers (`authChallenge`, `authQRStart`, app index) switch random byte generation to the new `platform/cryptoRandom` shim.
|
|
1601
1658
|
- `MainView` swaps inline status logic for `ConnectionStatusControl` (new UI primitive from the overlays work).
|
|
1659
|
+
- Sidebar/UI polish: `SidebarView` wraps in `PopoverBoundaryProvider`, replaces inline socket status UI with `ConnectionStatusControl`, and adds a retry/restore banner when sync/socket errors occur; `OptionTiles` gains a `disabled` option (with opacity/press guards).
|
|
1602
1660
|
|
|
1603
1661
|
### Verdict
|
|
1604
1662
|
|
|
@@ -1623,7 +1681,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bc779e4f7909 patchFile=/
|
|
|
1623
1681
|
---
|
|
1624
1682
|
|
|
1625
1683
|
## 044 2026-01-21 cb11d4bdb25a `docs`
|
|
1626
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cb11d4bdb25a patchFile=/tmp/leeroy-wip-pass2/044.patch patchSha256=d02b7bee3e56cf79b47b394f3645988462e7bc567333891fb5a54f9b1f614bdf patchBytes=7661 patchLines=118 notesReviewed=
|
|
1684
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cb11d4bdb25a patchFile=/tmp/leeroy-wip-pass2/044.patch patchSha256=d02b7bee3e56cf79b47b394f3645988462e7bc567333891fb5a54f9b1f614bdf patchBytes=7661 patchLines=118 notesReviewed=yes reviewedAt=2026-01-24T19:28:37+0100 notesUpdated=no
|
|
1627
1685
|
|
|
1628
1686
|
- Subject: docs: add AGENTS.md symlink + update CLAUDE.md
|
|
1629
1687
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1649,7 +1707,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cb11d4bdb25a patchFile=/
|
|
|
1649
1707
|
---
|
|
1650
1708
|
|
|
1651
1709
|
## 045 2026-01-21 1bc3b9715776 `sync`
|
|
1652
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bc3b9715776 patchFile=/tmp/leeroy-wip-pass2/045.patch patchSha256=677cf555e52a3c402aada9d454ccf354ebe2586511aea82db752f7ae257c2358 patchBytes=3116 patchLines=84 notesReviewed=
|
|
1710
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bc3b9715776 patchFile=/tmp/leeroy-wip-pass2/045.patch patchSha256=677cf555e52a3c402aada9d454ccf354ebe2586511aea82db752f7ae257c2358 patchBytes=3116 patchLines=84 notesReviewed=yes reviewedAt=2026-01-24T19:29:06+0100 notesUpdated=no
|
|
1653
1711
|
|
|
1654
1712
|
- Subject: fix(sync): handle non-JSON 400 responses
|
|
1655
1713
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1676,7 +1734,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bc3b9715776 patchFile=/
|
|
|
1676
1734
|
---
|
|
1677
1735
|
|
|
1678
1736
|
## 046 2026-01-21 ea2e4d19d633 `deps`
|
|
1679
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ea2e4d19d633 patchFile=/tmp/leeroy-wip-pass2/046.patch patchSha256=56d31e16958294810504afab058b72991c083212c0a3f8aeae3db8490c255d00 patchBytes=2141 patchLines=54 notesReviewed=
|
|
1737
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ea2e4d19d633 patchFile=/tmp/leeroy-wip-pass2/046.patch patchSha256=56d31e16958294810504afab058b72991c083212c0a3f8aeae3db8490c255d00 patchBytes=2141 patchLines=54 notesReviewed=yes reviewedAt=2026-01-24T19:29:31+0100 notesUpdated=no
|
|
1680
1738
|
|
|
1681
1739
|
- Subject: chore(deps): align react-test-renderer with react
|
|
1682
1740
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1699,7 +1757,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ea2e4d19d633 patchFile=/
|
|
|
1699
1757
|
---
|
|
1700
1758
|
|
|
1701
1759
|
## 047 2026-01-21 dd041d21ecfc `sync`
|
|
1702
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=dd041d21ecfc patchFile=/tmp/leeroy-wip-pass2/047.patch patchSha256=792389c9c15b60f99358c4b7d9feed9f15a4debd0b5fbaf9acdbd970342fed78 patchBytes=5691 patchLines=147 notesReviewed=
|
|
1760
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=dd041d21ecfc patchFile=/tmp/leeroy-wip-pass2/047.patch patchSha256=792389c9c15b60f99358c4b7d9feed9f15a4debd0b5fbaf9acdbd970342fed78 patchBytes=5691 patchLines=147 notesReviewed=yes reviewedAt=2026-01-24T19:30:12+0100 notesUpdated=no
|
|
1703
1761
|
|
|
1704
1762
|
- Subject: fix(sync): guard JSON parsing on disconnect errors
|
|
1705
1763
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1727,7 +1785,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=dd041d21ecfc patchFile=/
|
|
|
1727
1785
|
---
|
|
1728
1786
|
|
|
1729
1787
|
## 048 2026-01-21 395da4ff3167 `zen`
|
|
1730
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=395da4ff3167 patchFile=/tmp/leeroy-wip-pass2/048.patch patchSha256=428a760c29ed02bd7fd265fa22ad4393f4aa9cfaf3ff3d883d17911ef5e37e34 patchBytes=1153 patchLines=27 notesReviewed=
|
|
1788
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=395da4ff3167 patchFile=/tmp/leeroy-wip-pass2/048.patch patchSha256=428a760c29ed02bd7fd265fa22ad4393f4aa9cfaf3ff3d883d17911ef5e37e34 patchBytes=1153 patchLines=27 notesReviewed=yes reviewedAt=2026-01-24T19:30:36+0100 notesUpdated=no
|
|
1731
1789
|
|
|
1732
1790
|
- Subject: refactor(zen): avoid todo variable shadowing
|
|
1733
1791
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1749,7 +1807,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=395da4ff3167 patchFile=/
|
|
|
1749
1807
|
---
|
|
1750
1808
|
|
|
1751
1809
|
## 049 2026-01-21 2e956f32f220 `new`
|
|
1752
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2e956f32f220 patchFile=/tmp/leeroy-wip-pass2/049.patch patchSha256=f7fcfdf43ac24be5936137b84318c1fd819003a1f314b111adcfeba3f46e0475 patchBytes=39497 patchLines=974 notesReviewed=
|
|
1810
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2e956f32f220 patchFile=/tmp/leeroy-wip-pass2/049.patch patchSha256=f7fcfdf43ac24be5936137b84318c1fd819003a1f314b111adcfeba3f46e0475 patchBytes=39497 patchLines=974 notesReviewed=yes reviewedAt=2026-01-24T19:31:37+0100 notesUpdated=no
|
|
1753
1811
|
|
|
1754
1812
|
- Subject: fix(new): keep pick screens above iOS modal
|
|
1755
1813
|
- Reasons: safety/security-sensitive area
|
|
@@ -1782,7 +1840,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2e956f32f220 patchFile=/
|
|
|
1782
1840
|
---
|
|
1783
1841
|
|
|
1784
1842
|
## 050 2026-01-21 2da2f9349ec5 `popover`
|
|
1785
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2da2f9349ec5 patchFile=/tmp/leeroy-wip-pass2/050.patch patchSha256=528033ab018e1175a1abed29c9b3239d2c2eea51d18cee907707829ad0593521 patchBytes=3016 patchLines=48 notesReviewed=
|
|
1843
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2da2f9349ec5 patchFile=/tmp/leeroy-wip-pass2/050.patch patchSha256=528033ab018e1175a1abed29c9b3239d2c2eea51d18cee907707829ad0593521 patchBytes=3016 patchLines=48 notesReviewed=yes reviewedAt=2026-01-24T19:32:04+0100 notesUpdated=no
|
|
1786
1844
|
|
|
1787
1845
|
- Subject: fix(popover): allow web fixed positioning types
|
|
1788
1846
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1811,7 +1869,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2da2f9349ec5 patchFile=/
|
|
|
1811
1869
|
---
|
|
1812
1870
|
|
|
1813
1871
|
## 051 2026-01-21 43f23f2f082e `format`
|
|
1814
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=43f23f2f082e patchFile=/tmp/leeroy-wip-pass2/051.patch patchSha256=7c584fabdf4202d4ea83a309226e0fd7160771f8ccd65089c171e10c5c4f8674 patchBytes=3206 patchLines=82 notesReviewed=
|
|
1872
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=43f23f2f082e patchFile=/tmp/leeroy-wip-pass2/051.patch patchSha256=7c584fabdf4202d4ea83a309226e0fd7160771f8ccd65089c171e10c5c4f8674 patchBytes=3206 patchLines=82 notesReviewed=yes reviewedAt=2026-01-24T19:32:27+0100 notesUpdated=no
|
|
1815
1873
|
|
|
1816
1874
|
- Subject: chore(format): replace stray tabs with spaces
|
|
1817
1875
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1838,7 +1896,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=43f23f2f082e patchFile=/
|
|
|
1838
1896
|
---
|
|
1839
1897
|
|
|
1840
1898
|
## 052 2026-01-21 e1d55fdbd9ee `i18n`
|
|
1841
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e1d55fdbd9ee patchFile=/tmp/leeroy-wip-pass2/052.patch patchSha256=37114d44d75a7a9196bb9a2dc65e0a06dd3772e32188cfaa80d83a38b08936d0 patchBytes=2064 patchLines=40 notesReviewed=
|
|
1899
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e1d55fdbd9ee patchFile=/tmp/leeroy-wip-pass2/052.patch patchSha256=37114d44d75a7a9196bb9a2dc65e0a06dd3772e32188cfaa80d83a38b08936d0 patchBytes=2064 patchLines=40 notesReviewed=yes reviewedAt=2026-01-24T19:32:51+0100 notesUpdated=no
|
|
1842
1900
|
|
|
1843
1901
|
- Subject: fix(i18n): improve untranslated literal scan parsing
|
|
1844
1902
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1865,7 +1923,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e1d55fdbd9ee patchFile=/
|
|
|
1865
1923
|
---
|
|
1866
1924
|
|
|
1867
1925
|
## 053 2026-01-21 c210c1115598 `sync`
|
|
1868
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c210c1115598 patchFile=/tmp/leeroy-wip-pass2/053.patch patchSha256=fcc3390b3405216d1626e828703be21bfaf1dd90d3c6382756e29b77390f4828 patchBytes=1106 patchLines=29 notesReviewed=
|
|
1926
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c210c1115598 patchFile=/tmp/leeroy-wip-pass2/053.patch patchSha256=fcc3390b3405216d1626e828703be21bfaf1dd90d3c6382756e29b77390f4828 patchBytes=1106 patchLines=29 notesReviewed=yes reviewedAt=2026-01-24T19:33:20+0100 notesUpdated=no
|
|
1869
1927
|
|
|
1870
1928
|
- Subject: test(sync): restore stubbed fetch between tests
|
|
1871
1929
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1892,7 +1950,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c210c1115598 patchFile=/
|
|
|
1892
1950
|
---
|
|
1893
1951
|
|
|
1894
1952
|
## 054 2026-01-21 66c678451335 `ui`
|
|
1895
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66c678451335 patchFile=/tmp/leeroy-wip-pass2/054.patch patchSha256=8ef52fb7589c3b292d7a1eba66f35710fc0471b938034409381ee0401ae2da85 patchBytes=8880 patchLines=191 notesReviewed=
|
|
1953
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66c678451335 patchFile=/tmp/leeroy-wip-pass2/054.patch patchSha256=8ef52fb7589c3b292d7a1eba66f35710fc0471b938034409381ee0401ae2da85 patchBytes=8880 patchLines=191 notesReviewed=yes reviewedAt=2026-01-24T19:33:50+0100 notesUpdated=no
|
|
1896
1954
|
|
|
1897
1955
|
- Subject: fix(ui): apply small review fixes
|
|
1898
1956
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1927,7 +1985,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=66c678451335 patchFile=/
|
|
|
1927
1985
|
---
|
|
1928
1986
|
|
|
1929
1987
|
## 055 2026-01-21 2472b376775c `modal`
|
|
1930
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2472b376775c patchFile=/tmp/leeroy-wip-pass2/055.patch patchSha256=e3dd966bbbd9e34eeb832e502d4f13767f031955315a7ff627dd657fe58fe726 patchBytes=1127 patchLines=24 notesReviewed=
|
|
1988
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2472b376775c patchFile=/tmp/leeroy-wip-pass2/055.patch patchSha256=e3dd966bbbd9e34eeb832e502d4f13767f031955315a7ff627dd657fe58fe726 patchBytes=1127 patchLines=24 notesReviewed=yes reviewedAt=2026-01-24T20:01:38+0100 notesUpdated=no
|
|
1931
1989
|
|
|
1932
1990
|
- Subject: test(modal): make backdrop z-index assertion safer
|
|
1933
1991
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1954,7 +2012,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2472b376775c patchFile=/
|
|
|
1954
2012
|
---
|
|
1955
2013
|
|
|
1956
2014
|
## 056 2026-01-21 02450d179aaf `profiles`
|
|
1957
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=02450d179aaf patchFile=/tmp/leeroy-wip-pass2/056.patch patchSha256=ebf5a695b86c41c4206d012607f796f807d86cf30fffdbcdf2a9bd00cc44ba6e patchBytes=1242 patchLines=26 notesReviewed=
|
|
2015
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=02450d179aaf patchFile=/tmp/leeroy-wip-pass2/056.patch patchSha256=ebf5a695b86c41c4206d012607f796f807d86cf30fffdbcdf2a9bd00cc44ba6e patchBytes=1242 patchLines=26 notesReviewed=yes reviewedAt=2026-01-24T20:02:13+0100 notesUpdated=no
|
|
1958
2016
|
|
|
1959
2017
|
- Subject: fix(profiles): align experimentsEnabled for built-in profiles
|
|
1960
2018
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -1982,7 +2040,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=02450d179aaf patchFile=/
|
|
|
1982
2040
|
---
|
|
1983
2041
|
|
|
1984
2042
|
## 057 2026-01-21 ff7bec72358f `secrets`
|
|
1985
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ff7bec72358f patchFile=/tmp/leeroy-wip-pass2/057.patch patchSha256=f833cd26ae6c7c72e2ccdf89cd904485fb84d23f610c9930e30b4e385b138dc8 patchBytes=5039 patchLines=117 notesReviewed=
|
|
2043
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ff7bec72358f patchFile=/tmp/leeroy-wip-pass2/057.patch patchSha256=f833cd26ae6c7c72e2ccdf89cd904485fb84d23f610c9930e30b4e385b138dc8 patchBytes=5039 patchLines=117 notesReviewed=yes reviewedAt=2026-01-24T20:02:41+0100 notesUpdated=no
|
|
1986
2044
|
|
|
1987
2045
|
- Subject: fix(secrets): tighten callback deps and fix indentation
|
|
1988
2046
|
- Reasons: safety/security-sensitive area
|
|
@@ -2009,7 +2067,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=ff7bec72358f patchFile=/
|
|
|
2009
2067
|
---
|
|
2010
2068
|
|
|
2011
2069
|
## 058 2026-01-21 1bb65f5dd494 `new-session`
|
|
2012
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bb65f5dd494 patchFile=/tmp/leeroy-wip-pass2/058.patch patchSha256=12b9a312227605d1ea0d8240e4e17af44c7a086708cc93c3324d749e80105e20 patchBytes=1587 patchLines=34 notesReviewed=
|
|
2070
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bb65f5dd494 patchFile=/tmp/leeroy-wip-pass2/058.patch patchSha256=12b9a312227605d1ea0d8240e4e17af44c7a086708cc93c3324d749e80105e20 patchBytes=1587 patchLines=34 notesReviewed=yes reviewedAt=2026-01-24T20:03:11+0100 notesUpdated=no
|
|
2013
2071
|
|
|
2014
2072
|
- Subject: fix(new-session): avoid stuck secret requirement modal guard
|
|
2015
2073
|
- Reasons: safety/security-sensitive area
|
|
@@ -2036,7 +2094,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=1bb65f5dd494 patchFile=/
|
|
|
2036
2094
|
---
|
|
2037
2095
|
|
|
2038
2096
|
## 059 2026-01-21 f7f81497444d `modal`
|
|
2039
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f7f81497444d patchFile=/tmp/leeroy-wip-pass2/059.patch patchSha256=de24ba6a9db7bcf2b17709c54824a22ef25633a072ed5f88997a830411be70e8 patchBytes=25402 patchLines=574 notesReviewed=
|
|
2097
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f7f81497444d patchFile=/tmp/leeroy-wip-pass2/059.patch patchSha256=de24ba6a9db7bcf2b17709c54824a22ef25633a072ed5f88997a830411be70e8 patchBytes=25402 patchLines=574 notesReviewed=yes reviewedAt=2026-01-24T20:04:08+0100 notesUpdated=no
|
|
2040
2098
|
|
|
2041
2099
|
- Subject: fix(modal): prevent non-dismissible WebAlertModal
|
|
2042
2100
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2085,7 +2143,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=f7f81497444d patchFile=/
|
|
|
2085
2143
|
---
|
|
2086
2144
|
|
|
2087
2145
|
## 060 2026-01-22 bb09f91de715 `settings`
|
|
2088
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bb09f91de715 patchFile=/tmp/leeroy-wip-pass2/060.patch patchSha256=50913ce23f328820d8efa6165396c538c34abe2bab12661a2f7ba2c706c1bbd9 patchBytes=2955 patchLines=74 notesReviewed=
|
|
2146
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bb09f91de715 patchFile=/tmp/leeroy-wip-pass2/060.patch patchSha256=50913ce23f328820d8efa6165396c538c34abe2bab12661a2f7ba2c706c1bbd9 patchBytes=2955 patchLines=74 notesReviewed=yes reviewedAt=2026-01-24T20:04:42+0100 notesUpdated=no
|
|
2089
2147
|
|
|
2090
2148
|
- Subject: fix(settings): keep valid secrets when one entry is invalid
|
|
2091
2149
|
- Reasons: safety/security-sensitive area
|
|
@@ -2114,7 +2172,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=bb09f91de715 patchFile=/
|
|
|
2114
2172
|
---
|
|
2115
2173
|
|
|
2116
2174
|
## 061 2026-01-22 765423af52b4 `agent-input`
|
|
2117
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=765423af52b4 patchFile=/tmp/leeroy-wip-pass2/061.patch patchSha256=4a1ce74a09d5c2f1cdbeddeac4e823dcd4bd37faa8f6a2ee17bb6f0f544ac920 patchBytes=6745 patchLines=114 notesReviewed=
|
|
2175
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=765423af52b4 patchFile=/tmp/leeroy-wip-pass2/061.patch patchSha256=4a1ce74a09d5c2f1cdbeddeac4e823dcd4bd37faa8f6a2ee17bb6f0f544ac920 patchBytes=6745 patchLines=114 notesReviewed=yes reviewedAt=2026-01-24T20:05:10+0100 notesUpdated=no
|
|
2118
2176
|
|
|
2119
2177
|
- Subject: fix(agent-input): cycle permission mode from normalized state
|
|
2120
2178
|
- Reasons: safety/security-sensitive area
|
|
@@ -2143,7 +2201,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=765423af52b4 patchFile=/
|
|
|
2143
2201
|
---
|
|
2144
2202
|
|
|
2145
2203
|
## 062 2026-01-22 e533db1813a5 `popover`
|
|
2146
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e533db1813a5 patchFile=/tmp/leeroy-wip-pass2/062.patch patchSha256=06650937b0fb3c66a48f1cb6a678ceadfc1a0bcbe43b3eebb02183d52f85641a patchBytes=4238 patchLines=69 notesReviewed=
|
|
2204
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e533db1813a5 patchFile=/tmp/leeroy-wip-pass2/062.patch patchSha256=06650937b0fb3c66a48f1cb6a678ceadfc1a0bcbe43b3eebb02183d52f85641a patchBytes=4238 patchLines=69 notesReviewed=yes reviewedAt=2026-01-24T20:05:39+0100 notesUpdated=no
|
|
2147
2205
|
|
|
2148
2206
|
- Subject: fix(popover): add screens cjs helper and fix fixed positioning types
|
|
2149
2207
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2173,7 +2231,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e533db1813a5 patchFile=/
|
|
|
2173
2231
|
---
|
|
2174
2232
|
|
|
2175
2233
|
## 063 2026-01-22 2ed3100311c7 `secrets`
|
|
2176
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2ed3100311c7 patchFile=/tmp/leeroy-wip-pass2/063.patch patchSha256=7b77ffb2a149148d1285b141b086978059d6a5debd57819b4f67b2e0e364615a patchBytes=14045 patchLines=227 notesReviewed=
|
|
2234
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2ed3100311c7 patchFile=/tmp/leeroy-wip-pass2/063.patch patchSha256=7b77ffb2a149148d1285b141b086978059d6a5debd57819b4f67b2e0e364615a patchBytes=14045 patchLines=227 notesReviewed=yes reviewedAt=2026-01-24T20:06:18+0100 notesUpdated=no
|
|
2177
2235
|
|
|
2178
2236
|
- Subject: fix(secrets): hide values when using secret vault
|
|
2179
2237
|
- Reasons: safety/security-sensitive area
|
|
@@ -2205,7 +2263,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=2ed3100311c7 patchFile=/
|
|
|
2205
2263
|
---
|
|
2206
2264
|
|
|
2207
2265
|
## 064 2026-01-22 e5848c480522 `ui`
|
|
2208
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e5848c480522 patchFile=/tmp/leeroy-wip-pass2/064.patch patchSha256=922df47b48ab85bc86e1c6a755752947ed57ec0590af7b2aec084420ff2c16f0 patchBytes=16134 patchLines=400 notesReviewed=
|
|
2266
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e5848c480522 patchFile=/tmp/leeroy-wip-pass2/064.patch patchSha256=922df47b48ab85bc86e1c6a755752947ed57ec0590af7b2aec084420ff2c16f0 patchBytes=16134 patchLines=400 notesReviewed=yes reviewedAt=2026-01-24T20:07:04+0100 notesUpdated=no
|
|
2209
2267
|
|
|
2210
2268
|
- Subject: fix(ui): harden overlays and permission cycling
|
|
2211
2269
|
- Reasons: safety/security-sensitive area
|
|
@@ -2246,7 +2304,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=e5848c480522 patchFile=/
|
|
|
2246
2304
|
---
|
|
2247
2305
|
|
|
2248
2306
|
## 065 2026-01-13 69fdcff96a4c `sync`
|
|
2249
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=69fdcff96a4c patchFile=/tmp/leeroy-wip-pass2/065.patch patchSha256=20a7e9d9f2e6a834cd2c443d87fe87477985fb632f02551837797f48a915583c patchBytes=7673 patchLines=130 notesReviewed=
|
|
2307
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=69fdcff96a4c patchFile=/tmp/leeroy-wip-pass2/065.patch patchSha256=20a7e9d9f2e6a834cd2c443d87fe87477985fb632f02551837797f48a915583c patchBytes=7673 patchLines=130 notesReviewed=yes reviewedAt=2026-01-24T20:07:37+0100 notesUpdated=no
|
|
2250
2308
|
|
|
2251
2309
|
- Subject: fix(sync): restore session permission mode from last message
|
|
2252
2310
|
- Reasons: safety/security-sensitive area
|
|
@@ -2278,7 +2336,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=69fdcff96a4c patchFile=/
|
|
|
2278
2336
|
---
|
|
2279
2337
|
|
|
2280
2338
|
## 066 2026-01-13 9b499c5dccce `sync`
|
|
2281
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b499c5dccce patchFile=/tmp/leeroy-wip-pass2/066.patch patchSha256=f2d632496716cf934e43cf3a03bef46afcb73ba62a6d3898a6c1f54135484763 patchBytes=7448 patchLines=128 notesReviewed=
|
|
2339
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b499c5dccce patchFile=/tmp/leeroy-wip-pass2/066.patch patchSha256=f2d632496716cf934e43cf3a03bef46afcb73ba62a6d3898a6c1f54135484763 patchBytes=7448 patchLines=128 notesReviewed=yes reviewedAt=2026-01-24T20:08:03+0100 notesUpdated=no
|
|
2282
2340
|
|
|
2283
2341
|
- Subject: fix(sync): persist permission mode timestamp for restart-safe arbitration
|
|
2284
2342
|
- Reasons: safety/security-sensitive area
|
|
@@ -2311,7 +2369,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b499c5dccce patchFile=/
|
|
|
2311
2369
|
---
|
|
2312
2370
|
|
|
2313
2371
|
## 067 2026-01-13 def8852509d0 `sync`
|
|
2314
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=def8852509d0 patchFile=/tmp/leeroy-wip-pass2/067.patch patchSha256=243a4d97d0be485870473f3400dcddaf3f3c612ab127a56750817644b72cc042 patchBytes=20586 patchLines=422 notesReviewed=
|
|
2372
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=def8852509d0 patchFile=/tmp/leeroy-wip-pass2/067.patch patchSha256=243a4d97d0be485870473f3400dcddaf3f3c612ab127a56750817644b72cc042 patchBytes=20586 patchLines=422 notesReviewed=yes reviewedAt=2026-01-24T20:09:07+0100 notesUpdated=no
|
|
2315
2373
|
|
|
2316
2374
|
- Subject: fix(sync): persist permission mode reliably across devices
|
|
2317
2375
|
- Reasons: safety/security-sensitive area
|
|
@@ -2356,7 +2414,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=def8852509d0 patchFile=/
|
|
|
2356
2414
|
---
|
|
2357
2415
|
|
|
2358
2416
|
## 068 2026-01-12 b1c8a6fecd01 `session`
|
|
2359
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=b1c8a6fecd01 patchFile=/tmp/leeroy-wip-pass2/068.patch patchSha256=24a5192bad1dcf9d42a4810b4e66e4842627b56da16beb6f3bc4a7819f3c8983 patchBytes=5900 patchLines=126 notesReviewed=
|
|
2417
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=b1c8a6fecd01 patchFile=/tmp/leeroy-wip-pass2/068.patch patchSha256=24a5192bad1dcf9d42a4810b4e66e4842627b56da16beb6f3bc4a7819f3c8983 patchBytes=5900 patchLines=126 notesReviewed=yes reviewedAt=2026-01-24T20:09:38+0100 notesUpdated=no
|
|
2360
2418
|
|
|
2361
2419
|
- Subject: fix(session): archive when kill RPC unavailable
|
|
2362
2420
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2390,7 +2448,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=b1c8a6fecd01 patchFile=/
|
|
|
2390
2448
|
---
|
|
2391
2449
|
|
|
2392
2450
|
## 069 2026-01-06 c06b6202b5d4 `expo-app`
|
|
2393
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c06b6202b5d4 patchFile=/tmp/leeroy-wip-pass2/069.patch patchSha256=2da06e303c3470a4ba84a9c6108e68d93474b45de8034cb6dd9aa0ad48b6a5ed patchBytes=4354 patchLines=130 notesReviewed=
|
|
2451
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c06b6202b5d4 patchFile=/tmp/leeroy-wip-pass2/069.patch patchSha256=2da06e303c3470a4ba84a9c6108e68d93474b45de8034cb6dd9aa0ad48b6a5ed patchBytes=4354 patchLines=130 notesReviewed=yes reviewedAt=2026-01-24T20:15:28+0100 notesUpdated=no
|
|
2394
2452
|
|
|
2395
2453
|
- Subject: Add copy-to-clipboard button to message blocks
|
|
2396
2454
|
- Reasons: non-Conventional-Commits subject
|
|
@@ -2420,7 +2478,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c06b6202b5d4 patchFile=/
|
|
|
2420
2478
|
---
|
|
2421
2479
|
|
|
2422
2480
|
## 070 2026-01-21 9fc7d3d412b9 `sessions`
|
|
2423
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9fc7d3d412b9 patchFile=/tmp/leeroy-wip-pass2/070.patch patchSha256=c3bb8024d077a6d2124a731b8fdca25b6b61d9f5fbf0a8f6f973bab2399a5473 patchBytes=38406 patchLines=811 notesReviewed=
|
|
2481
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9fc7d3d412b9 patchFile=/tmp/leeroy-wip-pass2/070.patch patchSha256=c3bb8024d077a6d2124a731b8fdca25b6b61d9f5fbf0a8f6f973bab2399a5473 patchBytes=38406 patchLines=811 notesReviewed=yes reviewedAt=2026-01-24T20:17:34+0100 notesUpdated=no
|
|
2424
2482
|
|
|
2425
2483
|
- Subject: feat(sessions): group inactive sessions by project
|
|
2426
2484
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2452,7 +2510,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9fc7d3d412b9 patchFile=/
|
|
|
2452
2510
|
---
|
|
2453
2511
|
|
|
2454
2512
|
## 071 2026-01-21 62a8b1b07c3e `sessions`
|
|
2455
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=62a8b1b07c3e patchFile=/tmp/leeroy-wip-pass2/071.patch patchSha256=8f985046e31b2f570813303dd7abe624e45ec225c5b3eee071652d1f7bf494ba patchBytes=22794 patchLines=482 notesReviewed=
|
|
2513
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=62a8b1b07c3e patchFile=/tmp/leeroy-wip-pass2/071.patch patchSha256=8f985046e31b2f570813303dd7abe624e45ec225c5b3eee071652d1f7bf494ba patchBytes=22794 patchLines=482 notesReviewed=yes reviewedAt=2026-01-24T20:18:40+0100 notesUpdated=no
|
|
2456
2514
|
|
|
2457
2515
|
- Subject: feat(sessions): add unread badge
|
|
2458
2516
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2490,7 +2548,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=62a8b1b07c3e patchFile=/
|
|
|
2490
2548
|
---
|
|
2491
2549
|
|
|
2492
2550
|
## 072 2026-01-21 82d74454c3c4 `typecheck`
|
|
2493
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=82d74454c3c4 patchFile=/tmp/leeroy-wip-pass2/072.patch patchSha256=1a8dd521ceab0660a8ba515ae4e40adbd7afdd1fd29a4404b225ef6028f63431 patchBytes=2497 patchLines=43 notesReviewed=
|
|
2551
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=82d74454c3c4 patchFile=/tmp/leeroy-wip-pass2/072.patch patchSha256=1a8dd521ceab0660a8ba515ae4e40adbd7afdd1fd29a4404b225ef6028f63431 patchBytes=2497 patchLines=43 notesReviewed=yes reviewedAt=2026-01-24T20:19:14+0100 notesUpdated=no
|
|
2494
2552
|
|
|
2495
2553
|
- Subject: fix(typecheck): restore permission imports and Popover web styles
|
|
2496
2554
|
- Reasons: safety/security-sensitive area
|
|
@@ -2517,7 +2575,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=82d74454c3c4 patchFile=/
|
|
|
2517
2575
|
---
|
|
2518
2576
|
|
|
2519
2577
|
## 073 2026-01-11 4f2b533f99c2 `tools`
|
|
2520
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4f2b533f99c2 patchFile=/tmp/leeroy-wip-pass2/073.patch patchSha256=0fe31f7bea6a875d5eba5bd634ad16094893c27f942ce0ec933802836f0bfaf7 patchBytes=17604 patchLines=401 notesReviewed=
|
|
2578
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4f2b533f99c2 patchFile=/tmp/leeroy-wip-pass2/073.patch patchSha256=0fe31f7bea6a875d5eba5bd634ad16094893c27f942ce0ec933802836f0bfaf7 patchBytes=17604 patchLines=401 notesReviewed=yes reviewedAt=2026-01-24T20:20:20+0100 notesUpdated=no
|
|
2521
2579
|
|
|
2522
2580
|
- Subject: feat(tools): add approve/reject buttons to ExitPlanMode
|
|
2523
2581
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2550,7 +2608,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4f2b533f99c2 patchFile=/
|
|
|
2550
2608
|
---
|
|
2551
2609
|
|
|
2552
2610
|
## 074 2026-01-07 c86cbd26b040 `queue`
|
|
2553
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c86cbd26b040 patchFile=/tmp/leeroy-wip-pass2/074.patch patchSha256=a371a5fb976f8323071238d5478e67452f8101074b1e350c72156dec64a3e895 patchBytes=45107 patchLines=1043 notesReviewed=
|
|
2611
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c86cbd26b040 patchFile=/tmp/leeroy-wip-pass2/074.patch patchSha256=a371a5fb976f8323071238d5478e67452f8101074b1e350c72156dec64a3e895 patchBytes=45107 patchLines=1043 notesReviewed=yes reviewedAt=2026-01-24T20:22:09+0100 notesUpdated=no
|
|
2554
2612
|
|
|
2555
2613
|
- Subject: feat(queue): add pending message queue UI and send modes
|
|
2556
2614
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2594,7 +2652,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=c86cbd26b040 patchFile=/
|
|
|
2594
2652
|
---
|
|
2595
2653
|
|
|
2596
2654
|
## 075 2026-01-07 42da6dae8fe4 `session`
|
|
2597
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=42da6dae8fe4 patchFile=/tmp/leeroy-wip-pass2/075.patch patchSha256=0d8e35af710d88633ab53ea25e01f8d2491e5fb7dc977ac4c2204b83eb1d80e2 patchBytes=16372 patchLines=353 notesReviewed=
|
|
2655
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=42da6dae8fe4 patchFile=/tmp/leeroy-wip-pass2/075.patch patchSha256=0d8e35af710d88633ab53ea25e01f8d2491e5fb7dc977ac4c2204b83eb1d80e2 patchBytes=16372 patchLines=353 notesReviewed=yes reviewedAt=2026-01-24T20:23:19+0100 notesUpdated=no
|
|
2598
2656
|
|
|
2599
2657
|
- Subject: feat(session): add session rename support
|
|
2600
2658
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2629,7 +2687,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=42da6dae8fe4 patchFile=/
|
|
|
2629
2687
|
---
|
|
2630
2688
|
|
|
2631
2689
|
## 076 2026-01-12 057102f67904 `resume`
|
|
2632
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=057102f67904 patchFile=/tmp/leeroy-wip-pass2/076.patch patchSha256=a9dd95c610ad982c66168fab4e09c50f2c2ceb6de30962f5cc166a3e6c677d1b patchBytes=38206 patchLines=864 notesReviewed=
|
|
2690
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=057102f67904 patchFile=/tmp/leeroy-wip-pass2/076.patch patchSha256=a9dd95c610ad982c66168fab4e09c50f2c2ceb6de30962f5cc166a3e6c677d1b patchBytes=38206 patchLines=864 notesReviewed=yes reviewedAt=2026-01-24T20:27:11+0100 notesUpdated=yes
|
|
2633
2691
|
|
|
2634
2692
|
- Subject: feat(resume): add resume session option for new sessions
|
|
2635
2693
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2653,6 +2711,9 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=057102f67904 patchFile=/
|
|
|
2653
2711
|
- Coherence:
|
|
2654
2712
|
- This is a cohesive feature commit (new session resume UI + payload + gating + persistence).
|
|
2655
2713
|
- Minor mismatch with the body bullet “Expose Codex session id in Session Info”: this commit adds translations for Codex session ID copy UX, but the actual Session Info UI wiring appears in later commits (see 080).
|
|
2714
|
+
- Implementation details / risks:
|
|
2715
|
+
- In this commit, `resumeSessionId` is persisted to `NewSessionDraft` but does not appear to be written back into the temp session data store; `NewSessionData` is extended but the screen only *reads* `tempSessionData?.resumeSessionId`.
|
|
2716
|
+
- The resume picker returns the value by dispatching `CommonActions.setParams({ resumeSessionId })` to the previous route’s key via `navigation.getState()`. This should work for normal navigation, but is potentially brittle for deep-links/unusual navigation state (it falls back to `router.back()`).
|
|
2656
2717
|
|
|
2657
2718
|
### Verdict
|
|
2658
2719
|
|
|
@@ -2667,7 +2728,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=057102f67904 patchFile=/
|
|
|
2667
2728
|
---
|
|
2668
2729
|
|
|
2669
2730
|
## 077 2026-01-14 05532bd65c6b `resume`
|
|
2670
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=05532bd65c6b patchFile=/tmp/leeroy-wip-pass2/077.patch patchSha256=829d9f8e6db35a17bed895b7a14404c67c9f51fca3c8630aff3452d0eb152f44 patchBytes=10791 patchLines=200 notesReviewed=
|
|
2731
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=05532bd65c6b patchFile=/tmp/leeroy-wip-pass2/077.patch patchSha256=829d9f8e6db35a17bed895b7a14404c67c9f51fca3c8630aff3452d0eb152f44 patchBytes=10791 patchLines=200 notesReviewed=yes reviewedAt=2026-01-24T20:27:54+0100 notesUpdated=no
|
|
2671
2732
|
|
|
2672
2733
|
- Subject: feat(resume): show resume chip under path in new session
|
|
2673
2734
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2696,7 +2757,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=05532bd65c6b patchFile=/
|
|
|
2696
2757
|
---
|
|
2697
2758
|
|
|
2698
2759
|
## 078 2026-01-11 cd5771e50881 `resume`
|
|
2699
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cd5771e50881 patchFile=/tmp/leeroy-wip-pass2/078.patch patchSha256=307c27d9124dffbb4b057f095eac60ef354f8c8686e2078d9b88b189611d2a90 patchBytes=14375 patchLines=360 notesReviewed=
|
|
2760
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cd5771e50881 patchFile=/tmp/leeroy-wip-pass2/078.patch patchSha256=307c27d9124dffbb4b057f095eac60ef354f8c8686e2078d9b88b189611d2a90 patchBytes=14375 patchLines=360 notesReviewed=yes reviewedAt=2026-01-24T20:29:19+0100 notesUpdated=yes
|
|
2700
2761
|
|
|
2701
2762
|
- Subject: feat: resume inactive Claude sessions from UI
|
|
2702
2763
|
- Reasons: non-Conventional-Commits subject
|
|
@@ -2710,10 +2771,14 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cd5771e50881 patchFile=/
|
|
|
2710
2771
|
- Updates `-session/SessionView.tsx`:
|
|
2711
2772
|
- Detects inactive sessions and introduces resumable state (`isResumable`, `isResuming`).
|
|
2712
2773
|
- When sending a message for an inactive, resumable session, calls `resumeSession(...)` instead of the normal send flow.
|
|
2713
|
-
|
|
2774
|
+
- Adds a profile “fixed per session” modal via `profileId`/`onProfileClick` and a hardcoded English message (not translated).
|
|
2775
|
+
- Shows resume status in `connectionStatus` text/pulsing when resuming (`t('session.resuming')`) and uses `t('session.inactiveResumable')`/`t('session.inactiveNotResumable')`.
|
|
2776
|
+
- Adds `resumeSession` RPC operation in `sync/ops.ts` (machine RPC). `SessionView.tsx` also starts importing `canResumeSession(...)`/`getAgentSessionId(...)` from `utils/agentCapabilities.ts` (implemented in later commits).
|
|
2714
2777
|
- Coherence:
|
|
2715
2778
|
- This is the initial end-user “resume inactive sessions” feature landing. It is cohesive for the resume topic.
|
|
2716
2779
|
- As written here, the UI passes `agentSessionId` across the wire; later commits refactor this away (see 079). During rewrite, squash/reconcile to the final design.
|
|
2780
|
+
- The commit message body mentions “translations for session resume states”, but this commit does not add translation entries; it only introduces new `t('session.*')` usages + a hardcoded English modal string.
|
|
2781
|
+
- `SessionView.tsx` imports `canResumeSession`/`getAgentSessionId` from `utils/agentCapabilities.ts`, but this commit does not modify that module; it likely relies on later commits to add these exports. During rewrite, this should be squashed/reordered to keep intermediate commits typecheck-safe.
|
|
2717
2782
|
|
|
2718
2783
|
### Verdict
|
|
2719
2784
|
|
|
@@ -2727,7 +2792,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=cd5771e50881 patchFile=/
|
|
|
2727
2792
|
---
|
|
2728
2793
|
|
|
2729
2794
|
## 079 2026-01-12 456e2ad8e2b8 `resume`
|
|
2730
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=456e2ad8e2b8 patchFile=/tmp/leeroy-wip-pass2/079.patch patchSha256=1038412aa6be537c540443b64b6437f4eb00d0315c79e4e819e2c68d0eb0a234 patchBytes=10666 patchLines=265 notesReviewed=
|
|
2795
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=456e2ad8e2b8 patchFile=/tmp/leeroy-wip-pass2/079.patch patchSha256=1038412aa6be537c540443b64b6437f4eb00d0315c79e4e819e2c68d0eb0a234 patchBytes=10666 patchLines=265 notesReviewed=yes reviewedAt=2026-01-24T20:30:50+0100 notesUpdated=yes
|
|
2731
2796
|
|
|
2732
2797
|
- Subject: refactor(resume): don't require agentSessionId from UI
|
|
2733
2798
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2739,11 +2804,13 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=456e2ad8e2b8 patchFile=/
|
|
|
2739
2804
|
- `sync/ops.ts` / `SessionView.tsx`:
|
|
2740
2805
|
- Removes `agentSessionId` from the resume request shape; UI resumes by Happy session id and agent type only.
|
|
2741
2806
|
- This pushes “derive vendor resume id” responsibility to the machine/daemon (more secure + less UI coupling to vendor internals).
|
|
2807
|
+
- Likely leaves an unused `getAgentSessionId` import in `SessionView.tsx` (the callsite is removed but the patch does not remove the import); clean up during history rewrite.
|
|
2742
2808
|
- `utils/agentCapabilities.ts`:
|
|
2743
2809
|
- Broadens `canAgentResume(...)` to accept unknown strings safely.
|
|
2744
2810
|
- Adds `SessionMetadata` shape + helpers:
|
|
2745
2811
|
- `getAgentSessionIdField(...)`, `canResumeSession(...)`, and `getAgentSessionId(...)`.
|
|
2746
2812
|
- Adds session-state translation keys (`session.resuming`, `session.resumeFailed`, etc.).
|
|
2813
|
+
- Noted: Spanish `inactiveResumable` uses `reanundable` (likely a typo for `reanudable`).
|
|
2747
2814
|
- Coherence:
|
|
2748
2815
|
- Matches subject and is a solid architectural improvement for the resume feature.
|
|
2749
2816
|
|
|
@@ -2759,7 +2826,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=456e2ad8e2b8 patchFile=/
|
|
|
2759
2826
|
---
|
|
2760
2827
|
|
|
2761
2828
|
## 080 2026-01-11 9b0069e3d30c `fork`
|
|
2762
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b0069e3d30c patchFile=/tmp/leeroy-wip-pass2/080.patch patchSha256=d0775d17447e5f09b0c0043294929d4b05c4f7a900063c95323c37df142a214b patchBytes=13508 patchLines=247 notesReviewed=
|
|
2829
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b0069e3d30c patchFile=/tmp/leeroy-wip-pass2/080.patch patchSha256=d0775d17447e5f09b0c0043294929d4b05c4f7a900063c95323c37df142a214b patchBytes=13508 patchLines=247 notesReviewed=yes reviewedAt=2026-01-24T20:32:11+0100 notesUpdated=yes
|
|
2763
2830
|
|
|
2764
2831
|
- Subject: feat(fork): enable Codex resume support
|
|
2765
2832
|
- Reasons: fork-only behavior (should not go upstream as-is)
|
|
@@ -2771,9 +2838,9 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b0069e3d30c patchFile=/
|
|
|
2771
2838
|
- `utils/agentCapabilities.ts` adds `'codex'` to `RESUMABLE_AGENTS` with an explicit “Fork” note.
|
|
2772
2839
|
- Session Info UX in `app/(app)/session/[id]/info.tsx`:
|
|
2773
2840
|
- Adds a “Codex Session ID” item with copy-to-clipboard behavior (uses translation keys added earlier).
|
|
2774
|
-
- Refactors copy-command handlers (`handleCopyCommand` helper) and unifies “copy resume command”
|
|
2841
|
+
- Refactors copy-command handlers (`handleCopyCommand` helper) and unifies “copy resume command” into `happy resume <happySessionId>` (shown only for inactive sessions that have an agent session ID in metadata).
|
|
2775
2842
|
- `sync/storageTypes.ts` appears to add/validate `codexSessionId` metadata shape (schema alignment).
|
|
2776
|
-
- Adds
|
|
2843
|
+
- Adds i18n key `sessionInfo.copyResumeCommand` across locales (Codex Session ID translation keys were added earlier in 076).
|
|
2777
2844
|
- Coherence:
|
|
2778
2845
|
- This is still within the “resume support” topic, but it’s fork-specific (Codex resume enablement) and should be isolated from any upstream PR stack.
|
|
2779
2846
|
|
|
@@ -2789,7 +2856,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=9b0069e3d30c patchFile=/
|
|
|
2789
2856
|
---
|
|
2790
2857
|
|
|
2791
2858
|
## 081 2026-01-22 4ddaef02210e `sync`
|
|
2792
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4ddaef02210e patchFile=/tmp/leeroy-wip-pass2/081.patch patchSha256=4898c477cf549a2bf357661b4ade980ba45511fb0c0b93ad24c80baa3e93323d patchBytes=1566 patchLines=43 notesReviewed=
|
|
2859
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4ddaef02210e patchFile=/tmp/leeroy-wip-pass2/081.patch patchSha256=4898c477cf549a2bf357661b4ade980ba45511fb0c0b93ad24c80baa3e93323d patchBytes=1566 patchLines=43 notesReviewed=yes reviewedAt=2026-01-24T20:33:19+0100 notesUpdated=yes
|
|
2793
2860
|
|
|
2794
2861
|
- Subject: fix(sync): omit model meta for queued messages
|
|
2795
2862
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -2799,7 +2866,9 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4ddaef02210e patchFile=/
|
|
|
2799
2866
|
- Diffstat: `1 file changed, 7 insertions(+), 6 deletions(-)`
|
|
2800
2867
|
- What changed:
|
|
2801
2868
|
- `sync/sync.ts`:
|
|
2802
|
-
- Computes `model` from `(session.metadata.flavor, session.modelMode)
|
|
2869
|
+
- Computes `model` from `(session.metadata.flavor, session.modelMode)`:
|
|
2870
|
+
- For Gemini: defaults `modelMode` to `'gemini-2.5-pro'` when unset, and includes `model` in outgoing message meta when `modelMode !== 'default'`.
|
|
2871
|
+
- For non-Gemini: omits `model` (`undefined`) from outgoing meta.
|
|
2803
2872
|
- Switches meta construction to `buildOutgoingMessageMeta({ ... })` and drops `fallbackModel`.
|
|
2804
2873
|
- Coherence:
|
|
2805
2874
|
- Matches subject; this is a small correctness tweak to avoid sending irrelevant/incorrect model metadata in queued/outgoing messages.
|
|
@@ -2816,7 +2885,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=4ddaef02210e patchFile=/
|
|
|
2816
2885
|
---
|
|
2817
2886
|
|
|
2818
2887
|
## 082 2026-01-12 3fbdc10018fe `tmux`
|
|
2819
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=3fbdc10018fe patchFile=/tmp/leeroy-wip-pass2/082.patch patchSha256=f2cc8568717d548920cea037c3b6e362272f870517c93ed7e2a86d9115651d03 patchBytes=30647 patchLines=723 notesReviewed=
|
|
2888
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=3fbdc10018fe patchFile=/tmp/leeroy-wip-pass2/082.patch patchSha256=f2cc8568717d548920cea037c3b6e362272f870517c93ed7e2a86d9115651d03 patchBytes=30647 patchLines=723 notesReviewed=yes reviewedAt=2026-01-24T20:34:54+0100 notesUpdated=yes
|
|
2820
2889
|
|
|
2821
2890
|
- Subject: fix: tmux parsing/targeting + review feedback
|
|
2822
2891
|
- Reasons: safety/reliability-sensitive area (process control) + non-Conventional-Commits subject
|
|
@@ -2834,8 +2903,10 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=3fbdc10018fe patchFile=/
|
|
|
2834
2903
|
- Removes env-derived session/window fields from `TmuxSessionInfo` (only keeps `env_pane` + socket path, and relies on tmux query for session/window).
|
|
2835
2904
|
- Additional review feedback items are included (mixed into the same commit):
|
|
2836
2905
|
- Aligns `Machine.metadata` typing to runtime (nullable).
|
|
2837
|
-
- Tightens
|
|
2838
|
-
-
|
|
2906
|
+
- Tightens script/test behavior (`ripgrep_launcher`, `env-wrapper`, continue-test script) and clarifies failure modes (missing args, signal termination).
|
|
2907
|
+
- Adjusts CLI API sending behavior: introduces `ApiSessionClient.canSend(...)` and now returns early (drops the emit) when the socket is disconnected for multiple message/event types (may change socket.io buffering semantics vs prior behavior).
|
|
2908
|
+
- Improves resume/continue ergonomics and cancellation: supports `-r` as `--resume` alias and wires SIGINT/SIGTERM to abort offline `claudeLocal` runs.
|
|
2909
|
+
- Edits a CLI doc file (`cli/docs/bug-fix-plan-2025-01-15-athundt.md`) rather than deleting it.
|
|
2839
2910
|
- Coherence:
|
|
2840
2911
|
- The tmux portion is cohesive and important for correctness.
|
|
2841
2912
|
- The extra “misc scripts/tests/typing” changes make the commit mixed; during rewrite we should consider splitting to keep tmux fixes isolated and bisectable.
|
|
@@ -2857,7 +2928,7 @@ Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=3fbdc10018fe patchFile=/
|
|
|
2857
2928
|
---
|
|
2858
2929
|
|
|
2859
2930
|
## 083 2026-01-13 7292a29822bb `daemon`
|
|
2860
|
-
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7292a29822bb patchFile=/tmp/leeroy-wip-pass2/083.patch patchSha256=40cb173cb1aa03a44ac0c18b4e07de6b8872336399fb768bf21f7a60daef97ab patchBytes=5066 patchLines=99 notesReviewed=
|
|
2931
|
+
Pass2FullDiff: CAPTURED at 2026-01-24T17:39:06+0100 sha=7292a29822bb patchFile=/tmp/leeroy-wip-pass2/083.patch patchSha256=40cb173cb1aa03a44ac0c18b4e07de6b8872336399fb768bf21f7a60daef97ab patchBytes=5066 patchLines=99 notesReviewed=yes reviewedAt=2026-01-24T20:36:02+0100 notesUpdated=no
|
|
2861
2932
|
|
|
2862
2933
|
- Subject: fix(daemon): do not apply CLI active profile to GUI-spawned sessions
|
|
2863
2934
|
- Reasons: full manual review coverage (was not in the manual-review queue)
|
|
@@ -12,28 +12,74 @@ This avoids Docker/container UX issues (browser opening, Expo networking, file w
|
|
|
12
12
|
brew install lima
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
### 2) Create a VM
|
|
15
|
+
### 2) Create + configure a VM (recommended script)
|
|
16
|
+
|
|
17
|
+
On your macOS host (this repo):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
./scripts/provision/macos-lima-happy-vm.sh happy-test
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This creates the VM if needed and configures **localhost port forwarding** for the port ranges used by our VM defaults.
|
|
24
|
+
(This is important because the Expo web app uses WebCrypto and needs a secure context like `http://localhost`.)
|
|
25
|
+
|
|
26
|
+
### 2b) Manual setup (if you prefer)
|
|
16
27
|
|
|
17
28
|
```bash
|
|
18
29
|
limactl create --name happy-pr --tty=false template://ubuntu-24.04
|
|
19
|
-
limactl start happy-pr
|
|
30
|
+
limactl start happy-pr
|
|
20
31
|
```
|
|
21
32
|
|
|
22
|
-
###
|
|
33
|
+
### 2c) Host access (ports + browser URLs)
|
|
34
|
+
|
|
35
|
+
When you want to open Happy/Expo URLs in your macOS browser, **use localhost port forwarding**.
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
Why this matters: the Expo web app uses WebCrypto (`crypto.subtle`) via `expo-crypto` for things like key derivation.
|
|
38
|
+
Browsers only expose WebCrypto in **secure contexts**:
|
|
39
|
+
- `https://...`
|
|
40
|
+
- `http://localhost`, `http://127.0.0.1`, and `http://*.localhost`
|
|
25
41
|
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
If you open the UI via a VM LAN IP like `http://192.168.x.y:PORT`, the browser treats it as **insecure** and you can hit errors like:
|
|
43
|
+
`TypeError: Cannot read properties of undefined (reading 'digest')`.
|
|
28
44
|
|
|
29
|
-
|
|
45
|
+
#### Configure port forwarding (recommended)
|
|
46
|
+
|
|
47
|
+
Edit the instance config on the **macOS host**:
|
|
30
48
|
|
|
31
49
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
limactl stop happy-pr || true
|
|
51
|
+
open -a TextEdit ~/.lima/happy-pr/lima.yaml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Add a `portForwards` section to forward the Happy Stacks VM port ranges to your host `localhost`:
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
portForwards:
|
|
58
|
+
# Stack/server ports (default VM range from our provision script)
|
|
59
|
+
- guestPortRange: [13000, 13999]
|
|
60
|
+
hostPortRange: [13000, 13999]
|
|
61
|
+
|
|
62
|
+
# Expo dev-server (web) ports (default VM range from our provision script)
|
|
63
|
+
- guestPortRange: [18000, 19099]
|
|
64
|
+
hostPortRange: [18000, 19099]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then restart the VM:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
limactl start happy-pr
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Optional: IP-based access (only when you need LAN)
|
|
74
|
+
|
|
75
|
+
If you explicitly need to access guest services by VM IP (e.g. for testing from another device), you can enable `vzNAT`:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
limactl stop happy-pr || true
|
|
79
|
+
limactl start happy-pr --network vzNAT
|
|
34
80
|
```
|
|
35
81
|
|
|
36
|
-
Note:
|
|
82
|
+
Note: IP-based URLs (like `http://192.168...`) may break web-only crypto flows unless you use HTTPS or a browser dev override.
|
|
37
83
|
|
|
38
84
|
### 3) Provision the VM (Node + build deps)
|
|
39
85
|
|
|
@@ -56,7 +102,7 @@ export NVM_DIR="$HOME/.nvm"
|
|
|
56
102
|
If your goal is to **work on changes** (not just review a PR), you can run the dev profile:
|
|
57
103
|
|
|
58
104
|
```bash
|
|
59
|
-
npx --yes happy-stacks@latest setup --profile=dev
|
|
105
|
+
npx --yes happy-stacks@latest setup --profile=dev --bind=loopback
|
|
60
106
|
```
|
|
61
107
|
|
|
62
108
|
Notes:
|
|
@@ -73,7 +119,7 @@ npx --yes happy-stacks@latest review-pr \
|
|
|
73
119
|
--no-mobile \
|
|
74
120
|
--keep-sandbox \
|
|
75
121
|
--verbose \
|
|
76
|
-
-- --bind=
|
|
122
|
+
-- --bind=loopback
|
|
77
123
|
```
|
|
78
124
|
|
|
79
125
|
Notes:
|
package/package.json
CHANGED
|
@@ -118,6 +118,10 @@ fi
|
|
|
118
118
|
|
|
119
119
|
cat <<'EOF'
|
|
120
120
|
[provision] tip: If you want to open Happy/Expo URLs in your macOS browser:
|
|
121
|
-
-
|
|
122
|
-
|
|
121
|
+
- Prefer localhost port forwarding (secure context) instead of opening `http://<vm-ip>:<port>`
|
|
122
|
+
(Expo web uses WebCrypto and may fail on insecure origins).
|
|
123
|
+
- On the macOS host, add `portForwards` for the VM port ranges in `~/.lima/<name>/lima.yaml`,
|
|
124
|
+
then restart the VM.
|
|
125
|
+
- Then run happy-stacks with: `--bind=loopback` (or omit `--bind`) and open the `http://localhost/...`
|
|
126
|
+
or `http://*.localhost/...` URLs.
|
|
123
127
|
EOF
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Create/configure a Lima VM for testing happy-stacks in an isolated Linux environment,
|
|
5
|
+
# while still opening the Expo web UI on the macOS host via localhost port forwarding
|
|
6
|
+
# (required for WebCrypto/secure-context APIs).
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# ./scripts/provision/macos-lima-happy-vm.sh [vm-name]
|
|
10
|
+
#
|
|
11
|
+
# Defaults:
|
|
12
|
+
# vm-name: happy-test
|
|
13
|
+
# template: ubuntu-24.04
|
|
14
|
+
#
|
|
15
|
+
# What it does:
|
|
16
|
+
# - creates the VM (if missing)
|
|
17
|
+
# - injects port forwarding rules for the Happy Stacks VM port ranges
|
|
18
|
+
# - restarts the VM so the rules take effect
|
|
19
|
+
# - prints next steps (provision script + happy-stacks commands)
|
|
20
|
+
|
|
21
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
22
|
+
cat <<'EOF'
|
|
23
|
+
Usage:
|
|
24
|
+
./scripts/provision/macos-lima-happy-vm.sh [vm-name]
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
./scripts/provision/macos-lima-happy-vm.sh # uses "happy-test"
|
|
28
|
+
./scripts/provision/macos-lima-happy-vm.sh happy # uses "happy"
|
|
29
|
+
./scripts/provision/macos-lima-happy-vm.sh happy-vm # uses "happy-vm"
|
|
30
|
+
|
|
31
|
+
Notes:
|
|
32
|
+
- This is intended to be run on the macOS host (not inside the VM).
|
|
33
|
+
- It configures localhost port forwarding so you can open http://localhost / http://*.localhost
|
|
34
|
+
in your macOS browser (required for WebCrypto APIs used by Expo web).
|
|
35
|
+
EOF
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
40
|
+
echo "[lima] expected macOS (Darwin); got: $(uname -s)" >&2
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if ! command -v limactl >/dev/null 2>&1; then
|
|
45
|
+
echo "[lima] limactl not found. Install Lima first (example: brew install lima)." >&2
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
VM_NAME="${1:-happy-test}"
|
|
50
|
+
TEMPLATE="${LIMA_TEMPLATE:-ubuntu-24.04}"
|
|
51
|
+
LIMA_DIR="${HOME}/.lima/${VM_NAME}"
|
|
52
|
+
LIMA_YAML="${LIMA_DIR}/lima.yaml"
|
|
53
|
+
|
|
54
|
+
echo "[lima] vm: ${VM_NAME}"
|
|
55
|
+
echo "[lima] template: ${TEMPLATE}"
|
|
56
|
+
|
|
57
|
+
if [[ ! -f "${LIMA_YAML}" ]]; then
|
|
58
|
+
echo "[lima] creating VM..."
|
|
59
|
+
limactl create --name "${VM_NAME}" --tty=false "template://${TEMPLATE}"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
if [[ ! -f "${LIMA_YAML}" ]]; then
|
|
63
|
+
echo "[lima] expected instance config at: ${LIMA_YAML}" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo "[lima] stopping VM (if running)..."
|
|
68
|
+
limactl stop "${VM_NAME}" >/dev/null 2>&1 || true
|
|
69
|
+
|
|
70
|
+
echo "[lima] configuring port forwarding (localhost)..."
|
|
71
|
+
cp -a "${LIMA_YAML}" "${LIMA_YAML}.bak.$(date +%Y%m%d-%H%M%S)"
|
|
72
|
+
|
|
73
|
+
python3 - <<'PY'
|
|
74
|
+
import os, re
|
|
75
|
+
from pathlib import Path
|
|
76
|
+
|
|
77
|
+
vm_name = os.environ["VM_NAME"]
|
|
78
|
+
path = Path(os.environ["LIMA_YAML"])
|
|
79
|
+
text = path.read_text(encoding="utf-8")
|
|
80
|
+
|
|
81
|
+
MARK_BEGIN = "# --- happy-stacks port forwards (added by happy-local) ---"
|
|
82
|
+
MARK_END = "# --- /happy-stacks port forwards ---"
|
|
83
|
+
|
|
84
|
+
entries = [
|
|
85
|
+
" - guestPortRange: [13000, 13999]\n hostPortRange: [13000, 13999]\n",
|
|
86
|
+
" - guestPortRange: [18000, 19099]\n hostPortRange: [18000, 19099]\n",
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
block_as_section = (
|
|
90
|
+
f"\n{MARK_BEGIN}\n"
|
|
91
|
+
"portForwards:\n"
|
|
92
|
+
+ "".join(entries) +
|
|
93
|
+
f"{MARK_END}\n"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
block_as_list_items = (
|
|
97
|
+
f" # --- happy-stacks port forwards (added by happy-local) ---\n"
|
|
98
|
+
+ "".join(entries) +
|
|
99
|
+
f" # --- /happy-stacks port forwards ---\n"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if MARK_BEGIN in text and MARK_END in text:
|
|
103
|
+
text = re.sub(
|
|
104
|
+
re.escape(MARK_BEGIN) + r"[\\s\\S]*?" + re.escape(MARK_END) + r"\\n?",
|
|
105
|
+
block_as_section.strip("\n") + "\n",
|
|
106
|
+
text,
|
|
107
|
+
flags=re.MULTILINE,
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
m = re.search(r"^portForwards:\\s*$", text, flags=re.MULTILINE)
|
|
111
|
+
if m:
|
|
112
|
+
insert_at = m.end()
|
|
113
|
+
text = text[:insert_at] + "\n" + block_as_list_items + text[insert_at:]
|
|
114
|
+
else:
|
|
115
|
+
text = text.rstrip() + block_as_section
|
|
116
|
+
|
|
117
|
+
path.write_text(text, encoding="utf-8")
|
|
118
|
+
print(f"[lima] updated {path} ({vm_name})")
|
|
119
|
+
PY
|
|
120
|
+
|
|
121
|
+
echo "[lima] starting VM..."
|
|
122
|
+
limactl start "${VM_NAME}"
|
|
123
|
+
|
|
124
|
+
cat <<EOF
|
|
125
|
+
|
|
126
|
+
[lima] done.
|
|
127
|
+
|
|
128
|
+
Next steps:
|
|
129
|
+
limactl shell ${VM_NAME}
|
|
130
|
+
|
|
131
|
+
Inside the VM:
|
|
132
|
+
curl -fsSL https://raw.githubusercontent.com/leeroybrun/happy-local/main/scripts/provision/linux-ubuntu-review-pr.sh -o /tmp/linux-ubuntu-review-pr.sh \\
|
|
133
|
+
&& chmod +x /tmp/linux-ubuntu-review-pr.sh \\
|
|
134
|
+
&& /tmp/linux-ubuntu-review-pr.sh
|
|
135
|
+
|
|
136
|
+
Then:
|
|
137
|
+
npx --yes happy-stacks@latest setup --profile=dev --bind=loopback
|
|
138
|
+
|
|
139
|
+
Tip:
|
|
140
|
+
Open the printed URLs on your macOS host via http://localhost:<port> or http://*.localhost:<port>.
|
|
141
|
+
EOF
|
|
142
|
+
|
package/scripts/setup.mjs
CHANGED
|
@@ -288,7 +288,11 @@ async function maybeConfigureAuthDefaults({ rootDir, profile, interactive }) {
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
// Guided wizard: creates stack, starts temporary UI/server, stores dev key (optional), logs in CLI.
|
|
291
|
-
await runNodeScript({
|
|
291
|
+
await runNodeScript({
|
|
292
|
+
rootDir,
|
|
293
|
+
rel: 'scripts/stack.mjs',
|
|
294
|
+
args: ['create-dev-auth-seed', 'dev-auth', '--login', '--skip-default-seed'],
|
|
295
|
+
});
|
|
292
296
|
} else {
|
|
293
297
|
// eslint-disable-next-line no-console
|
|
294
298
|
console.log(dim(`Found an existing ${cyan('dev-auth')} seed stack; configuring auth reuse for new stacks.`));
|
|
@@ -306,6 +310,22 @@ async function maybeConfigureAuthDefaults({ rootDir, profile, interactive }) {
|
|
|
306
310
|
],
|
|
307
311
|
});
|
|
308
312
|
|
|
313
|
+
{
|
|
314
|
+
const envLocalPath = join(getCanonicalHomeDir(), 'env.local');
|
|
315
|
+
// eslint-disable-next-line no-console
|
|
316
|
+
console.log('');
|
|
317
|
+
// eslint-disable-next-line no-console
|
|
318
|
+
console.log(bold('Automatic sign-in for new stacks'));
|
|
319
|
+
// eslint-disable-next-line no-console
|
|
320
|
+
console.log(dim(`Enabled: when you create a new stack, Happy Stacks will reuse auth from ${cyan(seedChoice)} automatically.`));
|
|
321
|
+
// eslint-disable-next-line no-console
|
|
322
|
+
console.log(`${dim('Seed from:')} ${cyan(seedChoice)}`);
|
|
323
|
+
// eslint-disable-next-line no-console
|
|
324
|
+
console.log(`${dim('Mode:')} ${linkChoice === 'link' ? 'symlink' : 'copy'} ${dim(linkChoice === 'link' ? '(recommended)' : '')}`.trim());
|
|
325
|
+
// eslint-disable-next-line no-console
|
|
326
|
+
console.log(dim(`Config: ${envLocalPath}`));
|
|
327
|
+
}
|
|
328
|
+
|
|
309
329
|
// Optional: seed existing stacks now (useful if the user already has stacks).
|
|
310
330
|
const allStacks = await listAllStackNames().catch(() => ['main']);
|
|
311
331
|
const candidateTargets = allStacks.filter((s) => s !== 'main' && s !== seedChoice);
|
|
@@ -517,7 +537,7 @@ async function cmdSetup({ rootDir, argv }) {
|
|
|
517
537
|
`- ${cyan('init')}: set up Happy Stacks home + shims`,
|
|
518
538
|
`- ${cyan('bootstrap')}: clone/install components + dev tooling`,
|
|
519
539
|
`- ${cyan('auth')}: (recommended) set up a ${cyan('dev-auth')} seed stack (login once, reuse everywhere)`,
|
|
520
|
-
`- ${cyan('stacks')}: (recommended) create an isolated dev stack (
|
|
540
|
+
`- ${cyan('stacks')}: (recommended) next you’ll create an isolated dev stack for day-to-day work (keeps main stable)`,
|
|
521
541
|
`- ${cyan('mobile')}: (optional) install the iOS dev-client (for phone testing)`,
|
|
522
542
|
'',
|
|
523
543
|
dim(`Tip: for PR work, use ${cyan('worktrees')} (isolated branches) + ${cyan('stacks')} (isolated runtime state).`),
|
|
@@ -917,27 +937,6 @@ async function cmdSetup({ rootDir, argv }) {
|
|
|
917
937
|
// Recommended: dev-auth seed stack setup (login once, reuse across stacks).
|
|
918
938
|
await maybeConfigureAuthDefaults({ rootDir, profile, interactive });
|
|
919
939
|
|
|
920
|
-
// Recommended: create an isolated dev stack (keeps main stable).
|
|
921
|
-
const createStack = await withRl(async (rl) => {
|
|
922
|
-
return await promptSelect(rl, {
|
|
923
|
-
title: `${bold('Stacks')}\n${dim('Recommended: keep main stable by doing dev work in a dedicated stack.')}`,
|
|
924
|
-
options: [
|
|
925
|
-
{ label: `yes (${green('recommended')}) — create a new development stack`, value: true },
|
|
926
|
-
{ label: `no — I will use ${cyan('main')} for now`, value: false },
|
|
927
|
-
],
|
|
928
|
-
defaultIndex: 0,
|
|
929
|
-
});
|
|
930
|
-
});
|
|
931
|
-
if (createStack) {
|
|
932
|
-
await runNodeScriptMaybeQuiet({
|
|
933
|
-
label: 'create dev stack',
|
|
934
|
-
rootDir,
|
|
935
|
-
rel: 'scripts/stack.mjs',
|
|
936
|
-
args: ['new', '--interactive'],
|
|
937
|
-
interactiveChild: true,
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
|
|
941
940
|
// Optional: mobile dev-client install (macOS only).
|
|
942
941
|
if (process.platform === 'darwin') {
|
|
943
942
|
const installMobile = await withRl(async (rl) => {
|
|
@@ -1129,21 +1128,15 @@ async function cmdSetup({ rootDir, argv }) {
|
|
|
1129
1128
|
// eslint-disable-next-line no-console
|
|
1130
1129
|
console.log(dim('Next steps (development):'));
|
|
1131
1130
|
// eslint-disable-next-line no-console
|
|
1132
|
-
console.log(` ${yellow('happys dev')}
|
|
1131
|
+
console.log(` ${yellow('happys stack new dev --interactive')} ${dim('# create a dedicated dev stack (recommended)')}`);
|
|
1132
|
+
// eslint-disable-next-line no-console
|
|
1133
|
+
console.log(` ${yellow('happys stack dev dev')} ${dim('# run that stack (server + daemon + Expo web)')}`);
|
|
1133
1134
|
// eslint-disable-next-line no-console
|
|
1134
1135
|
console.log(` ${yellow('happys wt new ...')} ${dim('# create a worktree for a branch/PR')}`);
|
|
1135
1136
|
// eslint-disable-next-line no-console
|
|
1136
1137
|
console.log(` ${yellow('happys stack new ...')} ${dim('# create an isolated runtime stack')}`);
|
|
1137
1138
|
// eslint-disable-next-line no-console
|
|
1138
1139
|
console.log(` ${yellow('happys stack dev <name>')} ${dim('# run a specific stack')}`);
|
|
1139
|
-
// eslint-disable-next-line no-console
|
|
1140
|
-
console.log('');
|
|
1141
|
-
// eslint-disable-next-line no-console
|
|
1142
|
-
console.log(dim('Legacy note: if you still have split repos/branches (pre-monorepo), run:'));
|
|
1143
|
-
// eslint-disable-next-line no-console
|
|
1144
|
-
console.log(` ${yellow('happys import')} ${dim('# guided import + optional monorepo migration')}`);
|
|
1145
|
-
// eslint-disable-next-line no-console
|
|
1146
|
-
console.log(` ${yellow('happys import llm --copy')} ${dim('# copy/paste an LLM prompt to drive the flow')}`);
|
|
1147
1140
|
}
|
|
1148
1141
|
}
|
|
1149
1142
|
|
package/scripts/stack.mjs
CHANGED
|
@@ -2158,6 +2158,8 @@ async function cmdCreateDevAuthSeed({ rootDir, argv }) {
|
|
|
2158
2158
|
const serverComponent = (kv.get('--server') ?? '').trim() || 'happy-server-light';
|
|
2159
2159
|
const interactive = !flags.has('--non-interactive') && (flags.has('--interactive') || isTty());
|
|
2160
2160
|
const bindMode = resolveBindModeFromArgs({ flags, kv });
|
|
2161
|
+
const skipDefaultSeed =
|
|
2162
|
+
flags.has('--skip-default-seed') || flags.has('--no-default-seed') || flags.has('--no-configure-default-seed');
|
|
2161
2163
|
const forceLogin =
|
|
2162
2164
|
flags.has('--login') ? true : flags.has('--no-login') || flags.has('--skip-login') ? false : null;
|
|
2163
2165
|
|
|
@@ -2285,6 +2287,7 @@ async function cmdCreateDevAuthSeed({ rootDir, argv }) {
|
|
|
2285
2287
|
|
|
2286
2288
|
let serverProc = null;
|
|
2287
2289
|
let uiProc = null;
|
|
2290
|
+
let uiStopRequested = false;
|
|
2288
2291
|
try {
|
|
2289
2292
|
steps.start('start temporary server');
|
|
2290
2293
|
const started = await startDevServer({
|
|
@@ -2333,6 +2336,8 @@ async function cmdCreateDevAuthSeed({ rootDir, argv }) {
|
|
|
2333
2336
|
|
|
2334
2337
|
if (quietAuthFlow && uiProc) {
|
|
2335
2338
|
uiProc.once('exit', (code, sig) => {
|
|
2339
|
+
// We intentionally SIGINT Expo when we're done with login.
|
|
2340
|
+
if (uiStopRequested && (sig === 'SIGINT' || sig === 'SIGTERM')) return;
|
|
2336
2341
|
if (code === 0) return;
|
|
2337
2342
|
void (async () => {
|
|
2338
2343
|
const c = typeof code === 'number' ? code : null;
|
|
@@ -2405,6 +2410,7 @@ async function cmdCreateDevAuthSeed({ rootDir, argv }) {
|
|
|
2405
2410
|
if (uiProc) {
|
|
2406
2411
|
console.log('');
|
|
2407
2412
|
console.log(`[stack] stopping temporary UI (pid=${uiProc.pid})...`);
|
|
2413
|
+
uiStopRequested = true;
|
|
2408
2414
|
killProcessTree(uiProc, 'SIGINT');
|
|
2409
2415
|
await Promise.race([
|
|
2410
2416
|
new Promise((resolve) => uiProc.on('exit', resolve)),
|
|
@@ -2430,26 +2436,33 @@ async function cmdCreateDevAuthSeed({ rootDir, argv }) {
|
|
|
2430
2436
|
console.log(`[stack] skipping guided login. You can do it later with: ${yellow(`happys stack auth ${name} login`)}`);
|
|
2431
2437
|
}
|
|
2432
2438
|
|
|
2433
|
-
|
|
2434
|
-
title: `${bold('Default auth seed')}\n${dim(`Recommended: set ${cyan(name)} as the default seed for new stacks (writes ${getHomeEnvLocalPath()}).`)}`,
|
|
2435
|
-
options: [
|
|
2436
|
-
{ label: `yes (${green('recommended')}) — enable auto-seeding for new stacks`, value: true },
|
|
2437
|
-
{ label: `no — I will configure this later`, value: false },
|
|
2438
|
-
],
|
|
2439
|
-
defaultIndex: 0,
|
|
2440
|
-
});
|
|
2441
|
-
if (wantEnv) {
|
|
2439
|
+
if (!skipDefaultSeed) {
|
|
2442
2440
|
const envLocalPath = getHomeEnvLocalPath();
|
|
2443
|
-
await
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
{
|
|
2447
|
-
{
|
|
2441
|
+
const wantEnv = await promptSelect(rl, {
|
|
2442
|
+
title:
|
|
2443
|
+
`${bold('Automatic sign-in for new stacks')}\n` +
|
|
2444
|
+
`${dim(`Recommended: when you create a new stack, copy/symlink auth from ${cyan(name)} automatically.`)}\n` +
|
|
2445
|
+
`${dim(`This writes ${cyan('HAPPY_STACKS_AUTO_AUTH_SEED=1')} + ${cyan(`HAPPY_STACKS_AUTH_SEED_FROM=${name}`)} in ${envLocalPath}.`)}`,
|
|
2446
|
+
options: [
|
|
2447
|
+
{ label: `yes (${green('recommended')}) — enable automatic auth seeding`, value: true },
|
|
2448
|
+
{ label: `no — I will configure this later`, value: false },
|
|
2448
2449
|
],
|
|
2450
|
+
defaultIndex: 0,
|
|
2449
2451
|
});
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2452
|
+
if (wantEnv) {
|
|
2453
|
+
await ensureEnvFileUpdated({
|
|
2454
|
+
envPath: envLocalPath,
|
|
2455
|
+
updates: [
|
|
2456
|
+
{ key: 'HAPPY_STACKS_AUTH_SEED_FROM', value: name },
|
|
2457
|
+
{ key: 'HAPPY_STACKS_AUTO_AUTH_SEED', value: '1' },
|
|
2458
|
+
],
|
|
2459
|
+
});
|
|
2460
|
+
console.log(`[stack] updated: ${envLocalPath}`);
|
|
2461
|
+
} else {
|
|
2462
|
+
console.log(
|
|
2463
|
+
`[stack] tip: set in ${envLocalPath}: HAPPY_STACKS_AUTH_SEED_FROM=${name} and HAPPY_STACKS_AUTO_AUTH_SEED=1`
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2453
2466
|
}
|
|
2454
2467
|
|
|
2455
2468
|
if (!savedDevKey) {
|
|
@@ -3536,7 +3549,7 @@ async function main() {
|
|
|
3536
3549
|
' happys stack duplicate <from> <to> [--duplicate-worktrees] [--deps=none|link|install|link-or-install] [--json]',
|
|
3537
3550
|
' happys stack info <name> [--json]',
|
|
3538
3551
|
' happys stack pr <name> --happy=<pr-url|number> [--happy-server-light=<pr-url|number>] [--dev|--start] [--json] [-- ...]',
|
|
3539
|
-
' happys stack create-dev-auth-seed [name] [--server=happy-server|happy-server-light] [--login|--no-login] [--non-interactive] [--json]',
|
|
3552
|
+
' happys stack create-dev-auth-seed [name] [--server=happy-server|happy-server-light] [--login|--no-login] [--skip-default-seed] [--non-interactive] [--json]',
|
|
3540
3553
|
' happys stack daemon <name> start|stop|restart|status [--json]',
|
|
3541
3554
|
' happys stack happy <name> [-- ...]',
|
|
3542
3555
|
' happys stack env <name> set KEY=VALUE [KEY2=VALUE2...] | unset KEY [KEY2...] | get KEY | list | path [--json]',
|