Skip to content

feat: agent-first skill scripts — structured returns + minified build#63

Merged
nucliweb merged 3 commits intomainfrom
feat/agent-first-skill-scripts
Mar 7, 2026
Merged

feat: agent-first skill scripts — structured returns + minified build#63
nucliweb merged 3 commits intomainfrom
feat/agent-first-skill-scripts

Conversation

@nucliweb
Copy link
Owner

@nucliweb nucliweb commented Mar 5, 2026

Motivation

Inspired by Rewrite your CLI for AI agents — agents consuming these scripts don't need color-coded console output, emojis, or pretty-printed tables. What they need is structured data they can act on, and the smallest possible token footprint.

This PR makes skill scripts agent-first end to end.


Changes

1. Structured return values on all snippets (snippets/**/*.js)

Every IIFE now returns a JSON object when executed via evaluate_script(). Agents read the return value directly instead of parsing console output.

// Before: agents had to parse "🟢 LCP: 1.24s (good)" from console
// After:
{
  script: "LCP", status: "ok", metric: "LCP",
  value: 1240, unit: "ms", rating: "good",
  thresholds: { good: 2500, needsImprovement: 4000 },
  details: { element: "img.hero", url: "hero.avif", sizePixels: 756000 }
}

Schema documented in .claude/skills/SCHEMA.md:

  • Metric scripts{ value, unit, rating, thresholds, details }
  • Audit scripts{ count, items[], issues[] }
  • Tracking scripts{ status: "tracking", getDataFn } + a window.getFn() that returns structured data after user interaction
  • Early returns (no data, unsupported API) → { status: "error"|"unsupported", error }

Console output is unchanged — the return value is purely additive.

2. Agent-first build pipeline (scripts/generate-skills.js)

The generator minifies skill scripts at build time using terser instead of copying them verbatim:

  • drop_console: true — strips all console.* calls
  • pure_getters: true — marks property accesses as side-effect-free, enabling removal of dead code left behind after console stripping
  • passes: 2 — second compression pass eliminates secondary dead code (unused variables whose only consumers were removed in the first pass)
  • mangle: true + comments: false — single minified line per script
  • Falls back to raw copy if minification fails (build never breaks)

Dead code elimination

Without pure_getters + passes: 2, constants used exclusively for console output (e.g. the RATING object with emoji icons and colors) survived minification:

// Before — RATING object kept even though console.group() was removed:
const t={good:{icon:"🟢",color:"#0CCE6A"},"needs-improvement":{icon:"🟡",color:"#FFA400"},poor:{icon:"🔴",color:"#FF4E42"}}
const{icon:c,color:m}=t[l]  // c and m unused — console.group was dropped
// After — fully eliminated:
(e(n), o.element)  // only the side-effecting parts remain

Each generated skill script gets a one-line traceability header:

// snippets/CoreWebVitals/LCP.js | sha256:a3f1b2c9d4e5f678 | https://github.com/nucliweb/webperf-snippets/blob/main/snippets/CoreWebVitals/LCP.js
(()=>{...minified code...})();

The SHA-256 is computed from the original source file, so you can verify at any time that the minified skill script matches its snippet:

shasum -a 256 snippets/CoreWebVitals/LCP.js | cut -c1-16
# should match the hash in .claude/skills/webperf-core-web-vitals/scripts/LCP.js

Token impact

A verbose snippet with console output (~80 lines) becomes a single minified line (~300 chars). Across ~50 scripts loaded by an agent in a session, this is a significant reduction. Emoji/color constants eliminated by dead code removal reduce this further.


Usage

npm install          # adds terser devDependency
npm run generate-skills

nucliweb added 2 commits March 5, 2026 12:35
All IIFE scripts now return a JSON object from evaluate_script(),
enabling agents to read structured data directly from the return value
instead of parsing console output.

- Every script returns { script, status, ...} matching SCHEMA.md
- Audit scripts include count, items[], issues[]
- Tracking scripts return { status: "tracking", getDataFn } with a
  window function agents can call later for results
- Early returns (no data / unsupported API) also return structured objects
- No console output changed — the return value is additive
Inspired by https://justin.poehnelt.com/posts/rewrite-your-cli-for-ai-agents/
— skill scripts are now generated agent-first: no human-readable console
output, no comments, minimal token footprint.

- generate-skills.js now calls terser instead of copyFileSync
  - drop_console: true removes all console.* calls
  - mangle + no comments produces a single minified line per script
  - fallback to raw copy if minification fails (never breaks the build)
- Each generated script gets a one-line header:
    // snippets/<Category>/<file>.js | sha256:<16-char> | <github-url>
  SHA-256 is computed from the original source, allowing verification
  that the minified script corresponds to a specific snippet version
- terser added as devDependency
@vercel
Copy link

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
webperf-snippets Ready Ready Preview, Comment Mar 7, 2026 9:17am
webperf-snippets-u6am Ready Ready Preview, Comment Mar 7, 2026 9:17am

After `drop_console: true` removes console.* calls, Terser left behind
constants that were only used for console output (e.g. the RATING object
with emoji icons/colors like { good: { icon: "🟢", color: "#0CCE6A" }, ... }).

This happened because Terser's single-pass compression couldn't determine
that destructured values from those constants were unused after console
removal.

Fix: add two Terser compress options:
- `pure_getters: true` — tells Terser that property accesses (obj.prop,
  obj[key]) have no side effects, so unused destructured results can be
  safely dropped
- `passes: 2` — runs a second compression pass to eliminate secondary dead
  code (unused variables whose only consumers were already removed in the
  first pass)

Result: emoji/color constants and their associated destructuring assignments
are fully eliminated from the generated skill scripts, reducing token
footprint further.
@nucliweb nucliweb merged commit 98874e2 into main Mar 7, 2026
3 checks passed
@nucliweb nucliweb deleted the feat/agent-first-skill-scripts branch March 7, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant