diff --git a/extensions/render.ts b/extensions/render.ts index 879179f..3f0c786 100644 --- a/extensions/render.ts +++ b/extensions/render.ts @@ -1,5 +1,7 @@ // extensions/render.ts import { chromium } from "playwright-core" +import { Type } from "typebox" + import { pathToFileURL } from "node:url" import { writeFileSync, mkdirSync } from "node:fs" import { join } from "node:path" @@ -186,14 +188,15 @@ export default function (pi: any) { pi.registerTool({ name: "keystone_render", description: "Render an HTML file with headless Chromium at given viewports. Returns screenshots + computed styles + DOM snapshot for the Keystone gate engine.", - parameters: { - htmlPath: { type: "string", description: "Absolute path to the HTML file to render" }, - url: { type: "string", description: "Optional live URL to render instead of htmlPath (audit URL mode). If set, htmlPath is ignored." }, - viewports: { type: "array", items: { type: "number" }, description: "CSS pixel widths to screenshot", default: [1280, 375, 320, 414, 768] }, - outDir: { type: "string", description: "Directory to write outputs", default: "./keystone-render" }, - }, + parameters: Type.Object({ + htmlPath: Type.String({ description: "Absolute path to the HTML file to render" }), + url: Type.Optional(Type.String({ description: "Optional live URL to render instead of htmlPath (audit URL mode). If set, htmlPath is ignored." })), + viewports: Type.Optional(Type.Array(Type.Number({ description: "CSS pixel widths to screenshot" }))), + outDir: Type.Optional(Type.String({ description: "Directory to write outputs" })), + }), async execute(_toolCallId: string, input: RenderInput) { - return render(input) + const result = await render(input) + return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], details: result } }, }) } diff --git a/package.json b/package.json index 29c63ff..ee49040 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@getpipher/keystone", - "version": "1.0.1", + "version": "1.0.2", "description": "Anti-AI-slop design skill with an executable gate engine. Beats Hallmark by enforcing its gates instead of imagining them.", "keywords": [ "pi-package", @@ -52,7 +52,8 @@ }, "devDependencies": { "@types/node": "^24.13.3", - "playwright": "1.62.0" + "playwright": "1.62.0", + "typebox": "*" }, "packageManager": "pnpm@10.33.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 572260e..e23119f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,9 @@ importers: playwright: specifier: 1.62.0 version: 1.62.0 + typebox: + specifier: '*' + version: 1.3.28 packages: @@ -310,6 +313,9 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + typebox@1.3.28: + resolution: {integrity: sha512-5hTNlwzKj7BPPqhT91TPa4fK9bh/ZOei7mzweMpNidwLTxtduXHgr/OAbwx4mRW8aKFYu1I8fT1+0+PQtst1/g==} + uhyphen@0.2.0: resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} @@ -538,6 +544,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + typebox@1.3.28: {} + uhyphen@0.2.0: {} undici-types@7.18.2: {}