diff --git a/CHANGELOG.md b/CHANGELOG.md index 29fb109..70ce4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ format and uses semantic versioning when versioned releases are published. ## [Unreleased] +- Package smoke verification now checks the CLI bin target, documentation, + safety notes, package metadata, and npm files allowlist before the dry-run + pack. + ### Added - Local-first turn-taking engine with VAD, push-to-talk, wake-hook, half-duplex, mute, and barge-in semantics. diff --git a/README.md b/README.md index 989ebe4..a316784 100644 --- a/README.md +++ b/README.md @@ -157,10 +157,16 @@ npm run check npm test npm run typecheck npm run build +npm run smoke +npm run package:smoke npm run release:check bash scripts/validate.sh ``` +`npm run package:smoke` verifies the published `bargekit` bin target, package +metadata, documentation links, safety notes, and files allowlist before printing +the `npm pack --dry-run` tarball contents. + ## Documentation - [Turn-taking state machine contract](docs/TURN_TAKING_STATE_MACHINE.md) diff --git a/package.json b/package.json index 469d8ba..1579322 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,12 @@ "files": [ "src", "demo", + "docs", "examples", "README.md", "LICENSE", "SECURITY.md", + "SAFETY.md", "CHANGELOG.md", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md" @@ -30,7 +32,7 @@ "test": "node --test", "typecheck": "tsc --project tsconfig.json", "build": "node scripts/build.mjs", - "package:smoke": "npm pack --dry-run", + "package:smoke": "node scripts/verify-package.mjs && npm pack --dry-run", "release:check": "npm run check && npm test && npm run typecheck && npm run build && npm run smoke && npm run package:smoke", "smoke": "node test/fixtures.test.js", "lint": "npm run check" diff --git a/scripts/verify-package.mjs b/scripts/verify-package.mjs new file mode 100644 index 0000000..ea6987b --- /dev/null +++ b/scripts/verify-package.mjs @@ -0,0 +1,27 @@ +import { accessSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; + +const pkg = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')); + +for (const [name, target] of Object.entries(pkg.bin ?? {})) { + accessSync(new URL(`../${target}`, import.meta.url)); + console.log(`verified bin ${name} -> ${target}`); +} + +for (const entry of ['src', 'demo', 'docs', 'examples', 'README.md', 'LICENSE', 'SECURITY.md', 'SAFETY.md', 'CHANGELOG.md', 'CONTRIBUTING.md']) { + if (!pkg.files?.includes(entry)) { + throw new Error(`package files allowlist is missing ${entry}`); + } +} + +for (const path of ['../docs/CLI.md', '../docs/PRIVACY_PLATFORM_GUIDE.md', '../docs/TURN_TAKING_STATE_MACHINE.md', '../SAFETY.md']) { + accessSync(new URL(path, import.meta.url)); +} + +for (const field of ['repository', 'bugs', 'homepage', 'license']) { + if (!pkg[field]) { + throw new Error(`package metadata is missing ${field}`); + } +} + +console.log('verified package metadata, docs, safety notes, and files allowlist');