Deterministic formatting of specification documents in multiple output formats.
From spec-iterator-mcpnpx claudepluginhub JesseHenson/claude_code_apex_marketplace --plugin spec-iterator-mcpThis skill uses the workspace's default tool permissions.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Transforms raw data into narratives with story structures, visuals, and frameworks for executive presentations, analytics reports, and stakeholder communications.
Deterministic formatting of specification documents in multiple output formats.
Converts structured spec data into consistent, well-formatted output documents.
function formatMarkdown(spec: GeneratedSpec): string {
return `
# ${spec.title}
> Generated from session: ${spec.sessionId}
> Completeness: ${spec.metadata.completeness}%
> Generated: ${spec.metadata.generatedAt}
## Problem Statement
**Pain Point:** ${spec.problem.pain}
**Target User:** ${spec.problem.targetUser}
**Current Workarounds:**
${spec.problem.workarounds.map(w => `- ${w}`).join('\n')}
**Success Criteria:**
${spec.problem.successCriteria.map(c => `- ${c}`).join('\n')}
---
## User Flow
${formatUserFlow(spec.userFlow)}
---
## Features
### MVP Features
${formatFeatures(spec.features.mvp)}
### V2 Features
${formatFeatures(spec.features.v2)}
---
## Input/Output Contracts
### Inputs
| Field | Type | Required | Validation | Description |
|-------|------|----------|------------|-------------|
${formatInputTable(spec.contracts.inputs)}
### Outputs
| Field | Type | Nullable | Description |
|-------|------|----------|-------------|
${formatOutputTable(spec.contracts.outputs)}
${spec.contracts.api ? formatApiContracts(spec.contracts.api) : ''}
---
## Edge Cases
| Scenario | Expected Behavior | Priority |
|----------|-------------------|----------|
${formatEdgeCases(spec.edgeCases)}
---
## Assumptions
> These assumptions were made during clarification. Validate with stakeholders.
${spec.assumptions.map((a, i) => `${i + 1}. **${a.topic}**: ${a.assumption} _(${a.reason})_`).join('\n')}
---
## Open Questions
${spec.openQuestions.map(q => `- [ ] ${q}`).join('\n')}
---
_Generated by Spec Iterator MCP_
`.trim();
}
function formatUserFlow(flow: UserFlowStep[]): string {
return flow.map((step, i) => {
let line = `${i + 1}. **${step.actor}**: ${step.action} → ${step.outcome}`;
if (step.alternatives) {
line += '\n' + step.alternatives.map(alt =>
` - _If ${alt.condition}_ → ${alt.outcome}`
).join('\n');
}
return line;
}).join('\n');
}
function formatFeatures(features: Feature[]): string {
return features.map(f => `
#### ${f.name}
${f.description}
**Acceptance Criteria:**
${f.acceptanceCriteria.map(ac => `- [ ] ${ac}`).join('\n')}
**Priority:** ${f.priority}
`).join('\n---\n');
}
function formatInputTable(inputs: InputField[]): string {
return inputs.map(i =>
`| ${i.name} | ${i.type} | ${i.required ? 'Yes' : 'No'} | ${i.validation || '-'} | ${i.description} |`
).join('\n');
}
function formatOutputTable(outputs: OutputField[]): string {
return outputs.map(o =>
`| ${o.name} | ${o.type} | ${o.nullable ? 'Yes' : 'No'} | ${o.description} |`
).join('\n');
}
function formatEdgeCases(cases: EdgeCase[]): string {
return cases.map(c =>
`| ${c.scenario} | ${c.handling} | ${c.priority} |`
).join('\n');
}
function formatJson(spec: GeneratedSpec): string {
return JSON.stringify({
$schema: "https://spec-iterator.dev/schema/v1",
version: "1.0",
...spec
}, null, 2);
}
function formatYaml(spec: GeneratedSpec): string {
// Use a YAML library for proper formatting
return yaml.stringify({
version: "1.0",
...spec
});
}
interface GeneratedSpec {
title: string;
sessionId: string;
problem: {
pain: string;
targetUser: string;
workarounds: string[];
successCriteria: string[];
};
userFlow: UserFlowStep[];
features: {
mvp: Feature[];
v2: Feature[];
};
contracts: {
inputs: InputField[];
outputs: OutputField[];
api?: ApiEndpoint[];
};
edgeCases: EdgeCase[];
assumptions: Assumption[];
openQuestions: string[];
metadata: {
completeness: number;
generatedAt: string;
sessionRounds: number;
};
}
interface UserFlowStep {
actor: string;
action: string;
outcome: string;
alternatives?: {
condition: string;
outcome: string;
}[];
}
interface Feature {
name: string;
description: string;
acceptanceCriteria: string[];
priority: 'critical' | 'important' | 'nice_to_have';
}
interface InputField {
name: string;
type: string;
required: boolean;
validation?: string;
description: string;
}
interface OutputField {
name: string;
type: string;
nullable: boolean;
description: string;
}
interface EdgeCase {
scenario: string;
handling: string;
priority: 'MVP' | 'V2';
}
function generateFileName(requirement: string, format: string): string {
const slug = requirement
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '')
.substring(0, 50);
const extension = format === 'markdown' ? 'md' : format;
return `${slug}-spec.${extension}`;
}
// In spec-compiler agent
const spec = compileSpec(session);
const formatted = formatMarkdown(spec);
const fileName = generateFileName(session.requirement, 'markdown');
writeFile(`outputs/specs/${fileName}`, formatted);