Skip to content

Commit 5b8533f

Browse files
martig7claude
andcommitted
feat: seed wiki with codebase documentation and remove stale docs
- Analyzed all project markdown files for staleness - Created wiki pages: obs-plugin module, codebase-overview, e2e-test-architecture, plugin-integration-harness, obs-plugin-install, decision-800-line-limit - Archived llm-wiki.md to docs/wiki/raw/articles/ with source summary - Deleted stale CODEBASE_STRUCTURE.md (superseded by wiki codebase-overview page) - Updated index.md and log.md with all new entries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ce0034f commit 5b8533f

11 files changed

Lines changed: 516 additions & 165 deletions

File tree

CODEBASE_STRUCTURE.md

Lines changed: 0 additions & 161 deletions
This file was deleted.

docs/wiki/index.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@ _Updated by Claude on every ingest. Read this first when querying the wiki._
44

55
## Modules
66

7-
_(none yet)_
7+
- [[obs-plugin]] — OBS plugin HTTP API, C source structure, thread-safety model, Electron transport
88

99
## Edge Cases
1010

1111
_(none yet)_
1212

1313
## Decisions
1414

15-
_(none yet)_
15+
- [[decision-800-line-limit]] — Why files are capped at 800 lines: context window efficiency for LLM agents
1616

1717
## Concepts
1818

19-
_(none yet)_
19+
- [[codebase-overview]] — Two-app architecture, module inventory, 800-line rule, files currently over limit
20+
- [[e2e-test-architecture]] — Playwright mock strategy, setupApiRoutes helper, --test-mode flag, fixture layout
21+
- [[plugin-integration-harness]] — In-process HTTP mock harness, port override env vars, harness vs real-DLL boundary
22+
- [[obs-plugin-install]] — Install paths, modules.json management, known gotchas (stale entry, OBS update breakage)
2023

2124
## Sources
2225

23-
_(none yet)_
26+
- [[llm-wiki]] — LLM wiki pattern document used to design this knowledge base (2026-04-08)

docs/wiki/log.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ _`## [YYYY-MM-DD] lint | N issues found`_
99
_`## [YYYY-MM-DD] file | pages/type/name.md (mid-session)`_
1010

