/** * @file Tests for scripts/artifact-export-hint.js: when Claude is asked to save * a viewable copy of a published Doc / typed artifact, and when it is not. * @author Nguyễn Ngọc Trí Vĩ */ const { describe, it } = require("node:test"); const assert = require("node:assert/strict"); const { spawnSync } = require("node:child_process"); const path = require("node:path"); const { hintFor } = require("../../scripts/artifact-export-hint"); const PANE = { AGENTHUB_LANE_ID: "3" }; const docBirth = { tool_name: "mcp__claude_ai_Claude_Docs__batch", tool_input: { container: { kind: "project", create: { name: "Plan" } } }, tool_response: [{ type: "text", text: '{"frame":{"url":"https://claude.ai/artifact/doc-9"}}' }], }; const slides = { tool_name: "Artifact", tool_input: { type_url: "https://claude.ai/types/slides", title: "Deck" }, tool_response: "Created https://claude.ai/artifact/deck-1", }; describe("artifact export hint", () => { it("asks for a Markdown copy of a new doc and a PDF/HTML copy of a typed artifact", () => { assert.match(hintFor(docBirth, PANE), /artifacts-export\/doc-9\.md/); const s = hintFor(slides, PANE); assert.match(s, /artifacts-export\/deck-1\.pdf/); assert.match(s, /artifacts-export\/deck-1\.html/); }); it("stays silent everywhere else", () => { assert.equal(hintFor(slides, {}), null, "not an AgentHub pane"); assert.equal(hintFor(slides, { ...PANE, AGENTHUB_ARTIFACT_EXPORT: "0" }), null, "turned off"); const html = { ...slides, tool_input: { file_path: "/w/page.html" } }; assert.equal(hintFor(html, PANE), null, "an HTML page is copied by AgentHub itself"); const edit = { ...docBirth, tool_input: { container: { kind: "project", id: "p1" }, batch: [] }, }; assert.equal(hintFor(edit, PANE), null, "a later batch edits the doc"); assert.equal(hintFor({ ...slides, tool_response: "no link" }, PANE), null); assert.equal(hintFor({ ...slides, tool_name: "ArtifactData" }, PANE), null); assert.equal(hintFor(null, PANE), null); }); it("prints Claude Code's PostToolUse context, and nothing on bad input", () => { const script = path.join(__dirname, "..", "..", "scripts", "artifact-export-hint.js"); const run = (input, env = PANE) => spawnSync(process.execPath, [script], { input, env: { PATH: process.env.PATH, ...env }, encoding: "utf8", timeout: 10_000, }); const ok = run(JSON.stringify(slides)); assert.equal(ok.status, 0); const out = JSON.parse(ok.stdout); assert.equal(out.hookSpecificOutput.hookEventName, "PostToolUse"); assert.match(out.hookSpecificOutput.additionalContext, /deck-1/); const bad = run("{not json"); assert.equal(bad.status, 0); assert.equal(bad.stdout, ""); }); });