From 2054694f43b997b81400564806092f3a16f68234 Mon Sep 17 00:00:00 2001 From: gregorydemay Date: Tue, 17 Mar 2026 15:09:19 +0100 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20add=20canhelp=20skill=20=E2=80=94?= =?UTF-8?q?=20display=20canister=20interface=20summaries=20from=20ID=20or?= =?UTF-8?q?=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- skills/canhelp/SKILL.md | 48 +++++++++++++++++++ skills/canhelp/scripts/fetch-candid.sh | 13 +++++ skills/canhelp/scripts/resolve-canister-id.sh | 27 +++++++++++ 3 files changed, 88 insertions(+) create mode 100644 skills/canhelp/SKILL.md create mode 100755 skills/canhelp/scripts/fetch-candid.sh create mode 100755 skills/canhelp/scripts/resolve-canister-id.sh diff --git a/skills/canhelp/SKILL.md b/skills/canhelp/SKILL.md new file mode 100644 index 0000000..0e158ee --- /dev/null +++ b/skills/canhelp/SKILL.md @@ -0,0 +1,48 @@ +--- +name: canhelp +description: Display a human-readable summary of a canister's interface given its mainnet canister ID or name. Like --help but for canisters. +allowed-tools: Bash(./scripts/resolve-canister-id.sh *), Bash(./scripts/fetch-candid.sh *), Read, Grep, Glob +argument-hint: +--- + +Given a canister ID or name in `$ARGUMENTS`, fetch and summarize its Candid interface. + +## Steps + +1. Resolve the canister ID by running the resolve script from the skill's base directory: + ``` + ./scripts/resolve-canister-id.sh $ARGUMENTS + ``` + If `$ARGUMENTS` is already a valid principal, the script echoes it back. + Otherwise, it queries the IC Dashboard API and outputs matches as ` ` (one per line). + - If there is a single result, use it directly. + - If there are multiple results, present the list to the user and ask them to pick one before continuing. + +2. Fetch the Candid interface using the resolved canister ID: + ``` + ./scripts/fetch-candid.sh + ``` + The script outputs the path to the downloaded `.did` file. + +3. Read the file using the `Read` tool. + +4. Present the output as a readable summary with the following structure: + + **Canister ``** + + **Query methods:** + - `method_name(arg1: type1, arg2: type2) → return_type` — one-line description if inferable from the name + + **Update methods:** + - `method_name(arg1: type1) → return_type` + + **Types:** + - List any custom record/variant types defined in the interface, with their fields + +## Guidelines + +- Group methods by query vs update +- Sort methods alphabetically within each group +- For complex nested types, show the top-level structure and note nesting +- If the candid is very large (>100 methods), show a summary count and list only the most important-looking methods, offering to show the full list on request +- If the fetch fails, suggest the user verify the canister ID and that `icp` is installed \ No newline at end of file diff --git a/skills/canhelp/scripts/fetch-candid.sh b/skills/canhelp/scripts/fetch-candid.sh new file mode 100755 index 0000000..d494f49 --- /dev/null +++ b/skills/canhelp/scripts/fetch-candid.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail + +if ! command -v icp &>/dev/null; then + echo "Error: 'icp' CLI not found. Install it from https://dfinity.github.io/icp-cli" >&2 + exit 1 +fi + +CANISTER_ID="${1:?Usage: fetch-candid.sh }" +OUT="/tmp/candid_${CANISTER_ID}.did" + +icp canister metadata "$CANISTER_ID" candid:service --network ic > "$OUT" +echo "$OUT" \ No newline at end of file diff --git a/skills/canhelp/scripts/resolve-canister-id.sh b/skills/canhelp/scripts/resolve-canister-id.sh new file mode 100755 index 0000000..2661f73 --- /dev/null +++ b/skills/canhelp/scripts/resolve-canister-id.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -euo pipefail + +INPUT="${1:?Usage: resolve-canister-id.sh }" + +# Principal: Base32(CRC32 · blob) grouped into 5-char chunks separated by dashes. +# Each group is exactly 5 lowercase alphanumeric chars, except the last which is 1-5. +# Max 63 chars (29-byte blob → 53 base32 chars + 10 dashes). Must have at least 2 groups. +if [[ "$INPUT" =~ ^[a-z2-7]{5}(-[a-z2-7]{5})*(-[a-z2-7]{1,5})$ ]]; then + echo "$INPUT" + exit 0 +fi + +# Otherwise, query IC Dashboard API for name-based lookup +QUERY=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "$INPUT") +RESPONSE=$(curl -sf "https://ic-api.internetcomputer.org/api/v4/canisters?format=json&has_name=true&query=${QUERY}&limit=50") + +python3 -c " +import sys, json +data = json.load(sys.stdin) +entries = data.get('data', []) +if not entries: + print('Error: no canister found matching \"$INPUT\"', file=sys.stderr) + sys.exit(1) +for e in entries: + print(f\"{e['canister_id']} {e.get('name', 'N/A')}\") +" <<< "$RESPONSE" From 8b8ac6e9825e8def56c4f456fcab658d1604b9be Mon Sep 17 00:00:00 2001 From: gregorydemay Date: Tue, 17 Mar 2026 15:25:19 +0100 Subject: [PATCH 2/2] feat: refine --- skills/canhelp/SKILL.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/skills/canhelp/SKILL.md b/skills/canhelp/SKILL.md index 0e158ee..a8a3f72 100644 --- a/skills/canhelp/SKILL.md +++ b/skills/canhelp/SKILL.md @@ -3,6 +3,9 @@ name: canhelp description: Display a human-readable summary of a canister's interface given its mainnet canister ID or name. Like --help but for canisters. allowed-tools: Bash(./scripts/resolve-canister-id.sh *), Bash(./scripts/fetch-candid.sh *), Read, Grep, Glob argument-hint: +metadata: + title: Canister Help + category: Infrastructure --- Given a canister ID or name in `$ARGUMENTS`, fetch and summarize its Candid interface. @@ -10,7 +13,7 @@ Given a canister ID or name in `$ARGUMENTS`, fetch and summarize its Candid inte ## Steps 1. Resolve the canister ID by running the resolve script from the skill's base directory: - ``` + ```bash ./scripts/resolve-canister-id.sh $ARGUMENTS ``` If `$ARGUMENTS` is already a valid principal, the script echoes it back. @@ -19,7 +22,7 @@ Given a canister ID or name in `$ARGUMENTS`, fetch and summarize its Candid inte - If there are multiple results, present the list to the user and ask them to pick one before continuing. 2. Fetch the Candid interface using the resolved canister ID: - ``` + ```bash ./scripts/fetch-candid.sh ``` The script outputs the path to the downloaded `.did` file. @@ -45,4 +48,4 @@ Given a canister ID or name in `$ARGUMENTS`, fetch and summarize its Candid inte - Sort methods alphabetically within each group - For complex nested types, show the top-level structure and note nesting - If the candid is very large (>100 methods), show a summary count and list only the most important-looking methods, offering to show the full list on request -- If the fetch fails, suggest the user verify the canister ID and that `icp` is installed \ No newline at end of file +- If the fetch fails, suggest the user verify the canister ID and that `icp` is installed