# leeroy-wip commit analysis (oldest → newest)

Generated: 2026-01-24
Worktree: /Users/leeroy/Documents/Development/happy-local/components/.worktrees/happy/slopus/tmp/leeroy-wip
Range: upstream/main..HEAD
Upstream main SHA (at generation time): 8691991895b9c12ebe58cc7d6b178696765ee31f
Merge-base: 40792d9eddf7fdaabd375e00134c5cfe5aea2db5
HEAD: c803115dcbdcd55c036e47c0f0cfd6e1bceb9f74
Commits: 249

## Notes

- This pass includes: full message body, name-status, diffstat, and an automated diff summary (function/class/type identifiers when detectable).
- Sections marked “Manual review needed: YES” should be validated by reading the actual diff (especially large or safety-sensitive commits).

---

## 001 2026-01-17 58528a7c37d3

- SHA: 58528a7c37d3a4eea2874dbe1258c2626b88cd5e
- Subject: chore(crypto): patch react-native-libsodium
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +20 / -0
- Touched areas: expo-app(1)
- Topic bucket: `crypto`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/patches/@more-tech+react-native-libsodium+1.5.5.patch
```

### Diffstat

```text
 .../@more-tech+react-native-libsodium+1.5.5.patch    | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(crypto): patch react-native-libsodium
- Key files by churn (top 1):
  - expo-app/patches/@more-tech+react-native-libsodium+1.5.5.patch: +19/-0 | touches @@ -0,0 +1,20 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(crypto): patch react-native-libsodium`

### Topic Bucket

- `crypto`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 002 2026-01-17 552b8da0f621

- SHA: 552b8da0f62129749a8dd96bc7cfba125e51c1f6
- Subject: test(deps): add @types/react-test-renderer
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +8 / -0
- Touched areas: expo-app(2)
- Topic bucket: `deps`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/package.json
M	expo-app/yarn.lock
```

### Diffstat

```text
 expo-app/package.json | 1 +
 expo-app/yarn.lock    | 7 +++++++
 2 files changed, 8 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): test(deps): add @types/react-test-renderer
- Key files by churn (top 2):
  - expo-app/yarn.lock: +7/-0 | touches @@ -3111,0 +3112,7 @@
  - expo-app/package.json: +1/-0 | touches @@ -174,0 +175 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(deps): add @types/react-test-renderer`

### Topic Bucket

- `deps`

### Notes / Follow-ups


---

## 003 2026-01-17 017b15c07ad7

- SHA: 017b15c07ad75413718d9e734b8f40f2ce738ce7
- Subject: chore(config): harden app variant defaults
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +21 / -6
- Touched areas: expo-app(1)
- Topic bucket: `config`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/app.config.js
```

### Diffstat

```text
 expo-app/app.config.js | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(config): harden app variant defaults
- Key files by churn (top 1):
  - expo-app/app.config.js: +21/-6 | adds const bundleId, const bundleIdOverride, const bundleIdsByVariant, const name, const nameOverride, const namesByVariant | removes const bundleId, const name | touches const bundleId = {; const name = {; const variant = process.env.APP_ENV || 'development';; export default {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(config): harden app variant defaults`

### Topic Bucket

- `config`

### Notes / Follow-ups


---

## 004 2026-01-17 4890a471df31

- SHA: 4890a471df312191ae325d5691b61231097df078
- Subject: fix(auth): harden tokenStorage web persistence
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +137 / -9
- Touched areas: expo-app(2)
- Topic bucket: `auth`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/auth/tokenStorage.test.ts
M	expo-app/sources/auth/tokenStorage.ts
```

### Diffstat

```text
 expo-app/sources/auth/tokenStorage.test.ts | 91 ++++++++++++++++++++++++++++++
 expo-app/sources/auth/tokenStorage.ts      | 55 +++++++++++++++---
 2 files changed, 137 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(auth): harden tokenStorage web persistence
- Key files by churn (top 2):
  - expo-app/sources/auth/tokenStorage.test.ts: +91/-0 | adds const getItem, const previousDescriptor, const removeItem, const restore, const setItem, const store | touches @@ -0,0 +1,91 @@
  - expo-app/sources/auth/tokenStorage.ts: +46/-9 | adds const key, const raw, const scope, const stored, function getAuthKey | removes const stored | touches const AUTH_KEY = 'auth_credentials';; export const TokenStorage = {; import { Platform } from 'react-native';; let credentialsCache: string | null = null;

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(auth): harden tokenStorage web persistence`

### Topic Bucket

- `auth`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 005 2026-01-17 4adc41d92af0

- SHA: 4adc41d92af05c1028bb6b7b81239a6279d13c29
- Subject: feat(sync): add permission mode types and mapping
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +218 / -0
- Touched areas: expo-app(4)
- Topic bucket: `sync`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/sync/permissionMapping.test.ts
A	expo-app/sources/sync/permissionMapping.ts
A	expo-app/sources/sync/permissionTypes.test.ts
A	expo-app/sources/sync/permissionTypes.ts
```

### Diffstat

```text
 expo-app/sources/sync/permissionMapping.test.ts | 39 +++++++++++++++
 expo-app/sources/sync/permissionMapping.ts      | 52 ++++++++++++++++++++
 expo-app/sources/sync/permissionTypes.test.ts   | 65 +++++++++++++++++++++++++
 expo-app/sources/sync/permissionTypes.ts        | 62 +++++++++++++++++++++++
 4 files changed, 218 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(sync): add permission mode types and mapping
- Key files by churn (top 4):
  - expo-app/sources/sync/permissionTypes.test.ts: +65/-0 | touches @@ -0,0 +1,65 @@
  - expo-app/sources/sync/permissionTypes.ts: +62/-0 | adds const ALL_PERMISSION_MODES, const CLAUDE_PERMISSION_MODES, const CODEX_LIKE_PERMISSION_MODES, const MODEL_MODES, function isModelMode, function isPermissionMode | touches @@ -0,0 +1,62 @@
  - expo-app/sources/sync/permissionMapping.ts: +52/-0 | adds const fromCodexLike, const toCodexLike, function isCodexLike, function mapPermissionModeAcrossAgents | touches @@ -0,0 +1,52 @@
  - expo-app/sources/sync/permissionMapping.test.ts: +39/-0 | touches @@ -0,0 +1,39 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(sync): add permission mode types and mapping`

### Topic Bucket

- `sync`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 006 2026-01-17 a5fbc3e8ba00

- SHA: a5fbc3e8ba00ba0f41b9af18ca0c6296414f5533
- Subject: feat(persistence): scope storage and validate draft modes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +255 / -6
- Touched areas: expo-app(4)
- Topic bucket: `persistence`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/sync/persistence.test.ts
M	expo-app/sources/sync/persistence.ts
A	expo-app/sources/utils/storageScope.test.ts
A	expo-app/sources/utils/storageScope.ts
```

### Diffstat

```text
 expo-app/sources/sync/persistence.test.ts   | 114 ++++++++++++++++++++++++++++
 expo-app/sources/sync/persistence.ts        |  69 +++++++++++++++--
 expo-app/sources/utils/storageScope.test.ts |  46 +++++++++++
 expo-app/sources/utils/storageScope.ts      |  32 ++++++++
 4 files changed, 255 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(persistence): scope storage and validate draft modes
- Key files by churn (top 4):
  - expo-app/sources/sync/persistence.test.ts: +114/-0 | adds class MMKV, const draft, const store | touches @@ -0,0 +1,114 @@
  - expo-app/sources/sync/persistence.ts: +63/-6 | adds const SESSION_MODEL_MODES, const isWebRuntime, const mmkv, const modes, const selectedProfileId, const storageScope | removes const mmkv | touches export function clearPersistence() {; export function loadNewSessionDraft(): NewSessionDraft | null {; export function loadSettings(): { settings: Settings, version: number | null } {; export function saveSessionPermissionModes(modes: Record<string, PermissionMode>
  - expo-app/sources/utils/storageScope.test.ts: +46/-0 | adds const long | touches @@ -0,0 +1,46 @@
  - expo-app/sources/utils/storageScope.ts: +32/-0 | adds const EXPO_PUBLIC_STORAGE_SCOPE_ENV_VAR, const clamped, const collapsed, const sanitized, const trimmed, function normalizeStorageScope | touches @@ -0,0 +1,32 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(persistence): scope storage and validate draft modes`

### Topic Bucket

- `persistence`

### Notes / Follow-ups


---

## 007 2026-01-17 18e77c46f38a

- SHA: 18e77c46f38a2d336fb4e05d50aec3f4dcad5edd
- Subject: fix(session): clamp configurable model modes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +20 / -5
- Touched areas: expo-app(1)
- Topic bucket: `session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(session): clamp configurable model modes
- Key files by churn (top 1):
  - expo-app/sources/-session/SessionView.tsx: +20/-5 | adds const CONFIGURABLE_MODEL_MODES, const isConfigurableModelMode, const updateModelMode, type ConfigurableModelMode | removes const updateModelMode | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import { isVersionSupported, MINIMUM_CLI_VERSION } from '@/utils/versionUtils';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(session): clamp configurable model modes`

### Topic Bucket

- `session`

### Notes / Follow-ups


---

## 008 2026-01-17 f7bb8a28fff7

- SHA: f7bb8a28fff741703bf1238ec039197272703dce
- Subject: fix(tools): harden ACP tool parsing and titles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +202 / -28
- Touched areas: expo-app(4)
- Topic bucket: `tools`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/knownTools.tsx
M	expo-app/sources/components/tools/views/GeminiExecuteView.tsx
M	expo-app/sources/sync/typesRaw.spec.ts
M	expo-app/sources/sync/typesRaw.ts
```

### Diffstat

```text
 expo-app/sources/components/tools/knownTools.tsx   |  32 +++--
 .../components/tools/views/GeminiExecuteView.tsx   |   4 +-
 expo-app/sources/sync/typesRaw.spec.ts             | 132 +++++++++++++++++++++
 expo-app/sources/sync/typesRaw.ts                  |  62 ++++++++--
 4 files changed, 202 insertions(+), 28 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tools): harden ACP tool parsing and titles
- Key files by churn (top 4):
  - expo-app/sources/sync/typesRaw.spec.ts: +132/-0 | adds const item, const normalized, const raw | touches describe('Zod Transform - WOLOG Content Normalization', () => {
  - expo-app/sources/sync/typesRaw.ts: +49/-13 | adds const isTextBlocks, const maybeTextBlocks, const rawResultContent, const toolResultContentToText | touches const rawAgentRecordSchema = z.discriminatedUnion('type', [z.object({; const rawToolResultContentSchema = z.object({; export function normalizeRawMessage(id: string, localId: string | null, createdA
  - expo-app/sources/components/tools/knownTools.tsx: +19/-13 | adds const maybePath, const path | removes const path | touches export const knownTools = {
  - expo-app/sources/components/tools/views/GeminiExecuteView.tsx: +2/-2 | touches const styles = StyleSheet.create((theme) => ({; export const GeminiExecuteView = React.memo<ToolViewProps>(({ tool }) => {; import { CodeView } from '@/components/CodeView';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tools): harden ACP tool parsing and titles`

### Topic Bucket

- `tools`

### Notes / Follow-ups


---

## 009 2026-01-17 292424245277

- SHA: 292424245277951fc1aa80149407b720b72db9ad
- Subject: refactor(sync): centralize outgoing message metadata
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +84 / -55
- Touched areas: expo-app(3)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/sync/messageMeta.test.ts
A	expo-app/sources/sync/messageMeta.ts
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 expo-app/sources/sync/messageMeta.test.ts | 54 +++++++++++++++++++++++++
 expo-app/sources/sync/messageMeta.ts      | 19 +++++++++
 expo-app/sources/sync/sync.ts             | 66 ++++++-------------------------
 3 files changed, 84 insertions(+), 55 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(sync): centralize outgoing message metadata
- Key files by churn (top 3):
  - expo-app/sources/sync/sync.ts: +11/-55 | adds const isDev, const model | touches class Sync {; import { initializeTodoSync } from '../-zen/model/ops';
  - expo-app/sources/sync/messageMeta.test.ts: +54/-0 | adds const meta | touches @@ -0,0 +1,54 @@
  - expo-app/sources/sync/messageMeta.ts: +19/-0 | adds function buildOutgoingMessageMeta | touches @@ -0,0 +1,19 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(sync): centralize outgoing message metadata`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 010 2026-01-17 39cc25154cdd

- SHA: 39cc25154cddcfc43ed1c25dc4d126bd9d0137cd
- Subject: feat(storage): persist session model modes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +38 / -19
- Touched areas: expo-app(2)
- Topic bucket: `storage`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/serverConfig.ts
M	expo-app/sources/sync/storage.ts
```

### Diffstat

```text
 expo-app/sources/sync/serverConfig.ts |  5 +++-
 expo-app/sources/sync/storage.ts      | 52 +++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 19 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(storage): persist session model modes
- Key files by churn (top 2):
  - expo-app/sources/sync/storage.ts: +34/-18 | adds const existingModelMode, const modelModes, const savedModelMode, const savedModelModes, type SessionModelMode | touches export const storage = create<StorageState>()((set, get) => {; export type KnownEntitlements = 'pro';; import { UserProfile, RelationshipUpdatedEvent } from "./friendTypes";; interface StorageState {
  - expo-app/sources/sync/serverConfig.ts: +4/-1 | adds const isWebRuntime, const serverConfigScope, const serverConfigStorage | removes const serverConfigStorage | touches import { MMKV } from 'react-native-mmkv';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(storage): persist session model modes`

### Topic Bucket

- `storage`

### Notes / Follow-ups


---

## 011 2026-01-17 c2d3507357dc

- SHA: c2d3507357dc7ef150105ff56468ec2f580943f6
- Subject: fix(settings): make parsing tolerant for profiles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +224 / -141
- Touched areas: expo-app(3)
- Topic bucket: `settings`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 expo-app/sources/sync/settings.spec.ts |  78 ++++++++--
 expo-app/sources/sync/settings.ts      | 268 +++++++++++++++++----------------
 expo-app/sources/sync/sync.ts          |  19 ++-
 3 files changed, 224 insertions(+), 141 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(settings): make parsing tolerant for profiles
- Key files by churn (top 3):
  - expo-app/sources/sync/settings.ts: +139/-129 | adds const environmentVariables, const hasMachineSearch, const hasPathSearch, const input, const isDev, const legacy | removes const AnthropicConfigSchema, const AzureOpenAIConfigSchema, const OpenAIConfigSchema, const TogetherAIConfigSchema | touches const TmuxConfigSchema = z.object({; export const AIBackendProfileSchema = z.object({; export const SettingsSchema = z.object({; export const settingsDefaults: Settings = {
  - expo-app/sources/sync/settings.spec.ts: +69/-9 | adds const parsed, const profile | touches describe('settings', () => {
  - expo-app/sources/sync/sync.ts: +16/-3 | adds const mismatchHint | touches class Sync {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(settings): make parsing tolerant for profiles`

### Topic Bucket

- `settings`

### Notes / Follow-ups


---

## 012 2026-01-17 207ef1b2f572

- SHA: 207ef1b2f57207ad67a08256a11b40863e9fba76
- Subject: fix(dev): gate CLI detection logging
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +41 / -24
- Touched areas: expo-app(3)
- Topic bucket: `dev`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.ts
M	expo-app/sources/realtime/RealtimeVoiceSession.tsx
M	expo-app/sources/realtime/RealtimeVoiceSession.web.tsx
```

### Diffstat

```text
 expo-app/sources/hooks/useCLIDetection.ts          | 17 +++++++++----
 expo-app/sources/realtime/RealtimeVoiceSession.tsx | 19 ++++++++------
 .../sources/realtime/RealtimeVoiceSession.web.tsx  | 29 +++++++++++++---------
 3 files changed, 41 insertions(+), 24 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(dev): gate CLI detection logging
- Key files by churn (top 3):
  - expo-app/sources/realtime/RealtimeVoiceSession.web.tsx: +17/-12 | adds function debugLog | touches class RealtimeVoiceSessionImpl implements VoiceSession {; export const RealtimeVoiceSession: React.FC = () => {; let conversationInstance: ReturnType<typeof useConversation> | null = null;
  - expo-app/sources/realtime/RealtimeVoiceSession.tsx: +12/-7 | adds function debugLog | touches export const RealtimeVoiceSession: React.FC = () => {; let conversationInstance: ReturnType<typeof useConversation> | null = null;
  - expo-app/sources/hooks/useCLIDetection.ts: +12/-5 | adds function debugLog | touches export function useCLIDetection(machineId: string | null): CLIAvailability {; import { machineBash } from '@/sync/ops';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(dev): gate CLI detection logging`

### Topic Bucket

- `dev`

### Notes / Follow-ups


---

## 013 2026-01-17 58a892d413d1

- SHA: 58a892d413d17670aa459491ca3e4c60024d894f
- Subject: fix(command-palette): include navigate dependency
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +3 / -3
- Touched areas: expo-app(1)
- Topic bucket: `command-palette`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/CommandPalette/CommandPaletteProvider.tsx
```

### Diffstat

```text
 .../sources/components/CommandPalette/CommandPaletteProvider.tsx    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(command-palette): include navigate dependency
- Key files by churn (top 1):
  - expo-app/sources/components/CommandPalette/CommandPaletteProvider.tsx: +3/-3 | touches export function CommandPaletteProvider({ children }: { children: React.ReactNode

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(command-palette): include navigate dependency`

### Topic Bucket

- `command-palette`

### Notes / Follow-ups


---

## 014 2026-01-17 41479b35415f

- SHA: 41479b35415f4c4a725e7dc8887dccd78c1d38cd
- Subject: feat(env): add env var template parsing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +83 / -8
- Touched areas: expo-app(3)
- Topic bucket: `env`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/envVarUtils.ts
A	expo-app/sources/utils/envVarTemplate.test.ts
A	expo-app/sources/utils/envVarTemplate.ts
```

### Diffstat

```text
 expo-app/sources/hooks/envVarUtils.ts         | 20 ++++++++------
 expo-app/sources/utils/envVarTemplate.test.ts | 31 +++++++++++++++++++++
 expo-app/sources/utils/envVarTemplate.ts      | 40 +++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(env): add env var template parsing
- Key files by churn (top 3):
  - expo-app/sources/utils/envVarTemplate.ts: +40/-0 | adds const noFallback, const suffix, const withFallback, function formatEnvVarTemplate, function parseEnvVarTemplate, type EnvVarTemplate | touches @@ -0,0 +1,40 @@
  - expo-app/sources/utils/envVarTemplate.test.ts: +31/-0 | adds const input, const parsed | touches @@ -0,0 +1,31 @@
  - expo-app/sources/hooks/envVarUtils.ts: +12/-8 | adds const defaultValue, const match | removes const defaultValue, const match | touches export function extractEnvVarReferences(; export function resolveEnvVarSubstitution(

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(env): add env var template parsing`

### Topic Bucket

- `env`

### Notes / Follow-ups


---

## 015 2026-01-17 695bcd09eb9e

- SHA: 695bcd09eb9e67184daa24e0815c895c4af6612d
- Subject: fix(env): improve remote env resolution and previews
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +343 / -26
- Touched areas: expo-app(4)
- Topic bucket: `env`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useEnvironmentVariables.test.ts
M	expo-app/sources/hooks/useEnvironmentVariables.ts
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/settings.ts
```

### Diffstat

```text
 .../sources/hooks/useEnvironmentVariables.test.ts  |   4 +
 expo-app/sources/hooks/useEnvironmentVariables.ts  | 218 ++++++++++++++++++---
 expo-app/sources/sync/ops.ts                       | 142 +++++++++++++-
 expo-app/sources/sync/settings.ts                  |   5 +
 4 files changed, 343 insertions(+), 26 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(env): improve remote env resolution and previews
- Key files by churn (top 4):
  - expo-app/sources/hooks/useEnvironmentVariables.ts: +196/-22 | adds const SECRET_NAME_REGEX, const command, const entries, const entry, const equalsIndex, const extraEnvKey | removes const command, const equalsIndex, const lines, const name | touches export function useEnvironmentVariables(; export { resolveEnvVarSubstitution, extractEnvVarReferences } from './envVarUtil; import { useState, useEffect, useMemo } from 'react';; interface UseEnvironmentVariablesResult {
  - expo-app/sources/sync/ops.ts: +138/-4 | adds const display, const isForcedSensitive, const isSensitive, const isSet, const result, const safeDisplay | touches export async function machineBash(; export async function machineSpawnNewSession(options: SpawnSessionOptions): Prom; export interface SpawnSessionOptions {; export type {
  - expo-app/sources/sync/settings.ts: +5/-0 | touches const EnvironmentVariableSchema = z.object({
  - expo-app/sources/hooks/useEnvironmentVariables.test.ts: +4/-0 | touches describe('resolveEnvVarSubstitution', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(env): improve remote env resolution and previews`

### Topic Bucket

- `env`

### Notes / Follow-ups


---

## 016 2026-01-17 6cdb90a49aad

- SHA: 6cdb90a49aad04fbae4958cbcdf1fa57b2eda0b1
- Subject: feat(env): update env var list, cards, and preview modal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +1533 / -381
- Touched areas: expo-app(6)
- Topic bucket: `env`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/components/EnvironmentVariableCard.test.ts
M	expo-app/sources/components/EnvironmentVariableCard.tsx
A	expo-app/sources/components/EnvironmentVariablesList.test.ts
M	expo-app/sources/components/EnvironmentVariablesList.tsx
A	expo-app/sources/components/newSession/EnvironmentVariablesPreviewModal.tsx
A	expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx
```

### Diffstat

```text
 .../components/EnvironmentVariableCard.test.ts     | 189 ++++++
 .../sources/components/EnvironmentVariableCard.tsx | 664 ++++++++++++++-------
 .../components/EnvironmentVariablesList.test.ts    | 210 +++++++
 .../components/EnvironmentVariablesList.tsx        | 451 +++++++++-----
 .../EnvironmentVariablesPreviewModal.tsx           | 316 ++++++++++
 .../newSession/ProfileCompatibilityIcon.tsx        |  84 +++
 6 files changed, 1533 insertions(+), 381 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(env): update env var list, cards, and preview modal
- Key files by churn (top 6):
  - expo-app/sources/components/EnvironmentVariableCard.tsx: +446/-218 | adds const canEditSecret, const computedTemplateValue, const emptyValue, const fallbackOperator, const hasFallback, const machineLabel | removes const matchNoFallback, const matchWithFallback, const newValue, const parsed | touches export function EnvironmentVariableCard({; export interface EnvironmentVariableCardProps {; function parseVariableValue(value: string): {; import React from 'react';
  - expo-app/sources/components/EnvironmentVariablesList.tsx: +288/-163 | adds const ENV_VAR_TEMPLATE_REF_REGEX, const SECRET_NAME_REGEX, const autoSecret, const description, const documentedSecretNames, const effectiveIsSecret | removes const docs, const extractVarNameFromValue, const isSecret, const match | touches export function EnvironmentVariablesList({; export interface EnvironmentVariablesListProps {; import React from 'react';; import type { ProfileDocumentation } from '@/sync/profileUtils';
  - expo-app/sources/components/newSession/EnvironmentVariablesPreviewModal.tsx: +316/-0 | adds const ENV_VAR_TEMPLATE_REF_REGEX, const canCopy, const deltaY, const detailColor, const detailLabel, const emptyValue | touches @@ -0,0 +1,316 @@
  - expo-app/sources/components/EnvironmentVariablesList.test.ts: +210/-0 | adds const React, const cards, const useEnvironmentVariablesMock | touches @@ -0,0 +1,210 @@
  - expo-app/sources/components/EnvironmentVariableCard.test.ts: +189/-0 | adds const React, const firstSwitches, const firstUseMachineSwitch, const inputs, const lastCall, const onUpdate | touches @@ -0,0 +1,189 @@
  - expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx: +84/-0 | adds const CLAUDE_GLYPH, const GEMINI_GLYPH, const experimentsEnabled, const fontSize, const glyphs, const hasClaude | touches @@ -0,0 +1,84 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(env): update env var list, cards, and preview modal`

### Topic Bucket

- `env`

### Notes / Follow-ups


---

## 017 2026-01-17 65bae55a0b61

- SHA: 65bae55a0b61c4af5cd084945577a271a0c6cd9a
- Subject: refactor(i18n): separate translation types and content
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 14
- Lines: +1756 / -1006
- Touched areas: expo-app(14)
- Topic bucket: `i18n`
- Manual review needed: YES (diff summary skipped (large change (+1756/-1006)))

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/text/README.md
D	expo-app/sources/text/_default.ts
A	expo-app/sources/text/_types.ts
M	expo-app/sources/text/index.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
M	expo-app/sources/theme.css
```

### Diffstat

```text
 expo-app/sources/text/README.md               |  17 +-
 expo-app/sources/text/_default.ts             | 937 --------------------------
 expo-app/sources/text/_types.ts               |   3 +
 expo-app/sources/text/index.ts                |  14 +-
 expo-app/sources/text/translations/ca.ts      | 193 +++++-
 expo-app/sources/text/translations/en.ts      | 215 +++++-
 expo-app/sources/text/translations/es.ts      | 193 +++++-
 expo-app/sources/text/translations/it.ts      | 195 +++++-
 expo-app/sources/text/translations/ja.ts      | 209 +++++-
 expo-app/sources/text/translations/pl.ts      | 197 +++++-
 expo-app/sources/text/translations/pt.ts      | 191 +++++-
 expo-app/sources/text/translations/ru.ts      | 193 +++++-
 expo-app/sources/text/translations/zh-Hans.ts | 191 +++++-
 expo-app/sources/theme.css                    |  14 +-
 14 files changed, 1756 insertions(+), 1006 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(i18n): separate translation types and content
- Diff summary skipped: large change (+1756/-1006).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(i18n): separate translation types and content`

### Topic Bucket

- `i18n`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 018 2026-01-17 2993b5c860ff

- SHA: 2993b5c860ffe5165867095b7ae5f5440f0a935c
- Subject: fix(new-session): restore standard modal flow
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 17
- Lines: +3142 / -1629
- Touched areas: expo-app(17)
- Topic bucket: `new-session`
- Manual review needed: YES (diff summary skipped (large change (+3142/-1629)))

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/__tests__/app/new/pick/path.test.ts
M	expo-app/sources/app/(app)/_layout.tsx
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/app/(app)/new/pick/path.tsx
M	expo-app/sources/app/(app)/new/pick/profile-edit.tsx
A	expo-app/sources/app/(app)/new/pick/profile.tsx
M	expo-app/sources/app/(app)/settings/features.tsx
M	expo-app/sources/components/AgentInput.tsx
M	expo-app/sources/components/SessionTypeSelector.tsx
A	expo-app/sources/components/newSession/MachineSelector.tsx
A	expo-app/sources/components/newSession/PathSelector.tsx
M	expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx
A	expo-app/sources/sync/modelOptions.ts
A	expo-app/sources/utils/recentMachines.ts
A	expo-app/sources/utils/recentPaths.ts
```

### Diffstat

```text
 .../sources/__tests__/app/new/pick/path.test.ts    |   88 +
 expo-app/sources/app/(app)/_layout.tsx             |   17 +-
 expo-app/sources/app/(app)/machine/[id].tsx        |    1 -
 expo-app/sources/app/(app)/new/index.tsx           | 2368 +++++++++++---------
 expo-app/sources/app/(app)/new/pick/machine.tsx    |  153 +-
 expo-app/sources/app/(app)/new/pick/path.tsx       |  311 +--
 .../sources/app/(app)/new/pick/profile-edit.tsx    |  280 ++-
 expo-app/sources/app/(app)/new/pick/profile.tsx    |  380 ++++
 expo-app/sources/app/(app)/settings/features.tsx   |   36 +-
 expo-app/sources/components/AgentInput.tsx         |  143 +-
 .../sources/components/SessionTypeSelector.tsx     |  157 +-
 .../components/newSession/MachineSelector.tsx      |  113 +
 .../sources/components/newSession/PathSelector.tsx |  614 +++++
 .../newSession/ProfileCompatibilityIcon.tsx        |    1 -
 expo-app/sources/sync/modelOptions.ts              |   33 +
 expo-app/sources/utils/recentMachines.ts           |   31 +
 expo-app/sources/utils/recentPaths.ts              |   45 +
 17 files changed, 3142 insertions(+), 1629 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(new-session): restore standard modal flow
- Diff summary skipped: large change (+3142/-1629).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(new-session): restore standard modal flow`

### Topic Bucket

- `new-session`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 019 2026-01-17 9e08047d2478

- SHA: 9e08047d24789583f061743482c55ac30e591b28
- Subject: fix(profiles): harden routing, grouping, and editing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 13
- Lines: +1319 / -857
- Touched areas: expo-app(13)
- Topic bucket: `profiles`
- Manual review needed: YES (diff summary skipped (large change (+1319/-857)))

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/app/(app)/settings/profiles.tsx
M	expo-app/sources/components/ProfileEditForm.tsx
M	expo-app/sources/components/SettingsView.tsx
A	expo-app/sources/components/profileActions.ts
A	expo-app/sources/profileRouteParams.test.ts
A	expo-app/sources/profileRouteParams.ts
A	expo-app/sources/sync/profileGrouping.test.ts
A	expo-app/sources/sync/profileGrouping.ts
A	expo-app/sources/sync/profileMutations.ts
A	expo-app/sources/sync/profileUtils.test.ts
M	expo-app/sources/sync/profileUtils.ts
M	expo-app/sources/sync/storageTypes.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/session/[id]/info.tsx |   92 +-
 expo-app/sources/app/(app)/settings/profiles.tsx |  670 +++++++-------
 expo-app/sources/components/ProfileEditForm.tsx  | 1007 +++++++++++-----------
 expo-app/sources/components/SettingsView.tsx     |   31 +-
 expo-app/sources/components/profileActions.ts    |   65 ++
 expo-app/sources/profileRouteParams.test.ts      |   46 +
 expo-app/sources/profileRouteParams.ts           |   32 +
 expo-app/sources/sync/profileGrouping.test.ts    |   44 +
 expo-app/sources/sync/profileGrouping.ts         |   67 ++
 expo-app/sources/sync/profileMutations.ts        |   38 +
 expo-app/sources/sync/profileUtils.test.ts       |   26 +
 expo-app/sources/sync/profileUtils.ts            |   51 +-
 expo-app/sources/sync/storageTypes.ts            |    7 +-
 13 files changed, 1319 insertions(+), 857 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(profiles): harden routing, grouping, and editing
- Diff summary skipped: large change (+1319/-857).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(profiles): harden routing, grouping, and editing`

### Topic Bucket

- `profiles`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 020 2026-01-17 8d9f56e85e5a

- SHA: 8d9f56e85e5a0abf2a7bdd9eec48c172dad5c110
- Subject: refactor(ui): unify list selectors and modal primitives
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 28
- Lines: +1646 / -3588
- Touched areas: expo-app(28)
- Topic bucket: `ui`
- Manual review needed: YES (diff summary skipped (too many files (28)); safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/CONTRIBUTING.md
M	expo-app/sources/app/(app)/settings/voice/language.tsx
M	expo-app/sources/components/AgentInput.tsx
M	expo-app/sources/components/Item.tsx
A	expo-app/sources/components/ItemActionsMenuModal.tsx
A	expo-app/sources/components/ItemGroup.dividers.test.ts
A	expo-app/sources/components/ItemGroup.dividers.ts
A	expo-app/sources/components/ItemGroup.selectableCount.test.ts
A	expo-app/sources/components/ItemGroup.selectableCount.ts
M	expo-app/sources/components/ItemGroup.tsx
A	expo-app/sources/components/ItemRowActions.tsx
D	expo-app/sources/components/NewSessionWizard.tsx
D	expo-app/sources/components/PermissionModeSelector.tsx
A	expo-app/sources/components/SearchHeader.tsx
M	expo-app/sources/components/SearchableListSelector.tsx
A	expo-app/sources/components/Switch.web.tsx
M	expo-app/sources/modal/ModalManager.ts
M	expo-app/sources/modal/components/BaseModal.tsx
M	expo-app/sources/modal/components/CustomModal.tsx
M	expo-app/sources/modal/components/WebAlertModal.tsx
M	expo-app/sources/modal/types.ts
D	expo-app/sources/sync/profileSync.ts
M	expo-app/sources/sync/reducer/phase0-skipping.spec.ts
M	expo-app/sources/theme.ts
A	expo-app/sources/utils/ignoreNextRowPress.test.ts
A	expo-app/sources/utils/ignoreNextRowPress.ts
A	expo-app/sources/utils/promptUnsavedChangesAlert.test.ts
A	expo-app/sources/utils/promptUnsavedChangesAlert.ts
```

### Diffstat

```text
 expo-app/CONTRIBUTING.md                           |   70 +-
 .../sources/app/(app)/settings/voice/language.tsx  |   60 +-
 expo-app/sources/components/AgentInput.tsx         |  849 +++++----
 expo-app/sources/components/Item.tsx               |   11 +-
 .../sources/components/ItemActionsMenuModal.tsx    |  105 ++
 .../sources/components/ItemGroup.dividers.test.ts  |   67 +
 expo-app/sources/components/ItemGroup.dividers.ts  |   49 +
 .../components/ItemGroup.selectableCount.test.ts   |   47 +
 .../components/ItemGroup.selectableCount.ts        |   24 +
 expo-app/sources/components/ItemGroup.tsx          |   41 +-
 expo-app/sources/components/ItemRowActions.tsx     |   98 +
 expo-app/sources/components/NewSessionWizard.tsx   | 1917 --------------------
 .../sources/components/PermissionModeSelector.tsx  |  110 --
 expo-app/sources/components/SearchHeader.tsx       |  125 ++
 .../sources/components/SearchableListSelector.tsx  |  699 +++----
 expo-app/sources/components/Switch.web.tsx         |   64 +
 expo-app/sources/modal/ModalManager.ts             |   18 +-
 expo-app/sources/modal/components/BaseModal.tsx    |   24 +-
 expo-app/sources/modal/components/CustomModal.tsx  |    9 +-
 .../sources/modal/components/WebAlertModal.tsx     |  249 ++-
 expo-app/sources/modal/types.ts                    |   19 +-
 expo-app/sources/sync/profileSync.ts               |  453 -----
 .../sources/sync/reducer/phase0-skipping.spec.ts   |    8 +-
 expo-app/sources/theme.ts                          |    2 +-
 expo-app/sources/utils/ignoreNextRowPress.test.ts  |   19 +
 expo-app/sources/utils/ignoreNextRowPress.ts       |    7 +
 .../utils/promptUnsavedChangesAlert.test.ts        |   55 +
 .../sources/utils/promptUnsavedChangesAlert.ts     |   35 +
 28 files changed, 1646 insertions(+), 3588 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(ui): unify list selectors and modal primitives
- Diff summary skipped: too many files (28).

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(ui): unify list selectors and modal primitives`

### Topic Bucket

- `ui`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 021 2026-01-17 2ab560bb0535

- SHA: 2ab560bb0535df6c77cd14b314748566e46732b4
- Subject: feat(cli-detection): add daemon detect-cli RPC support
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +99 / -3
- Touched areas: expo-app(2)
- Topic bucket: `cli-detection`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.ts
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 expo-app/sources/hooks/useCLIDetection.ts | 29 ++++++++++--
 expo-app/sources/sync/ops.ts              | 73 +++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(cli-detection): add daemon detect-cli RPC support
- Key files by churn (top 2):
  - expo-app/sources/sync/ops.ts: +73/-0 | adds const claude, const clisRaw, const codex, const gemini, const getEntry, const pathValue | touches export async function machineBash(
  - expo-app/sources/hooks/useCLIDetection.ts: +26/-3 | adds const cliStatus | touches export function useCLIDetection(machineId: string | null): CLIAvailability {; import { useState, useEffect } from 'react';; interface CLIAvailability {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(cli-detection): add daemon detect-cli RPC support`

### Topic Bucket

- `cli-detection`

### Notes / Follow-ups


---

## 022 2026-01-17 2d4675a5d051

- SHA: 2d4675a5d051d623b18ca85f284e74c21197237d
- Subject: fix(agent-input): use compact permission badges
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +22 / -17
- Touched areas: expo-app(1)
- Topic bucket: `agent-input`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/AgentInput.tsx
```

### Diffstat

```text
 expo-app/sources/components/AgentInput.tsx | 39 +++++++++++++++++-------------
 1 file changed, 22 insertions(+), 17 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(agent-input): use compact permission badges
- Key files by churn (top 1):
  - expo-app/sources/components/AgentInput.tsx: +22/-17 | touches export const AgentInput = React.memo(React.forwardRef<MultiTextInputHandle, Agen

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(agent-input): use compact permission badges`

### Topic Bucket

- `agent-input`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 023 2026-01-18 d97924f3ef39

- SHA: d97924f3ef398638746919a3fee3675b0a12cee6
- Subject: chore(test): define __DEV__ for vitest
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +4 / -1
- Touched areas: expo-app(1)
- Topic bucket: `test`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/vitest.config.ts
```

### Diffstat

```text
 expo-app/vitest.config.ts | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(test): define __DEV__ for vitest
- Key files by churn (top 1):
  - expo-app/vitest.config.ts: +4/-1 | touches export default defineConfig({

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(test): define __DEV__ for vitest`

### Topic Bucket

- `test`

### Notes / Follow-ups


---

## 024 2026-01-18 9c19baa833b9

- SHA: 9c19baa833b91a7ac16bef710c18a19134e02ac2
- Subject: feat(settings): add api keys and experiment toggles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +331 / -0
- Touched areas: expo-app(4)
- Topic bucket: `settings`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/profileRouteParams.ts
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
```

### Diffstat

```text
 expo-app/sources/profileRouteParams.ts |  24 ++++
 expo-app/sources/sync/persistence.ts   |   3 +
 expo-app/sources/sync/settings.spec.ts | 200 +++++++++++++++++++++++++++++++++
 expo-app/sources/sync/settings.ts      | 104 +++++++++++++++++
 4 files changed, 331 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(settings): add api keys and experiment toggles
- Key files by churn (top 4):
  - expo-app/sources/sync/settings.spec.ts: +200/-0 | adds const invalidProfile, const now, const parsed | touches describe('settings', () => {
  - expo-app/sources/sync/settings.ts: +104/-0 | adds const RequiredEnvVarKindSchema, const RequiredEnvVarSchema, const RequiresMachineLoginSchema, const SavedApiKeySchema, const enableAll, const experimentKeys | touches const EnvironmentVariableSchema = z.object({; export const AIBackendProfileSchema = z.object({; export const SettingsSchema = z.object({; export const settingsDefaults: Settings = {
  - expo-app/sources/profileRouteParams.ts: +24/-0 | adds const nextApiKeyIdFromParams, function consumeApiKeyIdParam | touches export function consumeProfileIdParam(params: {
  - expo-app/sources/sync/persistence.ts: +3/-0 | adds const selectedApiKeyId | touches export function loadNewSessionDraft(): NewSessionDraft | null {; export interface NewSessionDraft {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(settings): add api keys and experiment toggles`

### Topic Bucket

- `settings`

### Notes / Follow-ups


---

## 025 2026-01-18 21cc6df79f50

- SHA: 21cc6df79f5099a3c72d264531999a5f46ee3956
- Subject: feat(api-keys): add saved API keys UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +580 / -10
- Touched areas: expo-app(5)
- Topic bucket: `api-keys`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/app/(app)/new/pick/api-key.tsx
A	expo-app/sources/app/(app)/settings/api-keys.tsx
A	expo-app/sources/components/ApiKeyAddModal.tsx
M	expo-app/sources/components/SettingsView.tsx
A	expo-app/sources/components/apiKeys/ApiKeysList.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/pick/api-key.tsx    |  42 ++++
 expo-app/sources/app/(app)/settings/api-keys.tsx   |  29 +++
 expo-app/sources/components/ApiKeyAddModal.tsx     | 204 +++++++++++++++++++
 expo-app/sources/components/SettingsView.tsx       |  95 ++++++++-
 .../sources/components/apiKeys/ApiKeysList.tsx     | 220 +++++++++++++++++++++
 5 files changed, 580 insertions(+), 10 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(api-keys): add saved API keys UI
- Key files by churn (top 5):
  - expo-app/sources/components/apiKeys/ApiKeysList.tsx: +220/-0 | adds const addApiKey, const confirmed, const deleteApiKey, const group, const groupFooter, const groupTitle | touches @@ -0,0 +1,220 @@
  - expo-app/sources/components/ApiKeyAddModal.tsx: +204/-0 | adds const styles, const stylesheet, const submit, const trimmedName, const trimmedValue, function ApiKeyAddModal | touches @@ -0,0 +1,204 @@
  - expo-app/sources/components/SettingsView.tsx: +85/-10 | adds const expUsageReporting, const headerTextStyle, const machinesTitle, const statusLineText, const statusText, const subtitle | touches @@ -1 +1 @@; export const SettingsView = React.memo(function SettingsView() {; import { Ionicons } from '@expo/vector-icons';; import { t } from '@/text';
  - expo-app/sources/app/(app)/new/pick/api-key.tsx: +42/-0 | adds const params, const router, const selectedId, const setApiKeyParamAndClose | touches @@ -0,0 +1,42 @@
  - expo-app/sources/app/(app)/settings/api-keys.tsx: +29/-0 | touches @@ -0,0 +1,29 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(api-keys): add saved API keys UI`

### Topic Bucket

- `api-keys`

### Notes / Follow-ups


---

## 026 2026-01-18 ce9cd74d408a

- SHA: ce9cd74d408afdfaa0453123e4ad69bf03239cbb
- Subject: feat(machine): surface detected CLI status
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 9
- Lines: +894 / -104
- Touched areas: expo-app(9)
- Topic bucket: `machine`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/components/SearchableListSelector.tsx
A	expo-app/sources/components/machine/DetectedClisList.tsx
A	expo-app/sources/components/machine/DetectedClisModal.tsx
A	expo-app/sources/components/newSession/MachineCliGlyphs.tsx
M	expo-app/sources/components/newSession/MachineSelector.tsx
M	expo-app/sources/hooks/useCLIDetection.ts
A	expo-app/sources/hooks/useMachineDetectCliCache.ts
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/machine/[id].tsx        | 144 +++++++++++--
 .../sources/components/SearchableListSelector.tsx  |  12 +-
 .../components/machine/DetectedClisList.tsx        | 123 +++++++++++
 .../components/machine/DetectedClisModal.tsx       | 106 ++++++++++
 .../components/newSession/MachineCliGlyphs.tsx     | 112 ++++++++++
 .../components/newSession/MachineSelector.tsx      |  24 +++
 expo-app/sources/hooks/useCLIDetection.ts          | 223 +++++++++++++-------
 expo-app/sources/hooks/useMachineDetectCliCache.ts | 230 +++++++++++++++++++++
 expo-app/sources/sync/ops.ts                       |  24 ++-
 9 files changed, 894 insertions(+), 104 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(machine): surface detected CLI status
- Key files by churn (top 8):
  - expo-app/sources/hooks/useMachineDetectCliCache.ts: +230/-0 | adds const DEFAULT_FETCH_TIMEOUT_MS, const DEFAULT_STALE_MS, const cache, const cacheKey, const current, const entry | touches @@ -0,0 +1,230 @@
  - expo-app/sources/hooks/useCLIDetection.ts: +149/-74 | adds const autoDetect, const bashInFlightRef, const bashLastRanAtRef, const cachedResponse, const isOnline, const lastSuccessfulDetectAtRef | removes const cliStatus, const detectCLIs, function useCLIDetection | touches @@ -1,2 +1,5 @@; export function useCLIDetection(machineId: string | null): CLIAvailability {; interface CLIAvailability {
  - expo-app/sources/app/(app)/machine/[id].tsx: +124/-20 | adds const approved, const canRefresh, const detectedClisTitle, const headerTextStyle, const isOnline, const machineName | removes const approved, const machineName | touches export default function MachineDetailScreen() {; import type { Session } from '@/sync/storageTypes';; import { MultiTextInput, type MultiTextInputHandle } from '@/components/MultiTex
  - expo-app/sources/components/machine/DetectedClisList.tsx: +123/-0 | adds const allowGemini, const available, const entries, const expGemini, const experimentsEnabled, const extractSemver | touches @@ -0,0 +1,123 @@
  - expo-app/sources/components/newSession/MachineCliGlyphs.tsx: +112/-0 | adds const CLAUDE_GLYPH, const CODEX_GLYPH, const GEMINI_GLYPH, const MachineCliGlyphs, const allowGemini, const expGemini | touches @@ -0,0 +1,112 @@
  - expo-app/sources/components/machine/DetectedClisModal.tsx: +106/-0 | adds const styles, const stylesheet, function DetectedClisModal, type Props | touches @@ -0,0 +1,106 @@
  - expo-app/sources/sync/ops.ts: +15/-9 | adds const isLoggedInRaw, const version, function machineDetectCli | removes function machineDetectCli | touches export async function machineDetectCli(machineId: string): Promise<MachineDetect; export interface DetectCliEntry {; export type MachineDetectCliResult =
  - expo-app/sources/components/newSession/MachineSelector.tsx: +24/-0 | touches export function MachineSelector({; export interface MachineSelectorProps {; import { t } from '@/text';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(machine): surface detected CLI status`

### Topic Bucket

- `machine`

### Notes / Follow-ups


---

## 027 2026-01-18 7899bbd8433e

- SHA: 7899bbd8433ebc5a0ba9d97e00ef6cc11c88614c
- Subject: feat(profiles): add API key requirements flow
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 11
- Lines: +1515 / -222
- Touched areas: expo-app(11)
- Topic bucket: `profiles`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/profiles.tsx
A	expo-app/sources/components/ApiKeyRequirementModal.tsx
A	expo-app/sources/components/OptionTiles.tsx
M	expo-app/sources/components/ProfileEditForm.tsx
A	expo-app/sources/components/ProfileRequirementsBadge.tsx
A	expo-app/sources/components/profiles/ProfilesList.tsx
A	expo-app/sources/components/profiles/profileListModel.test.ts
A	expo-app/sources/components/profiles/profileListModel.ts
A	expo-app/sources/hooks/useProfileEnvRequirements.ts
A	expo-app/sources/sync/profileSecrets.ts
M	expo-app/sources/sync/profileUtils.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/profiles.tsx   | 232 ++---------
 .../sources/components/ApiKeyRequirementModal.tsx  | 348 ++++++++++++++++
 expo-app/sources/components/OptionTiles.tsx        | 119 ++++++
 expo-app/sources/components/ProfileEditForm.tsx    | 292 ++++++++++++--
 .../components/ProfileRequirementsBadge.tsx        |  91 +++++
 .../sources/components/profiles/ProfilesList.tsx   | 443 +++++++++++++++++++++
 .../components/profiles/profileListModel.test.ts   |  37 ++
 .../components/profiles/profileListModel.ts        |  59 +++
 .../sources/hooks/useProfileEnvRequirements.ts     |  80 ++++
 expo-app/sources/sync/profileSecrets.ts            |  12 +
 expo-app/sources/sync/profileUtils.ts              |  24 +-
 11 files changed, 1515 insertions(+), 222 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(profiles): add API key requirements flow
- Key files by churn (top 8):
  - expo-app/sources/components/profiles/ProfilesList.tsx: +443/-0 | adds const ProfileRow, const actions, const actionsByProfileId, const allowGemini, const baseSubtitle, const build | touches @@ -0,0 +1,443 @@
  - expo-app/sources/components/ApiKeyRequirementModal.tsx: +348/-0 | adds const allowedSources, const apiKeyRequirementSelectionMemory, const envName, const machine, const machineEnvSubtitle, const machineEnvTitle | touches @@ -0,0 +1,348 @@
  - expo-app/sources/components/ProfileEditForm.tsx: +261/-31 | adds const allowGemini, const allowedMachineLoginOptions, const claudeDefaultSubtitle, const claudeSubtitle, const cliDetection, const codexDefaultSubtitle | touches const stylesheet = StyleSheet.create((theme) => ({; export function ProfileEditForm({; import { isMachineOnline } from '@/utils/machineUtils';
  - expo-app/sources/app/(app)/settings/profiles.tsx: +44/-188 | adds const handleResolve, const openApiKeyModal | removes const actions, const backend, const builtInLabel, const customLabel | touches const ProfileManager = React.memo(function ProfileManager({ onProfileSelect, sel; import { Item } from '@/components/Item';; import { Switch } from '@/components/Switch';; import { useSetting } from '@/sync/storage';
  - expo-app/sources/components/OptionTiles.tsx: +119/-0 | adds const columns, const gap, const selected, const styles, const stylesheet, const tileWidth | touches @@ -0,0 +1,119 @@
  - expo-app/sources/components/ProfileRequirementsBadge.tsx: +91/-0 | adds const iconName, const label, const requirements, const show, const statusColor, const styles | touches @@ -0,0 +1,91 @@
  - expo-app/sources/hooks/useProfileEnvRequirements.ts: +80/-0 | adds const entry, const extraEnv, const isReady, const keysToQuery, const metaSummary, const raw | touches @@ -0,0 +1,80 @@
  - expo-app/sources/components/profiles/profileListModel.ts: +59/-0 | adds const backend, const label, function buildProfilesListGroups, function getDefaultProfileListStrings, function getProfileBackendSubtitle, function getProfileSubtitle | touches @@ -0,0 +1,59 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(profiles): add API key requirements flow`

### Topic Bucket

- `profiles`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 028 2026-01-18 0023ba1ea5aa

- SHA: 0023ba1ea5aa2a824b450e8b95812e30f5e6907e
- Subject: refactor(i18n): update translations and tooling
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 11
- Lines: +2913 / -143
- Touched areas: expo-app(11)
- Topic bucket: `i18n`
- Manual review needed: YES (diff summary skipped (large change (+2913/-143)))

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/scripts/compareTranslations.ts
A	expo-app/sources/scripts/findUntranslatedLiterals.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/scripts/compareTranslations.ts    |   8 +-
 .../sources/scripts/findUntranslatedLiterals.ts    | 253 ++++++++++++++++
 expo-app/sources/text/translations/ca.ts           | 311 ++++++++++++++++++-
 expo-app/sources/text/translations/en.ts           | 279 +++++++++++++++++
 expo-app/sources/text/translations/es.ts           | 311 ++++++++++++++++++-
 expo-app/sources/text/translations/it.ts           | 301 ++++++++++++++++++-
 expo-app/sources/text/translations/ja.ts           | 305 ++++++++++++++++++-
 expo-app/sources/text/translations/pl.ts           | 321 ++++++++++++++++++--
 expo-app/sources/text/translations/pt.ts           | 315 ++++++++++++++++++--
 expo-app/sources/text/translations/ru.ts           | 331 +++++++++++++++++++--
 expo-app/sources/text/translations/zh-Hans.ts      | 321 ++++++++++++++++++--
 11 files changed, 2913 insertions(+), 143 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(i18n): update translations and tooling
- Diff summary skipped: large change (+2913/-143).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(i18n): update translations and tooling`

### Topic Bucket

- `i18n`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 029 2026-01-18 12e75a3b36fa

- SHA: 12e75a3b36fa49aa4d91cedd8464e8afcb65e2a8
- Subject: fix(autocomplete): remove debug suggestion logs
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +0 / -6
- Touched areas: expo-app(1)
- Topic bucket: `autocomplete`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/autocomplete/useActiveSuggestions.ts
```

### Diffstat

```text
 expo-app/sources/components/autocomplete/useActiveSuggestions.ts | 6 ------
 1 file changed, 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(autocomplete): remove debug suggestion logs
- Key files by churn (top 1):
  - expo-app/sources/components/autocomplete/useActiveSuggestions.ts: +0/-6 | touches export function useActiveSuggestions(

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(autocomplete): remove debug suggestion logs`

### Topic Bucket

- `autocomplete`

### Notes / Follow-ups


---

## 030 2026-01-18 679877c26ea9

- SHA: 679877c26ea9b3a3eb250a60c8c425ce2aee7f84
- Subject: feat(settings): expose per-experiment toggles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +94 / -3
- Touched areas: expo-app(1)
- Topic bucket: `settings`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx | 97 +++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(settings): expose per-experiment toggles
- Key files by churn (top 1):
  - expo-app/sources/app/(app)/settings/features.tsx: +94/-3 | adds const setAllExperimentToggles | touches export default React.memo(function FeaturesSettingsScreen() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(settings): expose per-experiment toggles`

### Topic Bucket

- `settings`

### Notes / Follow-ups


---

## 031 2026-01-18 4dc9c7f8759c

- SHA: 4dc9c7f8759c1f5f1713167ca0888b87463084b3
- Subject: feat(agent-input): add configurable action bar layout
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +477 / -117
- Touched areas: expo-app(2)
- Topic bucket: `agent-input`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/appearance.tsx
M	expo-app/sources/components/AgentInput.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/appearance.tsx |  45 +-
 expo-app/sources/components/AgentInput.tsx         | 549 ++++++++++++++++-----
 2 files changed, 477 insertions(+), 117 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(agent-input): add configurable action bar layout
- Key files by churn (top 2):
  - expo-app/sources/components/AgentInput.tsx: +434/-115 | adds const abortButton, const actionBarFadeColor, const actionBarFadeTransparent, const actionBarIsCollapsed, const actionBarShouldScroll, const agentChip | removes const cliStatus, const cliStatusText, const format, const parts | touches const stylesheet = StyleSheet.create((theme, runtime) => ({; export const AgentInput = React.memo(React.forwardRef<MultiTextInputHandle, Agen; function GitStatusButton({ sessionId, onPress }: { sessionId?: string, onPress?:; import * as React from 'react';
  - expo-app/sources/app/(app)/settings/appearance.tsx: +43/-2 | adds const idx, const next | touches @@ -0,0 +1 @@; const isKnownAvatarStyle = (style: string): style is KnownAvatarStyle => {; export default function AppearanceSettingsScreen() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(agent-input): add configurable action bar layout`

### Topic Bucket

- `agent-input`

### Notes / Follow-ups


---

## 032 2026-01-18 e8e42a6087ad

- SHA: e8e42a6087add8e0c3713980c9497c59e34a3fa9
- Subject: fix(modal): prevent stacked modal touch-blocking on iOS
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +111 / -8
- Touched areas: expo-app(5)
- Topic bucket: `modal`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/_layout.tsx
M	expo-app/sources/modal/ModalManager.ts
M	expo-app/sources/modal/components/BaseModal.tsx
M	expo-app/sources/modal/components/CustomModal.tsx
M	expo-app/sources/modal/types.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/_layout.tsx            | 25 ++++++++-
 expo-app/sources/modal/ModalManager.ts            |  2 +
 expo-app/sources/modal/components/BaseModal.tsx   | 67 +++++++++++++++++++++--
 expo-app/sources/modal/components/CustomModal.tsx | 20 ++++++-
 expo-app/sources/modal/types.ts                   |  5 ++
 5 files changed, 111 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(modal): prevent stacked modal touch-blocking on iOS
- Key files by churn (top 5):
  - expo-app/sources/modal/components/BaseModal.tsx: +63/-4 | touches const styles = StyleSheet.create({; export function BaseModal({
  - expo-app/sources/app/(app)/_layout.tsx: +23/-2 | touches @@ -1 +1 @@; export default function RootLayout() {; import { Platform, TouchableOpacity, Text } from 'react-native';
  - expo-app/sources/modal/components/CustomModal.tsx: +18/-2 | adds const handleClose, const maybe | touches export function CustomModal({ config, onClose }: CustomModalProps) {
  - expo-app/sources/modal/types.ts: +5/-0 | touches export interface CustomModalConfig<P extends CustomModalInjectedProps = any> ext
  - expo-app/sources/modal/ModalManager.ts: +2/-0 | touches class ModalManagerClass implements IModal {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(modal): prevent stacked modal touch-blocking on iOS`

### Topic Bucket

- `modal`

### Notes / Follow-ups


---

## 033 2026-01-18 daa0b4527d7f

- SHA: daa0b4527d7fb9b2108c9fef395e835fea32caa2
- Subject: feat(new-session): add api key selection and wizard extraction
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +1719 / -1116
- Touched areas: expo-app(4)
- Topic bucket: `new-session`
- Manual review needed: YES (diff summary skipped (large change (+1719/-1116)))

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/new/pick/profile.tsx
M	expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx
```

### Diffstat

```text
 .../sources/app/(app)/new/NewSessionWizard.tsx     |  878 +++++++++++
 expo-app/sources/app/(app)/new/index.tsx           | 1543 +++++++++-----------
 expo-app/sources/app/(app)/new/pick/profile.tsx    |  410 ++----
 .../newSession/ProfileCompatibilityIcon.tsx        |    4 +-
 4 files changed, 1719 insertions(+), 1116 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(new-session): add api key selection and wizard extraction
- Diff summary skipped: large change (+1719/-1116).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(new-session): add api key selection and wizard extraction`

### Topic Bucket

- `new-session`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 034 2026-01-18 94814465bf81

- SHA: 94814465bf81386c381971cd23b58b83874e5a15
- Subject: perf(sync): debounce pending settings writes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +69 / -4
- Touched areas: expo-app(1)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 expo-app/sources/sync/sync.ts | 73 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): perf(sync): debounce pending settings writes
- Key files by churn (top 1):
  - expo-app/sources/sync/sync.ts: +69/-4 | adds const flush, const force, const now, const staleMs | touches class Sync {; import { registerPushToken } from './apiPush';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `perf(sync): debounce pending settings writes`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 035 2026-01-18 7ffd0c3428cb

- SHA: 7ffd0c3428cbbceb7df39396142100da8fd4841d
- Subject: fix(ui): localize error alerts
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +4 / -3
- Touched areas: expo-app(1)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useHappyAction.ts
```

### Diffstat

```text
 expo-app/sources/hooks/useHappyAction.ts | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): localize error alerts
- Key files by churn (top 1):
  - expo-app/sources/hooks/useHappyAction.ts: +4/-3 | touches export function useHappyAction(action: () => Promise<void>) {; import { Modal } from '@/modal';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): localize error alerts`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 036 2026-01-18 97ca69e0a735

- SHA: 97ca69e0a735156301f1943a870e4220ed82296e
- Subject: refactor(i18n): replace remaining UI literals
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 19
- Lines: +64 / -59
- Touched areas: expo-app(19)
- Topic bucket: `i18n`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/artifacts/[id].tsx
M	expo-app/sources/app/(app)/restore/index.tsx
M	expo-app/sources/app/(app)/restore/manual.tsx
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/app/(app)/settings/connect/claude.tsx
M	expo-app/sources/components/ChatFooter.tsx
M	expo-app/sources/components/CommandPalette/CommandPaletteResults.tsx
M	expo-app/sources/components/CommandView.tsx
M	expo-app/sources/components/ConnectButton.tsx
M	expo-app/sources/components/EmptyMainScreen.tsx
M	expo-app/sources/components/EmptyMessages.tsx
M	expo-app/sources/components/EmptySessionsTablet.tsx
M	expo-app/sources/components/MessageView.tsx
M	expo-app/sources/components/OAuthView.tsx
M	expo-app/sources/components/VoiceAssistantStatusBar.tsx
M	expo-app/sources/components/markdown/MarkdownView.tsx
M	expo-app/sources/components/markdown/MermaidRenderer.tsx
M	expo-app/sources/components/usage/UsageChart.tsx
M	expo-app/sources/utils/microphonePermissions.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/artifacts/[id].tsx             | 10 +++++-----
 expo-app/sources/app/(app)/restore/index.tsx              |  7 ++-----
 expo-app/sources/app/(app)/restore/manual.tsx             |  4 ++--
 expo-app/sources/app/(app)/session/[id]/info.tsx          | 10 +++++-----
 expo-app/sources/app/(app)/settings/connect/claude.tsx    |  4 ++--
 expo-app/sources/components/ChatFooter.tsx                |  5 +++--
 .../components/CommandPalette/CommandPaletteResults.tsx   |  5 +++--
 expo-app/sources/components/CommandView.tsx               |  4 ++--
 expo-app/sources/components/ConnectButton.tsx             |  2 +-
 expo-app/sources/components/EmptyMainScreen.tsx           |  6 +++---
 expo-app/sources/components/EmptyMessages.tsx             |  6 +++---
 expo-app/sources/components/EmptySessionsTablet.tsx       | 11 ++++++-----
 expo-app/sources/components/MessageView.tsx               |  4 +++-
 expo-app/sources/components/OAuthView.tsx                 |  6 +++---
 expo-app/sources/components/VoiceAssistantStatusBar.tsx   | 13 +++++++------
 expo-app/sources/components/markdown/MarkdownView.tsx     |  4 ++--
 expo-app/sources/components/markdown/MermaidRenderer.tsx  |  2 +-
 expo-app/sources/components/usage/UsageChart.tsx          |  5 +++--
 expo-app/sources/utils/microphonePermissions.ts           | 15 ++++++++-------
 19 files changed, 64 insertions(+), 59 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(i18n): replace remaining UI literals
- Key files by churn (top 8):
  - expo-app/sources/utils/microphonePermissions.ts: +8/-7 | adds const title | removes const title | touches export function showMicrophonePermissionDeniedAlert(canAskAgain: boolean = false; import { AudioModule } from 'expo-audio';
  - expo-app/sources/components/VoiceAssistantStatusBar.tsx: +7/-6 | touches const styles = StyleSheet.create({; export const VoiceAssistantStatusBar = React.memo(({ variant = 'full', style }:; import { VoiceBars } from './VoiceBars';
  - expo-app/sources/components/EmptySessionsTablet.tsx: +6/-5 | touches export function EmptySessionsTablet() {; import { useRouter } from 'expo-router';
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +5/-5 | touches function SessionInfoContent({ session }: { session: Session }) {
  - expo-app/sources/app/(app)/artifacts/[id].tsx: +5/-5 | touches export default function ArtifactDetailScreen() {
  - expo-app/sources/app/(app)/restore/index.tsx: +2/-5 | touches export default function Restore() {
  - expo-app/sources/components/OAuthView.tsx: +3/-3 | touches export const OAuthViewUnsupported = React.memo((props: {
  - expo-app/sources/components/EmptyMessages.tsx: +3/-3 | touches export function EmptyMessages({ session }: EmptyMessagesProps) {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(i18n): replace remaining UI literals`

### Topic Bucket

- `i18n`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 037 2026-01-18 5f5b57df5181

- SHA: 5f5b57df5181fdb2879d44c72e1d41b871c0e5ff
- Subject: refactor(ui): improve item rendering and action menu timing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +33 / -9
- Touched areas: expo-app(5)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/Item.tsx
M	expo-app/sources/components/ItemActionsMenuModal.tsx
M	expo-app/sources/components/ItemGroup.tsx
M	expo-app/sources/components/ItemRowActions.tsx
M	expo-app/sources/components/SessionsList.tsx
```

### Diffstat

```text
 expo-app/sources/components/Item.tsx                 | 18 +++++++++++++++---
 expo-app/sources/components/ItemActionsMenuModal.tsx |  8 ++++++--
 expo-app/sources/components/ItemGroup.tsx            | 13 +++++++++++--
 expo-app/sources/components/ItemRowActions.tsx       |  2 +-
 expo-app/sources/components/SessionsList.tsx         |  1 -
 5 files changed, 33 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(ui): improve item rendering and action menu timing
- Key files by churn (top 5):
  - expo-app/sources/components/Item.tsx: +15/-3 | adds const subtitleText | touches export const Item = React.memo<ItemProps>((props) => {; export interface ItemProps {
  - expo-app/sources/components/ItemGroup.tsx: +11/-2 | touches export const ItemGroup = React.memo<ItemGroupProps>((props) => {; export interface ItemGroupProps {
  - expo-app/sources/components/ItemActionsMenuModal.tsx: +6/-2 | touches export function ItemActionsMenuModal(props: ItemActionsMenuModalProps) {; import React from 'react';
  - expo-app/sources/components/ItemRowActions.tsx: +1/-1 | adds const compact | removes const compact | touches export function ItemRowActions(props: ItemRowActionsProps) {
  - expo-app/sources/components/SessionsList.tsx: +0/-1 | removes const experiments | touches export function SessionsList() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(ui): improve item rendering and action menu timing`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 038 2026-01-18 7976b877259c

- SHA: 7976b877259cac770f41537f44fa70e54df721a2
- Subject: feat(experiments): gate Zen, file viewer, and voice auth flow
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 7
- Lines: +29 / -21
- Touched areas: expo-app(7)
- Topic bucket: `experiments`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/-zen/ZenAdd.tsx
M	expo-app/sources/-zen/ZenHome.tsx
M	expo-app/sources/-zen/ZenView.tsx
M	expo-app/sources/-zen/components/ZenHeader.tsx
M	expo-app/sources/components/SidebarView.tsx
M	expo-app/sources/realtime/RealtimeSession.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx      |  3 ++-
 expo-app/sources/-zen/ZenAdd.tsx               |  5 +++--
 expo-app/sources/-zen/ZenHome.tsx              |  5 +++--
 expo-app/sources/-zen/ZenView.tsx              | 13 +++++++------
 expo-app/sources/-zen/components/ZenHeader.tsx |  6 +++---
 expo-app/sources/components/SidebarView.tsx    | 14 ++++++++------
 expo-app/sources/realtime/RealtimeSession.ts   |  4 +++-
 7 files changed, 29 insertions(+), 21 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(experiments): gate Zen, file viewer, and voice auth flow
- Key files by churn (top 7):
  - expo-app/sources/components/SidebarView.tsx: +8/-6 | adds const expZen, const experimentsEnabled, const shouldLeftJustify, const showZen | removes const settings, const shouldLeftJustify | touches @@ -1 +1 @@; export const SidebarView = React.memo(() => {
  - expo-app/sources/-zen/ZenView.tsx: +7/-6 | touches const styles = StyleSheet.create((theme) => ({; export const ZenView = React.memo(() => {; import { removeTaskLinks, getSessionsForTask } from '@/-zen/model/taskSessionLin
  - expo-app/sources/-zen/components/ZenHeader.tsx: +3/-3 | touches function HeaderRight() {; function HeaderTitle() {; function HeaderTitleTablet() {
  - expo-app/sources/-zen/ZenHome.tsx: +3/-2 | touches export const ZenHome = () => {; import { VoiceAssistantStatusBar } from '@/components/VoiceAssistantStatusBar';
  - expo-app/sources/-zen/ZenAdd.tsx: +3/-2 | touches const styles = StyleSheet.create((theme) => ({; export const ZenAdd = React.memo(() => {; import { useAuth } from '@/auth/AuthContext';
  - expo-app/sources/realtime/RealtimeSession.ts: +3/-1 | adds const expVoiceAuthFlow, const useAuthFlow | touches export async function startRealtimeSession(sessionId: string, initialContext?: s
  - expo-app/sources/-session/SessionView.tsx: +2/-1 | adds const expFileViewer | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(experiments): gate Zen, file viewer, and voice auth flow`

### Topic Bucket

- `experiments`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 039 2026-01-21 6ed379f82c34

- SHA: 6ed379f82c3497512316f23d15b2c2a0556a160e
- Subject: refactor(ui): add modal + popover overlay primitives
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 43
- Lines: +4669 / -930
- Touched areas: expo-app(43)
- Topic bucket: `ui`
- Manual review needed: YES (diff summary skipped (too many files (43)))

### Commit Message Body

```text
- Introduce shared web/native modal stacking primitives (Radix Dialog on web; app modal host on native).

- Add Popover + portal/spotlight infrastructure (OverlayPortal, ModalPortalTarget, ScrollEdgeFades) to prevent clipped menus and focus/scroll issues.

- Refactor Command Palette/item actions to use new overlay plumbing and remove legacy modal wrappers.

- Add targeted tests for modal provider/manager, BaseModal, Popover portal behavior, and overlay positioning.
```

### Files (name-status)

```text
A	expo-app/sources/components/ActionListSection.tsx
A	expo-app/sources/components/AgentInput.autocomplete.test.ts
M	expo-app/sources/components/AgentInput.tsx
M	expo-app/sources/components/AgentInputAutocomplete.tsx
M	expo-app/sources/components/CommandPalette/CommandPalette.tsx
M	expo-app/sources/components/CommandPalette/CommandPaletteInput.tsx
M	expo-app/sources/components/CommandPalette/CommandPaletteItem.tsx
D	expo-app/sources/components/CommandPalette/CommandPaletteModal.tsx
A	expo-app/sources/components/ConnectionStatusControl.tsx
A	expo-app/sources/components/FloatingOverlay.arrow.test.ts
M	expo-app/sources/components/FloatingOverlay.tsx
M	expo-app/sources/components/Item.tsx
D	expo-app/sources/components/ItemActionsMenuModal.tsx
M	expo-app/sources/components/ItemGroup.tsx
M	expo-app/sources/components/ItemRowActions.tsx
A	expo-app/sources/components/ModalPortalTarget.tsx
A	expo-app/sources/components/OverlayPortal.tsx
A	expo-app/sources/components/Popover.nativePortal.test.ts
A	expo-app/sources/components/Popover.test.ts
A	expo-app/sources/components/Popover.tsx
A	expo-app/sources/components/PopoverBoundary.tsx
A	expo-app/sources/components/ScrollEdgeFades.tsx
A	expo-app/sources/components/ScrollEdgeIndicators.tsx
A	expo-app/sources/components/SelectableRow.tsx
A	expo-app/sources/components/dropdown/DropdownMenu.tsx
A	expo-app/sources/components/dropdown/SelectableMenuResults.tsx
A	expo-app/sources/components/dropdown/selectableMenuTypes.ts
A	expo-app/sources/components/dropdown/useSelectableMenu.ts
A	expo-app/sources/components/itemActions/types.ts
A	expo-app/sources/components/useScrollEdgeFades.ts
A	expo-app/sources/dev/reactNativeStub.ts
A	expo-app/sources/modal/ModalManager.test.ts
M	expo-app/sources/modal/ModalManager.ts
A	expo-app/sources/modal/ModalProvider.test.ts
M	expo-app/sources/modal/ModalProvider.tsx
A	expo-app/sources/modal/components/BaseModal.test.ts
M	expo-app/sources/modal/components/BaseModal.tsx
M	expo-app/sources/modal/components/CustomModal.tsx
M	expo-app/sources/modal/components/WebAlertModal.tsx
M	expo-app/sources/modal/components/WebPromptModal.tsx
A	expo-app/sources/utils/radixCjs.ts
A	expo-app/sources/utils/reactDomCjs.ts
M	expo-app/vitest.config.ts
```

### Diffstat

```text
 expo-app/sources/components/ActionListSection.tsx  |  71 ++
 .../components/AgentInput.autocomplete.test.ts     |  90 +++
 expo-app/sources/components/AgentInput.tsx         | 510 ++++++--------
 .../sources/components/AgentInputAutocomplete.tsx  |   7 +-
 .../components/CommandPalette/CommandPalette.tsx   |   1 +
 .../CommandPalette/CommandPaletteInput.tsx         |  17 +-
 .../CommandPalette/CommandPaletteItem.tsx          | 154 +---
 .../CommandPalette/CommandPaletteModal.tsx         | 148 ----
 .../sources/components/ConnectionStatusControl.tsx | 263 +++++++
 .../components/FloatingOverlay.arrow.test.ts       | 107 +++
 expo-app/sources/components/FloatingOverlay.tsx    | 183 ++++-
 expo-app/sources/components/Item.tsx               |  29 +-
 .../sources/components/ItemActionsMenuModal.tsx    | 109 ---
 expo-app/sources/components/ItemGroup.tsx          |  22 +-
 expo-app/sources/components/ItemRowActions.tsx     | 235 ++++--
 expo-app/sources/components/ModalPortalTarget.tsx  |  21 +
 expo-app/sources/components/OverlayPortal.tsx      |  69 ++
 .../components/Popover.nativePortal.test.ts        | 308 ++++++++
 expo-app/sources/components/Popover.test.ts        | 412 +++++++++++
 expo-app/sources/components/Popover.tsx            | 784 +++++++++++++++++++++
 expo-app/sources/components/PopoverBoundary.tsx    |  17 +
 expo-app/sources/components/ScrollEdgeFades.tsx    | 135 ++++
 .../sources/components/ScrollEdgeIndicators.tsx    | 116 +++
 expo-app/sources/components/SelectableRow.tsx      | 201 ++++++
 .../sources/components/dropdown/DropdownMenu.tsx   | 227 ++++++
 .../components/dropdown/SelectableMenuResults.tsx  | 152 ++++
 .../components/dropdown/selectableMenuTypes.ts     |  20 +
 .../components/dropdown/useSelectableMenu.ts       | 131 ++++
 expo-app/sources/components/itemActions/types.ts   |  12 +
 expo-app/sources/components/useScrollEdgeFades.ts  | 143 ++++
 expo-app/sources/dev/reactNativeStub.ts            |   7 +
 expo-app/sources/modal/ModalManager.test.ts        |  42 ++
 expo-app/sources/modal/ModalManager.ts             |  63 +-
 expo-app/sources/modal/ModalProvider.test.ts       | 110 +++
 expo-app/sources/modal/ModalProvider.tsx           | 114 +--
 .../sources/modal/components/BaseModal.test.ts     | 259 +++++++
 expo-app/sources/modal/components/BaseModal.tsx    | 217 ++++--
 expo-app/sources/modal/components/CustomModal.tsx  |  39 +-
 .../sources/modal/components/WebAlertModal.tsx     |  12 +-
 .../sources/modal/components/WebPromptModal.tsx    |  14 +-
 expo-app/sources/utils/radixCjs.ts                 |  10 +
 expo-app/sources/utils/reactDomCjs.ts              |   8 +
 expo-app/vitest.config.ts                          |  10 +
 43 files changed, 4669 insertions(+), 930 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(ui): add modal + popover overlay primitives
- Diff summary skipped: too many files (43).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(ui): add modal + popover overlay primitives`

### Topic Bucket

- `ui`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 040 2026-01-21 f0787de5308e

- SHA: f0787de5308e51a4898087bad56b83d387196116
- Subject: feat(sync): add secrets + terminal settings primitives
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 60
- Lines: +2348 / -636
- Touched areas: expo-app(60)
- Topic bucket: `sync`
- Manual review needed: YES (diff summary skipped (too many files (60)); safety/security-sensitive area)

### Commit Message Body

```text
- Add encrypted-at-rest SecretString plumbing and saved secrets/settings schemas (no plaintext persisted).

- Introduce terminal/tmux settings types and helpers (global + per-machine overrides) plus spawn payload utilities.

- Add platform crypto shims for vitest/node and extend sync + encryption utilities to support these flows.

- Add focused tests for secret sealing/decryption, secret satisfaction, spawn payload construction, terminal settings resolution, and detect-cli response parsing.
```

### Files (name-status)

```text
M	expo-app/sources/encryption/aes.appspec.ts
M	expo-app/sources/encryption/base64.appspec.ts
M	expo-app/sources/encryption/hmac_sha512.ts
M	expo-app/sources/encryption/libsodium.ts
A	expo-app/sources/platform/cryptoRandom.node.ts
A	expo-app/sources/platform/cryptoRandom.ts
A	expo-app/sources/platform/digest.node.ts
A	expo-app/sources/platform/digest.ts
A	expo-app/sources/platform/hmacSha512.node.ts
A	expo-app/sources/platform/hmacSha512.ts
A	expo-app/sources/platform/randomUUID.node.ts
A	expo-app/sources/platform/randomUUID.ts
M	expo-app/sources/profileRouteParams.ts
M	expo-app/sources/sync/apiArtifacts.ts
M	expo-app/sources/sync/apiFeed.ts
M	expo-app/sources/sync/apiFriends.ts
M	expo-app/sources/sync/apiGithub.ts
M	expo-app/sources/sync/apiKv.ts
M	expo-app/sources/sync/apiPush.ts
M	expo-app/sources/sync/apiServices.ts
M	expo-app/sources/sync/apiSocket.ts
M	expo-app/sources/sync/apiUsage.ts
A	expo-app/sources/sync/debugSettings.ts
A	expo-app/sources/sync/detectCliResponse.test.ts
A	expo-app/sources/sync/detectCliResponse.ts
M	expo-app/sources/sync/encryption/artifactEncryption.ts
M	expo-app/sources/sync/encryption/encryption.ts
M	expo-app/sources/sync/encryption/encryptor.appspec.ts
A	expo-app/sources/sync/ops.spawnSessionPayload.test.ts
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/persistence.test.ts
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/profileGrouping.test.ts
M	expo-app/sources/sync/profileMutations.ts
M	expo-app/sources/sync/profileSecrets.ts
M	expo-app/sources/sync/profileUtils.ts
M	expo-app/sources/sync/reducer/reducer.spec.ts
M	expo-app/sources/sync/reducer/reducer.ts
A	expo-app/sources/sync/secretBindings.test.ts
A	expo-app/sources/sync/secretBindings.ts
A	expo-app/sources/sync/secretSettings.test.ts
A	expo-app/sources/sync/secretSettings.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
A	expo-app/sources/sync/spawnSessionPayload.ts
M	expo-app/sources/sync/storage.ts
A	expo-app/sources/sync/storageTypes.terminal.test.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/sync.ts
A	expo-app/sources/sync/terminalSettings.spec.ts
A	expo-app/sources/sync/terminalSettings.ts
M	expo-app/sources/utils/errors.ts
M	expo-app/sources/utils/oauth.ts
A	expo-app/sources/utils/secretSatisfaction.test.ts
A	expo-app/sources/utils/secretSatisfaction.ts
M	expo-app/sources/utils/sync.ts
M	expo-app/sources/utils/tempDataStore.ts
A	expo-app/sources/utils/terminalSessionDetails.test.ts
A	expo-app/sources/utils/terminalSessionDetails.ts
M	expo-app/sources/utils/time.ts
```

### Diffstat

```text
 expo-app/sources/encryption/aes.appspec.ts         |   2 +-
 expo-app/sources/encryption/base64.appspec.ts      |   2 +-
 expo-app/sources/encryption/hmac_sha512.ts         |  49 +--
 expo-app/sources/encryption/libsodium.ts           |   2 +-
 expo-app/sources/platform/cryptoRandom.node.ts     |  17 +
 expo-app/sources/platform/cryptoRandom.ts          |  24 ++
 expo-app/sources/platform/digest.node.ts           |  15 +
 expo-app/sources/platform/digest.ts                |  24 ++
 expo-app/sources/platform/hmacSha512.node.ts       |  14 +
 expo-app/sources/platform/hmacSha512.ts            |  52 +++
 expo-app/sources/platform/randomUUID.node.ts       |  19 +
 expo-app/sources/platform/randomUUID.ts            |  14 +
 expo-app/sources/profileRouteParams.ts             |  24 +-
 expo-app/sources/sync/apiArtifacts.ts              |  59 ++-
 expo-app/sources/sync/apiFeed.ts                   |  11 +
 expo-app/sources/sync/apiFriends.ts                |  51 +++
 expo-app/sources/sync/apiGithub.ts                 |  35 +-
 expo-app/sources/sync/apiKv.ts                     |  41 +++
 expo-app/sources/sync/apiPush.ts                   |  11 +
 expo-app/sources/sync/apiServices.ts               |  23 +-
 expo-app/sources/sync/apiSocket.ts                 |  10 +
 expo-app/sources/sync/apiUsage.ts                  |  13 +-
 expo-app/sources/sync/debugSettings.ts             | 101 ++++++
 expo-app/sources/sync/detectCliResponse.test.ts    |  62 ++++
 expo-app/sources/sync/detectCliResponse.ts         |  70 ++++
 .../sources/sync/encryption/artifactEncryption.ts  |   4 +-
 expo-app/sources/sync/encryption/encryption.ts     |   2 +-
 .../sources/sync/encryption/encryptor.appspec.ts   |   2 +-
 .../sources/sync/ops.spawnSessionPayload.test.ts   |  44 +++
 expo-app/sources/sync/ops.ts                       |  88 +----
 expo-app/sources/sync/persistence.test.ts          |  78 +++-
 expo-app/sources/sync/persistence.ts               | 118 +++++-
 expo-app/sources/sync/profileGrouping.test.ts      |   1 +
 expo-app/sources/sync/profileMutations.ts          |   3 +-
 expo-app/sources/sync/profileSecrets.ts            |  11 +-
 expo-app/sources/sync/profileUtils.ts              |  22 +-
 expo-app/sources/sync/reducer/reducer.spec.ts      |  13 +-
 expo-app/sources/sync/reducer/reducer.ts           |  20 +-
 expo-app/sources/sync/secretBindings.test.ts       |  53 +++
 expo-app/sources/sync/secretBindings.ts            | 103 ++++++
 expo-app/sources/sync/secretSettings.test.ts       |  44 +++
 expo-app/sources/sync/secretSettings.ts            | 157 ++++++++
 expo-app/sources/sync/settings.spec.ts             | 404 ++++-----------------
 expo-app/sources/sync/settings.ts                  | 166 ++++-----
 expo-app/sources/sync/spawnSessionPayload.ts       |  55 +++
 expo-app/sources/sync/storage.ts                   |  43 ++-
 .../sources/sync/storageTypes.terminal.test.ts     |  30 ++
 expo-app/sources/sync/storageTypes.ts              |   9 +
 expo-app/sources/sync/sync.ts                      | 203 ++++++++++-
 expo-app/sources/sync/terminalSettings.spec.ts     |  74 ++++
 expo-app/sources/sync/terminalSettings.ts          |  53 +++
 expo-app/sources/utils/errors.ts                   |  10 +-
 expo-app/sources/utils/oauth.ts                    |  11 +-
 expo-app/sources/utils/secretSatisfaction.test.ts  |  81 +++++
 expo-app/sources/utils/secretSatisfaction.ts       | 160 ++++++++
 expo-app/sources/utils/sync.ts                     |  66 +++-
 expo-app/sources/utils/tempDataStore.ts            |   2 +-
 .../sources/utils/terminalSessionDetails.test.ts   |  41 +++
 expo-app/sources/utils/terminalSessionDetails.ts   |  26 ++
 expo-app/sources/utils/time.ts                     |  42 ++-
 60 files changed, 2348 insertions(+), 636 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(sync): add secrets + terminal settings primitives
- Diff summary skipped: too many files (60).

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(sync): add secrets + terminal settings primitives`

### Topic Bucket

- `sync`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 041 2026-01-21 66ee1eaf88a6

- SHA: 66ee1eaf88a68f1cfb742958ff06521f9a83cf97
- Subject: feat(secrets): add secrets management + requirement resolver
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 29
- Lines: +2315 / -1099
- Touched areas: expo-app(29)
- Topic bucket: `secrets`
- Manual review needed: YES (diff summary skipped (too many files (29)); safety/security-sensitive area)

### Commit Message Body

```text
- Replace legacy API key settings with encrypted-at-rest Secrets (saved secrets + session-only entry).

- Add SecretRequirementModal flow (use machine env / select saved / enter once) and improve profile requirements UX.

- Update env-var UI to handle sensitive/forced-sensitive values and improve disclosure controls.

- Extend i18n + theme tokens for the new secrets and requirements UI.
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
M	expo-app/sources/app/(app)/settings/profiles.tsx
R055	expo-app/sources/app/(app)/settings/api-keys.tsx	expo-app/sources/app/(app)/settings/secrets.tsx
D	expo-app/sources/components/ApiKeyRequirementModal.tsx
M	expo-app/sources/components/EnvironmentVariableCard.tsx
M	expo-app/sources/components/EnvironmentVariablesList.test.ts
M	expo-app/sources/components/EnvironmentVariablesList.tsx
M	expo-app/sources/components/ProfileEditForm.tsx
M	expo-app/sources/components/ProfileRequirementsBadge.tsx
A	expo-app/sources/components/SecretRequirementModal.tsx
M	expo-app/sources/components/profileActions.ts
M	expo-app/sources/components/profiles/ProfilesList.tsx
A	expo-app/sources/components/profiles/profileDisplay.ts
R092	expo-app/sources/components/ApiKeyAddModal.tsx	expo-app/sources/components/secrets/SecretAddModal.tsx
R060	expo-app/sources/components/apiKeys/ApiKeysList.tsx	expo-app/sources/components/secrets/SecretsList.tsx
A	expo-app/sources/hooks/useEnvironmentVariables.hook.test.ts
M	expo-app/sources/hooks/useEnvironmentVariables.ts
A	expo-app/sources/hooks/useMachineEnvPresence.ts
M	expo-app/sources/hooks/useProfileEnvRequirements.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
M	expo-app/sources/theme.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx   | 179 ++---
 expo-app/sources/app/(app)/settings/profiles.tsx   |  91 ++-
 .../(app)/settings/{api-keys.tsx => secrets.tsx}   |  15 +-
 .../sources/components/ApiKeyRequirementModal.tsx  | 348 ---------
 .../sources/components/EnvironmentVariableCard.tsx | 116 ++-
 .../components/EnvironmentVariablesList.test.ts    |  12 +
 .../components/EnvironmentVariablesList.tsx        |  19 +
 expo-app/sources/components/ProfileEditForm.tsx    | 396 +++++-----
 .../components/ProfileRequirementsBadge.tsx        |  38 +-
 .../sources/components/SecretRequirementModal.tsx  | 799 +++++++++++++++++++++
 expo-app/sources/components/profileActions.ts      |   2 +-
 .../sources/components/profiles/ProfilesList.tsx   |  87 ++-
 .../sources/components/profiles/profileDisplay.ts  |  14 +
 .../SecretAddModal.tsx}                            |  29 +-
 .../ApiKeysList.tsx => secrets/SecretsList.tsx}    | 130 ++--
 .../hooks/useEnvironmentVariables.hook.test.ts     |  41 ++
 expo-app/sources/hooks/useEnvironmentVariables.ts  |  11 +-
 expo-app/sources/hooks/useMachineEnvPresence.ts    | 184 +++++
 .../sources/hooks/useProfileEnvRequirements.ts     |  14 +-
 expo-app/sources/text/translations/ca.ts           |  99 ++-
 expo-app/sources/text/translations/en.ts           |  97 ++-
 expo-app/sources/text/translations/es.ts           |  99 ++-
 expo-app/sources/text/translations/it.ts           |  99 ++-
 expo-app/sources/text/translations/ja.ts           |  99 ++-
 expo-app/sources/text/translations/pl.ts           |  99 ++-
 expo-app/sources/text/translations/pt.ts           |  99 ++-
 expo-app/sources/text/translations/ru.ts           |  97 ++-
 expo-app/sources/text/translations/zh-Hans.ts      |  99 ++-
 expo-app/sources/theme.ts                          |   2 +-
 29 files changed, 2315 insertions(+), 1099 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(secrets): add secrets management + requirement resolver
- Diff summary skipped: too many files (29).

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(secrets): add secrets management + requirement resolver`

### Topic Bucket

- `secrets`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 042 2026-01-21 bdaf6913141f

- SHA: bdaf6913141f58774c1b2b2aeca4ace3e8633531
- Subject: feat(terminal): add Terminal settings + tmux metadata
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 8
- Lines: +509 / -28
- Touched areas: expo-app(8)
- Topic bucket: `terminal`
- Manual review needed: no

### Commit Message Body

```text
- Add Terminal settings screen with tmux options (session name, isolated server, tmp dir) and keep /settings/tmux as a backward-compatible alias.

- Update Settings entry to Terminal and show enabled/disabled subtitle based on terminalUseTmux.

- Extend CLI detection hook to include tmux availability and display it on machine details.

- Surface tmux attach target + fallback reason in session details for debugging/resume workflows.
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/session/[id]/info.tsx
A	expo-app/sources/app/(app)/settings/terminal.tsx
A	expo-app/sources/app/(app)/settings/tmux.tsx
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/components/machine/DetectedClisList.tsx
A	expo-app/sources/hooks/useCLIDetection.hook.test.ts
M	expo-app/sources/hooks/useCLIDetection.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/machine/[id].tsx        | 189 ++++++++++++++++++++-
 expo-app/sources/app/(app)/session/[id]/info.tsx   |  63 ++++++-
 expo-app/sources/app/(app)/settings/terminal.tsx   | 117 +++++++++++++
 expo-app/sources/app/(app)/settings/tmux.tsx       |   1 +
 expo-app/sources/components/SettingsView.tsx       |  35 +++-
 .../components/machine/DetectedClisList.tsx        |  18 +-
 .../sources/hooks/useCLIDetection.hook.test.ts     |  98 +++++++++++
 expo-app/sources/hooks/useCLIDetection.ts          |  16 +-
 8 files changed, 509 insertions(+), 28 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(terminal): add Terminal settings + tmux metadata
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/machine/[id].tsx: +187/-2 | adds const next, const response, const setTmuxOverrideEnabled, const setTmuxOverrideUseTmux, const terminal, const terminalTmuxIsolated | touches const styles = StyleSheet.create((theme) => ({; export default function MachineDetailScreen() {; import type { MachineDetectCliCacheState } from '@/hooks/useMachineDetectCliCach; import { Typography } from '@/constants/Typography';
  - expo-app/sources/app/(app)/settings/terminal.tsx: +117/-0 | adds const styles | touches @@ -0,0 +1,117 @@
  - expo-app/sources/hooks/useCLIDetection.hook.test.ts: +98/-0 | adds const useMachineDetectCliCacheMock, function Test | touches @@ -0,0 +1,98 @@
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +54/-9 | adds const attachCommand, const handleCopyAttachCommand, const resolved, const tmuxFallbackReason, const tmuxTarget | removes const builtIn, const custom, const key | touches function SessionInfoContent({ session }: { session: Session }) {; import { HappyError } from '@/utils/errors';; import { isVersionSupported, MINIMUM_CLI_VERSION } from '@/utils/versionUtils';
  - expo-app/sources/components/SettingsView.tsx: +28/-7 | adds const params, const terminalUseTmux | removes const params | touches export const SettingsView = React.memo(function SettingsView() {; import { MachineCliGlyphs } from '@/components/newSession/MachineCliGlyphs';
  - expo-app/sources/components/machine/DetectedClisList.tsx: +11/-7 | adds const version | removes const entries, const version | touches export function DetectedClisList({ state, layout = 'inline' }: Props) {
  - expo-app/sources/hooks/useCLIDetection.ts: +13/-3 | touches export function useCLIDetection(machineId: string | null, options?: UseCLIDetect; interface CLIAvailability {
  - expo-app/sources/app/(app)/settings/tmux.tsx: +1/-0 | touches @@ -0,0 +1 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(terminal): add Terminal settings + tmux metadata`

### Topic Bucket

- `terminal`

### Notes / Follow-ups


---

## 043 2026-01-21 bc779e4f7909

- SHA: bc779e4f7909eeeb1725b5352860d024961a0dba
- Subject: refactor(new-session): integrate secrets + terminal spawn options
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 17
- Lines: +1051 / -661
- Touched areas: expo-app(17)
- Topic bucket: `new-session`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
- Wire secret requirement resolution into the new session wizard (saved secrets, machine env, and session-only values).

- Use centralized terminal spawn option resolution for tmux requests and surface tmux-not-detected banners during machine selection.

- Update supporting screens/components (new session pickers, sidebar/main view, auth prompts) to match the new flows.
```

### Files (name-status)

```text
M	expo-app/sources/-zen/model/ops.ts
M	expo-app/sources/app/(app)/dev/messages-demo-data.ts
M	expo-app/sources/app/(app)/dev/todo-demo.tsx
M	expo-app/sources/app/(app)/friends/search.tsx
M	expo-app/sources/app/(app)/index.tsx
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/app/(app)/new/pick/profile-edit.tsx
M	expo-app/sources/app/(app)/new/pick/profile.tsx
R058	expo-app/sources/app/(app)/new/pick/api-key.tsx	expo-app/sources/app/(app)/new/pick/secret.tsx
M	expo-app/sources/auth/authChallenge.ts
M	expo-app/sources/auth/authQRStart.ts
M	expo-app/sources/components/MainView.tsx
M	expo-app/sources/components/OptionTiles.tsx
M	expo-app/sources/components/SidebarView.tsx
M	expo-app/sources/hooks/useSearch.ts
```

### Diffstat

```text
 expo-app/sources/-zen/model/ops.ts                 |    2 +-
 .../sources/app/(app)/dev/messages-demo-data.ts    |    2 +-
 expo-app/sources/app/(app)/dev/todo-demo.tsx       |    2 +-
 expo-app/sources/app/(app)/friends/search.tsx      |   11 +-
 expo-app/sources/app/(app)/index.tsx               |    2 +-
 .../sources/app/(app)/new/NewSessionWizard.tsx     |  167 ++--
 expo-app/sources/app/(app)/new/index.tsx           | 1026 +++++++++++---------
 expo-app/sources/app/(app)/new/pick/machine.tsx    |   61 +-
 .../sources/app/(app)/new/pick/profile-edit.tsx    |   14 +-
 expo-app/sources/app/(app)/new/pick/profile.tsx    |  162 +++-
 .../app/(app)/new/pick/{api-key.tsx => secret.tsx} |   23 +-
 expo-app/sources/auth/authChallenge.ts             |    2 +-
 expo-app/sources/auth/authQRStart.ts               |    2 +-
 expo-app/sources/components/MainView.tsx           |   52 +-
 expo-app/sources/components/OptionTiles.tsx        |   21 +-
 expo-app/sources/components/SidebarView.tsx        |   98 +-
 expo-app/sources/hooks/useSearch.ts                |   65 +-
 17 files changed, 1051 insertions(+), 661 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(new-session): integrate secrets + terminal spawn options
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/new/index.tsx: +591/-435 | adds const activeSecretSource, const allProfilesRequirementNames, const decrypted, const enc, const entry, const getSecretMachineEnvOverride | removes const actions, const activeApiKeySource, const apiKeyPreflight, const availability | touches function NewSessionScreen() {; import { EnvironmentVariablesPreviewModal } from '@/components/newSession/Enviro; import { NewSessionWizard } from './NewSessionWizard';; import { getModelOptionsForAgentType } from '@/sync/modelOptions';
  - expo-app/sources/app/(app)/new/NewSessionWizard.tsx: +111/-56 | adds const handleAgentInputAgentClick, const handleAgentInputMachineClick, const handleAgentInputPathClick, const handleAgentInputPermissionClick, const handleAgentInputProfileClick, const onRefreshMachines | removes const hasInjected, const hasMachineEnv | touches export const NewSessionWizard = React.memo(function NewSessionWizard(props: NewS; export interface NewSessionWizardAgentProps {; export interface NewSessionWizardFooterProps {; export interface NewSessionWizardLayoutProps {
  - expo-app/sources/app/(app)/new/pick/profile.tsx: +120/-42 | adds const allRequiredSecretNames, const getSecretMachineEnvOverride, const handleResolve, const item, const machineEnvPresence, const missing | removes const defaultKey, const defaultKeyId, const handleResolve, const machineHasKey | touches export default React.memo(function ProfilePickerScreen() {; import { Modal } from '@/modal';; import { ProfilesList } from '@/components/profiles/ProfilesList';; import { getProfileEnvironmentVariables } from '@/sync/settings';
  - expo-app/sources/components/SidebarView.tsx: +82/-16 | adds const popoverBoundaryRef, const syncError | touches @@ -1 +1 @@; const stylesheet = StyleSheet.create((theme, runtime) => ({; export const SidebarView = React.memo(() => {; import { Ionicons } from '@expo/vector-icons';
  - expo-app/sources/hooks/useSearch.ts: +37/-28 | adds const maxAttempts, const requestId, const requestIdRef | removes const isSearchingRef | touches export function useSearch<T>(; import { useEffect, useRef, useState, useCallback } from 'react';
  - expo-app/sources/app/(app)/new/pick/machine.tsx: +58/-3 | adds const handleRefresh, const selectedMachineId | touches export default React.memo(function MachinePickerScreen() {; import React from 'react';; import { getRecentMachinesFromSessions } from '@/utils/recentMachines';
  - expo-app/sources/components/MainView.tsx: +2/-50 | removes const connectionStatus, const socketStatus | touches const HeaderTitle = React.memo(({ activeTab }: { activeTab: ActiveTabType }) =>; import { trackFriendsSearch } from '@/track';
  - expo-app/sources/app/(app)/new/pick/secret.tsx: +12/-11 | adds const setSecretParamAndClose | removes const setApiKeyParamAndClose | touches export default React.memo(function ApiKeyPickerScreen() {; import { ApiKeysList } from '@/components/apiKeys/ApiKeysList';; import { t } from '@/text';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(new-session): integrate secrets + terminal spawn options`

### Topic Bucket

- `new-session`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 044 2026-01-21 cb11d4bdb25a

- SHA: cb11d4bdb25a6423f156dd0f9b859b5fbf603857
- Subject: docs: add AGENTS.md symlink + update CLAUDE.md
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +82 / -1
- Touched areas: expo-app(2)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
- Keep agent guidance single-sourced by symlinking AGENTS.md -> CLAUDE.md.

- Update CLAUDE.md to reflect current test runner and document modal/popover + settings/secret invariants.
```

### Files (name-status)

```text
A	expo-app/AGENTS.md
M	expo-app/CLAUDE.md
```

### Diffstat

```text
 expo-app/AGENTS.md |  1 +
 expo-app/CLAUDE.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 82 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): docs: add AGENTS.md symlink + update CLAUDE.md
- Key files by churn (top 2):
  - expo-app/CLAUDE.md: +81/-1 | touches const MyComponent = () => {; sources/
  - expo-app/AGENTS.md: +1/-0 | touches @@ -0,0 +1 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `docs: add AGENTS.md symlink + update CLAUDE.md`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 045 2026-01-21 1bc3b9715776

- SHA: 1bc3b971577664fc1f3d1f84a490c8054358c230
- Subject: fix(sync): handle non-JSON 400 responses
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +51 / -3
- Touched areas: expo-app(2)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/sync/apiGithub.test.ts
M	expo-app/sources/sync/apiGithub.ts
```

### Diffstat

```text
 expo-app/sources/sync/apiGithub.test.ts | 42 +++++++++++++++++++++++++++++++++
 expo-app/sources/sync/apiGithub.ts      | 12 +++++++---
 2 files changed, 51 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): handle non-JSON 400 responses
- Key files by churn (top 2):
  - expo-app/sources/sync/apiGithub.test.ts: +42/-0 | adds class MMKV, const jsonError | touches @@ -0,0 +1,42 @@
  - expo-app/sources/sync/apiGithub.ts: +9/-3 | adds const error | removes const error | touches export async function disconnectGitHub(credentials: AuthCredentials): Promise<vo; export async function getGitHubOAuthParams(credentials: AuthCredentials): Promis

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): handle non-JSON 400 responses`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 046 2026-01-21 ea2e4d19d633

- SHA: ea2e4d19d63370180f5558093ab3df1b9fb2f75b
- Subject: chore(deps): align react-test-renderer with react
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +8 / -8
- Touched areas: expo-app(2)
- Topic bucket: `deps`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/package.json
M	expo-app/yarn.lock
```

### Diffstat

```text
 expo-app/package.json |  2 +-
 expo-app/yarn.lock    | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(deps): align react-test-renderer with react
- Key files by churn (top 2):
  - expo-app/yarn.lock: +7/-7 | touches react-is@^18.0.0:; react-syntax-highlighter@^15.6.1:; react-test-renderer@19.0.0:
  - expo-app/package.json: +1/-1 | touches @@ -179 +179 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(deps): align react-test-renderer with react`

### Topic Bucket

- `deps`

### Notes / Follow-ups


---

## 047 2026-01-21 dd041d21ecfc

- SHA: dd041d21ecfc38b571011972a08b8532e5fe499f
- Subject: fix(sync): guard JSON parsing on disconnect errors
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +85 / -6
- Touched areas: expo-app(4)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/apiGithub.test.ts
M	expo-app/sources/sync/apiGithub.ts
A	expo-app/sources/sync/apiServices.test.ts
M	expo-app/sources/sync/apiServices.ts
```

### Diffstat

```text
 expo-app/sources/sync/apiGithub.test.ts   | 29 +++++++++++++++++++++-
 expo-app/sources/sync/apiGithub.ts        | 10 ++++++--
 expo-app/sources/sync/apiServices.test.ts | 40 +++++++++++++++++++++++++++++++
 expo-app/sources/sync/apiServices.ts      | 12 +++++++---
 4 files changed, 85 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): guard JSON parsing on disconnect errors
- Key files by churn (top 4):
  - expo-app/sources/sync/apiServices.test.ts: +40/-0 | adds class MMKV, const jsonError | touches @@ -0,0 +1,40 @@
  - expo-app/sources/sync/apiGithub.test.ts: +28/-1 | adds const jsonError | touches describe('getGitHubOAuthParams', () => {; import { HappyError } from '@/utils/errors';
  - expo-app/sources/sync/apiServices.ts: +9/-3 | adds const error | removes const error | touches export async function disconnectService(credentials: AuthCredentials, service: s
  - expo-app/sources/sync/apiGithub.ts: +8/-2 | adds const error | removes const error | touches export async function disconnectGitHub(credentials: AuthCredentials): Promise<vo

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): guard JSON parsing on disconnect errors`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 048 2026-01-21 395da4ff3167

- SHA: 395da4ff31674675c93d443626d50d3baa3f99ed
- Subject: refactor(zen): avoid todo variable shadowing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +2 / -2
- Touched areas: expo-app(1)
- Topic bucket: `zen`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-zen/ZenHome.tsx
```

### Diffstat

```text
 expo-app/sources/-zen/ZenHome.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(zen): avoid todo variable shadowing
- Key files by churn (top 1):
  - expo-app/sources/-zen/ZenHome.tsx: +2/-2 | touches export const ZenHome = () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(zen): avoid todo variable shadowing`

### Topic Bucket

- `zen`

### Notes / Follow-ups


---

## 049 2026-01-21 2e956f32f220

- SHA: 2e956f32f2200c1eb8199efc51ce1b443bf20e81
- Subject: fix(new): keep pick screens above iOS modal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 13
- Lines: +739 / -37
- Touched areas: expo-app(13)
- Topic bucket: `new`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/__tests__/app/new/pick/machine.presentation.test.ts
A	expo-app/sources/__tests__/app/new/pick/path.presentation.test.ts
A	expo-app/sources/__tests__/app/new/pick/profile-edit.headerButtons.test.ts
A	expo-app/sources/__tests__/app/new/pick/profile.presentation.test.ts
A	expo-app/sources/__tests__/app/new/pick/secret.presentation.test.ts
A	expo-app/sources/__tests__/app/settings/profiles.nativeNavigation.test.ts
M	expo-app/sources/app/(app)/_layout.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/app/(app)/new/pick/path.tsx
M	expo-app/sources/app/(app)/new/pick/profile-edit.tsx
M	expo-app/sources/app/(app)/new/pick/profile.tsx
M	expo-app/sources/app/(app)/new/pick/secret.tsx
M	expo-app/sources/app/(app)/settings/profiles.tsx
```

### Diffstat

```text
 .../app/new/pick/machine.presentation.test.ts      |  82 ++++++++++++
 .../app/new/pick/path.presentation.test.ts         |  84 ++++++++++++
 .../new/pick/profile-edit.headerButtons.test.ts    | 141 +++++++++++++++++++++
 .../app/new/pick/profile.presentation.test.ts      |  99 +++++++++++++++
 .../app/new/pick/secret.presentation.test.ts       |  56 ++++++++
 .../app/settings/profiles.nativeNavigation.test.ts | 135 ++++++++++++++++++++
 expo-app/sources/app/(app)/_layout.tsx             |   5 +
 expo-app/sources/app/(app)/new/pick/machine.tsx    |  28 +++-
 expo-app/sources/app/(app)/new/pick/path.tsx       |  32 ++++-
 .../sources/app/(app)/new/pick/profile-edit.tsx    |  61 +++++----
 expo-app/sources/app/(app)/new/pick/profile.tsx    |  15 +++
 expo-app/sources/app/(app)/new/pick/secret.tsx     |  19 ++-
 expo-app/sources/app/(app)/settings/profiles.tsx   |  19 ++-
 13 files changed, 739 insertions(+), 37 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(new): keep pick screens above iOS modal
- Key files by churn (top 8):
  - expo-app/sources/__tests__/app/new/pick/profile-edit.headerButtons.test.ts: +141/-0 | adds const ProfileEditScreen, const React, const headerRight, const navigationMock, const routerMock, const saveButton | touches @@ -0,0 +1,141 @@
  - expo-app/sources/__tests__/app/settings/profiles.nativeNavigation.test.ts: +135/-0 | adds const ProfileManager, const React, const routerMock | touches @@ -0,0 +1,135 @@
  - expo-app/sources/__tests__/app/new/pick/profile.presentation.test.ts: +99/-0 | adds const ProfilePickerScreen | touches @@ -0,0 +1,99 @@
  - expo-app/sources/__tests__/app/new/pick/path.presentation.test.ts: +84/-0 | adds const PathPickerScreen | touches @@ -0,0 +1,84 @@
  - expo-app/sources/__tests__/app/new/pick/machine.presentation.test.ts: +82/-0 | adds const MachinePickerScreen, const React, const stackScreen | touches @@ -0,0 +1,82 @@
  - expo-app/sources/app/(app)/new/pick/profile-edit.tsx: +29/-32 | touches export default React.memo(function ProfileEditScreen() {
  - expo-app/sources/__tests__/app/new/pick/secret.presentation.test.ts: +56/-0 | adds const SecretPickerScreen | touches @@ -0,0 +1,56 @@
  - expo-app/sources/app/(app)/new/pick/path.tsx: +31/-1 | touches export default React.memo(function PathPickerScreen() {; import React, { useState, useMemo } from 'react';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(new): keep pick screens above iOS modal`

### Topic Bucket

- `new`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 050 2026-01-21 2da2f9349ec5

- SHA: 2da2f9349ec5f50932cd3c2834c7b6c2fd0db16f
- Subject: fix(popover): allow web fixed positioning types
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +4 / -4
- Touched areas: expo-app(1)
- Topic bucket: `popover`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/Popover.tsx
```

### Diffstat

```text
 expo-app/sources/components/Popover.tsx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(popover): allow web fixed positioning types
- Key files by churn (top 1):
  - expo-app/sources/components/Popover.tsx: +4/-4 | adds const position | removes const position | touches export function Popover(props: PopoverWithBackdrop | PopoverWithoutBackdrop) {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(popover): allow web fixed positioning types`

### Topic Bucket

- `popover`

### Notes / Follow-ups


---

## 051 2026-01-21 43f23f2f082e

- SHA: 43f23f2f082e149eb2d5d29b43b5c7461eaa5e40
- Subject: chore(format): replace stray tabs with spaces
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +26 / -26
- Touched areas: expo-app(2)
- Topic bucket: `format`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/SearchHeader.tsx
M	expo-app/sources/sync/settings.spec.ts
```

### Diffstat

```text
 expo-app/sources/components/SearchHeader.tsx | 42 ++++++++++++++--------------
 expo-app/sources/sync/settings.spec.ts       | 10 +++----
 2 files changed, 26 insertions(+), 26 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(format): replace stray tabs with spaces
- Key files by churn (top 2):
  - expo-app/sources/components/SearchHeader.tsx: +21/-21 | touches const stylesheet = StyleSheet.create((theme) => ({
  - expo-app/sources/sync/settings.spec.ts: +5/-5 | touches describe('settings', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(format): replace stray tabs with spaces`

### Topic Bucket

- `format`

### Notes / Follow-ups


---

## 052 2026-01-21 e1d55fdbd9ee

- SHA: e1d55fdbd9ee31fb9bb80ce1a65643bef5890d44
- Subject: fix(i18n): improve untranslated literal scan parsing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +12 / -2
- Touched areas: expo-app(1)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/scripts/findUntranslatedLiterals.ts
```

### Diffstat

```text
 expo-app/sources/scripts/findUntranslatedLiterals.ts | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): improve untranslated literal scan parsing
- Key files by churn (top 1):
  - expo-app/sources/scripts/findUntranslatedLiterals.ts: +12/-2 | adds const colonIndex, const kind, const scriptKind, const sourceFile, const text | removes const sourceFile | touches for (const [key, list] of grouped.entries()) {; function scanFile(filePath: string): Finding[] {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): improve untranslated literal scan parsing`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 053 2026-01-21 c210c1115598

- SHA: c210c111559885f1206dc836e7c13c9e1cf2bd45
- Subject: test(sync): restore stubbed fetch between tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +5 / -1
- Touched areas: expo-app(1)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/apiGithub.test.ts
```

### Diffstat

```text
 expo-app/sources/sync/apiGithub.test.ts | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(sync): restore stubbed fetch between tests
- Key files by churn (top 1):
  - expo-app/sources/sync/apiGithub.test.ts: +5/-1 | touches @@ -1 +1 @@; import { disconnectGitHub, getGitHubOAuthParams } from './apiGithub';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(sync): restore stubbed fetch between tests`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 054 2026-01-21 66c678451335

- SHA: 66c6784513355e763d09dcfc530c09348c1c3a70
- Subject: fix(ui): apply small review fixes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 8
- Lines: +23 / -25
- Touched areas: expo-app(8)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/app/(app)/settings/terminal.tsx
M	expo-app/sources/components/ConnectionStatusControl.tsx
M	expo-app/sources/components/OptionTiles.tsx
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/components/dropdown/DropdownMenu.tsx
M	expo-app/sources/utils/sync.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx          | 25 +++++++++++-----------
 expo-app/sources/app/(app)/new/pick/machine.tsx    |  6 +++---
 expo-app/sources/app/(app)/settings/terminal.tsx   |  3 +--
 .../sources/components/ConnectionStatusControl.tsx |  3 +--
 expo-app/sources/components/OptionTiles.tsx        |  2 +-
 expo-app/sources/components/SettingsView.tsx       |  3 +--
 .../sources/components/dropdown/DropdownMenu.tsx   |  2 +-
 expo-app/sources/utils/sync.ts                     |  4 ++--
 8 files changed, 23 insertions(+), 25 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): apply small review fixes
- Key files by churn (top 8):
  - expo-app/sources/-session/SessionView.tsx: +13/-12 | adds const CONFIGURABLE_MODEL_MODES, const isConfigurableModelMode, type ConfigurableModelMode | removes const CONFIGURABLE_MODEL_MODES, const isConfigurableModelMode, type ConfigurableModelMode | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import { useUnistyles } from 'react-native-unistyles';
  - expo-app/sources/app/(app)/new/pick/machine.tsx: +3/-3 | touches export default React.memo(function MachinePickerScreen() {; import { Stack, useRouter, useLocalSearchParams, useNavigation } from 'expo-rout
  - expo-app/sources/utils/sync.ts: +2/-2 | touches export class InvalidateSync {; export class ValueSync<T> {
  - expo-app/sources/components/SettingsView.tsx: +1/-2 | touches export const SettingsView = React.memo(function SettingsView() {
  - expo-app/sources/components/ConnectionStatusControl.tsx: +1/-2 | removes const isCustomServer | touches export const ConnectionStatusControl = React.memo(function ConnectionStatusContr; import { useSocketStatus, useSyncError, useLastSyncAt } from '@/sync/storage';
  - expo-app/sources/app/(app)/settings/terminal.tsx: +1/-2 | touches const styles = StyleSheet.create((theme) => ({; export default React.memo(function TerminalSettingsScreen() {
  - expo-app/sources/components/dropdown/DropdownMenu.tsx: +1/-1 | touches export function DropdownMenu(props: DropdownMenuProps) {
  - expo-app/sources/components/OptionTiles.tsx: +1/-1 | touches const stylesheet = StyleSheet.create((theme) => ({

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): apply small review fixes`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 055 2026-01-21 2472b376775c

- SHA: 2472b376775cf1ba60b0af98e7abcda7299defba
- Subject: test(modal): make backdrop z-index assertion safer
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +3 / -1
- Touched areas: expo-app(1)
- Topic bucket: `modal`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/modal/ModalProvider.test.ts
```

### Diffstat

```text
 expo-app/sources/modal/ModalProvider.test.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(modal): make backdrop z-index assertion safer
- Key files by churn (top 1):
  - expo-app/sources/modal/ModalProvider.test.ts: +3/-1 | touches describe('ModalProvider', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(modal): make backdrop z-index assertion safer`

### Topic Bucket

- `modal`

### Notes / Follow-ups


---

## 056 2026-01-21 02450d179aaf

- SHA: 02450d179aaf75c109ab7b7a387bf1bfc93c2805
- Subject: fix(profiles): align experimentsEnabled for built-in profiles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -2
- Touched areas: expo-app(1)
- Topic bucket: `profiles`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/profiles/ProfilesList.tsx
```

### Diffstat

```text
 expo-app/sources/components/profiles/ProfilesList.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(profiles): align experimentsEnabled for built-in profiles
- Key files by churn (top 1):
  - expo-app/sources/components/profiles/ProfilesList.tsx: +1/-2 | touches export function ProfilesList(props: ProfilesListProps) {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(profiles): align experimentsEnabled for built-in profiles`

### Topic Bucket

- `profiles`

### Notes / Follow-ups


---

## 057 2026-01-21 ff7bec72358f

- SHA: ff7bec72358f73e2cc5e0e816317e688d31aaabf
- Subject: fix(secrets): tighten callback deps and fix indentation
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +29 / -21
- Touched areas: expo-app(1)
- Topic bucket: `secrets`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/secrets/SecretsList.tsx
```

### Diffstat

```text
 .../sources/components/secrets/SecretsList.tsx     | 50 +++++++++++++---------
 1 file changed, 29 insertions(+), 21 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(secrets): tighten callback deps and fix indentation
- Key files by churn (top 1):
  - expo-app/sources/components/secrets/SecretsList.tsx: +29/-21 | adds const defaultSecret, const resolvedDefaultId, const rest | removes const defaultId, const defaultSecret, const rest | touches export function SecretsList(props: SecretsListProps) {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(secrets): tighten callback deps and fix indentation`

### Topic Bucket

- `secrets`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 058 2026-01-21 1bb65f5dd494

- SHA: 1bb65f5dd494e7d8d14533d6623dd2cdbabd0283
- Subject: fix(new-session): avoid stuck secret requirement modal guard
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +5 / -3
- Touched areas: expo-app(1)
- Topic bucket: `new-session`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/index.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/index.tsx | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(new-session): avoid stuck secret requirement modal guard
- Key files by churn (top 1):
  - expo-app/sources/app/(app)/new/index.tsx: +5/-3 | touches function NewSessionScreen() {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(new-session): avoid stuck secret requirement modal guard`

### Topic Bucket

- `new-session`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 059 2026-01-21 f7f81497444d

- SHA: f7f81497444d9547c9e077e3ad45c41a3293c2a2
- Subject: fix(modal): prevent non-dismissible WebAlertModal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +368 / -36
- Touched areas: expo-app(6)
- Topic bucket: `modal`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/__tests__/app/new/pick/machine.presentation.test.ts
A	expo-app/sources/components/ConnectionStatusControl.popover.test.ts
M	expo-app/sources/components/ConnectionStatusControl.tsx
M	expo-app/sources/components/Popover.test.ts
M	expo-app/sources/components/Popover.tsx
M	expo-app/sources/modal/components/WebAlertModal.tsx
```

### Diffstat

```text
 .../app/new/pick/machine.presentation.test.ts      |   6 +
 .../ConnectionStatusControl.popover.test.ts        | 123 +++++++++++++++++
 .../sources/components/ConnectionStatusControl.tsx |   1 +
 expo-app/sources/components/Popover.test.ts        | 121 ++++++++++++++++-
 expo-app/sources/components/Popover.tsx            | 149 ++++++++++++++++-----
 .../sources/modal/components/WebAlertModal.tsx     |   4 +-
 6 files changed, 368 insertions(+), 36 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(modal): prevent non-dismissible WebAlertModal
- Key files by churn (top 6):
  - expo-app/sources/components/Popover.tsx: +115/-34 | adds const anchorNode, const boundaryNode, const boundaryNodeRaw, const edge, const height, const isMountedRef | removes const anchorNode, const boundaryNode, const boundaryNodeRaw, const measureOnce | touches export function Popover(props: PopoverWithBackdrop | PopoverWithoutBackdrop) {; function measureInWindow(node: any): Promise<WindowRect | null> {; import { requireReactDOM } from '@/utils/reactDomCjs';
  - expo-app/sources/components/ConnectionStatusControl.popover.test.ts: +123/-0 | touches @@ -0,0 +1,123 @@
  - expo-app/sources/components/Popover.test.ts: +120/-1 | adds const anchorRef, const backdrop, const child, const childAfter, const contentView, const contentViewAfter | removes const backdrop | touches describe('Popover (web)', () => {
  - expo-app/sources/__tests__/app/new/pick/machine.presentation.test.ts: +6/-0 | touches vi.mock('expo-router', () => ({
  - expo-app/sources/modal/components/WebAlertModal.tsx: +3/-1 | touches export function WebAlertModal({ config, onClose, onConfirm, showBackdrop = true,
  - expo-app/sources/components/ConnectionStatusControl.tsx: +1/-0 | touches export const ConnectionStatusControl = React.memo(function ConnectionStatusContr

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(modal): prevent non-dismissible WebAlertModal`

### Topic Bucket

- `modal`

### Notes / Follow-ups


---

## 060 2026-01-22 bb09f91de715

- SHA: bb09f91de71568e402517d526a2f068f01cc555d
- Subject: fix(settings): keep valid secrets when one entry is invalid
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +44 / -0
- Touched areas: expo-app(2)
- Topic bucket: `settings`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
```

### Diffstat

```text
 expo-app/sources/sync/settings.spec.ts | 26 ++++++++++++++++++++++++++
 expo-app/sources/sync/settings.ts      | 18 ++++++++++++++++++
 2 files changed, 44 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(settings): keep valid secrets when one entry is invalid
- Key files by churn (top 2):
  - expo-app/sources/sync/settings.spec.ts: +26/-0 | adds const invalidSecret, const parsed, const validSecret | touches describe('settings', () => {
  - expo-app/sources/sync/settings.ts: +18/-0 | adds const parsedSecret, const secretsValue | touches export function settingsParse(settings: unknown): Settings {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(settings): keep valid secrets when one entry is invalid`

### Topic Bucket

- `settings`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 061 2026-01-22 765423af52b4

- SHA: 765423af52b457cf6ca83ae52cf10301568f4a9c
- Subject: fix(agent-input): cycle permission mode from normalized state
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +43 / -10
- Touched areas: expo-app(3)
- Topic bucket: `agent-input`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/AgentInput.tsx
M	expo-app/sources/sync/permissionTypes.test.ts
M	expo-app/sources/sync/permissionTypes.ts
```

### Diffstat

```text
 expo-app/sources/components/AgentInput.tsx    | 14 ++++----------
 expo-app/sources/sync/permissionTypes.test.ts | 23 +++++++++++++++++++++++
 expo-app/sources/sync/permissionTypes.ts      | 16 ++++++++++++++++
 3 files changed, 43 insertions(+), 10 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(agent-input): cycle permission mode from normalized state
- Key files by churn (top 3):
  - expo-app/sources/sync/permissionTypes.test.ts: +23/-0 | touches describe('isPermissionMode', () => {; import {
  - expo-app/sources/sync/permissionTypes.ts: +16/-0 | adds const currentIndex, const nextIndex, const normalized, const safeIndex, function getNextPermissionModeForAgentFlavor | touches export function normalizePermissionModeForAgentFlavor(mode: PermissionMode, flav
  - expo-app/sources/components/AgentInput.tsx: +4/-10 | adds const flavor | removes const currentIndex, const nextIndex | touches export const AgentInput = React.memo(React.forwardRef<MultiTextInputHandle, Agen; import { Typography } from '@/constants/Typography';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(agent-input): cycle permission mode from normalized state`

### Topic Bucket

- `agent-input`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 062 2026-01-22 e533db1813a5

- SHA: e533db1813a54a9f6901b133b10e6d848e091ac3
- Subject: fix(popover): add screens cjs helper and fix fixed positioning types
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +14 / -4
- Touched areas: expo-app(2)
- Topic bucket: `popover`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/Popover.tsx
A	expo-app/sources/utils/reactNativeScreensCjs.ts
```

### Diffstat

```text
 expo-app/sources/components/Popover.tsx         | 10 ++++++----
 expo-app/sources/utils/reactNativeScreensCjs.ts |  8 ++++++++
 2 files changed, 14 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(popover): add screens cjs helper and fix fixed positioning types
- Key files by churn (top 2):
  - expo-app/sources/components/Popover.tsx: +6/-4 | adds const fixedPositionOnWeb, const position | removes const position | touches export function Popover(props: PopoverWithBackdrop | PopoverWithoutBackdrop) {
  - expo-app/sources/utils/reactNativeScreensCjs.ts: +8/-0 | adds function requireReactNativeScreens | touches @@ -0,0 +1,8 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(popover): add screens cjs helper and fix fixed positioning types`

### Topic Bucket

- `popover`

### Notes / Follow-ups


---

## 063 2026-01-22 2ed3100311c7

- SHA: 2ed3100311c722a476844f6c6cbcc6a3cb0d920f
- Subject: fix(secrets): hide values when using secret vault
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 10
- Lines: +31 / -9
- Touched areas: expo-app(10)
- Topic bucket: `secrets`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/EnvironmentVariableCard.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 .../sources/components/EnvironmentVariableCard.tsx | 31 +++++++++++++++-------
 expo-app/sources/text/translations/ca.ts           |  1 +
 expo-app/sources/text/translations/en.ts           |  1 +
 expo-app/sources/text/translations/es.ts           |  1 +
 expo-app/sources/text/translations/it.ts           |  1 +
 expo-app/sources/text/translations/ja.ts           |  1 +
 expo-app/sources/text/translations/pl.ts           |  1 +
 expo-app/sources/text/translations/pt.ts           |  1 +
 expo-app/sources/text/translations/ru.ts           |  1 +
 expo-app/sources/text/translations/zh-Hans.ts      |  1 +
 10 files changed, 31 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(secrets): hide values when using secret vault
- Key files by churn (top 8):
  - expo-app/sources/components/EnvironmentVariableCard.tsx: +22/-9 | adds const canEditSecret, const hideValueInUi | removes const canEditSecret | touches export function EnvironmentVariableCard({
  - expo-app/sources/text/translations/zh-Hans.ts: +1/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +1/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +1/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +1/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +1/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +1/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +1/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(secrets): hide values when using secret vault`

### Topic Bucket

- `secrets`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 064 2026-01-22 e5848c480522

- SHA: e5848c4805226e1c460df58717b182d25f06d504
- Subject: fix(ui): harden overlays and permission cycling
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +302 / -8
- Touched areas: expo-app(6)
- Topic bucket: `ui`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/components/AgentInput.tsx
A	expo-app/sources/components/ItemRowActions.test.ts
M	expo-app/sources/components/ItemRowActions.tsx
A	expo-app/sources/components/OverlayPortal.test.ts
M	expo-app/sources/components/Popover.nativePortal.test.ts
```

### Diffstat

```text
 .../sources/app/(app)/new/NewSessionWizard.tsx     |   1 +
 expo-app/sources/components/AgentInput.tsx         |  15 ++-
 expo-app/sources/components/ItemRowActions.test.ts | 125 +++++++++++++++++++++
 expo-app/sources/components/ItemRowActions.tsx     |  21 +++-
 expo-app/sources/components/OverlayPortal.test.ts  |  58 ++++++++++
 .../components/Popover.nativePortal.test.ts        |  90 +++++++++++++++
 6 files changed, 302 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): harden overlays and permission cycling
- Key files by churn (top 6):
  - expo-app/sources/components/ItemRowActions.test.ts: +125/-0 | adds const React, const editRow, const onEdit, const theme, const trigger | touches @@ -0,0 +1,125 @@
  - expo-app/sources/components/Popover.nativePortal.test.ts: +90/-0 | adds const React, const anchorRef, const overlays | touches describe('Popover (native portal)', () => {; vi.mock('expo-blur', () => {
  - expo-app/sources/components/OverlayPortal.test.ts: +58/-0 | adds const React, function CaptureDispatch, function RenderCountChild | touches @@ -0,0 +1,58 @@
  - expo-app/sources/components/ItemRowActions.tsx: +17/-4 | adds const fallback, const runOnce | touches export function ItemRowActions(props: ItemRowActionsProps) {
  - expo-app/sources/components/AgentInput.tsx: +11/-4 | adds const currentIndex, const nextIndex | removes const flavor | touches export const AgentInput = React.memo(React.forwardRef<MultiTextInputHandle, Agen; import { Typography } from '@/constants/Typography';
  - expo-app/sources/app/(app)/new/NewSessionWizard.tsx: +1/-0 | touches export const NewSessionWizard = React.memo(function NewSessionWizard(props: NewS

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): harden overlays and permission cycling`

### Topic Bucket

- `ui`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 065 2026-01-13 69fdcff96a4c

- SHA: 69fdcff96a4c7f21982cbc64ebe6a47222b9d685
- Subject: fix(sync): restore session permission mode from last message
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +56 / -5
- Touched areas: expo-app(2)
- Topic bucket: `sync`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/sync/storageTypes.ts
```

### Diffstat

```text
 expo-app/sources/sync/storage.ts      | 56 +++++++++++++++++++++++++++++++++--
 expo-app/sources/sync/storageTypes.ts |  5 ++--
 2 files changed, 56 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): restore session permission mode from last message
- Key files by churn (top 2):
  - expo-app/sources/sync/storage.ts: +53/-3 | adds const canInferPermissionMode, const existingPermissionModeUpdatedAt, const mode, const now, const shouldWritePermissionMode | touches export const storage = create<StorageState>()((set, get) => {
  - expo-app/sources/sync/storageTypes.ts: +3/-2 | touches export interface Session {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): restore session permission mode from last message`

### Topic Bucket

- `sync`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 066 2026-01-13 9b499c5dccce

- SHA: 9b499c5dccce7aa7762f13dece9b259183949b9d
- Subject: fix(sync): persist permission mode timestamp for restart-safe arbitration
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +39 / -2
- Touched areas: expo-app(2)
- Topic bucket: `sync`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/storage.ts
```

### Diffstat

```text
 expo-app/sources/sync/persistence.ts | 21 +++++++++++++++++++++
 expo-app/sources/sync/storage.ts     | 20 ++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): persist permission mode timestamp for restart-safe arbitration
- Key files by churn (top 2):
  - expo-app/sources/sync/persistence.ts: +21/-0 | adds const parsed, const raw, function loadSessionPermissionModeUpdatedAts, function saveSessionPermissionModeUpdatedAts | touches export function saveSessionPermissionModes(modes: Record<string, PermissionMode>
  - expo-app/sources/sync/storage.ts: +18/-2 | adds const savedPermissionModeUpdatedAt, const savedPermissionModeUpdatedAts | touches export const storage = create<StorageState>()((set, get) => {; import type { PermissionMode } from '@/sync/permissionTypes';; import { UserProfile, RelationshipUpdatedEvent } from "./friendTypes";

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): persist permission mode timestamp for restart-safe arbitration`

### Topic Bucket

- `sync`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 067 2026-01-13 def8852509d0

- SHA: def8852509d0163a36ed4363770ebd52877338bd
- Subject: fix(sync): persist permission mode reliably across devices
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 11
- Lines: +141 / -48
- Touched areas: expo-app(11)
- Topic bucket: `sync`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
A	expo-app/sources/constants/PermissionModes.ts
M	expo-app/sources/sync/apiSocket.ts
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/sync.ts
A	expo-app/sources/sync/time.ts
M	expo-app/sources/sync/typesMessageMeta.ts
M	expo-app/sources/sync/typesRaw.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx     |   2 +-
 expo-app/sources/constants/PermissionModes.ts |  12 +++
 expo-app/sources/sync/apiSocket.ts            |  19 ++++-
 expo-app/sources/sync/persistence.ts          |  11 ++-
 expo-app/sources/sync/settings.ts             |   2 +-
 expo-app/sources/sync/storage.ts              | 106 +++++++++++++++++---------
 expo-app/sources/sync/storageTypes.ts         |   9 ++-
 expo-app/sources/sync/sync.ts                 |   5 +-
 expo-app/sources/sync/time.ts                 |  17 +++++
 expo-app/sources/sync/typesMessageMeta.ts     |   3 +-
 expo-app/sources/sync/typesRaw.ts             |   3 +-
 11 files changed, 141 insertions(+), 48 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): persist permission mode reliably across devices
- Key files by churn (top 8):
  - expo-app/sources/sync/storage.ts: +69/-37 | adds const localUpdatedAt, const metadataPermissionMode, const metadataPermissionModeUpdatedAt, const mode, const now, const persistSessionPermissionData | removes const mode, const now | touches export const storage = create<StorageState>()((set, get) => {; import { FeedItem } from "./feedTypes";
  - expo-app/sources/sync/apiSocket.ts: +18/-1 | adds const dateHeader, const response, const serverNow | touches class ApiSocket {; import { Encryption } from './encryption/encryption';
  - expo-app/sources/sync/time.ts: +17/-0 | adds function nowServerMs, function observeServerTimestamp | touches @@ -0,0 +1,17 @@
  - expo-app/sources/constants/PermissionModes.ts: +12/-0 | adds const PERMISSION_MODES, type PermissionMode | touches @@ -0,0 +1,12 @@
  - expo-app/sources/sync/persistence.ts: +9/-2 | touches export function loadSessionPermissionModeUpdatedAts(): Record<string, number> {
  - expo-app/sources/sync/storageTypes.ts: +7/-2 | touches export const MetadataSchema = z.object({; export interface Session {; import { z } from "zod";
  - expo-app/sources/sync/sync.ts: +3/-2 | adds const createdAt | removes const createdAt | touches class Sync {; import { systemPrompt } from './prompt/systemPrompt';
  - expo-app/sources/sync/typesRaw.ts: +2/-1 | touches const rawToolResultContentSchema = z.object({; import { MessageMetaSchema, MessageMeta } from './typesMessageMeta';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): persist permission mode reliably across devices`

### Topic Bucket

- `sync`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 068 2026-01-12 b1c8a6fecd01

- SHA: b1c8a6fecd0142b90bb4056797735eb9201cd53a
- Subject: fix(session): archive when kill RPC unavailable
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +41 / -7
- Touched areas: expo-app(4)
- Topic bucket: `session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/components/ActiveSessionsGroup.tsx
M	expo-app/sources/components/ActiveSessionsGroupCompact.tsx
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/session/[id]/info.tsx   |  4 +--
 .../sources/components/ActiveSessionsGroup.tsx     |  4 +--
 .../components/ActiveSessionsGroupCompact.tsx      |  4 +--
 expo-app/sources/sync/ops.ts                       | 36 +++++++++++++++++++++-
 4 files changed, 41 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(session): archive when kill RPC unavailable
- Key files by churn (top 4):
  - expo-app/sources/sync/ops.ts: +35/-1 | adds const isRpcMethodUnavailable, const killResult, const message, function sessionArchive, interface SessionArchiveResponse | touches export async function sessionKill(sessionId: string): Promise<SessionKillRespons; export type {
  - expo-app/sources/components/ActiveSessionsGroupCompact.tsx: +2/-2 | adds const result | removes const result | touches const CompactSessionRow = React.memo(({ session, selected, showBorder }: { sessi; import { isMachineOnline } from '@/utils/machineUtils';
  - expo-app/sources/components/ActiveSessionsGroup.tsx: +2/-2 | adds const result | removes const result | touches const CompactSessionRow = React.memo(({ session, selected, showBorder }: { sessi; import { isMachineOnline } from '@/utils/machineUtils';
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +2/-2 | adds const result | removes const result | touches function SessionInfoContent({ session }: { session: Session }) {; import { Modal } from '@/modal';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(session): archive when kill RPC unavailable`

### Topic Bucket

- `session`

### Notes / Follow-ups


---

## 069 2026-01-06 c06b6202b5d4

- SHA: c06b6202b5d490d71adc5bda9c9f739eceaa1e8c
- Subject: Add copy-to-clipboard button to message blocks
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +84 / -2
- Touched areas: expo-app(1)
- Topic bucket: `expo-app`
- Manual review needed: YES (non-Conventional-Commits subject)

### Commit Message Body

```text
Introduces a CopyMessageButton component to allow users to copy message text from user and agent message blocks. Includes visual feedback on copy and error handling, with related styles added for the new button.
```

### Files (name-status)

```text
M	expo-app/sources/components/MessageView.tsx
```

### Diffstat

```text
 expo-app/sources/components/MessageView.tsx | 86 ++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Add copy-to-clipboard button to message blocks
- Key files by churn (top 1):
  - expo-app/sources/components/MessageView.tsx: +84/-2 | adds const handlePress, const isCopyable, const markdown, const resetTimer, function CopyMessageButton | touches const styles = StyleSheet.create((theme) => ({; function AgentTextBlock(props: {; function UserTextBlock(props: {; import * as React from "react";

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(expo-app): add copy-to-clipboard button to message blocks`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 070 2026-01-21 9fc7d3d412b9

- SHA: 9fc7d3d412b9ffcfb7fc9db08c05199ece6f5d75
- Subject: feat(sessions): group inactive sessions by project
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 16
- Lines: +404 / -117
- Touched areas: expo-app(16)
- Topic bucket: `sessions`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
M	expo-app/sources/components/SessionsList.tsx
A	expo-app/sources/sync/sessionListViewData.test.ts
A	expo-app/sources/sync/sessionListViewData.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx  |   8 +
 expo-app/sources/components/SessionsList.tsx      |  16 +-
 expo-app/sources/sync/sessionListViewData.test.ts | 113 +++++++++++++
 expo-app/sources/sync/sessionListViewData.ts      | 193 ++++++++++++++++++++++
 expo-app/sources/sync/settings.spec.ts            |   1 +
 expo-app/sources/sync/settings.ts                 |   3 +
 expo-app/sources/sync/storage.ts                  | 169 +++++++------------
 expo-app/sources/text/translations/ca.ts          |   2 +
 expo-app/sources/text/translations/en.ts          |   2 +
 expo-app/sources/text/translations/es.ts          |   2 +
 expo-app/sources/text/translations/it.ts          |   2 +
 expo-app/sources/text/translations/ja.ts          |   2 +
 expo-app/sources/text/translations/pl.ts          |   2 +
 expo-app/sources/text/translations/pt.ts          |   2 +
 expo-app/sources/text/translations/ru.ts          |   2 +
 expo-app/sources/text/translations/zh-Hans.ts     |   2 +
 16 files changed, 404 insertions(+), 117 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(sessions): group inactive sessions by project
- Key files by churn (top 8):
  - expo-app/sources/sync/sessionListViewData.ts: +193/-0 | adds const dateString, const diffDays, const diffTime, const existing, const groupDate, const groups | touches @@ -0,0 +1,193 @@
  - expo-app/sources/sync/storage.ts: +58/-111 | adds const newSettings, const sessionListViewData, const shouldRebuildSessionListViewData | removes const dateString, const diffDays, const diffTime, const groupDate | touches export const storage = create<StorageState>()((set, get) => {; import { nowServerMs } from "./time";; interface SessionMessages {; interface StorageState {
  - expo-app/sources/sync/sessionListViewData.test.ts: +113/-0 | adds const active, const activeAt, const createdAt, const data, const machineA, const machineB | touches @@ -0,0 +1,113 @@
  - expo-app/sources/components/SessionsList.tsx: +10/-6 | adds const SessionItem, const isFirst, const isLast | removes const SessionItem, const isFirst, const isLast | touches const SessionItem = React.memo(({ session, selected, isFirst, isLast, isSingle }; export function SessionsList() {
  - expo-app/sources/app/(app)/settings/features.tsx: +8/-0 | touches export default React.memo(function FeaturesSettingsScreen() {
  - expo-app/sources/sync/settings.ts: +3/-0 | touches export const SettingsSchema = z.object({; export const settingsDefaults: Settings = {; import { pruneSecretBindings } from './secretBindings';
  - expo-app/sources/text/translations/zh-Hans.ts: +2/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +2/-0 | touches export const ru: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(sessions): group inactive sessions by project`

### Topic Bucket

- `sessions`

### Notes / Follow-ups


---

## 071 2026-01-21 62a8b1b07c3e

- SHA: 62a8b1b07c3e66627718735d2737d2435e1fd22f
- Subject: feat(sessions): add unread badge
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 9
- Lines: +199 / -39
- Touched areas: expo-app(9)
- Topic bucket: `sessions`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/components/ActiveSessionsGroup.tsx
M	expo-app/sources/components/ActiveSessionsGroupCompact.tsx
M	expo-app/sources/components/Avatar.tsx
M	expo-app/sources/components/SessionsList.tsx
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/storage.ts
A	expo-app/sources/sync/unread.test.ts
A	expo-app/sources/sync/unread.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx          |  4 ++
 .../sources/components/ActiveSessionsGroup.tsx     | 11 ++-
 .../components/ActiveSessionsGroupCompact.tsx      | 15 +++-
 expo-app/sources/components/Avatar.tsx             | 84 +++++++++++++---------
 expo-app/sources/components/SessionsList.tsx       | 11 ++-
 expo-app/sources/sync/persistence.ts               | 28 ++++++++
 expo-app/sources/sync/storage.ts                   | 28 +++++++-
 expo-app/sources/sync/unread.test.ts               | 41 +++++++++++
 expo-app/sources/sync/unread.ts                    | 16 +++++
 9 files changed, 199 insertions(+), 39 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(sessions): add unread badge
- Key files by churn (top 8):
  - expo-app/sources/components/Avatar.tsx: +52/-32 | adds const showFlavorOverlay, const unreadBadgeElement, const unreadBadgeSize | touches const styles = StyleSheet.create((theme) => ({; export const Avatar = React.memo((props: AvatarProps) => {; interface AvatarProps {
  - expo-app/sources/sync/unread.test.ts: +41/-0 | touches @@ -0,0 +1,41 @@
  - expo-app/sources/sync/storage.ts: +27/-1 | adds const lastViewedAt, const messages, const now, function useHasUnreadMessages | touches export const storage = create<StorageState>()((set, get) => {; export function useSessionMessages(sessionId: string): { messages: Message[], is; import type { PermissionMode } from '@/sync/permissionTypes';; import { buildSessionListViewData, type SessionListViewItem } from './sessionLis
  - expo-app/sources/sync/persistence.ts: +28/-0 | adds const raw, function loadSessionLastViewed, function saveSessionLastViewed | touches export function saveSessionPermissionModeUpdatedAts(updatedAts: Record<string, n
  - expo-app/sources/sync/unread.ts: +16/-0 | adds const first, const last, const latestCreatedAt, function hasUnreadMessages | touches @@ -0,0 +1,16 @@
  - expo-app/sources/components/ActiveSessionsGroupCompact.tsx: +13/-2 | adds const ProjectHeaderAvatar, const hasUnreadMessages | touches export function ActiveSessionsGroupCompact({ sessions, selectedSessionId }: Acti; import { StatusDot } from './StatusDot';
  - expo-app/sources/components/SessionsList.tsx: +9/-2 | adds const hasUnreadMessages | touches const SessionItem = React.memo(({ session, selected, isFirst, isLast, isSingle,; import { usePathname } from 'expo-router';
  - expo-app/sources/components/ActiveSessionsGroup.tsx: +9/-2 | adds const hasUnreadMessages | touches const CompactSessionRow = React.memo(({ session, selected, showBorder }: { sessi; import { StatusDot } from './StatusDot';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(sessions): add unread badge`

### Topic Bucket

- `sessions`

### Notes / Follow-ups


---

## 072 2026-01-21 82d74454c3c4

- SHA: 82d74454c3c4407c2ec5b531adaa3910d159aa73
- Subject: fix(typecheck): restore permission imports and Popover web styles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +2 / -2
- Touched areas: expo-app(3)
- Topic bucket: `typecheck`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/storage.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx | 2 +-
 expo-app/sources/sync/ops.ts              | 1 -
 expo-app/sources/sync/storage.ts          | 1 +
 3 files changed, 2 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(typecheck): restore permission imports and Popover web styles
- Key files by churn (top 3):
  - expo-app/sources/-session/SessionView.tsx: +1/-1 | touches import { isVersionSupported, MINIMUM_CLI_VERSION } from '@/utils/versionUtils';
  - expo-app/sources/sync/storage.ts: +1/-0 | touches import { UserProfile, RelationshipUpdatedEvent } from "./friendTypes";
  - expo-app/sources/sync/ops.ts: +0/-1 | touches export type {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(typecheck): restore permission imports and Popover web styles`

### Topic Bucket

- `typecheck`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 073 2026-01-11 4f2b533f99c2

- SHA: 4f2b533f99c2505bd9960ade61760f7bab833652
- Subject: feat(tools): add approve/reject buttons to ExitPlanMode
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 10
- Lines: +249 / -13
- Touched areas: expo-app(10)
- Topic bucket: `tools`
- Manual review needed: no

### Commit Message Body

```text
Add interactive UI for plan approval in ExitPlanToolView:
- Approve button sends approval message and proceeds with implementation
- Reject button sends rejection message and asks for plan revision
- Shows 'Response sent' state after user responds
- Buttons disabled while processing to prevent double-submission

Changes:
- Rewrite ExitPlanToolView with interactive approve/reject buttons
- Add loading states and disabled styles for buttons
- Add translation strings for button labels and messages
- Use sessionDeny + sendMessage pattern (same as AskUserQuestion)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/views/ExitPlanToolView.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 .../components/tools/views/ExitPlanToolView.tsx    | 187 ++++++++++++++++++++-
 expo-app/sources/text/translations/ca.ts           |   9 +-
 expo-app/sources/text/translations/en.ts           |   7 +
 expo-app/sources/text/translations/es.ts           |   9 +-
 expo-app/sources/text/translations/it.ts           |   7 +
 expo-app/sources/text/translations/ja.ts           |   7 +
 expo-app/sources/text/translations/pl.ts           |   9 +-
 expo-app/sources/text/translations/pt.ts           |   9 +-
 expo-app/sources/text/translations/ru.ts           |   9 +-
 expo-app/sources/text/translations/zh-Hans.ts      |   9 +-
 10 files changed, 249 insertions(+), 13 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(tools): add approve/reject buttons to ExitPlanMode
- Key files by churn (top 8):
  - expo-app/sources/components/tools/views/ExitPlanToolView.tsx: +180/-7 | adds const ExitPlanToolView, const canInteract, const handleApprove, const handleReject, const isRunning, const styles | removes const ExitPlanToolView | touches export const ExitPlanToolView = React.memo<ToolViewProps>(({ tool }) => {; import * as React from 'react';; import { View } from 'react-native';; import { knownTools } from '../../tools/knownTools';
  - expo-app/sources/text/translations/zh-Hans.ts: +8/-1 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +8/-1 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +8/-1 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +8/-1 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +8/-1 | touches export const es: TranslationStructure = {
  - expo-app/sources/text/translations/ca.ts: +8/-1 | touches export const ca: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +7/-0 | touches export const ja: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(tools): add approve/reject buttons to ExitPlanMode`

### Topic Bucket

- `tools`

### Notes / Follow-ups


---

## 074 2026-01-07 c86cbd26b040

- SHA: c86cbd26b04087d45570bbb9109735c0d58e7db2
- Subject: feat(queue): add pending message queue UI and send modes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 12
- Lines: +703 / -59
- Touched areas: expo-app(12)
- Topic bucket: `queue`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
A	expo-app/sources/app/(app)/settings/message-sending.tsx
M	expo-app/sources/components/MessageView.tsx
A	expo-app/sources/components/PendingMessagesModal.tsx
A	expo-app/sources/components/PendingQueueIndicator.tsx
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/sync/apiTypes.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx          | 112 ++++++-----
 .../sources/app/(app)/settings/message-sending.tsx |  56 ++++++
 expo-app/sources/components/MessageView.tsx        |  16 +-
 .../sources/components/PendingMessagesModal.tsx    | 176 +++++++++++++++++
 .../sources/components/PendingQueueIndicator.tsx   |  51 +++++
 expo-app/sources/components/SettingsView.tsx       |   6 +
 expo-app/sources/sync/apiTypes.ts                  |   9 +-
 expo-app/sources/sync/settings.spec.ts             |   9 +-
 expo-app/sources/sync/settings.ts                  |   2 +
 expo-app/sources/sync/storage.ts                   | 106 ++++++++++-
 expo-app/sources/sync/storageTypes.ts              |  11 ++
 expo-app/sources/sync/sync.ts                      | 208 ++++++++++++++++++++-
 12 files changed, 703 insertions(+), 59 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(queue): add pending message queue UI and send modes
- Key files by churn (top 8):
  - expo-app/sources/sync/sync.ts: +206/-2 | adds const ack, const encryptedRawRecord, const encryption, const existing, const hasPendingCount, const localId | touches class Sync {; import type { ApiEphemeralActivityUpdate } from './apiTypes';
  - expo-app/sources/components/PendingMessagesModal.tsx: +176/-0 | adds const confirmed, const handleEdit, const handleRemove, const handleSendNow, const next, function ActionButton | touches @@ -0,0 +1,176 @@
  - expo-app/sources/-session/SessionView.tsx: +67/-45 | adds const text | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import { AgentInput } from '@/components/AgentInput';; import { sessionAbort } from '@/sync/ops';
  - expo-app/sources/sync/storage.ts: +103/-3 | adds const existing, const filtered, const idx, const localIdsToClear, const next, const pending | touches export const storage = create<StorageState>()((set, get) => {; export function useHasUnreadMessages(sessionId: string): boolean {; import { useShallow } from 'zustand/react/shallow'; interface SessionMessages {
  - expo-app/sources/app/(app)/settings/message-sending.tsx: +56/-0 | adds type MessageSendMode | touches @@ -0,0 +1,56 @@
  - expo-app/sources/components/PendingQueueIndicator.tsx: +51/-0 | adds const PendingQueueIndicator | touches @@ -0,0 +1,51 @@
  - expo-app/sources/components/MessageView.tsx: +14/-2 | touches function AgentTextBlock(props: {; function UserTextBlock(props: {
  - expo-app/sources/sync/storageTypes.ts: +11/-0 | adds interface PendingMessage | touches export interface Session {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(queue): add pending message queue UI and send modes`

### Topic Bucket

- `queue`

### Notes / Follow-ups


---

## 075 2026-01-07 42da6dae8fe4

- SHA: 42da6dae8fe47c5ecfa6678df38c7c6146e15248
- Subject: feat(session): add session rename support
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 11
- Lines: +192 / -6
- Touched areas: expo-app(11)
- Topic bucket: `session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/session/[id]/info.tsx | 47 +++++++++++-
 expo-app/sources/sync/ops.ts                     | 98 ++++++++++++++++++++++++
 expo-app/sources/text/translations/ca.ts         |  7 +-
 expo-app/sources/text/translations/en.ts         |  5 ++
 expo-app/sources/text/translations/es.ts         |  7 +-
 expo-app/sources/text/translations/it.ts         |  5 ++
 expo-app/sources/text/translations/ja.ts         |  5 ++
 expo-app/sources/text/translations/pl.ts         |  5 ++
 expo-app/sources/text/translations/pt.ts         |  7 +-
 expo-app/sources/text/translations/ru.ts         |  5 ++
 expo-app/sources/text/translations/zh-Hans.ts    |  7 +-
 11 files changed, 192 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(session): add session rename support
- Key files by churn (top 8):
  - expo-app/sources/sync/ops.ts: +98/-0 | adds const currentSession, const encryptedMetadata, const result, const session, const sessionEncryption, const updatedMetadata | touches export async function sessionDelete(sessionId: string): Promise<{ success: boole; export type {
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +45/-2 | adds const handleRenameSession, const newName, const result | touches function SessionInfoContent({ session }: { session: Session }) {; import { Modal } from '@/modal';
  - expo-app/sources/text/translations/zh-Hans.ts: +6/-1 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +6/-1 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +6/-1 | touches export const es: TranslationStructure = {
  - expo-app/sources/text/translations/ca.ts: +6/-1 | touches export const ca: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +5/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +5/-0 | touches export const pl: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(session): add session rename support`

### Topic Bucket

- `session`

### Notes / Follow-ups


---

## 076 2026-01-12 057102f67904

- SHA: 057102f679041663a6194c89d20fb37ce8c69826
- Subject: feat(resume): add resume session option for new sessions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 17
- Lines: +479 / -13
- Touched areas: expo-app(17)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
- Add resume picker and pass vendor resume id when the selected agent supports resume

- Gate resume UI via agent capabilities for upstream friendliness (Claude only by default)

- Expose Codex session id in Session Info + translations
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
A	expo-app/sources/app/(app)/new/pick/resume.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/spawnSessionPayload.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
A	expo-app/sources/utils/agentCapabilities.ts
M	expo-app/sources/utils/tempDataStore.ts
```

### Diffstat

```text
 .../sources/app/(app)/new/NewSessionWizard.tsx     |   3 +
 expo-app/sources/app/(app)/new/index.tsx           |  86 +++++++-
 expo-app/sources/app/(app)/new/pick/resume.tsx     | 232 +++++++++++++++++++++
 expo-app/sources/sync/ops.ts                       |   1 -
 expo-app/sources/sync/persistence.ts               |   1 +
 expo-app/sources/sync/spawnSessionPayload.ts       |   6 +-
 expo-app/sources/text/translations/ca.ts           |  16 +-
 expo-app/sources/text/translations/en.ts           |  16 +-
 expo-app/sources/text/translations/es.ts           |  16 +-
 expo-app/sources/text/translations/it.ts           |  16 +-
 expo-app/sources/text/translations/ja.ts           |  16 +-
 expo-app/sources/text/translations/pl.ts           |  16 +-
 expo-app/sources/text/translations/pt.ts           |  16 +-
 expo-app/sources/text/translations/ru.ts           |  16 +-
 expo-app/sources/text/translations/zh-Hans.ts      |  16 +-
 expo-app/sources/utils/agentCapabilities.ts        |  18 ++
 expo-app/sources/utils/tempDataStore.ts            |   1 +
 17 files changed, 479 insertions(+), 13 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(resume): add resume session option for new sessions
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/new/pick/resume.tsx: +232/-0 | adds const agentLabel, const handleClear, const handlePaste, const handleSave, const navigation, const params | touches @@ -0,0 +1,232 @@
  - expo-app/sources/app/(app)/new/index.tsx: +85/-1 | adds const handleResumeClick, const renderResumePicker | touches function NewSessionScreen() {; import { resolveTerminalSpawnOptions } from '@/sync/terminalSettings';
  - expo-app/sources/utils/agentCapabilities.ts: +18/-0 | adds const RESUMABLE_AGENTS, function canAgentResume, type AgentType | touches @@ -0,0 +1,18 @@
  - expo-app/sources/text/translations/zh-Hans.ts: +15/-1 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +15/-1 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +15/-1 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +15/-1 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +15/-1 | touches export const ja: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(resume): add resume session option for new sessions`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 077 2026-01-14 05532bd65c6b

- SHA: 05532bd65c6b8de70bc6ca514f1d7aacc152ae78
- Subject: feat(resume): show resume chip under path in new session
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +57 / -44
- Touched areas: expo-app(3)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/components/AgentInput.tsx
```

### Diffstat

```text
 .../sources/app/(app)/new/NewSessionWizard.tsx     |  9 ++--
 expo-app/sources/app/(app)/new/index.tsx           | 48 ++++------------------
 expo-app/sources/components/AgentInput.tsx         | 44 ++++++++++++++++++++
 3 files changed, 57 insertions(+), 44 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(resume): show resume chip under path in new session
- Key files by churn (top 3):
  - expo-app/sources/app/(app)/new/index.tsx: +7/-41 | removes const renderResumePicker | touches function NewSessionScreen() {
  - expo-app/sources/components/AgentInput.tsx: +44/-0 | touches export const AgentInput = React.memo(React.forwardRef<MultiTextInputHandle, Agen; interface AgentInputProps {
  - expo-app/sources/app/(app)/new/NewSessionWizard.tsx: +6/-3 | touches export const NewSessionWizard = React.memo(function NewSessionWizard(props: NewS; export interface NewSessionWizardFooterProps {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(resume): show resume chip under path in new session`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 078 2026-01-11 cd5771e50881

- SHA: cd5771e5088145cee2ff4b72989182290384c348
- Subject: feat: resume inactive Claude sessions from UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +261 / -3
- Touched areas: expo-app(3)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
Add the ability to resume inactive Claude sessions directly from the UI.
When a session becomes inactive (agent disconnected), users can now type
a message and send it to resume the session instead of starting a new one.

Changes:
- Add RESUMABLE_AGENTS config for dynamic agent resume capability
- Add canResumeSession() helper to check if session supports resume
- Enable input field for inactive resumable sessions with status indicator
- Add resumeSession RPC operation to trigger resume via daemon
- Add translations for session resume states

The resume feature uses the existing Claude session ID stored in metadata
to reconnect to the same conversation, preserving message history.
```

### Files (name-status)

```text
A	expo-app/INACTIVE_SESSION_RESUME.md
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 expo-app/INACTIVE_SESSION_RESUME.md       | 133 ++++++++++++++++++++++++++++++
 expo-app/sources/-session/SessionView.tsx |  70 +++++++++++++++-
 expo-app/sources/sync/ops.ts              |  61 ++++++++++++++
 3 files changed, 261 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat: resume inactive Claude sessions from UI
- Key files by churn (top 3):
  - expo-app/INACTIVE_SESSION_RESUME.md: +133/-0 | touches @@ -0,0 +1,133 @@
  - expo-app/sources/-session/SessionView.tsx: +67/-3 | adds const agentSessionId, const handleResumeSession, const inactiveStatusText, const isResumable, const isSessionActive, const profileId | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import { gitStatusSync } from '@/sync/gitStatusSync';; import { storage, useIsDataReady, useLocalSetting, useRealtimeStatus, useSession
  - expo-app/sources/sync/ops.ts: +61/-0 | adds const result, function resumeSession, interface ResumeSessionOptions, type ResumeSessionResult | touches export async function machineSpawnNewSession(options: SpawnSessionOptions): Prom

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat: resume inactive Claude sessions from UI`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 079 2026-01-12 456e2ad8e2b8

- SHA: 456e2ad8e2b80efcc7eb05ca71dedf313e4230b8
- Subject: refactor(resume): don't require agentSessionId from UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 12
- Lines: +84 / -11
- Touched areas: expo-app(12)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
- UI now resumes inactive sessions by Happy session id; machine/daemon derives vendor resume id from local persisted session state

- Keeps send disabled for inactive sessions that aren't resumable
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
M	expo-app/sources/utils/agentCapabilities.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx     |  4 +--
 expo-app/sources/sync/ops.ts                  |  6 +---
 expo-app/sources/text/translations/ca.ts      |  4 +++
 expo-app/sources/text/translations/en.ts      |  4 +++
 expo-app/sources/text/translations/es.ts      |  4 +++
 expo-app/sources/text/translations/it.ts      |  4 +++
 expo-app/sources/text/translations/ja.ts      |  4 +++
 expo-app/sources/text/translations/pl.ts      |  4 +++
 expo-app/sources/text/translations/pt.ts      |  4 +++
 expo-app/sources/text/translations/ru.ts      |  4 +++
 expo-app/sources/text/translations/zh-Hans.ts |  4 +++
 expo-app/sources/utils/agentCapabilities.ts   | 49 +++++++++++++++++++++++++--
 12 files changed, 84 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(resume): don't require agentSessionId from UI
- Key files by churn (top 8):
  - expo-app/sources/utils/agentCapabilities.ts: +46/-3 | adds const agent, const agentSessionId, const field, function canAgentResume, function canResumeSession, function getAgentSessionId | removes function canAgentResume | touches export const RESUMABLE_AGENTS: AgentType[] = ['claude'];
  - expo-app/sources/sync/ops.ts: +1/-5 | touches export async function resumeSession(options: ResumeSessionOptions): Promise<Resu; export interface ResumeSessionOptions {
  - expo-app/sources/text/translations/zh-Hans.ts: +4/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +4/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +4/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +4/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +4/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +4/-0 | touches export const it: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(resume): don't require agentSessionId from UI`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 080 2026-01-11 9b0069e3d30c

- SHA: 9b0069e3d30ca504df810d81cf2779398168cc0d
- Subject: feat(fork): enable Codex resume support
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 12
- Lines: +52 / -29
- Touched areas: expo-app(12)
- Topic bucket: `fork`
- Manual review needed: no

### Commit Message Body

```text
Enable 'codex' in RESUMABLE_AGENTS for fork builds.
This allows resuming Codex sessions from the UI.
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
M	expo-app/sources/utils/agentCapabilities.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/session/[id]/info.tsx | 66 ++++++++++++++----------
 expo-app/sources/sync/storageTypes.ts            |  1 +
 expo-app/sources/text/translations/ca.ts         |  1 +
 expo-app/sources/text/translations/en.ts         |  1 +
 expo-app/sources/text/translations/es.ts         |  1 +
 expo-app/sources/text/translations/it.ts         |  1 +
 expo-app/sources/text/translations/ja.ts         |  1 +
 expo-app/sources/text/translations/pl.ts         |  1 +
 expo-app/sources/text/translations/pt.ts         |  1 +
 expo-app/sources/text/translations/ru.ts         |  1 +
 expo-app/sources/text/translations/zh-Hans.ts    |  1 +
 expo-app/sources/utils/agentCapabilities.ts      |  5 +-
 12 files changed, 52 insertions(+), 29 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(fork): enable Codex resume support
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +38/-28 | adds const handleCopyCommand, const handleCopyUpdateCommand, const updateCommand | removes const handleCopyUpdateCommand, const updateCommand | touches function SessionInfoContent({ session }: { session: Session }) {
  - expo-app/sources/utils/agentCapabilities.ts: +4/-1 | adds const RESUMABLE_AGENTS | removes const RESUMABLE_AGENTS | touches export type AgentType = 'claude' | 'codex' | 'gemini';
  - expo-app/sources/text/translations/zh-Hans.ts: +1/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +1/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +1/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +1/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +1/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +1/-0 | touches export const it: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(fork): enable Codex resume support`

### Topic Bucket

- `fork`

### Notes / Follow-ups


---

## 081 2026-01-22 4ddaef02210e

- SHA: 4ddaef02210e47ed7fd8ea4cf287611d2ea6f450
- Subject: fix(sync): omit model meta for queued messages
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +7 / -6
- Touched areas: expo-app(1)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 expo-app/sources/sync/sync.ts | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): omit model meta for queued messages
- Key files by churn (top 1):
  - expo-app/sources/sync/sync.ts: +7/-6 | adds const flavor, const isGemini, const model, const modelMode | touches class Sync {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): omit model meta for queued messages`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 082 2026-01-12 3fbdc10018fe

- SHA: 3fbdc10018fe62b67ddc05dc62ebf9ba7466f90f
- Subject: fix: tmux parsing/targeting + review feedback
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 15
- Lines: +153 / -127
- Touched areas: cli(15)
- Topic bucket: `terminal`
- Manual review needed: no

### Commit Message Body

```text
Validation:

- Verified TMUX/TMUX_PANE values inside an isolated tmux server (custom socket)

- Verified kill-window syntax and new-session -t semantics via tmux manpage

Changes:

- Correct TMUX env parsing (socket_path + server_pid) and prefer TMUX_PANE for pane id

- Avoid invalid -t injection for commands that already specify a target; do not treat new-session as targetable

- Fix kill-window invocation to use -t session:window

- Align Machine.metadata typing with runtime (nullable)

- Make socket send behavior consistent when disconnected; tighten misc scripts/tests
```

### Files (name-status)

```text
M	cli/bin/happy-dev.mjs
M	cli/docs/bug-fix-plan-2025-01-15-athundt.md
M	cli/scripts/__tests__/ripgrep_launcher.test.ts
M	cli/scripts/claude_version_utils.cjs
M	cli/scripts/claude_version_utils.test.ts
M	cli/scripts/env-wrapper.cjs
M	cli/scripts/ripgrep_launcher.cjs
M	cli/scripts/test-continue-fix.sh
M	cli/src/api/api.test.ts
M	cli/src/api/apiSession.ts
M	cli/src/api/types.ts
M	cli/src/claude/claudeLocal.ts
M	cli/src/claude/runClaude.ts
M	cli/src/utils/tmux.test.ts
M	cli/src/utils/tmux.ts
```

### Diffstat

```text
 cli/bin/happy-dev.mjs                          | 12 ++---
 cli/docs/bug-fix-plan-2025-01-15-athundt.md    |  1 -
 cli/scripts/__tests__/ripgrep_launcher.test.ts | 42 ++++++++-------
 cli/scripts/claude_version_utils.cjs           |  4 +-
 cli/scripts/claude_version_utils.test.ts       |  4 +-
 cli/scripts/env-wrapper.cjs                    |  9 ++++
 cli/scripts/ripgrep_launcher.cjs               | 13 +++--
 cli/scripts/test-continue-fix.sh               |  7 ++-
 cli/src/api/api.test.ts                        |  3 +-
 cli/src/api/apiSession.ts                      | 26 ++++++---
 cli/src/api/types.ts                           |  2 +-
 cli/src/claude/claudeLocal.ts                  |  3 +-
 cli/src/claude/runClaude.ts                    |  9 +++-
 cli/src/utils/tmux.test.ts                     | 72 +++++++++++++------------
 cli/src/utils/tmux.ts                          | 73 ++++++++++----------------
 15 files changed, 153 insertions(+), 127 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix: tmux parsing/targeting + review feedback
- Key files by churn (top 8):
  - cli/src/utils/tmux.ts: +29/-44 | adds const hasExplicitTarget, const pane, const result, const serverPidStr, const socketPath | removes const pane, const parts, const pathParts, const result | touches const COMMANDS_SUPPORTING_TARGET = new Set([; export class TmuxUtilities {; export interface TmuxEnvironment {; export interface TmuxSessionInfo {
  - cli/src/utils/tmux.test.ts: +37/-35 | adds const originalTmuxPaneEnv, const result, const utils, const withTmuxEnv | removes const withTmuxEnv | touches describe('TmuxUtilities.detectTmuxEnvironment', () => {
  - cli/scripts/__tests__/ripgrep_launcher.test.ts: +23/-19 | adds const content, function readLauncherFile | removes const content, const fs, const path | touches @@ -0,0 +1,2 @@; describe('Ripgrep Launcher Runtime Compatibility', () => {; import { describe, it, expect, vi, beforeEach } from 'vitest';
  - cli/src/api/apiSession.ts: +18/-8 | touches export class ApiSessionClient extends EventEmitter {
  - cli/scripts/ripgrep_launcher.cjs: +10/-3 | touches function createRipgrepWrapper(binaryPath) {; function findSystemRipgrep() {; try {
  - cli/bin/happy-dev.mjs: +4/-8 | touches const hasNoDeprecation = process.execArgv.includes('--no-deprecation');; if (!hasNoWarnings || !hasNoDeprecation) {
  - cli/src/claude/runClaude.ts: +8/-1 | adds const abortController, const abortOnSignal | touches export async function runClaude(credentials: Credentials, options: StartOptions
  - cli/scripts/env-wrapper.cjs: +9/-0 | touches if (!variant || !VARIANTS[variant]) {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix: tmux parsing/targeting + review feedback`

### Topic Bucket

- `terminal`

### Notes / Follow-ups


---

## 083 2026-01-13 7292a29822bb

- SHA: 7292a29822bbd81cb10c292559a8f63bbc8ea73c
- Subject: fix(daemon): do not apply CLI active profile to GUI-spawned sessions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +5 / -54
- Touched areas: cli(1)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/daemon/run.ts
```

### Diffstat

```text
 cli/src/daemon/run.ts | 59 +++++----------------------------------------------
 1 file changed, 5 insertions(+), 54 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(daemon): do not apply CLI active profile to GUI-spawned sessions
- Key files by churn (top 1):
  - cli/src/daemon/run.ts: +5/-54 | removes const envVars, const profile, const settings, function getProfileEnvironmentVariablesForAgent | touches export async function startDaemon(): Promise<void> {; export const initialMachineMetadata: MachineMetadata = {; import { spawnHappyCLI } from '@/utils/spawnHappyCLI';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(daemon): do not apply CLI active profile to GUI-spawned sessions`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 084 2026-01-13 ce94cfa512ac

- SHA: ce94cfa512ac7be97c3e8802ffebcc804e7489b3
- Subject: feat(session): persist profileId in session metadata via daemon spawn
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +33 / -5
- Touched areas: cli(6)
- Topic bucket: `session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/api/types.ts
M	cli/src/claude/runClaude.ts
M	cli/src/daemon/run.ts
M	cli/src/modules/common/registerCommonHandlers.ts
M	cli/src/utils/createSessionMetadata.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts                        |  4 ++--
 cli/src/api/types.ts                             |  6 ++++++
 cli/src/claude/runClaude.ts                      |  3 ++-
 cli/src/daemon/run.ts                            | 11 +++++++++--
 cli/src/modules/common/registerCommonHandlers.ts |  8 ++++++++
 cli/src/utils/createSessionMetadata.ts           |  6 ++++++
 6 files changed, 33 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(session): persist profileId in session metadata via daemon spawn
- Key files by churn (top 6):
  - cli/src/daemon/run.ts: +9/-2 | touches export async function startDaemon(): Promise<void> {
  - cli/src/modules/common/registerCommonHandlers.ts: +8/-0 | touches export interface SpawnSessionOptions {
  - cli/src/utils/createSessionMetadata.ts: +6/-0 | adds const profileId, const profileIdEnv | touches export function createSessionMetadata(opts: CreateSessionMetadataOptions): Sessi
  - cli/src/api/types.ts: +6/-0 | touches export type Metadata = {
  - cli/src/api/apiMachine.ts: +2/-2 | adds const result | removes const result | touches export class ApiMachineClient {
  - cli/src/claude/runClaude.ts: +2/-1 | touches export async function runClaude(credentials: Credentials, options: StartOptions

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(session): persist profileId in session metadata via daemon spawn`

### Topic Bucket

- `session`

### Notes / Follow-ups


---

## 085 2026-01-13 e58e97fd7ff4

- SHA: e58e97fd7ff4eac9f60ec55224c90fde52ceb2d1
- Subject: fix(pr107): harden daemon spawn + align profile schema
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +38 / -11
- Touched areas: cli(3)
- Topic bucket: `pr107`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/daemon/run.ts
M	cli/src/persistence.ts
M	cli/src/utils/expandEnvVars.ts
```

### Diffstat

```text
 cli/src/daemon/run.ts          |  2 +-
 cli/src/persistence.ts         | 33 +++++++++++++++++++++++++++++----
 cli/src/utils/expandEnvVars.ts | 14 ++++++++------
 3 files changed, 38 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(pr107): harden daemon spawn + align profile schema
- Key files by churn (top 3):
  - cli/src/persistence.ts: +29/-4 | adds const URL_OR_TEMPLATE_ERROR, const URL_OR_TEMPLATE_REGEX, function isUrlOrTemplateString, function urlOrTemplateStringOptional | touches const AnthropicConfigSchema = z.object({; const AzureOpenAIConfigSchema = z.object({; const OpenAIConfigSchema = z.object({; export const AIBackendProfileSchema = z.object({
  - cli/src/utils/expandEnvVars.ts: +8/-6 | adds const colonEqIndex, const idx | touches export function expandEnvironmentVariables(
  - cli/src/daemon/run.ts: +1/-1 | touches export async function startDaemon(): Promise<void> {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(pr107): harden daemon spawn + align profile schema`

### Topic Bucket

- `pr107`

### Notes / Follow-ups


---

## 086 2026-01-13 86330e263595

- SHA: 86330e2635957cd9863f3142399b1adba9522949
- Subject: fix(security): redact spawn secrets from daemon logs
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +30 / -3
- Touched areas: cli(2)
- Topic bucket: `security`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/daemon/run.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts | 15 ++++++++++++++-
 cli/src/daemon/run.ts     | 18 ++++++++++++++++--
 2 files changed, 30 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(security): redact spawn secrets from daemon logs
- Key files by churn (top 2):
  - cli/src/daemon/run.ts: +16/-2 | adds const envKeys | touches export async function startDaemon(): Promise<void> {
  - cli/src/api/apiMachine.ts: +14/-1 | adds const envKeys | touches export class ApiMachineClient {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(security): redact spawn secrets from daemon logs`

### Topic Bucket

- `security`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 087 2026-01-15 a25acab22b64

- SHA: a25acab22b64372e47a7d2a22276d8fd4dad9c96
- Subject: fix(socket): restore offline buffering for sends
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +39 / -31
- Touched areas: cli(3)
- Topic bucket: `socket`
- Manual review needed: no

### Commit Message Body

```text
Remove the hard send guard that dropped messages while disconnected and rely on socket.io client buffering (tests updated).
```

### Files (name-status)

```text
M	cli/src/api/apiSession.test.ts
M	cli/src/api/apiSession.ts
M	cli/src/claude/runClaude.ts
```

### Diffstat

```text
 cli/src/api/apiSession.test.ts | 27 +++++++++++++++++++++++++--
 cli/src/api/apiSession.ts      | 33 +++++++++------------------------
 cli/src/claude/runClaude.ts    | 10 +++++-----
 3 files changed, 39 insertions(+), 31 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(socket): restore offline buffering for sends
- Key files by churn (top 3):
  - cli/src/api/apiSession.ts: +9/-24 | adds const encrypted | removes const encrypted | touches export class ApiSessionClient extends EventEmitter {
  - cli/src/api/apiSession.test.ts: +25/-2 | adds const client | touches describe('ApiSessionClient connection handling', () => {
  - cli/src/claude/runClaude.ts: +5/-5 | adds const abortController, const abortOnSignal | removes const abortController, const abortOnSignal | touches export async function runClaude(credentials: Credentials, options: StartOptions

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(socket): restore offline buffering for sends`

### Topic Bucket

- `socket`

### Notes / Follow-ups


---

## 088 2026-01-15 a7d23148c311

- SHA: a7d23148c3117d21f5b15a045f71d5da8757f49d
- Subject: fix(logging): gate debug output and redact templates
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +170 / -17
- Touched areas: cli(6)
- Topic bucket: `logging`
- Manual review needed: no

### Commit Message Body

```text
Make debugLargeJson a true DEBUG-only path and avoid logging expanded env values/defaults; tighten doctor masking for default templates.
```

### Files (name-status)

```text
A	cli/src/ui/doctor.test.ts
M	cli/src/ui/doctor.ts
A	cli/src/ui/logger.test.ts
M	cli/src/ui/logger.ts
M	cli/src/utils/expandEnvVars.test.ts
M	cli/src/utils/expandEnvVars.ts
```

### Diffstat

```text
 cli/src/ui/doctor.test.ts           | 13 +++++++++
 cli/src/ui/doctor.ts                | 54 +++++++++++++++++++++++++++++++++++--
 cli/src/ui/logger.test.ts           | 40 +++++++++++++++++++++++++++
 cli/src/ui/logger.ts                |  4 +--
 cli/src/utils/expandEnvVars.test.ts | 52 +++++++++++++++++++++++++++++++++++
 cli/src/utils/expandEnvVars.ts      | 24 ++++++++---------
 6 files changed, 170 insertions(+), 17 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(logging): gate debug output and redact templates
- Key files by churn (top 6):
  - cli/src/ui/doctor.ts: +52/-2 | adds const matchWithFallback, const p, const redacted, const redactedRecord, function maskValue, function redactSettingsForDisplay | touches export async function runDoctorCommand(filter?: 'all' | 'daemon'): Promise<void>; import packageJson from '../../package.json'
  - cli/src/utils/expandEnvVars.test.ts: +52/-0 | adds const envVars, const result, const sourceEnv | touches describe('expandEnvironmentVariables', () => {
  - cli/src/ui/logger.test.ts: +40/-0 | adds const actual, const originalDebug | touches @@ -0,0 +1,40 @@
  - cli/src/utils/expandEnvVars.ts: +12/-12 | adds const isMissing, const shouldTreatEmptyAsMissing | removes const displayValue, const isSensitive | touches export function expandEnvironmentVariables(; import { logger } from '@/ui/logger';
  - cli/src/ui/doctor.test.ts: +13/-0 | adds const doctorModule, const maskValue | touches @@ -0,0 +1,13 @@
  - cli/src/ui/logger.ts: +1/-3 | touches class Logger {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(logging): gate debug output and redact templates`

### Topic Bucket

- `logging`

### Notes / Follow-ups


---

## 089 2026-01-13 ef418bc4dda3

- SHA: ef418bc4dda3b67874a498a56ad0576fd8ca0ac9
- Subject: fix(pr107): redact profile secrets in doctor + align tmux tmpDir
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +12 / -8
- Touched areas: cli(2)
- Topic bucket: `pr107`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/persistence.ts
M	cli/src/ui/doctor.test.ts
```

### Diffstat

```text
 cli/src/persistence.ts    |  3 ++-
 cli/src/ui/doctor.test.ts | 17 ++++++++++-------
 2 files changed, 12 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(pr107): redact profile secrets in doctor + align tmux tmpDir
- Key files by churn (top 2):
  - cli/src/ui/doctor.test.ts: +10/-7 | removes const doctorModule, const maskValue | touches describe('doctor redaction', () => {; import { describe, it, expect } from 'vitest';
  - cli/src/persistence.ts: +2/-1 | touches export function getProfileEnvironmentVariables(profile: AIBackendProfile): Recor

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(pr107): redact profile secrets in doctor + align tmux tmpDir`

### Topic Bucket

- `pr107`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 090 2026-01-13 1f90659694be

- SHA: 1f90659694beaec4a990e7a02c6d628fb3721d08
- Subject: refactor(profiles): remove unwired startup script and local env cache
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +9 / -74
- Touched areas: cli(1)
- Topic bucket: `profiles`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/persistence.ts | 83 ++++++--------------------------------------------
 1 file changed, 9 insertions(+), 74 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(profiles): remove unwired startup script and local env cache
- Key files by churn (top 1):
  - cli/src/persistence.ts: +9/-74 | adds const SUPPORTED_SCHEMA_VERSION | removes const SUPPORTED_SCHEMA_VERSION, const envVar, const localEnvVars, const profile | touches const defaultSettings: Settings = {; export async function updateProfiles(profiles: unknown[]): Promise<void> {; export const AIBackendProfileSchema = z.object({; export const CURRENT_PROFILE_VERSION = '1.0.0';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(profiles): remove unwired startup script and local env cache`

### Topic Bucket

- `profiles`

### Notes / Follow-ups


---

## 091 2026-01-15 7aed8aaee02f

- SHA: 7aed8aaee02f5f444d099a243389c35685a1b3bd
- Subject: refactor(profiles): drop provider config objects
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +124 / -75
- Touched areas: cli(2)
- Topic bucket: `profiles`
- Manual review needed: no

### Commit Message Body

```text
Align happy-cli profile schema with the app: profiles are env-var based only. Migrate any legacy provider config fields into environmentVariables during parsing to avoid data loss.
```

### Files (name-status)

```text
A	cli/src/persistence.profileSchema.test.ts
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/persistence.profileSchema.test.ts |  57 ++++++++++++
 cli/src/persistence.ts                    | 142 ++++++++++++++----------------
 2 files changed, 124 insertions(+), 75 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(profiles): drop provider config objects
- Key files by churn (top 2):
  - cli/src/persistence.ts: +67/-75 | adds const AIBackendProfileSchema, const anthropicConfig, const asRecord, const azureOpenAIConfig, const environmentVariables, const map | removes const AIBackendProfileSchema, const AnthropicConfigSchema, const AzureOpenAIConfigSchema, const OpenAIConfigSchema | touches const AnthropicConfigSchema = z.object({; const AzureOpenAIConfigSchema = z.object({; const OpenAIConfigSchema = z.object({; const ProfileCompatibilitySchema = z.object({
  - cli/src/persistence.profileSchema.test.ts: +57/-0 | adds const profile | touches @@ -0,0 +1,57 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(profiles): drop provider config objects`

### Topic Bucket

- `profiles`

### Notes / Follow-ups


---

## 092 2026-01-15 6b0bfe546d9e

- SHA: 6b0bfe546d9e8475696d7694f52d4d64cf65fbfc
- Subject: feat(runtime): support bun for daemon-spawned subprocesses
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +130 / -20
- Touched areas: cli(3)
- Topic bucket: `runtime`
- Manual review needed: no

### Commit Message Body

```text
Add a single runtime invocation builder for node vs bun and allow overriding via HAPPY_CLI_SUBPROCESS_RUNTIME.
```

### Files (name-status)

```text
A	cli/src/utils/spawnHappyCLI.invocation.test.ts
A	cli/src/utils/spawnHappyCLI.test.ts
M	cli/src/utils/spawnHappyCLI.ts
```

### Diffstat

```text
 cli/src/utils/spawnHappyCLI.invocation.test.ts | 42 +++++++++++++++++++
 cli/src/utils/spawnHappyCLI.test.ts            | 56 ++++++++++++++++++++++++++
 cli/src/utils/spawnHappyCLI.ts                 | 52 +++++++++++++++---------
 3 files changed, 130 insertions(+), 20 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(runtime): support bun for daemon-spawned subprocesses
- Key files by churn (top 3):
  - cli/src/utils/spawnHappyCLI.test.ts: +56/-0 | adds const argv, const originalRuntimeOverride | touches @@ -0,0 +1,56 @@
  - cli/src/utils/spawnHappyCLI.ts: +32/-20 | adds const argv, const entrypoint, const errorMessage, const nodeArgs, const override, const projectRoot | removes const entrypoint, const errorMessage, const nodeArgs, const projectRoot | touches export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child; import { isBun } from './runtime';
  - cli/src/utils/spawnHappyCLI.invocation.test.ts: +42/-0 | adds const inv, const mod, const originalRuntimeOverride | touches @@ -0,0 +1,42 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(runtime): support bun for daemon-spawned subprocesses`

### Topic Bucket

- `runtime`

### Notes / Follow-ups


---

## 093 2026-01-15 4071466545ab

- SHA: 4071466545ab1eaffba8cb6ebd55a85ef2732370
- Subject: refactor(rpc): accept arbitrary env var maps for spawn
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +12 / -14
- Touched areas: cli(1)
- Topic bucket: `rpc`
- Manual review needed: no

### Commit Message Body

```text
The GUI sends a profile-derived env var map that may include provider-specific keys and tmux knobs; type it as Record<string,string>.
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 26 +++++++++++-------------
 1 file changed, 12 insertions(+), 14 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(rpc): accept arbitrary env var maps for spawn
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.ts: +12/-14 | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; export interface SpawnSessionOptions {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(rpc): accept arbitrary env var maps for spawn`

### Topic Bucket

- `rpc`

### Notes / Follow-ups


---

## 094 2026-01-17 809be82b53e7

- SHA: 809be82b53e786a3146fa818c03f0a88c1e24a76
- Subject: fix(env): implement default assignment semantics
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +36 / -5
- Touched areas: cli(2)
- Topic bucket: `env`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/utils/expandEnvVars.test.ts
M	cli/src/utils/expandEnvVars.ts
```

### Diffstat

```text
 cli/src/utils/expandEnvVars.test.ts | 12 ++++++++++++
 cli/src/utils/expandEnvVars.ts      | 29 ++++++++++++++++++++++++-----
 2 files changed, 36 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(env): implement default assignment semantics
- Key files by churn (top 2):
  - cli/src/utils/expandEnvVars.ts: +24/-5 | adds const idx, const resolvedValue, const warnOnUndefined, function readEnv | removes const idx, const resolvedValue | touches export function expandEnvironmentVariables(
  - cli/src/utils/expandEnvVars.test.ts: +12/-0 | adds const envVars, const result, const sourceEnv | touches describe('expandEnvironmentVariables', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(env): implement default assignment semantics`

### Topic Bucket

- `env`

### Notes / Follow-ups


---

## 095 2026-01-17 4c2a671dc3f4

- SHA: 4c2a671dc3f4409d572e9aef2c0c4340ddd5d097
- Subject: feat(rpc): add preview-env handler
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +380 / -0
- Touched areas: cli(2)
- Topic bucket: `rpc`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 .../registerCommonHandlers.previewEnv.test.ts      | 186 ++++++++++++++++++++
 cli/src/modules/common/registerCommonHandlers.ts   | 194 +++++++++++++++++++++
 2 files changed, 380 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(rpc): add preview-env handler
- Key files by churn (top 2):
  - cli/src/modules/common/registerCommonHandlers.ts: +194/-0 | adds const defaultSecretNameRegex, const endRaw, const expandedExtraEnv, const extraEnvRaw, const hintedSensitive, const isForcedSensitive | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; import { run as runDifftastic } from '@/modules/difftastic/index';; interface BashResponse {
  - cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts: +186/-0 | adds const decrypted, const encryptedParams, const encryptedResponse, const encryptionKey, const encryptionVariant, const manager | touches @@ -0,0 +1,186 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(rpc): add preview-env handler`

### Topic Bucket

- `rpc`

### Notes / Follow-ups


---

## 096 2026-01-15 2973f7fe6861

- SHA: 2973f7fe6861bf8623f0163aa99a2d73cfab81ad
- Subject: fix(codex): harden MCP command detection
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +148 / -51
- Touched areas: cli(2)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Handle codex --version output variations without misreporting 'not installed' and remove stdout logging of elicitation payloads.
```

### Files (name-status)

```text
A	cli/src/codex/codexMcpClient.test.ts
M	cli/src/codex/codexMcpClient.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.test.ts |  93 ++++++++++++++++++++++++++++++
 cli/src/codex/codexMcpClient.ts      | 106 ++++++++++++++++++-----------------
 2 files changed, 148 insertions(+), 51 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): harden MCP command detection
- Key files by churn (top 2):
  - cli/src/codex/codexMcpClient.ts: +55/-51 | adds const getPermissionHandler, const match, const params, const permissionHandler, const result, const toolName | removes const match, const params, const result, const toolName | touches export class CodexMcpClient {; function getCodexMcpCommand(): string | null {
  - cli/src/codex/codexMcpClient.test.ts: +93/-0 | adds class Client, class StdioClientTransport, const __transportInstances, const client, const consoleSpy, const handler | touches @@ -0,0 +1,93 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): harden MCP command detection`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 097 2026-01-15 c863db3d5bbc

- SHA: c863db3d5bbcb5edc6353657f09049e30e457900
- Subject: refactor(offline): make offline session stub safer
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +78 / -20
- Touched areas: cli(2)
- Topic bucket: `offline`
- Manual review needed: no

### Commit Message Body

```text
Provide an EventEmitter-compatible stub and a focused unit test so offline mode can't crash on basic session events.
```

### Files (name-status)

```text
A	cli/src/utils/offlineSessionStub.test.ts
M	cli/src/utils/offlineSessionStub.ts
```

### Diffstat

```text
 cli/src/utils/offlineSessionStub.test.ts | 15 ++++++
 cli/src/utils/offlineSessionStub.ts      | 83 ++++++++++++++++++++++++--------
 2 files changed, 78 insertions(+), 20 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(offline): make offline session stub safer
- Key files by churn (top 2):
  - cli/src/utils/offlineSessionStub.ts: +63/-20 | adds class OfflineSessionStub, const stub, type ApiSessionClientStubContract | touches @@ -13 +13,59 @@; export function createOfflineSessionStub(sessionTag: string): ApiSessionClient {
  - cli/src/utils/offlineSessionStub.test.ts: +15/-0 | adds const handler, const session | touches @@ -0,0 +1,15 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(offline): make offline session stub safer`

### Topic Bucket

- `offline`

### Notes / Follow-ups


---

## 098 2026-01-15 0a1a91a631e7

- SHA: 0a1a91a631e77883e9c0b874674021c288bd0e57
- Subject: feat(tmux): support per-instance socket path
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +198 / -84
- Touched areas: cli(2)
- Topic bucket: `tmux`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/utils/tmux.socketPath.test.ts
M	cli/src/utils/tmux.ts
```

### Diffstat

```text
 cli/src/utils/tmux.socketPath.test.ts |  49 +++++++
 cli/src/utils/tmux.ts                 | 233 ++++++++++++++++++++++------------
 2 files changed, 198 insertions(+), 84 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(tmux): support per-instance socket path
- Key files by churn (top 2):
  - cli/src/utils/tmux.ts: +149/-84 | adds const _tmuxUtilsByKey, const attached, const candidates, const createResult, const createWindowArgs, const created | removes const createResult, const createWindowArgs, const escapedValue, const firstSession | touches export async function createTmuxSession(; export class TmuxUtilities {; export function buildTmuxSessionIdentifier(params: {; export function extractSessionAndWindow(tmuxOutput: string): { session: string;
  - cli/src/utils/tmux.socketPath.test.ts: +49/-0 | adds const call, const child, const spawnMock, const utils | touches @@ -0,0 +1,49 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(tmux): support per-instance socket path`

### Topic Bucket

- `tmux`

### Notes / Follow-ups


---

## 099 2026-01-15 c52227082c2b

- SHA: c52227082c2b1366dbc878db1000395a0f3159d3
- Subject: fix(tmux): correct env, tmpdir, and session selection
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 21
- Lines: +915 / -206
- Touched areas: cli(21)
- Topic bucket: `tmux`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
- Treat TMUX_TMPDIR as a directory via tmux client env (not -S socket path)

- Pass per-window env via new-window -e KEY=value without shell-style quoting

- Make empty sessionName resolve deterministically (attached/most-recent)

- Preserve failure semantics for signal-terminated tmux commands
```

### Files (name-status)

```text
M	cli/src/api/api.test.ts
M	cli/src/api/apiMachine.ts
M	cli/src/api/apiSession.test.ts
M	cli/src/api/apiSession.ts
M	cli/src/claude/runClaude.ts
M	cli/src/claude/utils/sessionScanner.test.ts
M	cli/src/codex/codexMcpClient.ts
A	cli/src/daemon/run.tmuxEnv.test.ts
A	cli/src/daemon/run.tmuxSpawn.test.ts
M	cli/src/daemon/run.ts
M	cli/src/modules/common/registerCommonHandlers.ts
M	cli/src/persistence.profileSchema.test.ts
M	cli/src/persistence.ts
M	cli/src/ui/logger.test.ts
M	cli/src/utils/createSessionMetadata.ts
M	cli/src/utils/offlineSessionStub.test.ts
D	cli/src/utils/spawnHappyCLI.test.ts
A	cli/src/utils/tmux.commandEnv.test.ts
A	cli/src/utils/tmux.real.integration.test.ts
M	cli/src/utils/tmux.socketPath.test.ts
M	cli/src/utils/tmux.test.ts
```

### Diffstat

```text
 cli/src/api/api.test.ts                          | 107 ++++----
 cli/src/api/apiMachine.ts                        |   7 +-
 cli/src/api/apiSession.test.ts                   |   8 +-
 cli/src/api/apiSession.ts                        |  25 +-
 cli/src/claude/runClaude.ts                      |   3 +
 cli/src/claude/utils/sessionScanner.test.ts      |   3 -
 cli/src/codex/codexMcpClient.ts                  |  22 +-
 cli/src/daemon/run.tmuxEnv.test.ts               |  16 ++
 cli/src/daemon/run.tmuxSpawn.test.ts             |  39 +++
 cli/src/daemon/run.ts                            | 150 +++++++++--
 cli/src/modules/common/registerCommonHandlers.ts |   2 +-
 cli/src/persistence.profileSchema.test.ts        |   5 +-
 cli/src/persistence.ts                           |  11 +-
 cli/src/ui/logger.test.ts                        |  48 ++--
 cli/src/utils/createSessionMetadata.ts           |   4 +-
 cli/src/utils/offlineSessionStub.test.ts         |  13 +-
 cli/src/utils/spawnHappyCLI.test.ts              |  56 ----
 cli/src/utils/tmux.commandEnv.test.ts            |  60 +++++
 cli/src/utils/tmux.real.integration.test.ts      | 322 +++++++++++++++++++++++
 cli/src/utils/tmux.socketPath.test.ts            |  33 ++-
 cli/src/utils/tmux.test.ts                       | 187 ++++++++++++-
 21 files changed, 915 insertions(+), 206 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tmux): correct env, tmpdir, and session selection
- Key files by churn (top 8):
  - cli/src/utils/tmux.real.integration.test.ts: +322/-0 | adds const argWithSingleQuote, const argWithSpaces, const defaultList, const dir, const env, const injectionArg | touches @@ -0,0 +1,322 @@
  - cli/src/utils/tmux.test.ts: +175/-12 | adds class FakeTmuxUtilities, const commandArg, const commandIndex, const fIndex, const newWindowArgs, const newWindowCall | removes const result | touches @@ -8 +8 @@; describe('Round-trip consistency', () => {; describe('buildTmuxSessionIdentifier', () => {; describe('parseTmuxSessionIdentifier', () => {
  - cli/src/daemon/run.ts: +122/-28 | adds const args, const cleanup, const codexHomeDirCleanupByPid, const commandTokens, const filteredDaemonEnv, const tmux | removes const cliPath, const fullCommand, const tmux, const tmuxResult | touches export async function startDaemon(): Promise<void> {; export const initialMachineMetadata: MachineMetadata = {; import { getEnvironmentInfo } from '@/ui/doctor';; import { projectPath } from '@/projectPath';
  - cli/src/api/api.test.ts: +58/-49 | adds const authError, const result | removes const authError, const result | touches describe('Api server error handling', () => {
  - cli/src/utils/tmux.commandEnv.test.ts: +60/-0 | adds const call, const child, const spawnMock, const utils, type MinimalChild, type SpawnCall | touches @@ -0,0 +1,60 @@
  - cli/src/utils/spawnHappyCLI.test.ts: +0/-56 | removes const argv, const originalRuntimeOverride | touches @@ -1,56 +0,0 @@
  - cli/src/ui/logger.test.ts: +27/-21 | adds const content, const originalHappyHomeDir | removes const actual | touches @@ -1,13 +1,4 @@; describe('logger.debugLargeJson', () => {
  - cli/src/daemon/run.tmuxSpawn.test.ts: +39/-0 | adds const cfg, const originalPath, const originalRuntimeOverride, const runModule | touches @@ -0,0 +1,39 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tmux): correct env, tmpdir, and session selection`

### Topic Bucket

- `tmux`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 100 2026-01-16 7a01a8e42629

- SHA: 7a01a8e426291e8a32de4805ff12621db26fb990
- Subject: test(claude): align sessionScanner path mapping
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +34 / -7
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/utils/sessionScanner.test.ts
```

### Diffstat

```text
 cli/src/claude/utils/sessionScanner.test.ts | 41 ++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(claude): align sessionScanner path mapping
- Key files by churn (top 1):
  - cli/src/claude/utils/sessionScanner.test.ts: +34/-7 | adds const start, function waitFor | touches describe('sessionScanner', () => {; import { getProjectPath } from './path'

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(claude): align sessionScanner path mapping`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 101 2026-01-17 1075a768e551

- SHA: 1075a768e551d5b7fc135d88636b03baf6938969
- Subject: feat(rpc): add detect-cli handler
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +159 / -2
- Touched areas: cli(2)
- Topic bucket: `rpc`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/modules/common/registerCommonHandlers.detectCli.test.ts
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 .../registerCommonHandlers.detectCli.test.ts       | 84 ++++++++++++++++++++++
 cli/src/modules/common/registerCommonHandlers.ts   | 77 +++++++++++++++++++-
 2 files changed, 159 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(rpc): add detect-cli handler
- Key files by churn (top 2):
  - cli/src/modules/common/registerCommonHandlers.detectCli.test.ts: +84/-0 | adds const decrypted, const dir, const encryptedParams, const encryptedResponse, const encryptionKey, const encryptionVariant | touches @@ -0,0 +1,84 @@
  - cli/src/modules/common/registerCommonHandlers.ts: +75/-2 | adds const candidate, const extensions, const isWindows, const pairs, const pathEnv, const resolvedPath | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; import { createHash } from 'crypto';; import { promisify } from 'util';; interface BashResponse {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(rpc): add detect-cli handler`

### Topic Bucket

- `rpc`

### Notes / Follow-ups


---

## 102 2026-01-21 c988f68ca4d0

- SHA: c988f68ca4d03f202a5bc6ff3e5fe18da2c3eb37
- Subject: feat(ui): surface Codex/Gemini errors in session UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 9
- Lines: +306 / -71
- Touched areas: cli(9)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
- Add `formatErrorForUi` to turn unknown throws into user-visible text (with truncation).

- Codex: forward MCP error/stream/startup failures to `sendSessionEvent`, and show tool-response errors.

- Gemini: extract error formatting into `formatGeminiErrorForUi` so the UI gets actionable messages instead of silent hangs.
```

### Files (name-status)

```text
A	cli/src/codex/__tests__/extractCodexToolErrorText.test.ts
M	cli/src/codex/runCodex.ts
A	cli/src/codex/utils/formatCodexEventForUi.test.ts
A	cli/src/codex/utils/formatCodexEventForUi.ts
M	cli/src/gemini/runGemini.ts
A	cli/src/gemini/utils/formatGeminiErrorForUi.test.ts
A	cli/src/gemini/utils/formatGeminiErrorForUi.ts
A	cli/src/utils/formatErrorForUi.test.ts
A	cli/src/utils/formatErrorForUi.ts
```

### Diffstat

```text
 .../__tests__/extractCodexToolErrorText.test.ts    | 36 ++++++++
 cli/src/codex/runCodex.ts                          | 66 +++++++++++++--
 cli/src/codex/utils/formatCodexEventForUi.test.ts  | 27 ++++++
 cli/src/codex/utils/formatCodexEventForUi.ts       | 27 ++++++
 cli/src/gemini/runGemini.ts                        | 66 +--------------
 .../gemini/utils/formatGeminiErrorForUi.test.ts    | 19 +++++
 cli/src/gemini/utils/formatGeminiErrorForUi.ts     | 99 ++++++++++++++++++++++
 cli/src/utils/formatErrorForUi.test.ts             | 23 +++++
 cli/src/utils/formatErrorForUi.ts                  | 14 +++
 9 files changed, 306 insertions(+), 71 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(ui): surface Codex/Gemini errors in session UI
- Key files by churn (top 8):
  - cli/src/gemini/utils/formatGeminiErrorForUi.ts: +99/-0 | adds const currentModel, const errObj, const errorCode, const errorDetails, const errorMessage, const errorString | touches @@ -0,0 +1,99 @@
  - cli/src/gemini/runGemini.ts: +2/-64 | adds const errorMsg | removes const currentModel, const errObj, const errorCode, const errorDetails | touches export async function runGemini(opts: {; import type { ApiSessionClient } from '@/api/apiSession';
  - cli/src/codex/runCodex.ts: +59/-7 | adds const continueError, const details, const messageText, const startError, const startResponse, const text | touches export async function runCodex(opts: {; export function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, not; import { CodexPermissionHandler } from './utils/permissionHandler';; import { stopCaffeinate } from "@/utils/caffeinate";
  - cli/src/codex/__tests__/extractCodexToolErrorText.test.ts: +36/-0 | touches @@ -0,0 +1,36 @@
  - cli/src/codex/utils/formatCodexEventForUi.ts: +27/-0 | adds const errorText, const m, const raw, const serverName, const type, function formatCodexEventForUi | touches @@ -0,0 +1,27 @@
  - cli/src/codex/utils/formatCodexEventForUi.test.ts: +27/-0 | touches @@ -0,0 +1,27 @@
  - cli/src/utils/formatErrorForUi.test.ts: +23/-0 | adds const err, const input, const out | touches @@ -0,0 +1,23 @@
  - cli/src/gemini/utils/formatGeminiErrorForUi.test.ts: +19/-0 | adds const err | touches @@ -0,0 +1,19 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(ui): surface Codex/Gemini errors in session UI`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 103 2026-01-21 b2269ee11252

- SHA: b2269ee112523d99318612c2c23f81f3b0b58183
- Subject: fix(claude): use hook transcript path across switching
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 18
- Lines: +1025 / -93
- Touched areas: cli(18)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
- Prefer SessionStart hook transcript_path for session scanning + `claudeCheckSession` (keep `getProjectPath` heuristic as fallback).

- Emit a UI message when the transcript file can’t be found yet (prevents a silent/blank UI).

- Wait briefly for hook session info before switching to avoid null sessionId/transcript races.

- Make the `switch` RPC idempotent (accepts {to:'local'|'remote'}; returns boolean; keeps legacy toggle when params are missing).

- Keep hook-mode flags intact (don’t rewrite `--continue/--resume/--session-id` when hooks are enabled).

- KeepAlive now reports the correct mode; remote init no longer blocks on a 10s file wait.
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocal.test.ts
M	cli/src/claude/claudeLocal.ts
A	cli/src/claude/claudeLocalLauncher.test.ts
M	cli/src/claude/claudeLocalLauncher.ts
A	cli/src/claude/claudeRemote.test.ts
M	cli/src/claude/claudeRemote.ts
A	cli/src/claude/claudeRemoteLauncher.test.ts
M	cli/src/claude/claudeRemoteLauncher.ts
A	cli/src/claude/loop.test.ts
M	cli/src/claude/loop.ts
M	cli/src/claude/runClaude.ts
A	cli/src/claude/session.test.ts
M	cli/src/claude/session.ts
M	cli/src/claude/utils/claudeCheckSession.test.ts
M	cli/src/claude/utils/claudeCheckSession.ts
M	cli/src/claude/utils/sessionScanner.test.ts
M	cli/src/claude/utils/sessionScanner.ts
M	cli/src/claude/utils/startHookServer.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocal.test.ts              |  41 ++++-
 cli/src/claude/claudeLocal.ts                   |  61 ++++---
 cli/src/claude/claudeLocalLauncher.test.ts      | 229 ++++++++++++++++++++++++
 cli/src/claude/claudeLocalLauncher.ts           |  53 +++++-
 cli/src/claude/claudeRemote.test.ts             |  68 +++++++
 cli/src/claude/claudeRemote.ts                  |  17 +-
 cli/src/claude/claudeRemoteLauncher.test.ts     |  95 ++++++++++
 cli/src/claude/claudeRemoteLauncher.ts          |  34 +++-
 cli/src/claude/loop.test.ts                     |  55 ++++++
 cli/src/claude/loop.ts                          |   8 +-
 cli/src/claude/runClaude.ts                     |   2 +-
 cli/src/claude/session.test.ts                  |  81 +++++++++
 cli/src/claude/session.ts                       | 114 ++++++++++--
 cli/src/claude/utils/claudeCheckSession.test.ts |  13 ++
 cli/src/claude/utils/claudeCheckSession.ts      |   8 +-
 cli/src/claude/utils/sessionScanner.test.ts     |  95 ++++++++++
 cli/src/claude/utils/sessionScanner.ts          | 141 +++++++++++++--
 cli/src/claude/utils/startHookServer.ts         |   3 +-
 18 files changed, 1025 insertions(+), 93 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): use hook transcript path across switching
- Key files by churn (top 8):
  - cli/src/claude/claudeLocalLauncher.test.ts: +229/-0 | adds const client, const launcherPromise, const mockClaudeLocal, const mockCreateSessionScanner, const result, const sendSessionEvent | touches @@ -0,0 +1,229 @@
  - cli/src/claude/utils/sessionScanner.ts: +123/-18 | adds const desiredPath, const existing, const filePath, const initialProjectDir, const missingTranscriptTimers, const nextProjectDir | removes const expectedSessionFile, const projectDir, const sessionMessages, function readSessionLog | touches async function readSessionLog(projectDir: string, sessionId: string): Promise<Ra; const INTERNAL_CLAUDE_EVENT_TYPES = new Set([; export async function createSessionScanner(opts: {; function messageKey(message: RawJSONLines): string {
  - cli/src/claude/session.ts: +103/-11 | adds const cleanup, const didTranscriptPathChange, const isReady, const nextArg, const nextTranscriptPath, const nextTranscriptPathRaw | touches export class Session {; import type { JsRuntime } from "./runClaude";
  - cli/src/claude/utils/sessionScanner.test.ts: +95/-0 | adds const altProjectDir, const sessionId, const transcriptPath | touches describe('sessionScanner', () => {
  - cli/src/claude/claudeRemoteLauncher.test.ts: +95/-0 | adds const api, const client, const launcherPromise, const mockClaudeRemote, const sendSessionEvent, const session | touches @@ -0,0 +1,95 @@
  - cli/src/claude/session.test.ts: +81/-0 | adds const client, const session | touches @@ -0,0 +1,81 @@
  - cli/src/claude/claudeRemote.test.ts: +68/-0 | adds const canCallTool, const mockQuery, const nextMessage, const onMessage, const onReady, const onSessionFound | touches @@ -0,0 +1,68 @@
  - cli/src/claude/claudeLocal.ts: +33/-28 | adds const continueFlag, const lastSession, const resumeFlag | removes const continueFlag, const lastSession, const resumeFlag, const sessionIdFlag | touches export async function claudeLocal(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): use hook transcript path across switching`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 104 2026-01-21 f53cf71d416c

- SHA: f53cf71d416ca52e94b2eac1171cfc9f6c298045
- Subject: refactor(persistence): remove deprecated tmuxConfig
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -18
- Touched areas: cli(1)
- Topic bucket: `persistence`
- Manual review needed: no

### Commit Message Body

```text
- Drop the legacy profile tmuxConfig field and its env-var injection path.

- Keep terminal/tmux behavior driven by explicit terminal settings/flags to avoid schema drift.
```

### Files (name-status)

```text
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/persistence.ts | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(persistence): remove deprecated tmuxConfig
- Key files by churn (top 1):
  - cli/src/persistence.ts: +1/-18 | removes const TmuxConfigSchema | touches export const AIBackendProfileSchema = z.preprocess(normalizeLegacyProfileConfig,; export function getProfileEnvironmentVariables(profile: AIBackendProfile): Recor; export function validateProfile(profile: unknown): AIBackendProfile {; function normalizeLegacyProfileConfig(profile: unknown): unknown {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(persistence): remove deprecated tmuxConfig`

### Topic Bucket

- `persistence`

### Notes / Follow-ups


---

## 105 2026-01-21 8dae65f6c585

- SHA: 8dae65f6c5851277eb5fb3235190f2f02f947a25
- Subject: feat(rpc): include tmux in detect-cli
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +302 / -6
- Touched areas: cli(2)
- Topic bucket: `rpc`
- Manual review needed: no

### Commit Message Body

```text
- Extend the detect-cli RPC to report tmux availability for UI gating and better diagnostics.

- Add/adjust unit tests to cover tmux detection alongside existing CLI checks.
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.detectCli.test.ts
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 .../registerCommonHandlers.detectCli.test.ts       |  83 +++++++-
 cli/src/modules/common/registerCommonHandlers.ts   | 225 ++++++++++++++++++++-
 2 files changed, 302 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(rpc): include tmux in detect-cli
- Key files by churn (top 2):
  - cli/src/modules/common/registerCommonHandlers.ts: +221/-4 | adds const asString, const code, const execFileAsync, const execFileBestEffort, const firstLine, const includeLoginStatus | touches async function resolveCommandOnPath(command: string, pathEnv: string | null): Pr; const execAsync = promisify(exec);; export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; export interface SpawnSessionOptions {
  - cli/src/modules/common/registerCommonHandlers.detectCli.test.ts: +81/-2 | adds const dir, const fakeCodex, const fakeTmux, const isWindows, const result | touches describe('registerCommonHandlers detect-cli', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(rpc): include tmux in detect-cli`

### Topic Bucket

- `rpc`

### Notes / Follow-ups


---

## 106 2026-01-21 ad66c6aaa3ae

- SHA: ad66c6aaa3ae604456f02dc793b381a5064e43ec
- Subject: feat(terminal): add tmux metadata + attach tooling
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 23
- Lines: +1036 / -11
- Touched areas: cli(23)
- Topic bucket: `terminal`
- Manual review needed: no

### Commit Message Body

```text
- Add terminal/tmux metadata to session creation (used by UI Session Details + attach workflows).

- Persist local attachment info (best-effort) once a session ID exists and optionally surface tmux fallback reasons as UI-facing messages.

- Add attach planning utilities and a new `happy attach` command.

- Add headless tmux launcher support (`--tmux`) and internal terminal runtime flags for spawners.
```

### Files (name-status)

```text
M	cli/src/api/types.ts
M	cli/src/claude/runClaude.ts
M	cli/src/codex/runCodex.ts
A	cli/src/commands/attach.ts
M	cli/src/gemini/runGemini.ts
M	cli/src/index.ts
A	cli/src/terminal/headlessTmuxArgs.test.ts
A	cli/src/terminal/headlessTmuxArgs.ts
A	cli/src/terminal/startHappyHeadlessInTmux.ts
A	cli/src/terminal/terminalAttachPlan.test.ts
A	cli/src/terminal/terminalAttachPlan.ts
A	cli/src/terminal/terminalAttachmentInfo.test.ts
A	cli/src/terminal/terminalAttachmentInfo.ts
A	cli/src/terminal/terminalConfig.test.ts
A	cli/src/terminal/terminalConfig.ts
A	cli/src/terminal/terminalFallbackMessage.test.ts
A	cli/src/terminal/terminalFallbackMessage.ts
A	cli/src/terminal/terminalMetadata.ts
A	cli/src/terminal/terminalRuntimeFlags.test.ts
A	cli/src/terminal/terminalRuntimeFlags.ts
A	cli/src/terminal/tmuxSessionSelector.test.ts
A	cli/src/terminal/tmuxSessionSelector.ts
M	cli/src/utils/createSessionMetadata.ts
```

### Diffstat

```text
 cli/src/api/types.ts                             | 13 ++++
 cli/src/claude/runClaude.ts                      | 37 ++++++++-
 cli/src/codex/runCodex.ts                        | 26 ++++++-
 cli/src/commands/attach.ts                       | 89 ++++++++++++++++++++++
 cli/src/gemini/runGemini.ts                      | 26 ++++++-
 cli/src/index.ts                                 | 53 +++++++++++--
 cli/src/terminal/headlessTmuxArgs.test.ts        | 27 +++++++
 cli/src/terminal/headlessTmuxArgs.ts             | 16 ++++
 cli/src/terminal/startHappyHeadlessInTmux.ts     | 93 +++++++++++++++++++++++
 cli/src/terminal/terminalAttachPlan.test.ts      | 65 ++++++++++++++++
 cli/src/terminal/terminalAttachPlan.ts           | 65 ++++++++++++++++
 cli/src/terminal/terminalAttachmentInfo.test.ts  | 37 +++++++++
 cli/src/terminal/terminalAttachmentInfo.ts       | 61 +++++++++++++++
 cli/src/terminal/terminalConfig.test.ts          | 80 ++++++++++++++++++++
 cli/src/terminal/terminalConfig.ts               | 95 ++++++++++++++++++++++++
 cli/src/terminal/terminalFallbackMessage.test.ts | 24 ++++++
 cli/src/terminal/terminalFallbackMessage.ts      | 16 ++++
 cli/src/terminal/terminalMetadata.ts             | 34 +++++++++
 cli/src/terminal/terminalRuntimeFlags.test.ts    | 50 +++++++++++++
 cli/src/terminal/terminalRuntimeFlags.ts         | 68 +++++++++++++++++
 cli/src/terminal/tmuxSessionSelector.test.ts     | 22 ++++++
 cli/src/terminal/tmuxSessionSelector.ts          | 45 +++++++++++
 cli/src/utils/createSessionMetadata.ts           |  5 ++
 23 files changed, 1036 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(terminal): add tmux metadata + attach tooling
- Key files by churn (top 8):
  - cli/src/terminal/terminalConfig.ts: +95/-0 | adds const env, const isolated, const sessionName, const terminal, const tmpDir, const tmpDirOverride | touches @@ -0,0 +1,95 @@
  - cli/src/terminal/startHappyHeadlessInTmux.ts: +93/-0 | adds const agent, const argsWithoutTmux, const childArgs, const commandTokens, const first, const insideTmux | touches @@ -0,0 +1,93 @@
  - cli/src/commands/attach.ts: +89/-0 | adds const attachExit, const child, const info, const plan, const selectExit, const sessionId | touches @@ -0,0 +1,89 @@
  - cli/src/terminal/terminalConfig.test.ts: +80/-0 | adds const resolved | touches @@ -0,0 +1,80 @@
  - cli/src/terminal/terminalRuntimeFlags.ts: +68/-0 | adds const arg, const hasAny, const value, function parseAndStripTerminalRuntimeFlags, function parseTerminalMode, type TerminalRuntimeFlags | touches @@ -0,0 +1,68 @@
  - cli/src/terminal/terminalAttachPlan.ts: +65/-0 | adds const parsed, const shouldAttach, const shouldUnsetTmuxEnv, const target, const tmpDir, function createTerminalAttachPlan | touches @@ -0,0 +1,65 @@
  - cli/src/terminal/terminalAttachPlan.test.ts: +65/-0 | adds const plan | touches @@ -0,0 +1,65 @@
  - cli/src/terminal/terminalAttachmentInfo.ts: +61/-0 | adds const dir, const parsed, const path, const raw, const tmpPath, function readTerminalAttachmentInfo | touches @@ -0,0 +1,61 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(terminal): add tmux metadata + attach tooling`

### Topic Bucket

- `terminal`

### Notes / Follow-ups


---

## 107 2026-01-21 c13d51ee4638

- SHA: c13d51ee4638ab55a89ae789053f68bbdb04dc6a
- Subject: feat(daemon): support tmux spawn + harden runtime
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 8
- Lines: +324 / -74
- Touched areas: cli(8)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
- Spawn sessions in tmux when requested (including isolated server option) and record tmux target/fallback metadata.

- Extend spawn-session request plumbing and add a focused apiMachine spawn-session test.

- Harden backoff behavior (clamping + retry gates) and avoid throwing on best-effort log file write failures.
```

### Files (name-status)

```text
A	cli/src/api/apiMachine.spawnSession.test.ts
M	cli/src/api/apiMachine.ts
M	cli/src/daemon/run.tmuxSpawn.test.ts
M	cli/src/daemon/run.ts
M	cli/src/ui/logger.test.ts
M	cli/src/ui/logger.ts
M	cli/src/utils/sync.ts
M	cli/src/utils/time.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.spawnSession.test.ts |  52 ++++++
 cli/src/api/apiMachine.ts                   |  19 ++-
 cli/src/daemon/run.tmuxSpawn.test.ts        |   4 +
 cli/src/daemon/run.ts                       | 256 +++++++++++++++++++++-------
 cli/src/ui/logger.test.ts                   |  18 +-
 cli/src/ui/logger.ts                        |  11 +-
 cli/src/utils/sync.ts                       |   4 +-
 cli/src/utils/time.ts                       |  34 +++-
 8 files changed, 324 insertions(+), 74 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(daemon): support tmux spawn + harden runtime
- Key files by churn (top 8):
  - cli/src/daemon/run.ts: +199/-57 | adds const agent, const base, const current, const execFileAsync, const extraEnvForChild, const fallback | removes const agent, const happyProcess, const sessionDesc, const spawnSession | touches export async function startDaemon(): Promise<void> {; export function buildTmuxSpawnConfig(params: {; import * as tmp from 'tmp';; import { expandEnvironmentVariables } from '@/utils/expandEnvVars';
  - cli/src/api/apiMachine.spawnSession.test.ts: +52/-0 | adds const client, const encrypted, const params, const rpc | touches @@ -0,0 +1,52 @@
  - cli/src/utils/time.ts: +28/-6 | adds const clampedFailureCount, const jittered, const maxDelayRet, const maxFailureCount, const safeMaxFailureCount, const shouldRetry | removes const maxFailureCount | touches export function createBackoff(; export function exponentialBackoffDelay(currentFailureCount: number, minDelay: n
  - cli/src/api/apiMachine.ts: +16/-3 | adds const result | removes const result | touches export class ApiMachineClient {
  - cli/src/ui/logger.test.ts: +16/-2 | adds const logsDir | touches describe('logger.debugLargeJson', () => {; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
  - cli/src/ui/logger.ts: +7/-4 | touches class Logger {
  - cli/src/utils/sync.ts: +2/-2 | touches @@ -1 +1 @@; export class InvalidateSync {
  - cli/src/daemon/run.tmuxSpawn.test.ts: +4/-0 | touches describe('daemon tmux spawn config', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(daemon): support tmux spawn + harden runtime`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 108 2026-01-21 f7db44dea458

- SHA: f7db44dea4586a2a399e6765e31f8ad9d3f61475
- Subject: docs: add AGENTS.md symlink
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -0
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
- Keep agent guidance single-sourced by symlinking AGENTS.md -> CLAUDE.md.
```

### Files (name-status)

```text
A	cli/AGENTS.md
```

### Diffstat

```text
 cli/AGENTS.md | 1 +
 1 file changed, 1 insertion(+)
```

### What It Does (diff-based summary)

- Intent (from subject): docs: add AGENTS.md symlink
- Key files by churn (top 1):
  - cli/AGENTS.md: +1/-0 | touches @@ -0,0 +1 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `docs: add AGENTS.md symlink`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 109 2026-01-21 af5000ea6318

- SHA: af5000ea6318bf1e02fba19069660179d9318d84
- Subject: fix(ui): polish Codex and Gemini error messages
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +17 / -5
- Touched areas: cli(4)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/utils/formatCodexEventForUi.test.ts
M	cli/src/codex/utils/formatCodexEventForUi.ts
M	cli/src/gemini/utils/formatGeminiErrorForUi.test.ts
M	cli/src/gemini/utils/formatGeminiErrorForUi.ts
```

### Diffstat

```text
 cli/src/codex/utils/formatCodexEventForUi.test.ts   | 10 +++++++++-
 cli/src/codex/utils/formatCodexEventForUi.ts        |  3 +--
 cli/src/gemini/utils/formatGeminiErrorForUi.test.ts |  5 ++++-
 cli/src/gemini/utils/formatGeminiErrorForUi.ts      |  4 +++-
 4 files changed, 17 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): polish Codex and Gemini error messages
- Key files by churn (top 4):
  - cli/src/codex/utils/formatCodexEventForUi.test.ts: +9/-1 | touches describe('formatCodexEventForUi', () => {
  - cli/src/gemini/utils/formatGeminiErrorForUi.test.ts: +4/-1 | touches describe('formatGeminiErrorForUi', () => {
  - cli/src/gemini/utils/formatGeminiErrorForUi.ts: +3/-1 | touches export function formatGeminiErrorForUi(error: unknown, displayedModel?: string |
  - cli/src/codex/utils/formatCodexEventForUi.ts: +1/-2 | adds const errorText | removes const errorText | touches export function formatCodexEventForUi(msg: unknown): string | null {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): polish Codex and Gemini error messages`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 110 2026-01-21 f68552d03ab9

- SHA: f68552d03ab97641f8da5cd8ccb65113a8e13a34
- Subject: fix(tmux): print attach instructions in correct order
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +82 / -3
- Touched areas: cli(2)
- Topic bucket: `tmux`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/terminal/startHappyHeadlessInTmux.test.ts
M	cli/src/terminal/startHappyHeadlessInTmux.ts
```

### Diffstat

```text
 cli/src/terminal/startHappyHeadlessInTmux.test.ts | 80 +++++++++++++++++++++++
 cli/src/terminal/startHappyHeadlessInTmux.ts      |  5 +-
 2 files changed, 82 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tmux): print attach instructions in correct order
- Key files by churn (top 2):
  - cli/src/terminal/startHappyHeadlessInTmux.test.ts: +80/-0 | adds class TmuxUtilities, const calls, const mockExecuteTmuxCommand, const mockSpawnInTmux, const originalEnv, const originalTmuxEnv | touches @@ -0,0 +1,80 @@
  - cli/src/terminal/startHappyHeadlessInTmux.ts: +2/-3 | touches export async function startHappyHeadlessInTmux(argv: string[]): Promise<void> {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tmux): print attach instructions in correct order`

### Topic Bucket

- `tmux`

### Notes / Follow-ups


---

## 111 2026-01-21 4e4bb65ff3f0

- SHA: 4e4bb65ff3f0c7df410abd6fe2a6d69bd6d96f5e
- Subject: test(tmux): avoid brittle assertions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +15 / -14
- Touched areas: cli(1)
- Topic bucket: `tmux`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/terminal/startHappyHeadlessInTmux.test.ts
```

### Diffstat

```text
 cli/src/terminal/startHappyHeadlessInTmux.test.ts | 29 ++++++++++++-----------
 1 file changed, 15 insertions(+), 14 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(tmux): avoid brittle assertions
- Key files by churn (top 1):
  - cli/src/terminal/startHappyHeadlessInTmux.test.ts: +15/-14 | adds const attachIdx, const lines, const selectIdx | removes const calls, const originalEnv | touches describe('startHappyHeadlessInTmux', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(tmux): avoid brittle assertions`

### Topic Bucket

- `tmux`

### Notes / Follow-ups


---

## 112 2026-01-21 45f4eb5d145c

- SHA: 45f4eb5d145caff292136122c70fbfccd26207b0
- Subject: test(detect-cli): avoid process.env reassignment
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +22 / -3
- Touched areas: cli(1)
- Topic bucket: `detect-cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.detectCli.test.ts
```

### Diffstat

```text
 .../registerCommonHandlers.detectCli.test.ts       | 25 +++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(detect-cli): avoid process.env reassignment
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.detectCli.test.ts: +22/-3 | adds const originalPath, const originalPathext | removes const originalEnv | touches describe('registerCommonHandlers detect-cli', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(detect-cli): avoid process.env reassignment`

### Topic Bucket

- `detect-cli`

### Notes / Follow-ups


---

## 113 2026-01-21 51782fdbfbcd

- SHA: 51782fdbfbcd98757345f7f93a02bd825baa8cdf
- Subject: test(codex): reset transport instances between tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: cli(1)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/codexMcpClient.test.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.test.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(codex): reset transport instances between tests
- Key files by churn (top 1):
  - cli/src/codex/codexMcpClient.test.ts: +1/-1 | touches describe('CodexMcpClient command detection', () => {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(codex): reset transport instances between tests`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 114 2026-01-21 0ad76f4877ae

- SHA: 0ad76f4877ae26d382f5b33ae654e345ea17136d
- Subject: chore(cli): fix gemini daemon block indentation
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +2 / -2
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/index.ts
```

### Diffstat

```text
 cli/src/index.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): chore(cli): fix gemini daemon block indentation
- Key files by churn (top 1):
  - cli/src/index.ts: +2/-2 | touches import { handleAttachCommand } from '@/commands/attach'

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(cli): fix gemini daemon block indentation`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 115 2026-01-21 a8093e3e4ddb

- SHA: a8093e3e4ddb6ff974e69d8aa29fe43fce34dbad
- Subject: docs(persistence): update profile schema version comment
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: cli(1)
- Topic bucket: `persistence`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/persistence.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): docs(persistence): update profile schema version comment
- Key files by churn (top 1):
  - cli/src/persistence.ts: +1/-1 | touches export function validateProfile(profile: unknown): AIBackendProfile {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `docs(persistence): update profile schema version comment`

### Topic Bucket

- `persistence`

### Notes / Follow-ups


---

## 116 2026-01-21 b16c3658b944

- SHA: b16c3658b944b1a73ae86faa700e97b1887d1fad
- Subject: fix(gemini): normalize error details for UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +4 / -1
- Touched areas: cli(1)
- Topic bucket: `gemini`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/gemini/utils/formatGeminiErrorForUi.ts
```

### Diffstat

```text
 cli/src/gemini/utils/formatGeminiErrorForUi.ts | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(gemini): normalize error details for UI
- Key files by churn (top 1):
  - cli/src/gemini/utils/formatGeminiErrorForUi.ts: +4/-1 | adds const errorDetails, const rawDetails | removes const errorDetails | touches export function formatGeminiErrorForUi(error: unknown, displayedModel?: string |

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(gemini): normalize error details for UI`

### Topic Bucket

- `gemini`

### Notes / Follow-ups


---

## 117 2026-01-21 d9591372655f

- SHA: d9591372655f2765fbf5f993d330e4511607c445
- Subject: fix(common): handle execFileAsync exit codes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +2 / -1
- Touched areas: cli(1)
- Topic bucket: `common`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(common): handle execFileAsync exit codes
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.ts: +2/-1 | adds const code | removes const code | touches async function detectCliLoginStatus(params: { name: DetectCliName; resolvedPath:

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(common): handle execFileAsync exit codes`

### Topic Bucket

- `common`

### Notes / Follow-ups


---

## 118 2026-01-22 ab95e8cf920c

- SHA: ab95e8cf920c6b75514b54570222be18c6606542
- Subject: fix(sync): avoid hanging invalidateAndAwait on errors
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +84 / -11
- Touched areas: cli(3)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/utils/sessionScanner.ts
A	cli/src/utils/sync.test.ts
M	cli/src/utils/sync.ts
```

### Diffstat

```text
 cli/src/claude/utils/sessionScanner.ts |  7 ++++++
 cli/src/utils/sync.test.ts             | 45 ++++++++++++++++++++++++++++++++++
 cli/src/utils/sync.ts                  | 43 +++++++++++++++++++++++---------
 3 files changed, 84 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(sync): avoid hanging invalidateAndAwait on errors
- Key files by churn (top 3):
  - cli/src/utils/sync.test.ts: +45/-0 | adds const first, const firstRunGate, const run, const sync | touches @@ -0,0 +1,45 @@
  - cli/src/utils/sync.ts: +32/-11 | adds type InvalidateSyncOptions | touches @@ -1 +1,6 @@; export class InvalidateSync {
  - cli/src/claude/utils/sessionScanner.ts: +7/-0 | touches export async function createSessionScanner(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(sync): avoid hanging invalidateAndAwait on errors`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 119 2026-01-22 6f98c95fb5d8

- SHA: 6f98c95fb5d8a79a4e76a1917200e378b7e8355e
- Subject: fix(claude): support -c/-r and avoid session loss on switch
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 13
- Lines: +496 / -60
- Touched areas: cli(13)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocal.ts
M	cli/src/claude/claudeLocalLauncher.test.ts
M	cli/src/claude/claudeLocalLauncher.ts
M	cli/src/claude/claudeRemote.test.ts
M	cli/src/claude/claudeRemote.ts
M	cli/src/claude/claudeRemoteLauncher.test.ts
M	cli/src/claude/claudeRemoteLauncher.ts
M	cli/src/claude/session.test.ts
M	cli/src/claude/session.ts
M	cli/src/claude/utils/claudeFindLastSession.ts
M	cli/src/claude/utils/path.test.ts
M	cli/src/claude/utils/path.ts
M	cli/src/claude/utils/sessionScanner.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocal.ts                 |   8 +-
 cli/src/claude/claudeLocalLauncher.test.ts    |  81 ++++++++++++++
 cli/src/claude/claudeLocalLauncher.ts         |  20 +++-
 cli/src/claude/claudeRemote.test.ts           | 115 +++++++++++++++++++-
 cli/src/claude/claudeRemote.ts                |  56 ++++++----
 cli/src/claude/claudeRemoteLauncher.test.ts   | 145 +++++++++++++++++++++++++-
 cli/src/claude/claudeRemoteLauncher.ts        |  11 +-
 cli/src/claude/session.test.ts                |  59 +++++++++++
 cli/src/claude/session.ts                     |  24 ++---
 cli/src/claude/utils/claudeFindLastSession.ts |   9 +-
 cli/src/claude/utils/path.test.ts             |   7 ++
 cli/src/claude/utils/path.ts                  |   7 +-
 cli/src/claude/utils/sessionScanner.ts        |  14 ++-
 13 files changed, 496 insertions(+), 60 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): support -c/-r and avoid session loss on switch
- Key files by churn (top 8):
  - cli/src/claude/claudeRemoteLauncher.test.ts: +144/-1 | adds const api, const client, const launcherPromise, const mockResetParentChain, const mockUpdateSessionId, const session | touches describe('claudeRemoteLauncher', () => {; vi.mock('./claudeRemote', () => ({
  - cli/src/claude/claudeRemote.test.ts: +113/-2 | adds const call, const canCallTool, const nextMessage, const onMessage, const onReady, const onSessionFound | touches @@ -1 +1 @@; describe('claudeRemote', () => {; vi.mock('@/modules/watcher/awaitFileExist', () => ({
  - cli/src/claude/claudeLocalLauncher.test.ts: +81/-0 | adds const client, const launcherPromise, const sendSessionEvent, const session, const switchHandler | touches describe('claudeLocalLauncher', () => {
  - cli/src/claude/session.test.ts: +59/-0 | adds const client, const session | touches describe('Session', () => {
  - cli/src/claude/claudeRemote.ts: +36/-20 | adds const arg, const lastSession, const maybeValue | removes const nextArg | touches export async function claudeRemote(opts: {; import { claudeCheckSession } from "./utils/claudeCheckSession";
  - cli/src/claude/session.ts: +8/-16 | adds const nextArg | removes const nextArg | touches export class Session {
  - cli/src/claude/claudeLocalLauncher.ts: +19/-1 | adds const expectsFork, const resumeFromSessionId, const resumeFromTranscriptPath | touches export async function claudeLocalLauncher(session: Session): Promise<'switch' |
  - cli/src/claude/utils/sessionScanner.ts: +6/-8 | adds const initialProjectDir | removes const initialProjectDir | touches export async function createSessionScanner(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): support -c/-r and avoid session loss on switch`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 120 2026-01-16 9489d70848f3

- SHA: 9489d70848f3664c02cb2b248f60b396626b8cdf
- Subject: test(claude): align sessionScanner path mapping
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +0 / -1
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/utils/sessionScanner.test.ts
```

### Diffstat

```text
 cli/src/claude/utils/sessionScanner.test.ts | 1 -
 1 file changed, 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(claude): align sessionScanner path mapping
- Key files by churn (top 1):
  - cli/src/claude/utils/sessionScanner.test.ts: +0/-1 | touches describe('sessionScanner', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(claude): align sessionScanner path mapping`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 121 2026-01-12 9c4cb44b7d86

- SHA: 9c4cb44b7d869acd56a66f18a88b40525f830d65
- Subject: fix(daemon): reattach sessions after daemon restart
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 7
- Lines: +295 / -17
- Touched areas: cli(7)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/daemon/controlServer.ts
M	cli/src/daemon/doctor.ts
M	cli/src/daemon/run.ts
A	cli/src/daemon/sessionRegistry.ts
M	cli/src/daemon/types.ts
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts         |   6 +-
 cli/src/daemon/controlServer.ts   |   4 +-
 cli/src/daemon/doctor.ts          |   5 ++
 cli/src/daemon/run.ts             |  81 ++++++++++++++++++++++++-
 cli/src/daemon/sessionRegistry.ts | 124 ++++++++++++++++++++++++++++++++++++++
 cli/src/daemon/types.ts           |   5 ++
 cli/src/persistence.ts            |  87 ++++++++++++++++++++++----
 7 files changed, 295 insertions(+), 17 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(daemon): reattach sessions after daemon restart
- Key files by churn (top 7):
  - cli/src/daemon/sessionRegistry.ts: +124/-0 | adds const DaemonSessionMarkerSchema, const entries, const err, const existing, const filePath, const full | touches @@ -0,0 +1,124 @@
  - cli/src/persistence.ts: +76/-11 | adds const DaemonLocallyPersistedStateSchema, const content, const dir, const err, const parsed, const tmpPath | removes const content | touches export async function clearDaemonState(): Promise<void> {; export async function readDaemonState(): Promise<DaemonLocallyPersistedState | n; export function writeDaemonState(state: DaemonLocallyPersistedState): void {; export interface DaemonLocallyPersistedState {
  - cli/src/daemon/run.ts: +80/-1 | adds const ALLOWED_HAPPY_SESSION_PROCESS_TYPES, const happyPidToType, const happyProcesses, const markers, const proc, const procType | removes const stopSession | touches async function getPreferredHostName(): Promise<string> {; export async function startDaemon(): Promise<void> {; import { startDaemonControlServer } from './controlServer';
  - cli/src/api/apiMachine.ts: +3/-3 | adds const success | removes const success | touches export class ApiMachineClient {; type MachineRpcHandlers = {
  - cli/src/daemon/types.ts: +5/-0 | touches export interface TrackedSession {
  - cli/src/daemon/doctor.ts: +5/-0 | adds const all, function findHappyProcessByPid | touches export async function findAllHappyProcesses(): Promise<Array<{ pid: number, comm
  - cli/src/daemon/controlServer.ts: +2/-2 | adds const success | removes const success | touches export function startDaemonControlServer({

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(daemon): reattach sessions after daemon restart`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 122 2026-01-14 dbde6d871670

- SHA: dbde6d8716701939d4ce45bfb82541453b16b070
- Subject: test(daemon): add PID classification + session marker tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +199 / -34
- Touched areas: cli(3)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/daemon/doctor.test.ts
M	cli/src/daemon/doctor.ts
A	cli/src/daemon/sessionRegistry.test.ts
```

### Diffstat

```text
 cli/src/daemon/doctor.test.ts          |  40 ++++++++++++
 cli/src/daemon/doctor.ts               |  81 ++++++++++++++----------
 cli/src/daemon/sessionRegistry.test.ts | 112 +++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+), 34 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(daemon): add PID classification + session marker tests
- Key files by churn (top 3):
  - cli/src/daemon/sessionRegistry.test.ts: +112/-0 | adds const createdAt1, const dir, const filePath, const markers, const markers1, const markers2 | touches @@ -0,0 +1,112 @@
  - cli/src/daemon/doctor.ts: +47/-34 | adds const classified, const cmd, const isHappy, const name, function classifyHappyProcess, function findAllHappyProcesses | removes const cmd, const isHappy, const name, function findAllHappyProcesses | touches export async function findAllHappyProcesses(): Promise<Array<{ pid: number, comm; import spawn from 'cross-spawn';
  - cli/src/daemon/doctor.test.ts: +40/-0 | adds const res | touches @@ -0,0 +1,40 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(daemon): add PID classification + session marker tests`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 123 2026-01-14 7cffdd5ce614

- SHA: 7cffdd5ce614ef22d6d06b882f3237e837a572cd
- Subject: fix(daemon): verify PID via command hash for reattach/stop
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +74 / -10
- Touched areas: cli(4)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/daemon/run.ts
M	cli/src/daemon/sessionRegistry.test.ts
M	cli/src/daemon/sessionRegistry.ts
M	cli/src/daemon/types.ts
```

### Diffstat

```text
 cli/src/daemon/run.ts                  | 63 ++++++++++++++++++++++++++++------
 cli/src/daemon/sessionRegistry.test.ts |  7 ++++
 cli/src/daemon/sessionRegistry.ts      |  9 +++++
 cli/src/daemon/types.ts                |  5 +++
 4 files changed, 74 insertions(+), 10 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(daemon): verify PID via command hash for reattach/stop
- Key files by churn (top 4):
  - cli/src/daemon/run.ts: +53/-10 | adds const ALLOWED_HAPPY_SESSION_PROCESS_TYPES, const currentHash, const happyPidToCommandHash, const proc, const processCommandHash, const s | removes const ALLOWED_HAPPY_SESSION_PROCESS_TYPES | touches async function getPreferredHostName(): Promise<string> {; export async function startDaemon(): Promise<void> {; import { findAllHappyProcesses, findHappyProcessByPid } from './doctor';
  - cli/src/daemon/sessionRegistry.ts: +9/-0 | adds function hashProcessCommand | touches const DaemonSessionMarkerSchema = z.object({; export type DaemonSessionMarker = z.infer<typeof DaemonSessionMarkerSchema>;; import { logger } from '@/ui/logger';
  - cli/src/daemon/sessionRegistry.test.ts: +7/-0 | adds const processCommandHash | touches describe('sessionRegistry', () => {
  - cli/src/daemon/types.ts: +5/-0 | touches export interface TrackedSession {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(daemon): verify PID via command hash for reattach/stop`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 124 2026-01-13 8b88dcd73d40

- SHA: 8b88dcd73d406939feb019a431eeb49293e63225
- Subject: fix(claude): carry permission mode across remote/local switches
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +51 / -0
- Touched areas: cli(5)
- Topic bucket: `claude`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocalLauncher.ts
M	cli/src/claude/claudeRemoteLauncher.ts
M	cli/src/claude/loop.ts
M	cli/src/claude/session.ts
M	cli/src/claude/utils/permissionHandler.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocalLauncher.ts     | 36 +++++++++++++++++++++++++++++++
 cli/src/claude/claudeRemoteLauncher.ts    |  2 ++
 cli/src/claude/loop.ts                    |  4 ++++
 cli/src/claude/session.ts                 |  7 ++++++
 cli/src/claude/utils/permissionHandler.ts |  2 ++
 5 files changed, 51 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): carry permission mode across remote/local switches
- Key files by churn (top 5):
  - cli/src/claude/claudeLocalLauncher.ts: +36/-0 | adds const arg, const claudeMode, const input, function upsertClaudePermissionModeArgs | touches export async function claudeLocalLauncher(session: Session): Promise<'switch' |; import { formatErrorForUi } from "@/utils/formatErrorForUi";
  - cli/src/claude/session.ts: +7/-0 | touches export class Session {; import type { SessionHookData } from "./utils/startHookServer";
  - cli/src/claude/loop.ts: +4/-0 | touches export async function loop(opts: LoopOptions) {
  - cli/src/claude/utils/permissionHandler.ts: +2/-0 | touches export class PermissionHandler {
  - cli/src/claude/claudeRemoteLauncher.ts: +2/-0 | touches export async function claudeRemoteLauncher(session: Session): Promise<'switch' |

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): carry permission mode across remote/local switches`

### Topic Bucket

- `claude`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 125 2026-01-13 8f0e10c9428b

- SHA: 8f0e10c9428b34891b34fd310850705cc84a3ecd
- Subject: fix(claude): publish permission mode in session metadata
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 7
- Lines: +58 / -10
- Touched areas: cli(7)
- Topic bucket: `claude`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/types.ts
M	cli/src/claude/claudeLocalLauncher.ts
M	cli/src/claude/claudeRemoteLauncher.ts
M	cli/src/claude/loop.ts
M	cli/src/claude/runClaude.ts
M	cli/src/claude/session.ts
M	cli/src/claude/utils/permissionHandler.ts
```

### Diffstat

```text
 cli/src/api/types.ts                      |  9 +++++++-
 cli/src/claude/claudeLocalLauncher.ts     |  2 +-
 cli/src/claude/claudeRemoteLauncher.ts    |  2 --
 cli/src/claude/loop.ts                    |  5 ++---
 cli/src/claude/runClaude.ts               | 35 ++++++++++++++++++++++++++++++-
 cli/src/claude/session.ts                 | 11 ++++++++++
 cli/src/claude/utils/permissionHandler.ts |  4 ++--
 7 files changed, 58 insertions(+), 10 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): publish permission mode in session metadata
- Key files by churn (top 7):
  - cli/src/claude/runClaude.ts: +34/-1 | adds const arg, const initialPermissionMode, const input, const next, function inferPermissionModeFromClaudeArgs | touches export async function runClaude(credentials: Credentials, options: StartOptions; export interface StartOptions {
  - cli/src/claude/session.ts: +11/-0 | touches export class Session {
  - cli/src/api/types.ts: +8/-1 | touches export type Metadata = {
  - cli/src/claude/loop.ts: +2/-3 | touches export async function loop(opts: LoopOptions) {
  - cli/src/claude/utils/permissionHandler.ts: +2/-2 | touches export class PermissionHandler {
  - cli/src/claude/claudeRemoteLauncher.ts: +0/-2 | touches export async function claudeRemoteLauncher(session: Session): Promise<'switch' |
  - cli/src/claude/claudeLocalLauncher.ts: +1/-1 | touches export async function claudeLocalLauncher(session: Session): Promise<'switch' |

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): publish permission mode in session metadata`

### Topic Bucket

- `claude`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 126 2026-01-13 ffad20faa406

- SHA: ffad20faa406d5aebcd284649a0cc925d09fc7a2
- Subject: fix(cli): publish permission mode for codex/gemini sessions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +129 / -30
- Touched areas: cli(5)
- Topic bucket: `cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/types.ts
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
M	cli/src/index.ts
M	cli/src/utils/createSessionMetadata.ts
```

### Diffstat

```text
 cli/src/api/types.ts                   | 44 +++++++++++++++++++++--
 cli/src/codex/runCodex.ts              | 12 ++++++-
 cli/src/gemini/runGemini.ts            | 27 ++++++++------
 cli/src/index.ts                       | 66 ++++++++++++++++++++++++++--------
 cli/src/utils/createSessionMetadata.ts | 10 ++++--
 5 files changed, 129 insertions(+), 30 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): publish permission mode for codex/gemini sessions
- Key files by churn (top 5):
  - cli/src/index.ts: +52/-14 | adds const arg, const parseSessionStartArgs, const value | touches import { handleAttachCommand } from '@/commands/attach'
  - cli/src/api/types.ts: +41/-3 | adds const CLAUDE_ONLY_PERMISSION_MODES, const CODEX_GEMINI_NON_DEFAULT_PERMISSION_MODES, const CODEX_GEMINI_PERMISSION_MODES, const CODEX_PERMISSION_MODES, const PERMISSION_MODES, function isCodexGeminiPermissionMode | removes type PermissionMode | touches export const MessageMetaSchema = z.object({; import { UsageSchema } from '@/claude/types'
  - cli/src/gemini/runGemini.ts: +17/-10 | touches export async function runGemini(opts: {; import type { GeminiMode, CodexMessagePayload } from '@/gemini/types';
  - cli/src/codex/runCodex.ts: +11/-1 | adds const initialPermissionMode | touches export async function runCodex(opts: {
  - cli/src/utils/createSessionMetadata.ts: +8/-2 | touches export function createSessionMetadata(opts: CreateSessionMetadataOptions): Sessi; export interface CreateSessionMetadataOptions {; import { resolve } from 'node:path';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): publish permission mode for codex/gemini sessions`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 127 2026-01-13 eb72c6e69434

- SHA: eb72c6e694344ce79523ac36e715348753303bd8
- Subject: fix(codex): disable model override and remove experimental resume
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +13 / -96
- Touched areas: cli(1)
- Topic bucket: `codex`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/runCodex.ts
```

### Diffstat

```text
 cli/src/codex/runCodex.ts | 109 ++++++----------------------------------------
 1 file changed, 13 insertions(+), 96 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): disable model override and remove experimental resume
- Key files by churn (top 1):
  - cli/src/codex/runCodex.ts: +13/-96 | removes const abortResumeFile, const candidates, const codexHomeDir, const full | touches export async function runCodex(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): disable model override and remove experimental resume`

### Topic Bucket

- `codex`

### Notes / Follow-ups


---

## 128 2026-01-21 d317f6bfa282

- SHA: d317f6bfa28274763cce5fcfe346ed4c066cfdc6
- Subject: fix(typecheck): resolve duplicate terminalRuntime and RPC handler types
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +1 / -4
- Touched areas: cli(3)
- Topic bucket: `typecheck`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.spawnSession.test.ts
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.spawnSession.test.ts | 3 +--
 cli/src/codex/runCodex.ts                   | 1 -
 cli/src/gemini/runGemini.ts                 | 1 -
 3 files changed, 1 insertion(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(typecheck): resolve duplicate terminalRuntime and RPC handler types
- Key files by churn (top 3):
  - cli/src/api/apiMachine.spawnSession.test.ts: +1/-2 | touches describe('ApiMachineClient spawn-happy-session handler', () => {
  - cli/src/gemini/runGemini.ts: +0/-1 | touches export async function runGemini(opts: {
  - cli/src/codex/runCodex.ts: +0/-1 | touches export async function runCodex(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(typecheck): resolve duplicate terminalRuntime and RPC handler types`

### Topic Bucket

- `typecheck`

### Notes / Follow-ups


---

## 129 2026-01-21 a8682d427794

- SHA: a8682d427794ddcd9b0ea151b59d9529e3a3b25d
- Subject: fix(detect-cli): relax tmux version probe timeout
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: cli(1)
- Topic bucket: `detect-cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(detect-cli): relax tmux version probe timeout
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.ts: +1/-1 | adds const timeoutMs | removes const timeoutMs | touches async function detectTmuxVersion(params: { resolvedPath: string }): Promise<stri

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(detect-cli): relax tmux version probe timeout`

### Topic Bucket

- `detect-cli`

### Notes / Follow-ups


---

## 130 2026-01-07 e2824dbc858b

- SHA: e2824dbc858baa37f0f375efc8af460eba9d3ea7
- Subject: feat(queue): add server-side pending message pull support
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +58 / -8
- Touched areas: cli(5)
- Topic bucket: `queue`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiSession.ts
M	cli/src/api/types.ts
M	cli/src/claude/claudeRemoteLauncher.ts
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
```

### Diffstat

```text
 cli/src/api/apiSession.ts              | 20 ++++++++++++++++++++
 cli/src/api/types.ts                   | 10 ++++++++++
 cli/src/claude/claudeRemoteLauncher.ts |  7 +++++++
 cli/src/codex/runCodex.ts              | 19 +++++++++++++------
 cli/src/gemini/runGemini.ts            | 10 ++++++++--
 5 files changed, 58 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(queue): add server-side pending message pull support
- Key files by churn (top 5):
  - cli/src/api/apiSession.ts: +20/-0 | adds const result | touches export class ApiSessionClient extends EventEmitter {
  - cli/src/codex/runCodex.ts: +13/-6 | adds const popped | touches export async function runCodex(opts: {
  - cli/src/gemini/runGemini.ts: +8/-2 | adds const popped | touches export async function runGemini(opts: {
  - cli/src/api/types.ts: +10/-0 | touches export interface ClientToServerEvents {; export type Metadata = {
  - cli/src/claude/claudeRemoteLauncher.ts: +7/-0 | touches export async function claudeRemoteLauncher(session: Session): Promise<'switch' |

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(queue): add server-side pending message pull support`

### Topic Bucket

- `queue`

### Notes / Follow-ups


---

## 131 2026-01-12 37a2c55a6c2f

- SHA: 37a2c55a6c2f10186a3f208b857931d3a9073370
- Subject: fix(session): prime agent state for readiness
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +20 / -0
- Touched areas: cli(2)
- Topic bucket: `session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
```

### Diffstat

```text
 cli/src/codex/runCodex.ts   | 10 ++++++++++
 cli/src/gemini/runGemini.ts | 10 ++++++++++
 2 files changed, 20 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(session): prime agent state for readiness
- Key files by churn (top 2):
  - cli/src/gemini/runGemini.ts: +10/-0 | touches export async function runGemini(opts: {
  - cli/src/codex/runCodex.ts: +10/-0 | touches export async function runCodex(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(session): prime agent state for readiness`

### Topic Bucket

- `session`

### Notes / Follow-ups


---

## 132 2026-01-21 88494b122194

- SHA: 88494b122194e4482ea817fad9c655c83b61a9e7
- Subject: fix(tools): support Windows arm64 tool unpacking
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +70 / -6
- Touched areas: cli(6)
- Topic bucket: `tools`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/scripts/__tests__/ripgrep_launcher.test.ts
A	cli/scripts/__tests__/unpack-tools.test.ts
M	cli/scripts/ripgrep_launcher.cjs
M	cli/scripts/unpack-tools.cjs
M	cli/src/test-setup.ts
M	cli/vitest.config.ts
```

### Diffstat

```text
 cli/scripts/__tests__/ripgrep_launcher.test.ts |  7 ++++++
 cli/scripts/__tests__/unpack-tools.test.ts     | 17 +++++++++++++
 cli/scripts/ripgrep_launcher.cjs               |  3 ++-
 cli/scripts/unpack-tools.cjs                   |  6 ++++-
 cli/src/test-setup.ts                          | 35 ++++++++++++++++++++++++++
 cli/vitest.config.ts                           |  8 +++---
 6 files changed, 70 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tools): support Windows arm64 tool unpacking
- Key files by churn (top 6):
  - cli/src/test-setup.ts: +35/-0 | adds const claudeConfigDir, const configuredClaudeConfigDir, const configuredHappyHomeDir, const ensureWritableDir, const expandHome, const fallbackBaseDir | touches export function setup() {; import { spawnSync } from 'node:child_process'
  - cli/scripts/__tests__/unpack-tools.test.ts: +17/-0 | adds const os | touches @@ -0,0 +1,17 @@
  - cli/vitest.config.ts: +4/-4 | touches const testEnv = dotenv.config({; export default defineConfig({
  - cli/scripts/__tests__/ripgrep_launcher.test.ts: +7/-0 | adds const content | touches describe('Ripgrep Launcher Runtime Compatibility', () => {
  - cli/scripts/unpack-tools.cjs: +5/-1 | touches function getPlatformDir() {; if (require.main === module) {
  - cli/scripts/ripgrep_launcher.cjs: +2/-1 | adds const binaryName, const binaryPath | removes const binaryPath | touches function loadRipgrepNative() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tools): support Windows arm64 tool unpacking`

### Topic Bucket

- `tools`

### Notes / Follow-ups


---

## 133 2026-01-09 d71587eda2db

- SHA: d71587eda2dbe089330ecd07f40a27d669fd831e
- Subject: feat: resume Claude sessions from UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +83 / -41
- Touched areas: cli(4)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
Plumbs an optional resume session id through spawn RPC and passes --resume to Claude when starting a daemon session.
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/daemon/run.ts
M	cli/src/modules/common/registerCommonHandlers.ts
A	cli/src/utils/agentCapabilities.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts                        |  5 +-
 cli/src/daemon/run.ts                            | 94 ++++++++++++++----------
 cli/src/modules/common/registerCommonHandlers.ts |  7 ++
 cli/src/utils/agentCapabilities.ts               | 18 +++++
 4 files changed, 83 insertions(+), 41 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat: resume Claude sessions from UI
- Key files by churn (top 4):
  - cli/src/daemon/run.ts: +55/-39 | adds const args, const envKeys, const normalizedResume, const reason, const spawnSession | removes const args, const envKeys, const reason, const spawnSession | touches export async function startDaemon(): Promise<void> {; import { writeDaemonState, DaemonLocallyPersistedState, readDaemonState, acquire
  - cli/src/utils/agentCapabilities.ts: +18/-0 | adds const VENDOR_RESUME_SUPPORTED_AGENTS, function supportsVendorResume, type AgentType | touches @@ -0,0 +1,18 @@
  - cli/src/modules/common/registerCommonHandlers.ts: +7/-0 | touches export interface SpawnSessionOptions {
  - cli/src/api/apiMachine.ts: +3/-2 | adds const result | removes const result | touches export class ApiMachineClient {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat: resume Claude sessions from UI`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 134 2026-01-11 a80868aff50d

- SHA: a80868aff50d9c685cf35a03de73d7abef1537c2
- Subject: feat: resume inactive Claude sessions from UI
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 7
- Lines: +253 / -69
- Touched areas: cli(7)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
Add CLI support for resuming inactive Claude sessions from the UI.
When the UI sends a resume-session RPC, the daemon spawns a new CLI
process that reconnects to the existing Happy session instead of
creating a new one.

Changes:
- Add RESUMABLE_AGENTS config for dynamic agent resume capability
- Add --existing-session flag to reconnect to existing Happy session
- Handle resume-session RPC type in apiMachine
- Pass HAPPY_INITIAL_MESSAGE env var for the resume message
- Update runClaude to reconnect to existing session when specified

The CLI uses the existing Claude session ID to resume the conversation
via claude --resume, and updates the session metadata to reflect the
resumed state.
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/claude/runClaude.ts
A	cli/src/daemon/persistedHappySession.ts
M	cli/src/daemon/run.ts
M	cli/src/index.ts
M	cli/src/modules/common/registerCommonHandlers.ts
M	cli/src/utils/agentCapabilities.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts                        |  32 +++++
 cli/src/claude/runClaude.ts                      | 159 +++++++++++++++--------
 cli/src/daemon/persistedHappySession.ts          |  85 ++++++++++++
 cli/src/daemon/run.ts                            |  24 ++--
 cli/src/index.ts                                 |   3 +
 cli/src/modules/common/registerCommonHandlers.ts |  18 ++-
 cli/src/utils/agentCapabilities.ts               |   1 -
 7 files changed, 253 insertions(+), 69 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat: resume inactive Claude sessions from UI
- Key files by churn (top 7):
  - cli/src/claude/runClaude.ts: +103/-56 | adds const abortController, const abortOnSignal, const attached, const initialMessage, const reconnection, const resp | removes const abortController, const abortOnSignal, const reconnection, const resp | touches export async function runClaude(credentials: Credentials, options: StartOptions; export interface StartOptions {; import { buildTerminalFallbackMessage } from '@/terminal/terminalFallbackMessage; import { loop } from '@/claude/loop';
  - cli/src/daemon/persistedHappySession.ts: +85/-0 | adds const PersistedHappySessionSchema, const filePath, const now, const parsed, const persisted, const raw | touches @@ -0,0 +1,85 @@
  - cli/src/api/apiMachine.ts: +32/-0 | adds const result | touches export class ApiMachineClient {
  - cli/src/daemon/run.ts: +16/-8 | adds const extraEnvForChildWithMessage, const normalizedExistingSessionId, const sessionDesc | removes const sessionDesc | touches export async function startDaemon(): Promise<void> {
  - cli/src/modules/common/registerCommonHandlers.ts: +14/-4 | touches export interface SpawnSessionOptions {; export type SpawnSessionResult =
  - cli/src/index.ts: +3/-0 | touches ${chalk.bold('To clean up runaway processes:')} Use ${chalk.cyan('happy doctor c
  - cli/src/utils/agentCapabilities.ts: +0/-1 | touches export function supportsVendorResume(agent: AgentType | undefined): boolean {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat: resume inactive Claude sessions from UI`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 135 2026-01-12 bcaa530b12d7

- SHA: bcaa530b12d7f351db4e5865c85e54b4f08d693b
- Subject: feat(resume): add happy resume and persist vendor resume id
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +98 / -27
- Touched areas: cli(3)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
- Persist Claude vendor resume id to $HAPPY_HOME_DIR/sessions/<sessionId>.json when discovered via SessionStart hook

- Add `happy resume <happySessionId>` to respawn a worker attached to the same Happy session (uses --existing-session + --resume)

- Keep behavior safe: fail fast when resume is requested for unsupported agents
```

### Files (name-status)

```text
M	cli/src/claude/session.ts
M	cli/src/daemon/persistedHappySession.ts
M	cli/src/index.ts
```

### Diffstat

```text
 cli/src/claude/session.ts               |  5 +++
 cli/src/daemon/persistedHappySession.ts | 46 ++++++++++++++------
 cli/src/index.ts                        | 74 ++++++++++++++++++++++++++-------
 3 files changed, 98 insertions(+), 27 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(resume): add happy resume and persist vendor resume id
- Key files by churn (top 3):
  - cli/src/index.ts: +60/-14 | adds const child, const cwd, const flavor, const happySessionId, const persisted, const spawnArgs | touches ${chalk.bold('Usage:')}; import { CODEX_GEMINI_PERMISSION_MODES, CODEX_PERMISSION_MODES, PERMISSION_MODES
  - cli/src/daemon/persistedHappySession.ts: +33/-13 | adds const current, const filePath, const persisted, function readPersistedHappySession, function readPersistedHappySessionFile, function updatePersistedHappySessionVendorResumeId | removes const persisted, function readPersistedHappySession | touches const PersistedHappySessionSchema = z.object({; export async function readPersistedHappySession(sessionId: string): Promise<Sess; export async function writePersistedHappySession(session: Session): Promise<void
  - cli/src/claude/session.ts: +5/-0 | touches export class Session {; import type { PermissionMode } from "@/api/types";

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(resume): add happy resume and persist vendor resume id`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 136 2026-01-12 e085e75c5d36

- SHA: e085e75c5d3695ec93c986c5e30a547e74e4489d
- Subject: feat(resume): allow resume-session without agentSessionId
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +83 / -64
- Touched areas: cli(3)
- Topic bucket: `resume`
- Manual review needed: no

### Commit Message Body

```text
- UI/daemon can resume with only Happy session id; daemon derives latest vendor resume id from local persisted session state

- `happy resume <id...>` now supports resuming multiple sessions for bulk recovery
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/daemon/run.ts
M	cli/src/index.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts |   5 +--
 cli/src/daemon/run.ts     |  31 +++++++++----
 cli/src/index.ts          | 111 +++++++++++++++++++++++++---------------------
 3 files changed, 83 insertions(+), 64 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(resume): allow resume-session without agentSessionId
- Key files by churn (top 3):
  - cli/src/index.ts: +60/-51 | adds const child, const cwd, const flavor, const happySessionIds, const persisted, const spawnArgs | removes const child, const cwd, const flavor, const happySessionId | touches import { supportsVendorResume, type AgentType } from './utils/agentCapabilities'
  - cli/src/daemon/run.ts: +22/-9 | adds const next, const persisted, const sessionDesc | removes const sessionDesc | touches export async function startDaemon(): Promise<void> {; import { supportsVendorResume } from '@/utils/agentCapabilities';
  - cli/src/api/apiMachine.ts: +1/-4 | touches export class ApiMachineClient {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(resume): allow resume-session without agentSessionId`

### Topic Bucket

- `resume`

### Notes / Follow-ups


---

## 137 2026-01-12 68a6ba4bc244

- SHA: 68a6ba4bc244452b1d297af0fcc38f1abe33f3bf
- Subject: feat(fork): enable Codex inactive-session resume via codex-reply
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +224 / -73
- Touched areas: cli(6)
- Topic bucket: `fork`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
- Enable Codex in vendor resume capability gating

- Parse --existing-session/--resume for codex and attach to persisted Happy session

- Resume Codex via MCP tool codex-reply (no transcript scanning)

- Persist codexSessionId for future resumes
```

### Files (name-status)

```text
M	cli/src/codex/codexMcpClient.ts
M	cli/src/codex/runCodex.ts
M	cli/src/daemon/persistedHappySession.ts
M	cli/src/daemon/run.ts
M	cli/src/index.ts
M	cli/src/utils/agentCapabilities.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.ts         |  11 ++
 cli/src/codex/runCodex.ts               | 248 +++++++++++++++++++++++---------
 cli/src/daemon/persistedHappySession.ts |   9 +-
 cli/src/daemon/run.ts                   |   4 +-
 cli/src/index.ts                        |  20 ++-
 cli/src/utils/agentCapabilities.ts      |   5 +-
 6 files changed, 224 insertions(+), 73 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(fork): enable Codex inactive-session resume via codex-reply
- Key files by churn (top 6):
  - cli/src/codex/runCodex.ts: +182/-66 | adds const attached, const existingId, const fallbackMessage, const initialMessage, const nextId, const offline | removes const fallbackMessage, const response, const result, const startError | touches export async function runCodex(opts: {; import { buildTerminalFallbackMessage } from '@/terminal/terminalFallbackMessage; import { createSessionMetadata } from '@/utils/createSessionMetadata';
  - cli/src/index.ts: +17/-3 | adds const existingSessionId, const idx, const readFlagValue, const resume, const value, const vendorResumeId | removes const vendorResumeId | touches import { supportsVendorResume, type AgentType } from './utils/agentCapabilities'
  - cli/src/codex/codexMcpClient.ts: +11/-0 | touches export class CodexMcpClient {
  - cli/src/daemon/persistedHappySession.ts: +8/-1 | adds const flavor, const vendorResumeId | touches export async function writePersistedHappySession(session: Session): Promise<void
  - cli/src/utils/agentCapabilities.ts: +4/-1 | adds const VENDOR_RESUME_SUPPORTED_AGENTS | removes const VENDOR_RESUME_SUPPORTED_AGENTS | touches export type AgentType = 'claude' | 'codex' | 'gemini';
  - cli/src/daemon/run.ts: +2/-2 | touches export async function startDaemon(): Promise<void> {; import { readPersistedHappySessionFile } from './persistedHappySession';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(fork): enable Codex inactive-session resume via codex-reply`

### Topic Bucket

- `fork`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 138 2026-01-22 d3aefaa9b598

- SHA: d3aefaa9b598a0cbe3a28eaddc86041b35cb3014
- Subject: refactor(daemon): extract reattach and pid safety helpers
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +86 / -64
- Touched areas: cli(3)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/daemon/pidSafety.ts
A	cli/src/daemon/reattach.ts
M	cli/src/daemon/run.ts
```

### Diffstat

```text
 cli/src/daemon/pidSafety.ts | 25 +++++++++++++++
 cli/src/daemon/reattach.ts  | 50 ++++++++++++++++++++++++++++++
 cli/src/daemon/run.ts       | 75 +++++++--------------------------------------
 3 files changed, 86 insertions(+), 64 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(daemon): extract reattach and pid safety helpers
- Key files by churn (top 3):
  - cli/src/daemon/run.ts: +11/-64 | adds const aliveMarkers, const safe | removes const ALLOWED_HAPPY_SESSION_PROCESS_TYPES, const currentHash, const happyPidToCommandHash, const happyPidToType | touches async function getPreferredHostName(): Promise<string> {; export async function startDaemon(): Promise<void> {; import { hashProcessCommand, listSessionMarkers, removeSessionMarker, writeSessi
  - cli/src/daemon/reattach.ts: +50/-0 | adds const currentHash, const happyPidToCommandHash, const happyPidToType, const procType, function adoptSessionsFromMarkers | touches @@ -0,0 +1,50 @@
  - cli/src/daemon/pidSafety.ts: +25/-0 | adds const ALLOWED_HAPPY_SESSION_PROCESS_TYPES, const proc, function isPidSafeHappySessionProcess | touches @@ -0,0 +1,25 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(daemon): extract reattach and pid safety helpers`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 139 2026-01-22 72397b7e8c94

- SHA: 72397b7e8c94b466d4883f5a5f106d8a943e01a1
- Subject: test(daemon): add opt-in reattach integration tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +238 / -0
- Touched areas: cli(2)
- Topic bucket: `daemon`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/daemon/pidSafety.real.integration.test.ts
A	cli/src/daemon/reattach.real.integration.test.ts
```

### Diffstat

```text
 cli/src/daemon/pidSafety.real.integration.test.ts |  83 ++++++++++++
 cli/src/daemon/reattach.real.integration.test.ts  | 155 ++++++++++++++++++++++
 2 files changed, 238 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): test(daemon): add opt-in reattach integration tests
- Key files by churn (top 2):
  - cli/src/daemon/reattach.real.integration.test.ts: +155/-0 | adds const child, const happyProcesses, const home, const map, const markers, const originalHappyHomeDir | touches @@ -0,0 +1,155 @@
  - cli/src/daemon/pidSafety.real.integration.test.ts: +83/-0 | adds const child, const expected, const p, const proc, const start, const wrong | touches @@ -0,0 +1,83 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(daemon): add opt-in reattach integration tests`

### Topic Bucket

- `daemon`

### Notes / Follow-ups


---

## 140 2026-01-22 9c40c54018c2

- SHA: 9c40c54018c2e9d7ceb4741da8f15bddded1caf2
- Subject: Revert "fix(tools): support Windows arm64 tool unpacking"
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +6 / -70
- Touched areas: cli(6)
- Topic bucket: `cli`
- Manual review needed: YES (non-Conventional-Commits subject; revert commit)

### Commit Message Body

```text
This reverts commit 88494b122194e4482ea817fad9c655c83b61a9e7.
```

### Files (name-status)

```text
M	cli/scripts/__tests__/ripgrep_launcher.test.ts
D	cli/scripts/__tests__/unpack-tools.test.ts
M	cli/scripts/ripgrep_launcher.cjs
M	cli/scripts/unpack-tools.cjs
M	cli/src/test-setup.ts
M	cli/vitest.config.ts
```

### Diffstat

```text
 cli/scripts/__tests__/ripgrep_launcher.test.ts |  7 ------
 cli/scripts/__tests__/unpack-tools.test.ts     | 17 -------------
 cli/scripts/ripgrep_launcher.cjs               |  3 +--
 cli/scripts/unpack-tools.cjs                   |  6 +----
 cli/src/test-setup.ts                          | 35 --------------------------
 cli/vitest.config.ts                           |  8 +++---
 6 files changed, 6 insertions(+), 70 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Revert "fix(tools): support Windows arm64 tool unpacking"
- Key files by churn (top 6):
  - cli/src/test-setup.ts: +0/-35 | removes const claudeConfigDir, const configuredClaudeConfigDir, const configuredHappyHomeDir, const ensureWritableDir | touches export function setup() {; import { spawnSync } from 'node:child_process'
  - cli/scripts/__tests__/unpack-tools.test.ts: +0/-17 | removes const os | touches @@ -1,17 +0,0 @@
  - cli/vitest.config.ts: +4/-4 | touches const testEnv = dotenv.config({; export default defineConfig({
  - cli/scripts/__tests__/ripgrep_launcher.test.ts: +0/-7 | removes const content | touches describe('Ripgrep Launcher Runtime Compatibility', () => {
  - cli/scripts/unpack-tools.cjs: +1/-5 | touches function getPlatformDir() {; if (require.main === module) {
  - cli/scripts/ripgrep_launcher.cjs: +1/-2 | adds const binaryPath | removes const binaryName, const binaryPath | touches function loadRipgrepNative() {

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(cli): revert "fix(tools): support Windows arm64 tool unpacking"`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Revert commit: consider whether to keep as-is, or drop if rewrite uses a clean pick of the final intended state.
- Manual review: required before squashing/reordering.

---

## 141 2026-01-22 ab35b47ff699

- SHA: ab35b47ff69959457418cb23836e670961f8bf34
- Subject: fix(resume): make inactive resume reliable; gate Codex resume
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 17
- Lines: +483 / -89
- Touched areas: expo-app(9), cli(8)
- Topic bucket: `resume`
- Manual review needed: YES (multiple major areas: cli, expo-app; safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.ts
M	cli/src/claude/runClaude.ts
M	cli/src/codex/codexMcpClient.ts
M	cli/src/codex/runCodex.ts
M	cli/src/daemon/run.ts
M	cli/src/modules/common/registerCommonHandlers.ts
A	cli/src/utils/agentCapabilities.test.ts
M	cli/src/utils/agentCapabilities.ts
M	expo-app/INACTIVE_SESSION_RESUME.md
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/spawnSessionPayload.ts
M	expo-app/sources/utils/agentCapabilities.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.ts                        |  11 +-
 cli/src/claude/runClaude.ts                      |  16 ---
 cli/src/codex/codexMcpClient.ts                  |  18 +--
 cli/src/codex/runCodex.ts                        |  35 ++++--
 cli/src/daemon/run.ts                            |  11 +-
 cli/src/modules/common/registerCommonHandlers.ts | 144 ++++++++++++++++++++++-
 cli/src/utils/agentCapabilities.test.ts          |  34 ++++++
 cli/src/utils/agentCapabilities.ts               |  18 ++-
 expo-app/INACTIVE_SESSION_RESUME.md              |  12 +-
 expo-app/sources/-session/SessionView.tsx        |  29 ++++-
 expo-app/sources/app/(app)/machine/[id].tsx      | 139 +++++++++++++++++++++-
 expo-app/sources/app/(app)/new/index.tsx         |  14 ++-
 expo-app/sources/app/(app)/session/[id]/info.tsx |   6 +-
 expo-app/sources/sync/ops.ts                     |  43 ++++++-
 expo-app/sources/sync/settings.ts                |   6 +
 expo-app/sources/sync/spawnSessionPayload.ts     |   9 +-
 expo-app/sources/utils/agentCapabilities.ts      |  27 ++++-
 17 files changed, 483 insertions(+), 89 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(resume): make inactive resume reliable; gate Codex resume
- Key files by churn (top 8):
  - cli/src/modules/common/registerCommonHandlers.ts: +139/-5 | adds const binName, const binPath, const codexResumeBinPath, const codexResumeInstallDir, const codexResumeStatePath, const installDir | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; export interface SpawnSessionOptions {; import { expandEnvironmentVariables } from '@/utils/expandEnvVars';; import { promisify } from 'util';
  - expo-app/sources/app/(app)/machine/[id].tsx: +137/-2 | adds const entry, const expCodexResume, const experimentsEnabled, const next, const refreshCodexResumeStatus, const result | touches export default function MachineDetailScreen() {; import type { Session } from '@/sync/storageTypes';; import { useNavigateToSession } from '@/hooks/useNavigateToSession';
  - expo-app/sources/sync/ops.ts: +38/-5 | adds const result, function machineCodexResumeInstall, function machineCodexResumeStatus, type CodexResumeInstallResult, type CodexResumeStatus | touches export async function resumeSession(options: ResumeSessionOptions): Promise<Resu; export interface ResumeSessionOptions {
  - cli/src/codex/runCodex.ts: +24/-11 | adds const binName, const client, const codexCommand, const defaultPath, const fromEnv, const isVendorResumeRequested | removes const client, const initialMessage | touches export async function runCodex(opts: {; import { readPersistedHappySession, writePersistedHappySession, updatePersistedH; import { resolve, join } from 'node:path';
  - cli/src/utils/agentCapabilities.test.ts: +34/-0 | adds const prev | touches @@ -0,0 +1,34 @@
  - expo-app/sources/-session/SessionView.tsx: +23/-6 | adds const allowCodexResume, const expCodexResume, const handleResumeSession, const isResumable | removes const handleResumeSession, const isResumable | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import { storage, useIsDataReady, useLocalSetting, useRealtimeStatus, useSession
  - expo-app/sources/utils/agentCapabilities.ts: +22/-5 | adds const RESUMABLE_AGENTS, const agent, const agentSessionId, const field, function canAgentResume, function canResumeSessionWithOptions | removes const RESUMABLE_AGENTS, function canAgentResume | touches export const RESUMABLE_AGENTS: AgentType[] = [; export function canAgentResume(agent: string | null | undefined): boolean {; export function canResumeSession(metadata: SessionMetadata | null | undefined):; export type AgentType = 'claude' | 'codex' | 'gemini';
  - cli/src/utils/agentCapabilities.ts: +12/-6 | adds const VENDOR_RESUME_SUPPORTED_AGENTS, const raw, function isExperimentalCodexVendorResumeEnabled, function supportsVendorResume | removes const VENDOR_RESUME_SUPPORTED_AGENTS, function supportsVendorResume | touches export const VENDOR_RESUME_SUPPORTED_AGENTS: AgentType[] = [; export function supportsVendorResume(agent: AgentType | undefined): boolean {; export type AgentType = 'claude' | 'codex' | 'gemini';

### Message Quality

- Conventional Commits: yes
- Multi-area risk: touches cli, expo-app.
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely mixed: multiple major areas touched.

### Suggested Rewrite (Conventional Commit)

- `fix(resume): make inactive resume reliable; gate Codex resume`

### Topic Bucket

- `resume`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 142 2026-01-22 aa9b11684389

- SHA: aa9b1168438959ccab8afe2c4f7d7ee1409698eb
- Subject: fix(codex): increase installer output buffer
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: cli(1)
- Topic bucket: `codex`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): increase installer output buffer
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.ts: +1/-1 | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): increase installer output buffer`

### Topic Bucket

- `codex`

### Notes / Follow-ups


---

## 143 2026-01-22 c4beebbfa375

- SHA: c4beebbfa37580bf07b591774ccb7fa32c457caa
- Subject: feat(ui): add Codex resume experiment toggle
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 10
- Lines: +26 / -0
- Touched areas: expo-app(10)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx | 8 ++++++++
 expo-app/sources/text/translations/ca.ts         | 2 ++
 expo-app/sources/text/translations/en.ts         | 2 ++
 expo-app/sources/text/translations/es.ts         | 2 ++
 expo-app/sources/text/translations/it.ts         | 2 ++
 expo-app/sources/text/translations/ja.ts         | 2 ++
 expo-app/sources/text/translations/pl.ts         | 2 ++
 expo-app/sources/text/translations/pt.ts         | 2 ++
 expo-app/sources/text/translations/ru.ts         | 2 ++
 expo-app/sources/text/translations/zh-Hans.ts    | 2 ++
 10 files changed, 26 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(ui): add Codex resume experiment toggle
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/settings/features.tsx: +8/-0 | touches export default React.memo(function FeaturesSettingsScreen() {
  - expo-app/sources/text/translations/zh-Hans.ts: +2/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +2/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +2/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +2/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +2/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +2/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +2/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(ui): add Codex resume experiment toggle`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 144 2026-01-22 0140ae276869

- SHA: 0140ae2768696b961488e227c9f7586ef3a32b42
- Subject: refactor(codex): install mcp resume server via install-dep
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 5
- Lines: +211 / -89
- Touched areas: cli(3), expo-app(2)
- Topic bucket: `codex`
- Manual review needed: YES (multiple major areas: cli, expo-app; safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/codexMcpClient.ts
M	cli/src/codex/runCodex.ts
M	cli/src/modules/common/registerCommonHandlers.ts
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/settings.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.ts                  |  45 ++++--
 cli/src/codex/runCodex.ts                        |  37 +++--
 cli/src/modules/common/registerCommonHandlers.ts | 193 ++++++++++++++++-------
 expo-app/sources/sync/ops.ts                     |  23 ++-
 expo-app/sources/sync/settings.ts                |   2 +-
 5 files changed, 211 insertions(+), 89 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(codex): install mcp resume server via install-dep
- Key files by churn (top 5):
  - cli/src/modules/common/registerCommonHandlers.ts: +136/-57 | adds const DEFAULT_CODEX_MCP_RESUME_INSTALL_SPEC, const binName, const binPath, const codexResumeInstallDir, const codexResumeLegacyBinPath, const codexResumeLegacyInstallDir | removes const binName, const binPath, const codexResumeInstallDir, const installDir | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; type CodexResumeInstallResponse =
  - cli/src/codex/codexMcpClient.ts: +29/-16 | adds const mcpCommand, const transportArgs, type CodexMcpClientSpawnMode | removes const mcpCommand | touches const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1000; // 14 days, which is the half; export class CodexMcpClient {
  - cli/src/codex/runCodex.ts: +26/-11 | adds const binName, const client, const codexMcpServer, const defaultNew, const defaultOld, const envOverride | removes const binName, const client, const codexCommand, const defaultPath | touches export async function runCodex(opts: {
  - expo-app/sources/sync/ops.ts: +19/-4 | adds const result, function machineCodexResumeInstall, function machineInstallDep, type InstallDepId, type InstallDepResult | removes const result, function machineCodexResumeInstall | touches export async function machineCodexResumeInstall(machineId: string, options: { in; export type CodexResumeInstallResult =
  - expo-app/sources/sync/settings.ts: +1/-1 | touches export const settingsDefaults: Settings = {

### Message Quality

- Conventional Commits: yes
- Multi-area risk: touches cli, expo-app.
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely mixed: multiple major areas touched.

### Suggested Rewrite (Conventional Commit)

- `refactor(codex): install mcp resume server via install-dep`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 145 2026-01-22 2ec41b621b54

- SHA: 2ec41b621b54b67ca8ef42e8e9219ac4e0e37b22
- Subject: fix(codex): detect resume binary on Windows
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +4 / -3
- Touched areas: cli(1)
- Topic bucket: `codex`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): detect resume binary on Windows
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.ts: +4/-3 | adds const accessMode | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): detect resume binary on Windows`

### Topic Bucket

- `codex`

### Notes / Follow-ups


---

## 146 2026-01-22 e1deb6db8ddb

- SHA: e1deb6db8ddb001b3099dd68726871811142fb6b
- Subject: refactor(codex): add dep-status and drop codex-resume RPCs
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +125 / -83
- Touched areas: expo-app(2), cli(1)
- Topic bucket: `codex`
- Manual review needed: YES (multiple major areas: cli, expo-app)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.ts
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 cli/src/modules/common/registerCommonHandlers.ts | 122 +++++++++++++++--------
 expo-app/sources/app/(app)/machine/[id].tsx      |  46 ++++++---
 expo-app/sources/sync/ops.ts                     |  40 +++-----
 3 files changed, 125 insertions(+), 83 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(codex): add dep-status and drop codex-resume RPCs
- Key files by churn (top 3):
  - cli/src/modules/common/registerCommonHandlers.ts: +78/-44 | adds const CODEX_MCP_RESUME_DIST_TAG, const CODEX_MCP_RESUME_NPM_PACKAGE, const DEFAULT_CODEX_MCP_RESUME_INSTALL_SPEC, const dep, const extraHelp, const installDir | removes const DEFAULT_CODEX_MCP_RESUME_INSTALL_SPEC, const installSpecOverride, const result, const text | touches export function registerCommonHandlers(rpcHandlerManager: RpcHandlerManager, wor; interface DetectCliResponse {; type InstallDepResponse =
  - expo-app/sources/app/(app)/machine/[id].tsx: +32/-14 | adds const codexResumeUpdateAvailable, const installed, const latest, const result, const status | removes const result, const status | touches export default function MachineDetailScreen() {; import {
  - expo-app/sources/sync/ops.ts: +15/-25 | adds const result, function machineDepStatus, type DepStatus, type InstallDepId, type InstallDepResult | removes const result, function machineCodexResumeInstall, function machineCodexResumeStatus, type CodexResumeInstallResult | touches export async function machineCodexResumeStatus(machineId: string): Promise<Codex; export async function machineInstallDep(machineId: string, options: { dep: Insta; export async function resumeSession(options: ResumeSessionOptions): Promise<Resu; export type CodexResumeStatus = {

### Message Quality

- Conventional Commits: yes
- Multi-area risk: touches cli, expo-app.

### Unrelated Changes?

- Likely mixed: multiple major areas touched.

### Suggested Rewrite (Conventional Commit)

- `refactor(codex): add dep-status and drop codex-resume RPCs`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 147 2026-01-22 231d7ad9bdd9

- SHA: 231d7ad9bdd9403add470515830adaf8e8dab890
- Subject: fix(ui): clarify Codex resume server label
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: expo-app(1)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/machine/[id].tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/machine/[id].tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): clarify Codex resume server label
- Key files by churn (top 1):
  - expo-app/sources/app/(app)/machine/[id].tsx: +1/-1 | touches export default function MachineDetailScreen() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): clarify Codex resume server label`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 148 2026-01-22 8bebf04aca92

- SHA: 8bebf04aca9228e434a03760d2bdaea65d4a6740
- Subject: refactor(cli): modularize capabilities and env preview
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 18
- Lines: +1296 / -908
- Touched areas: cli(18)
- Topic bucket: `cli`
- Manual review needed: YES (diff summary skipped (large change (+1296/-908)); safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/modules/common/capabilities/caps/cliBase.ts
A	cli/src/modules/common/capabilities/caps/cliClaude.ts
A	cli/src/modules/common/capabilities/caps/cliCodex.ts
A	cli/src/modules/common/capabilities/caps/cliGemini.ts
A	cli/src/modules/common/capabilities/caps/depCodexMcpResume.ts
A	cli/src/modules/common/capabilities/caps/toolTmux.ts
A	cli/src/modules/common/capabilities/checklists.ts
A	cli/src/modules/common/capabilities/context/buildDetectContext.ts
A	cli/src/modules/common/capabilities/deps/codexMcpResume.ts
A	cli/src/modules/common/capabilities/errors.ts
A	cli/src/modules/common/capabilities/registerCapabilitiesHandlers.ts
A	cli/src/modules/common/capabilities/service.ts
A	cli/src/modules/common/capabilities/snapshots/cliSnapshot.ts
A	cli/src/modules/common/capabilities/types.ts
A	cli/src/modules/common/previewEnv/registerPreviewEnvHandler.ts
A	cli/src/modules/common/registerCommonHandlers.capabilities.test.ts
D	cli/src/modules/common/registerCommonHandlers.detectCli.test.ts
M	cli/src/modules/common/registerCommonHandlers.ts
```

### Diffstat

```text
 .../modules/common/capabilities/caps/cliBase.ts    |  21 +
 .../modules/common/capabilities/caps/cliClaude.ts  |  11 +
 .../modules/common/capabilities/caps/cliCodex.ts   |  11 +
 .../modules/common/capabilities/caps/cliGemini.ts  |  11 +
 .../common/capabilities/caps/depCodexMcpResume.ts  |  37 ++
 .../modules/common/capabilities/caps/toolTmux.ts   |   9 +
 cli/src/modules/common/capabilities/checklists.ts  |  23 +
 .../capabilities/context/buildDetectContext.ts     |  14 +
 .../common/capabilities/deps/codexMcpResume.ts     | 222 +++++++
 cli/src/modules/common/capabilities/errors.ts      |  10 +
 .../capabilities/registerCapabilitiesHandlers.ts   |  43 ++
 cli/src/modules/common/capabilities/service.ts     | 126 ++++
 .../common/capabilities/snapshots/cliSnapshot.ts   | 292 ++++++++
 cli/src/modules/common/capabilities/types.ts       |  54 ++
 .../common/previewEnv/registerPreviewEnvHandler.ts | 198 ++++++
 .../registerCommonHandlers.capabilities.test.ts    | 208 ++++++
 .../registerCommonHandlers.detectCli.test.ts       | 182 -----
 cli/src/modules/common/registerCommonHandlers.ts   | 732 +--------------------
 18 files changed, 1296 insertions(+), 908 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(cli): modularize capabilities and env preview
- Diff summary skipped: large change (+1296/-908).

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(cli): modularize capabilities and env preview`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 149 2026-01-22 bcf10af94626

- SHA: bcf10af946264798f626e32723b64a6a4073d585
- Subject: test(ui): update useCLIDetection hook tests for capabilities
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +23 / -27
- Touched areas: expo-app(1)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.hook.test.ts
```

### Diffstat

```text
 .../sources/hooks/useCLIDetection.hook.test.ts     | 50 ++++++++++------------
 1 file changed, 23 insertions(+), 27 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(ui): update useCLIDetection hook tests for capabilities
- Key files by churn (top 1):
  - expo-app/sources/hooks/useCLIDetection.hook.test.ts: +23/-27 | adds const useMachineCapabilitiesCacheMock | removes const useMachineDetectCliCacheMock | touches describe('useCLIDetection (hook)', () => {; import renderer, { act } from 'react-test-renderer';; vi.mock('@/hooks/useMachineDetectCliCache', () => {; vi.mock('@/utils/machineUtils', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(ui): update useCLIDetection hook tests for capabilities`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 150 2026-01-22 a5cac698f15b

- SHA: a5cac698f15bf874f4c51996be1ce321431639b7
- Subject: feat(cli): harden session queue, switching, and lifecycle
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 24
- Lines: +1429 / -84
- Touched areas: cli(24)
- Topic bucket: `cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
- Add metadata-backed messageQueueV1 pop/materialize path for pending messages\n- Preserve per-message localId so we can mark committed messages discarded\n- Prompt + discard policy for remote→local switching when remote backlog exists\n- Emit durable ACP task_started/task_complete edges for Claude and Codex\n- Add unit tests for queue pop, discard markers, and lifecycle events
```

### Files (name-status)

```text
M	cli/src/api/apiSession.test.ts
M	cli/src/api/apiSession.ts
A	cli/src/api/discardedCommittedMessageLocalIds.test.ts
A	cli/src/api/discardedCommittedMessageLocalIds.ts
A	cli/src/api/messageQueueV1.test.ts
A	cli/src/api/messageQueueV1.ts
M	cli/src/api/types.ts
M	cli/src/claude/claudeLocalLauncher.test.ts
M	cli/src/claude/claudeLocalLauncher.ts
M	cli/src/claude/claudeRemoteLauncher.ts
M	cli/src/claude/loop.ts
M	cli/src/claude/runClaude.ts
M	cli/src/claude/session.test.ts
M	cli/src/claude/session.ts
M	cli/src/codex/codexMcpClient.test.ts
M	cli/src/codex/runCodex.ts
A	cli/src/codex/utils/codexAcpLifecycle.test.ts
A	cli/src/codex/utils/codexAcpLifecycle.ts
M	cli/src/gemini/runGemini.ts
M	cli/src/test-setup.ts
A	cli/src/utils/createSessionMetadata.test.ts
M	cli/src/utils/createSessionMetadata.ts
A	cli/src/utils/waitForMessagesOrPending.test.ts
A	cli/src/utils/waitForMessagesOrPending.ts
```

### Diffstat

```text
 cli/src/api/apiSession.test.ts                     | 174 ++++++++++++-
 cli/src/api/apiSession.ts                          | 281 ++++++++++++++++++++-
 .../api/discardedCommittedMessageLocalIds.test.ts  |  25 ++
 cli/src/api/discardedCommittedMessageLocalIds.ts   |  31 +++
 cli/src/api/messageQueueV1.test.ts                 |  72 ++++++
 cli/src/api/messageQueueV1.ts                      | 206 +++++++++++++++
 cli/src/api/types.ts                               |  37 ++-
 cli/src/claude/claudeLocalLauncher.test.ts         | 138 +++++++++-
 cli/src/claude/claudeLocalLauncher.ts              | 104 +++++++-
 cli/src/claude/claudeRemoteLauncher.ts             |  56 ++--
 cli/src/claude/loop.ts                             |   5 +
 cli/src/claude/runClaude.ts                        |   3 +
 cli/src/claude/session.test.ts                     |  40 +++
 cli/src/claude/session.ts                          |  18 ++
 cli/src/codex/codexMcpClient.test.ts               |   6 +-
 cli/src/codex/runCodex.ts                          |  37 ++-
 cli/src/codex/utils/codexAcpLifecycle.test.ts      |  58 +++++
 cli/src/codex/utils/codexAcpLifecycle.ts           |  32 +++
 cli/src/gemini/runGemini.ts                        |  11 +-
 cli/src/test-setup.ts                              |  12 +-
 cli/src/utils/createSessionMetadata.test.ts        |  33 +++
 cli/src/utils/createSessionMetadata.ts             |   3 +
 cli/src/utils/waitForMessagesOrPending.test.ts     |  72 ++++++
 cli/src/utils/waitForMessagesOrPending.ts          |  59 +++++
 24 files changed, 1429 insertions(+), 84 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(cli): harden session queue, switching, and lifecycle
- Key files by churn (top 8):
  - cli/src/api/apiSession.ts: +272/-9 | adds const answer, const bodyWithLocalId, const claimed, const cleanup, const cleared, const current | removes const result, const userResult | touches export class ApiSessionClient extends EventEmitter {; import { registerCommonHandlers } from '../modules/common/registerCommonHandlers
  - cli/src/api/messageQueueV1.ts: +206/-0 | adds const MESSAGE_QUEUE_V1_RECLAIM_IN_FLIGHT_AFTER_MS, const ageMs, const claimedAt, const createdAt, const discarded, const discardedAt | touches @@ -0,0 +1,206 @@
  - cli/src/api/apiSession.test.ts: +170/-4 | adds const client, const emitWithAck, const encrypted, const metadataBase, const nextMetadata, const onUserMessage | touches describe('ApiSessionClient connection handling', () => {; import type { RawJSONLines } from '@/claude/types';
  - cli/src/claude/claudeLocalLauncher.test.ts: +126/-12 | adds const client, const result, const sendSessionEvent, const session | touches describe('claudeLocalLauncher', () => {; import { Session } from './session';
  - cli/src/claude/claudeLocalLauncher.ts: +101/-3 | adds const answer, const confirmed, const normalized, const preview, const question, const queued | touches export async function claudeLocalLauncher(session: Session): Promise<'switch' |; import { mapToClaudeMode } from "./utils/permissionMode";
  - cli/src/utils/waitForMessagesOrPending.test.ts: +72/-0 | adds const abortController, const onAbort, const popPendingMessage, const promise, const queue, const result | touches @@ -0,0 +1,72 @@
  - cli/src/api/messageQueueV1.test.ts: +72/-0 | adds const cleared, const input, const parsed, const result | touches @@ -0,0 +1,72 @@
  - cli/src/utils/waitForMessagesOrPending.ts: +59/-0 | adds const controller, const onAbort, const winner, function waitForMessagesOrPending, type MessageBatch | touches @@ -0,0 +1,59 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(cli): harden session queue, switching, and lifecycle`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 151 2026-01-22 3fc704424e8d

- SHA: 3fc704424e8da38264e7fc10227519121b572db3
- Subject: feat(app): add pending queue, discard markers, and capabilities
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 44
- Lines: +2248 / -957
- Touched areas: expo-app(44)
- Topic bucket: `app`
- Manual review needed: YES (diff summary skipped (too many files (44)))

### Commit Message Body

```text
- Replace broken pending-* socket events with encrypted messageQueueV1 in session metadata\n- Prefer queueing when agent not ready/offline/controlledByUser to avoid switch bounce\n- Render committed-but-discarded messages via metadata localId markers\n- Use durable lifecycle edges to drive thinking transitions (less reliance on volatile keepalive)\n- Refactor detect-cli plumbing into detect-capabilities cache/hook
```

### Files (name-status)

```text
M	expo-app/INACTIVE_SESSION_RESUME.md
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/__tests__/app/new/pick/machine.presentation.test.ts
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/components/MessageView.tsx
M	expo-app/sources/components/PendingMessagesModal.tsx
M	expo-app/sources/components/machine/DetectedClisList.tsx
M	expo-app/sources/components/machine/DetectedClisModal.tsx
M	expo-app/sources/components/newSession/MachineCliGlyphs.tsx
M	expo-app/sources/hooks/useCLIDetection.ts
A	expo-app/sources/hooks/useMachineCapabilitiesCache.ts
D	expo-app/sources/hooks/useMachineDetectCliCache.ts
M	expo-app/sources/sync/apiTypes.ts
A	expo-app/sources/sync/capabilitiesProtocol.ts
A	expo-app/sources/sync/controlledByUserTransitions.test.ts
A	expo-app/sources/sync/controlledByUserTransitions.ts
D	expo-app/sources/sync/detectCliResponse.test.ts
D	expo-app/sources/sync/detectCliResponse.ts
A	expo-app/sources/sync/messageQueueV1.test.ts
A	expo-app/sources/sync/messageQueueV1.ts
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/storage.ts
A	expo-app/sources/sync/storageTypes.discardedCommitted.test.ts
M	expo-app/sources/sync/storageTypes.ts
A	expo-app/sources/sync/submitMode.test.ts
A	expo-app/sources/sync/submitMode.ts
M	expo-app/sources/sync/sync.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
A	expo-app/sources/utils/discardedCommittedMessages.test.ts
A	expo-app/sources/utils/discardedCommittedMessages.ts
A	expo-app/sources/utils/sessionUtils.test.ts
M	expo-app/sources/utils/sessionUtils.ts
```

### Diffstat

```text
 expo-app/INACTIVE_SESSION_RESUME.md                |  26 +-
 expo-app/sources/-session/SessionView.tsx          |  17 +-
 .../app/new/pick/machine.presentation.test.ts      |   4 +-
 expo-app/sources/app/(app)/machine/[id].tsx        | 271 +++++++++-------
 .../sources/app/(app)/new/NewSessionWizard.tsx     |  87 +++++
 expo-app/sources/app/(app)/new/index.tsx           | 227 ++++++++++++-
 expo-app/sources/app/(app)/new/pick/machine.tsx    |   5 +-
 expo-app/sources/components/MessageView.tsx        |  18 +-
 .../sources/components/PendingMessagesModal.tsx    | 113 ++++++-
 .../components/machine/DetectedClisList.tsx        |  56 +++-
 .../components/machine/DetectedClisModal.tsx       |   6 +-
 .../components/newSession/MachineCliGlyphs.tsx     |  17 +-
 expo-app/sources/hooks/useCLIDetection.ts          | 253 +++++----------
 .../sources/hooks/useMachineCapabilitiesCache.ts   | 238 ++++++++++++++
 expo-app/sources/hooks/useMachineDetectCliCache.ts | 230 -------------
 expo-app/sources/sync/apiTypes.ts                  |   7 -
 expo-app/sources/sync/capabilitiesProtocol.ts      | 197 ++++++++++++
 .../sync/controlledByUserTransitions.test.ts       |  23 ++
 .../sources/sync/controlledByUserTransitions.ts    |   7 +
 expo-app/sources/sync/detectCliResponse.test.ts    |  62 ----
 expo-app/sources/sync/detectCliResponse.ts         |  70 ----
 expo-app/sources/sync/messageQueueV1.test.ts       | 139 ++++++++
 expo-app/sources/sync/messageQueueV1.ts            | 170 ++++++++++
 expo-app/sources/sync/ops.ts                       | 161 ++++++----
 expo-app/sources/sync/settings.spec.ts             |   2 +
 expo-app/sources/sync/storage.ts                   | 129 +++++++-
 .../sync/storageTypes.discardedCommitted.test.ts   |  15 +
 expo-app/sources/sync/storageTypes.ts              |  36 ++-
 expo-app/sources/sync/submitMode.test.ts           |  71 ++++
 expo-app/sources/sync/submitMode.ts                |  31 ++
 expo-app/sources/sync/sync.ts                      | 356 ++++++++++++---------
 expo-app/sources/text/translations/ca.ts           |   1 +
 expo-app/sources/text/translations/en.ts           |   1 +
 expo-app/sources/text/translations/es.ts           |   1 +
 expo-app/sources/text/translations/it.ts           |   1 +
 expo-app/sources/text/translations/ja.ts           |   1 +
 expo-app/sources/text/translations/pl.ts           |   1 +
 expo-app/sources/text/translations/pt.ts           |   1 +
 expo-app/sources/text/translations/ru.ts           |   1 +
 expo-app/sources/text/translations/zh-Hans.ts      |   1 +
 .../utils/discardedCommittedMessages.test.ts       |  21 ++
 .../sources/utils/discardedCommittedMessages.ts    |   8 +
 expo-app/sources/utils/sessionUtils.test.ts        |  82 +++++
 expo-app/sources/utils/sessionUtils.ts             |  41 ++-
 44 files changed, 2248 insertions(+), 957 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(app): add pending queue, discard markers, and capabilities
- Diff summary skipped: too many files (44).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(app): add pending queue, discard markers, and capabilities`

### Topic Bucket

- `app`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 152 2026-01-22 49893dd7d16a

- SHA: 49893dd7d16a82a90d41f8d43450d6e9099e9002
- Subject: fix(terminal): harden remote→local switching input
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 4
- Lines: +218 / -42
- Touched areas: cli(4)
- Topic bucket: `terminal`
- Manual review needed: no

### Commit Message Body

```text
Problem: users report terminal corruption / sluggish input after switching from remote→local, often after spamming space to trigger the switch.

Change:
- Add a pure keypress interpreter and support Ctrl+T as an immediate ‘switch to terminal’ shortcut (keeps double-space behavior).
- Add a small stdin cleanup helper to briefly drain buffered input after the Ink UI unmounts, then pause stdin.
- Add focused unit tests for key interpretation and stdin cleanup.

Why:
- Avoid leaving stdin in an unexpected state and prevent buffered ‘space spam’ from leaking into the next interactive process.

Refs: slopus/happy#301, slopus/happy-cli#124
```

### Files (name-status)

```text
A	cli/src/ui/ink/RemoteModeDisplay.test.ts
M	cli/src/ui/ink/RemoteModeDisplay.tsx
A	cli/src/utils/terminalStdinCleanup.test.ts
A	cli/src/utils/terminalStdinCleanup.ts
```

### Diffstat

```text
 cli/src/ui/ink/RemoteModeDisplay.test.ts   |  30 ++++++++
 cli/src/ui/ink/RemoteModeDisplay.tsx       | 113 ++++++++++++++++++-----------
 cli/src/utils/terminalStdinCleanup.test.ts |  60 +++++++++++++++
 cli/src/utils/terminalStdinCleanup.ts      |  57 +++++++++++++++
 4 files changed, 218 insertions(+), 42 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(terminal): harden remote→local switching input
- Key files by churn (top 4):
  - cli/src/ui/ink/RemoteModeDisplay.tsx: +71/-42 | adds const setConfirmationWithTimeout, function interpretRemoteModeKeypress, type RemoteModeActionInProgress, type RemoteModeConfirmation, type RemoteModeKeypressAction | removes const setConfirmationWithTimeout | touches export const RemoteModeDisplay: React.FC<RemoteModeDisplayProps> = ({ messageBuf; import { MessageBuffer, type BufferedMessage } from './messageBuffer'
  - cli/src/utils/terminalStdinCleanup.test.ts: +60/-0 | adds const api, const listeners, const promise, const set, const stdin, function createFakeStdin | touches @@ -0,0 +1,60 @@
  - cli/src/utils/terminalStdinCleanup.ts: +57/-0 | adds const drainListener, const drainMs, const stdin, function cleanupStdinAfterInk | touches @@ -0,0 +1,57 @@
  - cli/src/ui/ink/RemoteModeDisplay.test.ts: +30/-0 | adds const first, const result, const second | touches @@ -0,0 +1,30 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(terminal): harden remote→local switching input`

### Topic Bucket

- `terminal`

### Notes / Follow-ups


---

## 153 2026-01-22 0126667539b6

- SHA: 0126667539b67a34fc4aa8106d9647df8d135ff2
- Subject: fix(claude): forward signals to binary child process
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 2
- Lines: +78 / -2
- Touched areas: cli(2)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
Problem: when Claude is installed as a binary (e.g. Homebrew), the launcher can exit during mode switches but the Claude child may survive as an orphan and keep reading from inherited stdin, causing ‘competing processes’/terminal corruption symptoms.

Change:
- Add attachChildSignalForwarding() and use it in the binary-spawn path so SIGTERM/SIGINT (and SIGHUP on non-Windows) are forwarded to the child.
- Add a lightweight unit test that asserts which signals are registered and that the child receives forwarded kills.

Why:
- Ensures mode-switch termination actually terminates the process that owns stdin, preventing multiple readers.

Refs: slopus/happy#301, slopus/happy-cli#124
```

### Files (name-status)

```text
M	cli/scripts/claude_version_utils.cjs
A	cli/src/scripts/claude_version_utils.signalForwarding.test.ts
```

### Diffstat

```text
 cli/scripts/claude_version_utils.cjs               | 30 ++++++++++++-
 .../claude_version_utils.signalForwarding.test.ts  | 50 ++++++++++++++++++++++
 2 files changed, 78 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): forward signals to binary child process
- Key files by churn (top 2):
  - cli/src/scripts/claude_version_utils.signalForwarding.test.ts: +50/-0 | adds const child, const handlers, const list, const proc, const require | touches @@ -0,0 +1,50 @@
  - cli/scripts/claude_version_utils.cjs: +28/-2 | adds const forwardSignal, const signals, function attachChildSignalForwarding | touches function getClaudeCliPath() {; function runClaudeCli(cliPath) {; module.exports = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): forward signals to binary child process`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 154 2026-01-22 39c7b8a56b32

- SHA: 39c7b8a56b3221f64922ccb9116cdaa9f5826ade
- Subject: refactor(app): rename tmux/message-send settings under session
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 11
- Lines: +235 / -231
- Touched areas: expo-app(11)
- Topic bucket: `app`
- Manual review needed: no

### Commit Message Body

```text
- Rename terminal tmux settings keys to session* (and migrate old keys in settingsParse)\n- Rename messageSendMode to sessionMessageSendMode\n- Add unified Session settings screen combining message sending + tmux\n- Keep /settings/terminal and /settings/message-sending as aliases
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/settings/message-sending.tsx
A	expo-app/sources/app/(app)/settings/session.tsx
M	expo-app/sources/app/(app)/settings/terminal.tsx
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/sync.ts
M	expo-app/sources/sync/terminalSettings.spec.ts
M	expo-app/sources/sync/terminalSettings.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/machine/[id].tsx        |  10 +-
 expo-app/sources/app/(app)/new/index.tsx           |   4 +-
 .../sources/app/(app)/settings/message-sending.tsx |  57 +-------
 expo-app/sources/app/(app)/settings/session.tsx    | 153 +++++++++++++++++++++
 expo-app/sources/app/(app)/settings/terminal.tsx   | 117 +---------------
 expo-app/sources/components/SettingsView.tsx       |  14 +-
 expo-app/sources/sync/settings.spec.ts             |  12 +-
 expo-app/sources/sync/settings.ts                  |  55 ++++++--
 expo-app/sources/sync/sync.ts                      |   2 +-
 expo-app/sources/sync/terminalSettings.spec.ts     |  32 ++---
 expo-app/sources/sync/terminalSettings.ts          |  10 +-
 11 files changed, 235 insertions(+), 231 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(app): rename tmux/message-send settings under session
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/settings/session.tsx: +153/-0 | adds const styles, type MessageSendMode | touches @@ -0,0 +1,153 @@
  - expo-app/sources/app/(app)/settings/terminal.tsx: +1/-116 | removes const styles | touches @@ -1,116 +1 @@
  - expo-app/sources/app/(app)/settings/message-sending.tsx: +1/-56 | removes type MessageSendMode | touches @@ -1,56 +1 @@
  - expo-app/sources/sync/settings.ts: +41/-14 | adds const SessionTmuxMachineOverrideSchema, const parsed | removes const TerminalTmuxMachineOverrideSchema | touches export const SettingsSchema = z.object({; export const settingsDefaults: Settings = {; export function settingsParse(settings: unknown): Settings {; export type AIBackendProfile = z.infer<typeof AIBackendProfileSchema>;
  - expo-app/sources/sync/terminalSettings.spec.ts: +16/-16 | touches describe('resolveTerminalSpawnOptions', () => {
  - expo-app/sources/components/SettingsView.tsx: +4/-10 | adds const terminalUseTmux | removes const terminalUseTmux | touches export const SettingsView = React.memo(function SettingsView() {
  - expo-app/sources/sync/settings.spec.ts: +6/-6 | touches describe('settings', () => {
  - expo-app/sources/sync/terminalSettings.ts: +5/-5 | adds const isolated, const override, const useTmux | removes const isolated, const override, const useTmux | touches export function resolveTerminalSpawnOptions(params: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(app): rename tmux/message-send settings under session`

### Topic Bucket

- `app`

### Notes / Follow-ups


---

## 155 2026-01-22 fcec6c311b6b

- SHA: fcec6c311b6bc9e71b38fcf7713fb07af4a8b820
- Subject: feat(sync): add cross-device unread markers
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +187 / -41
- Touched areas: expo-app(6)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
Store read markers in encrypted session metadata (readStateV1) so unread state syncs across devices without relying on local MMKV.\n\nUnread is computed from session.seq + pending queue activity timestamps, and SessionView marks the session as viewed on focus and when new activity arrives while focused (debounced).\n\nAdds computeHasUnreadActivity tests and updates useHasUnreadMessages to use metadata instead of message lists.
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/sync.ts
M	expo-app/sources/sync/unread.test.ts
M	expo-app/sources/sync/unread.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx | 46 +++++++++++++++++++-
 expo-app/sources/sync/storage.ts          | 15 +++++--
 expo-app/sources/sync/storageTypes.ts     |  6 +++
 expo-app/sources/sync/sync.ts             | 29 +++++++++++++
 expo-app/sources/sync/unread.test.ts      | 72 +++++++++++++++++++++----------
 expo-app/sources/sync/unread.ts           | 60 ++++++++++++++++++++------
 6 files changed, 187 insertions(+), 41 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(sync): add cross-device unread markers
- Key files by churn (top 6):
  - expo-app/sources/sync/unread.test.ts: +49/-23 | touches describe('hasUnreadMessages', () => {; import { describe, expect, it } from 'vitest';; import { hasUnreadMessages } from './unread';
  - expo-app/sources/sync/unread.ts: +48/-12 | adds const bump, const discarded, const hasAnyActivity, const hasMarker, const inFlight, const queue | removes const first, const last, const latestCreatedAt, function hasUnreadMessages | touches @@ -1,7 +1,24 @@; export function hasUnreadMessages(params: {
  - expo-app/sources/-session/SessionView.tsx: +44/-2 | adds const current, const isFocusedRef, const last, const lastMarkedRef, const markSessionViewed, const markViewedTimeoutRef | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:; import type { ModelMode, PermissionMode } from '@/sync/permissionTypes';; import { Ionicons } from '@expo/vector-icons';
  - expo-app/sources/sync/sync.ts: +29/-0 | adds const existing, const existingPendingAt, const existingSeq, const pendingActivityAt, const prev, const prevPendingAt | touches class Sync {; import { nowServerMs } from './time';
  - expo-app/sources/sync/storage.ts: +11/-4 | adds const pendingActivityAt, const readState, const session | removes const lastViewedAt, const messages | touches export function useHasUnreadMessages(sessionId: string): boolean {; import { buildSessionListViewData, type SessionListViewItem } from './sessionLis
  - expo-app/sources/sync/storageTypes.ts: +6/-0 | touches export const MetadataSchema = z.object({

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(sync): add cross-device unread markers`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 156 2026-01-22 8c16ee8f9cef

- SHA: 8c16ee8f9cef04c3ae515ab2ebcb12b5ef317759
- Subject: fix(auth): surface auth failures and gate unauth routes
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +89 / -2
- Touched areas: expo-app(5), package.json(1)
- Topic bucket: `auth`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Why
- Some upstream error payloads include usage.service_tier=null. Our Zod schema required a string, so we dropped the whole message during normalization, which could hide critical auth errors (e.g. 401 OAuth expired) in the app.
- Users could deep-link into protected routes (e.g. /new) while unauthenticated, leading to confusing screens that then fail later.

What
- Accept service_tier as nullish so messages are not dropped.
- Add an auth guard in the (app) layout that redirects unauthenticated users to / unless they are on public routes (index, restore).
- Add a small routing helper with unit tests.
- Add root package.json test/typecheck scripts so happys stack test/typecheck can run in the monorepo context (delegates to expo-app).
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/_layout.tsx
A	expo-app/sources/auth/authRouting.test.ts
A	expo-app/sources/auth/authRouting.ts
M	expo-app/sources/sync/typesRaw.spec.ts
M	expo-app/sources/sync/typesRaw.ts
M	package.json
```

### Diffstat

```text
 expo-app/sources/app/(app)/_layout.tsx    | 18 +++++++++++++++++-
 expo-app/sources/auth/authRouting.test.ts | 21 +++++++++++++++++++++
 expo-app/sources/auth/authRouting.ts      | 16 ++++++++++++++++
 expo-app/sources/sync/typesRaw.spec.ts    | 28 ++++++++++++++++++++++++++++
 expo-app/sources/sync/typesRaw.ts         |  4 +++-
 package.json                              |  4 ++++
 6 files changed, 89 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(auth): surface auth failures and gate unauth routes
- Key files by churn (top 6):
  - expo-app/sources/sync/typesRaw.spec.ts: +28/-0 | adds const message, const result | touches describe('Zod Transform - WOLOG Content Normalization', () => {
  - expo-app/sources/auth/authRouting.test.ts: +21/-0 | touches @@ -0,0 +1,21 @@
  - expo-app/sources/app/(app)/_layout.tsx: +17/-1 | adds const auth, const segments, const shouldRedirect | touches @@ -1 +1 @@; export default function RootLayout() {; import { t } from '@/text';
  - expo-app/sources/auth/authRouting.ts: +16/-0 | adds const first, const normalized, function isPublicRouteForUnauthenticated | touches @@ -0,0 +1,16 @@
  - package.json: +4/-0 | touches @@ -3,0 +4,4 @@
  - expo-app/sources/sync/typesRaw.ts: +3/-1 | touches const usageDataSchema = z.object({

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(auth): surface auth failures and gate unauth routes`

### Topic Bucket

- `auth`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 157 2026-01-22 320a89e19ca0

- SHA: 320a89e19ca060f23f67c0283cb075b1fd68635c
- Subject: test(happy): run cli and server checks from root scripts
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +9 / -9
- Touched areas: package.json(1)
- Topic bucket: `happy`
- Manual review needed: no

### Commit Message Body

```text
The Happy monorepo includes expo-app, cli, and server subprojects, but the root scripts only ran expo-app checks.\n\n- Expand "test" to run expo-app + cli + server suites\n- Expand "typecheck" to include cli typecheck and server TS build\n\nThis keeps existing behavior for expo-app and ensures new cli/server tests are exercised when running `happys test/typecheck happy`.
```

### Files (name-status)

```text
M	package.json
```

### Diffstat

```text
 package.json | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(happy): run cli and server checks from root scripts
- Key files by churn (top 1):
  - package.json: +9/-9 | touches @@ -14,7 +14,7 @@; @@ -5,2 +5,2 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(happy): run cli and server checks from root scripts`

### Topic Bucket

- `happy`

### Notes / Follow-ups


---

## 158 2026-01-22 3b3609fed434

- SHA: 3b3609fed43448255148dbbfcaa9c656f35703a3
- Subject: fix(rpc): add structured code for missing RPC methods
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 7
- Lines: +186 / -9
- Touched areas: expo-app(5), server(2)
- Topic bucket: `rpc`
- Manual review needed: YES (multiple major areas: expo-app, server)

### Commit Message Body

```text
Server now returns an explicit "RPC_METHOD_NOT_AVAILABLE" errorCode alongside the legacy error string so newer clients can detect this case without brittle string matching.\n\nClient-side changes:\n- Propagate server error + errorCode via thrown Error (rpcErrorCode)\n- sessionArchive fallback prefers rpcErrorCode and falls back to an exact legacy message match for older servers\n\nTests:\n- server rpcHandler includes errorCode\n- app rpcErrors + sessionArchive behavior
```

### Files (name-status)

```text
M	expo-app/sources/sync/apiSocket.ts
A	expo-app/sources/sync/ops.sessionArchive.test.ts
M	expo-app/sources/sync/ops.ts
A	expo-app/sources/sync/rpcErrors.test.ts
A	expo-app/sources/sync/rpcErrors.ts
A	server/sources/app/api/socket/rpcHandler.spec.ts
M	server/sources/app/api/socket/rpcHandler.ts
```

### Diffstat

```text
 expo-app/sources/sync/apiSocket.ts               | 17 +++++--
 expo-app/sources/sync/ops.sessionArchive.test.ts | 65 ++++++++++++++++++++++++
 expo-app/sources/sync/ops.ts                     | 10 +++-
 expo-app/sources/sync/rpcErrors.test.ts          | 26 ++++++++++
 expo-app/sources/sync/rpcErrors.ts               | 25 +++++++++
 server/sources/app/api/socket/rpcHandler.spec.ts | 45 ++++++++++++++++
 server/sources/app/api/socket/rpcHandler.ts      |  7 ++-
 7 files changed, 186 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(rpc): add structured code for missing RPC methods
- Key files by churn (top 7):
  - expo-app/sources/sync/ops.sessionArchive.test.ts: +65/-0 | adds const res | touches @@ -0,0 +1,65 @@
  - server/sources/app/api/socket/rpcHandler.spec.ts: +45/-0 | adds class FakeSocket, const callback, const handler, const rpcListeners, const socket | touches @@ -0,0 +1,45 @@
  - expo-app/sources/sync/rpcErrors.test.ts: +26/-0 | adds const err | touches @@ -0,0 +1,26 @@
  - expo-app/sources/sync/rpcErrors.ts: +25/-0 | adds const err, const msg, function createRpcCallError, function isRpcMethodNotAvailableError, type RpcErrorCode | touches @@ -0,0 +1,25 @@
  - expo-app/sources/sync/apiSocket.ts: +12/-5 | adds const apiSocket | removes const apiSocket, const result | touches class ApiSocket {; import { observeServerTimestamp } from './time';
  - expo-app/sources/sync/ops.ts: +8/-2 | adds const isRpcMethodUnavailable | removes const isRpcMethodUnavailable | touches export async function sessionArchive(sessionId: string): Promise<SessionArchiveR; export async function sessionKill(sessionId: string): Promise<SessionKillRespons; import { buildSpawnHappySessionRpcParams, type SpawnHappySessionRpcParams, type; interface SessionKillResponse {
  - server/sources/app/api/socket/rpcHandler.ts: +5/-2 | touches export function rpcHandler(userId: string, socket: Socket, rpcListeners: Map<str

### Message Quality

- Conventional Commits: yes
- Multi-area risk: touches expo-app, server.

### Unrelated Changes?

- Likely mixed: multiple major areas touched.

### Suggested Rewrite (Conventional Commit)

- `fix(rpc): add structured code for missing RPC methods`

### Topic Bucket

- `rpc`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 159 2026-01-22 0e2c7928f24c

- SHA: 0e2c7928f24cd0791c77060e170b0e7a84b847d3
- Subject: fix(scanner): tolerate onMessage exceptions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 3
- Lines: +106 / -2
- Touched areas: cli(3)
- Topic bucket: `scanner`
- Manual review needed: no

### Commit Message Body

```text
createSessionScanner now catches exceptions thrown by the consumer `onMessage` callback and logs them instead of letting the scanner crash or trigger InvalidateSync retry/backoff loops.\n\nAlso documents InvalidateSync coalescing + failure semantics explicitly (invalidateAndAwait always resolves).\n\nTest: sessionScanner logs and continues when onMessage throws.
```

### Files (name-status)

```text
A	cli/src/claude/utils/sessionScanner.onMessageErrors.test.ts
M	cli/src/claude/utils/sessionScanner.ts
M	cli/src/utils/sync.ts
```

### Diffstat

```text
 .../utils/sessionScanner.onMessageErrors.test.ts   | 78 ++++++++++++++++++++++
 cli/src/claude/utils/sessionScanner.ts             |  8 ++-
 cli/src/utils/sync.ts                              | 22 ++++++
 3 files changed, 106 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(scanner): tolerate onMessage exceptions
- Key files by churn (top 3):
  - cli/src/claude/utils/sessionScanner.onMessageErrors.test.ts: +78/-0 | adds const debugSpy, const sessionFile, const sessionId, const start, function waitFor | touches @@ -0,0 +1,78 @@
  - cli/src/utils/sync.ts: +22/-0 | touches export type InvalidateSyncOptions = {
  - cli/src/claude/utils/sessionScanner.ts: +6/-2 | touches export async function createSessionScanner(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(scanner): tolerate onMessage exceptions`

### Topic Bucket

- `scanner`

### Notes / Follow-ups


---

## 160 2026-01-22 7fbe1f1cc727

- SHA: 7fbe1f1cc7273821a45986cfc6ef4f2d7eb32eec
- Subject: fix(permission): avoid no-op permissionModeUpdatedAt bumps
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +128 / -18
- Touched areas: cli(6)
- Topic bucket: `permission`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Prevent unnecessary permission metadata churn by only bumping permissionModeUpdatedAt when the effective permission mode actually changes.\n\n- Claude: Session.setLastPermissionMode is a no-op when mode is unchanged\n- Codex/Gemini: reuse shared helper to conditionally update session metadata\n\nWhy: the UI merges permission mode based on permissionModeUpdatedAt, so repeated no-op bumps can incorrectly override the user's latest selection.\n\nTests: add coverage for the no-op behavior.
```

### Files (name-status)

```text
M	cli/src/claude/session.test.ts
M	cli/src/claude/session.ts
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
A	cli/src/utils/permissionModeMetadata.test.ts
A	cli/src/utils/permissionModeMetadata.ts
```

### Diffstat

```text
 cli/src/claude/session.test.ts               | 35 +++++++++++++++++++++++
 cli/src/claude/session.ts                    |  3 ++
 cli/src/codex/runCodex.ts                    | 20 +++++++------
 cli/src/gemini/runGemini.ts                  | 24 +++++++++-------
 cli/src/utils/permissionModeMetadata.test.ts | 42 ++++++++++++++++++++++++++++
 cli/src/utils/permissionModeMetadata.ts      | 22 +++++++++++++++
 6 files changed, 128 insertions(+), 18 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(permission): avoid no-op permissionModeUpdatedAt bumps
- Key files by churn (top 6):
  - cli/src/utils/permissionModeMetadata.test.ts: +42/-0 | adds const nowMs, const res, const updateMetadata, const updater | touches @@ -0,0 +1,42 @@
  - cli/src/claude/session.test.ts: +35/-0 | adds const client, const session | touches describe('Session', () => {
  - cli/src/gemini/runGemini.ts: +14/-10 | adds const nextPermissionMode, const res | touches export async function runGemini(opts: {; import { buildTerminalFallbackMessage } from '@/terminal/terminalFallbackMessage
  - cli/src/utils/permissionModeMetadata.ts: +22/-0 | adds const nowMs, function maybeUpdatePermissionModeMetadata | touches @@ -0,0 +1,22 @@
  - cli/src/codex/runCodex.ts: +12/-8 | adds const nextPermissionMode, const res | touches export async function runCodex(opts: {; import { isExperimentalCodexVendorResumeEnabled } from '@/utils/agentCapabilitie
  - cli/src/claude/session.ts: +3/-0 | touches export class Session {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(permission): avoid no-op permissionModeUpdatedAt bumps`

### Topic Bucket

- `permission`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 161 2026-01-22 2026fbab5cb3

- SHA: 2026fbab5cb33d17d466ac7b81e811169d7fe7ef
- Subject: fix(claude): accept -c as continue flag
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +1 / -1
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
Claude local runner now treats `-c` as equivalent to `--continue` when detecting user-provided session control flags.
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocal.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocal.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): accept -c as continue flag
- Key files by churn (top 1):
  - cli/src/claude/claudeLocal.ts: +1/-1 | adds const hasContinueFlag | removes const hasContinueFlag | touches export async function claudeLocal(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): accept -c as continue flag`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 162 2026-01-22 ee0bec2a0b90

- SHA: ee0bec2a0b90bb277db7c3f04607de867b57bf33
- Subject: Delete INACTIVE_SESSION_RESUME.md
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 1
- Lines: +0 / -127
- Touched areas: expo-app(1)
- Topic bucket: `resume`
- Manual review needed: YES (non-Conventional-Commits subject)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
D	expo-app/INACTIVE_SESSION_RESUME.md
```

### Diffstat

```text
 expo-app/INACTIVE_SESSION_RESUME.md | 127 ------------------------------------
 1 file changed, 127 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Delete INACTIVE_SESSION_RESUME.md
- Key files by churn (top 1):
  - expo-app/INACTIVE_SESSION_RESUME.md: +0/-127 | touches @@ -1,127 +0,0 @@

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(resume): delete INACTIVE_SESSION_RESUME.md`

### Topic Bucket

- `resume`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 163 2026-01-22 84df0d260513

- SHA: 84df0d2605133a165a381dd6ae65507cfda23795
- Subject: fix(expo-app): stabilize postinstall and libsodium patches
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-22
- Files changed: 6
- Lines: +69 / -29
- Touched areas: expo-app(5), yarn.lock(1)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
- Replace inline postinstall command with a dedicated script (expo-app/tools/postinstall.mjs)\n- Run patch-package from the repo root to support Yarn workspace hoisting\n- Add a patch for libsodium-wrappers@0.7.16 to restore missing dist/modules-esm/libsodium.mjs\n- Remove the obsolete @more-tech/react-native-libsodium 1.5.5 patch (package is now 1.5.6 and already avoids folly_version)\n- Tighten TypeScript typing for the web libsodium adapter\n\nThis makes installs more reliable across hoisting layouts and RN/Expo versions.
```

### Files (name-status)

```text
M	expo-app/package.json
D	expo-app/patches/@more-tech+react-native-libsodium+1.5.5.patch
A	expo-app/patches/libsodium-wrappers+0.7.16.patch
M	expo-app/sources/encryption/libsodium.lib.web.ts
A	expo-app/tools/postinstall.mjs
M	yarn.lock
```

### Diffstat

```text
 expo-app/package.json                              |  2 +-
 .../@more-tech+react-native-libsodium+1.5.5.patch  | 20 ----------
 expo-app/patches/libsodium-wrappers+0.7.16.patch   |  7 ++++
 expo-app/sources/encryption/libsodium.lib.web.ts   |  5 ++-
 expo-app/tools/postinstall.mjs                     | 43 ++++++++++++++++++++++
 yarn.lock                                          | 21 +++++++----
 6 files changed, 69 insertions(+), 29 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): stabilize postinstall and libsodium patches
- Key files by churn (top 6):
  - expo-app/tools/postinstall.mjs: +43/-0 | adds const expoAppDir, const patchPackageCliCandidatePaths, const patchPackageCliPath, const repoRootDir, const result, const toolsDir | touches @@ -0,0 +1,43 @@
  - yarn.lock: +14/-7 | touches @@ -2956,0 +2957,7 @@; react-is@^18.0.0:; react-syntax-highlighter@^15.6.1:; react-test-renderer@19.0.0:
  - expo-app/patches/@more-tech+react-native-libsodium+1.5.5.patch: +0/-19 | touches @@ -1,20 +0,0 @@
  - expo-app/patches/libsodium-wrappers+0.7.16.patch: +6/-0 | touches @@ -0,0 +1,7 @@
  - expo-app/sources/encryption/libsodium.lib.web.ts: +4/-1 | touches @@ -0,0 +1,2 @@; import sodium from 'libsodium-wrappers';
  - expo-app/package.json: +1/-1 | touches @@ -17 +17 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): stabilize postinstall and libsodium patches`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 164 2026-01-23 544f9711b6cf

- SHA: 544f9711b6cfe195ed56d7426e326b54189dc2be
- Subject: fix(ui): respond to plan/question tools via session RPC
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 5
- Lines: +295 / -14
- Touched areas: expo-app(5)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
- ExitPlanMode: approve/reject via permission RPC (no extra chat message)

- AskUserQuestion: send answers via new session RPC interaction.respond; fallback to deny+sendMessage when RPC unsupported

- Add unit tests covering both tool views
```

### Files (name-status)

```text
A	expo-app/sources/components/tools/views/AskUserQuestionView.test.ts
M	expo-app/sources/components/tools/views/AskUserQuestionView.tsx
A	expo-app/sources/components/tools/views/ExitPlanToolView.test.ts
M	expo-app/sources/components/tools/views/ExitPlanToolView.tsx
M	expo-app/sources/sync/ops.ts
```

### Diffstat

```text
 .../tools/views/AskUserQuestionView.test.ts        | 113 +++++++++++++++++
 .../components/tools/views/AskUserQuestionView.tsx |  23 ++--
 .../tools/views/ExitPlanToolView.test.ts           | 140 +++++++++++++++++++++
 .../components/tools/views/ExitPlanToolView.tsx    |   9 +-
 expo-app/sources/sync/ops.ts                       |  24 ++++
 5 files changed, 295 insertions(+), 14 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): respond to plan/question tools via session RPC
- Key files by churn (top 5):
  - expo-app/sources/components/tools/views/ExitPlanToolView.test.ts: +140/-0 | adds const buttons, const sendMessage, const sessionAllow, const sessionDeny | touches @@ -0,0 +1,140 @@
  - expo-app/sources/components/tools/views/AskUserQuestionView.test.ts: +113/-0 | adds const sendMessage, const sessionDeny, const sessionInteractionRespond, const touchables | touches @@ -0,0 +1,113 @@
  - expo-app/sources/sync/ops.ts: +24/-0 | adds function sessionInteractionRespond, interface SessionInteractionRespondRequest, interface SessionInteractionRespondResponse | touches export async function sessionDeny(sessionId: string, id: string, mode?: 'default; interface SessionPermissionRequest {
  - expo-app/sources/components/tools/views/AskUserQuestionView.tsx: +16/-7 | adds const toolCallId | touches export const AskUserQuestionView = React.memo<ToolViewProps>(({ tool, sessionId; import { ToolSectionView } from '../ToolSectionView';
  - expo-app/sources/components/tools/views/ExitPlanToolView.tsx: +2/-7 | touches export const ExitPlanToolView = React.memo<ToolViewProps>(({ tool, sessionId }); import { knownTools } from '../../tools/knownTools';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): respond to plan/question tools via session RPC`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 165 2026-01-23 8b3f39f22664

- SHA: 8b3f39f226644bd72269d484a13bb8faa9730d13
- Subject: feat(cli): add interaction.respond for AskUserQuestion
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 5
- Lines: +141 / -42
- Touched areas: cli(5)
- Topic bucket: `cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
- Register session RPC interaction.respond in Claude remote launcher

- Approve tool call and inject tool_result into Claude prompt stream

- Expose sender hook from claudeRemote for mid-turn tool_result injection

- Add unit test for interaction respond helper
```

### Files (name-status)

```text
M	cli/src/claude/claudeRemote.ts
M	cli/src/claude/claudeRemoteLauncher.ts
A	cli/src/claude/utils/interactionRespond.test.ts
A	cli/src/claude/utils/interactionRespond.ts
M	cli/src/claude/utils/permissionHandler.ts
```

### Diffstat

```text
 cli/src/claude/claudeRemote.ts                  |  5 +-
 cli/src/claude/claudeRemoteLauncher.ts          | 30 ++++++++
 cli/src/claude/utils/interactionRespond.test.ts | 29 ++++++++
 cli/src/claude/utils/interactionRespond.ts      | 28 ++++++++
 cli/src/claude/utils/permissionHandler.ts       | 91 ++++++++++++++-----------
 5 files changed, 141 insertions(+), 42 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(cli): add interaction.respond for AskUserQuestion
- Key files by churn (top 5):
  - cli/src/claude/utils/permissionHandler.ts: +50/-41 | adds const id, const pending, const request | removes const id, const pending, const request | touches export class PermissionHandler {
  - cli/src/claude/claudeRemoteLauncher.ts: +30/-0 | adds const responseText, const sender, const toolCallId | touches export async function claudeRemoteLauncher(session: Session): Promise<'switch' |; import { cleanupStdinAfterInk } from "@/utils/terminalStdinCleanup";
  - cli/src/claude/utils/interactionRespond.test.ts: +29/-0 | adds const approve, const pushToolResult | touches @@ -0,0 +1,29 @@
  - cli/src/claude/utils/interactionRespond.ts: +28/-0 | adds function createClaudeToolResultUserMessage, function handleClaudeInteractionRespond | touches @@ -0,0 +1,28 @@
  - cli/src/claude/claudeRemote.ts: +4/-1 | touches export async function claudeRemote(opts: {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(cli): add interaction.respond for AskUserQuestion`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 166 2025-12-24 ed4bc007308a

- SHA: ed4bc007308af4c1c4e0ac6f67d58adcc54fe37b
- Subject: feat: add execpolicy approval option for Codex
- Author: Ordinary <Ordinary@zjgsdx.edu.cn>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 13
- Lines: +117 / -27
- Touched areas: expo-app(13)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/PermissionFooter.tsx
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/reducer/reducer.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/typesMessage.ts
M	expo-app/sources/sync/typesRaw.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 .../sources/components/tools/PermissionFooter.tsx  | 84 +++++++++++++++++++---
 expo-app/sources/sync/ops.ts                       | 23 +++++-
 expo-app/sources/sync/reducer/reducer.ts           | 20 +++---
 expo-app/sources/sync/storageTypes.ts              |  2 +-
 expo-app/sources/sync/typesMessage.ts              |  4 +-
 expo-app/sources/sync/typesRaw.ts                  |  4 +-
 expo-app/sources/text/translations/ca.ts           |  1 +
 expo-app/sources/text/translations/en.ts           |  1 +
 expo-app/sources/text/translations/es.ts           |  1 +
 expo-app/sources/text/translations/pl.ts           |  1 +
 expo-app/sources/text/translations/pt.ts           |  1 +
 expo-app/sources/text/translations/ru.ts           |  1 +
 expo-app/sources/text/translations/zh-Hans.ts      |  1 +
 13 files changed, 117 insertions(+), 27 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat: add execpolicy approval option for Codex
- Key files by churn (top 8):
  - expo-app/sources/components/tools/PermissionFooter.tsx: +73/-11 | adds const canApproveExecPolicy, const execPolicyCommand, const handleCodexApproveExecPolicy, const isCodexApprovedExecPolicy, const proposedAmendment | touches export const PermissionFooter: React.FC<PermissionFooterProps> = ({ permission,; interface PermissionFooterProps {
  - expo-app/sources/sync/ops.ts: +20/-3 | adds function sessionAllow | removes function sessionAllow | touches export async function sessionAbort(sessionId: string): Promise<void> {; interface SessionPermissionRequest {
  - expo-app/sources/sync/reducer/reducer.ts: +12/-8 | touches export function reducer(state: ReducerState, messages: NormalizedMessage[], agen; function convertReducerMessageToMessage(reducerMsg: ReducerMessage, state: Reduc; type StoredPermission = {
  - expo-app/sources/sync/typesRaw.ts: +2/-2 | touches const rawToolResultContentSchema = z.object({; type NormalizedAgentContent =
  - expo-app/sources/sync/typesMessage.ts: +2/-2 | adds type Message | removes type Message | touches export type ToolCall = {; export type ToolCallMessage = {
  - expo-app/sources/sync/storageTypes.ts: +1/-1 | touches export const AgentStateSchema = z.object({
  - expo-app/sources/text/translations/zh-Hans.ts: +1/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +1/-0 | touches export const ru: TranslationStructure = {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat: add execpolicy approval option for Codex`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 167 2025-12-24 78adc9c58811

- SHA: 78adc9c58811ae4178823ddb6418121a0ecb34a7
- Subject: feat(codex): support execpolicy approvals and MCP tool calls
- Author: Ordinary <Ordinary@zjgsdx.edu.cn>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 5
- Lines: +459 / -106
- Touched areas: cli(5)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/agent/acp/AcpBackend.ts
M	cli/src/api/types.ts
M	cli/src/codex/codexMcpClient.ts
M	cli/src/codex/runCodex.ts
M	cli/src/utils/BasePermissionHandler.ts
```

### Diffstat

```text
 cli/src/agent/acp/AcpBackend.ts        |   7 +-
 cli/src/api/types.ts                   |   2 +-
 cli/src/codex/codexMcpClient.ts        | 501 ++++++++++++++++++++++++++-------
 cli/src/codex/runCodex.ts              |  23 ++
 cli/src/utils/BasePermissionHandler.ts |  32 ++-
 5 files changed, 459 insertions(+), 106 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(codex): support execpolicy approvals and MCP tool calls
- Key files by churn (top 5):
  - cli/src/codex/codexMcpClient.ts: +404/-99 | adds const ElicitRequestSchemaWithExtras, const MCP_SERVER_MIN_VERSION, const action, const amendment, const args, const cached | removes const CodexBashElicitationParamsSchema, const alphaNum, const args, const getPermissionHandler | touches export class CodexMcpClient {; export function createCodexElicitationRequestHandler(; function getCodexMcpCommand(codexCommand: string): string | null {; import { execFileSync } from 'child_process';
  - cli/src/utils/BasePermissionHandler.ts: +27/-5 | adds const wantsExecpolicyAmendment | touches export abstract class BasePermissionHandler {; export interface PermissionResponse {; export interface PermissionResult {
  - cli/src/codex/runCodex.ts: +23/-0 | adds const output, const toolName | touches export async function runCodex(opts: {
  - cli/src/agent/acp/AcpBackend.ts: +5/-2 | adds const isApproved | touches export class AcpBackend implements AgentBackend {; export interface AcpPermissionHandler {
  - cli/src/api/types.ts: +1/-1 | touches export type AgentState = {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(codex): support execpolicy approvals and MCP tool calls`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 168 2026-01-22 9dfa09bef8d8

- SHA: 9dfa09bef8d8d6a9b791c91e2cb1fe49c4204806
- Subject: fix(i18n): add Codex execpolicy button text
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +2 / -0
- Touched areas: expo-app(2)
- Topic bucket: `i18n`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Add missing codex.permissions.yesAlwaysAllowCommand translations for Italian and Japanese to keep the translation schema complete.
```

### Files (name-status)

```text
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
```

### Diffstat

```text
 expo-app/sources/text/translations/it.ts | 1 +
 expo-app/sources/text/translations/ja.ts | 1 +
 2 files changed, 2 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): add Codex execpolicy button text
- Key files by churn (top 2):
  - expo-app/sources/text/translations/ja.ts: +1/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +1/-0 | touches export const it: TranslationStructure = {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): add Codex execpolicy button text`

### Topic Bucket

- `i18n`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 169 2026-01-22 559d39da116d

- SHA: 559d39da116dcbae4d9be05e55a23d9e79d44160
- Subject: fix(reducer): keep permission messages idempotent
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +18 / -3
- Touched areas: expo-app(1)
- Topic bucket: `reducer`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Avoid marking permission tool messages as changed when AgentState.request arguments are unchanged. This prevents permission messages from being re-emitted on unrelated message updates while still allowing late-arriving fields (e.g. proposedExecpolicyAmendment) to update the existing message.
```

### Files (name-status)

```text
M	expo-app/sources/sync/reducer/reducer.ts
```

### Diffstat

```text
 expo-app/sources/sync/reducer/reducer.ts | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(reducer): keep permission messages idempotent
- Key files by churn (top 1):
  - expo-app/sources/sync/reducer/reducer.ts: +18/-3 | adds const inputUnchanged | touches export function reducer(state: ReducerState, messages: NormalizedMessage[], agen; import { parseMessageAsEvent } from "./messageToEvent";

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(reducer): keep permission messages idempotent`

### Topic Bucket

- `reducer`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 170 2026-01-18 cc3c711ae28e

- SHA: cc3c711ae28e700c1d0b96485e0df06c5ac9978c
- Subject: fix: move claudeArgs to end of args array for slash command support
- Author: jio <g2gallardy@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +5 / -5
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
Slash commands like /help weren't working because the prompt wasn't at the end of the
   CLI args where Claude expects it.
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocal.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocal.ts | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix: move claudeArgs to end of args array for slash command support
- Key files by churn (top 1):
  - cli/src/claude/claudeLocal.ts: +5/-5 | touches export async function claudeLocal(opts: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix: move claudeArgs to end of args array for slash command support`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 171 2026-01-19 d06d5a833f8e

- SHA: d06d5a833f8ed6fdcfe82ae6a829e20307a97532
- Subject: Add signal forwarding to claudeLocal.ts
- Author: Felix Berlakovich <felix@berlakovich.at>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +22 / -0
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: YES (non-Conventional-Commits subject)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/claudeLocal.ts
```

### Diffstat

```text
 cli/src/claude/claudeLocal.ts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): Add signal forwarding to claudeLocal.ts
- Key files by churn (top 1):
  - cli/src/claude/claudeLocal.ts: +22/-0 | adds const forwardSignal, const onSighup, const onSigint, const onSigterm | touches export async function claudeLocal(opts: {

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(claude): add signal forwarding to claudeLocal.ts`

### Topic Bucket

- `claude`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 172 2025-11-20 1b7cb3bfea86

- SHA: 1b7cb3bfea86cb429d3e04b329595013a8590f3e
- Subject: feat: handle /clear command as session reset in codex
- Author: zhangkunyuan <zhangkunyuan@cmhi.chinamobile.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +41 / -11
- Touched areas: cli(3)
- Topic bucket: `codex`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/runClaude.ts
M	cli/src/codex/runCodex.ts
M	cli/src/parsers/specialCommands.ts
```

### Diffstat

```text
 cli/src/claude/runClaude.ts        |  3 +--
 cli/src/codex/runCodex.ts          | 37 ++++++++++++++++++++++++++++++++++---
 cli/src/parsers/specialCommands.ts | 12 ++++++------
 3 files changed, 41 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat: handle /clear command as session reset in codex
- Key files by churn (top 3):
  - cli/src/codex/runCodex.ts: +34/-3 | adds const specialCommand | touches export async function runCodex(opts: {; import { maybeUpdatePermissionModeMetadata } from '@/utils/permissionModeMetadat
  - cli/src/parsers/specialCommands.ts: +6/-6 | touches export function parseClear(message: string): ClearCommandResult {; export function parseCompact(message: string): CompactCommandResult {; export function parseSpecialCommand(message: string): SpecialCommandResult {
  - cli/src/claude/runClaude.ts: +1/-2 | touches export async function runClaude(credentials: Credentials, options: StartOptions

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat: handle /clear command as session reset in codex`

### Topic Bucket

- `codex`

### Notes / Follow-ups


---

## 173 2026-01-11 332ab2b0cd93

- SHA: 332ab2b0cd93e30c1f8dae994bfa2c5d7e0dfbc9
- Subject: fix(cli): improve abort error handling to reduce spurious error messages
- Author: Gershom Rogers <gershomrogers@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +58 / -2
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
- Detect DOMException/AbortError from Node.js spawn\n- Only show "Process exited unexpectedly" for genuine failures\n- Better error logging for debugging
```

### Files (name-status)

```text
M	cli/src/claude/claudeRemoteLauncher.ts
```

### Diffstat

```text
 cli/src/claude/claudeRemoteLauncher.ts | 60 ++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): improve abort error handling to reduce spurious error messages
- Key files by churn (top 1):
  - cli/src/claude/claudeRemoteLauncher.ts: +58/-2 | adds const abortError, const code, const err, const message, const name, const stack | touches export async function claudeRemoteLauncher(session: Session): Promise<'switch' |; import { Future } from "@/utils/future";; interface PermissionsField {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): improve abort error handling to reduce spurious error messages`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 174 2025-12-24 e956463db3e2

- SHA: e956463db3e216e89d832c4a5082a3583e81968d
- Subject: fix: use runtime execPath for MCP bridge
- Author: Ordinary <Ordinary@zjgsdx.edu.cn>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +9 / -7
- Touched areas: cli(3)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/runCodex.ts
M	cli/src/gemini/runGemini.ts
M	cli/src/utils/spawnHappyCLI.ts
```

### Diffstat

```text
 cli/src/codex/runCodex.ts      | 7 ++++---
 cli/src/gemini/runGemini.ts    | 7 ++++---
 cli/src/utils/spawnHappyCLI.ts | 2 +-
 3 files changed, 9 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix: use runtime execPath for MCP bridge
- Key files by churn (top 3):
  - cli/src/gemini/runGemini.ts: +4/-3 | adds const bridgeScript | removes const bridgeCommand | touches export async function runGemini(opts: {
  - cli/src/codex/runCodex.ts: +4/-3 | adds const bridgeScript | removes const bridgeCommand | touches export async function runCodex(opts: {
  - cli/src/utils/spawnHappyCLI.ts: +1/-1 | touches export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix: use runtime execPath for MCP bridge`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 175 2026-01-23 f0a7d8d0b40c

- SHA: f0a7d8d0b40ccf97cce099e021810be8eedfc904
- Subject: fix(codex): use mcp tool call id for approvals
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +44 / -30
- Touched areas: cli(2)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
Prefer codex_mcp_tool_call_id over codex_call_id when deriving toolCallId for permission requests, and align execpolicy amendment caching with the same id when available.

Adds a small unit test for tool call id selection.
```

### Files (name-status)

```text
M	cli/src/codex/codexMcpClient.test.ts
M	cli/src/codex/codexMcpClient.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.test.ts | 40 ++++++++++++------------------------
 cli/src/codex/codexMcpClient.ts      | 34 +++++++++++++++++++++++++++---
 2 files changed, 44 insertions(+), 30 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): use mcp tool call id for approvals
- Key files by churn (top 2):
  - cli/src/codex/codexMcpClient.test.ts: +13/-27 | removes const consoleSpy, const handler, const permissionHandler | touches import { describe, it, expect, vi } from 'vitest';; vi.mock('@modelcontextprotocol/sdk/client/index.js', () => {
  - cli/src/codex/codexMcpClient.ts: +31/-3 | adds const callId, const mcpToolCallId, const toolCallId, function getCodexElicitationToolCallId, function getCodexEventToolCallId | removes const callId, const toolCallId | touches export class CodexMcpClient {; type ElicitationResponseStyle = 'decision' | 'both';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): use mcp tool call id for approvals`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 176 2026-01-22 da620b6865ad

- SHA: da620b6865adfba9e3b4d0a0330404c603fdab8d
- Subject: feat(server): add full/light flavors with sqlite migrations
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 38
- Lines: +2210 / -165
- Touched areas: server(38)
- Topic bucket: `server`
- Manual review needed: YES (diff summary skipped (too many files (38)))

### Commit Message Body

```text
(cherry picked from commit b21928c5e779f7691cb06a240cfab5f83f167809)
```

### Files (name-status)

```text
M	server/.gitignore
M	server/README.md
M	server/package.json
A	server/prisma/sqlite/migrations/20260122190000_baseline/migration.sql
A	server/prisma/sqlite/migrations/migration_lock.toml
A	server/prisma/sqlite/schema.prisma
A	server/scripts/dev.full.ts
A	server/scripts/dev.fullArgs.spec.ts
A	server/scripts/dev.fullArgs.ts
A	server/scripts/dev.light.ts
A	server/scripts/dev.lightPlan.spec.ts
A	server/scripts/dev.lightPlan.ts
A	server/scripts/generateSqliteSchema.spec.ts
A	server/scripts/generateSqliteSchema.ts
A	server/scripts/migrate.light.deploy.ts
A	server/scripts/migrate.light.new.ts
A	server/scripts/migrate.light.resolveBaseline.ts
M	server/sources/app/api/api.ts
M	server/sources/app/api/routes/userRoutes.ts
A	server/sources/app/api/uiConfig.spec.ts
A	server/sources/app/api/uiConfig.ts
M	server/sources/app/api/utils/enableErrorHandlers.ts
A	server/sources/app/api/utils/enableOptionalStatics.ts
A	server/sources/app/api/utils/enablePublicFiles.ts
A	server/sources/app/api/utils/enableServeUi.ts
M	server/sources/app/presence/timeout.ts
A	server/sources/flavors/light/env.spec.ts
A	server/sources/flavors/light/env.ts
A	server/sources/flavors/light/files.spec.ts
A	server/sources/flavors/light/files.ts
A	server/sources/main.light.ts
M	server/sources/main.ts
A	server/sources/startServer.ts
M	server/sources/storage/db.ts
M	server/sources/storage/files.ts
M	server/sources/storage/processImage.spec.ts
M	server/sources/storage/uploadImage.ts
A	server/sources/utils/processHandlers.ts
```

### Diffstat

```text
 server/.gitignore                                  |   2 +
 server/README.md                                   | 152 ++++++++-
 server/package.json                                |  18 +-
 .../20260122190000_baseline/migration.sql          | 345 +++++++++++++++++++
 .../prisma/sqlite/migrations/migration_lock.toml   |   3 +
 server/prisma/sqlite/schema.prisma                 | 364 +++++++++++++++++++++
 server/scripts/dev.full.ts                         |  21 ++
 server/scripts/dev.fullArgs.spec.ts                |  25 ++
 server/scripts/dev.fullArgs.ts                     |  47 +++
 server/scripts/dev.light.ts                        |  44 +++
 server/scripts/dev.lightPlan.spec.ts               |  11 +
 server/scripts/dev.lightPlan.ts                    |  15 +
 server/scripts/generateSqliteSchema.spec.ts        |  22 ++
 server/scripts/generateSqliteSchema.ts             | 102 ++++++
 server/scripts/migrate.light.deploy.ts             |  35 ++
 server/scripts/migrate.light.new.ts                |  81 +++++
 server/scripts/migrate.light.resolveBaseline.ts    |  54 +++
 server/sources/app/api/api.ts                      |   8 +-
 server/sources/app/api/routes/userRoutes.ts        |  12 +-
 server/sources/app/api/uiConfig.spec.ts            |  30 ++
 server/sources/app/api/uiConfig.ts                 |  26 ++
 .../sources/app/api/utils/enableErrorHandlers.ts   |  63 +++-
 .../sources/app/api/utils/enableOptionalStatics.ts |  23 ++
 server/sources/app/api/utils/enablePublicFiles.ts  |  39 +++
 server/sources/app/api/utils/enableServeUi.ts      | 184 +++++++++++
 server/sources/app/presence/timeout.ts             |  14 +-
 server/sources/flavors/light/env.spec.ts           |  66 ++++
 server/sources/flavors/light/env.ts                |  77 +++++
 server/sources/flavors/light/files.spec.ts         |  18 +
 server/sources/flavors/light/files.ts              |  58 ++++
 server/sources/main.light.ts                       |  14 +
 server/sources/main.ts                             | 109 +-----
 server/sources/startServer.ts                      |  66 ++++
 server/sources/storage/db.ts                       |  16 +-
 server/sources/storage/files.ts                    | 115 +++++--
 server/sources/storage/processImage.spec.ts        |  25 +-
 server/sources/storage/uploadImage.ts              |  13 +-
 server/sources/utils/processHandlers.ts            |  58 ++++
 38 files changed, 2210 insertions(+), 165 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(server): add full/light flavors with sqlite migrations
- Diff summary skipped: too many files (38).

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(server): add full/light flavors with sqlite migrations`

### Topic Bucket

- `server`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 177 2026-01-23 893ce7af5df0

- SHA: 893ce7af5df079be26925ff7a7c5baf6e9d35088
- Subject: fix(expo-app): avoid hooks order violation on redirect
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +113 / -1
- Touched areas: expo-app(2)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/app/(app)/_layout.test.ts
M	expo-app/sources/app/(app)/_layout.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/_layout.test.ts | 112 +++++++++++++++++++++++++++++
 expo-app/sources/app/(app)/_layout.tsx     |   2 +-
 2 files changed, 113 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): avoid hooks order violation on redirect
- Key files by churn (top 2):
  - expo-app/sources/app/(app)/_layout.test.ts: +112/-0 | adds const React | touches @@ -0,0 +1,112 @@
  - expo-app/sources/app/(app)/_layout.tsx: +1/-1 | touches export default function RootLayout() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): avoid hooks order violation on redirect`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 178 2026-01-23 7afbc9a2decd

- SHA: 7afbc9a2decd82d9283025eaab20b502b7ff9d3f
- Subject: fix(expo-app): persist resumeSessionId and harden clipboard paste
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 5
- Lines: +65 / -3
- Touched areas: expo-app(5)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/pick/resume.tsx
M	expo-app/sources/sync/persistence.test.ts
M	expo-app/sources/sync/persistence.ts
A	expo-app/sources/utils/clipboard.test.ts
A	expo-app/sources/utils/clipboard.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/pick/resume.tsx |  5 ++---
 expo-app/sources/sync/persistence.test.ts      | 21 ++++++++++++++++++
 expo-app/sources/sync/persistence.ts           |  2 ++
 expo-app/sources/utils/clipboard.test.ts       | 30 ++++++++++++++++++++++++++
 expo-app/sources/utils/clipboard.ts            | 10 +++++++++
 5 files changed, 65 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): persist resumeSessionId and harden clipboard paste
- Key files by churn (top 5):
  - expo-app/sources/utils/clipboard.test.ts: +30/-0 | touches @@ -0,0 +1,30 @@
  - expo-app/sources/sync/persistence.test.ts: +21/-0 | adds const draft | touches describe('persistence', () => {
  - expo-app/sources/utils/clipboard.ts: +10/-0 | adds function getClipboardStringTrimmedSafe | touches @@ -0,0 +1,10 @@
  - expo-app/sources/app/(app)/new/pick/resume.tsx: +2/-3 | adds const text | removes const text | touches export default function ResumePickerScreen() {; import { AgentType } from '@/utils/agentCapabilities';; import { MultiTextInput } from '@/components/MultiTextInput';
  - expo-app/sources/sync/persistence.ts: +2/-0 | adds const resumeSessionId | touches export function loadNewSessionDraft(): NewSessionDraft | null {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): persist resumeSessionId and harden clipboard paste`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 179 2026-01-23 9a13879b753a

- SHA: 9a13879b753a5cb0c3c31aaae99e56b136a51e7a
- Subject: fix(expo-app): avoid false homeDir prefix matches
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +19 / -2
- Touched areas: expo-app(2)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/sessionListViewData.test.ts
M	expo-app/sources/sync/sessionListViewData.ts
```

### Diffstat

```text
 expo-app/sources/sync/sessionListViewData.test.ts | 17 +++++++++++++++++
 expo-app/sources/sync/sessionListViewData.ts      |  4 ++--
 2 files changed, 19 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): avoid false homeDir prefix matches
- Key files by churn (top 2):
  - expo-app/sources/sync/sessionListViewData.test.ts: +17/-0 | adds const data, const group, const machine | touches describe('buildSessionListViewData', () => {
  - expo-app/sources/sync/sessionListViewData.ts: +2/-2 | adds const isInHome | touches export function buildSessionListViewData(; function formatPathRelativeToHome(path: string, homeDir?: string | null): string

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): avoid false homeDir prefix matches`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 180 2026-01-23 c107a779e07d

- SHA: c107a779e07d3f934178b6b6c21d5a650952fb99
- Subject: fix(expo-app): avoid stuck loading in capabilities cache
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +61 / -1
- Touched areas: expo-app(2)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/hooks/useMachineCapabilitiesCache.hook.test.ts
M	expo-app/sources/hooks/useMachineCapabilitiesCache.ts
```

### Diffstat

```text
 .../hooks/useMachineCapabilitiesCache.hook.test.ts | 45 ++++++++++++++++++++++
 .../sources/hooks/useMachineCapabilitiesCache.ts   | 17 +++++++-
 2 files changed, 61 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): avoid stuck loading in capabilities cache
- Key files by churn (top 2):
  - expo-app/sources/hooks/useMachineCapabilitiesCache.hook.test.ts: +45/-0 | adds function Test | touches @@ -0,0 +1,45 @@
  - expo-app/sources/hooks/useMachineCapabilitiesCache.ts: +16/-1 | adds const current, const stillInFlight | touches async function fetchAndMerge(params: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): avoid stuck loading in capabilities cache`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 181 2026-01-23 35c0974eff1f

- SHA: 35c0974eff1fdd934ddc71f1e07a57a6dc0c3206
- Subject: refactor(expo-app): remove dead code and dedupe types
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +5 / -7
- Touched areas: expo-app(3)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/session.tsx
M	expo-app/sources/components/PendingMessagesModal.tsx
M	expo-app/sources/hooks/useCLIDetection.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/session.tsx      | 4 +---
 expo-app/sources/components/PendingMessagesModal.tsx | 7 ++++---
 expo-app/sources/hooks/useCLIDetection.ts            | 1 -
 3 files changed, 5 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(expo-app): remove dead code and dedupe types
- Key files by churn (top 3):
  - expo-app/sources/components/PendingMessagesModal.tsx: +4/-3 | adds const backgroundColor | touches function ActionButton(props: {
  - expo-app/sources/app/(app)/settings/session.tsx: +1/-3 | removes type MessageSendMode | touches const styles = StyleSheet.create((theme) => ({; import { useSettingMutable } from '@/sync/storage';
  - expo-app/sources/hooks/useCLIDetection.ts: +0/-1 | touches export function useCLIDetection(machineId: string | null, options?: UseCLIDetect

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(expo-app): remove dead code and dedupe types`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 182 2026-01-23 b319d85e72c3

- SHA: b319d85e72c3495255b1407450886d9aaa462c2e
- Subject: fix(i18n): correct Spanish resumable label
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +1 / -1
- Touched areas: expo-app(1)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/text/translations/es.ts
```

### Diffstat

```text
 expo-app/sources/text/translations/es.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): correct Spanish resumable label
- Key files by churn (top 1):
  - expo-app/sources/text/translations/es.ts: +1/-1 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): correct Spanish resumable label`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 183 2026-01-23 46186162ae14

- SHA: 46186162ae142634423c7530c485e09cba719cba
- Subject: test(happy-cli): fix timer cleanup and MCP schema mocks
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +14 / -6
- Touched areas: cli(3)
- Topic bucket: `happy-cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/codex/codexMcpClient.test.ts
M	cli/src/ui/logger.test.ts
M	cli/src/utils/terminalStdinCleanup.test.ts
```

### Diffstat

```text
 cli/src/codex/codexMcpClient.test.ts       | 11 ++++++++---
 cli/src/ui/logger.test.ts                  |  2 +-
 cli/src/utils/terminalStdinCleanup.test.ts |  7 +++++--
 3 files changed, 14 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(happy-cli): fix timer cleanup and MCP schema mocks
- Key files by churn (top 3):
  - cli/src/codex/codexMcpClient.test.ts: +8/-3 | touches vi.mock('child_process', () => ({
  - cli/src/utils/terminalStdinCleanup.test.ts: +5/-2 | touches @@ -1 +1 @@; describe('cleanupStdinAfterInk', () => {
  - cli/src/ui/logger.test.ts: +1/-1 | touches describe('logger.debugLargeJson', () => {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(happy-cli): fix timer cleanup and MCP schema mocks`

### Topic Bucket

- `happy-cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 184 2026-01-23 ac5bf2f3abfa

- SHA: ac5bf2f3abfa54b992c42f7249084dab4424a4c7
- Subject: test(happy-cli): reset modules for runtime override
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +5 / -1
- Touched areas: cli(1)
- Topic bucket: `happy-cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/utils/spawnHappyCLI.invocation.test.ts
```

### Diffstat

```text
 cli/src/utils/spawnHappyCLI.invocation.test.ts | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(happy-cli): reset modules for runtime override
- Key files by churn (top 1):
  - cli/src/utils/spawnHappyCLI.invocation.test.ts: +5/-1 | touches @@ -4 +4 @@; describe('happy-cli subprocess invocation', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(happy-cli): reset modules for runtime override`

### Topic Bucket

- `happy-cli`

### Notes / Follow-ups


---

## 185 2026-01-23 947b8d1814fb

- SHA: 947b8d1814fbbaa486c0e8a978418ca3a7759a8b
- Subject: refactor(expo-app): remove unused optimistic flag
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +0 / -1
- Touched areas: expo-app(1)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/utils/sessionUtils.ts
```

### Diffstat

```text
 expo-app/sources/utils/sessionUtils.ts | 1 -
 1 file changed, 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(expo-app): remove unused optimistic flag
- Key files by churn (top 1):
  - expo-app/sources/utils/sessionUtils.ts: +0/-1 | removes const isOptimisticOnly | touches export function getSessionStatus(session: Session, nowMs: number = Date.now(), v

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(expo-app): remove unused optimistic flag`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 186 2026-01-23 8cc823d1ba2d

- SHA: 8cc823d1ba2d95896633fe34ab39654e04a52cb6
- Subject: fix(server-light): validate PORT and normalize paths
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 4
- Lines: +12 / -7
- Touched areas: server(4)
- Topic bucket: `server-light`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/flavors/light/env.spec.ts
M	server/sources/flavors/light/env.ts
M	server/sources/flavors/light/files.spec.ts
M	server/sources/flavors/light/files.ts
```

### Diffstat

```text
 server/sources/flavors/light/env.spec.ts   | 6 ++++++
 server/sources/flavors/light/env.ts        | 3 ++-
 server/sources/flavors/light/files.spec.ts | 1 +
 server/sources/flavors/light/files.ts      | 9 +++------
 4 files changed, 12 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server-light): validate PORT and normalize paths
- Key files by churn (top 4):
  - server/sources/flavors/light/files.ts: +3/-6 | adds const p | removes const p, const port | touches export function getLightPublicBaseUrl(env: NodeJS.ProcessEnv): string {; export function normalizePublicPath(path: string): string {; import { homedir } from 'node:os';
  - server/sources/flavors/light/env.spec.ts: +6/-0 | touches describe('light env helpers', () => {
  - server/sources/flavors/light/env.ts: +2/-1 | adds const parsed, const port | removes const port | touches export function resolveLightPublicUrl(env: LightEnv): string {
  - server/sources/flavors/light/files.spec.ts: +1/-0 | touches describe('normalizePublicPath', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server-light): validate PORT and normalize paths`

### Topic Bucket

- `server-light`

### Notes / Follow-ups


---

## 187 2026-01-23 8cb995a1abe1

- SHA: 8cb995a1abe159525864088b6b4736a5e91fc0e6
- Subject: test(server): fix schema generation sort regex
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +1 / -1
- Touched areas: server(1)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/scripts/generateSqliteSchema.spec.ts
```

### Diffstat

```text
 server/scripts/generateSqliteSchema.spec.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(server): fix schema generation sort regex
- Key files by churn (top 1):
  - server/scripts/generateSqliteSchema.spec.ts: +1/-1 | touches describe('generateSqliteSchemaFromPostgres', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(server): fix schema generation sort regex`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 188 2026-01-23 04d9c60ef8e7

- SHA: 04d9c60ef8e776c7510f6dd46570774bb3bf2b7f
- Subject: refactor(happy-cli): remove unreachable gemini error branch
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +0 / -2
- Touched areas: cli(1)
- Topic bucket: `happy-cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/gemini/utils/formatGeminiErrorForUi.ts
```

### Diffstat

```text
 cli/src/gemini/utils/formatGeminiErrorForUi.ts | 2 --
 1 file changed, 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(happy-cli): remove unreachable gemini error branch
- Key files by churn (top 1):
  - cli/src/gemini/utils/formatGeminiErrorForUi.ts: +0/-2 | touches export function formatGeminiErrorForUi(error: unknown, displayedModel?: string |

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(happy-cli): remove unreachable gemini error branch`

### Topic Bucket

- `happy-cli`

### Notes / Follow-ups


---

## 189 2026-01-23 2616e5e19253

- SHA: 2616e5e192538bd273b7fb05d265067caf755167
- Subject: fix(server): handle missing UI index.html
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +29 / -1
- Touched areas: server(2)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	server/sources/app/api/utils/enableServeUi.spec.ts
M	server/sources/app/api/utils/enableServeUi.ts
```

### Diffstat

```text
 server/sources/app/api/utils/enableServeUi.spec.ts | 20 ++++++++++++++++++++
 server/sources/app/api/utils/enableServeUi.ts      | 10 +++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): handle missing UI index.html
- Key files by churn (top 2):
  - server/sources/app/api/utils/enableServeUi.spec.ts: +20/-0 | adds const app, const dir, const res | touches @@ -0,0 +1,20 @@
  - server/sources/app/api/utils/enableServeUi.ts: +9/-1 | removes const html | touches export function enableServeUi(app: AnyFastifyInstance, ui: UiConfig) {; import { readFile, stat } from "node:fs/promises";

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): handle missing UI index.html`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 190 2026-01-23 911365366024

- SHA: 91136536602426430f50ad31bc5dc91a268f5a87
- Subject: fix(server): make build typecheck tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +3 / -0
- Touched areas: server(3)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/package.json
M	server/sources/flavors/light/env.spec.ts
M	server/sources/flavors/light/files.spec.ts
```

### Diffstat

```text
 server/package.json                        | 1 +
 server/sources/flavors/light/env.spec.ts   | 1 +
 server/sources/flavors/light/files.spec.ts | 1 +
 3 files changed, 3 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): make build typecheck tests
- Key files by churn (top 3):
  - server/sources/flavors/light/files.spec.ts: +1/-0 | touches import { normalizePublicPath } from './files';
  - server/sources/flavors/light/env.spec.ts: +1/-0 | touches import { join } from 'node:path';
  - server/package.json: +1/-0 | touches @@ -10,0 +11 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): make build typecheck tests`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 191 2026-01-23 0dd19e7fb257

- SHA: 0dd19e7fb2578a3f46f4a6cd9b5dc58f7e13e0e6
- Subject: fix(expo-app): default codex resume spec to empty
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +2 / -11
- Touched areas: expo-app(3)
- Topic bucket: `expo-app`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/ops.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
```

### Diffstat

```text
 expo-app/sources/sync/ops.ts           | 9 ---------
 expo-app/sources/sync/settings.spec.ts | 2 +-
 expo-app/sources/sync/settings.ts      | 2 +-
 3 files changed, 2 insertions(+), 11 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo-app): default codex resume spec to empty
- Key files by churn (top 3):
  - expo-app/sources/sync/ops.ts: +0/-9 | removes const session | touches export async function sessionRename(sessionId: string, title: string): Promise<S
  - expo-app/sources/sync/settings.ts: +1/-1 | touches export const settingsDefaults: Settings = {
  - expo-app/sources/sync/settings.spec.ts: +1/-1 | touches describe('settings', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo-app): default codex resume spec to empty`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups


---

## 192 2026-01-23 229e5fc36570

- SHA: 229e5fc3657000e08516acc4e5382a773598bb00
- Subject: fix(server-light): use file URLs for sqlite db
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +3 / -2
- Touched areas: server(2)
- Topic bucket: `server-light`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/flavors/light/env.spec.ts
M	server/sources/flavors/light/env.ts
```

### Diffstat

```text
 server/sources/flavors/light/env.spec.ts | 2 +-
 server/sources/flavors/light/env.ts      | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server-light): use file URLs for sqlite db
- Key files by churn (top 2):
  - server/sources/flavors/light/env.ts: +2/-1 | touches export function resolveLightDatabaseUrl(env: LightEnv, dataDir: string): string; import { homedir as defaultHomedir } from 'node:os';
  - server/sources/flavors/light/env.spec.ts: +1/-1 | touches describe('light env helpers', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server-light): use file URLs for sqlite db`

### Topic Bucket

- `server-light`

### Notes / Follow-ups


---

## 193 2026-01-23 e6f597e436c5

- SHA: e6f597e436c583b5deb111e365827ad165f51852
- Subject: fix(server): fix server-light typecheck
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +3 / -3
- Touched areas: server(2)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/storage/files.ts
M	server/tsconfig.json
```

### Diffstat

```text
 server/sources/storage/files.ts | 2 +-
 server/tsconfig.json            | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): fix server-light typecheck
- Key files by churn (top 2):
  - server/tsconfig.json: +2/-2 | touches @@ -47 +47 @@; @@ -8 +8 @@
  - server/sources/storage/files.ts: +1/-1 | touches export function initFilesS3FromEnv(env: NodeJS.ProcessEnv = process.env): void {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): fix server-light typecheck`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 194 2026-01-23 1564e800e355

- SHA: 1564e800e355e94beb66d0493a5f704011f2548e
- Subject: fix(server): relax module settings for typecheck
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +2 / -2
- Touched areas: server(1)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/tsconfig.json
```

### Diffstat

```text
 server/tsconfig.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): relax module settings for typecheck
- Key files by churn (top 1):
  - server/tsconfig.json: +2/-2 | touches @@ -47 +47 @@; @@ -8 +8 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): relax module settings for typecheck`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 195 2026-01-23 8ab11f2788c1

- SHA: 8ab11f2788c1c3a2422d62f306b65eaf951f361a
- Subject: fix(happy-cli): parse CLI versions from full output
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +3 / -3
- Touched areas: cli(1)
- Topic bucket: `happy-cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/capabilities/snapshots/cliSnapshot.ts
```

### Diffstat

```text
 cli/src/modules/common/capabilities/snapshots/cliSnapshot.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(happy-cli): parse CLI versions from full output
- Key files by churn (top 1):
  - cli/src/modules/common/capabilities/snapshots/cliSnapshot.ts: +3/-3 | adds const combined, const firstLine, const semver | removes const firstLine, const semver | touches async function detectCliVersion(params: { name: DetectCliName; resolvedPath: str; export async function detectCliSnapshotOnDaemonPath(data: DetectCliRequest): Pro

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(happy-cli): parse CLI versions from full output`

### Topic Bucket

- `happy-cli`

### Notes / Follow-ups


---

## 196 2026-01-23 21e096e9454e

- SHA: 21e096e9454e4ab8ed684aa90eb544e8dbacb14f
- Subject: fix(i18n): localize session settings item
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 10
- Lines: +29 / -2
- Touched areas: expo-app(10)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/components/SettingsView.tsx  | 4 ++--
 expo-app/sources/text/translations/ca.ts      | 3 +++
 expo-app/sources/text/translations/en.ts      | 3 +++
 expo-app/sources/text/translations/es.ts      | 3 +++
 expo-app/sources/text/translations/it.ts      | 3 +++
 expo-app/sources/text/translations/ja.ts      | 3 +++
 expo-app/sources/text/translations/pl.ts      | 3 +++
 expo-app/sources/text/translations/pt.ts      | 3 +++
 expo-app/sources/text/translations/ru.ts      | 3 +++
 expo-app/sources/text/translations/zh-Hans.ts | 3 +++
 10 files changed, 29 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize session settings item
- Key files by churn (top 8):
  - expo-app/sources/components/SettingsView.tsx: +2/-2 | touches export const SettingsView = React.memo(function SettingsView() {
  - expo-app/sources/text/translations/zh-Hans.ts: +3/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +3/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +3/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +3/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +3/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +3/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +3/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize session settings item`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 197 2026-01-23 7ca9e93196d6

- SHA: 7ca9e93196d6e6cf3eb30415ab0c692d2a05cff2
- Subject: fix(i18n): translate ExitPlanMode strings
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 8
- Lines: +40 / -40
- Touched areas: expo-app(8)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/text/translations/ca.ts      | 10 +++++-----
 expo-app/sources/text/translations/es.ts      | 10 +++++-----
 expo-app/sources/text/translations/it.ts      | 10 +++++-----
 expo-app/sources/text/translations/ja.ts      | 10 +++++-----
 expo-app/sources/text/translations/pl.ts      | 10 +++++-----
 expo-app/sources/text/translations/pt.ts      | 10 +++++-----
 expo-app/sources/text/translations/ru.ts      | 10 +++++-----
 expo-app/sources/text/translations/zh-Hans.ts | 10 +++++-----
 8 files changed, 40 insertions(+), 40 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): translate ExitPlanMode strings
- Key files by churn (top 8):
  - expo-app/sources/text/translations/zh-Hans.ts: +5/-5 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +5/-5 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +5/-5 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +5/-5 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +5/-5 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +5/-5 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +5/-5 | touches export const es: TranslationStructure = {
  - expo-app/sources/text/translations/ca.ts: +5/-5 | touches export const ca: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): translate ExitPlanMode strings`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 198 2026-01-23 c4a81947f002

- SHA: c4a81947f00288a00d1653835343015761503346
- Subject: fix(i18n): localize search error
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +56 / -8
- Touched areas: expo-app(3)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/friends/search.tsx
A	expo-app/sources/hooks/useSearch.hook.test.ts
M	expo-app/sources/hooks/useSearch.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/friends/search.tsx |  8 +++--
 expo-app/sources/hooks/useSearch.hook.test.ts | 44 +++++++++++++++++++++++++++
 expo-app/sources/hooks/useSearch.ts           | 12 +++++---
 3 files changed, 56 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize search error
- Key files by churn (top 3):
  - expo-app/sources/hooks/useSearch.hook.test.ts: +44/-0 | adds const searchFn, function Test | touches @@ -0,0 +1,44 @@
  - expo-app/sources/hooks/useSearch.ts: +7/-5 | adds type UseSearchError | touches export function useSearch<T>(; import { useEffect, useRef, useState, useCallback } from 'react';
  - expo-app/sources/app/(app)/friends/search.tsx: +5/-3 | adds const searchErrorText | touches const styles = StyleSheet.create((theme) => ({; export default function SearchFriendsScreen() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize search error`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 199 2026-01-23 208f0222a997

- SHA: 208f0222a997dd9f9dd2ec8ed7eef9dcb91b842a
- Subject: fix(i18n): localize Codex resume dialog
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 10
- Lines: +119 / -18
- Touched areas: expo-app(10)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/index.tsx      | 95 ++++++++++++++++++++++-----
 expo-app/sources/text/translations/ca.ts      |  4 ++
 expo-app/sources/text/translations/en.ts      |  4 ++
 expo-app/sources/text/translations/es.ts      |  4 ++
 expo-app/sources/text/translations/it.ts      |  4 ++
 expo-app/sources/text/translations/ja.ts      | 10 ++-
 expo-app/sources/text/translations/pl.ts      |  4 ++
 expo-app/sources/text/translations/pt.ts      |  4 ++
 expo-app/sources/text/translations/ru.ts      |  4 ++
 expo-app/sources/text/translations/zh-Hans.ts |  4 ++
 10 files changed, 119 insertions(+), 18 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize Codex resume dialog
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/new/index.tsx: +80/-15 | touches function NewSessionScreen() {; import { Modal } from '@/modal';
  - expo-app/sources/text/translations/ja.ts: +7/-3 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/zh-Hans.ts: +4/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +4/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +4/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +4/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +4/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +4/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize Codex resume dialog`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 200 2026-01-23 02ad6b4a8352

- SHA: 02ad6b4a8352635f173dfdb1bf96109135255d58
- Subject: fix(i18n): move openMachine to connect scope
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 9
- Lines: +9 / -9
- Touched areas: expo-app(9)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/index.tsx      | 2 +-
 expo-app/sources/text/translations/ca.ts      | 2 +-
 expo-app/sources/text/translations/es.ts      | 2 +-
 expo-app/sources/text/translations/it.ts      | 2 +-
 expo-app/sources/text/translations/ja.ts      | 2 +-
 expo-app/sources/text/translations/pl.ts      | 2 +-
 expo-app/sources/text/translations/pt.ts      | 2 +-
 expo-app/sources/text/translations/ru.ts      | 2 +-
 expo-app/sources/text/translations/zh-Hans.ts | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): move openMachine to connect scope
- Key files by churn (top 8):
  - expo-app/sources/text/translations/zh-Hans.ts: +1/-1 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +1/-1 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +1/-1 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +1/-1 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +1/-1 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +1/-1 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +1/-1 | touches export const es: TranslationStructure = {
  - expo-app/sources/text/translations/ca.ts: +1/-1 | touches export const ca: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): move openMachine to connect scope`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 201 2026-01-23 ce42bf56d7b6

- SHA: ce42bf56d7b682929ce1022293c8cbaa78918711
- Subject: fix(web): correct libsodium wrapper typing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +12 / -2
- Touched areas: expo-app(1)
- Topic bucket: `web`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/encryption/libsodium.lib.web.ts
```

### Diffstat

```text
 expo-app/sources/encryption/libsodium.lib.web.ts | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(web): correct libsodium wrapper typing
- Key files by churn (top 1):
  - expo-app/sources/encryption/libsodium.lib.web.ts: +12/-2 | adds const sodium | touches import sodium from 'libsodium-wrappers';; import type sodiumType from 'libsodium-wrappers';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(web): correct libsodium wrapper typing`

### Topic Bucket

- `web`

### Notes / Follow-ups


---

## 202 2026-01-23 f0417ca11ac5

- SHA: f0417ca11ac5112ee9f9a38b6d0b3bdbf644749b
- Subject: fix(web): keep libsodium wrapper namespace typing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +1 / -1
- Touched areas: expo-app(1)
- Topic bucket: `web`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/encryption/libsodium.lib.web.ts
```

### Diffstat

```text
 expo-app/sources/encryption/libsodium.lib.web.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(web): keep libsodium wrapper namespace typing
- Key files by churn (top 1):
  - expo-app/sources/encryption/libsodium.lib.web.ts: +1/-1 | touches const sodium = require('libsodium-wrappers/dist/modules/libsodium-wrappers.js');

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(web): keep libsodium wrapper namespace typing`

### Topic Bucket

- `web`

### Notes / Follow-ups


---

## 203 2026-01-23 b6d3874bf175

- SHA: b6d3874bf175911f2dea935203994ce6027d6ad1
- Subject: fix(settings): include Codex resume in master experiment toggle
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +2 / -0
- Touched areas: expo-app(1)
- Topic bucket: `settings`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx | 2 ++
 1 file changed, 2 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(settings): include Codex resume in master experiment toggle
- Key files by churn (top 1):
  - expo-app/sources/app/(app)/settings/features.tsx: +2/-0 | touches export default React.memo(function FeaturesSettingsScreen() {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(settings): include Codex resume in master experiment toggle`

### Topic Bucket

- `settings`

### Notes / Follow-ups


---

## 204 2026-01-23 a4d7faba961f

- SHA: a4d7faba961f201272071834324f270be4ad93e7
- Subject: fix(i18n): localize session error fallbacks
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 10
- Lines: +67 / -13
- Touched areas: expo-app(10)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx     | 26 +++++++++++++-------------
 expo-app/sources/text/translations/ca.ts      |  6 ++++++
 expo-app/sources/text/translations/en.ts      |  6 ++++++
 expo-app/sources/text/translations/es.ts      |  6 ++++++
 expo-app/sources/text/translations/it.ts      |  6 ++++++
 expo-app/sources/text/translations/ja.ts      |  6 ++++++
 expo-app/sources/text/translations/pl.ts      |  6 ++++++
 expo-app/sources/text/translations/pt.ts      |  6 ++++++
 expo-app/sources/text/translations/ru.ts      |  6 ++++++
 expo-app/sources/text/translations/zh-Hans.ts |  6 ++++++
 10 files changed, 67 insertions(+), 13 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize session error fallbacks
- Key files by churn (top 8):
  - expo-app/sources/-session/SessionView.tsx: +13/-13 | adds const profileId, const profileInfo | removes const profileId, const profileInfo | touches function SessionViewLoaded({ sessionId, session }: { sessionId: string, session:
  - expo-app/sources/text/translations/zh-Hans.ts: +6/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +6/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +6/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +6/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +6/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +6/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +6/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize session error fallbacks`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 205 2026-01-23 1ea2bddb8bbd

- SHA: 1ea2bddb8bbd522d3c3353ceb17f4f6eab40ade3
- Subject: test(server): validate processImage resize output
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +11 / -6
- Touched areas: server(1)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/storage/processImage.spec.ts
```

### Diffstat

```text
 server/sources/storage/processImage.spec.ts | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(server): validate processImage resize output
- Key files by churn (top 1):
  - server/sources/storage/processImage.spec.ts: +11/-6 | adds const originalHeight, const originalWidth, const targetHeight, const targetWidth | touches describe('processImage', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(server): validate processImage resize output`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 206 2026-01-23 1e7d7f8a4747

- SHA: 1e7d7f8a4747a5ac249d1b8b0738bb6d841e397a
- Subject: fix(server): keep light server running
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +0 / -3
- Touched areas: server(1)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/main.light.ts
```

### Diffstat

```text
 server/sources/main.light.ts | 3 ---
 1 file changed, 3 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): keep light server running
- Key files by churn (top 1):
  - server/sources/main.light.ts: +0/-3 | touches startServer('light').catch((e) => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): keep light server running`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 207 2026-01-23 61bf70183ebf

- SHA: 61bf70183ebff64ec14716cee0ccf8c1b2a59ea4
- Subject: test(cli): set DEBUG before importing logger
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +2 / -1
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/ui/logger.test.ts
```

### Diffstat

```text
 cli/src/ui/logger.test.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(cli): set DEBUG before importing logger
- Key files by churn (top 1):
  - cli/src/ui/logger.test.ts: +2/-1 | touches describe('logger.debugLargeJson', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(cli): set DEBUG before importing logger`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 208 2026-01-23 61a18ac95e17

- SHA: 61a18ac95e1701c5b5ec245053b39cba1a906d6e
- Subject: fix(tools): require permission id for ExitPlanMode actions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 11
- Lines: +100 / -6
- Touched areas: expo-app(11)
- Topic bucket: `tools`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/views/ExitPlanToolView.test.ts
M	expo-app/sources/components/tools/views/ExitPlanToolView.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 .../tools/views/ExitPlanToolView.test.ts           | 78 ++++++++++++++++++++++
 .../components/tools/views/ExitPlanToolView.tsx    | 19 ++++--
 expo-app/sources/text/translations/ca.ts           |  1 +
 expo-app/sources/text/translations/en.ts           |  1 +
 expo-app/sources/text/translations/es.ts           |  1 +
 expo-app/sources/text/translations/it.ts           |  1 +
 expo-app/sources/text/translations/ja.ts           |  1 +
 expo-app/sources/text/translations/pl.ts           |  1 +
 expo-app/sources/text/translations/pt.ts           |  1 +
 expo-app/sources/text/translations/ru.ts           |  1 +
 expo-app/sources/text/translations/zh-Hans.ts      |  1 +
 11 files changed, 100 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tools): require permission id for ExitPlanMode actions
- Key files by churn (top 8):
  - expo-app/sources/components/tools/views/ExitPlanToolView.test.ts: +78/-0 | adds const buttons, const buttonsAfter, const modalAlert | touches const sendMessage = vi.fn();; describe('ExitPlanToolView', () => {; vi.mock('@/text', () => ({
  - expo-app/sources/components/tools/views/ExitPlanToolView.tsx: +13/-6 | adds const permissionId | touches export const ExitPlanToolView = React.memo<ToolViewProps>(({ tool, sessionId }); import { sessionAllow, sessionDeny } from '@/sync/ops';
  - expo-app/sources/text/translations/zh-Hans.ts: +1/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +1/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +1/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +1/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +1/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +1/-0 | touches export const it: TranslationStructure = {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tools): require permission id for ExitPlanMode actions`

### Topic Bucket

- `tools`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 209 2026-01-23 5b36c9bf91c1

- SHA: 5b36c9bf91c115079c627b8428065f2275ae71c9
- Subject: test(tools): avoid null permission in ExitPlanToolView tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +2 / -2
- Touched areas: expo-app(1)
- Topic bucket: `tools`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/views/ExitPlanToolView.test.ts
```

### Diffstat

```text
 expo-app/sources/components/tools/views/ExitPlanToolView.test.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(tools): avoid null permission in ExitPlanToolView tests
- Key files by churn (top 1):
  - expo-app/sources/components/tools/views/ExitPlanToolView.test.ts: +2/-2 | touches describe('ExitPlanToolView', () => {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(tools): avoid null permission in ExitPlanToolView tests`

### Topic Bucket

- `tools`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 210 2026-01-23 b7f63e928e4f

- SHA: b7f63e928e4f999ddb69a3b09071fb8b75306978
- Subject: fix(persistence): retry daemon state read when file appears
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +51 / -4
- Touched areas: cli(2)
- Topic bucket: `persistence`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/persistence.daemonState.test.ts
M	cli/src/persistence.ts
```

### Diffstat

```text
 cli/src/persistence.daemonState.test.ts | 45 +++++++++++++++++++++++++++++++++
 cli/src/persistence.ts                  | 10 +++++---
 2 files changed, 51 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(persistence): retry daemon state read when file appears
- Key files by churn (top 2):
  - cli/src/persistence.daemonState.test.ts: +45/-0 | adds const homeDir, const previousHomeDir, const state | touches @@ -0,0 +1,45 @@
  - cli/src/persistence.ts: +6/-4 | adds const err | touches export async function readDaemonState(): Promise<DaemonLocallyPersistedState | n

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(persistence): retry daemon state read when file appears`

### Topic Bucket

- `persistence`

### Notes / Follow-ups


---

## 211 2026-01-23 55428fb0253c

- SHA: 55428fb0253c6cf2df46095083f6016734506f27
- Subject: fix(tools): alert when AskUserQuestion permission id is missing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +59 / -1
- Touched areas: expo-app(2)
- Topic bucket: `tools`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/views/AskUserQuestionView.test.ts
M	expo-app/sources/components/tools/views/AskUserQuestionView.tsx
```

### Diffstat

```text
 .../tools/views/AskUserQuestionView.test.ts        | 56 ++++++++++++++++++++++
 .../components/tools/views/AskUserQuestionView.tsx |  4 +-
 2 files changed, 59 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(tools): alert when AskUserQuestion permission id is missing
- Key files by churn (top 2):
  - expo-app/sources/components/tools/views/AskUserQuestionView.test.ts: +56/-0 | adds const modalAlert, const touchables | touches const sessionInteractionRespond = vi.fn();; describe('AskUserQuestionView', () => {; vi.mock('@/text', () => ({
  - expo-app/sources/components/tools/views/AskUserQuestionView.tsx: +3/-1 | touches export const AskUserQuestionView = React.memo<ToolViewProps>(({ tool, sessionId; import { sync } from '@/sync/sync';

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(tools): alert when AskUserQuestion permission id is missing`

### Topic Bucket

- `tools`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 212 2026-01-23 dc6955f88abd

- SHA: dc6955f88abd46b63e56102ccd936b0f59ea41e4
- Subject: fix(terminal): prevent sessionId path traversal in attachment info
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +66 / -5
- Touched areas: cli(2)
- Topic bucket: `terminal`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/terminal/terminalAttachmentInfo.test.ts
M	cli/src/terminal/terminalAttachmentInfo.ts
```

### Diffstat

```text
 cli/src/terminal/terminalAttachmentInfo.test.ts | 49 ++++++++++++++++++++++++-
 cli/src/terminal/terminalAttachmentInfo.ts      | 22 +++++++++--
 2 files changed, 66 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(terminal): prevent sessionId path traversal in attachment info
- Key files by churn (top 2):
  - cli/src/terminal/terminalAttachmentInfo.test.ts: +47/-2 | adds const dir, const encodedFileName, const info, const legacyPath, const parsed, const raw | touches describe('terminalAttachmentInfo', () => {; import * as tmp from 'tmp';
  - cli/src/terminal/terminalAttachmentInfo.ts: +19/-3 | adds const encodedPath, const err, const legacyPath, function legacySessionFilePath, function sessionIdToFilename | removes const path, const raw | touches export async function readTerminalAttachmentInfo(params: {; function sessionFilePath(happyHomeDir: string, sessionId: string): string {; function sessionsDir(happyHomeDir: string): string {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(terminal): prevent sessionId path traversal in attachment info`

### Topic Bucket

- `terminal`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 213 2026-01-23 bb685fbeff7b

- SHA: bb685fbeff7bda2707f656c5d8c0831b95f874f9
- Subject: fix(terminal): clarify missing --happy-starting-mode value
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +7 / -2
- Touched areas: cli(2)
- Topic bucket: `terminal`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/terminal/headlessTmuxArgs.test.ts
M	cli/src/terminal/headlessTmuxArgs.ts
```

### Diffstat

```text
 cli/src/terminal/headlessTmuxArgs.test.ts | 5 ++++-
 cli/src/terminal/headlessTmuxArgs.ts      | 4 +++-
 2 files changed, 7 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(terminal): clarify missing --happy-starting-mode value
- Key files by churn (top 2):
  - cli/src/terminal/headlessTmuxArgs.test.ts: +4/-1 | touches describe('ensureRemoteStartingModeArgs', () => {
  - cli/src/terminal/headlessTmuxArgs.ts: +3/-1 | touches export function ensureRemoteStartingModeArgs(argv: string[]): string[] {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(terminal): clarify missing --happy-starting-mode value`

### Topic Bucket

- `terminal`

### Notes / Follow-ups


---

## 214 2026-01-23 5bcc7d20cd6b

- SHA: 5bcc7d20cd6b14c30f3c36cbbe73f7c4317d5d37
- Subject: test(utils): stabilize serverConnectionErrors retry count test
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +9 / -7
- Touched areas: cli(1)
- Topic bucket: `utils`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/utils/serverConnectionErrors.test.ts
```

### Diffstat

```text
 cli/src/utils/serverConnectionErrors.test.ts | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(utils): stabilize serverConnectionErrors retry count test
- Key files by churn (top 1):
  - cli/src/utils/serverConnectionErrors.test.ts: +9/-7 | adds const randomSpy | touches describe('startOfflineReconnection', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(utils): stabilize serverConnectionErrors retry count test`

### Topic Bucket

- `utils`

### Notes / Follow-ups


---

## 215 2026-01-23 82968aa8fe6c

- SHA: 82968aa8fe6c0b18c4aa8aac76d398dca3decea2
- Subject: fix(ui): send pending messages before closing modal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +172 / -4
- Touched areas: expo-app(2)
- Topic bucket: `ui`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/components/PendingMessagesModal.test.ts
M	expo-app/sources/components/PendingMessagesModal.tsx
```

### Diffstat

```text
 .../components/PendingMessagesModal.test.ts        | 160 +++++++++++++++++++++
 .../sources/components/PendingMessagesModal.tsx    |  16 ++-
 2 files changed, 172 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ui): send pending messages before closing modal
- Key files by churn (top 2):
  - expo-app/sources/components/PendingMessagesModal.test.ts: +160/-0 | adds const abortOrder, const closeOrder, const deleteDiscardedPendingMessage, const deleteOrder, const deletePendingMessage, const fetchPendingMessages | touches @@ -0,0 +1,160 @@
  - expo-app/sources/components/PendingMessagesModal.tsx: +12/-4 | touches export function PendingMessagesModal(props: { sessionId: string; onClose: () =>; function ActionButton(props: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ui): send pending messages before closing modal`

### Topic Bucket

- `ui`

### Notes / Follow-ups


---

## 216 2026-01-23 b7219c8bfe2b

- SHA: b7219c8bfe2b32b86e8fb35fb17bc8b977d7394f
- Subject: fix(ink): avoid async useInput handler
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +13 / -5
- Touched areas: cli(1)
- Topic bucket: `ink`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/ui/ink/RemoteModeDisplay.tsx
```

### Diffstat

```text
 cli/src/ui/ink/RemoteModeDisplay.tsx | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(ink): avoid async useInput handler
- Key files by churn (top 1):
  - cli/src/ui/ink/RemoteModeDisplay.tsx: +13/-5 | adds const actionTimeoutRef | touches export const RemoteModeDisplay: React.FC<RemoteModeDisplayProps> = ({ messageBuf

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(ink): avoid async useInput handler`

### Topic Bucket

- `ink`

### Notes / Follow-ups


---

## 217 2026-01-23 d70a6f6669fe

- SHA: d70a6f6669feef788c724d53f66c58041c68d561
- Subject: fix(claude): trim CLAUDE_CONFIG_DIR overrides
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +9 / -1
- Touched areas: cli(2)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/utils/path.test.ts
M	cli/src/claude/utils/path.ts
```

### Diffstat

```text
 cli/src/claude/utils/path.test.ts | 7 +++++++
 cli/src/claude/utils/path.ts      | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(claude): trim CLAUDE_CONFIG_DIR overrides
- Key files by churn (top 2):
  - cli/src/claude/utils/path.test.ts: +7/-0 | adds const result, const workingDir | touches describe('getProjectPath', () => {
  - cli/src/claude/utils/path.ts: +2/-1 | adds const claudeConfigDir, const claudeConfigDirTrimmed | removes const claudeConfigDir | touches export function getProjectPath(workingDirectory: string, claudeConfigDirOverride

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(claude): trim CLAUDE_CONFIG_DIR overrides`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 218 2026-01-23 47f638b73fca

- SHA: 47f638b73fca8b4ca64edd08ddbe3e0f74344b43
- Subject: test(utils): cover failuresCount with custom backoff
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +32 / -1
- Touched areas: cli(1)
- Topic bucket: `utils`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/utils/sync.test.ts
```

### Diffstat

```text
 cli/src/utils/sync.test.ts | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(utils): cover failuresCount with custom backoff
- Key files by churn (top 1):
  - cli/src/utils/sync.test.ts: +32/-1 | adds const backoff, const sync | touches describe('InvalidateSync', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(utils): cover failuresCount with custom backoff`

### Topic Bucket

- `utils`

### Notes / Follow-ups


---

## 219 2026-01-23 2abc70fef03c

- SHA: 2abc70fef03c2cb70867ac4e853177d8e4c63b1a
- Subject: fix(utils): track failuresCount for custom backoff
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +13 / -8
- Touched areas: cli(1)
- Topic bucket: `utils`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/utils/sync.ts
```

### Diffstat

```text
 cli/src/utils/sync.ts | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(utils): track failuresCount for custom backoff
- Key files by churn (top 1):
  - cli/src/utils/sync.ts: +13/-8 | touches export class InvalidateSync {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(utils): track failuresCount for custom backoff`

### Topic Bucket

- `utils`

### Notes / Follow-ups


---

## 220 2026-01-23 dc8016f01c56

- SHA: dc8016f01c561d77cedb6650d7c2564f92bea88d
- Subject: fix(server): validate HAPPY_SERVER_LIGHT_DATA_DIR for light migrations
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 3
- Lines: +67 / -5
- Touched areas: server(3)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/scripts/migrate.light.deploy.ts
A	server/scripts/migrate.light.deployPlan.spec.ts
A	server/scripts/migrate.light.deployPlan.ts
```

### Diffstat

```text
 server/scripts/migrate.light.deploy.ts          | 10 +++----
 server/scripts/migrate.light.deployPlan.spec.ts | 37 +++++++++++++++++++++++++
 server/scripts/migrate.light.deployPlan.ts      | 25 +++++++++++++++++
 3 files changed, 67 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): validate HAPPY_SERVER_LIGHT_DATA_DIR for light migrations
- Key files by churn (top 3):
  - server/scripts/migrate.light.deployPlan.spec.ts: +37/-0 | adds const plan | touches @@ -0,0 +1,37 @@
  - server/scripts/migrate.light.deployPlan.ts: +25/-0 | adds const dataDir, const prismaSchemaPath, const raw, function buildLightMigrateDeployPlan, function requireLightDataDir, type LightMigrateDeployPlan | touches @@ -0,0 +1,25 @@
  - server/scripts/migrate.light.deploy.ts: +5/-5 | adds const plan | removes const dataDir | touches async function main() {; import { applyLightDefaultEnv } from '@/flavors/light/env';; main().catch((err) => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): validate HAPPY_SERVER_LIGHT_DATA_DIR for light migrations`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 221 2026-01-23 b0085827322c

- SHA: b0085827322c0affa0a0d014b130f6fa26f32e00
- Subject: fix(server): handle missing UI index in error handlers
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +49 / -7
- Touched areas: server(2)
- Topic bucket: `server`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	server/sources/app/api/utils/enableErrorHandlers.spec.ts
M	server/sources/app/api/utils/enableErrorHandlers.ts
```

### Diffstat

```text
 .../app/api/utils/enableErrorHandlers.spec.ts      | 33 ++++++++++++++++++++++
 .../sources/app/api/utils/enableErrorHandlers.ts   | 23 ++++++++++-----
 2 files changed, 49 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server): handle missing UI index in error handlers
- Key files by churn (top 2):
  - server/sources/app/api/utils/enableErrorHandlers.spec.ts: +33/-0 | adds const app, const dir, const prevUiDir, const prevUiPrefix, const res | touches @@ -0,0 +1,33 @@
  - server/sources/app/api/utils/enableErrorHandlers.ts: +16/-7 | adds const mtimeMs, const st | removes const mtimeMs, const st | touches export function enableErrorHandlers(app: Fastify) {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server): handle missing UI index in error handlers`

### Topic Bucket

- `server`

### Notes / Follow-ups


---

## 222 2026-01-23 abf288056636

- SHA: abf28805663692bd6fce36b5d91b5041a5e9b75b
- Subject: fix(cli): reject invalid messageQueueV1 inFlight
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +19 / -2
- Touched areas: cli(2)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/messageQueueV1.test.ts
M	cli/src/api/messageQueueV1.ts
```

### Diffstat

```text
 cli/src/api/messageQueueV1.test.ts |  9 +++++++++
 cli/src/api/messageQueueV1.ts      | 12 ++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): reject invalid messageQueueV1 inFlight
- Key files by churn (top 2):
  - cli/src/api/messageQueueV1.ts: +10/-2 | adds const parsed | removes const inFlight | touches export function parseMessageQueueV1(raw: unknown): MessageQueueV1 | null {
  - cli/src/api/messageQueueV1.test.ts: +9/-0 | adds const parsed | touches describe('messageQueueV1', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): reject invalid messageQueueV1 inFlight`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 223 2026-01-23 73ce32d242a0

- SHA: 73ce32d242a050a44cdf4cb70439abcd594fcde1
- Subject: fix(i18n): translate Spanish experiment subtitles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +8 / -8
- Touched areas: expo-app(1)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/text/translations/es.ts
```

### Diffstat

```text
 expo-app/sources/text/translations/es.ts | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): translate Spanish experiment subtitles
- Key files by churn (top 1):
  - expo-app/sources/text/translations/es.ts: +8/-8 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): translate Spanish experiment subtitles`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 224 2026-01-23 98bc00096e86

- SHA: 98bc00096e866770f8dac6f82b5a7028012c2dd2
- Subject: fix(i18n): localize Codex resume banner
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 10
- Lines: +161 / -66
- Touched areas: expo-app(10)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 .../sources/app/(app)/new/NewSessionWizard.tsx     | 119 +++++++++------------
 expo-app/sources/text/translations/ca.ts           |  12 +++
 expo-app/sources/text/translations/en.ts           |  12 +++
 expo-app/sources/text/translations/es.ts           |  12 +++
 expo-app/sources/text/translations/it.ts           |  12 +++
 expo-app/sources/text/translations/ja.ts           |  12 +++
 expo-app/sources/text/translations/pl.ts           |  12 +++
 expo-app/sources/text/translations/pt.ts           |  12 +++
 expo-app/sources/text/translations/ru.ts           |  12 +++
 expo-app/sources/text/translations/zh-Hans.ts      |  12 +++
 10 files changed, 161 insertions(+), 66 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize Codex resume banner
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/new/NewSessionWizard.tsx: +53/-66 | touches export const NewSessionWizard = React.memo(function NewSessionWizard(props: NewS; import type { PermissionMode, ModelMode } from '@/sync/permissionTypes';; import { PathSelector } from '@/components/newSession/PathSelector';
  - expo-app/sources/text/translations/zh-Hans.ts: +12/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +12/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +12/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +12/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +12/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +12/-0 | touches export const it: TranslationStructure = {
  - expo-app/sources/text/translations/es.ts: +12/-0 | touches export const es: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize Codex resume banner`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 225 2026-01-23 4fabec9b69b3

- SHA: 4fabec9b69b30538cc4360762bc8d7af77cc65bb
- Subject: feat(new-session): add WizardSectionHeaderRow
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +44 / -0
- Touched areas: expo-app(1)
- Topic bucket: `new-session`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/components/newSession/WizardSectionHeaderRow.tsx
```

### Diffstat

```text
 .../newSession/WizardSectionHeaderRow.tsx          | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(new-session): add WizardSectionHeaderRow
- Key files by churn (top 1):
  - expo-app/sources/components/newSession/WizardSectionHeaderRow.tsx: +44/-0 | adds const WizardSectionHeaderRow, type WizardSectionHeaderRowAction, type WizardSectionHeaderRowProps | touches @@ -0,0 +1,44 @@

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(new-session): add WizardSectionHeaderRow`

### Topic Bucket

- `new-session`

### Notes / Follow-ups


---

## 226 2026-01-23 c461ed1cb4ef

- SHA: c461ed1cb4efd785a2d60be60c63aca8349dc1a1
- Subject: feat(permission): add permission mode option helpers
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +74 / -0
- Touched areas: expo-app(1)
- Topic bucket: `permission`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/sync/permissionModeOptions.ts
```

### Diffstat

```text
 expo-app/sources/sync/permissionModeOptions.ts | 74 ++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): feat(permission): add permission mode option helpers
- Key files by churn (top 1):
  - expo-app/sources/sync/permissionModeOptions.ts: +74/-0 | adds function getPermissionModeLabelForAgentType, function getPermissionModeOptionsForAgentType, function getPermissionModeTitleForAgentType, function getPermissionModesForAgentType, function normalizePermissionModeForAgentType, type PermissionModeOption | touches @@ -0,0 +1,74 @@

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `feat(permission): add permission mode option helpers`

### Topic Bucket

- `permission`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 227 2026-01-23 23b595edd0fe

- SHA: 23b595edd0fe59e36481574f0ca958343a233dc2
- Subject: refactor(sync): simplify path formatting
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +1 / -7
- Touched areas: expo-app(1)
- Topic bucket: `sync`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/sync/sessionListViewData.ts
```

### Diffstat

```text
 expo-app/sources/sync/sessionListViewData.ts | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(sync): simplify path formatting
- Key files by churn (top 1):
  - expo-app/sources/sync/sessionListViewData.ts: +1/-7 | touches function formatPathRelativeToHome(path: string, homeDir?: string | null): string

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(sync): simplify path formatting`

### Topic Bucket

- `sync`

### Notes / Follow-ups


---

## 228 2026-01-23 523989b4de8e

- SHA: 523989b4de8ea8a339a1605a756250feaadb14ec
- Subject: fix(server-light): avoid master secret race
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +16 / -2
- Touched areas: server(1)
- Topic bucket: `server-light`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/flavors/light/env.ts
```

### Diffstat

```text
 server/sources/flavors/light/env.ts | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server-light): avoid master secret race
- Key files by churn (top 1):
  - server/sources/flavors/light/env.ts: +16/-2 | adds const existing | touches export async function ensureHandyMasterSecret(env: LightEnv, opts?: { dataDir?:

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server-light): avoid master secret race`

### Topic Bucket

- `server-light`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 229 2026-01-23 d89a9427e765

- SHA: d89a9427e765ed8c176ff2049fd2fc965132139a
- Subject: fix(cli): clean up metadata waiters on disconnect
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +31 / -7
- Touched areas: cli(2)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/apiSession.test.ts
M	cli/src/api/apiSession.ts
```

### Diffstat

```text
 cli/src/api/apiSession.test.ts | 29 ++++++++++++++++++++++-------
 cli/src/api/apiSession.ts      |  9 +++++++++
 2 files changed, 31 insertions(+), 7 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): clean up metadata waiters on disconnect
- Key files by churn (top 2):
  - cli/src/api/apiSession.test.ts: +22/-7 | adds const client, const disconnectHandlers, const lastDisconnectHandler, const waitPromise | removes const client, const waitPromise | touches describe('ApiSessionClient connection handling', () => {
  - cli/src/api/apiSession.ts: +9/-0 | adds const onDisconnect | touches export class ApiSessionClient extends EventEmitter {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): clean up metadata waiters on disconnect`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 230 2026-01-23 fedb8a66160a

- SHA: fedb8a66160ae16ec6c713cf84348a84d3632cc6
- Subject: test(cli): accept lowercase preview-env keys
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +17 / -0
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts
```

### Diffstat

```text
 .../common/registerCommonHandlers.previewEnv.test.ts    | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): test(cli): accept lowercase preview-env keys
- Key files by churn (top 1):
  - cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts: +17/-0 | adds const result | touches describe('registerCommonHandlers preview-env', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(cli): accept lowercase preview-env keys`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 231 2026-01-23 fc0ce89b13b7

- SHA: fc0ce89b13b7fe1119ed6c966dc3709b0a83e78c
- Subject: fix(cli): allow lowercase preview-env keys
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +19 / -6
- Touched areas: cli(2)
- Topic bucket: `cli`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/modules/common/previewEnv/registerPreviewEnvHandler.ts
M	cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts
```

### Diffstat

```text
 .../modules/common/previewEnv/registerPreviewEnvHandler.ts  | 13 +++++++------
 .../common/registerCommonHandlers.previewEnv.test.ts        | 12 ++++++++++++
 2 files changed, 19 insertions(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): allow lowercase preview-env keys
- Key files by churn (top 2):
  - cli/src/modules/common/previewEnv/registerPreviewEnvHandler.ts: +7/-6 | adds const forbiddenKeys, const isValidEnvVarKey, const validNameRegex | removes const validNameRegex | touches export function registerPreviewEnvHandler(rpcHandlerManager: RpcHandlerManager):
  - cli/src/modules/common/registerCommonHandlers.previewEnv.test.ts: +12/-0 | adds const result | touches describe('registerCommonHandlers preview-env', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): allow lowercase preview-env keys`

### Topic Bucket

- `cli`

### Notes / Follow-ups


---

## 232 2026-01-23 ad95c5b01c25

- SHA: ad95c5b01c2590f24582f6336621088e3788634c
- Subject: test(happy): keep useCLIDetection timestamp stable
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +52 / -0
- Touched areas: expo-app(1)
- Topic bucket: `happy`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.hook.test.ts
```

### Diffstat

```text
 .../sources/hooks/useCLIDetection.hook.test.ts     | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): test(happy): keep useCLIDetection timestamp stable
- Key files by churn (top 1):
  - expo-app/sources/hooks/useCLIDetection.hook.test.ts: +52/-0 | adds const root, function Test | touches describe('useCLIDetection (hook)', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(happy): keep useCLIDetection timestamp stable`

### Topic Bucket

- `happy`

### Notes / Follow-ups


---

## 233 2026-01-23 c251edf3c307

- SHA: c251edf3c307d33fba9dad71739a9a7f0396cb15
- Subject: test(happy): fix useCLIDetection timestamp test
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +47 / -42
- Touched areas: expo-app(1)
- Topic bucket: `happy`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.hook.test.ts
```

### Diffstat

```text
 .../sources/hooks/useCLIDetection.hook.test.ts     | 89 ++++++++++++----------
 1 file changed, 47 insertions(+), 42 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(happy): fix useCLIDetection timestamp test
- Key files by churn (top 1):
  - expo-app/sources/hooks/useCLIDetection.hook.test.ts: +47/-42 | adds function Test | removes const root, function Test | touches describe('useCLIDetection (hook)', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(happy): fix useCLIDetection timestamp test`

### Topic Bucket

- `happy`

### Notes / Follow-ups


---

## 234 2026-01-23 34fa4091d3cc

- SHA: 34fa4091d3cc376ae79bfbcc59688dae762c0b61
- Subject: fix(happy): stabilize useCLIDetection timestamp
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +11 / -12
- Touched areas: expo-app(1)
- Topic bucket: `happy`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.ts
```

### Diffstat

```text
 expo-app/sources/hooks/useCLIDetection.ts | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(happy): stabilize useCLIDetection timestamp
- Key files by churn (top 1):
  - expo-app/sources/hooks/useCLIDetection.ts: +11/-12 | adds const fallbackDetectAtRef, const request | removes const request | touches export function useCLIDetection(machineId: string | null, options?: UseCLIDetect; import type { CapabilityDetectResult, CliCapabilityData, TmuxCapabilityData } fr

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(happy): stabilize useCLIDetection timestamp`

### Topic Bucket

- `happy`

### Notes / Follow-ups


---

## 235 2026-01-23 31340e53294c

- SHA: 31340e53294c92e12b95cac429fdcc3e0c100af4
- Subject: fix(happy): inline CLI detection request
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +11 / -4
- Touched areas: expo-app(1)
- Topic bucket: `happy`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/hooks/useCLIDetection.ts
```

### Diffstat

```text
 expo-app/sources/hooks/useCLIDetection.ts | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(happy): inline CLI detection request
- Key files by churn (top 1):
  - expo-app/sources/hooks/useCLIDetection.ts: +11/-4 | adds const request | removes const request | touches export function useCLIDetection(machineId: string | null, options?: UseCLIDetect; import type { CapabilityDetectResult, CliCapabilityData, TmuxCapabilityData } fr

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(happy): inline CLI detection request`

### Topic Bucket

- `happy`

### Notes / Follow-ups


---

## 236 2026-01-23 054250f408e2

- SHA: 054250f408e21f9c2208ef306d574674796356b8
- Subject: fix(i18n): localize codex resume install modals
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 11
- Lines: +143 / -16
- Touched areas: expo-app(11)
- Topic bucket: `i18n`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/machine/[id].tsx   | 24 +++++++++++++++---------
 expo-app/sources/app/(app)/new/index.tsx      | 18 +++++++++++-------
 expo-app/sources/text/translations/ca.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/en.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/es.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/it.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/ja.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/pl.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/pt.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/ru.ts      | 13 +++++++++++++
 expo-app/sources/text/translations/zh-Hans.ts | 13 +++++++++++++
 11 files changed, 143 insertions(+), 16 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(i18n): localize codex resume install modals
- Key files by churn (top 8):
  - expo-app/sources/app/(app)/machine/[id].tsx: +15/-9 | touches export default function MachineDetailScreen() {
  - expo-app/sources/app/(app)/new/index.tsx: +11/-7 | touches function NewSessionScreen() {
  - expo-app/sources/text/translations/zh-Hans.ts: +13/-0 | touches export const zhHans: TranslationStructure = {
  - expo-app/sources/text/translations/ru.ts: +13/-0 | touches export const ru: TranslationStructure = {
  - expo-app/sources/text/translations/pt.ts: +13/-0 | touches export const pt: TranslationStructure = {
  - expo-app/sources/text/translations/pl.ts: +13/-0 | touches export const pl: TranslationStructure = {
  - expo-app/sources/text/translations/ja.ts: +13/-0 | touches export const ja: TranslationStructure = {
  - expo-app/sources/text/translations/it.ts: +13/-0 | touches export const it: TranslationStructure = {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(i18n): localize codex resume install modals`

### Topic Bucket

- `i18n`

### Notes / Follow-ups


---

## 237 2026-01-23 241f0ae24b1d

- SHA: 241f0ae24b1dd65641ab832dac9a0b5efd8b7e6a
- Subject: test(cli): prevent legacy sessionId path traversal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +23 / -0
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/terminal/terminalAttachmentInfo.test.ts
```

### Diffstat

```text
 cli/src/terminal/terminalAttachmentInfo.test.ts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): test(cli): prevent legacy sessionId path traversal
- Key files by churn (top 1):
  - cli/src/terminal/terminalAttachmentInfo.test.ts: +23/-0 | adds const dir, const info, const sessionId, const traversedPath | touches describe('terminalAttachmentInfo', () => {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(cli): prevent legacy sessionId path traversal`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 238 2026-01-23 a1e4a6dd3fbd

- SHA: a1e4a6dd3fbd6b432a09e3f57d1ca952134b68ea
- Subject: fix(cli): block legacy sessionId path traversal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +4 / -0
- Touched areas: cli(1)
- Topic bucket: `cli`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/terminal/terminalAttachmentInfo.ts
```

### Diffstat

```text
 cli/src/terminal/terminalAttachmentInfo.ts | 4 ++++
 1 file changed, 4 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(cli): block legacy sessionId path traversal
- Key files by churn (top 1):
  - cli/src/terminal/terminalAttachmentInfo.ts: +4/-0 | touches export async function readTerminalAttachmentInfo(params: {

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(cli): block legacy sessionId path traversal`

### Topic Bucket

- `cli`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 239 2026-01-23 e2618e04a26b

- SHA: e2618e04a26b54ff9ccab8bd44273c60601884f1
- Subject: fix(a11y): add labels to codex resume actions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +10 / -0
- Touched areas: expo-app(1)
- Topic bucket: `a11y`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/new/NewSessionWizard.tsx | 10 ++++++++++
 1 file changed, 10 insertions(+)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(a11y): add labels to codex resume actions
- Key files by churn (top 1):
  - expo-app/sources/app/(app)/new/NewSessionWizard.tsx: +10/-0 | touches export const NewSessionWizard = React.memo(function NewSessionWizard(props: NewS

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(a11y): add labels to codex resume actions`

### Topic Bucket

- `a11y`

### Notes / Follow-ups


---

## 240 2026-01-23 d0f9ad5e8310

- SHA: d0f9ad5e8310338e2771a7c77e32f80bf2763dfc
- Subject: test(claude): remove stale transcriptPath red-test scaffolding
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +3 / -5
- Touched areas: cli(1)
- Topic bucket: `claude`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/claude/utils/sessionScanner.test.ts
```

### Diffstat

```text
 cli/src/claude/utils/sessionScanner.test.ts | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): test(claude): remove stale transcriptPath red-test scaffolding
- Key files by churn (top 1):
  - cli/src/claude/utils/sessionScanner.test.ts: +3/-5 | touches describe('sessionScanner', () => {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `test(claude): remove stale transcriptPath red-test scaffolding`

### Topic Bucket

- `claude`

### Notes / Follow-ups


---

## 241 2026-01-23 1464402758bf

- SHA: 1464402758bf699fa05cc50dacb8f26791775273
- Subject: fix(codex): preserve falsy MCP tool results
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +41 / -1
- Touched areas: cli(2)
- Topic bucket: `codex`
- Manual review needed: YES (safety/security-sensitive area)

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	cli/src/codex/__tests__/extractMcpToolCallResultOutput.test.ts
M	cli/src/codex/runCodex.ts
```

### Diffstat

```text
 .../extractMcpToolCallResultOutput.test.ts         | 27 ++++++++++++++++++++++
 cli/src/codex/runCodex.ts                          | 15 +++++++++++-
 2 files changed, 41 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(codex): preserve falsy MCP tool results
- Key files by churn (top 2):
  - cli/src/codex/__tests__/extractMcpToolCallResultOutput.test.ts: +27/-0 | touches @@ -0,0 +1,27 @@
  - cli/src/codex/runCodex.ts: +14/-1 | adds const output, const record, function extractMcpToolCallResultOutput | removes const output | touches export async function runCodex(opts: {; export function extractCodexToolErrorText(response: CodexToolResponse): string |

### Message Quality

- Conventional Commits: yes
- Sensitive area: ensure commit message explains rationale + risk mitigation.

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(codex): preserve falsy MCP tool results`

### Topic Bucket

- `codex`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 242 2026-01-23 57f84f0691c6

- SHA: 57f84f0691c6c098a0522071326a7ac008b3ae97
- Subject: fix(server-light): harden public file path encoding
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +43 / -19
- Touched areas: server(2)
- Topic bucket: `server-light`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	server/sources/flavors/light/files.spec.ts
M	server/sources/flavors/light/files.ts
```

### Diffstat

```text
 server/sources/flavors/light/files.spec.ts | 36 ++++++++++++++++++------------
 server/sources/flavors/light/files.ts      | 26 ++++++++++++++++-----
 2 files changed, 43 insertions(+), 19 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(server-light): harden public file path encoding
- Key files by churn (top 2):
  - server/sources/flavors/light/files.spec.ts: +22/-14 | adds const env, const url | touches @@ -1 +0,0 @@; describe('normalizePublicPath', () => {; import { describe, expect, it } from 'vitest';
  - server/sources/flavors/light/files.ts: +21/-5 | adds const encoded, const normalized, const parts, const raw, const rawParts | removes const p, const parts | touches export function getLightPublicUrl(env: NodeJS.ProcessEnv, path: string): string; export function normalizePublicPath(path: string): string {; import { mkdir, readFile, writeFile } from 'node:fs/promises';

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(server-light): harden public file path encoding`

### Topic Bucket

- `server-light`

### Notes / Follow-ups


---

## 243 2026-01-23 0b7db6945325

- SHA: 0b7db6945325444e01dbf4e19be029718847dac8
- Subject: fix(storage): validate S3_PORT and bucket existence
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +58 / -2
- Touched areas: server(2)
- Topic bucket: `storage`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	server/sources/storage/files.spec.ts
M	server/sources/storage/files.ts
```

### Diffstat

```text
 server/sources/storage/files.spec.ts | 46 ++++++++++++++++++++++++++++++++++++
 server/sources/storage/files.ts      | 14 +++++++++--
 2 files changed, 58 insertions(+), 2 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(storage): validate S3_PORT and bucket existence
- Key files by churn (top 2):
  - server/sources/storage/files.spec.ts: +46/-0 | adds const bucketExists | touches @@ -0,0 +1,46 @@
  - server/sources/storage/files.ts: +12/-2 | adds const exists, const parsed | removes const s3Port | touches export function initFilesS3FromEnv(env: NodeJS.ProcessEnv = process.env): void {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(storage): validate S3_PORT and bucket existence`

### Topic Bucket

- `storage`

### Notes / Follow-ups


---

## 244 2026-01-23 74fc860b07b5

- SHA: 74fc860b07b59fa724400bcedf09aab0c56b1b80
- Subject: refactor(queue): simplify stale in-flight reclaim
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +1 / -6
- Touched areas: cli(1)
- Topic bucket: `queue`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
M	cli/src/api/messageQueueV1.ts
```

### Diffstat

```text
 cli/src/api/messageQueueV1.ts | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): refactor(queue): simplify stale in-flight reclaim
- Key files by churn (top 1):
  - cli/src/api/messageQueueV1.ts: +1/-6 | removes const firstRecovered | touches export function claimMessageQueueV1Next(metadata: Record<string, unknown>, now:

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(queue): simplify stale in-flight reclaim`

### Topic Bucket

- `queue`

### Notes / Follow-ups


---

## 245 2026-01-23 82bf82cb6715

- SHA: 82bf82cb6715a87d3377b5ad7ea5e9c58a4b7878
- Subject: fix(hooks): prevent stale capabilities cache overwrite
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 2
- Lines: +78 / -4
- Touched areas: expo-app(2)
- Topic bucket: `hooks`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/hooks/useMachineCapabilitiesCache.race.test.ts
M	expo-app/sources/hooks/useMachineCapabilitiesCache.ts
```

### Diffstat

```text
 .../hooks/useMachineCapabilitiesCache.race.test.ts | 74 ++++++++++++++++++++++
 .../sources/hooks/useMachineCapabilitiesCache.ts   |  8 +--
 2 files changed, 78 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(hooks): prevent stale capabilities cache overwrite
- Key files by churn (top 2):
  - expo-app/sources/hooks/useMachineCapabilitiesCache.race.test.ts: +74/-0 | adds const machineCapabilitiesDetect, const p1, const p2, const request, function Test | touches @@ -0,0 +1,74 @@
  - expo-app/sources/hooks/useMachineCapabilitiesCache.ts: +4/-4 | removes const stillInFlight | touches async function fetchAndMerge(params: {

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(hooks): prevent stale capabilities cache overwrite`

### Topic Bucket

- `hooks`

### Notes / Follow-ups


---

## 246 2026-01-23 384b15252026

- SHA: 384b1525202636c212f3ca41fa37148ae08805eb
- Subject: fix(expo): harden tool submit and pending send
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 8
- Lines: +282 / -4
- Touched areas: expo-app(8)
- Topic bucket: `expo`
- Manual review needed: no

### Commit Message Body

```text
(no body)
```

### Files (name-status)

```text
A	expo-app/sources/components/PendingMessagesModal.discardFallback.test.ts
M	expo-app/sources/components/PendingMessagesModal.test.ts
M	expo-app/sources/components/PendingMessagesModal.tsx
M	expo-app/sources/components/tools/views/AskUserQuestionView.test.ts
M	expo-app/sources/components/tools/views/AskUserQuestionView.tsx
M	expo-app/sources/sync/messageQueueV1.test.ts
M	expo-app/sources/sync/messageQueueV1.ts
M	expo-app/sources/sync/sync.ts
```

### Diffstat

```text
 .../PendingMessagesModal.discardFallback.test.ts   | 122 +++++++++++++++++++++
 .../components/PendingMessagesModal.test.ts        |   3 +
 .../sources/components/PendingMessagesModal.tsx    |  10 +-
 .../tools/views/AskUserQuestionView.test.ts        |  50 +++++++++
 .../components/tools/views/AskUserQuestionView.tsx |   2 +-
 expo-app/sources/sync/messageQueueV1.test.ts       |  29 ++++-
 expo-app/sources/sync/messageQueueV1.ts            |  54 +++++++++
 expo-app/sources/sync/sync.ts                      |  16 ++-
 8 files changed, 282 insertions(+), 4 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): fix(expo): harden tool submit and pending send
- Key files by churn (top 8):
  - expo-app/sources/components/PendingMessagesModal.discardFallback.test.ts: +122/-0 | adds const deletePendingMessage, const discardPendingMessage, const fetchPendingMessages, const modalAlert, const modalConfirm, const onClose | touches @@ -0,0 +1,122 @@
  - expo-app/sources/sync/messageQueueV1.ts: +54/-0 | adds const existingDiscarded, const inFlightItem, const maxDiscarded, const mq, const nextQueue, const queueIndex | touches export function discardMessageQueueV1All(
  - expo-app/sources/components/tools/views/AskUserQuestionView.test.ts: +50/-0 | adds const touchables | touches describe('AskUserQuestionView', () => {
  - expo-app/sources/sync/messageQueueV1.test.ts: +28/-1 | adds const next | touches describe('messageQueueV1 helpers', () => {; import type { Metadata } from './storageTypes';
  - expo-app/sources/sync/sync.ts: +15/-1 | adds const discardedAt | touches class Sync {; import { deriveSettingsSecretsKey, decryptSecretValue, encryptSecretString, seal
  - expo-app/sources/components/PendingMessagesModal.tsx: +9/-1 | touches export function PendingMessagesModal(props: { sessionId: string; onClose: () =>
  - expo-app/sources/components/PendingMessagesModal.test.ts: +3/-0 | adds const discardPendingMessage | touches const deletePendingMessage = vi.fn();; describe('PendingMessagesModal', () => {; vi.mock('@/sync/sync', () => ({
  - expo-app/sources/components/tools/views/AskUserQuestionView.tsx: +1/-1 | touches export const AskUserQuestionView = React.memo<ToolViewProps>(({ tool, sessionId

### Message Quality

- Conventional Commits: yes

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `fix(expo): harden tool submit and pending send`

### Topic Bucket

- `expo`

### Notes / Follow-ups


---

## 247 2026-01-23 24b607abfa07

- SHA: 24b607abfa073171038e72ba2cc77b20a1991aa1
- Subject: Refactor schema sync and centralize Prisma types
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 29
- Lines: +373 / -185
- Touched areas: server(28), yarn.lock(1)
- Topic bucket: `server`
- Manual review needed: YES (non-Conventional-Commits subject; diff summary skipped (too many files (29)))

### Commit Message Body

```text
Replaces generateSqliteSchema.ts with schemaSync.ts to generate both the SQLite schema and TypeScript enums from the main Prisma schema. Centralizes all Prisma types and the db client in sources/storage/prisma.ts, updating imports throughout the codebase to use this module. Updates scripts and documentation to use the new schema:sync command, and ensures enum consistency between schema and TypeScript. Adds tests for the new storage/prisma module and generated enums.
```

### Files (name-status)

```text
M	server/README.md
M	server/package.json
M	server/prisma/sqlite/schema.prisma
M	server/scripts/dev.light.ts
D	server/scripts/generateSqliteSchema.ts
M	server/scripts/migrate.light.deploy.ts
M	server/scripts/migrate.light.new.ts
M	server/scripts/migrate.light.resolveBaseline.ts
R063	server/scripts/generateSqliteSchema.spec.ts	server/scripts/schemaSync.spec.ts
A	server/scripts/schemaSync.ts
M	server/sources/app/api/routes/sessionRoutes.ts
M	server/sources/app/api/routes/userRoutes.ts
M	server/sources/app/api/socket/sessionUpdateHandler.ts
M	server/sources/app/feed/feedGet.ts
M	server/sources/app/social/friendAdd.ts
M	server/sources/app/social/friendList.ts
M	server/sources/app/social/friendNotification.spec.ts
M	server/sources/app/social/friendNotification.ts
M	server/sources/app/social/friendRemove.ts
M	server/sources/app/social/relationshipGet.ts
M	server/sources/app/social/relationshipSet.ts
M	server/sources/app/social/type.ts
M	server/sources/context.ts
M	server/sources/storage/db.ts
A	server/sources/storage/enums.generated.ts
M	server/sources/storage/inTx.ts
A	server/sources/storage/prisma.spec.ts
A	server/sources/storage/prisma.ts
M	yarn.lock
```

### Diffstat

```text
 server/README.md                                   |   4 +-
 server/package.json                                |  10 +-
 server/prisma/sqlite/schema.prisma                 |   2 +-
 server/scripts/dev.light.ts                        |   2 +-
 server/scripts/generateSqliteSchema.ts             | 102 -----------
 server/scripts/migrate.light.deploy.ts             |  10 +-
 server/scripts/migrate.light.new.ts                |   3 +-
 server/scripts/migrate.light.resolveBaseline.ts    |   3 +-
 ...rateSqliteSchema.spec.ts => schemaSync.spec.ts} |  11 +-
 server/scripts/schemaSync.ts                       | 193 +++++++++++++++++++++
 server/sources/app/api/routes/sessionRoutes.ts     |   4 +-
 server/sources/app/api/routes/userRoutes.ts        |   6 +-
 .../sources/app/api/socket/sessionUpdateHandler.ts |   2 +-
 server/sources/app/feed/feedGet.ts                 |   4 +-
 server/sources/app/social/friendAdd.ts             |   4 +-
 server/sources/app/social/friendList.ts            |   4 +-
 .../sources/app/social/friendNotification.spec.ts  |   4 +-
 server/sources/app/social/friendNotification.ts    |  10 +-
 server/sources/app/social/friendRemove.ts          |   4 +-
 server/sources/app/social/relationshipGet.ts       |   7 +-
 server/sources/app/social/relationshipSet.ts       |   7 +-
 server/sources/app/social/type.ts                  |   4 +-
 server/sources/context.ts                          |   4 +-
 server/sources/storage/db.ts                       |  18 +-
 server/sources/storage/enums.generated.ts          |  13 ++
 server/sources/storage/inTx.ts                     |  16 +-
 server/sources/storage/prisma.spec.ts              |  49 ++++++
 server/sources/storage/prisma.ts                   |  50 ++++++
 yarn.lock                                          |   8 +-
 29 files changed, 373 insertions(+), 185 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Refactor schema sync and centralize Prisma types
- Diff summary skipped: too many files (29).

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `refactor(server): refactor schema sync and centralize Prisma types`

### Topic Bucket

- `server`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 248 2026-01-23 bf3027799623

- SHA: bf3027799623c286fe138c7b69e140ea90fdfa48
- Subject: Set EXPO_UNSTABLE_WEB_MODAL env var in Expo scripts
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 4
- Lines: +35 / -17
- Touched areas: expo-app(3), package.json(1)
- Topic bucket: `expo-app`
- Manual review needed: YES (non-Conventional-Commits subject)

### Commit Message Body

```text
Updated all relevant Expo-related scripts in expo-app/package.json to include the EXPO_UNSTABLE_WEB_MODAL=1 environment variable using cross-env.

EXPO_UNSTABLE_WEB_MODAL is necessary to restore the expo-router modal behavior on web to what we had before, which Expo moved to "experimental".

Also upgraded expo-router to version 6.0.22 and added a resolutions field in the root package.json to enforce this version.
```

### Files (name-status)

```text
M	expo-app/package.json
A	expo-app/patches-expo-app/expo-router+6.0.22.patch
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	package.json
```

### Diffstat

```text
 expo-app/package.json                              | 30 +++++++++++-----------
 expo-app/patches-expo-app/expo-router+6.0.22.patch | 14 ++++++++++
 expo-app/sources/app/(app)/session/[id]/info.tsx   |  5 ++--
 package.json                                       |  3 +++
 4 files changed, 35 insertions(+), 17 deletions(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Set EXPO_UNSTABLE_WEB_MODAL env var in Expo scripts
- Key files by churn (top 4):
  - expo-app/package.json: +15/-15 | touches @@ -11 +11 @@; @@ -111 +111 @@; @@ -13 +13 @@; @@ -20,9 +20,9 @@
  - expo-app/patches-expo-app/expo-router+6.0.22.patch: +13/-0 | touches @@ -0,0 +1,14 @@
  - expo-app/sources/app/(app)/session/[id]/info.tsx: +3/-2 | adds const expCodexAcp | touches function SessionInfoContent({ session }: { session: Session }) {
  - package.json: +3/-0 | touches @@ -21,0 +22,3 @@

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(expo-app): set EXPO_UNSTABLE_WEB_MODAL env var in Expo scripts`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 249 2026-01-23 c803115dcbdc

- SHA: c803115dcbdcd55c036e47c0f0cfd6e1bceb9f74
- Subject: Improve postinstall script for symlinked paths and patching
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-23
- Files changed: 1
- Lines: +9 / -1
- Touched areas: expo-app(1)
- Topic bucket: `expo-app`
- Manual review needed: YES (non-Conventional-Commits subject)

### Commit Message Body

```text
Resolves symlinks when determining toolsDir to support Yarn workspaces executing the script via symlinked paths. Adds a second patch-package run scoped to expo-app to apply patches for dependencies not hoisted to the repo root, such as expo-router.
```

### Files (name-status)

```text
M	expo-app/tools/postinstall.mjs
```

### Diffstat

```text
 expo-app/tools/postinstall.mjs | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
```

### What It Does (diff-based summary)

- Intent (from subject): Improve postinstall script for symlinked paths and patching
- Key files by churn (top 1):
  - expo-app/tools/postinstall.mjs: +9/-1 | adds const toolsDir | removes const toolsDir | touches import url from 'node:url';; run(process.execPath, [patchPackageCliPath, '--patch-dir', 'expo-app/patches'],

### Message Quality

- Conventional Commits: NO

### Unrelated Changes?

- Likely cohesive (single major area), but verify if subject is broad.

### Suggested Rewrite (Conventional Commit)

- `chore(expo-app): improve postinstall script for symlinked paths and patching`

### Topic Bucket

- `expo-app`

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 250 2026-01-24 0c3b41030bbc

- SHA: 0c3b41030bbc4a888e621a6b5787eaac4b581a59
- Subject: Add Vitest stubs for Expo and React Native modules
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-24
- Files changed: 4
- Lines: +72 / -0
- Touched areas: expo-app(4)
- Topic bucket: `test`
- Manual review needed: YES

### Commit Message Body

```text
Introduces stub implementations for `expo-localization`, `expo-modules-core`, and `react-native` to enable unit testing in a Node environment with Vitest. Also adds a Vitest setup file that mocks `react-native-mmkv` with an in-memory store for tests. These changes allow tests to run without requiring actual Expo or React Native dependencies.
```

### Files (name-status)

```text
A	expo-app/sources/dev/expoLocalizationStub.ts
A	expo-app/sources/dev/expoModulesCoreStub.ts
M	expo-app/sources/dev/reactNativeStub.ts
A	expo-app/sources/dev/vitestSetup.ts
```

### Diffstat

```text
 expo-app/sources/dev/expoLocalizationStub.ts | 12 +++++++++++
 expo-app/sources/dev/expoModulesCoreStub.ts  | 12 +++++++++++
 expo-app/sources/dev/reactNativeStub.ts      | 16 ++++++++++++++
 expo-app/sources/dev/vitestSetup.ts          | 32 ++++++++++++++++++++++++++++
 4 files changed, 72 insertions(+)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 251 2026-01-25 7d60e6fc77f2

- SHA: 7d60e6fc77f28a0457e306780c44956e8cb4c4c7
- Subject: cli(acp): support loadSession + replay capture; normalize tool events
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 17
- Lines: +2249 / -454
- Touched areas: cli(17)
- Topic bucket: `acp`
- Manual review needed: YES

### Commit Message Body

```text
- Adds replay history capture + import helpers and publishSlashCommands
- Normalizes ACP tool events and permission request payloads
- Adds focused tests for tool normalization + permission mapping
```

### Files (name-status)

```text
M	cli/src/agent/acp/AcpBackend.ts
A	cli/src/agent/acp/bridge/acpCommonHandlers.test.ts
A	cli/src/agent/acp/bridge/acpCommonHandlers.ts
A	cli/src/agent/acp/commands/publishSlashCommands.ts
A	cli/src/agent/acp/history/acpReplayCapture.ts
A	cli/src/agent/acp/history/importAcpReplayHistory.ts
A	cli/src/agent/acp/permissions/permissionMapping.test.ts
A	cli/src/agent/acp/permissions/permissionMapping.ts
A	cli/src/agent/acp/permissions/permissionRequest.test.ts
A	cli/src/agent/acp/permissions/permissionRequest.ts
A	cli/src/agent/acp/sessionUpdateHandlers.test.ts
M	cli/src/agent/acp/sessionUpdateHandlers.ts
A	cli/src/agent/acp/toolNormalization.test.ts
A	cli/src/agent/acp/toolNormalization.ts
M	cli/src/agent/core/AgentBackend.ts
A	cli/src/agent/transport/handlers/GeminiTransport.test.ts
M	cli/src/agent/transport/handlers/GeminiTransport.ts
```

### Diffstat

```text
 cli/src/agent/acp/AcpBackend.ts                    | 915 ++++++++++++---------
 cli/src/agent/acp/bridge/acpCommonHandlers.test.ts | 107 +++
 cli/src/agent/acp/bridge/acpCommonHandlers.ts      | 121 +++
 cli/src/agent/acp/commands/publishSlashCommands.ts |  61 ++
 cli/src/agent/acp/history/acpReplayCapture.ts      |  99 +++
 .../agent/acp/history/importAcpReplayHistory.ts    | 289 +++++++
 .../acp/permissions/permissionMapping.test.ts      |  39 +
 cli/src/agent/acp/permissions/permissionMapping.ts | 115 +++
 .../acp/permissions/permissionRequest.test.ts      |  30 +
 cli/src/agent/acp/permissions/permissionRequest.ts |  73 ++
 cli/src/agent/acp/sessionUpdateHandlers.test.ts    |  80 ++
 cli/src/agent/acp/sessionUpdateHandlers.ts         | 430 ++++++++--
 cli/src/agent/acp/toolNormalization.test.ts        |  41 +
 cli/src/agent/acp/toolNormalization.ts             | 225 +++++
 cli/src/agent/core/AgentBackend.ts                 |  18 +
 .../transport/handlers/GeminiTransport.test.ts     |  24 +
 .../agent/transport/handlers/GeminiTransport.ts    |  36 +-
 17 files changed, 2249 insertions(+), 454 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 252 2026-01-25 e35328ab19ad

- SHA: e35328ab19ad2f00fa581e7e85ee75c91cb13f04
- Subject: cli(permissions): persist per-session allowlists; harden shell approvals
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 7
- Lines: +576 / -28
- Touched areas: cli(7)
- Topic bucket: `permission`
- Manual review needed: NO

### Commit Message Body

```text
- Introduces BasePermissionHandler allowlist persistence and a shell command allowlist
- Adds tool identifier helpers to keep permission decisions consistent across agents
- Adds targeted tests for allowlist behavior and tool identifier
```

### Files (name-status)

```text
M	cli/src/codex/utils/permissionHandler.ts
M	cli/src/gemini/utils/permissionHandler.ts
A	cli/src/utils/BasePermissionHandler.allowlist.test.ts
M	cli/src/utils/BasePermissionHandler.ts
A	cli/src/utils/permissionToolIdentifier.test.ts
A	cli/src/utils/permissionToolIdentifier.ts
A	cli/src/utils/shellCommandAllowlist.ts
```

### Diffstat

```text
 cli/src/codex/utils/permissionHandler.ts           |  16 +-
 cli/src/gemini/utils/permissionHandler.ts          |  44 +++---
 .../utils/BasePermissionHandler.allowlist.test.ts  |  83 ++++++++++
 cli/src/utils/BasePermissionHandler.ts             | 108 ++++++++++++-
 cli/src/utils/permissionToolIdentifier.test.ts     |  59 +++++++
 cli/src/utils/permissionToolIdentifier.ts          | 121 ++++++++++++++
 cli/src/utils/shellCommandAllowlist.ts             | 173 +++++++++++++++++++++
 7 files changed, 576 insertions(+), 28 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 253 2026-01-25 caf5adfe3449

- SHA: caf5adfe344919984e46a0eabc0fa570601fcd65
- Subject: cli(claude): support AskUserQuestion answers + ExitPlanMode negotiation
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 10
- Lines: +242 / -217
- Touched areas: cli(10)
- Topic bucket: `claude`
- Manual review needed: NO

### Commit Message Body

```text
- Routes AskUserQuestion responses through the permission decision path
- Implements ExitPlanMode semantics via permission handler, with regression tests
- Removes legacy prompt/interaction respond helpers no longer used
```

### Files (name-status)

```text
M	cli/src/claude/claudeRemoteLauncher.test.ts
M	cli/src/claude/claudeRemoteLauncher.ts
D	cli/src/claude/sdk/prompts.ts
M	cli/src/claude/sdk/types.ts
M	cli/src/claude/session.ts
D	cli/src/claude/utils/interactionRespond.test.ts
D	cli/src/claude/utils/interactionRespond.ts
A	cli/src/claude/utils/permissionHandler.exitPlanMode.test.ts
M	cli/src/claude/utils/permissionHandler.ts
M	cli/src/claude/utils/systemPrompt.ts
```

### Diffstat

```text
 cli/src/claude/claudeRemoteLauncher.test.ts        |   2 +-
 cli/src/claude/claudeRemoteLauncher.ts             | 107 +-------------
 cli/src/claude/sdk/prompts.ts                      |   2 -
 cli/src/claude/sdk/types.ts                        |  11 +-
 cli/src/claude/session.ts                          |   4 -
 cli/src/claude/utils/interactionRespond.test.ts    |  29 ----
 cli/src/claude/utils/interactionRespond.ts         |  28 ----
 .../utils/permissionHandler.exitPlanMode.test.ts   | 113 +++++++++++++++
 cli/src/claude/utils/permissionHandler.ts          | 156 +++++++++++++++------
 cli/src/claude/utils/systemPrompt.ts               |   7 +-
 10 files changed, 242 insertions(+), 217 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 254 2026-01-25 011a3602411f

- SHA: 011a3602411f2cc0f0f5affff31d2c1226a9dc5e
- Subject: cli(api): observe self-broadcasts for pending-queue; add tool tracing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 6
- Lines: +1299 / -114
- Touched areas: cli(6)
- Topic bucket: `queue`
- Manual review needed: YES

### Commit Message Body

```text
- Treats self-broadcasts as pending-queue signals to improve UI reliability
- Adds transcript recovery behavior in apiSession
- Introduces JSONL tool tracing (writer + unit tests)
```

### Files (name-status)

```text
M	cli/src/api/apiSession.test.ts
M	cli/src/api/apiSession.ts
A	cli/src/toolTrace/toolTrace.test.ts
A	cli/src/toolTrace/toolTrace.ts
M	cli/src/utils/MessageQueue2.ts
M	cli/src/utils/waitForMessagesOrPending.ts
```

### Diffstat

```text
 cli/src/api/apiSession.test.ts            | 592 +++++++++++++++++++++++++---
 cli/src/api/apiSession.ts                 | 619 +++++++++++++++++++++++++++---
 cli/src/toolTrace/toolTrace.test.ts       |  76 ++++
 cli/src/toolTrace/toolTrace.ts            | 103 +++++
 cli/src/utils/MessageQueue2.ts            |  21 +-
 cli/src/utils/waitForMessagesOrPending.ts |   2 +-
 6 files changed, 1299 insertions(+), 114 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 255 2026-01-25 809d2bb385e0

- SHA: 809d2bb385e086b568f20171757b83ecffa39635
- Subject: cli(tool-trace): add fixture extraction + CLI script
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 4
- Lines: +205 / -0
- Touched areas: cli(4)
- Topic bucket: `tools`
- Manual review needed: NO

### Commit Message Body

```text
- Adds a small JSONL -> fixtures extractor (with truncation/sanitization)
- Adds a tsx script and npm script for local fixture generation
```

### Files (name-status)

```text
M	cli/package.json
A	cli/scripts/tool-trace-extract.ts
A	cli/src/toolTrace/extractToolTraceFixtures.test.ts
A	cli/src/toolTrace/extractToolTraceFixtures.ts
```

### Diffstat

```text
 cli/package.json                                   |   1 +
 cli/scripts/tool-trace-extract.ts                  |  53 +++++++++++
 cli/src/toolTrace/extractToolTraceFixtures.test.ts |  48 ++++++++++
 cli/src/toolTrace/extractToolTraceFixtures.ts      | 103 +++++++++++++++++++++
 4 files changed, 205 insertions(+)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 256 2026-01-25 553781556305

- SHA: 5537815563059192774839feca13768250362b79
- Subject: cli(auth): add --no-open to skip browser open
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 4
- Lines: +68 / -9
- Touched areas: cli(4)
- Topic bucket: `auth`
- Manual review needed: NO

### Commit Message Body

```text
- Adds --no-open (and compat aliases) to happy auth login
- Threads HAPPY_NO_BROWSER_OPEN through auth UI and openBrowser
- Adds a unit test to ensure browser open is skipped when the env is set
```

### Files (name-status)

```text
M	cli/src/commands/auth.ts
M	cli/src/ui/auth.ts
A	cli/src/utils/browser.test.ts
M	cli/src/utils/browser.ts
```

### Diffstat

```text
 cli/src/commands/auth.ts      |  9 ++++++++-
 cli/src/ui/auth.ts            | 23 +++++++++++++++--------
 cli/src/utils/browser.test.ts | 39 +++++++++++++++++++++++++++++++++++++++
 cli/src/utils/browser.ts      |  6 ++++++
 4 files changed, 68 insertions(+), 9 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 257 2026-01-25 5955ea5c21a3

- SHA: 5955ea5c21a3da320b37b4dd9557d73bdd295ab8
- Subject: cli(daemon): idempotent resume + attach files + shutdown policy
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 22
- Lines: +1333 / -397
- Touched areas: cli(22)
- Topic bucket: `daemon`
- Manual review needed: YES

### Commit Message Body

```text
- Ensures resume requests are idempotent (avoid duplicate processes)
- Adds session attach files and startup metadata merge/update helpers
- Adds shutdown watchdog policy and a non-interactive auth gating regression test
```

### Files (name-status)

```text
M	cli/src/api/apiMachine.spawnSession.test.ts
M	cli/src/api/apiMachine.ts
M	cli/src/claude/runClaude.ts
A	cli/src/daemon/findRunningTrackedSessionById.test.ts
A	cli/src/daemon/findRunningTrackedSessionById.ts
D	cli/src/daemon/persistedHappySession.ts
A	cli/src/daemon/run.noninteractiveAuth.test.ts
M	cli/src/daemon/run.ts
A	cli/src/daemon/sessionAttachFile.test.ts
A	cli/src/daemon/sessionAttachFile.ts
A	cli/src/daemon/shutdownPolicy.test.ts
A	cli/src/daemon/shutdownPolicy.ts
M	cli/src/daemon/types.ts
M	cli/src/utils/createSessionMetadata.ts
A	cli/src/utils/sessionAttach.test.ts
A	cli/src/utils/sessionAttach.ts
A	cli/src/utils/sessionStartup/createBaseSessionForAttach.ts
A	cli/src/utils/sessionStartup/mergeSessionMetadataForStartup.test.ts
A	cli/src/utils/sessionStartup/mergeSessionMetadataForStartup.ts
A	cli/src/utils/sessionStartup/startupMetadataUpdate.test.ts
A	cli/src/utils/sessionStartup/startupMetadataUpdate.ts
A	cli/src/utils/sessionStartup/startupSideEffects.ts
```

### Diffstat

```text
 cli/src/api/apiMachine.spawnSession.test.ts        |  55 ++
 cli/src/api/apiMachine.ts                          |  61 ++-
 cli/src/claude/runClaude.ts                        | 120 ++---
 .../daemon/findRunningTrackedSessionById.test.ts   |  53 ++
 cli/src/daemon/findRunningTrackedSessionById.ts    |  30 ++
 cli/src/daemon/persistedHappySession.ts            | 112 ----
 cli/src/daemon/run.noninteractiveAuth.test.ts      |  62 +++
 cli/src/daemon/run.ts                              | 598 ++++++++++++++-------
 cli/src/daemon/sessionAttachFile.test.ts           |  71 +++
 cli/src/daemon/sessionAttachFile.ts                |  55 ++
 cli/src/daemon/shutdownPolicy.test.ts              |  20 +
 cli/src/daemon/shutdownPolicy.ts                   |  13 +
 cli/src/daemon/types.ts                            |   4 +-
 cli/src/utils/createSessionMetadata.ts             |   6 +-
 cli/src/utils/sessionAttach.test.ts                |  38 ++
 cli/src/utils/sessionAttach.ts                     |  58 ++
 .../sessionStartup/createBaseSessionForAttach.ts   |  30 ++
 .../mergeSessionMetadataForStartup.test.ts         |  92 ++++
 .../mergeSessionMetadataForStartup.ts              | 106 ++++
 .../sessionStartup/startupMetadataUpdate.test.ts   |  47 ++
 .../utils/sessionStartup/startupMetadataUpdate.ts  |  37 ++
 cli/src/utils/sessionStartup/startupSideEffects.ts |  62 +++
 22 files changed, 1333 insertions(+), 397 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 258 2026-01-25 cce05b18a5d7

- SHA: cce05b18a5d73223cb74899e44c1709301efff2e
- Subject: cli(agents): wire ACP agents into factory/transport registry
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 4
- Lines: +18 / -5
- Touched areas: cli(4)
- Topic bucket: `acp`
- Manual review needed: NO

### Commit Message Body

```text
- Exposes Codex ACP + OpenCode factories from the agent factory index
- Registers OpenCode agent during initializeAgents
- Exports OpenCode transport from the transport handler registry
```

### Files (name-status)

```text
M	cli/src/agent/factories/index.ts
M	cli/src/agent/index.ts
M	cli/src/agent/transport/handlers/index.ts
M	cli/src/agent/transport/index.ts
```

### Diffstat

```text
 cli/src/agent/factories/index.ts          | 15 ++++++++++++++-
 cli/src/agent/index.ts                    |  3 ++-
 cli/src/agent/transport/handlers/index.ts |  2 +-
 cli/src/agent/transport/index.ts          |  3 +--
 4 files changed, 18 insertions(+), 5 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 259 2026-01-25 27bb2523f690

- SHA: 27bb2523f690614db4d6a4fbce42cb02ff328b5d
- Subject: cli(opencode): add OpenCode ACP agent runtime
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 11
- Lines: +1276 / -0
- Touched areas: cli(11)
- Topic bucket: `acp`
- Manual review needed: YES

### Commit Message Body

```text
- Adds OpenCode ACP runtime and transport handler
- Adds permission handler + session id helpers for OpenCode
- Includes focused unit tests for transport and OpenCode helpers
```

### Files (name-status)

```text
A	cli/src/agent/factories/opencode.ts
A	cli/src/agent/transport/handlers/OpenCodeTransport.test.ts
A	cli/src/agent/transport/handlers/OpenCodeTransport.ts
A	cli/src/opencode/acp/openCodeAcpRuntime.ts
A	cli/src/opencode/runOpenCode.ts
A	cli/src/opencode/utils/opencodeSessionIdMetadata.test.ts
A	cli/src/opencode/utils/opencodeSessionIdMetadata.ts
A	cli/src/opencode/utils/permissionHandler.test.ts
A	cli/src/opencode/utils/permissionHandler.ts
A	cli/src/opencode/utils/waitForNextOpenCodeMessage.test.ts
A	cli/src/opencode/utils/waitForNextOpenCodeMessage.ts
```

### Diffstat

```text
 cli/src/agent/factories/opencode.ts                |  55 ++++
 .../transport/handlers/OpenCodeTransport.test.ts   |  64 ++++
 .../agent/transport/handlers/OpenCodeTransport.ts  | 250 ++++++++++++++
 cli/src/opencode/acp/openCodeAcpRuntime.ts         | 272 ++++++++++++++++
 cli/src/opencode/runOpenCode.ts                    | 358 +++++++++++++++++++++
 .../utils/opencodeSessionIdMetadata.test.ts        |  56 ++++
 .../opencode/utils/opencodeSessionIdMetadata.ts    |  21 ++
 cli/src/opencode/utils/permissionHandler.test.ts   |  24 ++
 cli/src/opencode/utils/permissionHandler.ts        | 115 +++++++
 .../utils/waitForNextOpenCodeMessage.test.ts       |  42 +++
 .../opencode/utils/waitForNextOpenCodeMessage.ts   |  19 ++
 11 files changed, 1276 insertions(+)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 260 2026-01-25 abe1cf8ed370

- SHA: abe1cf8ed37061422ee5db65a004e27deeed379b
- Subject: cli(codex-acp): add runtime + capability gating
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 24
- Lines: +1513 / -343
- Touched areas: cli(24)
- Topic bucket: `acp`
- Manual review needed: YES

### Commit Message Body

```text
- Adds Codex ACP runtime + command resolution and session-id helpers
- Extends capabilities framework for ACP probing and Codex ACP dependency checks
- Updates API/metadata types to cover ACP session ids and capability flags
```

### Files (name-status)

```text
A	cli/src/agent/factories/codexAcp.ts
M	cli/src/api/types.ts
A	cli/src/codex/acp/codexAcpRuntime.ts
A	cli/src/codex/acp/resolveCodexAcpCommand.ts
M	cli/src/codex/codexMcpClient.ts
M	cli/src/codex/runCodex.ts
M	cli/src/codex/types.ts
A	cli/src/codex/utils/codexSessionIdMetadata.test.ts
A	cli/src/codex/utils/codexSessionIdMetadata.ts
M	cli/src/gemini/runGemini.ts
A	cli/src/modules/common/capabilities/caps/acpProbe.ts
M	cli/src/modules/common/capabilities/caps/cliCodex.ts
M	cli/src/modules/common/capabilities/caps/cliGemini.ts
A	cli/src/modules/common/capabilities/caps/cliOpenCode.ts
A	cli/src/modules/common/capabilities/caps/depCodexAcp.ts
M	cli/src/modules/common/capabilities/checklists.ts
A	cli/src/modules/common/capabilities/deps/codexAcp.ts
M	cli/src/modules/common/capabilities/registerCapabilitiesHandlers.ts
M	cli/src/modules/common/capabilities/snapshots/cliSnapshot.ts
M	cli/src/modules/common/capabilities/types.ts
M	cli/src/modules/common/registerCommonHandlers.capabilities.test.ts
M	cli/src/modules/common/registerCommonHandlers.ts
M	cli/src/utils/agentCapabilities.test.ts
M	cli/src/utils/agentCapabilities.ts
```

### Diffstat

```text
 cli/src/agent/factories/codexAcp.ts                |  36 +++
 cli/src/api/types.ts                               |  27 +-
 cli/src/codex/acp/codexAcpRuntime.ts               | 284 ++++++++++++++++++
 cli/src/codex/acp/resolveCodexAcpCommand.ts        |  26 ++
 cli/src/codex/codexMcpClient.ts                    | 112 ++++---
 cli/src/codex/runCodex.ts                          | 322 +++++++++++----------
 cli/src/codex/types.ts                             |   5 +
 cli/src/codex/utils/codexSessionIdMetadata.test.ts |  56 ++++
 cli/src/codex/utils/codexSessionIdMetadata.ts      |  21 ++
 cli/src/gemini/runGemini.ts                        | 311 ++++++++++++--------
 .../modules/common/capabilities/caps/acpProbe.ts   | 207 +++++++++++++
 .../modules/common/capabilities/caps/cliCodex.ts   |  39 ++-
 .../modules/common/capabilities/caps/cliGemini.ts  |  29 +-
 .../common/capabilities/caps/cliOpenCode.ts        |  37 +++
 .../common/capabilities/caps/depCodexAcp.ts        |  37 +++
 cli/src/modules/common/capabilities/checklists.ts  |  10 +-
 .../modules/common/capabilities/deps/codexAcp.ts   | 180 ++++++++++++
 .../capabilities/registerCapabilitiesHandlers.ts   |   5 +-
 .../common/capabilities/snapshots/cliSnapshot.ts   |  27 +-
 cli/src/modules/common/capabilities/types.ts       |   7 +-
 .../registerCommonHandlers.capabilities.test.ts    |  19 +-
 cli/src/modules/common/registerCommonHandlers.ts   |  27 +-
 cli/src/utils/agentCapabilities.test.ts            |  14 +-
 cli/src/utils/agentCapabilities.ts                 |  18 +-
 24 files changed, 1513 insertions(+), 343 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 261 2026-01-25 d9100a80112b

- SHA: d9100a80112b304f64a8e1807747f1ac3ecefe79
- Subject: cli(entry): refactor agent subcommands and startup flags
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 0
- Lines: +138 / -114
- Touched areas: cli(1)
- Topic bucket: `acp`
- Manual review needed: NO

### Commit Message Body

```text
- Adds --permission-mode-updated-at parsing (for consistent session metadata)
- Adds opencode command wiring and aligns codex/gemini argument parsing
- Removes the legacy resume subcommand in favor of existing-session/resume flags
```

### Files (name-status)

```text
M	cli/src/index.ts
```

### Diffstat

```text
 cli/src/index.ts | 252 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 138 insertions(+), 114 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 262 2026-01-25 2edc5305ca3f

- SHA: 2edc5305ca3fa26cd148a5ad9f775fd9d1f4eb41
- Subject: expo-app(test): harden vitest stubs + unistyles typing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 6
- Lines: +60 / -47
- Touched areas: expo-app(5), root(1)
- Topic bucket: `test`
- Manual review needed: NO

### Commit Message Body

```text
- Updates vitest config aliases/setup to improve node-test reliability
- Improves unistyles typing/bootstrap and normalizes formatting
- Adds RootLayout hook-order regression test and removes the old layout test location
```

### Files (name-status)

```text
M	expo-app/index.ts
R097	expo-app/sources/app/(app)/_layout.test.ts	expo-app/sources/__tests__/app/_layout.test.ts
M	expo-app/sources/dev/expoModulesCoreStub.ts
M	expo-app/sources/dev/reactNativeStub.ts
M	expo-app/sources/unistyles.ts
M	expo-app/vitest.config.ts
```

### Diffstat

```text
 expo-app/index.ts                                  |  2 +-
 .../{app/(app) => __tests__/app}/_layout.test.ts   |  3 +-
 expo-app/sources/dev/expoModulesCoreStub.ts        | 10 ++++
 expo-app/sources/dev/reactNativeStub.ts            |  4 ++
 expo-app/sources/unistyles.ts                      | 62 ++++++++++------------
 expo-app/vitest.config.ts                          | 26 +++++----
 6 files changed, 60 insertions(+), 47 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 263 2026-01-25 5575d7267cd0

- SHA: 5575d7267cd0dbd92d690b847bcf9e37fc9acd11
- Subject: expo-app(tools): normalize tool inference + rendering inputs
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 10
- Lines: +572 / -82
- Touched areas: expo-app(10)
- Topic bucket: `tools`
- Manual review needed: NO

### Commit Message Body

```text
- Adds shared tool-call normalization and parsing helpers
- Improves tool name inference and permission summaries
- Updates ToolView/ToolFullView to rely on normalized shapes
```

### Files (name-status)

```text
M	expo-app/sources/components/tools/ToolFullView.tsx
M	expo-app/sources/components/tools/ToolView.tsx
M	expo-app/sources/components/tools/knownTools.tsx
A	expo-app/sources/components/tools/utils/normalizeToolCallForRendering.ts
A	expo-app/sources/components/tools/utils/parseJson.ts
A	expo-app/sources/components/tools/utils/parseParenIdentifier.ts
A	expo-app/sources/components/tools/utils/permissionSummary.ts
A	expo-app/sources/components/tools/utils/shellCommand.ts
A	expo-app/sources/components/tools/utils/stdStreams.ts
A	expo-app/sources/components/tools/utils/toolNameInference.ts
```

### Diffstat

```text
 expo-app/sources/components/tools/ToolFullView.tsx |  92 ++++++++++++-----
 expo-app/sources/components/tools/ToolView.tsx     | 110 ++++++++++++++-------
 expo-app/sources/components/tools/knownTools.tsx   |  94 +++++++++++++-----
 .../tools/utils/normalizeToolCallForRendering.ts   |  73 ++++++++++++++
 .../sources/components/tools/utils/parseJson.ts    |  13 +++
 .../components/tools/utils/parseParenIdentifier.ts |   8 ++
 .../components/tools/utils/permissionSummary.ts    |  81 +++++++++++++++
 .../sources/components/tools/utils/shellCommand.ts |  76 ++++++++++++++
 .../sources/components/tools/utils/stdStreams.ts   |  27 +++++
 .../components/tools/utils/toolNameInference.ts    |  80 +++++++++++++++
 10 files changed, 572 insertions(+), 82 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 264 2026-01-25 d115797fcdde

- SHA: d115797fcdde2decf50800d887f383d6024dde47
- Subject: expo-app(tools): add specialized tool views + tests
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 40
- Lines: +3566 / -185
- Touched areas: expo-app(40)
- Topic bucket: `tools`
- Manual review needed: YES

### Commit Message Body

```text
- Adds dedicated views for common tools (bash/read/grep/glob/web) and structured results
- Improves permission UI flows (pending/abort/decision) and adds regression tests
- Expands tool rendering test coverage for inference and fallback behavior
```

### Files (name-status)

```text
A	expo-app/sources/components/tools/PermissionFooter.codexDecision.test.tsx
A	expo-app/sources/components/tools/PermissionFooter.stopAbortsRun.test.tsx
M	expo-app/sources/components/tools/PermissionFooter.tsx
A	expo-app/sources/components/tools/ToolFullView.inference.test.ts
A	expo-app/sources/components/tools/ToolFullView.permissionPending.test.tsx
A	expo-app/sources/components/tools/ToolView.acpKindFallback.test.tsx
A	expo-app/sources/components/tools/ToolView.exitPlanMode.test.ts
A	expo-app/sources/components/tools/ToolView.minimalSpecificView.test.ts
A	expo-app/sources/components/tools/ToolView.minimalStructuredFallback.test.ts
A	expo-app/sources/components/tools/ToolView.permissionPending.test.tsx
A	expo-app/sources/components/tools/ToolView.runningStructuredFallback.test.ts
A	expo-app/sources/components/tools/utils/normalizeToolCallForRendering.test.ts
A	expo-app/sources/components/tools/utils/parseParenIdentifier.test.ts
A	expo-app/sources/components/tools/utils/permissionSummary.test.ts
A	expo-app/sources/components/tools/utils/shellCommand.test.ts
A	expo-app/sources/components/tools/utils/toolNameInference.test.ts
A	expo-app/sources/components/tools/views/AcpHistoryImportView.tsx
M	expo-app/sources/components/tools/views/AskUserQuestionView.test.ts
M	expo-app/sources/components/tools/views/AskUserQuestionView.tsx
A	expo-app/sources/components/tools/views/BashView.test.tsx
M	expo-app/sources/components/tools/views/BashView.tsx
A	expo-app/sources/components/tools/views/BashViewFull.test.ts
M	expo-app/sources/components/tools/views/BashViewFull.tsx
A	expo-app/sources/components/tools/views/CodeSearchView.tsx
M	expo-app/sources/components/tools/views/CodexBashView.tsx
M	expo-app/sources/components/tools/views/ExitPlanToolView.test.ts
M	expo-app/sources/components/tools/views/ExitPlanToolView.tsx
A	expo-app/sources/components/tools/views/GeminiExecuteView.test.ts
M	expo-app/sources/components/tools/views/GeminiExecuteView.tsx
A	expo-app/sources/components/tools/views/GlobView.tsx
A	expo-app/sources/components/tools/views/GrepView.tsx
A	expo-app/sources/components/tools/views/ReadView.tsx
A	expo-app/sources/components/tools/views/ReasoningView.test.tsx
A	expo-app/sources/components/tools/views/ReasoningView.tsx
A	expo-app/sources/components/tools/views/StructuredResultView.tsx
A	expo-app/sources/components/tools/views/TodoView.test.tsx
M	expo-app/sources/components/tools/views/TodoView.tsx
A	expo-app/sources/components/tools/views/WebFetchView.tsx
A	expo-app/sources/components/tools/views/WebSearchView.tsx
M	expo-app/sources/components/tools/views/_all.tsx
```

### Diffstat

```text
 .../tools/PermissionFooter.codexDecision.test.tsx  | 117 ++++++++
 .../tools/PermissionFooter.stopAbortsRun.test.tsx  |  96 ++++++
 .../sources/components/tools/PermissionFooter.tsx  | 324 ++++++++++++++++++---
 .../tools/ToolFullView.inference.test.ts           | 134 +++++++++
 .../tools/ToolFullView.permissionPending.test.tsx  |  81 ++++++
 .../tools/ToolView.acpKindFallback.test.tsx        | 114 ++++++++
 .../components/tools/ToolView.exitPlanMode.test.ts | 137 +++++++++
 .../tools/ToolView.minimalSpecificView.test.ts     | 111 +++++++
 .../ToolView.minimalStructuredFallback.test.ts     | 144 +++++++++
 .../tools/ToolView.permissionPending.test.tsx      | 169 +++++++++++
 .../ToolView.runningStructuredFallback.test.ts     | 113 +++++++
 .../utils/normalizeToolCallForRendering.test.ts    |  62 ++++
 .../tools/utils/parseParenIdentifier.test.ts       |  14 +
 .../tools/utils/permissionSummary.test.ts          |  29 ++
 .../components/tools/utils/shellCommand.test.ts    |  19 ++
 .../tools/utils/toolNameInference.test.ts          |  56 ++++
 .../tools/views/AcpHistoryImportView.tsx           | 213 ++++++++++++++
 .../tools/views/AskUserQuestionView.test.ts        |  30 +-
 .../components/tools/views/AskUserQuestionView.tsx |  64 ++--
 .../components/tools/views/BashView.test.tsx       |  98 +++++++
 .../sources/components/tools/views/BashView.tsx    |  42 +--
 .../components/tools/views/BashViewFull.test.ts    |  80 +++++
 .../components/tools/views/BashViewFull.tsx        |  48 +--
 .../components/tools/views/CodeSearchView.tsx      | 117 ++++++++
 .../components/tools/views/CodexBashView.tsx       |  30 +-
 .../tools/views/ExitPlanToolView.test.ts           |  95 +++++-
 .../components/tools/views/ExitPlanToolView.tsx    | 228 ++++++++++++---
 .../tools/views/GeminiExecuteView.test.ts          | 105 +++++++
 .../components/tools/views/GeminiExecuteView.tsx   |  46 ++-
 .../sources/components/tools/views/GlobView.tsx    |  78 +++++
 .../sources/components/tools/views/GrepView.tsx    | 114 ++++++++
 .../sources/components/tools/views/ReadView.tsx    |  67 +++++
 .../components/tools/views/ReasoningView.test.tsx  |  56 ++++
 .../components/tools/views/ReasoningView.tsx       |  31 ++
 .../tools/views/StructuredResultView.tsx           | 223 ++++++++++++++
 .../components/tools/views/TodoView.test.tsx       |  47 +++
 .../sources/components/tools/views/TodoView.tsx    |  25 +-
 .../components/tools/views/WebFetchView.tsx        |  60 ++++
 .../components/tools/views/WebSearchView.tsx       | 103 +++++++
 expo-app/sources/components/tools/views/_all.tsx   |  31 +-
 40 files changed, 3566 insertions(+), 185 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 265 2026-01-25 23014814ea50

- SHA: 23014814ea50c8799864ed14572078719504ccf0
- Subject: expo-app(agents): introduce agent registry + UI behavior helpers
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 17
- Lines: +1526 / -0
- Touched areas: expo-app(17)
- Topic bucket: `agents`
- Manual review needed: YES

### Commit Message Body

```text
- Adds a typed agent registry (core + UI helpers)
- Centralizes enabled-agent logic, CLI warnings, and resume capability option derivation
- Includes tests for registry behavior and picker options
```

### Files (name-status)

```text
A	expo-app/sources/agents/acpRuntimeResume.ts
A	expo-app/sources/agents/agentPickerOptions.test.ts
A	expo-app/sources/agents/agentPickerOptions.ts
A	expo-app/sources/agents/cliWarnings.test.ts
A	expo-app/sources/agents/cliWarnings.ts
A	expo-app/sources/agents/enabled.test.ts
A	expo-app/sources/agents/enabled.ts
A	expo-app/sources/agents/permissionUiCopy.ts
A	expo-app/sources/agents/registryCore.test.ts
A	expo-app/sources/agents/registryCore.ts
A	expo-app/sources/agents/registryUi.ts
A	expo-app/sources/agents/registryUiBehavior.test.ts
A	expo-app/sources/agents/registryUiBehavior.ts
A	expo-app/sources/agents/resolve.test.ts
A	expo-app/sources/agents/resolve.ts
A	expo-app/sources/agents/useEnabledAgentIds.ts
A	expo-app/sources/agents/useResumeCapabilityOptions.ts
```

### Diffstat

```text
 expo-app/sources/agents/acpRuntimeResume.ts        |  34 ++
 expo-app/sources/agents/agentPickerOptions.test.ts |  15 +
 expo-app/sources/agents/agentPickerOptions.ts      |  22 ++
 expo-app/sources/agents/cliWarnings.test.ts        |  36 ++
 expo-app/sources/agents/cliWarnings.ts             |  54 +++
 expo-app/sources/agents/enabled.test.ts            |  22 ++
 expo-app/sources/agents/enabled.ts                 |  22 ++
 expo-app/sources/agents/permissionUiCopy.ts        |  36 ++
 expo-app/sources/agents/registryCore.test.ts       |  34 ++
 expo-app/sources/agents/registryCore.ts            | 382 ++++++++++++++++++++
 expo-app/sources/agents/registryUi.ts              |  89 +++++
 expo-app/sources/agents/registryUiBehavior.test.ts | 281 +++++++++++++++
 expo-app/sources/agents/registryUiBehavior.ts      | 388 +++++++++++++++++++++
 expo-app/sources/agents/resolve.test.ts            |  17 +
 expo-app/sources/agents/resolve.ts                 |  27 ++
 expo-app/sources/agents/useEnabledAgentIds.ts      |  16 +
 .../sources/agents/useResumeCapabilityOptions.ts   |  51 +++
 17 files changed, 1526 insertions(+)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 266 2026-01-25 b142327f5e32

- SHA: b142327f5e328c3e8719f8c9a435cb4df93564b9
- Subject: expo-app(sync): capabilities protocol + resume/pending-queue plumbing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 59
- Lines: +3568 / -481
- Touched areas: expo-app(59)
- Topic bucket: `capabilities`
- Manual review needed: YES

### Commit Message Body

```text
- Adds installable dependency registry and machine capability request protocol
- Extends sync reducer/storage/types to support pending-queue + resume flows
- Adds tests for capabilities parsing, permission defaults, and resume/pending logic
```

### Files (name-status)

```text
A	expo-app/sources/capabilities/codexAcpDep.test.ts
A	expo-app/sources/capabilities/codexAcpDep.ts
A	expo-app/sources/capabilities/codexMcpResume.test.ts
A	expo-app/sources/capabilities/codexMcpResume.ts
A	expo-app/sources/capabilities/installableDepsRegistry.test.ts
A	expo-app/sources/capabilities/installableDepsRegistry.ts
A	expo-app/sources/capabilities/requests.ts
M	expo-app/sources/hooks/useMachineCapabilitiesCache.hook.test.ts
M	expo-app/sources/hooks/useMachineCapabilitiesCache.ts
M	expo-app/sources/sync/apiGithub.test.ts
M	expo-app/sources/sync/apiServices.test.ts
M	expo-app/sources/sync/capabilitiesProtocol.ts
A	expo-app/sources/sync/messageQueueV1Pending.test.ts
A	expo-app/sources/sync/messageQueueV1Pending.ts
A	expo-app/sources/sync/modelOptions.test.ts
M	expo-app/sources/sync/modelOptions.ts
A	expo-app/sources/sync/ops.sessionAbort.test.ts
M	expo-app/sources/sync/ops.ts
A	expo-app/sources/sync/pendingQueueWake.test.ts
A	expo-app/sources/sync/pendingQueueWake.ts
A	expo-app/sources/sync/permissionDefaults.test.ts
A	expo-app/sources/sync/permissionDefaults.ts
M	expo-app/sources/sync/permissionMapping.test.ts
M	expo-app/sources/sync/permissionMapping.ts
A	expo-app/sources/sync/permissionModeOptions.test.ts
M	expo-app/sources/sync/permissionModeOptions.ts
A	expo-app/sources/sync/permissionModeOverride.test.ts
A	expo-app/sources/sync/permissionModeOverride.ts
M	expo-app/sources/sync/permissionTypes.test.ts
M	expo-app/sources/sync/permissionTypes.ts
M	expo-app/sources/sync/persistence.test.ts
M	expo-app/sources/sync/persistence.ts
M	expo-app/sources/sync/profileGrouping.test.ts
M	expo-app/sources/sync/profileGrouping.ts
M	expo-app/sources/sync/profileMutations.ts
M	expo-app/sources/sync/profileUtils.test.ts
M	expo-app/sources/sync/profileUtils.ts
A	expo-app/sources/sync/readStateV1.test.ts
A	expo-app/sources/sync/readStateV1.ts
A	expo-app/sources/sync/realtimeSessionSeq.test.ts
A	expo-app/sources/sync/realtimeSessionSeq.ts
M	expo-app/sources/sync/reducer/phase0-skipping.spec.ts
M	expo-app/sources/sync/reducer/reducer.spec.ts
M	expo-app/sources/sync/reducer/reducer.ts
A	expo-app/sources/sync/resumeSessionBase.test.ts
A	expo-app/sources/sync/resumeSessionBase.ts
A	expo-app/sources/sync/resumeSessionPayload.test.ts
A	expo-app/sources/sync/resumeSessionPayload.ts
M	expo-app/sources/sync/settings.spec.ts
M	expo-app/sources/sync/settings.ts
M	expo-app/sources/sync/spawnSessionPayload.ts
M	expo-app/sources/sync/storage.ts
M	expo-app/sources/sync/storageTypes.ts
M	expo-app/sources/sync/suggestionCommands.ts
M	expo-app/sources/sync/sync.ts
M	expo-app/sources/sync/typesRaw.spec.ts
M	expo-app/sources/sync/typesRaw.ts
A	expo-app/sources/sync/updateSessionMetadataWithRetry.test.ts
A	expo-app/sources/sync/updateSessionMetadataWithRetry.ts
```

### Diffstat

```text
 expo-app/sources/capabilities/codexAcpDep.test.ts  | 155 ++++++++++++
 expo-app/sources/capabilities/codexAcpDep.ts       |  88 +++++++
 .../sources/capabilities/codexMcpResume.test.ts    | 155 ++++++++++++
 expo-app/sources/capabilities/codexMcpResume.ts    |  88 +++++++
 .../capabilities/installableDepsRegistry.test.ts   |  14 ++
 .../capabilities/installableDepsRegistry.ts        | 130 ++++++++++
 expo-app/sources/capabilities/requests.ts          |  32 +++
 .../hooks/useMachineCapabilitiesCache.hook.test.ts | 155 +++++++++++-
 .../sources/hooks/useMachineCapabilitiesCache.ts   |  34 ++-
 expo-app/sources/sync/apiGithub.test.ts            |   9 -
 expo-app/sources/sync/apiServices.test.ts          |  10 -
 expo-app/sources/sync/capabilitiesProtocol.ts      |  26 +-
 .../sources/sync/messageQueueV1Pending.test.ts     | 113 +++++++++
 expo-app/sources/sync/messageQueueV1Pending.ts     | 150 ++++++++++++
 expo-app/sources/sync/modelOptions.test.ts         |  26 ++
 expo-app/sources/sync/modelOptions.ts              |  60 +++--
 expo-app/sources/sync/ops.sessionAbort.test.ts     |  51 ++++
 expo-app/sources/sync/ops.ts                       | 122 ++++++----
 expo-app/sources/sync/pendingQueueWake.test.ts     | 193 +++++++++++++++
 expo-app/sources/sync/pendingQueueWake.ts          |  52 ++++
 expo-app/sources/sync/permissionDefaults.test.ts   |  35 +++
 expo-app/sources/sync/permissionDefaults.ts        |  60 +++++
 expo-app/sources/sync/permissionMapping.test.ts    |   5 +-
 expo-app/sources/sync/permissionMapping.ts         |   6 +-
 .../sources/sync/permissionModeOptions.test.ts     |  28 +++
 expo-app/sources/sync/permissionModeOptions.ts     |  94 ++++---
 .../sources/sync/permissionModeOverride.test.ts    |  48 ++++
 expo-app/sources/sync/permissionModeOverride.ts    |  22 ++
 expo-app/sources/sync/permissionTypes.test.ts      |  50 ++--
 expo-app/sources/sync/permissionTypes.ts           |  20 +-
 expo-app/sources/sync/persistence.test.ts          |   2 +-
 expo-app/sources/sync/persistence.ts               |  32 +--
 expo-app/sources/sync/profileGrouping.test.ts      |  30 +++
 expo-app/sources/sync/profileGrouping.ts           |  19 +-
 expo-app/sources/sync/profileMutations.ts          |   1 +
 expo-app/sources/sync/profileUtils.test.ts         |  41 +++-
 expo-app/sources/sync/profileUtils.ts              | 251 ++++++++++++++++---
 expo-app/sources/sync/readStateV1.test.ts          |  42 ++++
 expo-app/sources/sync/readStateV1.ts               |  46 ++++
 expo-app/sources/sync/realtimeSessionSeq.test.ts   |  33 +++
 expo-app/sources/sync/realtimeSessionSeq.ts        |  21 ++
 .../sources/sync/reducer/phase0-skipping.spec.ts   |  61 +++++
 expo-app/sources/sync/reducer/reducer.spec.ts      | 111 ++++++++-
 expo-app/sources/sync/reducer/reducer.ts           | 270 +++++++++++++++++++--
 expo-app/sources/sync/resumeSessionBase.test.ts    |  52 ++++
 expo-app/sources/sync/resumeSessionBase.ts         |  43 ++++
 expo-app/sources/sync/resumeSessionPayload.test.ts |  23 ++
 expo-app/sources/sync/resumeSessionPayload.ts      |  41 ++++
 expo-app/sources/sync/settings.spec.ts             | 134 +++++-----
 expo-app/sources/sync/settings.ts                  | 100 ++++++--
 expo-app/sources/sync/spawnSessionPayload.ts       |  21 +-
 expo-app/sources/sync/storage.ts                   |   4 +-
 expo-app/sources/sync/storageTypes.ts              |  27 ++-
 expo-app/sources/sync/suggestionCommands.ts        |  36 ++-
 expo-app/sources/sync/sync.ts                      | 242 ++++++++++--------
 expo-app/sources/sync/typesRaw.spec.ts             |  99 +++++++-
 expo-app/sources/sync/typesRaw.ts                  |  58 ++++-
 .../sync/updateSessionMetadataWithRetry.test.ts    |  81 +++++++
 .../sources/sync/updateSessionMetadataWithRetry.ts |  97 ++++++++
 59 files changed, 3568 insertions(+), 481 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 267 2026-01-25 552f517e9823

- SHA: 552f517e9823b56b4bbadbceb3acabb1c1d098ae
- Subject: expo-app(ui): add InlineAddExpander; inline add for secrets/env vars
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 5
- Lines: +504 / -121
- Touched areas: expo-app(5)
- Topic bucket: `secrets`
- Manual review needed: NO

### Commit Message Body

```text
- Introduces a reusable inline expander with Cancel/Save actions
- Refactors EnvironmentVariablesList and SecretsList to add items inline (no modal)
- Adds tests covering the new inline add flows
```

### Files (name-status)

```text
M	expo-app/sources/components/EnvironmentVariablesList.test.ts
M	expo-app/sources/components/EnvironmentVariablesList.tsx
A	expo-app/sources/components/InlineAddExpander.tsx
A	expo-app/sources/components/secrets/SecretsList.test.ts
M	expo-app/sources/components/secrets/SecretsList.tsx
```

### Diffstat

```text
 .../components/EnvironmentVariablesList.test.ts    |  53 ++++++-
 .../components/EnvironmentVariablesList.tsx        | 138 ++++++++----------
 expo-app/sources/components/InlineAddExpander.tsx  | 143 +++++++++++++++++++
 .../sources/components/secrets/SecretsList.test.ts | 137 ++++++++++++++++++
 .../sources/components/secrets/SecretsList.tsx     | 154 +++++++++++++++------
 5 files changed, 504 insertions(+), 121 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 268 2026-01-25 cbaf39a63c60

- SHA: cbaf39a63c60a674e2b13f71c63a92d43d29ffe2
- Subject: expo-app(secret-requirement): add picker route + modularized modal
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 10
- Lines: +1214 / -808
- Touched areas: expo-app(10)
- Topic bucket: `new-session`
- Manual review needed: YES

### Commit Message Body

```text
- Extracts SecretRequirementModal into a focused module and adds a full-screen picker route
- Adds pure helpers for applying results and gating auto-prompt behavior (with tests)
- Adjusts /new modal presentation + web CSS sizing to avoid hidden/stacked screens
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/_layout.tsx
A	expo-app/sources/app/(app)/new/pick/secret-requirement.tsx
M	expo-app/sources/components/SecretRequirementModal.tsx
A	expo-app/sources/components/secretRequirement/SecretRequirementModal.tsx
A	expo-app/sources/components/secretRequirement/SecretRequirementScreen.tsx
M	expo-app/sources/theme.css
A	expo-app/sources/utils/secretRequirementApply.test.ts
A	expo-app/sources/utils/secretRequirementApply.ts
A	expo-app/sources/utils/secretRequirementPromptEligibility.test.ts
A	expo-app/sources/utils/secretRequirementPromptEligibility.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/_layout.tsx             |  22 +-
 .../app/(app)/new/pick/secret-requirement.tsx      | 175 +++++
 .../sources/components/SecretRequirementModal.tsx  | 804 +-------------------
 .../secretRequirement/SecretRequirementModal.tsx   | 828 +++++++++++++++++++++
 .../secretRequirement/SecretRequirementScreen.tsx  |  10 +
 expo-app/sources/theme.css                         |   5 +
 .../sources/utils/secretRequirementApply.test.ts   |  59 ++
 expo-app/sources/utils/secretRequirementApply.ts   |  70 ++
 .../secretRequirementPromptEligibility.test.ts     |  18 +
 .../utils/secretRequirementPromptEligibility.ts    |  31 +
 10 files changed, 1214 insertions(+), 808 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 269 2026-01-25 36641d906490

- SHA: 36641d90649053864c09916bcfbf383669f479c4
- Subject: expo-app(session): capability-gated resume flows + pending queue UX
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 33
- Lines: +2535 / -1307
- Touched areas: expo-app(33)
- Topic bucket: `resume`
- Manual review needed: YES

### Commit Message Body

```text
- Wires agent registry + machine capabilities into new-session and session resume flows
- Adds pending message rendering and session notices for inactive/offline states
- Adds supporting UI components/tests for CLI detection and capability preflight
```

### Files (name-status)

```text
M	expo-app/sources/-session/SessionView.tsx
A	expo-app/sources/-session/sessionResumeUi.test.ts
A	expo-app/sources/-session/sessionResumeUi.ts
A	expo-app/sources/__tests__/app/machine/machineDetails.capabilitiesRequestStability.test.ts
M	expo-app/sources/app/(app)/machine/[id].tsx
M	expo-app/sources/app/(app)/new/NewSessionWizard.tsx
M	expo-app/sources/app/(app)/new/index.tsx
M	expo-app/sources/app/(app)/new/pick/machine.tsx
M	expo-app/sources/app/(app)/new/pick/resume.tsx
M	expo-app/sources/app/(app)/session/[id]/info.tsx
M	expo-app/sources/app/(app)/session/[id]/message/[messageId].tsx
M	expo-app/sources/components/ChatFooter.tsx
M	expo-app/sources/components/ChatList.tsx
A	expo-app/sources/components/PendingUserTextMessageView.test.tsx
A	expo-app/sources/components/PendingUserTextMessageView.tsx
A	expo-app/sources/components/SessionNoticeBanner.tsx
A	expo-app/sources/components/agentInput/PathAndResumeRow.test.ts
A	expo-app/sources/components/agentInput/PathAndResumeRow.tsx
A	expo-app/sources/components/agentInput/ResumeChip.tsx
A	expo-app/sources/components/agentInput/actionBarLogic.test.ts
A	expo-app/sources/components/agentInput/actionBarLogic.ts
A	expo-app/sources/components/chatListItems.test.ts
A	expo-app/sources/components/chatListItems.ts
A	expo-app/sources/components/machine/DetectedClisList.errorSnapshot.test.ts
M	expo-app/sources/components/machine/DetectedClisList.tsx
M	expo-app/sources/components/machine/DetectedClisModal.tsx
A	expo-app/sources/components/machine/InstallableDepInstaller.tsx
A	expo-app/sources/components/navigation/HeaderTitleWithAction.tsx
A	expo-app/sources/components/newSession/CliNotDetectedBanner.tsx
M	expo-app/sources/components/newSession/MachineCliGlyphs.tsx
M	expo-app/sources/components/newSession/ProfileCompatibilityIcon.tsx
A	expo-app/sources/components/newSession/WizardSectionHeaderRow.test.ts
M	expo-app/sources/hooks/useCLIDetection.ts
```

### Diffstat

```text
 expo-app/sources/-session/SessionView.tsx          |  234 ++++-
 expo-app/sources/-session/sessionResumeUi.test.ts  |   54 ++
 expo-app/sources/-session/sessionResumeUi.ts       |   40 +
 ...ineDetails.capabilitiesRequestStability.test.ts |  214 +++++
 expo-app/sources/app/(app)/machine/[id].tsx        |  297 ++----
 .../sources/app/(app)/new/NewSessionWizard.tsx     |  406 +-------
 expo-app/sources/app/(app)/new/index.tsx           | 1004 ++++++++++----------
 expo-app/sources/app/(app)/new/pick/machine.tsx    |  127 ++-
 expo-app/sources/app/(app)/new/pick/resume.tsx     |   75 +-
 expo-app/sources/app/(app)/session/[id]/info.tsx   |   63 +-
 .../app/(app)/session/[id]/message/[messageId].tsx |    8 +-
 expo-app/sources/components/ChatFooter.tsx         |   20 +-
 expo-app/sources/components/ChatList.tsx           |   52 +-
 .../components/PendingUserTextMessageView.test.tsx |   81 ++
 .../components/PendingUserTextMessageView.tsx      |  102 ++
 .../sources/components/SessionNoticeBanner.tsx     |   35 +
 .../components/agentInput/PathAndResumeRow.test.ts |   62 ++
 .../components/agentInput/PathAndResumeRow.tsx     |   81 ++
 .../sources/components/agentInput/ResumeChip.tsx   |   61 ++
 .../components/agentInput/actionBarLogic.test.ts   |   39 +
 .../components/agentInput/actionBarLogic.ts        |   34 +
 expo-app/sources/components/chatListItems.test.ts  |   55 ++
 expo-app/sources/components/chatListItems.ts       |   54 ++
 .../machine/DetectedClisList.errorSnapshot.test.ts |   65 ++
 .../components/machine/DetectedClisList.tsx        |   35 +-
 .../components/machine/DetectedClisModal.tsx       |    3 +-
 .../components/machine/InstallableDepInstaller.tsx |  203 ++++
 .../navigation/HeaderTitleWithAction.tsx           |   65 ++
 .../components/newSession/CliNotDetectedBanner.tsx |  103 ++
 .../components/newSession/MachineCliGlyphs.tsx     |   38 +-
 .../newSession/ProfileCompatibilityIcon.tsx        |   32 +-
 .../newSession/WizardSectionHeaderRow.test.ts      |   32 +
 expo-app/sources/hooks/useCLIDetection.ts          |   68 +-
 33 files changed, 2535 insertions(+), 1307 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 270 2026-01-25 9a9d439e5499

- SHA: 9a9d439e54998316e64ab28bafc93f06025ff88b
- Subject: expo-app(settings): wire agent registry into settings
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 2
- Lines: +98 / -20
- Touched areas: expo-app(2)
- Topic bucket: `settings`
- Manual review needed: NO

### Commit Message Body

```text
- Updates settings screens to reflect agent registry defaults and available agents
- Keeps session/account settings aligned with new permission/default behavior
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/account.tsx
M	expo-app/sources/app/(app)/settings/session.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/account.tsx | 42 +++++++-------
 expo-app/sources/app/(app)/settings/session.tsx | 76 ++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 20 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 271 2026-01-25 67ceab362d6b

- SHA: 67ceab362d6bacce54ed360b59eda35404c2c570
- Subject: expo-app(experiments): add inbox friends experiment gate
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 7
- Lines: +62 / -2
- Touched areas: expo-app(7)
- Topic bucket: `inbox`
- Manual review needed: NO

### Commit Message Body

```text
- Adds an experiment flag and hooks for inbox/friends enablement
- Updates inbox/friends routes to gate access and routing based on the experiment
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/friends/index.tsx
M	expo-app/sources/app/(app)/friends/search.tsx
M	expo-app/sources/app/(app)/inbox/index.tsx
A	expo-app/sources/experiments/inboxFriends.test.ts
A	expo-app/sources/experiments/inboxFriends.ts
A	expo-app/sources/hooks/useInboxFriendsEnabled.ts
A	expo-app/sources/hooks/useRequireInboxFriendsEnabled.ts
```

### Diffstat

```text
 expo-app/sources/app/(app)/friends/index.tsx           |  6 +++++-
 expo-app/sources/app/(app)/friends/search.tsx          |  4 ++++
 expo-app/sources/app/(app)/inbox/index.tsx             |  6 +++++-
 expo-app/sources/experiments/inboxFriends.test.ts      | 18 ++++++++++++++++++
 expo-app/sources/experiments/inboxFriends.ts           |  4 ++++
 expo-app/sources/hooks/useInboxFriendsEnabled.ts       | 10 ++++++++++
 .../sources/hooks/useRequireInboxFriendsEnabled.ts     | 16 ++++++++++++++++
 7 files changed, 62 insertions(+), 2 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 272 2026-01-25 05b45b4f505d

- SHA: 05b45b4f505dd9da88501ea728c6c3897019ab5b
- Subject: expo-app(settings): update features toggles for agents/inbox/codex
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 0
- Lines: +76 / -12
- Touched areas: expo-app(1)
- Topic bucket: `settings`
- Manual review needed: NO

### Commit Message Body

```text
- Replaces expGemini toggle with agent-registry-backed experimental agent toggles
- Adds inbox friends experiment toggle
- Adds Codex ACP toggle and keeps Codex resume/acp mutually exclusive
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/settings/features.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/settings/features.tsx | 88 ++++++++++++++++++++----
 1 file changed, 76 insertions(+), 12 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 273 2026-01-25 ec9225a8f935

- SHA: ec9225a8f93564a418e6e446cecf8d0f383fc510
- Subject: expo-app(i18n): add device locale helpers + update translations
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 12
- Lines: +553 / -119
- Touched areas: expo-app(12)
- Topic bucket: `i18n`
- Manual review needed: NO

### Commit Message Body

```text
- Adds device locale helpers for native and shared runtime
- Updates translation dictionaries and text index wiring
```

### Files (name-status)

```text
A	expo-app/sources/text/deviceLocales.native.ts
A	expo-app/sources/text/deviceLocales.ts
M	expo-app/sources/text/index.ts
M	expo-app/sources/text/translations/ca.ts
M	expo-app/sources/text/translations/en.ts
M	expo-app/sources/text/translations/es.ts
M	expo-app/sources/text/translations/it.ts
M	expo-app/sources/text/translations/ja.ts
M	expo-app/sources/text/translations/pl.ts
M	expo-app/sources/text/translations/pt.ts
M	expo-app/sources/text/translations/ru.ts
M	expo-app/sources/text/translations/zh-Hans.ts
```

### Diffstat

```text
 expo-app/sources/text/deviceLocales.native.ts |  7 +++
 expo-app/sources/text/deviceLocales.ts        | 49 ++++++++++++++++
 expo-app/sources/text/index.ts                |  4 +-
 expo-app/sources/text/translations/ca.ts      | 68 +++++++++++++++++-----
 expo-app/sources/text/translations/en.ts      | 68 +++++++++++++++++-----
 expo-app/sources/text/translations/es.ts      | 60 +++++++++++++++++---
 expo-app/sources/text/translations/it.ts      | 48 +++++++++++++++-
 expo-app/sources/text/translations/ja.ts      | 68 +++++++++++++++++-----
 expo-app/sources/text/translations/pl.ts      | 68 +++++++++++++++++-----
 expo-app/sources/text/translations/pt.ts      | 82 ++++++++++++++++++++-------
 expo-app/sources/text/translations/ru.ts      | 68 +++++++++++++++++-----
 expo-app/sources/text/translations/zh-Hans.ts | 82 ++++++++++++++++++++-------
 12 files changed, 553 insertions(+), 119 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 274 2026-01-25 98b7138360ff

- SHA: 98b7138360ff2bade61c2a2f78e1ef1b11b3e320
- Subject: expo-app(agents): align resume helpers + temp session data typing
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 3
- Lines: +81 / -27
- Touched areas: expo-app(3)
- Topic bucket: `agents`
- Manual review needed: NO

### Commit Message Body

```text
- Refactors agent resume capability helpers to use the agent registry
- Adds getAgentVendorResumeId for vendor resume id lookup
- Types temp session data agentType as AgentId and adds regression tests
```

### Files (name-status)

```text
A	expo-app/sources/utils/agentCapabilities.test.ts
M	expo-app/sources/utils/agentCapabilities.ts
M	expo-app/sources/utils/tempDataStore.ts
```

### Diffstat

```text
 expo-app/sources/utils/agentCapabilities.test.ts | 38 ++++++++++++++
 expo-app/sources/utils/agentCapabilities.ts      | 65 +++++++++++++++---------
 expo-app/sources/utils/tempDataStore.ts          |  5 +-
 3 files changed, 81 insertions(+), 27 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 275 2026-01-25 63cda8b20882

- SHA: 63cda8b20882dde5746e9f007b0866a0e39c3134
- Subject: expo-app(ui): add list/pending primitives and polish
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 31
- Lines: +1610 / -670
- Touched areas: expo-app(31)
- Topic bucket: `list`
- Manual review needed: YES

### Commit Message Body

```text
- Adds reusable item-group row helpers and pending queue UI coverage
- Refines list and settings components for more consistent layout/behavior
- Updates profile list model helpers and adds targeted tests
```

### Files (name-status)

```text
M	expo-app/sources/components/AgentInput.tsx
M	expo-app/sources/components/Avatar.tsx
M	expo-app/sources/components/EnvironmentVariableCard.tsx
M	expo-app/sources/components/Item.tsx
M	expo-app/sources/components/ItemGroup.dividers.test.ts
M	expo-app/sources/components/ItemGroup.dividers.ts
A	expo-app/sources/components/ItemGroupRowPosition.tsx
A	expo-app/sources/components/ItemGroupTitleWithAction.test.ts
A	expo-app/sources/components/ItemGroupTitleWithAction.tsx
M	expo-app/sources/components/ItemList.tsx
M	expo-app/sources/components/MainView.tsx
M	expo-app/sources/components/MultiTextInput.tsx
M	expo-app/sources/components/PendingMessagesModal.test.ts
M	expo-app/sources/components/PendingMessagesModal.tsx
A	expo-app/sources/components/PendingQueueIndicator.test.ts
M	expo-app/sources/components/PendingQueueIndicator.tsx
M	expo-app/sources/components/Popover.test.ts
M	expo-app/sources/components/Popover.tsx
M	expo-app/sources/components/ProfileEditForm.tsx
M	expo-app/sources/components/SettingsView.tsx
M	expo-app/sources/components/SidebarView.tsx
M	expo-app/sources/components/TabBar.tsx
M	expo-app/sources/components/dropdown/DropdownMenu.tsx
M	expo-app/sources/components/dropdown/SelectableMenuResults.tsx
A	expo-app/sources/components/itemGroupRowCorners.test.ts
A	expo-app/sources/components/itemGroupRowCorners.ts
M	expo-app/sources/components/profiles/ProfilesList.tsx
M	expo-app/sources/components/profiles/profileListModel.test.ts
M	expo-app/sources/components/profiles/profileListModel.ts
A	expo-app/sources/utils/profileConfigRequirements.test.ts
A	expo-app/sources/utils/profileConfigRequirements.ts
```

### Diffstat

```text
 expo-app/sources/components/AgentInput.tsx         | 372 +++++++++------------
 expo-app/sources/components/Avatar.tsx             |  47 +--
 .../sources/components/EnvironmentVariableCard.tsx | 256 +++++++-------
 expo-app/sources/components/Item.tsx               |  38 ++-
 .../sources/components/ItemGroup.dividers.test.ts  |   6 +
 expo-app/sources/components/ItemGroup.dividers.ts  |   9 +-
 .../sources/components/ItemGroupRowPosition.tsx    |  36 ++
 .../components/ItemGroupTitleWithAction.test.ts    |  42 +++
 .../components/ItemGroupTitleWithAction.tsx        |  44 +++
 expo-app/sources/components/ItemList.tsx           |  19 +-
 expo-app/sources/components/MainView.tsx           |  24 +-
 expo-app/sources/components/MultiTextInput.tsx     |   4 +-
 .../components/PendingMessagesModal.test.ts        |  47 ++-
 .../sources/components/PendingMessagesModal.tsx    |  24 +-
 .../components/PendingQueueIndicator.test.ts       | 142 ++++++++
 .../sources/components/PendingQueueIndicator.tsx   | 117 +++++--
 expo-app/sources/components/Popover.test.ts        | 220 +++++++++++-
 expo-app/sources/components/Popover.tsx            | 175 ++++++++--
 expo-app/sources/components/ProfileEditForm.tsx    | 343 ++++++++++++-------
 expo-app/sources/components/SettingsView.tsx       |  12 +-
 expo-app/sources/components/SidebarView.tsx        |  70 ++--
 expo-app/sources/components/TabBar.tsx             |  13 +-
 .../sources/components/dropdown/DropdownMenu.tsx   |   8 +-
 .../components/dropdown/SelectableMenuResults.tsx  |  13 +-
 .../sources/components/itemGroupRowCorners.test.ts |  33 ++
 expo-app/sources/components/itemGroupRowCorners.ts |  20 ++
 .../sources/components/profiles/ProfilesList.tsx   |  23 +-
 .../components/profiles/profileListModel.test.ts   |  29 +-
 .../components/profiles/profileListModel.ts        |  36 +-
 .../utils/profileConfigRequirements.test.ts        |  43 +++
 .../sources/utils/profileConfigRequirements.ts     |  15 +
 31 files changed, 1610 insertions(+), 670 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 276 2026-01-25 10dca4ca7057

- SHA: 10dca4ca7057ad04c6d121110f7fd2f006a411bc
- Subject: chore(expo): pin libsodium-wrappers and align patch-package dirs
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 5
- Lines: +11 / -11
- Touched areas: expo-app(3), root(1), yarn.lock(1)
- Topic bucket: `expo`
- Manual review needed: NO

### Commit Message Body

```text
- Pins libsodium-wrappers to 0.7.15 to avoid patching 0.7.16
- Moves expo-router patch to expo-app/patches and updates postinstall patch-package invocation
- Updates yarn.lock to match dependency pin
```

### Files (name-status)

```text
M	expo-app/package.json
R100	expo-app/patches-expo-app/expo-router+6.0.22.patch	expo-app/patches/expo-router+6.0.22.patch
D	expo-app/patches/libsodium-wrappers+0.7.16.patch
M	expo-app/tools/postinstall.mjs
M	yarn.lock
```

### Diffstat

```text
 expo-app/package.json                                         |  2 +-
 .../{patches-expo-app => patches}/expo-router+6.0.22.patch    |  0
 expo-app/patches/libsodium-wrappers+0.7.16.patch              |  7 -------
 expo-app/tools/postinstall.mjs                                |  2 +-
 yarn.lock                                                     | 11 +++++++++--
 5 files changed, 11 insertions(+), 11 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 277 2026-01-25 cfe2ecd3e626

- SHA: cfe2ecd3e626030ecf3f63b159fbba34d7a6ff8e
- Subject: refactor: migrate StyleSheet imports to react-native-unistyles
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 23
- Lines: +156 / -38
- Touched areas: expo-app(23)
- Topic bucket: `format`
- Manual review needed: NO

### Commit Message Body

```text
Replaces all StyleSheet imports from 'react-native' with imports from 'react-native-unistyles' across sources/. Adds a test to enforce the invariant. This improves consistency and leverages unistyles for styling.
```

### Files (name-status)

```text
M	expo-app/sources/app/(app)/dev/colors.tsx
M	expo-app/sources/app/(app)/dev/inverted-list.tsx
M	expo-app/sources/app/(app)/dev/modal-demo.tsx
M	expo-app/sources/app/(app)/dev/shimmer-demo.tsx
M	expo-app/sources/app/(app)/dev/tools2.tsx
M	expo-app/sources/app/(app)/dev/typography.tsx
M	expo-app/sources/components/ChatHeaderView.tsx
M	expo-app/sources/components/CommandPalette/CommandPalette.tsx
M	expo-app/sources/components/CommandPalette/CommandPaletteResults.tsx
M	expo-app/sources/components/CommandView.tsx
M	expo-app/sources/components/OverlayPortal.tsx
M	expo-app/sources/components/Popover.tsx
M	expo-app/sources/components/ShimmerView.tsx
M	expo-app/sources/components/VoiceAssistantStatusBar.tsx
M	expo-app/sources/components/tools/PermissionFooter.tsx
M	expo-app/sources/components/tools/ToolStatusIndicator.tsx
M	expo-app/sources/components/tools/views/BashViewFull.test.ts
M	expo-app/sources/components/tools/views/BashViewFull.tsx
M	expo-app/sources/components/tools/views/MultiEditView.tsx
M	expo-app/sources/components/tools/views/MultiEditViewFull.tsx
M	expo-app/sources/components/tools/views/TaskView.tsx
A	expo-app/sources/dev/unistylesStyleSheetImports.test.ts
M	expo-app/sources/modal/components/WebPromptModal.tsx
```

### Diffstat

```text
 expo-app/sources/app/(app)/dev/colors.tsx          |  5 +-
 expo-app/sources/app/(app)/dev/inverted-list.tsx   |  5 +-
 expo-app/sources/app/(app)/dev/modal-demo.tsx      |  5 +-
 expo-app/sources/app/(app)/dev/shimmer-demo.tsx    |  5 +-
 expo-app/sources/app/(app)/dev/tools2.tsx          |  5 +-
 expo-app/sources/app/(app)/dev/typography.tsx      |  5 +-
 expo-app/sources/components/ChatHeaderView.tsx     |  6 +-
 .../components/CommandPalette/CommandPalette.tsx   |  5 +-
 .../CommandPalette/CommandPaletteResults.tsx       |  3 +-
 expo-app/sources/components/CommandView.tsx        |  4 +-
 expo-app/sources/components/OverlayPortal.tsx      |  3 +-
 expo-app/sources/components/Popover.tsx            |  3 +-
 expo-app/sources/components/ShimmerView.tsx        |  5 +-
 .../sources/components/VoiceAssistantStatusBar.tsx |  4 +-
 .../sources/components/tools/PermissionFooter.tsx  |  4 +-
 .../components/tools/ToolStatusIndicator.tsx       |  5 +-
 .../components/tools/views/BashViewFull.test.ts    |  4 +
 .../components/tools/views/BashViewFull.tsx        |  3 +-
 .../components/tools/views/MultiEditView.tsx       |  5 +-
 .../components/tools/views/MultiEditViewFull.tsx   |  3 +-
 .../sources/components/tools/views/TaskView.tsx    |  4 +-
 .../sources/dev/unistylesStyleSheetImports.test.ts | 99 ++++++++++++++++++++++
 .../sources/modal/components/WebPromptModal.tsx    |  4 +-
 23 files changed, 156 insertions(+), 38 deletions(-)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---

## 278 2026-01-25 8aaacbfaac7a

- SHA: 8aaacbfaac7acb3b946c9e7bdd99ee6af5be3a62
- Subject: docs: add Conventional Commits instructions
- Author: Leeroy Brun <leeroy.brun@gmail.com>
- Committer: Leeroy Brun <leeroy.brun@gmail.com>
- CommitDate: 2026-01-25
- Files changed: 1
- Lines: +30 / -0
- Touched areas: root(1)
- Topic bucket: `dev`
- Manual review needed: NO

### Commit Message Body

```text
Introduce .github/copilot-commit-instructions.md to document the Conventional Commits specification and provide commit message guidelines for the repository.
```

### Files (name-status)

```text
A	.github/copilot-commit-instructions.md
```

### Diffstat

```text
 .github/copilot-commit-instructions.md | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
```

### Notes / Follow-ups

- Manual review: required before squashing/reordering.

---
