refactor(app): consume shared indexing core, remove duplicated indexer (Phase 5d-3c-i)
The desktop app now indexes through the shared provider adapters + persist
layer (scripts/providers/{claude,codex}, scripts/persist, scripts/parsing)
instead of maintaining its own parallel indexer. buildIndex shrinks from
~1173 to ~592 lines, eliminating the skill<->app parse duplication that
Phase 5 set out to remove. electron-vite bundles the .ts core from source
with better-sqlite3 injected; the provider->parsing graph stays
node:sqlite-free so nothing drags node:sqlite into the app.
Also fix a misleading log: when a manual rebuild tears down the worker
mid-build, the cancelled background build is a deliberate stop, not a
failure. Guard the service's failure log with the stopped flag so it no
longer prints "Obelisk index build failed: Indexer worker stopped" on
every rebuild.
- CONTEXT.md: provider-adapter + single-persist + node:sqlite-free parsing.
- docs/adr/0005: app builds with electron-vite (TS+ESM), packages with
electron-builder; preload CJS for sandbox; app consumes core from source.
Verified: full suite 121/121; a node:sqlite-adapter dogfood of the rebuild
path over real data (969 files, 285 sessions, FTS rebuilt) runs clean; app
Rebuild confirmed in real Electron/better-sqlite3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
905c10789a
commit
60d47a852e
@@ -73,6 +73,48 @@ test('indexer service runs one pending build after an in-flight build finishes',
|
||||
assert.deepEqual(calls, ['first', 'pending']);
|
||||
});
|
||||
|
||||
test('indexer service does not log a build cancelled by a service stop', async () => {
|
||||
const timers = manualTimers();
|
||||
const warnings = [];
|
||||
let rejectBuild;
|
||||
const service = createIndexerService({
|
||||
buildIndex: () => new Promise((_resolve, reject) => { rejectBuild = reject; }),
|
||||
watchProjects: () => null,
|
||||
writeHeartbeat: () => {},
|
||||
timers,
|
||||
stabilityMs: 0,
|
||||
logger: { warn: (msg) => warnings.push(msg) },
|
||||
});
|
||||
|
||||
const build = service.runBuildNow('startup');
|
||||
service.stop(); // manual rebuild path tears the worker down mid-build
|
||||
rejectBuild(new Error('Indexer worker stopped'));
|
||||
await build;
|
||||
|
||||
assert.deepEqual(warnings, []);
|
||||
});
|
||||
|
||||
test('indexer service logs a build that fails while running', async () => {
|
||||
const timers = manualTimers();
|
||||
const warnings = [];
|
||||
let rejectBuild;
|
||||
const service = createIndexerService({
|
||||
buildIndex: () => new Promise((_resolve, reject) => { rejectBuild = reject; }),
|
||||
watchProjects: () => null,
|
||||
writeHeartbeat: () => {},
|
||||
timers,
|
||||
stabilityMs: 0,
|
||||
logger: { warn: (msg) => warnings.push(msg) },
|
||||
});
|
||||
|
||||
const build = service.runBuildNow('watch');
|
||||
rejectBuild(new Error('disk on fire'));
|
||||
await build;
|
||||
|
||||
assert.equal(warnings.length, 1);
|
||||
assert.match(warnings[0], /Obelisk index build failed: disk on fire/);
|
||||
});
|
||||
|
||||
test('indexer service waits for a stability window before building', async () => {
|
||||
const timers = manualTimers();
|
||||
const calls = [];
|
||||
|
||||
Reference in New Issue
Block a user