mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-08 13:39:45 +08:00
fix(gen-skill-docs): keep module sync so test require() still works
Two regressions caught by the full test suite after the v1.28.0.0
landing pass:
1) package.json version mismatch — VERSION was bumped to 1.28.0.0
but package.json still pinned to 1.27.1.0.
test/gen-skill-docs.test.ts asserts they match.
2) Top-level await in scripts/gen-llms-txt.ts (CLI entry block) and
scripts/gen-skill-docs.ts (post-step) made gen-skill-docs an
async module. test/gen-skill-docs.test.ts uses require() to pull
extractVoiceTriggers/processVoiceTriggers from gen-skill-docs,
which Bun rejects on async modules with:
"TypeError: require() async module ... unsupported.
use 'await import()' instead."
Fix: wrap the await blocks in void IIFEs so the modules remain sync
from a require() perspective.
After fix: all 379 gen-skill-docs tests pass, all 77 new feature
tests pass (3 skipped on macOS — Linux+Xvfb gates).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user