Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .agents/skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ CellixJS skills follow the same structure as community skills in [simnova/sharet

```
.agents/skills/ # Primary skills location (agentskills.io standard)
├── cellix-tdd/ # Consumer-first TDD workflow for @cellix packages
│ ├── SKILL.md # Main workflow and rules
│ ├── rubric.md # Artifact scoring rubric
│ ├── references/ # Manifest/docs guidance
│ ├── fixtures/ # Evaluation scenarios
│ └── evaluator/ # Rubric-based checker
├── madr-enforcement/ # Enforces ADR standards in code
│ ├── SKILL.md # Main skill instructions (required)
│ ├── EXAMPLES.md # Comprehensive code examples (recommended)
Expand All @@ -26,6 +32,7 @@ CellixJS skills follow the same structure as community skills in [simnova/sharet
└── (future skills)/ # Additional skills as needed

.github/skills/ # Symlinks for GitHub Copilot
├── cellix-tdd -> ../../.agents/skills/cellix-tdd
└── madr-enforcement -> ../../.agents/skills/madr-enforcement
```

Expand All @@ -42,6 +49,45 @@ CellixJS skills follow the same structure as community skills in [simnova/sharet

## Available Skills

### Cellix TDD

**Purpose:** Drive consumer-first, TDD-based development for `@cellix/*` framework packages while keeping `manifest.md`, `README.md`, TSDoc, tests, and release hardening aligned.

**Use Cases:**
- Adding or changing public behavior in an existing `@cellix/*` package
- Refactoring internals while preserving the public contract
- Starting a new `@cellix/*` package from consumer usage first
- Repairing drift between package docs and the shipped API
- Narrowing leaky or overbroad public exports before release

**What This Skill Does:**
- Requires discovery of consumer usage and package intent before implementation
- Forces public-contract-first testing instead of internal helper testing
- Requires `manifest.md`, consumer-facing `README.md`, and public-export TSDoc alignment
- Adds release-hardening and validation expectations to package work
- Ships fixtures plus an evaluator for rubric-based artifact scoring

**What This Skill Does NOT Do:**
- ❌ Does NOT treat tests as a post-implementation cleanup step
- ❌ Does NOT allow deep-import testing of internals
- ❌ Does NOT treat `README.md` as maintainer-only design notes
- ✅ DOES bias toward minimal, intentional public APIs

**Key Features:**
- Required workflow sections for package maturity work summaries
- Manifest and documentation templates captured inside the skill
- Mixed pass/fail fixtures covering the expected edge cases
- A standalone evaluator for public-contract and docs-alignment checks

**References:**
- [SKILL.md](cellix-tdd/SKILL.md) - Workflow, rules, and output structure
- [rubric.md](cellix-tdd/rubric.md) - Artifact scoring rubric
- [fixtures/README.md](cellix-tdd/fixtures/README.md) - Included scenario coverage

**Verification Commands:**
- `pnpm run test:skill:cellix-tdd` - run the fixture regression suite
- `pnpm run skill:cellix-tdd:check -- --package <pkg>` - scaffold the summary if needed, then evaluate it

### MADR Enforcement

**Purpose:** Ensure code adheres to architectural standards defined in MADRs (ADR-0003, ADR-0012, ADR-0013, ADR-0022, etc.)
Expand Down Expand Up @@ -87,6 +133,8 @@ Skills in `.agents/skills/` and `.github/skills/` are automatically discovered b
Skills are referenced in `.github/instructions/` files:
- `.github/instructions/madr.instructions.md` - MADR enforcement in code

Some skills, such as `cellix-tdd`, are intentionally discoverable through `.agents/skills/` and `.github/skills/` only so they stay on-demand instead of adding always-on instructions to unrelated tasks.

## Community Skills from ShareThrift

The [simnova/sharethrift](https://github.com/simnova/sharethrift) repository maintains a collection of community skills that our madr-enforcement skill aligns with structurally. ShareThrift skills follow the same agentskills.io specification and provide excellent examples of skill organization.
Expand Down
266 changes: 266 additions & 0 deletions .agents/skills/cellix-tdd/SKILL.md

Large diffs are not rendered by default.

114 changes: 114 additions & 0 deletions .agents/skills/cellix-tdd/evaluator/check-cellix-tdd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { resolve } from "node:path";
import { spawnSync } from "node:child_process";
import process from "node:process";
import { fileExists, getDefaultSummaryPath } from "./utils.ts";

interface ParsedArgs {
forceInit: boolean;
initOnly: boolean;
json: boolean;
outputPath?: string;
packageRoot?: string;
}

function parseArgs(argv: string[]): ParsedArgs {
const parsed: ParsedArgs = {
forceInit: false,
initOnly: false,
json: false,
};

for (let index = 0; index < argv.length; index += 1) {
const arg = argv[index];
const next = argv[index + 1];

switch (arg) {
case "--":
break;
case "--package":
parsed.packageRoot = next;
index += 1;
break;
case "--output":
parsed.outputPath = next;
index += 1;
break;
case "--force-init":
parsed.forceInit = true;
break;
case "--init-only":
parsed.initOnly = true;
break;
case "--json":
parsed.json = true;
break;
case "--help":
printUsage();
process.exit(0);
break;
default:
throw new Error(`Unknown argument: ${arg}`);
}
}

return parsed;
}

function printUsage(): void {
console.log(`Usage:
node --experimental-strip-types .agents/skills/cellix-tdd/evaluator/check-cellix-tdd.ts --package <package-root> [--output <summary.md>] [--init-only] [--force-init] [--json]`);
}

function runScript(scriptPath: string, args: string[]): number {
const result = spawnSync(process.execPath, ["--experimental-strip-types", scriptPath, ...args], {
cwd: process.cwd(),
stdio: "inherit",
});

if (result.error) {
throw result.error;
}

return result.status ?? 1;
}

function main(): void {
const args = parseArgs(process.argv.slice(2));

if (!args.packageRoot) {
printUsage();
process.exit(1);
}

const packageRoot = resolve(args.packageRoot);
const outputPath = args.outputPath ? resolve(args.outputPath) : getDefaultSummaryPath(packageRoot);
const initScriptPath = new URL("./init-cellix-tdd-summary.ts", import.meta.url);
const evaluateScriptPath = new URL("./evaluate-cellix-tdd.ts", import.meta.url);

if (!fileExists(outputPath) || args.forceInit) {
console.log(`No summary found. Creating scaffold at ${outputPath}`);
const initArgs = ["--package", packageRoot, "--output", outputPath];
if (args.forceInit) {
initArgs.push("--force");
}
const initStatus = runScript(initScriptPath.pathname, initArgs);
if (initStatus !== 0) {
process.exit(initStatus);
}
console.log("Summary scaffold created. Replace the TODO sections, then re-run the check.");
}

if (args.initOnly) {
process.exit(0);
}

const evaluateArgs = ["--package", packageRoot, "--output", outputPath];
if (args.json) {
evaluateArgs.push("--json");
}

const evaluateStatus = runScript(evaluateScriptPath.pathname, evaluateArgs);
process.exit(evaluateStatus);
}

main();
Loading
Loading