From 8a859280ada19dc8216331ed18430c1f7692a9f6 Mon Sep 17 00:00:00 2001 From: jean-baptiste Date: Fri, 21 Aug 2026 16:23:52 +0200 Subject: [PATCH] cleanup(viewer): drop "plans" from the memory/work-files names #138 already removed the Plans tab, its viewer panel, the get-plans/read-plan/save-plan IPC handlers and the 'plan' FTS type. What it left behind is the naming: public/plans-memory-view.js and docs/plans-memory-workfiles.md still carried "plans" in their names, and several comments and doc tables still listed a panel that no longer exists. Rename both files to memory-workfiles-view.js / memory-workfiles.md and update every reference. Restore the cross-tab search test that #138 deleted along with its plans case, retargeted at the memory tab: it covers the same sub-3-char routing branch, which was left untested. Left untouched: the shared .plans-empty CSS class, reused by Memory, Work Files, Stats and jsonl-viewer; the 'plan' permission mode; and the 'plan' subagent type colour. --- .ai/contexts/README.md | 2 +- .ai/contexts/schedule-runner.md | 2 +- .ai/contexts/viewer-panel.md | 2 +- .ai/shared-guidelines.md | 2 +- README.md | 4 ++-- docs/README.md | 2 +- ...ans-memory-workfiles.md => memory-workfiles.md} | 0 eslint.config.js | 2 +- public/app.js | 5 +---- public/index.html | 2 +- public/jsonl-viewer.js | 2 +- ...ans-memory-view.js => memory-workfiles-view.js} | 2 +- public/style.css | 4 ++-- public/viewer-panel.js | 2 +- public/viewer-toolbar.js | 2 +- test/dom-subagent-transcript.test.js | 2 +- test/dom-work-files-view.test.js | 14 +++++++------- test/search-perf.test.js | 14 ++++++++++++++ 18 files changed, 38 insertions(+), 27 deletions(-) rename docs/{plans-memory-workfiles.md => memory-workfiles.md} (100%) rename public/{plans-memory-view.js => memory-workfiles-view.js} (99%) diff --git a/.ai/contexts/README.md b/.ai/contexts/README.md index 5e8df230..a0faa987 100644 --- a/.ai/contexts/README.md +++ b/.ai/contexts/README.md @@ -9,7 +9,7 @@ Five sub-system docs, ~150 lines each, written for AI agents who need to make a | SQLite, indexing, search, heatmap aggregation, fs.watch | [session-cache](session-cache.md) | | Cron schedules, schedule `.md` files, `claude --resume -p` spawn | [schedule-runner](schedule-runner.md) | | Subagent sidebar grouping, transcript view, parent→child wiring | [subagent-observability](subagent-observability.md) | -| Plans/Memory/.work-files tabs, CodeMirror panel, format/delete buttons | [viewer-panel](viewer-panel.md) | +| Memory/.work-files tabs, CodeMirror panel, format/delete buttons | [viewer-panel](viewer-panel.md) | | New IPC, preload bridge changes, renderer ↔ main protocol | [ipc-bridge](ipc-bridge.md) | | File-trigger watcher, harness input injection, idle-wait | [trigger-watcher](trigger-watcher.md) | diff --git a/.ai/contexts/schedule-runner.md b/.ai/contexts/schedule-runner.md index ba243feb..e0a67d4c 100644 --- a/.ai/contexts/schedule-runner.md +++ b/.ai/contexts/schedule-runner.md @@ -61,7 +61,7 @@ cli: ## If you change this, also check - `public/dialogs.js` (`launchScheduleCreator`) — UI entry point for the schedule creator flow -- `public/plans-memory-view.js` brain tab — lists existing `schedule-*.md` files, surfaces the "run now" play button +- `public/memory-workfiles-view.js` brain tab — lists existing `schedule-*.md` files, surfaces the "run now" play button - `public/sidebar.js` — `.project-schedule-btn` clock icon wiring per project - `schedule-ipc.js` `SCHEDULE_CREATOR_TEMPLATE` — if you change the schedule file format, update the template's instructions - `main.js:1618` (or wherever `startScheduler(log, runScheduleCommand)` is invoked at app boot) diff --git a/.ai/contexts/viewer-panel.md b/.ai/contexts/viewer-panel.md index b79bb716..44fdd883 100644 --- a/.ai/contexts/viewer-panel.md +++ b/.ai/contexts/viewer-panel.md @@ -30,7 +30,7 @@ panel.getContent(); // current editor content panel.destroy(); // tear down (rare; usually open() replaces) ``` -Used at `public/app.js:19-44` for the three panel instances. +Used at `public/app.js:31-55` for the two panel instances. ## Toolbar buttons (visibility rules) diff --git a/.ai/shared-guidelines.md b/.ai/shared-guidelines.md index 8b487d01..fbbd3502 100644 --- a/.ai/shared-guidelines.md +++ b/.ai/shared-guidelines.md @@ -13,7 +13,7 @@ Switchboard is an **Electron desktop app**: renderer + main-process, no Domain/A | Change SQLite, indexing, watcher, FTS, heatmap | [contexts/session-cache.md](contexts/session-cache.md) | | Change schedule cron / `.md` files / schedule spawn | [contexts/schedule-runner.md](contexts/schedule-runner.md) | | Change subagent grouping, transcript view, parent→child | [contexts/subagent-observability.md](contexts/subagent-observability.md) | -| Change Plans/Memory/.work-files panels (CodeMirror) | [contexts/viewer-panel.md](contexts/viewer-panel.md) | +| Change Memory/.work-files panels (CodeMirror) | [contexts/viewer-panel.md](contexts/viewer-panel.md) | | Change the renderer (sidebar, terminal, app.js) | `public/*.js` — entry is `app.js` | | Write a test | `test/*.test.js` — node:test + jsdom for renderer files | | Working practices for AI agents (HANDOFF format, shell pitfalls, review loop) | [agent-practices.md](agent-practices.md) | diff --git a/README.md b/README.md index 9ed39804..cf0998d6 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ This repository is a fork of **[doctly/switchboard](https://github.com/doctly/sw - **Full-Text Search** — Find any session by what was discussed, not just when it happened - **Sandboxed Sessions** (Linux) — Optionally run Claude inside a [bubblewrap](https://github.com/containers/bubblewrap) sandbox where the rest of `$HOME` is hidden: only the project directory and Claude's own config/state are visible (filesystem isolation — network and environment are shared, see [docs](docs/settings.md#what-the-sandbox-does-and-doesnt-isolate)). Off by default; enable per session, per project, or globally. Needs unprivileged user namespaces, which Ubuntu 23.10+ restricts by default — the wrapper says so and how to fix it - **IDE Emulation** — Switchboard acts as an IDE for Claude CLI, showing file diffs and opens in a side panel where you can accept, reject, or edit changes before they're applied. Supports both inline and side-by-side diff views. Disable this in Global Settings if you prefer Claude to use your own editor (VS Code, Cursor, etc.) -- **Memory** — Browse and edit your CLAUDE.md memory files in one place +- **Memory & Work Files** — Browse and edit your CLAUDE.md memory files and per-project `.work-files/` scratch notes in one place - **Activity Stats** — Heatmap of your coding activity across all projects - **Session Names** — Picks up session names from Claude Code's `/rename` command automatically @@ -88,7 +88,7 @@ Full user-facing documentation lives in [docs/](docs/README.md): - [Session Restore](docs/session-restore.md) — persist open sessions and restore them on restart - [Keyboard Shortcuts](docs/keyboard-shortcuts.md) — editor/terminal shortcuts and rebindable session-nav keys - [Notifications](docs/notifications.md) — sidebar status badges -- [Memory and Work Files](docs/plans-memory-workfiles.md) — CodeMirror panels for CLAUDE.md and `.work-files/` +- [Memory and Work Files](docs/memory-workfiles.md) — CodeMirror panels for CLAUDE.md and `.work-files/` - [Activity Stats](docs/activity-stats.md) — coding activity heatmap - [Settings Reference](docs/settings.md) — every field in Global and Project Settings - [Automation](docs/automation.md) — scheduled Claude tasks (cron) and the file-based trigger API diff --git a/docs/README.md b/docs/README.md index 4a26942e..523978e5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,7 +14,7 @@ This is the documentation for the [devsuitup/switchboard](https://github.com/dev - [Session Restore](session-restore.md) — persist open sessions and restore them on restart - [Keyboard Shortcuts](keyboard-shortcuts.md) — editor/terminal shortcuts and rebindable session-nav keys - [Notifications](notifications.md) — sidebar status badges: waiting for input, permission approval, activity -- [Memory and Work Files](plans-memory-workfiles.md) — edit CLAUDE.md and `.work-files/` in CodeMirror panels +- [Memory and Work Files](memory-workfiles.md) — edit CLAUDE.md and `.work-files/` in CodeMirror panels - [Activity Stats](activity-stats.md) — coding activity heatmap - [Settings Reference](settings.md) — every field in Global and Project Settings - [Automation](automation.md) — scheduled Claude tasks (cron) and the file-based trigger API diff --git a/docs/plans-memory-workfiles.md b/docs/memory-workfiles.md similarity index 100% rename from docs/plans-memory-workfiles.md rename to docs/memory-workfiles.md diff --git a/eslint.config.js b/eslint.config.js index 814b647c..98c47050 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -161,7 +161,7 @@ const rendererCrossFileGlobals = { WebglAddon: 'readonly', UnicodeGraphemesAddon: 'readonly', - // Terminal/grid/file-panel/plans/stats/notifications and assorted helpers + // Terminal/grid/file-panel/stats/notifications and assorted helpers // shared across renderer files (defined somewhere in public/*.js). TERMINAL_THEME: 'writable', TERMINAL_THEMES: 'readonly', diff --git a/public/app.js b/public/app.js index ea460175..2d87a08f 100644 --- a/public/app.js +++ b/public/app.js @@ -1122,9 +1122,6 @@ document.querySelectorAll('.sidebar-tab').forEach(tab => { }); }); -// Plans & viewer helpers → plans-memory-view.js - - // Grid view → grid-view.js // Initialize grid observers now that DOM refs are ready initGridObservers(); @@ -1133,7 +1130,7 @@ initGridObservers(); // Stats view (loadStats, buildUsageSection, buildDailyBarChart, buildHeatmap, calculateStreak, buildStatsSummary) → stats-view.js -// Memory viewer → plans-memory-view.js +// Memory & Work Files viewers → memory-workfiles-view.js // Dialogs (resolveDefaultSessionOptions, forkSession, showNewSessionPopover, diff --git a/public/index.html b/public/index.html index b09d7917..e407cf6d 100644 --- a/public/index.html +++ b/public/index.html @@ -134,7 +134,7 @@ - + diff --git a/public/jsonl-viewer.js b/public/jsonl-viewer.js index 7f2f7184..e41d01aa 100644 --- a/public/jsonl-viewer.js +++ b/public/jsonl-viewer.js @@ -16,7 +16,7 @@ const liveSubagents = new Set(); // Active subagent file watches for the currently-rendered viewer. Each entry // is a stopWatch closure created when an Agent block expands and starts a // live tail. Drained on viewer dismissal so we don't leak fs.watchFile polls. -// Attached to `window` so the cross-file hideAllViewers() (in plans-memory-view.js) +// Attached to `window` so the cross-file hideAllViewers() (in memory-workfiles-view.js) // can drain via the function declaration below — top-level `const` in classic // scripts isn't global. window.__activeViewerWatches = window.__activeViewerWatches || new Set(); diff --git a/public/plans-memory-view.js b/public/memory-workfiles-view.js similarity index 99% rename from public/plans-memory-view.js rename to public/memory-workfiles-view.js index 4e18a536..dcc1efb0 100644 --- a/public/plans-memory-view.js +++ b/public/memory-workfiles-view.js @@ -1,6 +1,6 @@ // --- Memory & Work Files viewers --- // Depends on globals: memoryContent, memoryPanel, memoryViewer, placeholder, -// terminalArea, statsViewer, settingsViewer, jsonlViewer (app.js) +// terminalArea, statsViewer, settingsViewer, jsonlViewer, workFilesViewer (app.js) // Depends on: formatDate (utils.js) let cachedMemoryData = { global: { files: [] }, projects: [] }; diff --git a/public/style.css b/public/style.css index 19fa7e27..05fb2fb1 100644 --- a/public/style.css +++ b/public/style.css @@ -1902,7 +1902,7 @@ body { display: flex; flex-direction: column; } font-size: 13px; } -/* Shared viewer toolbar (memory, file panel) */ +/* Shared viewer toolbar (memory, work files, file panel) */ .viewer-toolbar { display: flex; align-items: center; @@ -1970,7 +1970,7 @@ body { display: flex; flex-direction: column; } background: rgba(120,130,255,0.1); } -/* Plan CodeMirror editor */ +/* Viewer panel CodeMirror editor */ .viewer-panel-editor { flex: 1; overflow: hidden; diff --git a/public/viewer-panel.js b/public/viewer-panel.js index 812005ad..9adbab0b 100644 --- a/public/viewer-panel.js +++ b/public/viewer-panel.js @@ -1,7 +1,7 @@ /** * viewer-panel.js — Unified viewer component for CodeMirror-based panels. * - * A single component used by memory viewer and file panel. + * A single component used by memory viewer, work files viewer, and file panel. * Manages toolbar, editor, preview area, and all interactions. * Watches files for external changes and reloads automatically. * diff --git a/public/viewer-toolbar.js b/public/viewer-toolbar.js index 58e3254f..9ffec178 100644 --- a/public/viewer-toolbar.js +++ b/public/viewer-toolbar.js @@ -2,7 +2,7 @@ * viewer-toolbar.js — Shared toolbar factory for all CodeMirror viewer panels. * * Creates a consistent toolbar with title, path, and action buttons. - * Used by memory viewer and file panel. + * Used by memory viewer, work files viewer, and file panel. */ const SAVE_ICON = ''; diff --git a/test/dom-subagent-transcript.test.js b/test/dom-subagent-transcript.test.js index 561cdb03..349a4c0d 100644 --- a/test/dom-subagent-transcript.test.js +++ b/test/dom-subagent-transcript.test.js @@ -131,7 +131,7 @@ function setupDom({ readSubagentJsonlResult = { entries: SAMPLE_ENTRIES }, readS loadProjects: () => {}, launchScheduleCreator: () => {}, setActiveSession: () => {}, - // hideAllViewers is defined in plans-memory-view.js in the real app; stub it here. + // hideAllViewers is defined in memory-workfiles-view.js in the real app; stub it here. hideAllViewers: () => {}, // openSession is stubbed after eval; we pre-stub it so it's present during eval openSession: () => {}, diff --git a/test/dom-work-files-view.test.js b/test/dom-work-files-view.test.js index 0b25a7a4..d518ef21 100644 --- a/test/dom-work-files-view.test.js +++ b/test/dom-work-files-view.test.js @@ -1,6 +1,6 @@ -// Smoke tests for the Work Files tab renderer (plans-memory-view.js work-files section). +// Smoke tests for the Work Files tab renderer (memory-workfiles-view.js work-files section). // -// Strategy: load icons.js + utils.js + plans-memory-view.js into a jsdom window +// Strategy: load icons.js + utils.js + memory-workfiles-view.js into a jsdom window // that stubs the minimal globals those scripts need (DOM refs, window.api). // Then call loadWorkFiles / renderWorkFiles / openWorkFile and assert the // resulting DOM matches expectations. @@ -14,7 +14,7 @@ const { JSDOM } = require('jsdom'); const PUBLIC_DIR = path.join(__dirname, '..', 'public'); -// Minimal HTML that plans-memory-view.js references via globals set in app.js. +// Minimal HTML that memory-workfiles-view.js references via globals set in app.js. const INDEX_HTML = ` @@ -36,7 +36,7 @@ function evalInWindow(dom, file) { vm.runInContext(src, dom.getInternalVMContext(), { filename: file }); } -// A minimal ViewerPanel stub — plans-memory-view.js calls workFilesPanel.open(...) +// A minimal ViewerPanel stub — memory-workfiles-view.js calls workFilesPanel.open(...) function makeViewerPanelStub() { return { open: () => {}, close: () => {} }; } @@ -50,7 +50,7 @@ function setupWorkFilesDom() { const { window } = dom; // jsdom doesn't expose CSS.escape — polyfill it. - // plans-memory-view.js uses CSS.escape() in openMemory / openWorkFile. + // memory-workfiles-view.js uses CSS.escape() in openMemory / openWorkFile. if (!window.CSS) { Object.defineProperty(window, 'CSS', { value: { @@ -69,7 +69,7 @@ function setupWorkFilesDom() { runScheduleNow: () => Promise.resolve({ ok: true }), }; - // DOM handles that plans-memory-view.js reads as globals (set by app.js normally) + // DOM handles that memory-workfiles-view.js reads as globals (set by app.js normally) const stubGlobals = { memoryContent: window.document.getElementById('memory-content'), workFilesContent: window.document.getElementById('work-files-content'), @@ -94,7 +94,7 @@ function setupWorkFilesDom() { // Load dependencies evalInWindow(dom, path.join(PUBLIC_DIR, 'utils.js')); evalInWindow(dom, path.join(PUBLIC_DIR, 'icons.js')); - evalInWindow(dom, path.join(PUBLIC_DIR, 'plans-memory-view.js')); + evalInWindow(dom, path.join(PUBLIC_DIR, 'memory-workfiles-view.js')); return { window, diff --git a/test/search-perf.test.js b/test/search-perf.test.js index 929275e8..b1dcf58e 100644 --- a/test/search-perf.test.js +++ b/test/search-perf.test.js @@ -267,3 +267,17 @@ test('search: " a " (1 trimmed char) does NOT call api.search and preserves in assert.equal(inputEl.value, ' a ', 'input value must be preserved (not cleared)'); }); +// --------------------------------------------------------------------------- +// Cross-tab: non-sessions tabs route correctly under 3-char threshold +// --------------------------------------------------------------------------- + +test('search: 2-char query on memory tab calls renderMemories (not api.search)', async () => { + const { state, inputEl, runSearchQuery } = makeSearchState(); + state.activeTab = 'memory'; + inputEl.value = 'me'; + let apiCalled = false; + await runSearchQuery(() => { apiCalled = true; }); + + assert.equal(apiCalled, false, 'api.search not called for 2-char on memory tab'); + assert.equal(state.renderMemoriesCalls.length, 1, 'renderMemories called to show unfiltered list'); +});