|
| 1 | +#!/usr/bin/env node |
| 2 | +import fs from 'node:fs'; |
| 3 | +import path from 'node:path'; |
| 4 | + |
| 5 | +const prompt = fs.readFileSync(0, 'utf8'); |
| 6 | +const stage = process.env.DOCGEN_STAGE; |
| 7 | +const cwd = process.cwd(); |
| 8 | +const tick = String.fromCharCode(96); |
| 9 | +const between = (text, start, end) => { |
| 10 | + const tail = text.split(start)[1]; |
| 11 | + return tail ? tail.split(end)[0] : null; |
| 12 | +}; |
| 13 | +const target = between(prompt, `Write exactly one JSON file: ${tick}`, tick); |
| 14 | +const write = (rel, value) => { |
| 15 | + if (!rel) throw new Error(`missing output path for ${stage}`); |
| 16 | + const file = path.join(cwd, rel); |
| 17 | + fs.mkdirSync(path.dirname(file), { recursive: true }); |
| 18 | + fs.writeFileSync(file, JSON.stringify(value, null, 2) + '\n'); |
| 19 | +}; |
| 20 | + |
| 21 | +if (stage === 'modelCore') { |
| 22 | + write(target, { |
| 23 | + system: { |
| 24 | + components: [{ id: 'resource', kind: 'component', name: 'Resource', statement: 'HTTP resource', classification: 'FACT', confidence: 1, evidence: [{ path: 'src/Resource.java', startLine: 1 }] }], |
| 25 | + relationships: [], workflows: [], unknowns: [] |
| 26 | + }, |
| 27 | + business: { actors: [], capabilities: [], concepts: [], businessRules: [], decisions: [], branchConditions: [], lifecycles: [], invariants: [], useCases: [], unknowns: [] }, |
| 28 | + flows: { businessFlows: [], controlFlows: [], requestFlows: [], trafficFlows: [], dataFlows: [], eventFlows: [] }, |
| 29 | + catalogs: { endpoints: [], messageHandlers: [], externalDependencies: [], dataStores: [], scheduledJobs: [] } |
| 30 | + }); |
| 31 | +} else if (stage === 'modelEnterprise') { |
| 32 | + write(target, { |
| 33 | + security: { unknowns: [] }, operations: { unknowns: [] }, testing: { unknowns: [] }, |
| 34 | + 'data-governance': { unknowns: [] }, decisions: { unknowns: [] }, configuration: { unknowns: [] }, |
| 35 | + 'change-impact': { unknowns: [] }, ownership: { unknowns: [] } |
| 36 | + }); |
| 37 | +} else if (stage === 'plan') { |
| 38 | + write(target, { |
| 39 | + schemaVersion: '2.0', metadata: { description: 'Fixture docs' }, |
| 40 | + pages: [{ |
| 41 | + id: 'overview', title: 'System Overview', summary: 'Fixture overview.', category: 'orientation', |
| 42 | + mode: 'explanation', type: 'overview', order: 1, audience: ['engineer'], coverageTags: ['architecture'], |
| 43 | + query: 'resource architecture', requiredSections: [], risk: 'low', relatedPages: [] |
| 44 | + }] |
| 45 | + }); |
| 46 | +} else if (stage === 'generate') { |
| 47 | + const json = between(prompt, 'Page contracts:\n', '\n\nFor every contract:'); |
| 48 | + const contracts = JSON.parse(json); |
| 49 | + for (const contract of contracts) { |
| 50 | + const page = contract.page; |
| 51 | + const md = `--- |
| 52 | +title: ${JSON.stringify(page.title)} |
| 53 | +description: ${JSON.stringify(page.summary)} |
| 54 | +pageId: ${JSON.stringify(page.id)} |
| 55 | +category: ${JSON.stringify(page.category)} |
| 56 | +mode: ${JSON.stringify(page.mode)} |
| 57 | +type: ${JSON.stringify(page.type)} |
| 58 | +order: ${page.order} |
| 59 | +--- |
| 60 | +# ${page.title} |
| 61 | +
|
| 62 | +${page.summary} |
| 63 | +
|
| 64 | +The repository exposes an HTTP resource. |
| 65 | +`; |
| 66 | + const output = path.join(cwd, contract.outputPath); |
| 67 | + fs.mkdirSync(path.dirname(output), { recursive: true }); |
| 68 | + fs.writeFileSync(output, md); |
| 69 | + write(contract.traceabilityPath, { |
| 70 | + schemaVersion: '2.0', pageId: page.id, pagePath: contract.outputPath, |
| 71 | + claims: [{ |
| 72 | + id: `${page.id}:resource`, section: page.title, |
| 73 | + statement: 'The repository exposes an HTTP resource.', classification: 'FACT', confidence: 1, |
| 74 | + evidence: [{ path: 'src/Resource.java', startLine: 1 }], sourceModelRefs: ['system:resource'] |
| 75 | + }] |
| 76 | + }); |
| 77 | + } |
| 78 | +} else if (stage === 'audit') { |
| 79 | + const output = between(prompt, `report: ${tick}`, tick) || '.docgen/audit/llm-risk.json'; |
| 80 | + write(output, { schemaVersion: '2.0', pages: [] }); |
| 81 | +} else { |
| 82 | + console.error(`unexpected stage ${stage}`); |
| 83 | + process.exitCode = 2; |
| 84 | +} |
0 commit comments