From 593affe14a54629ebb1aa05c30b53fc3fecc5a97 Mon Sep 17 00:00:00 2001 From: Roger Chappel Date: Mon, 24 Aug 2026 18:40:20 +1000 Subject: [PATCH 1/2] test: verify documented API symbols --- scripts/verify-documented-imports.mjs | 33 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/scripts/verify-documented-imports.mjs b/scripts/verify-documented-imports.mjs index 30307ef..f92f990 100644 --- a/scripts/verify-documented-imports.mjs +++ b/scripts/verify-documented-imports.mjs @@ -12,6 +12,13 @@ const documentedImports = [ .map((match) => match[1]) ) ]; +const staleCoreExamples = ['EVENTS.userSpeechStarted', 'setPushToTalk(', 'triggerWake(']; + +for (const example of staleCoreExamples) { + if (apiDocs.includes(example)) { + throw new Error(`docs/API.md references unsupported core API: ${example}`); + } +} if (documentedImports.length === 0) { throw new Error('docs/API.md does not contain any @bargekit/core imports'); @@ -51,10 +58,28 @@ try { ['install', '--ignore-scripts', '--no-audit', '--no-fund', tarballPath], { cwd: consumerDir, stdio: 'inherit' } ); - writeFileSync( - join(consumerDir, 'verify.mjs'), - `await Promise.all(${JSON.stringify(documentedImports)}.map((specifier) => import(specifier)));\n` - ); + const documentedNames = new Map(); + for (const match of apiDocs.matchAll(/import\s*{([^}]+)}\s*from\s*['"](@bargekit\/core(?:\/[^'"]+)?)['"]/g)) { + const names = match[1].split(',').map((name) => name.trim()).filter(Boolean); + documentedNames.set(match[2], [...(documentedNames.get(match[2]) ?? []), ...names]); + } + writeFileSync(join(consumerDir, 'verify.mjs'), ` +const documentedNames = new Map(${JSON.stringify([...documentedNames])}); +for (const [specifier, names] of documentedNames) { + const module = await import(specifier); + for (const name of names) { + if (!(name in module)) throw new Error(\`\${specifier} does not export \${name}\`); + } +} +const { createBargeKit } = await import('@bargekit/core'); +const engine = createBargeKit({ mode: 'vad' }); +for (const method of ['on', 'ingestLevel', 'press', 'release', 'detectWake']) { + if (typeof engine[method] !== 'function') throw new Error(\`BargeKitEngine does not provide \${method}()\`); +} +const unsubscribe = engine.on('bargekit.user_speech.started', () => {}); +if (typeof unsubscribe !== 'function') throw new Error('BargeKitEngine.on() must return an unsubscribe function'); +unsubscribe(); +`); execFileSync('node', ['verify.mjs'], { cwd: consumerDir, stdio: 'inherit' }); console.log(`verified documented imports from packed tarball: ${documentedImports.join(', ')}`); From b69d952c7b3d108d3408c3744b007f76e6d6626a Mon Sep 17 00:00:00 2001 From: Roger Chappel Date: Mon, 24 Aug 2026 18:40:39 +1000 Subject: [PATCH 2/2] docs: align API reference with package surface --- docs/API.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/API.md b/docs/API.md index 60dba92..212987c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -8,21 +8,28 @@ BargeKit is a small ESM package. The public surface is split by runtime so apps import { createBargeKit, BargeKitEngine, MODES, STATES, EVENTS } from '@bargekit/core'; ``` -Use `createBargeKit(config)` for the deterministic turn-taking state machine. Feed it level frames with `engine.ingestLevel({ timestamp, level })`; subscribe with `engine.on(EVENTS.userSpeechStarted, handler)`. +Use `createBargeKit(config)` for the deterministic turn-taking state machine. Feed it level frames with `engine.ingestLevel({ timestamp, level })`; subscribe with the literal event names listed in `EVENTS`: + +```js +const engine = createBargeKit({ mode: 'vad' }); +const unsubscribe = engine.on('bargekit.user_speech.started', handler); +engine.ingestLevel({ timestamp: Date.now(), level: 0.7 }); +unsubscribe(); +``` Key behaviours: - `vad` mode opens from level threshold and debounce timing. -- `push_to_talk` ignores hot levels until `setPushToTalk(true)`. -- `wake_hook` requires `triggerWake()` before speech can open the gate. +- `push_to_talk` ignores hot levels until `press()` and stops accepting them after `release()`. +- `wake_hook` requires `detectWake()` before speech can open the gate. - `half_duplex` holds input while agent output is active. - mute always wins over speech detection. ## Fixtures ```js -import { SYNTHETIC_FIXTURES, runFixture, loadFixtureFile } from '@bargekit/core/fixtures'; -import { saveFixtureFile, createFixtureFromLevels } from '@bargekit/core/fixture-io'; +import { SYNTHETIC_FIXTURES, runFixture } from '@bargekit/core/fixtures'; +import { loadFixtureFile, saveFixtureFile, createFixtureFromLevels } from '@bargekit/core/fixture-io'; ``` Built-in fixtures are synthetic level traces, not recordings. Checked-in JSON fixtures live in `tests/fixtures/` for test and CLI compatibility.