From 37efee482d5a2fe2437d6a5a6cd9aa57b990c036 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 19 Apr 2026 15:48:17 +0200 Subject: [PATCH] feat: AI skills indexes Signed-off-by: David Dal Busco --- .github/workflows/update-ai.yml | 39 ++++++++++++++ package.json | 1 + scripts/ai.mjs | 63 ++++++++++++++++++++++ static/.well-known/agent-skills/index.json | 12 +++++ 4 files changed, 115 insertions(+) create mode 100644 .github/workflows/update-ai.yml create mode 100755 scripts/ai.mjs create mode 100644 static/.well-known/agent-skills/index.json diff --git a/.github/workflows/update-ai.yml b/.github/workflows/update-ai.yml new file mode 100644 index 00000000..cd652396 --- /dev/null +++ b/.github/workflows/update-ai.yml @@ -0,0 +1,39 @@ +name: Update AI indexes + +on: + schedule: + - cron: "30 8 1 * *" + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-subnets: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Update + run: npm run docs:ai + + - name: Check for Changes + run: | + if ! git diff --quiet; then + echo "CHANGES_DETECTED=true" >> $GITHUB_ENV + fi + + # This action creates a PR only if there are changes. + - name: Create Pull Request + if: env.CHANGES_DETECTED == 'true' + uses: ./.github/actions/create-pr + with: + branch: bot-cli-docs-update + title: "docs: Update AI indexes" + body: | + Modifications have been made to the AI skills. diff --git a/package.json b/package.json index 7b7e26c9..811ede65 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dev": "npm run start", "start": "docusaurus start", "build": "docusaurus build", + "docs:ai": "./scripts/ai.mjs && npm run format", "docs:cli": "scripts/cli-to-md.sh", "docs:subnets": "./scripts/subnets.mjs && npm run format", "swizzle": "docusaurus swizzle", diff --git a/scripts/ai.mjs b/scripts/ai.mjs new file mode 100755 index 00000000..9c7c3149 --- /dev/null +++ b/scripts/ai.mjs @@ -0,0 +1,63 @@ +#!/usr/bin/env node + +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; + +// Generate /.well-known/agent-skills/index.json for AI discovery as defined by Cloudflare +// @see https://github.com/cloudflare/agent-skills-discovery-rfc +// @see https://isitagentready.com/.well-known/agent-skills/agent-skills/SKILL.md +// test: https://isitagentready.com/juno.build + +const TEMPLATE_SKILL_WITHOUT_DIGEST = { + name: "juno", + type: "skill-md", + description: + "Up-to-date knowledge about Juno's CLI, SDK, and serverless functions for AI coding agents.", + url: "https://raw.githubusercontent.com/junobuild/skills/main/SKILL.md" +}; + +const TEMPLATE = { + $schema: "https://schemas.agentskills.io/discovery/0.2.0/schema.json", + skills: [] +}; + +const OUTPUT_DIR = join("static", ".well-known", "agent-skills"); +const OUTPUT_FILE_PATH = join(OUTPUT_DIR, "index.json"); + +await mkdir(OUTPUT_DIR, { recursive: true }); + +const computeSkillSha256 = async () => { + const response = await fetch( + "https://raw.githubusercontent.com/junobuild/skills/main/SKILL.md" + ); + + if (!response.ok) { + throw new Error("Fetching the current SKILL.md failed!"); + } + + const md = await response.text(); + + const encoder = new TextEncoder(); + const hash = await crypto.subtle.digest("SHA-256", encoder.encode(md)); + + const sha256ToHex = (hashBuffer) => { + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); + }; + + return sha256ToHex(hash); +}; + +const sha256 = await computeSkillSha256(); + +const skill = { + ...TEMPLATE_SKILL_WITHOUT_DIGEST, + digest: `sha256:${sha256}` +}; + +const json = { + ...TEMPLATE, + skills: [skill] +}; + +await writeFile(OUTPUT_FILE_PATH, JSON.stringify(json, null, 2), "utf8"); diff --git a/static/.well-known/agent-skills/index.json b/static/.well-known/agent-skills/index.json new file mode 100644 index 00000000..be0fdfa8 --- /dev/null +++ b/static/.well-known/agent-skills/index.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json", + "skills": [ + { + "name": "juno", + "type": "skill-md", + "description": "Up-to-date knowledge about Juno's CLI, SDK, and serverless functions for AI coding agents.", + "url": "https://raw.githubusercontent.com/junobuild/skills/main/SKILL.md", + "digest": "sha256:18b7fec3e46664b67bdf5bd66f4f36fd9fca138a8749ddc2638f61fed4c23483" + } + ] +}