Setting the file. One moment. Set Adr Status · Adr Skill · vercel/ai · Skills Docsscripts/set_adr_status.js
JavaScript·170 lines·4 KB
13
function
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 line
124 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();