agents-standards
Standards for authoring SDD plugin agents — frontmatter, self-containment, skill references, and no-user-interaction rules.
Testing methodology for Claude Code plugins ensuring deterministic verification of LLM-driven workflows.
$ npx -y skills add LiorCohen/sdd --skill plugin-testing-standards --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/plugin-testing-standardsContext preview
The summary Claude sees to decide when to auto-load this skill.
Testing methodology for Claude Code plugins ensuring deterministic verification of LLM-driven workflows.
Testing methodology for Claude Code plugins ensuring deterministic verification of LLM-driven workflows.
---
tests/
├── lib/ # All helper/utility code (wraps Node.js)
│ ├── index.ts # Re-exports everything
│ ├── paths.ts # Directory constants
│ ├── fs.ts # File system operations
│ ├── process.ts # Command execution
│ ├── claude.ts # Claude CLI helpers
│ └── http.ts # HTTP utilities
└── tests/ # Test files (NO direct node:* imports)
├── unit/ # No LLM required
├── workflows/ # LLM with deterministic verification
└── integration/ # Full functional verificationTest files must NOT import from `node:*` directly. All Node.js functionality is accessed through `lib/` helpers.
// BAD - direct node import
import * as fs from 'node:fs';
import * as path from 'node:path';
// GOOD - use lib helpers
import { readFile, joinPath, fileExists } from '../lib/index.js';If a test file exceeds 300 lines, split it into a directory with multiple smaller files.
tests/unit/large-feature.test.ts (350 lines - TOO BIG) # Split into: tests/unit/large-feature/ ├── core.test.ts (~100 lines) ├── validation.test.ts (~120 lines) └── integration.test.ts (~130 lines)
Every `describe` and `it` block must have a WHY comment explaining the business/technical value, not the mechanics.
/**
* WHY: Ensures scaffolding substitutes project name variables.
* Without this, generated projects have {{PROJECT_NAME}} literals
* in package.json, breaking npm install.
*/
it('substitutes {{PROJECT_NAME}} in templates', async () => { ... });---
| Tier | Name | LLM | Purpose | Duration | |------|------|-----|---------|----------| | 1 | Unit | No | Test pure functions, templates, structure | < 10s | | 2 | Workflow | Yes | Verify correct agent/skill invocations | < 15min | | 3 | Integration | Yes | Verify generated output actually works | < 20min |
Pure TypeScript tests with no Claude involved.
Run Claude with predefined inputs, parse output, verify invocations.
Verify generated output actually works.
---
1. Run Claude in non-interactive mode with predefined inputs 2. Capture structured output via `--output-format stream-json` 3. Parse tool/skill/agent invocations from JSON 4. Compare to expected behavior defined in test specs
{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":"init"}}]}}
{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Task","input":{"subagent_type":"spec-writer"}}]}}interface ParsedOutput {
readonly toolUses: readonly ToolUse[];
readonly skillInvocations: readonly string[];
readonly agentInvocations: readonly string[];
}
const parseClaudeOutput = (output: string): ParsedOutput => {
const toolUses: ToolUse[] = [];
const skillInvocations: string[] = [];
const agentInvocations: string[] = [];
for (const line of output.split('\n')) {
try {
const event = JSON.parse(line);
if (event.type === 'assistant' && event.message?.content) {
for (const content of event.message.content) {
if (content.type === 'tool_use') {
toolUses.push({ name: content.name, input: content.input, id: content.id });
if (content.name === 'Skill') skillInvocations.push(content.input.skill);
if (content.name === 'Task') agentInvocations.push(content.input.subagent_type);
}
}
}
} catch { /* skip non-JSON */ }
}
return { toolUses, skillInvocations, agentInvocations };
};---
Include these instructions in all automated test prompts:
THIS IS AN AUTOMATED TEST. You MUST: 1. Skip ALL discovery questions and use the values above 2. Skip approval steps - consider it PRE-APPROVED 3. Execute ALL steps through completion 4. Do NOT stop for user input at any point 5. Create ALL files in the CURRENT WORKING DIRECTORY (.) - do NOT use absolute paths
---
/**
* WHY: Verifies that init generates projects that actually compile.
* Catches issues like invalid TypeScript, missing dependencies, or
* broken import paths that would break users immediately.
*/
describe('init functional verification', () => {
/**
* WHY: npm install must succeed for users to run the project.
* Catches invalid package.json, missing dependencies, or
* dependency version conflicts.
*/
it('generated project installs dependencies', async () => {
const result = await runClaude(PROMPT, testDir, 300);
expect(result.exitCode).toBe(0);
const installResult = await runCommand('npm', ['install'], { cwd: projectDir });
expect(installResult.exitCode).toBe(0);
});
/**
* WHY: TypeScript must compile for the project to be usable.
* Catches type errors, missing type definitions, or invalid
* tsconfig settings in templates.
*/
it('generated project builds successStructure for AI-assisted development AI coding assistants are powerful but chaotic. You prompt, you get code, but then what?
Repo: LiorCohen/sdd
Standards for authoring SDD plugin agents — frontmatter, self-containment, skill references, and no-user-interaction rules.
Standards for authoring SDD plugin commands — frontmatter, user interaction, skill/agent invocation, CLI integration, and output formatting.
Create a commit following repository guidelines with proper versioning and changelog updates.
Two-step self-review at every task lifecycle phase. Step 1 (this skill) runs in-context to gather session signals — files read vs grepped, user pushback, build…
D2 diagramming language reference for architecture diagrams, sequence diagrams, grid layouts, SQL tables, and class diagrams. Produces .d2 files rendered via…
Writes and maintains user-facing documentation for the SDD plugin. Proactively detects when docs are out of sync with plugin capabilities.