From 083802201d3d9d8fbbccadcba5ce7567482e856c Mon Sep 17 00:00:00 2001 From: "melodic-automation-lanes[bot]" <337595936+melodic-automation-lanes[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2026 06:32:01 +0000 Subject: [PATCH 1/2] refactor(visualization): route check-deck's K2 refusal through its local-result helper --- ...idy-adhoc-plugins-visualization-2026-11-03-fa6c9917.md | 7 +++++++ .../visualization/skills/present/scripts/check-deck.mjs | 8 +++----- 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changes/visualization/chore-tidy-adhoc-plugins-visualization-2026-11-03-fa6c9917.md diff --git a/.changes/visualization/chore-tidy-adhoc-plugins-visualization-2026-11-03-fa6c9917.md b/.changes/visualization/chore-tidy-adhoc-plugins-visualization-2026-11-03-fa6c9917.md new file mode 100644 index 00000000000..b245f184469 --- /dev/null +++ b/.changes/visualization/chore-tidy-adhoc-plugins-visualization-2026-11-03-fa6c9917.md @@ -0,0 +1,7 @@ +--- +bump: patch +--- + +### Changed + +- Tidied check-deck.mjs: the K2 refusal reuses the local-result helper, and the header usage lists the hosted argument the parser already accepts. diff --git a/plugins/visualization/skills/present/scripts/check-deck.mjs b/plugins/visualization/skills/present/scripts/check-deck.mjs index 66883c53f4f..f60f5305531 100755 --- a/plugins/visualization/skills/present/scripts/check-deck.mjs +++ b/plugins/visualization/skills/present/scripts/check-deck.mjs @@ -8,7 +8,7 @@ // send. Prints one JSON object. // // check-deck.mjs --class K0|K1|K2 -// [--argument terminal|file|artifact] [--option ] +// [--argument terminal|file|artifact|hosted] [--option ] // Exit 0 decided (read `medium`), 1 a deck refused, 2 usage or an unreadable root. import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs"; @@ -184,7 +184,7 @@ function workTree(dir) { * @param {{root: string, visibility: string, cls: string, layers?: {argument?: string|null, option?: string|null, home?: string, project?: string|null}}} input */ export function checkDeck({ root, visibility, cls, layers = {} }) { - const local = (exit, reason) => ({ exit, result: { medium: "file", class: cls, reason } }); + const local = (exit, reason, extra = {}) => ({ exit, result: { medium: "file", class: cls, reason, ...extra } }); const resolved = resolve(root); if (lstatSync(resolved).isSymbolicLink() || realpathSync(resolved) !== resolved) { return local(2, `the deck root ${resolved} is or passes through a symlink; pass its real path`); @@ -210,9 +210,7 @@ export function checkDeck({ root, visibility, cls, layers = {} }) { if (badTitle) return local(1, badTitle); if (cls === "K2") { const refused = k2Refusals(files); - if (refused.length) { - return { exit: 1, result: { medium: "file", class: cls, reason: "a K2 deck carries more than text in the slide format", refused } }; - } + if (refused.length) return local(1, "a K2 deck carries more than text in the slide format", { refused }); } const { medium: chosen, source, warnings } = trustedMedium(layers); const extra = warnings.length ? { warnings } : {}; From d9ff164f23bf6ab6af686e030c8572ee1e7484fd Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Tue, 3 Nov 2026 04:49:08 -0500 Subject: [PATCH 2/2] refactor(visualization): pass check-deck's K2 refusal list to local() by name local() took an open extra object spread after the fixed keys, so a caller could overwrite medium or class. It now takes the refusal list as its one optional argument. A test pins the K2 refusal's key order and checks other refusals carry no refused key. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Vcupom3BKF6QuC5U3sRJPj --- .../visualization/skills/present/scripts/check-deck.mjs | 4 ++-- plugins/visualization/tests/present.test.mjs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/visualization/skills/present/scripts/check-deck.mjs b/plugins/visualization/skills/present/scripts/check-deck.mjs index 2bb550be00b..caaff2f6b2d 100755 --- a/plugins/visualization/skills/present/scripts/check-deck.mjs +++ b/plugins/visualization/skills/present/scripts/check-deck.mjs @@ -186,7 +186,7 @@ function workTree(dir) { * @param {{root: string, visibility: string, cls: string, layers?: {argument?: string|null, option?: string|null, home?: string, project?: string|null, dataDir?: string|null}}} input */ export function checkDeck({ root, visibility, cls, layers = {} }) { - const local = (exit, reason, extra = {}) => ({ exit, result: { medium: "file", class: cls, reason, ...extra } }); + const local = (exit, reason, refused) => ({ exit, result: { medium: "file", class: cls, reason, ...(refused && { refused }) } }); const resolved = resolve(root); if (lstatSync(resolved).isSymbolicLink() || realpathSync(resolved) !== resolved) { return local(2, `the deck root ${resolved} is or passes through a symlink; pass its real path`); @@ -212,7 +212,7 @@ export function checkDeck({ root, visibility, cls, layers = {} }) { if (badTitle) return local(1, badTitle); if (cls === "K2") { const refused = k2Refusals(files); - if (refused.length) return local(1, "a K2 deck carries more than text in the slide format", { refused }); + if (refused.length) return local(1, "a K2 deck carries more than text in the slide format", refused); } const { argument = null, option = null, home, project = findRoot(), dataDir = process.env.CLAUDE_PLUGIN_DATA || null } = layers; const resolution = resolveMedium({ lane: "visualization:present", argument, userConfig: option, projectRoot: project }, { ...(home ? { userHome: home } : {}), dataDir }); diff --git a/plugins/visualization/tests/present.test.mjs b/plugins/visualization/tests/present.test.mjs index bf79b3d7146..bf3a1a51956 100644 --- a/plugins/visualization/tests/present.test.mjs +++ b/plugins/visualization/tests/present.test.mjs @@ -138,6 +138,13 @@ describe("check-deck", () => { assert.deepEqual(result.refused, [{ file: "project/slides/s1.html", carries }]); }); } + test("a K2 refusal prints medium, class, reason and refused in that order; other refusals carry no refused key", () => { + const k2 = checkDeck({ root: deck({ s1: slide("s1", hostile[0][1]) }), visibility: "PUBLIC", cls: "K2" }); + assert.deepEqual(Object.keys(k2.result), ["medium", "class", "reason", "refused"]); + assert.equal(k2.result.class, "K2"); + const untitled = checkDeck({ root: deck(plain, { v: 4, order: ["cover"] }), visibility: "PUBLIC", cls: "K2" }); + assert.deepEqual(Object.keys(untitled.result), ["medium", "class", "reason"]); + }); test("a K2 deck of escaped text and uploaded images passes; text that reads like markup does not trip it", () => { const body = [ "

Fix <script> onload = 1 url(x) href=x & > done

",