From 561fb166ff25a25dcd2ca5b957d44dc8e1963580 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Wed, 4 Nov 2026 23:39:57 +0100 Subject: [PATCH 1/4] feat(ksail): add the plugin directory icon The Claude plugin directory check reported "No icon" for the ksail plugin. Add the KSail app icon (1024x1024 PNG from devantler-tech/ksail desktop/resources/icon.png) at .claude-plugin/icon.png, the path the directory reads by convention, so no manifest field is needed and the portable and strict manifests stay identical. Bump ksail to 1.0.1. Co-Authored-By: Claude Opus 5.5 --- .claude-plugin/marketplace.json | 2 +- .github/plugin/marketplace.json | 2 +- plugins/ksail/.claude-plugin/icon.png | Bin 0 -> 49695 bytes plugins/ksail/.claude-plugin/plugin.json | 2 +- plugins/ksail/CHANGELOG.md | 7 +++++++ plugins/ksail/plugin.json | 2 +- 6 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 plugins/ksail/.claude-plugin/icon.png create mode 100644 plugins/ksail/CHANGELOG.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 41771c07..85da96a0 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -32,7 +32,7 @@ { "name": "ksail", "description": "KSail CLI expertise and MCP server — create and operate Kubernetes clusters (Kind, K3d, Talos, vCluster, KWOK, EKS) and GitOps workloads declaratively", - "version": "1.0.0", + "version": "1.0.1", "source": "./plugins/ksail" } ] diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 41771c07..85da96a0 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -32,7 +32,7 @@ { "name": "ksail", "description": "KSail CLI expertise and MCP server — create and operate Kubernetes clusters (Kind, K3d, Talos, vCluster, KWOK, EKS) and GitOps workloads declaratively", - "version": "1.0.0", + "version": "1.0.1", "source": "./plugins/ksail" } ] diff --git a/plugins/ksail/.claude-plugin/icon.png b/plugins/ksail/.claude-plugin/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b33408821dda9808e26cc60ae76a65437ccf40fa GIT binary patch literal 49695 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�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 z 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 literal 0 HcmV?d00001 diff --git a/plugins/ksail/.claude-plugin/plugin.json b/plugins/ksail/.claude-plugin/plugin.json index 1850145a..9abf838d 100644 --- a/plugins/ksail/.claude-plugin/plugin.json +++ b/plugins/ksail/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "ksail", "description": "KSail CLI expertise and MCP server — create and operate Kubernetes clusters (Kind, K3d, Talos, vCluster, KWOK, EKS) and GitOps workloads declaratively", - "version": "1.0.0", + "version": "1.0.1", "author": { "name": "devantler-tech", "url": "https://github.com/devantler-tech" diff --git a/plugins/ksail/CHANGELOG.md b/plugins/ksail/CHANGELOG.md new file mode 100644 index 00000000..57d8da70 --- /dev/null +++ b/plugins/ksail/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog — `ksail` + +## 1.0.1 — 2026-11-04 + +- Add the KSail app icon at `.claude-plugin/icon.png` (1024 × 1024 PNG, copied from + `desktop/resources/icon.png` in `devantler-tech/ksail`), so the Claude plugin directory can show + it as the listing icon. diff --git a/plugins/ksail/plugin.json b/plugins/ksail/plugin.json index 1850145a..9abf838d 100644 --- a/plugins/ksail/plugin.json +++ b/plugins/ksail/plugin.json @@ -1,7 +1,7 @@ { "name": "ksail", "description": "KSail CLI expertise and MCP server — create and operate Kubernetes clusters (Kind, K3d, Talos, vCluster, KWOK, EKS) and GitOps workloads declaratively", - "version": "1.0.0", + "version": "1.0.1", "author": { "name": "devantler-tech", "url": "https://github.com/devantler-tech" From 7642deb15bb2a47892d0628c5d031cb127500b17 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Wed, 4 Nov 2026 23:50:39 +0100 Subject: [PATCH 2/4] feat(ksail): add a Codex manifest with the plugin directory listing The OpenAI plugin directory reads its listing from .codex-plugin/plugin.json: display name, short and long descriptions, category, links, example prompts, brand colours, logo and composer icon. Add one for ksail that repeats the portable manifest (validate-manifests.sh enforces parity), loads the skill and the ksail MCP server, and points both icons at the existing .claude-plugin/icon.png. Co-Authored-By: Claude Opus 5.5 --- docs/installation.md | 3 +- plugins/ksail/.codex-plugin/plugin.json | 51 +++++++++++++++++++++++++ plugins/ksail/CHANGELOG.md | 4 ++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 plugins/ksail/.codex-plugin/plugin.json diff --git a/docs/installation.md b/docs/installation.md index 504667f4..1ea6bb90 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -54,7 +54,8 @@ Codex reads a plugin's `.codex-plugin/plugin.json` before its `.claude-plugin/pl `agentic-engineering` plugin ships one so that it can also offer the official Codex apps its agents use: iCloud Mail, iCloud Calendar, LinkedIn and Codex Security Cloud, all optional, listed in its [`.app.json`](../plugins/agentic-engineering/.app.json). Each still needs your own sign-in. -`scripts/validate-manifests.sh` keeps that manifest identical to the portable one apart from its +The `ksail` plugin ships one for its OpenAI plugin directory listing; it offers no apps. +`scripts/validate-manifests.sh` keeps each Codex manifest identical to the portable one apart from its component paths, app list and listing, and `scripts/bump-plugin-version.sh` moves its version with the others. diff --git a/plugins/ksail/.codex-plugin/plugin.json b/plugins/ksail/.codex-plugin/plugin.json new file mode 100644 index 00000000..caff0cdc --- /dev/null +++ b/plugins/ksail/.codex-plugin/plugin.json @@ -0,0 +1,51 @@ +{ + "name": "ksail", + "description": "KSail CLI expertise and MCP server — create and operate Kubernetes clusters (Kind, K3d, Talos, vCluster, KWOK, EKS) and GitOps workloads declaratively", + "version": "1.0.1", + "author": { + "name": "devantler-tech", + "url": "https://github.com/devantler-tech" + }, + "license": "PolyForm-Shield-1.0.0", + "homepage": "https://ksail.devantler.tech", + "repository": "https://github.com/devantler-tech/ksail", + "keywords": [ + "kubernetes", + "k8s", + "gitops", + "ksail", + "kind", + "k3d", + "talos", + "vcluster", + "eks", + "flux", + "argocd", + "mcp" + ], + "skills": "./skills/", + "mcpServers": "./.mcp.json", + "interface": { + "displayName": "KSail", + "shortDescription": "Create Kubernetes clusters", + "longDescription": "KSail is one CLI for creating and operating Kubernetes clusters and the GitOps workloads on them. This plugin teaches Codex to use it: scaffold a KSail project, create Kind, K3d, Talos, vCluster or KWOK clusters locally in Docker (Talos also on Hetzner and Omni), bootstrap Flux or ArgoCD, apply, validate and watch workloads, manage SOPS-encrypted secrets, and back up or restore cluster resources. It needs the ksail CLI on your PATH and, for local clusters, a running Docker daemon.", + "developerName": "Devantler Tech", + "category": "Developer Tools", + "capabilities": [ + "Interactive", + "Read", + "Write" + ], + "websiteURL": "https://ksail.devantler.tech/", + "supportURL": "https://github.com/devantler-tech/ksail/issues", + "defaultPrompt": [ + "Create a local Kubernetes cluster with KSail and Flux, then deploy the manifests in k8s/", + "Scaffold a KSail project for a Talos cluster and explain each file it writes", + "Encrypt the Kubernetes secrets in this repository with SOPS using ksail workload cipher" + ], + "brandColor": "#143150", + "brandColorDark": "#2EC4E6", + "composerIcon": "./.claude-plugin/icon.png", + "logo": "./.claude-plugin/icon.png" + } +} diff --git a/plugins/ksail/CHANGELOG.md b/plugins/ksail/CHANGELOG.md index 57d8da70..10795e63 100644 --- a/plugins/ksail/CHANGELOG.md +++ b/plugins/ksail/CHANGELOG.md @@ -5,3 +5,7 @@ - Add the KSail app icon at `.claude-plugin/icon.png` (1024 × 1024 PNG, copied from `desktop/resources/icon.png` in `devantler-tech/ksail`), so the Claude plugin directory can show it as the listing icon. +- Add a Codex manifest at `.codex-plugin/plugin.json`. It repeats the portable manifest, loads the + skill and the `ksail` MCP server, and gives the OpenAI plugin directory its listing: name, short + and long descriptions, the Developer Tools category, website and support links, three example + prompts, brand colours and the same icon. From 4acfad9c939d050e3776ee755c5e64887adc1351 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Thu, 5 Nov 2026 00:07:51 +0100 Subject: [PATCH 3/4] fix(guard): skip signature-checked raster images in the gh JSON field guard The ksail plugin's listing icon (.claude-plugin/icon.png) is the first image packaged under plugins/, and the guard reported UNKNOWN for it because every file type it does not scan fails closed. That is the intended design: extend the list rather than skip a new kind of file. A raster image is pixels, not prose an agent reads, so it cannot prescribe a gh field. But its name proves nothing, so .png, .jpg, .jpeg and .webp files are skipped only when they are regular, unlinked files whose leading bytes match their format's signature. Text named icon.png, an empty file, a mismatched signature or a symlink stays UNKNOWN. Tests cover each case. Co-Authored-By: Claude Opus 5.5 --- scripts/guard-gh-json-fields.sh | 22 +++++++++++++++++++++- scripts/guard-gh-json-fields.test.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/scripts/guard-gh-json-fields.sh b/scripts/guard-gh-json-fields.sh index a41b2fc1..71f69f39 100755 --- a/scripts/guard-gh-json-fields.sh +++ b/scripts/guard-gh-json-fields.sh @@ -14,7 +14,8 @@ # Usage: guard-gh-json-fields.sh [ROOT] (ROOT defaults to this repository) # Scans every *.md, *.txt, *.json, *.jq, *.go, *.yaml and *.yml under ROOT/plugins; any other non-script file is UNKNOWN. Shell # scripts are not scanned: a script with a bad field fails loudly the first time it runs, whereas prose -# silently misleads every agent that reads it. +# silently misleads every agent that reads it. Raster images (*.png, *.jpg, *.jpeg, *.webp — listing +# icons) are skipped only when they are regular files that begin with that format's signature. # Go 1.22+ is required: only the installed observer is built. Literal adjacent shell quotes are # joined without evaluating inspected text; expansions are UNKNOWN. JSON requires unique decoded # keys. Normalized text is bounded to 8 MiB. The Go decoder reads comments, decoded literal @@ -58,6 +59,22 @@ ensure_decoder() { fi } +# A raster image is pixels, not prose an agent reads, so it cannot prescribe a `gh` field. Its name +# alone proves nothing: a text file called icon.png would hide its prescriptions from this guard. So +# an image is skipped only when it is a regular, unlinked file whose leading bytes are the signature +# of the format its extension names. Anything else — including an unreadable file — is not an image. +raster_image() { + local path="$1" magic + [ -f "${path}" ] && [ ! -L "${path}" ] || return 1 + magic="$(LC_ALL=C od -An -N12 -tx1 "${path}" | tr -d ' \n')" || return 1 + case "${path}" in + *.png) [ "${magic:0:16}" = 89504e470d0a1a0a ] ;; + *.jpg | *.jpeg) [ "${magic:0:6}" = ffd8ff ] ;; + *.webp) [ "${magic:0:8}" = 52494646 ] && [ "${magic:16:8}" = 57454250 ] ;; + *) return 1 ;; + esac +} + # Emit the retained surface as plain text. $1 selects its type; $2 contains its observed bytes. # JSON is DECODED, never pattern-matched: a \u escape of a letter IS # that letter, so an escaped `merged` is still `merged`. Each decoded string is followed by `%`, which ends a field @@ -198,6 +215,9 @@ while IFS= read -r -d '' f; do case "$f" in *.md|*.txt|*.json|*.jq|*.go|*.yaml|*.yml) surfaces+=("$f") ;; *.sh) ;; + *.png | *.jpg | *.jpeg | *.webp) + raster_image "$f" || + unknown "${f#"${root}/"} is named as an image but is not a regular file with that image format's signature, so it may be text this guard does not scan" ;; *) unknown "${f#"${root}/"} is a file type this guard does not scan, so any field it prescribes would go unseen" ;; esac done < "${discovered}" diff --git a/scripts/guard-gh-json-fields.test.sh b/scripts/guard-gh-json-fields.test.sh index 2d2ff644..b18f646d 100755 --- a/scripts/guard-gh-json-fields.test.sh +++ b/scripts/guard-gh-json-fields.test.sh @@ -367,6 +367,33 @@ dir="$(fixture unknown-unscanned-type)" printf '%s\n' 'cmd: gh pr view 42 --json state,merged' > "${dir}/plugins/p/agents/case.ini" expect 2 "an unscanned file type is UNKNOWN" "${dir}" +# Listing icons are raster images: skipped only when their bytes carry that format's signature. +dir="$(fixture good-png-icon)" +mkdir -p "${dir}/plugins/p/.claude-plugin" +printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/plugins/p/.claude-plugin/icon.png" +expect 0 "a PNG with the PNG signature is skipped" "${dir}" +dir="$(fixture good-jpeg-icon)" +printf '\xff\xd8\xff\xe0\0\x10JFIF' > "${dir}/plugins/p/agents/logo.jpg" +printf '\xff\xd8\xff\xe0\0\x10JFIF' > "${dir}/plugins/p/agents/logo.jpeg" +expect 0 "a JPEG with the JPEG signature is skipped" "${dir}" +dir="$(fixture good-webp-icon)" +printf 'RIFF\x24\0\0\0WEBPVP8 ' > "${dir}/plugins/p/agents/logo.webp" +expect 0 "a WebP with the RIFF/WEBP signature is skipped" "${dir}" +# A name proves nothing: text called icon.png would carry prescriptions past the scan. +dir="$(fixture unknown-text-named-png)" +printf '%s\n' 'gh pr view 42 --json state,merged' > "${dir}/plugins/p/agents/icon.png" +expect 2 "text named .png is UNKNOWN, never skipped" "${dir}" +dir="$(fixture unknown-wrong-signature)" +printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/plugins/p/agents/icon.webp" +expect 2 "an image whose signature does not match its extension is UNKNOWN" "${dir}" +dir="$(fixture unknown-empty-png)" +: > "${dir}/plugins/p/agents/icon.png" +expect 2 "an empty .png is UNKNOWN" "${dir}" +dir="$(fixture unknown-symlinked-png)" +printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/real.png" +ln -s "${dir}/real.png" "${dir}/plugins/p/agents/icon.png" +expect 2 "a symlinked .png is UNKNOWN even when its target is an image" "${dir}" + # Native skill runtime metadata is YAML. Decode supported mappings rather than treating # their quotes as shell syntax or permitting escaped prescriptions to go unseen. for extension in yaml yml; do From fbcb5aad572adfd8bc2ca5505683037973ad1257 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Thu, 5 Nov 2026 00:59:34 +0100 Subject: [PATCH 4/4] fix(guard): state exactly what the image skip checks, and test its failure paths Local review round nits: - The comment claimed more than the check does. Only the leading signature is read; text after it, or in a PNG text chunk, is not inspected, because agents open image files as images. Say so, and say that the skip applies to images anywhere under plugins/. - Cover the untested fail-closed paths: a FIFO named .png, an uppercase .PNG, and an unreadable .png (skipped when running as root, which reads it anyway). Co-Authored-By: Claude Opus 5.5 --- scripts/guard-gh-json-fields.sh | 15 +++++++++------ scripts/guard-gh-json-fields.test.sh | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/scripts/guard-gh-json-fields.sh b/scripts/guard-gh-json-fields.sh index 71f69f39..cc861f3c 100755 --- a/scripts/guard-gh-json-fields.sh +++ b/scripts/guard-gh-json-fields.sh @@ -14,8 +14,9 @@ # Usage: guard-gh-json-fields.sh [ROOT] (ROOT defaults to this repository) # Scans every *.md, *.txt, *.json, *.jq, *.go, *.yaml and *.yml under ROOT/plugins; any other non-script file is UNKNOWN. Shell # scripts are not scanned: a script with a bad field fails loudly the first time it runs, whereas prose -# silently misleads every agent that reads it. Raster images (*.png, *.jpg, *.jpeg, *.webp — listing -# icons) are skipped only when they are regular files that begin with that format's signature. +# silently misleads every agent that reads it. Raster images (*.png, *.jpg, *.jpeg, *.webp, such as +# listing icons, anywhere under plugins/) are skipped only when they are regular files that begin with +# that format's signature; the bytes after the signature are not inspected. # Go 1.22+ is required: only the installed observer is built. Literal adjacent shell quotes are # joined without evaluating inspected text; expansions are UNKNOWN. JSON requires unique decoded # keys. Normalized text is bounded to 8 MiB. The Go decoder reads comments, decoded literal @@ -59,10 +60,12 @@ ensure_decoder() { fi } -# A raster image is pixels, not prose an agent reads, so it cannot prescribe a `gh` field. Its name -# alone proves nothing: a text file called icon.png would hide its prescriptions from this guard. So -# an image is skipped only when it is a regular, unlinked file whose leading bytes are the signature -# of the format its extension names. Anything else — including an unreadable file — is not an image. +# An agent opens a raster image as pixels, not as prose to follow, so it is not a surface this guard +# scans. Its name alone proves nothing: a plain text file called icon.png would hide its prescriptions. +# So an image is skipped only when it is a regular, unlinked file whose leading bytes are the +# signature of the format its extension names; anything else, including an unreadable file, is +# UNKNOWN. Only the signature is checked: text placed after it, or in a PNG text chunk, is not +# inspected, because no agent reads an image file as instructions. raster_image() { local path="$1" magic [ -f "${path}" ] && [ ! -L "${path}" ] || return 1 diff --git a/scripts/guard-gh-json-fields.test.sh b/scripts/guard-gh-json-fields.test.sh index b18f646d..9e29dcb4 100755 --- a/scripts/guard-gh-json-fields.test.sh +++ b/scripts/guard-gh-json-fields.test.sh @@ -393,6 +393,21 @@ dir="$(fixture unknown-symlinked-png)" printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/real.png" ln -s "${dir}/real.png" "${dir}/plugins/p/agents/icon.png" expect 2 "a symlinked .png is UNKNOWN even when its target is an image" "${dir}" +dir="$(fixture unknown-fifo-png)" +mkfifo "${dir}/plugins/p/agents/icon.png" +expect 2 "a .png that is not a regular file (a FIFO) is UNKNOWN" "${dir}" +dir="$(fixture unknown-uppercase-png)" +printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/plugins/p/agents/icon.PNG" +expect 2 "an uppercase .PNG is not a recognised image extension and is UNKNOWN" "${dir}" +# An unreadable image cannot have its signature read, so it is UNKNOWN. Root reads it regardless of +# its mode, so the case only proves something when the file really is unreadable. +dir="$(fixture unknown-unreadable-png)" +printf '\x89PNG\r\n\x1a\n\0\0\0\rIHDR' > "${dir}/plugins/p/agents/icon.png" +chmod 000 "${dir}/plugins/p/agents/icon.png" +if [ ! -r "${dir}/plugins/p/agents/icon.png" ]; then + expect 2 "an unreadable .png is UNKNOWN" "${dir}" +fi +chmod 600 "${dir}/plugins/p/agents/icon.png" # Native skill runtime metadata is YAML. Decode supported mappings rather than treating # their quotes as shell syntax or permitting escaped prescriptions to go unseen.