1111
---
12+
13+
## [2026-04-08] ingest | CODEBASE_STRUCTURE.md — created pages/concepts/codebase-overview.md
14+
## [2026-04-08] ingest | electron-app/tests/e2e/README.md — created pages/concepts/e2e-test-architecture.md
15+
## [2026-04-08] ingest | electron-app/tests/integration/plugin/README.md — created pages/concepts/plugin-integration-harness.md
16+
## [2026-04-08] ingest | obs-plugin/README.md + obs-plugin/src/README.md — created pages/modules/obs-plugin.md
17+
## [2026-04-08] ingest | obs-plugin/PluginInstall.md — created pages/concepts/obs-plugin-install.md
18+
## [2026-04-08] ingest | llm-wiki.md — archived to raw/articles/, created pages/sources/llm-wiki.md
19+
## [2026-04-08] file | pages/decisions/decision-800-line-limit.md (mid-session)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
type: concept
3+
tags: [architecture, electron, obs-plugin, structure]
4+
updated: 2026-04-08
5+
sources: 1
6+
---
7+
8+
# Codebase Overview
9+
10+
OpenClip is composed of two independently-built applications that communicate at runtime: an Electron desktop app and a native OBS Studio plugin. The Electron app drives the UI and business logic; the OBS plugin runs inside OBS to expose recording controls and scene management via HTTP.
11+
12+
## Key Points
13+
14+
- **Two-app architecture:** `electron-app/` (Electron + React + Node.js) and `obs-plugin/` (C plugin for OBS Studio). They are built and packaged separately but ship together in the NSIS installer.
15+
- **Communication:** The Electron app reaches the OBS plugin through a local HTTP transport (`pluginHttpTransport.js`). It also communicates with OBS directly over WebSocket for some operations.
16+
- **800-line file limit:** The project enforces a soft rule that no source file should exceed 800 lines. Files approaching this limit are candidates for extraction.
17+
- **Backend modules** live in `electron-app/electron/`. Key ones:
18+
- `fileManager.js` — file organization, week-folder logic, move operations (950 lines — over limit)
19+
- `recordingService.js` — recording lifecycle, clip numbering, date-based counting (932 lines — over limit)
20+
- `gameWatcher.js` — process detection loop, hotkey registration, OBS start/stop triggers (424 lines)
21+
- `apiServer.js` — Express HTTP server exposing the local REST API consumed by the frontend viewer (574 lines)
22+
- `ipcHandlers.js` + `ipcHandlers/` subdirectory — IPC dispatch; refactored into per-domain handler files (`gameHandlers.js`, `obsHandlers.js`, `recordingHandlers.js`, `shareHandlers.js`, `watcherHandlers.js`, `windowHandlers.js`)
23+
- `obsPlugin.js` — manages the OBS plugin installation and detection
24+
- `obsIntegration.js` — high-level OBS control bridge
25+
- `obsEncoding.js` — re-encoding pipeline (H.264/H.265/AV1)
26+
- `store.js` — electron-store config wrapper
27+
- `winUtils.js` — Windows-specific utilities (655 lines)
28+
- `waveformCache.js`, `waveformPreCache.js`, `waveformUtils.js` — audio waveform generation and caching
29+
- `fileOperations.js` — lower-level file operation helpers (split from fileManager)
30+
- `migrations.js` — store schema migrations
31+
- `pluginHttpTransport.js` — HTTP client for talking to the OBS plugin
32+
- **Frontend** lives in `electron-app/src/`. Key entry points:
33+
- `App.jsx` — root layout (vertical sidebar nav + main content area)
34+
- `pages/GamesPage.jsx` — game management UI (677 lines, near limit)
35+
- `pages/SettingsPage.jsx` — app settings
36+
- `viewer/` — the media viewer (Recordings, Clips, Storage pages)
37+
- `viewer/components/VideoPlayer.jsx` — video player with trim timeline (1207 lines — significantly over limit)
38+
- **OBS plugin source** lives in `obs-plugin/src/`. Written in C. Key files: `http-server.c`, `scene-handlers.c`, `audio-handlers.c`. See `obs-plugin/README.md` for the full plugin API reference.
39+
- **Tests** live in `electron-app/tests/`. Unit tests use Jest/Vitest; E2E tests use Playwright. Run the full suite with `npm run test` from `electron-app/` — do NOT use `npx vitest run` directly as it skips the Playwright E2E tests.
40+
- **Testing stubs** (`*-testing.js` files in `electron-app/electron/`) are Jest module mapping stubs required for tests; they are not imported by production code.
41+
42+
## Files Over the 800-Line Limit (as of 2026-04-08)
43+
44+
| File | Lines |
45+
|------|------:|
46+
| `electron/fileManager.js` | 950 |
47+
| `electron/recordingService.js` | 932 |
48+
| `src/viewer/components/VideoPlayer.jsx` | 1207 |
49+
50+
## Related
51+
52+
- [[ipc-patterns]]
53+
- [[fileManager]]
54+
- [[gameWatcher]]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
type: concept
3+
tags: [testing, e2e, playwright, mock-api, electron]
4+
updated: 2026-04-08
5+
sources: 0
6+
---
7+
8+
# E2E Test Architecture
9+
10+
OpenClip's end-to-end tests use Playwright running against a plain Chromium browser, not the Electron renderer. This means `window.api` (injected by Electron's preload via contextBridge) is never available in test runs, so two separate mock strategies are used depending on how each page fetches data.
11+
12+
## Key Points
13+
14+
### Two distinct mock layers
15+
16+
**`window.api` pages (GamesPage, SettingsPage)**
17+
18+
These pages call `window.api.*` directly. In the test browser there is no preload, so `src/api.js` automatically falls back to `mockApi`, which returns `mockGames` (Valorant, CS2) and `defaultSettings` (F9 hotkey, all toggles off) from `src/mockData.js`. No test setup is required for these pages — the mock data is deterministic and always present.
19+
20+
**`apiFetch` pages (RecordingsPage, ClipsPage, StoragePage)**
21+
22+
These pages call `apiFetch('/api/...')`, which normally proxies to the Electron-side HTTP API server. In tests, these requests are intercepted at the network layer using Playwright's `page.route()`. The helper `setupApiRoutes(page)` from `fixtures/routes.js` must be called **before** `page.goto()`.
23+
24+
`setupApiRoutes` registers the following intercepts:
25+
26+
| Route | Mock response |
27+
|-------|--------------|
28+
| `GET /api/recordings` | `testRecordings` (Valorant + CS2 recordings) |
29+
| `GET /api/clips` | `testClips` (one Valorant clip) |
30+
| `GET /api/storage/stats` | `testStorageStats` (4.43 GB total, 2 rec, 1 clip) |
31+
| `GET /api/storage/settings` | `testStorageSettings` (auto-delete off) |
32+
| `POST /api/**` | `{ success: true }` catch-all for mutations |
33+
34+
### Test mode flag
35+
36+
`npm run dev:test` starts Electron with `--test-mode`, which gives the Electron process an in-memory store (empty by default). Playwright's Chromium is unaffected by this — it still uses `mockApi` and `page.route()` mocks, not the Electron store.
37+
38+
### File layout
39+
40+
```
41+
tests/e2e/
42+
├── navigation.spec.js — navigation and page loading
43+
├── games.spec.js — Games page: mock rendering, toggle, delete, add modal
44+
├── settings.spec.js — Settings page: hotkey, toggles, dirty-state save button
45+
├── pages.spec.js — Recordings/Clips/Storage/Settings data rendering
46+
├── interactions.spec.js — cross-page user interaction flows
47+
└── fixtures/
48+
├── testData.js — shared mock data for both window.api and route responses
49+
└── routes.js — setupApiRoutes(page) helper
50+
```
51+
52+
### Running
53+
54+
```bash
55+
# From electron-app/
56+
npm run test:e2e # headless
57+
npm run test:e2e:ui # Playwright UI mode
58+
59+
# Prerequisite (one-time)
60+
npx playwright install chromium
61+
```
62+
63+
Do not run `npx vitest run` directly — use `npm run test` from `electron-app/` to include Playwright tests alongside unit tests.
64+
65+
## Related
66+
67+
- [[plugin-integration-harness]]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
type: concept
3+
tags: [obs-plugin, install, modules.json, obs, windows]
4+
updated: 2026-04-08
5+
sources: 1
6+
---
7+
8+
# OBS Plugin Installation
9+
10+
The OpenClip OBS plugin (`openclip-obs`) is a native DLL/SO that OBS discovers by scanning specific directories on startup. No registry-based loader is involved — file placement is all that matters, with one important exception: the `modules.json` state file introduced in OBS v32.
11+
12+
## Key Points
13+
14+
### Install Paths (Windows)
15+
16+
Three locations are valid, with different admin and discovery behaviors:
17+
18+
| Path | Admin required | OBS auto-discovers in modules.json |
19+
|------|---------------|-----------------------------------|
20+
| `C:\Program Files\obs-studio\obs-plugins\64bit\` | Yes | Yes — auto-scanned on next launch |
21+
| `C:\ProgramData\obs-studio\plugins\<name>\obs-plugins\64bit\` | No (OBS v28+) | **No** — entry must be written manually |
22+
| `%AppData%\obs-studio\plugins\<name>\obs-plugins\64bit\` | No | **No** — entry must be written manually |
23+
24+
For the AppData and ProgramData paths, if `modules.json` does not already have an entry for the plugin, OBS will not load it even though the file exists. An installer writing to these paths must also write the 9-field entry to `modules.json` while OBS is not running.
25+
26+
### modules.json (`%AppData%\Roaming\obs-studio\plugin_manager\modules.json`)
27+
28+
- Introduced in OBS v32's Plugin Manager.
29+
- OBS reads this file to track discovered plugins and their enabled/disabled state.
30+
- On install to `Program Files`: OBS auto-adds the entry on next launch.
31+
- On install to AppData/ProgramData: **the installer must write the entry** before OBS launches.
32+
- On uninstall: OBS does not clean up stale entries. Remove the entry from `modules.json` manually (while OBS is closed) to avoid a greyed-out phantom entry in the Plugin Manager.
33+
- Always write/modify `modules.json` while OBS is not running.
34+
35+
### Normal Install Flow
36+
37+
The OpenClip desktop app's setup wizard handles installation automatically. Manual steps:
38+
39+
1. Copy the compiled DLL to the appropriate directory.
40+
2. If using AppData/ProgramData path, write the `modules.json` entry.
41+
3. Restart OBS — the plugin loads automatically.
42+
43+
## Known Gotchas
44+
45+
### "[PLUGIN NOT FOUND]" after OBS Update
46+
47+
**Symptom:** Plugin appears in Plugin Manager as "[PLUGIN NOT FOUND]". The DLL is on disk, loads with `LoadLibraryW`, exports `obs_module_load`, and OBS logs contain no mention of it at all.
48+
49+
**Root cause:** A stale or incorrect `module_path` in `modules.json` causes OBS to report not-found without re-scanning the file. This is a state tracking problem in OBS, not a DLL problem.
50+
51+
**Fix:** While OBS is closed, delete or correct the plugin's entry in `modules.json`, then relaunch OBS. It will re-scan and add a fresh entry.
52+
53+
### Plugin Missing After In-Place OBS Update
54+
55+
**Symptom:** Plugin was working, OBS updates, plugin now appears missing or fails to load.
56+
57+
**Root cause:** In-place OBS updates skip the installer's DLL directory registration step. `obs.dll` and `obs-frontend-api.dll` can no longer be resolved at plugin load time. OBS 32.1.0's new Plugin Manager surfaces these previously-silent failures.
58+
59+
**Fix:** Reinstall OBS fully (not just the plugin). This re-runs the installer's DLL registration. See also the known issue note in `CLAUDE.md`.
60+
61+
## Related
62+
63+
- [[obs-plugin]]

0 commit comments

Comments
 (0)