diff --git a/biome.json b/biome.json index 1fbc28920..f4361aeed 100644 --- a/biome.json +++ b/biome.json @@ -60,7 +60,6 @@ "!**/vendor/**/*", "!**/node_modules/**/*", "!**/test-sessions.ts", - "!**/template.generated.ts", "!**/docs-index.generated.ts", "!**/agent_pb.ts", "!.worktrees/**/*", diff --git a/docs/porting-from-pi-mono.md b/docs/porting-from-pi-mono.md index 23e4dfcd1..a7ac8dbab 100644 --- a/docs/porting-from-pi-mono.md +++ b/docs/porting-from-pi-mono.md @@ -100,7 +100,7 @@ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "myapp-")); ## 5) Prefer Bun embeds (no copying) -Do not add new runtime asset copy steps. Keep assets in repo and prefer Bun embeds/imports; preserve existing explicit generation workflows such as `packages/coding-agent/src/export/html/template.generated.ts`. +Do not add new runtime asset copy steps. Keep assets in repo and prefer Bun embeds/imports; preserve existing explicit generation workflows such as `packages/coding-agent/src/export/html/tool-views.generated.js` (built from collab-web sources via `bun run build-tool-views`). - If upstream copies assets into a dist folder, replace with Bun-friendly embeds. - Prompts are static `.md` files; use Bun text imports (`with { type: "text" }`) and Handlebars instead of inline prompt strings. diff --git a/package.json b/package.json index 451ef7ea3..c4117663e 100644 --- a/package.json +++ b/package.json @@ -157,13 +157,13 @@ "lint:py": "ruff check python && ruff format --check python", "fix:py": "ruff check --fix python && ruff format python", "prepublishOnly": "bun run check", - "prepare": "bun --cwd=packages/coding-agent run generate-docs-index", + "prepare": "bun run generate-docs-index && bun run build-tool-views", "publish": "bun run prepublishOnly && npm publish -ws --access public", "publish:dry": "bun run prepublishOnly && npm publish -ws --access public --dry-run", "release": "bun scripts/release.ts", "generate-models": "bun --cwd=packages/catalog run generate-models", "generate-docs-index": "bun --cwd=packages/coding-agent run generate-docs-index", - "generate-template": "bun --cwd=packages/coding-agent run generate-template", + "build-tool-views": "bun --cwd=packages/collab-web run build:tool-views", "check-spoofed-versions": "bun scripts/check-spoofed-versions.ts" }, "devDependencies": { diff --git a/packages/coding-agent/.gitignore b/packages/coding-agent/.gitignore deleted file mode 100644 index a4a1c26c9..000000000 --- a/packages/coding-agent/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src/core/export-html/template.generated.ts diff --git a/packages/coding-agent/DEVELOPMENT.md b/packages/coding-agent/DEVELOPMENT.md index 3f16ac804..caace8d82 100644 --- a/packages/coding-agent/DEVELOPMENT.md +++ b/packages/coding-agent/DEVELOPMENT.md @@ -1111,8 +1111,8 @@ Use only script names that exist in `packages/coding-agent/package.json`: - `bun --cwd=packages/coding-agent run format-prompts` - Regenerate docs index files for package docs: - `bun --cwd=packages/coding-agent run generate-docs-index` -- Regenerate template artifacts: - - `bun --cwd=packages/coding-agent run generate-template` +- Rebuild the embedded React tool renderers (after changing collab-web `src/tool-render/`): + - `bun --cwd=packages/collab-web run build:tool-views` - Build compiled binary artifact (`dist/omp`): - `bun --cwd=packages/coding-agent run build` diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index 986c926f8..2cce3acd1 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -40,8 +40,7 @@ "fmt": "biome format --write . && bun run format-prompts", "format-prompts": "bun scripts/format-prompts.ts", "generate-docs-index": "bun scripts/generate-docs-index.ts", - "prepack": "bun scripts/generate-docs-index.ts && bun scripts/bundle-dist.ts", - "generate-template": "bun scripts/generate-template.ts", + "prepack": "bun scripts/generate-docs-index.ts && bun --cwd=../collab-web run build:tool-views && bun scripts/bundle-dist.ts", "bench:guard": "bun scripts/bench-guard.ts" }, "dependencies": { diff --git a/packages/coding-agent/scripts/generate-template.ts b/packages/coding-agent/scripts/generate-template.ts deleted file mode 100644 index 8d2ae3c4f..000000000 --- a/packages/coding-agent/scripts/generate-template.ts +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bun -/** - * Pre-compute the HTML template at publish time. - * This avoids the Bun macro restriction in node_modules. - */ - -const dir = new URL("../src/export/html/", import.meta.url).pathname; - -// Read all files -const html = await Bun.file(`${dir}template.html`).text(); -const css = await Bun.file(`${dir}template.css`).text(); -const js = await Bun.file(`${dir}template.js`).text(); - -// Minify CSS -const minifiedCss = css - .replace(/\/\*[\s\S]*?\*\//g, "") - .replace(/\s+/g, " ") - .replace(/\s*([{}:;,])\s*/g, "$1") - .trim(); - -// Inline everything; use function replacements so `$'`, `$&`, `$$`, etc. inside -// the embedded CSS/JS are not interpreted as substitution patterns. -const template = html - .replace("", () => ``) - .replace("", () => ``); - -// Write generated file -const output = `// Auto-generated by scripts/generate-template.ts - DO NOT EDIT -export const TEMPLATE = ${JSON.stringify(template)}; -`; - -await Bun.write(`${dir}template.generated.ts`, output); -console.log("Generated template.generated.ts"); diff --git a/packages/coding-agent/src/bun-imports.d.ts b/packages/coding-agent/src/bun-imports.d.ts index f783792aa..90c3f7077 100644 --- a/packages/coding-agent/src/bun-imports.d.ts +++ b/packages/coding-agent/src/bun-imports.d.ts @@ -26,3 +26,20 @@ declare module "*.lark" { const content: string; export default content; } + +// Session-export template assets imported as text. +// No `*.html` declaration: bun-types claims that pattern as HTMLBundle, so the +// text import in src/export/html/index.ts casts at the use site instead. +declare module "*.css" { + const content: string; + export default content; +} +declare module "*/template.js" { + const content: string; + export default content; +} + +declare module "*.generated.js" { + const content: string; + export default content; +} diff --git a/packages/coding-agent/src/export/html/index.ts b/packages/coding-agent/src/export/html/index.ts index 5f1b010ff..b98d5e813 100644 --- a/packages/coding-agent/src/export/html/index.ts +++ b/packages/coding-agent/src/export/html/index.ts @@ -2,9 +2,39 @@ import * as path from "node:path"; import type { AgentState } from "@oh-my-pi/pi-agent-core"; import { APP_NAME, isEnoent } from "@oh-my-pi/pi-utils"; import { getResolvedThemeColors, getThemeExportColors } from "../../modes/theme/theme"; -import { type SessionEntry, type SessionHeader, SessionManager } from "../../session/session-manager"; -// Pre-generated template (created by scripts/generate-template.ts at publish time) -import { TEMPLATE } from "./template.generated"; +import { + loadEntriesFromFile, + type SessionEntry, + type SessionHeader, + SessionManager, +} from "../../session/session-manager"; +import templateCss from "./template.css" with { type: "text" }; +import templateHtml from "./template.html" with { type: "text" }; +import templateJs from "./template.js" with { type: "text" }; +// Pre-built React tool renderers: built by `bun --cwd=packages/collab-web run build:tool-views`, +// run automatically by root `prepare` on install and by `prepack` at publish. +import toolViewsJs from "./tool-views.generated.js" with { type: "text" }; + +let cachedTemplate: string | undefined; + +/** Compose the standalone export template: minified CSS, tool renderers, and viewer JS inlined. */ +export function getTemplate(): string { + if (cachedTemplate) return cachedTemplate; + const minifiedCss = templateCss + .replace(/\/\*[\s\S]*?\*\//g, "") + .replace(/\s+/g, " ") + .replace(/\s*([{}:;,])\s*/g, "$1") + .trim(); + // Function replacements so `$'`, `$&`, `$$`, etc. inside the embedded + // CSS/JS are not interpreted as substitution patterns. The cast is safe: + // `with { type: "text" }` yields a string at runtime; bun-types just types + // every *.html import as HTMLBundle (TS can't vary types by import attribute). + cachedTemplate = (templateHtml as unknown as string) + .replace("", () => ``) + .replace("", () => ``) + .replace("", () => ``); + return cachedTemplate; +} export interface ExportOptions { outputPath?: string; @@ -106,10 +136,9 @@ async function generateHtml(sessionData: SessionData, themeName?: string): Promi // Use function replacements so `$'`, `$&`, `$$`, `$n`, etc. in the // substituted CSS/base64 are not interpreted as substitution patterns // (see https://mdn.io/String.replace). - return TEMPLATE.replace("", () => ``).replace( - "{{SESSION_DATA}}", - () => sessionDataBase64, - ); + return getTemplate() + .replace("", () => ``) + .replace("{{SESSION_DATA}}", () => sessionDataBase64); } /** Export session to HTML using SessionManager and AgentState. */ diff --git a/packages/coding-agent/src/export/html/template.generated.ts b/packages/coding-agent/src/export/html/template.generated.ts deleted file mode 100644 index 168182e87..000000000 --- a/packages/coding-agent/src/export/html/template.generated.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Auto-generated by scripts/generate-template.ts - DO NOT EDIT -export const TEMPLATE = "\n\n\n \n \n Session Export\n \n \n\n\n \n
\n
\n \n
\n
\n
\n
\n
\n
\n \"\"\n
\n
\n\n \n \n \n \n\n\n"; diff --git a/packages/coding-agent/src/export/html/template.macro.ts b/packages/coding-agent/src/export/html/template.macro.ts deleted file mode 100644 index 26a532189..000000000 --- a/packages/coding-agent/src/export/html/template.macro.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Bun macro that inlines HTML template with CSS/JS at compile time. - * This runs during `bun build` and embeds the result as a string. - */ -export async function getTemplate(): Promise { - const dir = new URL(".", import.meta.url).pathname; - - // Read all files - const html = await Bun.file(`${dir}template.html`).text(); - const css = await Bun.file(`${dir}template.css`).text(); - const js = await Bun.file(`${dir}template.js`).text(); - - // Minify CSS - const minifiedCss = css - .replace(/\/\*[\s\S]*?\*\//g, "") - .replace(/\s+/g, " ") - .replace(/\s*([{}:;,])\s*/g, "$1") - .trim(); - - // Inline everything; use function replacements so `$'`, `$&`, `$$`, etc. - // inside the embedded CSS/JS are not interpreted as substitution patterns. - return html - .replace("", () => ``) - .replace("", () => ``); -}