diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 568ecc0..53fb9ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,8 @@ jobs: - name: Run local eval harness run: node eval/harness/run.mjs - - name: Build skillpacks (Codex + VS Code) - run: node shared/scripts/skillpack-build.mjs --clean --out=dist --targets=codex,vscode + - name: Build skillpacks (Codex + VS Code + Junie) + run: node shared/scripts/skillpack-build.mjs --clean --out=dist --targets=codex,vscode,junie - name: Install skillpacks (smoke) run: | @@ -28,6 +28,8 @@ jobs: node shared/scripts/skillpack-install.mjs --from=dist --dest=/tmp/skillpack-install-test --targets=codex,vscode test -f /tmp/skillpack-install-test/.codex/skills/wordpress-router/SKILL.md test -f /tmp/skillpack-install-test/.github/skills/wordpress-router/SKILL.md + # verify Junie guidelines file existed in build output + test -f dist/junie/.junie/wordpress_guidelines.md - uses: actions/setup-python@v5 with: diff --git a/README.md b/README.md index 13273a7..311abb1 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ cd agent-skills node shared/scripts/skillpack-build.mjs --clean # Install into your WordPress project -node shared/scripts/skillpack-install.mjs --dest=../your-wp-project --targets=codex,vscode,claude,cursor +node shared/scripts/skillpack-install.mjs --dest=../your-wp-project --targets=codex,vscode,claude,cursor,junie ``` This copies skills into: @@ -74,6 +74,7 @@ This copies skills into: - `.github/skills/` for VS Code / GitHub Copilot - `.claude/skills/` for Claude Code (project-level) - `.cursor/skills/` for Cursor (project-level) +- `.junie/skills/` for Junie (project-level) plus an included `wordpress_guidelines.md` ### Install globally for Cursor diff --git a/docs/packaging.md b/docs/packaging.md index 9a629af..fef4c73 100644 --- a/docs/packaging.md +++ b/docs/packaging.md @@ -16,13 +16,15 @@ Outputs: - `dist/vscode/.github/skills/*` (VS Code / Copilot repo layout) - `dist/claude/.claude/skills/*` (Claude Code repo layout) - `dist/cursor/.cursor/skills/*` (Cursor repo layout) +- `dist/junie/.junie/skills/*` (Junie target layout) +- `dist/junie/.junie/wordpress_guidelines.md` (additional guidelines file) ## Install into another repo 1. Build dist (above). 2. Install into a destination repo: -- `node shared/scripts/skillpack-install.mjs --dest=../some-repo --targets=codex,vscode,claude,cursor` +- `node shared/scripts/skillpack-install.mjs --dest=../some-repo --targets=codex,vscode,claude,cursor,junie` By default, install mode is `replace` (it replaces only the skill directories it installs). diff --git a/eval/scenarios/skillpack-build-and-install.json b/eval/scenarios/skillpack-build-and-install.json index 653e1b2..49e5854 100644 --- a/eval/scenarios/skillpack-build-and-install.json +++ b/eval/scenarios/skillpack-build-and-install.json @@ -1,10 +1,10 @@ { "name": "Build and install skillpacks", "skills": [], - "query": "Package this repo's skills for Codex, VS Code, Claude, and Cursor and install them into another repository.", + "query": "Package this repo's skills for Codex, VS Code, Claude, Cursor, and Junie and install them into another repository.", "expected_behavior": [ - "Step 1: Run build command: node shared/scripts/skillpack-build.mjs --clean --targets=codex,vscode,claude,cursor", - "Step 2: Verify build output in dist/ directory", + "Step 1: Run build command: node shared/scripts/skillpack-build.mjs --clean --targets=codex,vscode,claude,cursor,junie", + "Step 2: Verify build output in dist/ directory (including dist/junie/.junie/wordpress_guidelines.md)", "Step 3: Run install command: node shared/scripts/skillpack-install.mjs --from=dist --dest= --targets=codex,vscode,claude,cursor", "Step 4: Verify skills installed in target repository", "Step 5: Confirm no symlinks in installed skills (files are copied)" @@ -14,6 +14,6 @@ "Output created in dist/ directory", "Install command copies to target repository", "No symlinks in installed skills", - "Codex, vscode, claude, and cursor targets supported" + "Codex, vscode, claude, cursor, and junie targets supported" ] } diff --git a/shared/scripts/skillpack-build.mjs b/shared/scripts/skillpack-build.mjs index a5841de..4c82323 100644 --- a/shared/scripts/skillpack-build.mjs +++ b/shared/scripts/skillpack-build.mjs @@ -1,32 +1,37 @@ import fs from "node:fs"; import path from "node:path"; +import http from "node:http"; +import https from "node:https"; function usage() { process.stderr.write( [ "Usage:", - " node shared/scripts/skillpack-build.mjs [--out=dist] [--targets=codex,vscode,claude,cursor] [--skills=skill1,skill2] [--clean]", + " node shared/scripts/skillpack-build.mjs [--out=dist] [--targets=codex,vscode,claude,cursor,junie] [--skills=skill1,skill2] [--clean]", "", "Outputs:", " - /codex/.codex/skills//SKILL.md", " - /vscode/.github/skills//SKILL.md", " - /claude/.claude/skills//SKILL.md", " - /cursor/.cursor/skills//SKILL.md", + " - /junie/.junie/skills//SKILL.md", + " - /junie/.junie/wordpress_guidelines.md", "", "Options:", - " --targets Comma-separated list of targets (codex, vscode, claude, cursor). Default: codex,vscode,claude,cursor", + " --targets Comma-separated list of targets (codex, vscode, claude, cursor, junie). Default: codex,vscode,claude,cursor,junie", " --skills Comma-separated list of skill names to build. Default: all skills", " --clean Remove target directories before building", "", "Notes:", "- Avoids symlinks (Codex ignores symlinked directories).", + ""," - junie target also downloads WordPress guidelines into the .junie folder.", "", ].join("\n") ); } function parseArgs(argv) { - const args = { out: "dist", targets: ["codex", "vscode", "claude", "cursor"], skills: [], clean: false }; + const args = { out: "dist", targets: ["codex", "vscode", "claude", "cursor", "junie"], skills: [], clean: false }; for (const a of argv) { if (a === "--help" || a === "-h") args.help = true; else if (a === "--clean") args.clean = true; @@ -101,6 +106,7 @@ function buildTarget({ repoRoot, outDir, target, skillDirs }) { vscode: path.join(outDir, "vscode", ".github", "skills"), claude: path.join(outDir, "claude", ".claude", "skills"), cursor: path.join(outDir, "cursor", ".cursor", "skills"), + junie: path.join(outDir, "junie", ".junie", "skills"), }; const destSkillsRoot = rootByTarget[target]; assert(destSkillsRoot, `Unknown target: ${target}`); @@ -117,9 +123,22 @@ function buildTarget({ repoRoot, outDir, target, skillDirs }) { process.stdout.write(`OK: built ${target} skillpack at ${rel}\n`); } -const VALID_TARGETS = ["codex", "vscode", "claude", "cursor"]; +const VALID_TARGETS = ["codex", "vscode", "claude", "cursor", "junie"]; -function main() { +async function downloadGuidelines(destRoot) { + // Download the WordPress guidelines markdown and save it into destRoot + const url = "https://github.com/user-attachments/files/25775597/wordpress_guidelines.md"; + const destPath = path.join(destRoot, "wordpress_guidelines.md"); + + const res = await fetch(url); + if (!res.ok) { + throw new Error(`Failed to download guidelines: ${res.status} ${res.statusText}`); + } + const content = await res.text(); + fs.writeFileSync(destPath, content); +} + +async function main() { const args = parseArgs(process.argv.slice(2)); if (args.help) { usage(); @@ -160,8 +179,21 @@ function main() { for (const target of targets) { buildTarget({ repoRoot, outDir, target, skillDirs }); + if (target === "junie") { + // ensure guidelines file is present in the root of the .junie folder + const junieRoot = path.join(outDir, "junie", ".junie"); + try { + await downloadGuidelines(junieRoot); + process.stdout.write(`OK: downloaded guidelines to ${path.relative(repoRoot, junieRoot)}\n`); + } catch (err) { + process.stderr.write(`Warning: could not download guidelines: ${err.message}\n`); + } + } } } -main(); +main().catch((err) => { + console.error(err); + process.exit(1); +});