diff --git a/package.json b/package.json index 4f9990a1..219e3a3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.27.1.0", + "version": "1.28.0.0", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/scripts/gen-llms-txt.ts b/scripts/gen-llms-txt.ts index 1cc5cbf3..02e55d12 100644 --- a/scripts/gen-llms-txt.ts +++ b/scripts/gen-llms-txt.ts @@ -230,24 +230,30 @@ export async function writeLlmsTxt(opts: GenerateOptions & { outputPath?: string } // ─── CLI entry ────────────────────────────────────────────── +// Wrapped in an IIFE so top-level await doesn't make this module async-by- +// import (which would break require() consumers like +// test/gen-skill-docs.test.ts that pull writeLlmsTxt indirectly via +// gen-skill-docs). if (import.meta.main) { - const strict = process.argv.includes('--strict'); - const dryRun = process.argv.includes('--dry-run'); - const result = dryRun - ? await generateLlmsTxt({ strict }) - : await writeLlmsTxt({ strict }); + void (async () => { + const strict = process.argv.includes('--strict'); + const dryRun = process.argv.includes('--dry-run'); + const result = dryRun + ? await generateLlmsTxt({ strict }) + : await writeLlmsTxt({ strict }); - for (const w of result.warnings) console.error(`[gen-llms-txt] WARN: ${w}`); + for (const w of result.warnings) console.error(`[gen-llms-txt] WARN: ${w}`); - if (dryRun) { - const existing = fs.existsSync(OUTPUT) ? fs.readFileSync(OUTPUT, 'utf-8') : ''; - if (existing !== result.content) { - console.error('[gen-llms-txt] OUT OF DATE — run `bun run gen:skill-docs` to regenerate gstack/llms.txt'); - process.exit(1); + if (dryRun) { + const existing = fs.existsSync(OUTPUT) ? fs.readFileSync(OUTPUT, 'utf-8') : ''; + if (existing !== result.content) { + console.error('[gen-llms-txt] OUT OF DATE — run `bun run gen:skill-docs` to regenerate gstack/llms.txt'); + process.exit(1); + } + console.log('[gen-llms-txt] up to date'); + } else { + console.log(`[gen-llms-txt] wrote ${OUTPUT}`); + console.log(`[gen-llms-txt] skills=${result.skills.length} browse=${result.browseCommands.length} design=${result.designCommands.length}`); } - console.log('[gen-llms-txt] up to date'); - } else { - console.log(`[gen-llms-txt] wrote ${OUTPUT}`); - console.log(`[gen-llms-txt] skills=${result.skills.length} browse=${result.browseCommands.length} design=${result.designCommands.length}`); - } + })(); } diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 2f23c26a..b89aea8b 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -12,6 +12,7 @@ import { COMMAND_DESCRIPTIONS } from '../browse/src/commands'; import { SNAPSHOT_FLAGS } from '../browse/src/snapshot'; import { discoverTemplates } from './discover-skills'; +import { writeLlmsTxt } from './gen-llms-txt'; import * as fs from 'fs'; import * as path from 'path'; import type { Host, TemplateContext } from './resolvers/types'; @@ -665,18 +666,22 @@ if (!DRY_RUN) { // Regenerate gstack/llms.txt — single-file capability index for AI agents. // Runs after SKILL.md generation so it sees current skill descriptions and -// browse command list. Freshness is asserted in test/llms-txt-shape.test.ts. +// browse command list. Wrapped in an IIFE so the await-import doesn't make +// this module async (test/gen-skill-docs.test.ts uses require() to pull +// extractVoiceTriggers/processVoiceTriggers, which fails on async modules). +// Freshness is asserted in test/llms-txt-shape.test.ts. if (!DRY_RUN) { - try { - const { writeLlmsTxt } = await import('./gen-llms-txt'); - const result = await writeLlmsTxt(); - if (result.warnings.length > 0) { - for (const w of result.warnings) console.error(`[gen-llms-txt] WARN: ${w}`); - } else { - console.log(`[gen-llms-txt] gstack/llms.txt: ${result.skills.length} skills, ${result.browseCommands.length} browse commands`); + void (async () => { + try { + const result = await writeLlmsTxt(); + if (result.warnings.length > 0) { + for (const w of result.warnings) console.error(`[gen-llms-txt] WARN: ${w}`); + } else { + console.log(`[gen-llms-txt] gstack/llms.txt: ${result.skills.length} skills, ${result.browseCommands.length} browse commands`); + } + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`[gen-llms-txt] FAILED: ${msg}`); } - } catch (err) { - const msg = err instanceof Error ? err.message : String(err); - console.error(`[gen-llms-txt] FAILED: ${msg}`); - } + })(); }