@esquadrao/cli 0.0.0-stage → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +366 -2
- package/assets/fonts/Anton-Regular.ttf +0 -0
- package/assets/fonts/BebasNeue-Regular.ttf +0 -0
- package/assets/fonts/OFL.txt +93 -0
- package/assets/fonts/Poppins-Bold.ttf +0 -0
- package/assets/fonts/README.md +13 -0
- package/bin/cli.js +126 -0
- package/package.json +58 -4
- package/scripts/ast_slice.js +73 -0
- package/scripts/cutout.py +197 -0
- package/scripts/dag_validator.js +78 -0
- package/scripts/lint.js +43 -0
- package/scripts/merkle_verify.js +83 -0
- package/scripts/wcag_check.js +77 -0
- package/skill-audit/SKILL.md +42 -0
- package/skill-audit/references/merkle-ledger-spec.md +27 -0
- package/skill-audit/references/receipt-ed25519-verification.md +17 -0
- package/skill-audit/references/time-travel-replay.md +10 -0
- package/skill-code-reviewer/SKILL.md +40 -0
- package/skill-context/SKILL.md +44 -0
- package/skill-context/references/ast-virtualization.md +10 -0
- package/skill-context/references/openapi-contract-synthesis.md +10 -0
- package/skill-engineering-manager/SKILL.md +40 -0
- package/skill-media-producer/SKILL.md +328 -0
- package/skill-media-producer/references/caption-templates.md +194 -0
- package/skill-media-producer/references/composicoes-especiais.md +99 -0
- package/skill-media-producer/references/configuracao-inicial.md +239 -0
- package/skill-media-producer/references/corte-podcast-3-niveis.md +179 -0
- package/skill-media-producer/references/llm-agent-guide.md +231 -0
- package/skill-orchestrate/SKILL.md +49 -0
- package/skill-orchestrate/references/mission-lifecycle.md +36 -0
- package/skill-orchestrate/references/swarm-coordination.md +33 -0
- package/skill-pipeline/SKILL.md +42 -0
- package/skill-pipeline/references/auto-healing-patterns.md +17 -0
- package/skill-pipeline/references/dag-decomposition-rules.md +18 -0
- package/skill-pipeline/references/topological-waves.md +16 -0
- package/skill-product-manager/SKILL.md +40 -0
- package/skill-qa-engineer/SKILL.md +40 -0
- package/skill-review/SKILL.md +46 -0
- package/skill-review/references/anti-slop-patterns.md +17 -0
- package/skill-review/references/dual-blind-adjudication.md +15 -0
- package/skill-review/references/voice-calibration.md +10 -0
- package/skill-security-engineer/SKILL.md +40 -0
- package/skill-software-architect/SKILL.md +40 -0
- package/skill-software-engineer/SKILL.md +40 -0
- package/skill-sre-engineer/SKILL.md +40 -0
- package/skill-system-analyst/SKILL.md +40 -0
- package/skill-tech-lead/SKILL.md +40 -0
- package/skill-technical-writer/SKILL.md +40 -0
- package/skill-ui/SKILL.md +45 -0
- package/skill-ui/references/design-tokens-spec.md +19 -0
- package/skill-ui/references/visual-tdd-methodology.md +10 -0
- package/skill-ui/references/wcag-target-sizes.md +9 -0
- package/src/captionTemplates.js +285 -0
- package/src/commands/onboard.js +618 -0
- package/src/commands/role.js +119 -0
- package/src/commands/setup.js +174 -0
- package/src/commands/studio.js +1822 -0
- package/src/roles/authority.js +129 -0
- package/src/roles/codeReviewer.js +65 -0
- package/src/roles/engineeringManager.js +53 -0
- package/src/roles/index.js +80 -0
- package/src/roles/mediaProducer.js +223 -0
- package/src/roles/productManager.js +50 -0
- package/src/roles/qaEngineer.js +54 -0
- package/src/roles/securityEngineer.js +53 -0
- package/src/roles/softwareArchitect.js +58 -0
- package/src/roles/softwareEngineer.js +76 -0
- package/src/roles/sreEngineer.js +60 -0
- package/src/roles/systemAnalyst.js +45 -0
- package/src/roles/techLead.js +46 -0
- package/src/roles/technicalWriter.js +46 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Application Security Engineer (formerly spec_critic)
|
|
2
|
+
// Adversarial security reviews, threat modeling, attack surface analysis, and edge case identification.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'security-engineer',
|
|
6
|
+
title: 'Security Engineer',
|
|
7
|
+
formerName: 'spec_critic',
|
|
8
|
+
category: 'security',
|
|
9
|
+
description: 'Conducts adversarial audits, threat modeling, vulnerability assessments, and boundary validation.',
|
|
10
|
+
requiredCapabilities: ['chat'],
|
|
11
|
+
readOnly: true,
|
|
12
|
+
allowedOutputPrefixes: ['reports/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { implementationContract = {}, architecture = '' } = params;
|
|
17
|
+
return `You are acting as an Application Security Engineer.
|
|
18
|
+
Perform an adversarial security review of the technical design and contract. Search for trust boundary violations, injection vectors, authorization bypasses, and data-loss edge cases.
|
|
19
|
+
|
|
20
|
+
Architecture / Contract:
|
|
21
|
+
${JSON.stringify(implementationContract, null, 2)}
|
|
22
|
+
${architecture}
|
|
23
|
+
|
|
24
|
+
Output Requirements:
|
|
25
|
+
Return a structured JSON object with:
|
|
26
|
+
{
|
|
27
|
+
"verdict": "PASS | REVISE | BLOCK",
|
|
28
|
+
"findings": [
|
|
29
|
+
{
|
|
30
|
+
"severity": "INFO | MINOR | MAJOR | BLOCKER",
|
|
31
|
+
"category": "AUTH | INJECTION | DATA_LOSS | PRIVACY | RESOURCE_EXHAUSTION | EDGE_CASE",
|
|
32
|
+
"description": "Clear explanation of the risk",
|
|
33
|
+
"remediation": "Concrete action required to mitigate"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"threat_model_summary": "Concise summary of evaluated attack vectors",
|
|
37
|
+
"recommended_mitigations": ["mitigation 1", "mitigation 2"]
|
|
38
|
+
}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function validateContract(data) {
|
|
42
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
43
|
+
if (!['PASS', 'REVISE', 'BLOCK'].includes(data.verdict)) {
|
|
44
|
+
throw new Error('verdict must be PASS, REVISE, or BLOCK');
|
|
45
|
+
}
|
|
46
|
+
if (!Array.isArray(data.findings)) throw new Error('"findings" must be an array');
|
|
47
|
+
for (const f of data.findings) {
|
|
48
|
+
if (!['INFO', 'MINOR', 'MAJOR', 'BLOCKER'].includes(f.severity)) {
|
|
49
|
+
throw new Error(`Invalid finding severity: ${f.severity}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Principal Software Architect (formerly chief_architect)
|
|
2
|
+
// Strategic decomposition, interface contract synthesis, invariant definitions, and rollback criteria.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'software-architect',
|
|
6
|
+
title: 'Principal Software Architect',
|
|
7
|
+
formerName: 'chief_architect',
|
|
8
|
+
category: 'architecture',
|
|
9
|
+
description: 'Decomposes complex systems, defines strict interface boundaries, establishes invariants, and authors implementation contracts.',
|
|
10
|
+
requiredCapabilities: ['chat', 'reasoning'],
|
|
11
|
+
readOnly: false,
|
|
12
|
+
allowedOutputPrefixes: ['docs/', 'reports/', 'schemas/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { objective = '', requirements = {}, repoSummary = '', allowedCandidates = [] } = params;
|
|
17
|
+
return `You are acting as a Principal Software Architect.
|
|
18
|
+
Synthesize an authoritative implementation contract with strict invariants and rollback criteria.
|
|
19
|
+
|
|
20
|
+
Objective:
|
|
21
|
+
${objective}
|
|
22
|
+
|
|
23
|
+
Requirements & Constraints:
|
|
24
|
+
${JSON.stringify(requirements, null, 2)}
|
|
25
|
+
|
|
26
|
+
Codebase Context:
|
|
27
|
+
${repoSummary}
|
|
28
|
+
|
|
29
|
+
Candidate Files for Modification:
|
|
30
|
+
${allowedCandidates.map((c) => `- ${c}`).join('\n') || '- None specified'}
|
|
31
|
+
|
|
32
|
+
Output Requirements:
|
|
33
|
+
Return a structured JSON object with:
|
|
34
|
+
{
|
|
35
|
+
"architecture": "High-level technical solution design",
|
|
36
|
+
"decisions": [
|
|
37
|
+
{"decision": "choice made", "rationale": "why this choice was made"}
|
|
38
|
+
],
|
|
39
|
+
"allowed_changes": ["concrete file paths authorized for modification, NO GLOBS"],
|
|
40
|
+
"forbidden_changes": ["files or paths strictly protected from modification"],
|
|
41
|
+
"invariants": ["system invariants that must not be broken"],
|
|
42
|
+
"rollback_conditions": ["observable failure states that trigger immediate abort/revert"],
|
|
43
|
+
"implementation_sequence": ["step 1", "step 2", "step 3"]
|
|
44
|
+
}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function validateContract(data) {
|
|
48
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
49
|
+
if (!data.architecture || typeof data.architecture !== 'string') throw new Error('Missing "architecture"');
|
|
50
|
+
if (!Array.isArray(data.allowed_changes)) throw new Error('"allowed_changes" must be an array');
|
|
51
|
+
if (!Array.isArray(data.invariants) || data.invariants.length === 0) {
|
|
52
|
+
throw new Error('"invariants" must be a non-empty array');
|
|
53
|
+
}
|
|
54
|
+
if (!Array.isArray(data.rollback_conditions) || data.rollback_conditions.length === 0) {
|
|
55
|
+
throw new Error('"rollback_conditions" must be a non-empty array');
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Senior Software Engineer (formerly implementer)
|
|
2
|
+
// Generates production-grade atomic code patches, unit tests, and minimal working diffs.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'software-engineer',
|
|
6
|
+
title: 'Senior Software Engineer',
|
|
7
|
+
formerName: 'implementer',
|
|
8
|
+
category: 'engineering',
|
|
9
|
+
description: 'Implements production code within strictly authorized scope, authors focused unit tests, and delivers clean atomic patches.',
|
|
10
|
+
requiredCapabilities: ['chat', 'tool_calling'],
|
|
11
|
+
readOnly: false,
|
|
12
|
+
allowedOutputPrefixes: ['*'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const {
|
|
17
|
+
objective = '',
|
|
18
|
+
allowedChanges = [],
|
|
19
|
+
forbiddenChanges = [],
|
|
20
|
+
invariants = [],
|
|
21
|
+
existingContext = '',
|
|
22
|
+
} = params;
|
|
23
|
+
|
|
24
|
+
return `You are acting as a Senior Software Engineer.
|
|
25
|
+
Implement the requested feature or fix within the authorized scope.
|
|
26
|
+
Follow the "laziness" principle: minimal working diff, native stdlib first, zero unrequested dependencies.
|
|
27
|
+
|
|
28
|
+
Objective:
|
|
29
|
+
${objective}
|
|
30
|
+
|
|
31
|
+
Authorized Files (allowed_changes):
|
|
32
|
+
${allowedChanges.map((f) => `- ${f}`).join('\n')}
|
|
33
|
+
|
|
34
|
+
Forbidden Files (do NOT touch):
|
|
35
|
+
${forbiddenChanges.map((f) => `- ${f}`).join('\n') || '- None'}
|
|
36
|
+
|
|
37
|
+
Invariants to Preserve:
|
|
38
|
+
${invariants.map((i) => `- ${i}`).join('\n')}
|
|
39
|
+
|
|
40
|
+
Relevant Existing Code Context:
|
|
41
|
+
${existingContext}
|
|
42
|
+
|
|
43
|
+
Output Requirements:
|
|
44
|
+
Your code deliverables must be provided in clean FILE blocks in the following format:
|
|
45
|
+
FILE: path/to/file.ext
|
|
46
|
+
\`\`\`
|
|
47
|
+
// file content
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
Rules:
|
|
51
|
+
1. Every modified or created file must have its full content inside a FILE block.
|
|
52
|
+
2. Touch ONLY files listed in Authorized Files.
|
|
53
|
+
3. Include at least one runnable test verifying the core logic.
|
|
54
|
+
4. Do not include speculative boilerplate or unused abstractions.`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function parseFileBlocks(text = '') {
|
|
58
|
+
const fileRegex = /FILE:\s*([^\r\n]+)\r?\n```[^\r\n]*\r?\n([\s\S]*?)```/g;
|
|
59
|
+
const files = [];
|
|
60
|
+
let match;
|
|
61
|
+
while ((match = fileRegex.exec(text)) !== null) {
|
|
62
|
+
files.push({
|
|
63
|
+
path: match[1].trim(),
|
|
64
|
+
content: match[2],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return files;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function validateContract(data) {
|
|
71
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
72
|
+
if (!Array.isArray(data.files_changed) && !Array.isArray(data.files)) {
|
|
73
|
+
throw new Error('Must provide files_changed or files list');
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Site Reliability Engineer / Debugging Specialist (formerly failure_diagnostician)
|
|
2
|
+
// Root-cause analysis of test failures, stack traces, and deterministic fix-contract synthesis.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'sre-engineer',
|
|
6
|
+
title: 'Site Reliability Engineer',
|
|
7
|
+
formerName: 'failure_diagnostician',
|
|
8
|
+
category: 'operations',
|
|
9
|
+
description: 'Performs deep root-cause analysis on failing test runs, runtime crashes, and synthesizes targeted fix contracts.',
|
|
10
|
+
requiredCapabilities: ['chat', 'reasoning'],
|
|
11
|
+
readOnly: false,
|
|
12
|
+
allowedOutputPrefixes: ['reports/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { errorLog = '', failureHistory = [], testFile = '' } = params;
|
|
17
|
+
return `You are acting as a Site Reliability Engineer and Debugging Specialist.
|
|
18
|
+
Analyze the test failure, error logs, and execution traces to produce an immutable Root Cause Analysis and Fix Contract.
|
|
19
|
+
|
|
20
|
+
Failing Test:
|
|
21
|
+
${testFile || 'Unknown'}
|
|
22
|
+
|
|
23
|
+
Error Logs:
|
|
24
|
+
\`\`\`
|
|
25
|
+
${errorLog}
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
Failure History:
|
|
29
|
+
${JSON.stringify(failureHistory, null, 2)}
|
|
30
|
+
|
|
31
|
+
Output Requirements:
|
|
32
|
+
Return a structured JSON object with:
|
|
33
|
+
{
|
|
34
|
+
"root_cause_analysis": {
|
|
35
|
+
"summary": "Precise mechanical explanation of why the failure occurred",
|
|
36
|
+
"failing_symbol_or_line": "function, line, or invariant that broke",
|
|
37
|
+
"flaw_category": "BOUNDARY_CONDITION | CONCURRENCY | REGRESSION | TYPE_ERROR | NETWORK | TIMEOUT",
|
|
38
|
+
"revised_assumptions": ["incorrect assumption previously held"]
|
|
39
|
+
},
|
|
40
|
+
"fix_contract": {
|
|
41
|
+
"targeted_files": ["exact file paths that must be fixed"],
|
|
42
|
+
"required_invariants": ["invariants that the fix must uphold"],
|
|
43
|
+
"regression_test_strategy": "description of unit test to prevent recurrence"
|
|
44
|
+
}
|
|
45
|
+
}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function validateContract(data) {
|
|
49
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
50
|
+
if (!data.root_cause_analysis || typeof data.root_cause_analysis !== 'object') {
|
|
51
|
+
throw new Error('Missing root_cause_analysis object');
|
|
52
|
+
}
|
|
53
|
+
if (!data.fix_contract || typeof data.fix_contract !== 'object') {
|
|
54
|
+
throw new Error('Missing fix_contract object');
|
|
55
|
+
}
|
|
56
|
+
if (!Array.isArray(data.fix_contract.targeted_files) || data.fix_contract.targeted_files.length === 0) {
|
|
57
|
+
throw new Error('fix_contract.targeted_files must be a non-empty array');
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Systems Analyst / Codebase Navigator (formerly cartographer)
|
|
2
|
+
// Maps repository structure, dependencies, entry points, and identifies affected modules.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'system-analyst',
|
|
6
|
+
title: 'Systems Analyst',
|
|
7
|
+
formerName: 'cartographer',
|
|
8
|
+
category: 'engineering',
|
|
9
|
+
description: 'Navigates codebases, extracts module dependency graphs, maps architectural boundaries, and identifies touchpoints.',
|
|
10
|
+
requiredCapabilities: ['chat'],
|
|
11
|
+
readOnly: true,
|
|
12
|
+
allowedOutputPrefixes: ['reports/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { files = [], objective = '' } = params;
|
|
17
|
+
return `You are acting as a Systems Analyst and Codebase Navigator.
|
|
18
|
+
Perform read-only repository reconnaissance and map structural dependencies for the stated objective.
|
|
19
|
+
|
|
20
|
+
Objective:
|
|
21
|
+
${objective}
|
|
22
|
+
|
|
23
|
+
Discovered File Tree (sample):
|
|
24
|
+
${files.slice(0, 100).map((f) => `- ${f}`).join('\n')}
|
|
25
|
+
|
|
26
|
+
Output Requirements:
|
|
27
|
+
Return a structured JSON object with:
|
|
28
|
+
{
|
|
29
|
+
"summary": "High-level summary of relevant codebase modules",
|
|
30
|
+
"entrypoints": ["main entrypoint files"],
|
|
31
|
+
"affected_components": ["components likely impacted"],
|
|
32
|
+
"dependency_graph": {
|
|
33
|
+
"moduleA": ["dependsOnB", "dependsOnC"]
|
|
34
|
+
},
|
|
35
|
+
"suggested_scope": ["concrete file paths to inspect or modify"]
|
|
36
|
+
}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function validateContract(data) {
|
|
40
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
41
|
+
if (!data.summary || typeof data.summary !== 'string') throw new Error('Missing or invalid "summary"');
|
|
42
|
+
if (!Array.isArray(data.entrypoints)) throw new Error('"entrypoints" must be an array');
|
|
43
|
+
if (!Array.isArray(data.suggested_scope)) throw new Error('"suggested_scope" must be an array');
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Tech Lead / Architecture Arbiter (formerly architecture_adjudicator)
|
|
2
|
+
// Arbitrates architectural disputes, evaluates technical trade-offs, and enforces engineering guidelines.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'tech-lead',
|
|
6
|
+
title: 'Technical Lead',
|
|
7
|
+
formerName: 'architecture_adjudicator',
|
|
8
|
+
category: 'architecture',
|
|
9
|
+
description: 'Arbitrates architectural disagreements, evaluates trade-offs between competing proposals, and governs technical standards.',
|
|
10
|
+
requiredCapabilities: ['chat', 'reasoning'],
|
|
11
|
+
readOnly: false,
|
|
12
|
+
allowedOutputPrefixes: ['docs/', 'reports/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { proposals = [], issue = '', constraints = [] } = params;
|
|
17
|
+
return `You are acting as the Technical Lead and Architecture Arbiter.
|
|
18
|
+
Review the competing technical proposals, evaluate trade-offs against constraints, and make a binding adjudication.
|
|
19
|
+
|
|
20
|
+
Dispute / Architecture Decision:
|
|
21
|
+
${issue}
|
|
22
|
+
|
|
23
|
+
Constraints:
|
|
24
|
+
${constraints.map((c) => `- ${c}`).join('\n')}
|
|
25
|
+
|
|
26
|
+
Proposals:
|
|
27
|
+
${JSON.stringify(proposals, null, 2)}
|
|
28
|
+
|
|
29
|
+
Output Requirements:
|
|
30
|
+
Return a structured JSON object with:
|
|
31
|
+
{
|
|
32
|
+
"verdict": "APPROVED_PROPOSAL_A | APPROVED_PROPOSAL_B | COMPROMISE | REJECTED",
|
|
33
|
+
"chosen_solution": "Summary of the accepted approach",
|
|
34
|
+
"rationale": "Clear technical justification citing simplicity, maintainability, and constraints",
|
|
35
|
+
"required_adjustments": ["mandatory modifications required before implementation"],
|
|
36
|
+
"technical_debt_impact": "LOW | MEDIUM | HIGH with explanation"
|
|
37
|
+
}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function validateContract(data) {
|
|
41
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
42
|
+
if (!data.verdict || typeof data.verdict !== 'string') throw new Error('Missing "verdict"');
|
|
43
|
+
if (!data.chosen_solution || typeof data.chosen_solution !== 'string') throw new Error('Missing "chosen_solution"');
|
|
44
|
+
if (!data.rationale || typeof data.rationale !== 'string') throw new Error('Missing "rationale"');
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Technical Writer (formerly documentation)
|
|
2
|
+
// Authors developer documentation, API contracts, changelogs, and release summaries.
|
|
3
|
+
|
|
4
|
+
export const definition = {
|
|
5
|
+
id: 'technical-writer',
|
|
6
|
+
title: 'Technical Writer',
|
|
7
|
+
formerName: 'documentation',
|
|
8
|
+
category: 'documentation',
|
|
9
|
+
description: 'Authors technical documentation, API specs, architectural decision records (ADRs), and user guides.',
|
|
10
|
+
requiredCapabilities: ['chat'],
|
|
11
|
+
readOnly: false,
|
|
12
|
+
allowedOutputPrefixes: ['docs/', 'README.md', 'CHANGELOG.md', 'reports/'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function buildPrompt(params = {}) {
|
|
16
|
+
const { changes = [], prTitle = '', architectureSummary = '' } = params;
|
|
17
|
+
return `You are acting as a Staff Technical Writer.
|
|
18
|
+
Produce clear, accurate, and concise developer documentation reflecting the changes.
|
|
19
|
+
|
|
20
|
+
Title / PR:
|
|
21
|
+
${prTitle}
|
|
22
|
+
|
|
23
|
+
Architecture Summary:
|
|
24
|
+
${architectureSummary}
|
|
25
|
+
|
|
26
|
+
Changes Delivered:
|
|
27
|
+
${changes.map((c) => `- ${c}`).join('\n')}
|
|
28
|
+
|
|
29
|
+
Output Requirements:
|
|
30
|
+
Return a structured JSON object with:
|
|
31
|
+
{
|
|
32
|
+
"summary": "Plain English summary of what was built and why",
|
|
33
|
+
"documentation_markdown": "Full markdown text for documentation or README updates",
|
|
34
|
+
"changelog_entry": "Markdown line formatted for CHANGELOG.md under Added/Changed/Fixed",
|
|
35
|
+
"affected_apis": ["list of endpoints, interfaces, or CLI flags updated"]
|
|
36
|
+
}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function validateContract(data) {
|
|
40
|
+
if (!data || typeof data !== 'object') throw new Error('Contract must be an object');
|
|
41
|
+
if (!data.summary || typeof data.summary !== 'string') throw new Error('Missing "summary"');
|
|
42
|
+
if (!data.documentation_markdown || typeof data.documentation_markdown !== 'string') {
|
|
43
|
+
throw new Error('Missing "documentation_markdown"');
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|