From 4f45e4fdae12c9819b5a2dacffbaae88787afa34 Mon Sep 17 00:00:00 2001 From: akirilyuk Date: Sun, 20 Sep 2026 13:34:11 +0700 Subject: [PATCH] chore(repo): pin @voicethere/agent 0.8.0 and release 0.14.3 Seed init workspaces from templates// (echo/agent.ts) and add world-sync, world-sync-binary, and spatial-showcase create templates. --- CHANGELOG.md | 7 +++ README.md | 2 +- package-lock.json | 99 +++++++++++++++++-------------- package.json | 4 +- src/commands/init.test.ts | 44 +++++++++++--- src/lib/customer-package-json.ts | 4 +- src/lib/project-templates.test.ts | 51 ++++++++++++++++ src/lib/project-templates.ts | 77 ++---------------------- 8 files changed, 160 insertions(+), 128 deletions(-) create mode 100644 src/lib/project-templates.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 890f373..fde0169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). Versioning foll ## [Unreleased] +## [0.14.3] - 2026-09-20 + +### Changed + +- Dependency: `@voicethere/agent` **0.8.0** (runtime verify). Customer `init` workspaces pin `^0.8.0` and seed `templates//` sources (`echo/agent.ts` instead of `echo.ts`). +- **`voicethere init --template`** — add `world-sync`, `world-sync-binary`, and `spatial-showcase` (same ids as dashboard create). + ## [0.14.2] - 2026-09-20 ### Added diff --git a/README.md b/README.md index 478da6e..bf1a59a 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ npm run verify | Flag | Behavior | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--template ` | Platform template (default: `echo`). Also: `blank`, `voice-starter`, `echo-dc`, `voice-showcase`, `game-sync`, `recording-consent`, `positional-tts` | +| `--template ` | Platform template (default: `echo`). Also: `blank`, `voice-starter`, `echo-dc`, `voice-showcase`, `world-sync`, `world-sync-binary`, `game-sync`, `recording-consent`, `positional-tts`, `spatial-showcase` | | `--local-only` | Write files on disk only — no login, cloud project, or source upload | | `--no-install` | Skip `npm install` after scaffolding | | `--force` | Overwrite when `package.json` already exists | diff --git a/package-lock.json b/package-lock.json index 3d3d51b..beb30e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@voicethere/cli", - "version": "0.14.2", + "version": "0.14.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@voicethere/cli", - "version": "0.14.2", + "version": "0.14.3", "license": "MIT", "dependencies": { - "@voicethere/agent": "0.5.3", + "@voicethere/agent": "0.8.0", "commander": "13.1.0", "ffmpeg-static": "5.3.0" }, @@ -481,27 +481,27 @@ } }, "node_modules/@node-webrtc-rust/bindings": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings/-/bindings-0.7.4.tgz", - "integrity": "sha512-7MQoWuUGCxInrJeENb8ZDPU5ZTJD6nRYaTfGP6/MjklqLcIJyG165AS0tq9qz7KlfqBwxh3Yj3ECy9fFRKS65w==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings/-/bindings-0.9.10.tgz", + "integrity": "sha512-7Oz2D59h2fruGS1T9eYWo09t7Im+qPMJUX8LNEgMlZ3nAfF0MNeUkjAqJ9Bhm9L/Led1p0Elt41O1nuD4HVPIg==", "license": "MIT", "peer": true, "engines": { "node": ">=18" }, "optionalDependencies": { - "@node-webrtc-rust/bindings-darwin-arm64": "0.7.4", - "@node-webrtc-rust/bindings-darwin-x64": "0.7.4", - "@node-webrtc-rust/bindings-linux-arm64-gnu": "0.7.4", - "@node-webrtc-rust/bindings-linux-x64-gnu": "0.7.4", - "@node-webrtc-rust/bindings-linux-x64-musl": "0.7.4", - "@node-webrtc-rust/bindings-win32-x64-msvc": "0.7.4" + "@node-webrtc-rust/bindings-darwin-arm64": "0.9.10", + "@node-webrtc-rust/bindings-darwin-x64": "0.9.10", + "@node-webrtc-rust/bindings-linux-arm64-gnu": "0.9.10", + "@node-webrtc-rust/bindings-linux-x64-gnu": "0.9.10", + "@node-webrtc-rust/bindings-linux-x64-musl": "0.9.10", + "@node-webrtc-rust/bindings-win32-x64-msvc": "0.9.10" } }, "node_modules/@node-webrtc-rust/bindings-darwin-arm64": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-darwin-arm64/-/bindings-darwin-arm64-0.7.4.tgz", - "integrity": "sha512-vXZFtCiXHeBsEuo01iLx910NVXzsFcBa8lze5Aw2Zs5EiBgaLxLZuIybICv2Y9uO9IwuXjq7H/RyvxJFZuJeaw==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-darwin-arm64/-/bindings-darwin-arm64-0.9.10.tgz", + "integrity": "sha512-lZiyD8gCfXzlnBPW7QmUt2jSAybYquWdPuuscvGnG47aj5VJBoWKU2eqjgi3kp088yRx53lW6qO+OKZjM8zDSw==", "cpu": [ "arm64" ], @@ -516,9 +516,9 @@ } }, "node_modules/@node-webrtc-rust/bindings-darwin-x64": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-darwin-x64/-/bindings-darwin-x64-0.7.4.tgz", - "integrity": "sha512-UoJzk+mZCpHq5Mm5E4mGi5fP3mQwLr3faUOnONQYl94sTZbQc3LNNMrZi3QggfXvbd0PeNJFN6Ina44Y8Fi5Qw==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-darwin-x64/-/bindings-darwin-x64-0.9.10.tgz", + "integrity": "sha512-8mWG5QRpOK0BggIpK8e1DyoOBF5DcQubkaG9LnsYK4CzGNOyBT51BlK01q7Sd5NKLDtd/eMOq91Hu4iMsXvsBg==", "cpu": [ "x64" ], @@ -533,12 +533,15 @@ } }, "node_modules/@node-webrtc-rust/bindings-linux-arm64-gnu": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-arm64-gnu/-/bindings-linux-arm64-gnu-0.7.4.tgz", - "integrity": "sha512-lZeLCbcq5Tq/R3G97uSU0XDetsqOiUOGLZkWHvGD1KNBNl2myY7DzwCwQEmM0FeSKprVur00Jz7MGxzn9uX7oQ==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-arm64-gnu/-/bindings-linux-arm64-gnu-0.9.10.tgz", + "integrity": "sha512-Sgx0w5YQp2i5LEOFcjlR1fZw1Tmt1Zmn3ApGgrz8URshQkQdS0/WM4vvCUdV+I8/oWoZVsMMdc7MOtcbIE1uyA==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -550,12 +553,15 @@ } }, "node_modules/@node-webrtc-rust/bindings-linux-x64-gnu": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-x64-gnu/-/bindings-linux-x64-gnu-0.7.4.tgz", - "integrity": "sha512-/BSwJgYrPAQXtJ7Qpwv6MF7+HozBHoZPba3NODNbODOkmer+fqRCLvgIgMsXzkGe/5xShbDuT8pGPlNfECoS0g==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-x64-gnu/-/bindings-linux-x64-gnu-0.9.10.tgz", + "integrity": "sha512-SP0EmzlhdcGmelzclvxAY4CDzawN7ls9zSImkP1+7LtY+6GQZVaxTFiN+kUsbzDaGMVsHkhAVHHdV7f2Oz2ijg==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -567,12 +573,15 @@ } }, "node_modules/@node-webrtc-rust/bindings-linux-x64-musl": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-x64-musl/-/bindings-linux-x64-musl-0.7.4.tgz", - "integrity": "sha512-PDa6pSqkwW4/vhqpWfvnd1o8FFqITliqgKGivQs1giC/nhUoC2R4A+Ni9WIeCXd2QHCc+YX0qRRCYm51AZA8wg==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-linux-x64-musl/-/bindings-linux-x64-musl-0.9.10.tgz", + "integrity": "sha512-dSmejbjvv7LKaA8XckroZzLpjOfU6S17jxQvM0Bcan+34L7kQ6O3o/gUQL+iPuUaUbPbAuT97n5YEn4gDzra8w==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -584,9 +593,9 @@ } }, "node_modules/@node-webrtc-rust/bindings-win32-x64-msvc": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-win32-x64-msvc/-/bindings-win32-x64-msvc-0.7.4.tgz", - "integrity": "sha512-Nej7wlgZo30CDU0kaz+50eNWSZhUb1tWBtb1c6WXuj7UVRG7ACei2BnLumj9pYlhBDst6YV40P8hnf1W+J/pQQ==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/bindings-win32-x64-msvc/-/bindings-win32-x64-msvc-0.9.10.tgz", + "integrity": "sha512-mVZeGMC5dPsUvHh7Vp2sjPsZO0wjKYzrhdiR/VLXqYjzSrbRuBfhe1n9krsvIcx33fMZvbpK5epOUylj8RnADQ==", "cpu": [ "x64" ], @@ -601,34 +610,34 @@ } }, "node_modules/@node-webrtc-rust/sdk": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/sdk/-/sdk-0.7.4.tgz", - "integrity": "sha512-zS5P+ZTz6almM3wv9VqWJQnRiaOIbjkl2fJrpOYT+UukclS11LXYyapgCkXhciFAxu2izg68mYTsNkYktZtllQ==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/sdk/-/sdk-0.9.10.tgz", + "integrity": "sha512-ca72CGaPRgrsJcOo8G2f0Rjs/Z91LzxXGCEMIAKgEaslwJ+msqjGFy/AcL+u7IFpN3yRG23v9Yu6ZgCVS2Y6ww==", "license": "MIT", "peer": true, "dependencies": { - "@node-webrtc-rust/bindings": "0.7.4", - "@node-webrtc-rust/signaling": "0.7.4" + "@node-webrtc-rust/bindings": "0.9.10", + "@node-webrtc-rust/signaling": "0.9.10" }, "engines": { "node": ">=18" } }, "node_modules/@node-webrtc-rust/signaling": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@node-webrtc-rust/signaling/-/signaling-0.7.4.tgz", - "integrity": "sha512-kr4x5Ff0X75RLlytYr+UZRl51+Tc4FQpZ9prkcbsVuNtIgOWwA/3mdcrtYjIFiFNrYiEdyTfltENi9mvOniInA==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@node-webrtc-rust/signaling/-/signaling-0.9.10.tgz", + "integrity": "sha512-QKwdF4OD7p8Leot2wyhYFPQcc8kI/vEC+PYk2XJFHP2vxmazW/N2Em8bKYfMEjjgwoPg8Aspx0HhAhgN4IGNVg==", "license": "MIT", "peer": true, "dependencies": { - "@node-webrtc-rust/sdk": "0.7.4", + "@node-webrtc-rust/sdk": "0.9.10", "ws": "^8.18.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@node-webrtc-rust/sdk": "^0.7.4" + "@node-webrtc-rust/sdk": "^0.9.10" }, "peerDependenciesMeta": { "@node-webrtc-rust/sdk": { @@ -1137,12 +1146,12 @@ } }, "node_modules/@voicethere/agent": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@voicethere/agent/-/agent-0.5.3.tgz", - "integrity": "sha512-YmOQIKrwz+8B+GZn1ZvnJV+VFEh4L3cCRvbcRUSga1RBD+nULUh6tNURVELQTiIUbosu80GazvU1UO4r0nfCZw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@voicethere/agent/-/agent-0.8.0.tgz", + "integrity": "sha512-YMIDoGPAl0AoTVb6aYNSSl+qYtKlUdp0UvQSOAQ/ZEyePgWuU+gPZW+S9HiD/d+muyiYqkz82oLSAHBZx+MYwQ==", "license": "MIT", "dependencies": { - "esbuild": "^0.25.12" + "esbuild": "0.25.12" }, "bin": { "agent": "dist/cli.js" @@ -1151,7 +1160,7 @@ "node": ">=26" }, "peerDependencies": { - "@node-webrtc-rust/sdk": ">=0.6.5" + "@node-webrtc-rust/sdk": ">=0.9.0" } }, "node_modules/agent-base": { diff --git a/package.json b/package.json index f2d5815..93d9fff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@voicethere/cli", - "version": "0.14.2", + "version": "0.14.3", "description": "VoiceThere cloud CLI — login, projects, and agent bundle upload", "type": "module", "bin": { @@ -38,7 +38,7 @@ }, "license": "MIT", "dependencies": { - "@voicethere/agent": "0.5.3", + "@voicethere/agent": "0.8.0", "commander": "13.1.0", "ffmpeg-static": "5.3.0" }, diff --git a/src/commands/init.test.ts b/src/commands/init.test.ts index 9a7a52c..2978244 100644 --- a/src/commands/init.test.ts +++ b/src/commands/init.test.ts @@ -74,7 +74,7 @@ describe("runInit", () => { }); putProjectSource.mockResolvedValue({ project_id: "proj-init", - entry_path: "echo.ts", + entry_path: "echo/agent.ts", files: [], revision: 1, }); @@ -108,12 +108,12 @@ describe("runInit", () => { dependencies: Record; scripts: Record; }; - expect(packageJson.dependencies["@voicethere/agent"]).toBe("^0.7.7"); - expect(packageJson.scripts.verify).toContain("echo.ts"); + expect(packageJson.dependencies["@voicethere/agent"]).toBe("^0.8.0"); + expect(packageJson.scripts.verify).toContain("echo/agent.ts"); expect(packageJson.scripts.upload).toBe("voicethere build upload"); expect(packageJson.scripts["source:push"]).toBe("voicethere source push"); - await expect(access(join(target, "echo.ts"))).resolves.toBeUndefined(); + await expect(access(join(target, "echo", "agent.ts"))).resolves.toBeUndefined(); await expect(access(join(target, ".gitignore"))).resolves.toBeUndefined(); await expect( access(join(target, ".voicethere", "config.json")), @@ -135,6 +135,36 @@ describe("runInit", () => { expect(packageJson.dependencies.ioredis).toBe("^5.11.1"); }); + it("writes world-sync JSON template under world-sync/agent.ts", async () => { + const target = join(tempDir, "world-sync-local"); + await runInit({ + dir: target, + template: "world-sync", + localOnly: true, + noInstall: true, + }); + + const packageJson = JSON.parse( + await readFile(join(target, "package.json"), "utf8"), + ) as { dependencies: Record; scripts: Record }; + expect(packageJson.dependencies["@voicethere/agent"]).toBe("^0.8.0"); + expect(packageJson.scripts.build).toContain("world-sync/agent.ts"); + await expect( + access(join(target, "world-sync", "agent.ts")), + ).resolves.toBeUndefined(); + }); + + it("rejects e2e-only redis-sync as a create template", async () => { + await expect( + runInit({ + dir: join(tempDir, "redis-sync-local"), + template: "redis-sync", + localOnly: true, + noInstall: true, + }), + ).rejects.toThrow(/Unknown template "redis-sync"/); + }); + it("writes blank stub with agent.ts entry", async () => { const target = join(tempDir, "blank-local"); await runInit({ @@ -157,8 +187,8 @@ describe("runInit", () => { const target = join(tempDir, "cloud-echo"); getProjectSource.mockResolvedValueOnce({ project_id: "proj-init", - entry_path: "echo.ts", - files: [{ path: "echo.ts", content: "seed" }], + entry_path: "echo/agent.ts", + files: [{ path: "echo/agent.ts", content: "seed" }], revision: 1, }); @@ -185,7 +215,7 @@ describe("runInit", () => { expect(putProjectSource).toHaveBeenCalledWith( "proj-init", expect.objectContaining({ - entry_path: "echo.ts", + entry_path: "echo/agent.ts", revision: 1, files: expect.arrayContaining([ expect.objectContaining({ path: "package.json" }), diff --git a/src/lib/customer-package-json.ts b/src/lib/customer-package-json.ts index 56b9b5f..3dd78d3 100644 --- a/src/lib/customer-package-json.ts +++ b/src/lib/customer-package-json.ts @@ -1,5 +1,5 @@ /** Customer workspace pin — may differ from the CLI runtime `@voicethere/agent` dependency. */ -export const CUSTOMER_AGENT_VERSION = "0.7.7"; +export const CUSTOMER_AGENT_VERSION = "0.8.0"; /** Extra npm deps for platform create templates (not in every agent registry release). */ const EXTRA_TEMPLATE_NPM_DEPS: Record> = { @@ -8,7 +8,7 @@ const EXTRA_TEMPLATE_NPM_DEPS: Record> = { export interface BuildCustomerPackageJsonOptions { templateId: string; - /** Agent entry relative to project root (e.g. `echo.ts`, `voice-showcase/agent.ts`). */ + /** Agent entry relative to project root (e.g. `echo/agent.ts`, `voice-showcase/agent.ts`). */ entryPath: string; /** npm package `name` field — defaults to `voicethere-`. */ packageName?: string; diff --git a/src/lib/project-templates.test.ts b/src/lib/project-templates.test.ts new file mode 100644 index 0000000..ac6afab --- /dev/null +++ b/src/lib/project-templates.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from "vitest"; +import { + assertPlatformCreateTemplateId, + loadTemplateWorkspaceSources, + PLATFORM_CREATE_TEMPLATE_IDS, + resolveTemplateEntryPath, +} from "./project-templates.js"; + +describe("project templates", () => { + it("lists dashboard create templates including 0.8.0 world-sync ids", () => { + expect(PLATFORM_CREATE_TEMPLATE_IDS).toEqual([ + "blank", + "voice-starter", + "echo-dc", + "echo", + "voice-showcase", + "world-sync", + "world-sync-binary", + "game-sync", + "recording-consent", + "positional-tts", + "spatial-showcase", + ]); + }); + + it("resolves folder entries from @voicethere/agent 0.8.0", () => { + expect(resolveTemplateEntryPath("blank")).toBe("agent.ts"); + expect(resolveTemplateEntryPath("echo")).toBe("echo/agent.ts"); + expect(resolveTemplateEntryPath("world-sync-binary")).toBe( + "world-sync-binary/agent.ts", + ); + expect(resolveTemplateEntryPath("spatial-showcase")).toBe( + "spatial-showcase/agent.ts", + ); + }); + + it("loads binary world-sync sources from the installed agent package", () => { + const files = loadTemplateWorkspaceSources("world-sync-binary"); + expect(files.map((file) => file.path)).toEqual([ + "world-sync-binary/agent.ts", + "world-sync-binary/protocol.ts", + ]); + expect(files[0]?.content).toContain("onDataChannelBinary"); + }); + + it("rejects unknown create template ids", () => { + expect(() => assertPlatformCreateTemplateId("redis-sync")).toThrow( + /Unknown template "redis-sync"/, + ); + }); +}); diff --git a/src/lib/project-templates.ts b/src/lib/project-templates.ts index 55c9ae5..b948c80 100644 --- a/src/lib/project-templates.ts +++ b/src/lib/project-templates.ts @@ -1,9 +1,6 @@ -import { readFileSync } from "node:fs"; -import { createRequire } from "node:module"; -import { dirname, join } from "node:path"; - import { getTemplate, + loadTemplateWorkspaceSources as loadAgentTemplateWorkspaceSources, type TemplateSourceFile, } from "@voicethere/agent/templates"; @@ -14,9 +11,12 @@ export const PLATFORM_CREATE_TEMPLATE_IDS = [ "echo-dc", "echo", "voice-showcase", + "world-sync", + "world-sync-binary", "game-sync", "recording-consent", "positional-tts", + "spatial-showcase", ] as const; export type PlatformCreateTemplateId = @@ -26,38 +26,6 @@ const PLATFORM_CREATE_TEMPLATE_SET = new Set( PLATFORM_CREATE_TEMPLATE_IDS, ); -/** Registry entries for templates shipped in newer @voicethere/agent releases. */ -const EXTENDED_TEMPLATE_SOURCE_FILES: Record = { - "voice-showcase": [ - "voice-showcase/agent.ts", - "voice-showcase/conversation.ts", - "voice-showcase/delivery.ts", - "voice-showcase/weather.ts", - "voice-showcase/recipes.ts", - "voice-showcase/fun-facts.ts", - ], - "recording-consent": [ - "recording-consent/agent.ts", - "recording-consent/conversation.ts", - ], - "positional-tts": ["positional-tts/agent.ts", "positional-tts/orbit.ts"], -}; - -const EXTENDED_TEMPLATE_ENTRIES: Record = { - "voice-showcase": "voice-showcase/agent.ts", - "recording-consent": "recording-consent/agent.ts", - "positional-tts": "positional-tts/agent.ts", -}; - -const require = createRequire(import.meta.url); -const templatesModulePath = require.resolve("@voicethere/agent/templates"); -const AGENT_TEMPLATES_DIR = join( - dirname(templatesModulePath), - "..", - "..", - "templates", -); - export const BLANK_AGENT_ENTRY = "agent.ts"; export const BLANK_AGENT_SOURCE = `import { defineAgent } from "@voicethere/agent"; @@ -88,26 +56,7 @@ export function resolveTemplateEntryPath(templateId: string): string { return BLANK_AGENT_ENTRY; } - try { - return getTemplate(templateId).entry; - } catch { - const extended = EXTENDED_TEMPLATE_ENTRIES[templateId]; - if (extended) { - return extended; - } - throw new Error(`Unknown agent template id: ${templateId}`); - } -} - -function readTemplateFile(sourceFile: string): string { - const absolutePath = join(AGENT_TEMPLATES_DIR, sourceFile); - try { - return readFileSync(absolutePath, "utf8"); - } catch { - throw new Error( - `Template source not found: ${sourceFile}. Update @voicethere/agent or pick another --template.`, - ); - } + return getTemplate(templateId).entry; } /** Load template sources with registry-relative paths (dashboard Code UI parity). */ @@ -118,19 +67,5 @@ export function loadTemplateWorkspaceSources( return [{ path: BLANK_AGENT_ENTRY, content: BLANK_AGENT_SOURCE }]; } - let sourceFiles: string[]; - try { - sourceFiles = getTemplate(templateId).sourceFiles; - } catch { - const extended = EXTENDED_TEMPLATE_SOURCE_FILES[templateId]; - if (!extended) { - throw new Error(`Unknown agent template id: ${templateId}`); - } - sourceFiles = extended; - } - - return sourceFiles.map((sourceFile) => ({ - path: sourceFile, - content: readTemplateFile(sourceFile), - })); + return loadAgentTemplateWorkspaceSources(templateId); }