From 0ff58108e40df57ef6be83e9cf15241a42f65b18 Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Wed, 8 Apr 2026 12:58:02 -0700 Subject: [PATCH] fix: restore agent yaml command export --- WORKING-CONTEXT.md | 6 ++- agent.yaml | 80 +++++++++++++++++++++++++++++ tests/ci/agent-yaml-surface.test.js | 79 ++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 tests/ci/agent-yaml-surface.test.js diff --git a/WORKING-CONTEXT.md b/WORKING-CONTEXT.md index 66a70ef0..62fa3450 100644 --- a/WORKING-CONTEXT.md +++ b/WORKING-CONTEXT.md @@ -1,6 +1,6 @@ # Working Context -Last updated: 2026-04-05 +Last updated: 2026-04-08 ## Purpose @@ -10,7 +10,7 @@ Public ECC plugin repo for agents, skills, commands, hooks, rules, install surfa - Default branch: `main` - Public release surface is aligned at `v1.10.0` -- Public catalog truth is `39` agents, `73` commands, and `179` skills +- Public catalog truth is `47` agents, `79` commands, and `181` skills - Public plugin slug is now `ecc`; legacy `everything-claude-code` install paths remain supported for compatibility - Release discussion: `#1272` - ECC 2.0 exists in-tree and builds, but it is still alpha rather than GA @@ -36,6 +36,7 @@ Public ECC plugin repo for agents, skills, commands, hooks, rules, install surfa - control plane primitives - operator surface - self-improving skills + - keep `agent.yaml` export parity with the shipped `commands/` and `skills/` directories so modern install surfaces do not silently lose command registration - Skill quality: - rewrite content-facing skills to use source-backed voice modeling - remove generic LLM rhetoric, canned CTA patterns, and forced platform stereotypes @@ -175,3 +176,4 @@ Keep this file detailed for only the current sprint, blockers, and next actions. - `skills/oura-health` and `skills/pmx-guidelines` are user- or project-specific, not canonical ECC surfaces - `docs/releases/2.0.0-preview/*` is premature collateral and should be rebuilt from current product truth later - nested `skills/hermes-generated/*` is superseded by the top-level ECC-native operator skills already ported to `main` +- 2026-04-08: Fixed the command-export regression reported in `#1327` by restoring a canonical `commands:` section in `agent.yaml` and adding `tests/ci/agent-yaml-surface.test.js` to enforce exact parity between the YAML export surface and the real `commands/` directory. Verified with the full repo test sweep: `1764/1764` passing. diff --git a/agent.yaml b/agent.yaml index cdf22d1f..8241c085 100644 --- a/agent.yaml +++ b/agent.yaml @@ -143,6 +143,86 @@ skills: - videodb - visa-doc-translate - x-api +commands: + - agent-sort + - aside + - build-fix + - checkpoint + - claw + - code-review + - context-budget + - cpp-build + - cpp-review + - cpp-test + - devfleet + - docs + - e2e + - eval + - evolve + - feature-dev + - flutter-build + - flutter-review + - flutter-test + - gan-build + - gan-design + - go-build + - go-review + - go-test + - gradle-build + - harness-audit + - hookify + - hookify-configure + - hookify-help + - hookify-list + - instinct-export + - instinct-import + - instinct-status + - jira + - kotlin-build + - kotlin-review + - kotlin-test + - learn + - learn-eval + - loop-start + - loop-status + - model-route + - multi-backend + - multi-execute + - multi-frontend + - multi-plan + - multi-workflow + - orchestrate + - plan + - pm2 + - projects + - promote + - prompt-optimize + - prp-commit + - prp-implement + - prp-plan + - prp-pr + - prp-prd + - prune + - python-review + - quality-gate + - refactor-clean + - resume-session + - review-pr + - rules-distill + - rust-build + - rust-review + - rust-test + - santa-loop + - save-session + - sessions + - setup-pm + - skill-create + - skill-health + - tdd + - test-coverage + - update-codemaps + - update-docs + - verify tags: - agent-harness - developer-tools diff --git a/tests/ci/agent-yaml-surface.test.js b/tests/ci/agent-yaml-surface.test.js new file mode 100644 index 00000000..6e9d1333 --- /dev/null +++ b/tests/ci/agent-yaml-surface.test.js @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Validate agent.yaml exports the legacy command shim surface. + */ + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const REPO_ROOT = path.join(__dirname, '..', '..'); +const AGENT_YAML_PATH = path.join(REPO_ROOT, 'agent.yaml'); +const COMMANDS_DIR = path.join(REPO_ROOT, 'commands'); + +function extractTopLevelList(yamlSource, key) { + const lines = yamlSource.replace(/^\uFEFF/, '').split(/\r?\n/); + const results = []; + let collecting = false; + + for (const line of lines) { + if (!collecting) { + if (line.trim() === `${key}:`) { + collecting = true; + } + continue; + } + + if (/^[A-Za-z0-9_-]+:\s*/.test(line)) { + break; + } + + const match = line.match(/^\s*-\s+(.+?)\s*$/); + if (match) { + results.push(match[1]); + } + } + + return results; +} + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + return true; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + return false; + } +} + +function run() { + console.log('\n=== Testing agent.yaml export surface ===\n'); + + let passed = 0; + let failed = 0; + + const yamlSource = fs.readFileSync(AGENT_YAML_PATH, 'utf8'); + const declaredCommands = extractTopLevelList(yamlSource, 'commands').sort(); + const actualCommands = fs.readdirSync(COMMANDS_DIR) + .filter(file => file.endsWith('.md')) + .map(file => path.basename(file, '.md')) + .sort(); + + if (test('agent.yaml declares commands export surface', () => { + assert.ok(declaredCommands.length > 0, 'Expected non-empty commands list in agent.yaml'); + })) passed++; else failed++; + + if (test('agent.yaml commands stay in sync with commands/ directory', () => { + assert.deepStrictEqual(declaredCommands, actualCommands); + })) passed++; else failed++; + + console.log(`\nPassed: ${passed}`); + console.log(`Failed: ${failed}`); + + process.exit(failed > 0 ? 1 : 0); +} + +run();