Skip to content

feat: centralised getEffectiveCwd() + provider helpers with stale session guard#114

Merged
InbarR merged 3 commits into
InbarR:mainfrom
yoziv:feature/yoziv/effective-cwd-helper
May 24, 2026
Merged

feat: centralised getEffectiveCwd() + provider helpers with stale session guard#114
InbarR merged 3 commits into
InbarR:mainfrom
yoziv:feature/yoziv/effective-cwd-helper

Conversation

@yoziv
Copy link
Copy Markdown
Contributor

@yoziv yoziv commented May 19, 2026

Summary

Follow-up to #112 — addresses both pieces of @InbarR's review feedback on the original draft, now that #112 has merged.

1. Stale session guard (unchanged from prior revision)

getEffectiveCwd() only prefers the AI session's CWD when the session is active (status !== 'idle'). After the CLI exits and the session goes idle, the helper falls back to the shell's CWD — preventing the diff panel from showing the wrong repo.

2. Centralised helpers (now actually applied across the codebase)

Three exported helpers live in src/renderer/state/terminal-store.ts:

  • findSessionById(copilotSessions, claudeCodeSessions, id) — replaces the duplicated cs.find(...) ?? ccs.find(...) pattern.
  • getSessionProvider(copilotSessions, claudeCodeSessions, id) — returns 'copilot' \| 'claude-code' \| undefined for sites that only need the provider tag (replaces .some() duplicates).
  • getEffectiveCwd(terminal, copilotSessions, claudeCodeSessions) — single source of truth for where is this terminal working?

When a third AI provider is added, only these helpers need updating.

3. e2e test no longer relies on require() in the renderer

The previous spec used require('../src/renderer/state/terminal-store') inside window.evaluate(). Electron's renderer is a sandboxed browser context with no CommonJS require, so the call threw before the typeof fallback could run and the test silently failed on CI.

App.tsx now exposes __getEffectiveCwd, __findSessionById, and __getSessionProvider on window alongside __terminalStore, and the spec calls the real helpers directly. The inline fallback is gone — the test now actually exercises production code.

Changes

File Change
src/renderer/state/terminal-store.ts Added findSessionById, getSessionProvider, getEffectiveCwd; migrated 4 internal sites
src/renderer/App.tsx Exposed the three helpers on window for e2e
src/renderer/components/DiffReview.tsx Uses getEffectiveCwd + getSessionProvider
src/renderer/components/StatusBar.tsx 2 sites migrated to findSessionById
src/renderer/components/TabBar.tsx aiStatus selector migrated
src/renderer/components/TerminalPanel.tsx 4 selectors migrated (latestPrompt, latestPromptTime, sessionStatus, aiProvider)
tests/e2e/effective-cwd-helper.spec.ts Drops require() + inline fallback; calls the real helper via window

Net -28 lines across renderer code, no behaviour change for the migrated sites (IDs are unique across the provider arrays, so the lookup-order swap is semantically equivalent).

Test coverage

Scenario Expected CWD Test
Active AI session linked AI session CWD
Idle AI session linked (stale) Shell CWD (fallback)
No AI session linked Shell CWD
Stale aiSessionId (session removed) Shell CWD (fallback)

Dependencies

Now rebased on top of merged #112. No outstanding chain.

Copy link
Copy Markdown
Owner

@InbarR InbarR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direction is good - having a single source of truth for the effective CWD makes sense, especially with the idle-session guard.

Two things before merging:

  1. The new e2e spec (effective-cwd-helper.spec.ts) fails on CI because it uses require(...) inside a browser context, and browsers don't have CommonJS require. The typeof getEffectiveCwd === 'function' fallback never runs because require throws first. Easiest fix is a top-level ES import, or expose the helper on window from the renderer for e2e access.

  2. The PR description mentions ~10 call sites being migrated, but only DiffReview.tsx is converted in this diff. Are the rest planned for a follow-up?

The other Playwright failures look like the same pre-existing base-branch issue I noted on #112, not anything you introduced.

Suggest landing #112 first since this one builds on it, then this rebases cleanly.

yoziv and others added 3 commits May 24, 2026 10:35
Follow-up to #3 (diff panel CWD resolution).

Two improvements based on adversarial review feedback:

1. Stale session guard: getEffectiveCwd() only prefers AI session CWD
   when the session is active (status !== 'idle'). After CLI exit, the
   session goes idle and the helper falls back to shell CWD — preventing
   the diff panel from showing the wrong repo.

2. Centralized helper: findSessionById() and getEffectiveCwd() are
   exported from terminal-store.ts. This eliminates the hardcoded
   copilotSessions.find() ?? claudeCodeSessions.find() pattern and
   makes adding a third provider a single-point change.

DiffReview.tsx now uses getEffectiveCwd() instead of inline logic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous spec called require('../src/renderer/state/terminal-store')

inside window.evaluate(). Electron's renderer is a sandboxed browser

context with no CommonJS require, so the call threw and the typeof

fallback never ran, masking real failures and tripping CI.

App.tsx now exposes getEffectiveCwd, findSessionById and

getSessionProvider on window alongside __terminalStore, and the

spec calls the real helper directly. The inline fallback is removed

so the test now actually exercises production code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the small getSessionProvider() helper next to findSessionById()

in terminal-store, then converts every remaining call site of the

duplicated copilotSessions.find/some + claudeCodeSessions.find/some

pattern across the renderer:

  - terminal-store.ts: snapshotPaneForRestore, getStartupCommand,

    linker idle-session guard, resumeAllSessions

  - StatusBar.tsx: focusedAiSession + terminalListEntries.findStatus

  - TabBar.tsx: aiStatus selector

  - TerminalPanel.tsx: latestPrompt, latestPromptTime,

    sessionStatus, aiProvider selectors

  - DiffReview.tsx: agentLabel provider branch

When a third provider is added, only the two helpers in

terminal-store need touching. Net -28 lines, no behaviour change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yoziv yoziv force-pushed the feature/yoziv/effective-cwd-helper branch from 7e3847c to 946bdfb Compare May 24, 2026 07:40
@yoziv yoziv changed the title feat: centralized getEffectiveCwd() with stale session guard feat: centralised getEffectiveCwd() + provider helpers with stale session guard May 24, 2026
@yoziv
Copy link
Copy Markdown
Contributor Author

yoziv commented May 24, 2026

Both points addressed in the latest push:

1. tests/e2e/effective-cwd-helper.spec.ts no longer uses require(). The renderer's helpers are now exposed on window from App.tsx (same pattern as __terminalStore), and the spec calls window.__getEffectiveCwd(...) directly — the test now exercises the real production code instead of the inline fallback.

2. The ~10 call sites are migrated in this PR (not deferred). findSessionById covers session-object lookups; added a small sibling getSessionProvider() for the .some || .some sites that only want the provider tag. Sites converted: 4 internal in terminal-store.ts, plus StatusBar, TabBar, TerminalPanel (4 selectors) and DiffReview. Net -28 lines.

Also rebased on top of merged #112 (one trivial conflict in DiffReview.tsx resolved by keeping the centralised version).

@InbarR InbarR merged commit 7be83b4 into InbarR:main May 24, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants