feat(ce-demo-reel): add demo reel skill with Python capture pipeline (#541)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trevin Chow
2026-04-09 21:29:51 -07:00
committed by GitHub
parent f3cc7545e5
commit b979143ad0
18 changed files with 1796 additions and 751 deletions

402
tests/ce-demo-reel.test.ts Normal file
View File

@@ -0,0 +1,402 @@
import { describe, expect, test, beforeAll, afterAll } from "bun:test"
import { promises as fs } from "fs"
import path from "path"
import os from "os"
const SCRIPT = path.join(
process.cwd(),
"plugins",
"compound-engineering",
"skills",
"ce-demo-reel",
"scripts",
"capture-demo.py",
)
async function run(
...args: string[]
): Promise<{ exitCode: number; stdout: string; stderr: string }> {
const proc = Bun.spawn(["python3", SCRIPT, ...args], {
stdout: "pipe",
stderr: "pipe",
})
const exitCode = await proc.exited
const stdout = await new Response(proc.stdout).text()
const stderr = await new Response(proc.stderr).text()
return { exitCode, stdout, stderr }
}
/** Create a minimal valid PNG (1x1 pixel, solid color). */
function createTestPng(color: [number, number, number]): Buffer {
const [r, g, b] = color
// Raw RGB pixel data: 1 row, filter byte 0, then RGB
const rawData = Buffer.from([0, r, g, b])
// Compress with zlib
const compressed = Bun.deflateSync(rawData, { level: 0 })
const cmf = 0x78
const flg = 0x01
let s1 = 1
let s2 = 0
for (const byte of rawData) {
s1 = (s1 + byte) % 65521
s2 = (s2 + s1) % 65521
}
const adler32 = Buffer.alloc(4)
adler32.writeUInt32BE((s2 << 16) | s1)
const zlibData = Buffer.concat([Buffer.from([cmf, flg]), compressed, adler32])
const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])
function chunk(type: string, data: Buffer): Buffer {
const len = Buffer.alloc(4)
len.writeUInt32BE(data.length)
const typeB = Buffer.from(type, "ascii")
const body = Buffer.concat([typeB, data])
const crc = crc32(body)
const crcB = Buffer.alloc(4)
crcB.writeUInt32BE(crc >>> 0)
return Buffer.concat([len, body, crcB])
}
// IHDR: 1x1, 8-bit RGB (color type 2)
const ihdr = Buffer.alloc(13)
ihdr.writeUInt32BE(1, 0)
ihdr.writeUInt32BE(1, 4)
ihdr[8] = 8 // bit depth
ihdr[9] = 2 // color type: RGB
ihdr[10] = 0
ihdr[11] = 0
ihdr[12] = 0
return Buffer.concat([
signature,
chunk("IHDR", ihdr),
chunk("IDAT", zlibData),
chunk("IEND", Buffer.alloc(0)),
])
}
function crc32(data: Buffer): number {
let crc = 0xffffffff
for (const byte of data) {
crc ^= byte
for (let j = 0; j < 8; j++) {
crc = crc & 1 ? (crc >>> 1) ^ 0xedb88320 : crc >>> 1
}
}
return (crc ^ 0xffffffff) >>> 0
}
// --- Preflight ---
describe("capture-evidence.py", () => {
describe("preflight", () => {
test("returns JSON with tool availability", async () => {
const { exitCode, stdout } = await run("preflight")
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result).toHaveProperty("agent_browser")
expect(result).toHaveProperty("vhs")
expect(result).toHaveProperty("silicon")
expect(result).toHaveProperty("ffmpeg")
expect(result).toHaveProperty("ffprobe")
expect(typeof result.ffmpeg).toBe("boolean")
})
})
// --- Detect ---
describe("detect", () => {
let tmpDir: string
beforeAll(async () => {
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "evidence-detect-"))
})
afterAll(async () => {
if (tmpDir) await fs.rm(tmpDir, { recursive: true, force: true })
})
test("detects web-app from package.json with react", async () => {
const dir = path.join(tmpDir, "webapp")
await fs.mkdir(dir)
await fs.writeFile(
path.join(dir, "package.json"),
JSON.stringify({ dependencies: { react: "^18.0.0" } }),
)
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("web-app")
})
test("detects cli-tool from package.json with bin field", async () => {
const dir = path.join(tmpDir, "clitool")
await fs.mkdir(dir)
await fs.writeFile(
path.join(dir, "package.json"),
JSON.stringify({ bin: { mycli: "./cli.js" } }),
)
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("cli-tool")
})
test("detects desktop-app from electron dependency", async () => {
const dir = path.join(tmpDir, "electron")
await fs.mkdir(dir)
await fs.writeFile(
path.join(dir, "package.json"),
JSON.stringify({ devDependencies: { electron: "^28.0.0", react: "^18.0.0" } }),
)
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("desktop-app")
})
test("detects library when manifest exists but no web/CLI signals", async () => {
const dir = path.join(tmpDir, "lib")
await fs.mkdir(dir)
await fs.writeFile(
path.join(dir, "package.json"),
JSON.stringify({ name: "my-utils", version: "1.0.0" }),
)
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("library")
})
test("detects text-only when no manifest exists", async () => {
const dir = path.join(tmpDir, "textonly")
await fs.mkdir(dir)
await fs.writeFile(path.join(dir, "README.md"), "# Hello")
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("text-only")
})
test("electron takes priority over web-app", async () => {
const dir = path.join(tmpDir, "electron-react")
await fs.mkdir(dir)
await fs.writeFile(
path.join(dir, "package.json"),
JSON.stringify({ dependencies: { react: "^18.0.0" }, devDependencies: { electron: "^28.0.0" } }),
)
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("desktop-app")
})
test("detects web-app from Gemfile with rails", async () => {
const dir = path.join(tmpDir, "rails")
await fs.mkdir(dir)
await fs.writeFile(path.join(dir, "Gemfile"), 'gem "rails", "~> 7.0"')
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("web-app")
})
test("detects cli-tool from go.mod with cmd/ directory", async () => {
const dir = path.join(tmpDir, "gocli")
await fs.mkdir(dir)
await fs.writeFile(path.join(dir, "go.mod"), "module example.com/mycli\n\ngo 1.21")
await fs.mkdir(path.join(dir, "cmd"))
const { exitCode, stdout } = await run("detect", "--repo-root", dir)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.type).toBe("cli-tool")
})
})
// --- Recommend ---
describe("recommend", () => {
const allTools = '{"agent_browser":true,"vhs":true,"silicon":true,"ffmpeg":true,"ffprobe":true}'
const noTools = '{"agent_browser":false,"vhs":false,"silicon":false,"ffmpeg":false,"ffprobe":false}'
test("web-app with browser + ffmpeg recommends browser-reel", async () => {
const { exitCode, stdout } = await run(
"recommend", "--project-type", "web-app", "--change-type", "states", "--tools", allTools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.recommended).toBe("browser-reel")
})
test("cli-tool with motion + vhs recommends terminal-recording", async () => {
const { exitCode, stdout } = await run(
"recommend", "--project-type", "cli-tool", "--change-type", "motion", "--tools", allTools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.recommended).toBe("terminal-recording")
})
test("cli-tool with states + silicon recommends screenshot-reel", async () => {
const tools = '{"agent_browser":false,"vhs":false,"silicon":true,"ffmpeg":true,"ffprobe":true}'
const { exitCode, stdout } = await run(
"recommend", "--project-type", "cli-tool", "--change-type", "states", "--tools", tools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.recommended).toBe("screenshot-reel")
})
test("library always recommends static-screenshots", async () => {
const { exitCode, stdout } = await run(
"recommend", "--project-type", "library", "--change-type", "states", "--tools", allTools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.recommended).toBe("static-screenshots")
})
test("no tools always falls back to static-screenshots", async () => {
const { exitCode, stdout } = await run(
"recommend", "--project-type", "cli-tool", "--change-type", "motion", "--tools", noTools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.recommended).toBe("static-screenshots")
})
test("available list includes only tiers with tools present", async () => {
const tools = '{"agent_browser":false,"vhs":true,"silicon":false,"ffmpeg":true,"ffprobe":true}'
const { exitCode, stdout } = await run(
"recommend", "--project-type", "cli-tool", "--change-type", "motion", "--tools", tools,
)
expect(exitCode).toBe(0)
const result = JSON.parse(stdout.trim())
expect(result.available).toContain("terminal-recording")
expect(result.available).toContain("static-screenshots")
expect(result.available).not.toContain("browser-reel")
expect(result.available).not.toContain("screenshot-reel")
})
})
// --- Stitch arg validation ---
describe("stitch arg validation", () => {
test("stitch with no args fails", async () => {
const { exitCode, stderr } = await run("stitch")
expect(exitCode).not.toBe(0)
})
test("stitch fails on missing frame file", async () => {
const { exitCode, stderr } = await run(
"stitch", "out.gif", "/tmp/nonexistent-frame-abc123.png",
)
expect(exitCode).toBe(1)
expect(stderr).toContain("Frame not found")
})
test("upload fails on missing file", async () => {
const { exitCode, stderr } = await run(
"upload", "/tmp/nonexistent-file-abc123.gif",
)
expect(exitCode).toBe(1)
expect(stderr).toContain("File not found")
})
})
// --- Stitch integration (requires ffmpeg) ---
describe("stitch integration", () => {
let tmpDir: string
let hasFFmpeg: boolean
beforeAll(async () => {
const proc = Bun.spawn(["which", "ffmpeg"], {
stdout: "pipe",
stderr: "pipe",
})
hasFFmpeg = (await proc.exited) === 0
if (!hasFFmpeg) return
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "evidence-test-"))
const red = createTestPng([255, 0, 0])
const green = createTestPng([0, 255, 0])
const blue = createTestPng([0, 0, 255])
await fs.writeFile(path.join(tmpDir, "frame1.png"), red)
await fs.writeFile(path.join(tmpDir, "frame2.png"), green)
await fs.writeFile(path.join(tmpDir, "frame3.png"), blue)
})
afterAll(async () => {
if (tmpDir) await fs.rm(tmpDir, { recursive: true, force: true })
})
test("stitches frames into a GIF", async () => {
if (!hasFFmpeg) {
console.log("Skipping: ffmpeg not available")
return
}
const output = path.join(tmpDir, "output.gif")
const { exitCode, stdout } = await run(
"stitch", "--duration", "0.5", output,
path.join(tmpDir, "frame1.png"),
path.join(tmpDir, "frame2.png"),
)
expect(exitCode).toBe(0)
expect(stdout).toContain("Stitching 2 frames")
expect(stdout).toContain("Created:")
const stat = await fs.stat(output)
expect(stat.size).toBeGreaterThan(0)
const header = Buffer.alloc(6)
const fh = await fs.open(output, "r")
await fh.read(header, 0, 6)
await fh.close()
expect(header.toString("ascii").startsWith("GIF")).toBe(true)
})
test("stitches 3 frames into a GIF", async () => {
if (!hasFFmpeg) {
console.log("Skipping: ffmpeg not available")
return
}
const output = path.join(tmpDir, "output3.gif")
const { exitCode, stdout } = await run(
"stitch", "--duration", "0.5", output,
path.join(tmpDir, "frame1.png"),
path.join(tmpDir, "frame2.png"),
path.join(tmpDir, "frame3.png"),
)
expect(exitCode).toBe(0)
expect(stdout).toContain("Stitching 3 frames")
})
test("default duration is used when --duration not specified", async () => {
if (!hasFFmpeg) {
console.log("Skipping: ffmpeg not available")
return
}
const output = path.join(tmpDir, "output-default-dur.gif")
const { exitCode, stdout } = await run(
"stitch", output,
path.join(tmpDir, "frame1.png"),
path.join(tmpDir, "frame2.png"),
)
expect(exitCode).toBe(0)
expect(stdout).toContain("Created:")
})
})
})