diff --git a/biome.json b/biome.json
index d07721d5a..aa33de87a 100644
--- a/biome.json
+++ b/biome.json
@@ -33,6 +33,7 @@
"!**/node_modules/**/*",
"!**/test-sessions.ts",
"!**/models.generated.ts",
+ "!**/template.generated.ts",
"!packages/web-ui/src/app.css",
"!packages/mom/data/**/*",
"!!**/node_modules"
diff --git a/bun.lock b/bun.lock
index 789a1d03b..b2e2e568b 100644
--- a/bun.lock
+++ b/bun.lock
@@ -20,7 +20,7 @@
},
"packages/agent": {
"name": "@oh-my-pi/pi-agent-core",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"dependencies": {
"@oh-my-pi/pi-ai": "workspace:*",
"@oh-my-pi/pi-tui": "workspace:*",
@@ -32,7 +32,7 @@
},
"packages/ai": {
"name": "@oh-my-pi/pi-ai",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"bin": {
"pi-ai": "./src/cli.ts",
},
@@ -56,7 +56,7 @@
},
"packages/coding-agent": {
"name": "@oh-my-pi/pi-coding-agent",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"bin": {
"pi": "src/cli.ts",
},
@@ -87,7 +87,7 @@
},
"packages/mom": {
"name": "@oh-my-pi/pi-mom",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"bin": {
"mom": "src/main.ts",
},
@@ -111,7 +111,7 @@
},
"packages/tui": {
"name": "@oh-my-pi/pi-tui",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"dependencies": {
"@types/mime-types": "^2.1.4",
"chalk": "^5.5.0",
@@ -126,7 +126,7 @@
},
"packages/web-ui": {
"name": "@oh-my-pi/pi-web-ui",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"dependencies": {
"@lmstudio/sdk": "^1.5.0",
"@oh-my-pi/pi-agent-core": "workspace:*",
diff --git a/packages/agent/CHANGELOG.md b/packages/agent/CHANGELOG.md
index 748c5dc24..8fdfcd5f8 100644
--- a/packages/agent/CHANGELOG.md
+++ b/packages/agent/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/agent/package.json b/packages/agent/package.json
index ff0b73295..046bf0d6d 100644
--- a/packages/agent/package.json
+++ b/packages/agent/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-agent-core",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
"type": "module",
"main": "./src/index.ts",
diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md
index 0e3e7135b..c8535ad8b 100644
--- a/packages/ai/CHANGELOG.md
+++ b/packages/ai/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/ai/package.json b/packages/ai/package.json
index 32d9d21b7..12b9cc822 100644
--- a/packages/ai/package.json
+++ b/packages/ai/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-ai",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "Unified LLM API with automatic model discovery and provider configuration",
"type": "module",
"main": "./src/index.ts",
diff --git a/packages/coding-agent/.gitignore b/packages/coding-agent/.gitignore
new file mode 100644
index 000000000..a4a1c26c9
--- /dev/null
+++ b/packages/coding-agent/.gitignore
@@ -0,0 +1 @@
+src/core/export-html/template.generated.ts
diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md
index 7d6c01d4e..6dc516bfa 100644
--- a/packages/coding-agent/CHANGELOG.md
+++ b/packages/coding-agent/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json
index 98c5fa079..11dd99056 100644
--- a/packages/coding-agent/package.json
+++ b/packages/coding-agent/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-coding-agent",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
"type": "module",
"piConfig": {
@@ -33,8 +33,10 @@
"clean": "rm -rf dist",
"build": "tsgo -p tsconfig.build.json && chmod +x dist/cli.js",
"build:binary": "bun build --compile ./src/cli.ts --outfile dist/pi",
+ "generate-template": "bun scripts/generate-template.ts",
+ "postinstall": "[ -f scripts/generate-template.ts ] && bun run generate-template || true",
"test": "bun test",
- "prepublishOnly": "npm run clean && npm run build"
+ "prepublishOnly": "bun run generate-template && bun run clean && bun run build"
},
"dependencies": {
"@oh-my-pi/pi-agent-core": "workspace:*",
diff --git a/packages/coding-agent/scripts/generate-template.ts b/packages/coding-agent/scripts/generate-template.ts
new file mode 100644
index 000000000..26ac5273b
--- /dev/null
+++ b/packages/coding-agent/scripts/generate-template.ts
@@ -0,0 +1,32 @@
+#!/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/core/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
+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/core/export-html/index.ts b/packages/coding-agent/src/core/export-html/index.ts
index 372014860..2552d6dba 100644
--- a/packages/coding-agent/src/core/export-html/index.ts
+++ b/packages/coding-agent/src/core/export-html/index.ts
@@ -5,8 +5,8 @@ import { APP_NAME } from "../../config";
import { getResolvedThemeColors, getThemeExportColors } from "../../modes/interactive/theme/theme";
import { SessionManager } from "../session-manager";
-// Bun macro: bundles HTML+CSS+JS at compile time, evaluated at bundle time
-import { getTemplate } from "./template.macro" with { type: "macro" };
+// Pre-generated template (created by scripts/generate-template.ts at publish time)
+import { TEMPLATE } from "./template.generated";
export interface ExportOptions {
outputPath?: string;
@@ -101,14 +101,14 @@ interface SessionData {
}
/** Generate HTML from bundled template with runtime substitutions. */
-async function generateHtml(sessionData: SessionData, themeName?: string): Promise {
+function generateHtml(sessionData: SessionData, themeName?: string): string {
const themeVars = generateThemeVars(themeName);
const sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString("base64");
- const template = await getTemplate();
- return template
- .replace("", ``)
- .replace("{{SESSION_DATA}}", sessionDataBase64);
+ return TEMPLATE.replace("", ``).replace(
+ "{{SESSION_DATA}}",
+ sessionDataBase64,
+ );
}
/** Export session to HTML using SessionManager and AgentState. */
@@ -131,7 +131,7 @@ export async function exportSessionToHtml(
tools: state?.tools?.map((t) => ({ name: t.name, description: t.description })),
};
- const html = await generateHtml(sessionData, opts.themeName);
+ const html = generateHtml(sessionData, opts.themeName);
const outputPath = opts.outputPath || `${APP_NAME}-session-${basename(sessionFile, ".jsonl")}.html`;
writeFileSync(outputPath, html, "utf8");
@@ -151,7 +151,7 @@ export async function exportFromFile(inputPath: string, options?: ExportOptions
leafId: sm.getLeafId(),
};
- const html = await generateHtml(sessionData, opts.themeName);
+ const html = generateHtml(sessionData, opts.themeName);
const outputPath = opts.outputPath || `${APP_NAME}-session-${basename(inputPath, ".jsonl")}.html`;
writeFileSync(outputPath, html, "utf8");
diff --git a/packages/mom/CHANGELOG.md b/packages/mom/CHANGELOG.md
index aaa043643..7551fddd1 100644
--- a/packages/mom/CHANGELOG.md
+++ b/packages/mom/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/mom/package.json b/packages/mom/package.json
index cab953fc6..74d9da4e4 100644
--- a/packages/mom/package.json
+++ b/packages/mom/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-mom",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "Slack bot that delegates messages to the pi coding agent",
"type": "module",
"bin": {
diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md
index c85c72cbb..ff5cd09d7 100644
--- a/packages/tui/CHANGELOG.md
+++ b/packages/tui/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/tui/package.json b/packages/tui/package.json
index 9f53c4ad3..0cd4a9dd7 100644
--- a/packages/tui/package.json
+++ b/packages/tui/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-tui",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
"type": "module",
"main": "src/index.ts",
diff --git a/packages/web-ui/CHANGELOG.md b/packages/web-ui/CHANGELOG.md
index 7783ad486..8dda9e0c9 100644
--- a/packages/web-ui/CHANGELOG.md
+++ b/packages/web-ui/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## [2.3.1337] - 2026-01-03
+
## [2.2.1337] - 2026-01-03
## [2.1.1337] - 2026-01-03
diff --git a/packages/web-ui/package.json b/packages/web-ui/package.json
index bd2bc0a6b..ba33950e9 100644
--- a/packages/web-ui/package.json
+++ b/packages/web-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@oh-my-pi/pi-web-ui",
- "version": "2.2.1337",
+ "version": "2.3.1337",
"description": "Reusable web UI components for AI chat interfaces powered by @oh-my-pi/pi-ai",
"type": "module",
"main": "src/index.ts",