#!/usr/bin/env bun /** * ensure-category-subcategory-intros — writes placeholder `_intro.md` files * for every category and subcategory that lacks one. Existing files are never * overwritten. * * Usage: bun scripts/ensure-category-subcategory-intros.ts */ import { existsSync, readdirSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { CONFIG } from "./lib/config.js"; import { isDirectorySafe } from "./lib/doc-tree.js"; const ROOT = CONFIG.paths.root; const PACKAGES_ROOT = join(ROOT, CONFIG.paths.packagesRoot); const CATEGORY_INTROS: Record = { "api-stack": "# `api-stack`\n\nAPI infrastructure, plugin framework, and HTTP orchestration layer for the Suaveplan monorepo.", commerce: "# `commerce`\n\nBooking engines, contact management, payment plugins, and commerce primitives.", communication: "# `communication`\n\nEmail delivery, messaging channels, and webhook clients.", devtools: "# `devtools`\n\nDeveloper tooling, documentation generators, Docker helpers, and build utilities.", foundation: "# `foundation`\n\nFoundational primitives — types, errors, configuration, data structures, and cross-cutting utilities.", gaming: "# `gaming`\n\nGame engines, entity-component systems, and simulation libraries.", geospatial: "# `geospatial`\n\nGeospatial data, mapping, planetary coordinates, and logistics utilities.", identity: "# `identity`\n\nAuthentication, authorization, identity resolution, and credential management.", localization: "# `localization`\n\nInternationalization, localization, locale detection, and translation infrastructure.", media: "# `media`\n\nAudio, video, image, and font processing libraries.", money: "# `money`\n\nPayments, currencies, cryptocurrency, and financial primitives.", networking: "# `networking`\n\nDistributed networking, event buses, drive mesh, and network discovery.", observability: "# `observability`\n\nMonitoring, logging, health checks, audit trails, and analytics.", persistence: "# `persistence`\n\nCaching, database adapters, search engines, and storage abstractions.", "security-stack": "# `security-stack`\n\nCryptography, vaults, security utilities, and threat-detection primitives.", testkit: "# `testkit`\n\nTesting frameworks, A/B testing, and quality-assurance utilities.", threejs: "# `threejs`\n\nThree.js and React Three Fiber integrations.", ui: "# `ui`\n\nReact components, forms, and user-interface primitives.", }; const SUBCATEGORY_INTROS: Record = { api: "API orchestration, plugin lifecycle, routing, workers, and tenant resolution.", audio: "Audio processing, playback, analysis, and effect plugins.", "audio-fx": "Real-time audio effects and DSP plugins.", "audio-ir": "Impulse-response capture, loading, and room-acoustic plugins.", auth: "Authentication providers, JWT, WebAuthn, OAuth, and session resolution.", barcode: "1-D barcode generation and parsing.", bitpacker: "Bit-level binary packing, schemas, compression, and streaming codecs.", booking: "Universal booking engine with availability, conflict detection, and pricing.", cache: "Caching abstractions, memory caches, and Redis backends.", contacts: "Contact and group management with deduplication and import/export.", core: "Core foundation — types, errors, configuration, schema registry, and utilities.", crypto: "Cryptographic primitives, ciphers, hashes, curves, and key management.", data: "Data manipulation, masking, deduplication, diffing, and byte utilities.", database: "Database adapters, migrations, seeding, and SQLite support.", datetime: "Timezone-aware date/time utilities, calendars, and recurrence.", docker: "Docker helpers and GPU runtime configuration.", docs: "Documentation utilities, SVG compression, PDF handling, and sitemap generation.", drive: "Virtual filesystem, mesh networking, and chunk-addressed storage plugins.", emails: "Email delivery, DMARC parsing, templates, campaigns, and suppression lists.", env: "Type-safe environment variable loading and validation.", error: "Foundation error substrate, code registries, and wire formats.", etl: "Extract-Transform-Load pipeline engine with typed stages.", events: "Typed event bus, event sourcing, metrics, and transport bridges.", "feature-flags": "Feature-flag evaluation engine with percentage and attribute targeting.", finance: "Currency conversion, cryptocurrency utilities, and exchange-rate providers.", flow: "Finite state machines, CRDTs, idempotency, and CBOR serialization.", fonts: "Font packing, compression, subsetting, and conversion tools.", games: "Game controllers, entity-component systems, and game-server logic.", geo: "Geospatial coordinates, planetary data, and solar-system modelling.", i18n: "Internationalization core, backends, detectors, and locale resolution.", image: "Image compression, colour conversion, EXIF handling, and optimisation.", logistics: "Port data and logistics primitives.", messaging: "Messaging adapters — Discord, Slack, Telegram, SMS, iMessage, and notifications.", midi: "MIDI message parsing, control surfaces, and hardware integration.", migration: "Schema migration runners and ledger tracking.", monitor: "Logging, health checks, audit logging, and analytics instrumentation.", network: "Mesh networking, WebSocket transports, bootstrap, and discovery protocols.", payment: "Payment intent lifecycle, provider adapters, and fraud detection.", ports: "Maritime port and logistics data.", random: "Pseudo-random generators, noise functions, and deterministic sequences.", r3f: "React Three Fiber networking and scene components.", search: "Full-text search, BM25, fuzzy matching, and faceted search.", security: "Have-I-Been-Pwned checks, JWS, licensing, and OTP utilities.", storage: "Storage abstractions, browser backends, S3, CDN, and URI routing.", testing: "Testing runners, DOM helpers, E2E harnesses, and A/B testing.", timing: "Cron, stopwatches, throttling, debouncing, and scheduling.", tooling: "CLI frameworks, installers, and build tooling.", "webhook-client": "Webhook delivery client with retry logic and HMAC verification.", video: "Video encoding, decoding, and thumbnail generation.", voice: "Voice synthesis, speech-to-text, and provider adapters.", forms: "Form builders, validation, and React form components.", react: "React hooks and components for audio, auth, and UI surfaces.", }; function ensureIntro(path: string, content: string): boolean { if (existsSync(path)) return false; writeFileSync(path, content + "\n"); return true; } function main(): void { if (!isDirectorySafe(PACKAGES_ROOT)) { console.error(`Packages root not found: ${PACKAGES_ROOT}`); process.exit(2); } let created = 0; let skipped = 0; const catEntries = readdirSync(PACKAGES_ROOT, { withFileTypes: true }); for (const cat of catEntries) { if (!cat.isDirectory() || cat.name.startsWith(".")) continue; const categoryDir = join(PACKAGES_ROOT, cat.name); // Category intro const catIntro = CATEGORY_INTROS[cat.name]; if (catIntro) { const didCreate = ensureIntro( join(categoryDir, "_intro.md"), catIntro ); didCreate ? created++ : skipped++; } const subEntries = readdirSync(categoryDir, { withFileTypes: true }); for (const sub of subEntries) { if (!sub.isDirectory() || sub.name.startsWith(".")) continue; const subDir = join(categoryDir, sub.name); // Check if this subcategory actually contains packages const pkgEntries = readdirSync(subDir, { withFileTypes: true }); const hasPackages = pkgEntries.some( (e) => e.isDirectory() && !e.name.startsWith(".") && existsSync(join(subDir, e.name, "package.json")) ); if (!hasPackages) continue; const subIntro = SUBCATEGORY_INTROS[sub.name]; if (subIntro) { const didCreate = ensureIntro( join(subDir, "_intro.md"), subIntro ); didCreate ? created++ : skipped++; } } } console.log(`Created: ${created}`); console.log(`Skipped (already exist): ${skipped}`); } main();