Skip to content

Commit efead8f

Browse files
committed
fix: generate .ts from .md at build time for bundler compatibility
Fixes issue where readFileSync with __dirname fails when bundled by Bun (same issue as #222, reintroduced by #327). - Add scripts/generate-prompts.ts prebuild script - Import generated .ts files instead of runtime readFileSync - Remove postbuild .md copy (no longer needed)
1 parent 3d9e4df commit efead8f

4 files changed

Lines changed: 52 additions & 10 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ Thumbs.db
2828
# OpenCode
2929
.opencode/
3030

31+
# Generated prompt files (from scripts/generate-prompts.ts)
32+
lib/prompts/*.generated.ts
33+
3134
# Tests (local development only)
3235
tests/
3336
notes/

lib/prompts/index.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
import { readFileSync } from "node:fs"
2-
import { dirname, join } from "node:path"
3-
import { fileURLToPath } from "node:url"
4-
51
// Tool specs
62
import { PRUNE_TOOL_SPEC } from "./prune-tool-spec"
73
import { DISTILL_TOOL_SPEC } from "./distill-tool-spec"
84
import { COMPRESS_TOOL_SPEC } from "./compress-tool-spec"
95

10-
const __dirname = dirname(fileURLToPath(import.meta.url))
11-
12-
// Load markdown prompts at module init
13-
const SYSTEM_PROMPT = readFileSync(join(__dirname, "system.md"), "utf-8")
14-
const NUDGE = readFileSync(join(__dirname, "nudge.md"), "utf-8")
6+
// Generated prompts (from .md files via scripts/generate-prompts.ts)
7+
import { SYSTEM as SYSTEM_PROMPT } from "./system.generated"
8+
import { NUDGE } from "./nudge.generated"
159

1610
export interface ToolFlags {
1711
prune: boolean

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
"types": "./dist/index.d.ts",
99
"scripts": {
1010
"clean": "rm -rf dist",
11+
"generate:prompts": "tsx scripts/generate-prompts.ts",
12+
"prebuild": "npm run generate:prompts",
1113
"build": "npm run clean && tsc",
12-
"postbuild": "rm -rf dist/logs && cp lib/prompts/*.md dist/lib/prompts/",
1314
"prepublishOnly": "npm run build",
1415
"dev": "opencode plugin dev",
1516
"typecheck": "tsc --noEmit",

scripts/generate-prompts.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env tsx
2+
/**
3+
* Prebuild script that generates TypeScript files from Markdown prompts.
4+
*
5+
* This solves the issue where readFileSync with __dirname fails when the
6+
* package is bundled by Bun (see issue #222, PR #272, #327).
7+
*
8+
* The .md files are kept for convenient editing, and this script generates
9+
* .ts files with exported string constants that bundle correctly.
10+
*/
11+
12+
import { readFileSync, writeFileSync, readdirSync } from "node:fs"
13+
import { dirname, join, basename } from "node:path"
14+
import { fileURLToPath } from "node:url"
15+
16+
const __dirname = dirname(fileURLToPath(import.meta.url))
17+
const PROMPTS_DIR = join(__dirname, "..", "lib", "prompts")
18+
19+
// Find all .md files in the prompts directory
20+
const mdFiles = readdirSync(PROMPTS_DIR).filter((f) => f.endsWith(".md"))
21+
22+
for (const mdFile of mdFiles) {
23+
const mdPath = join(PROMPTS_DIR, mdFile)
24+
const baseName = basename(mdFile, ".md")
25+
const constName = baseName.toUpperCase().replace(/-/g, "_")
26+
const tsPath = join(PROMPTS_DIR, `${baseName}.generated.ts`)
27+
28+
const content = readFileSync(mdPath, "utf-8")
29+
30+
// Escape backticks and ${} template expressions for safe embedding in template literal
31+
const escaped = content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")
32+
33+
const tsContent = `// AUTO-GENERATED FILE - DO NOT EDIT
34+
// Generated from ${mdFile} by scripts/generate-prompts.ts
35+
// To modify, edit ${mdFile} and run \`npm run generate:prompts\`
36+
37+
export const ${constName} = \`${escaped}\`
38+
`
39+
40+
writeFileSync(tsPath, tsContent)
41+
console.log(`Generated: ${baseName}.generated.ts`)
42+
}
43+
44+
console.log(`Done! Generated ${mdFiles.length} TypeScript file(s) from Markdown prompts.`)

0 commit comments

Comments
 (0)