#!/usr/bin/env node /** * GATE 0 — Repository structure and documentation presence. * Fails if required plan/docs/source paths are missing or empty. */ import { existsSync, statSync, readFileSync } from 'node:fs'; import { resolve, dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); /** @type {string[]} */ const requiredFiles = [ 'TODO.md', 'README.md', 'package.json', 'docs/00-sources/provenance.md', 'docs/00-sources/veraetime-openapi.yaml', 'docs/01-product/features-a-m.md', 'docs/01-product/billing-and-keys.md', 'docs/02-architecture/overview.md', 'docs/02-architecture/nats-subjects.md', 'docs/02-architecture/composition.md', 'docs/developer/debugging.md', 'docs/developer/modules/README.md', 'docs/developer/modules/debug.md', 'docs/developer/modules/function-reference.md', 'docs/plans/phase-gates.md', 'packages/zappier/package.json', 'packages/zappier/openapi.yaml', 'packages/zappier/src/pricing.ts', 'packages/verae-zapier-middleware/package.json', 'packages/verae-zapier-middleware/src/debug/config.js', 'packages/verae-zapier-middleware/src/debug/logger.js', 'packages/verae-zapier-middleware/src/debug/redact.js', 'packages/verae-zapier-middleware/src/debug/trace.js', 'packages/verae-zapier-middleware/src/debug/index.js', 'packages/verae-zapier-middleware/src/config.js', 'packages/verae-zapier-middleware/src/errors.js', 'packages/verae-zapier-middleware/src/app.js', 'packages/verae-zapier-middleware/src/nats/subjects.js', 'packages/verae-zapier-middleware/src/nats/connection.js', 'packages/verae-zapier-middleware/src/nats/publishers.js', 'packages/verae-zapier-middleware/src/workers/jobPollerWorker.js', 'packages/verae-zapier-middleware/src/workers/webhookWorker.js', 'packages/verae-zapier-middleware/test/unit/debug.test.js', 'packages/verae-zapier/index.js', 'packages/verae-zapier/authentication.js', 'vendor/zapier-platform/package.json', 'research/README.md', 'research/zapier/README.md', 'research/zapier/getting-started.md', 'research/zapier/PLATFORM-REFERENCE.md', 'research/zapier/VENDOR-RESEARCH.md', ]; /** @type {string[]} */ const requiredDirs = [ 'docs/developer/modules', 'packages/zappier/src', 'packages/zappier/admin', 'packages/zappier/portal', 'packages/verae-zapier-middleware/src/debug', 'packages/verae-zapier-middleware/src/nats', 'packages/verae-zapier-middleware/src/workers', 'packages/verae-zapier', 'vendor/zapier-platform', 'harness', 'research/zapier/raw', 'research/zapier/repos', 'research/zapier/docs/diagrams', 'research/zapier/profiles', 'research/zapier/scratch/veraetime', ]; let failed = false; function fail(msg) { console.error(`FAIL: ${msg}`); failed = true; } function ok(msg) { console.log(`OK: ${msg}`); } for (const rel of requiredDirs) { const p = join(root, rel); if (!existsSync(p) || !statSync(p).isDirectory()) { fail(`missing directory ${rel}`); } else { ok(`dir ${rel}`); } } for (const rel of requiredFiles) { const p = join(root, rel); if (!existsSync(p) || !statSync(p).isFile()) { fail(`missing file ${rel}`); continue; } const size = statSync(p).size; if (size < 40) { fail(`file too small (${size}b): ${rel}`); } else { ok(`file ${rel} (${size}b)`); } } const todo = readFileSync(join(root, 'TODO.md'), 'utf8'); for (const needle of ['GATE 0', 'NATS', 'DEBUG_VERAE', 'gate:all', 'api.veraetime.net']) { if (!todo.includes(needle)) { fail(`TODO.md missing required term: ${needle}`); } else { ok(`TODO.md contains "${needle}"`); } } if (failed) { console.error('\nGATE 0 FAILED'); process.exit(1); } console.log('\nGATE 0 PASSED'); process.exit(0);