scripts/set_adr_status.js
scripts/set_adr_status.jsBrowse 11 files
1,166 tokens
4,266 bytes
Token encoding: o200k_base
Snapshot 8b92ba9
← Back to SKILL.md
1#!/usr/bin/env node2/**3 * Update an ADR's status in-place.4 *5 * Supported patterns:6 * - Bullet status: "- Status: proposed" or "* Status: proposed"7 * - Nygard-style section: "## Status" followed by a single-line status value8 */9 10const fs = require('node:fs');11const path = require('node:path');12 13function die(msg) {14 process.stderr.write(`${msg}\n`);15 process.exit(1);16}17 18function toPosix(p) {19 return p.split(path.sep).join('/');20}21 22function parseArgs(argv) {23 if (argv.includes('--help') || argv.includes('-h')) {24 process.stdout.write(25 [26 'Usage: node set_adr_status.js <path> --status <value> [--json]',27 '',28 'Example:',29 ' node set_adr_status.js adr/2025-06-15-foo.md --status accepted',30 '',31 ].join('\n'),32 );33 process.exit(0);34 }35 36 if (argv.length < 3) die('Missing <path>');37 const file = argv[2];38 39 let status = null;40 let json = false;41 for (let i = 3; i < argv.length; i++) {42 const a = argv[i];43 if (a === '--status') {44 if (i + 1 >= argv.length) die('Missing value for --status');45 status = argv[++i];46 } else if (a === '--json') {47 json = true;48 } else {49 die(`Unknown arg: ${a}`);50 }51 }52 if (!status) die('Missing required --status');53 return { file, status: String(status).trim(), json };54}55 56function setYamlFrontMatterStatus(lines, newStatus) {57 // YAML front matter: starts with '---', ends with next '---'58 if (lines.length < 2 || lines[0].trim() !== '---')59 return { lines, changed: false };60 61 let changed = false;62 const out = [];63 let inFrontMatter = true;64 let passedOpening = false;65 66 for (let i = 0; i < lines.length; i++) {67 const line = lines[i];68 69 if (i === 0 && line.trim() === '---') {70 passedOpening = true;71 out.push(line);72 continue;73 }74 75 if (passedOpening && inFrontMatter && line.trim() === '---') {76 inFrontMatter = false;77 out.push(line);78 continue;79 }80 81 if (passedOpening && inFrontMatter && /^status\s*:/.test(line)) {82 out.push(`status: ${newStatus}`);83 changed = true;84 continue;85 }86 87 out.push(line);88 }89 90 return { lines: out, changed };91}92 93function setBulletStatus(lines, newStatus) {94 let changed = false;95 const out = lines.map(line => {96 const m = line.match(/^([*-])\s*Status:\s*(.*)$/);97 if (!m) return line;98 changed = true;99 return `${m[1]} Status: ${newStatus}`;100 });101 return { lines: out, changed };102}103 104function setSectionStatus(lines, newStatus) {105 let changed = false;106 const out = [];107 108 for (let i = 0; i < lines.length; i++) {109 out.push(lines[i]);110 111 if (!/^##\s+Status\s*$/.test(lines[i])) continue;112 113 // Replace next non-empty, non-heading line. If not found, insert.114 let j = i + 1;115 while (j < lines.length && lines[j].trim() === '') {116 out.push(lines[j]);117 j++;118 }119 120 if (j < lines.length && !/^##\s+/.test(lines[j])) {121 out.push(newStatus);122 changed = true;123 i = j; // skip original status line124 continue;125 }126 127 out.push(newStatus);128 changed = true;129 i = j - 1;130 }131 132 return { lines: out, changed };133}134 135function main() {136 const args = parseArgs(process.argv);137 const filePath = path.resolve(process.cwd(), args.file);138 if (!fs.existsSync(filePath)) die(`File not found: ${filePath}`);139 140 const content = fs.readFileSync(filePath, 'utf8');141 const hadTrailingNewline = content.endsWith('\n');142 const lines = content.replace(/\r\n/g, '\n').split('\n');143 144 let r = setYamlFrontMatterStatus(lines, args.status);145 if (!r.changed) r = setBulletStatus(lines, args.status);146 if (!r.changed) r = setSectionStatus(lines, args.status);147 if (!r.changed) {148 die(149 "Could not find a status to update. Expected YAML front matter 'status:', '- Status:'/'* Status:', or a '## Status' section.",150 );151 }152 153 const newContent = r.lines.join('\n') + (hadTrailingNewline ? '\n' : '');154 fs.writeFileSync(filePath, newContent, 'utf8');155 156 if (args.json) {157 process.stdout.write(158 `${JSON.stringify({159 filePath,160 fileRelPath: toPosix(path.relative(process.cwd(), filePath)),161 status: args.status,162 changed: true,163 })}\n`,164 );165 } else {166 process.stdout.write(`${filePath}\n`);167 }168}169 170main();171 Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 234.SKILL.mdView in source ↗2342. Use `scripts/set_adr_status.js` for status changes (supports YAML front matter, bullet status, and section status).
Source excerpt starting at line 285.285- `scripts/new_adr.js` — create a new ADR file from a template, using repo conventions.286- `scripts/set_adr_status.js` — update an ADR status in-place (YAML front matter or inline). Use `--json` for machine output.287- `scripts/bootstrap_adr.js` — create ADR dir, `README.md`, and initial "Adopt ADRs" decision.