@rsaglobaltech/specgate 0.24.0 → 0.25.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/packages/core/src/domain/Clarification.js +173 -0
  3. package/dist/packages/core/src/domain/Clarification.js.map +1 -0
  4. package/dist/packages/core/src/domain/DraftChecklist.js +16 -16
  5. package/dist/packages/core/src/domain/DraftChecklist.js.map +1 -1
  6. package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
  7. package/dist/packages/core/test/unit/clarification.test.js +161 -0
  8. package/dist/packages/core/test/unit/clarification.test.js.map +1 -0
  9. package/dist/scripts/answer.js +10 -0
  10. package/dist/scripts/answer.js.map +1 -0
  11. package/dist/scripts/ask.js +10 -0
  12. package/dist/scripts/ask.js.map +1 -0
  13. package/dist/scripts/brief_add.js +10 -0
  14. package/dist/scripts/brief_add.js.map +1 -0
  15. package/dist/scripts/cli/commands/change/ChangeCommand.js +87 -1
  16. package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
  17. package/dist/scripts/cli/commands/harness/RunCommand.js +78 -3
  18. package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
  19. package/dist/scripts/cli/commands/spec/ClarifyCommands.js +275 -0
  20. package/dist/scripts/cli/commands/spec/ClarifyCommands.js.map +1 -0
  21. package/dist/scripts/harness/prompt.js +2 -0
  22. package/dist/scripts/harness/prompt.js.map +1 -1
  23. package/dist/scripts/lib/brief-add.js +197 -0
  24. package/dist/scripts/lib/brief-add.js.map +1 -0
  25. package/dist/scripts/lib/change-impact.js +156 -0
  26. package/dist/scripts/lib/change-impact.js.map +1 -0
  27. package/dist/scripts/lib/clarification.js +300 -0
  28. package/dist/scripts/lib/clarification.js.map +1 -0
  29. package/dist/scripts/lib/live-detail.js +3 -2
  30. package/dist/scripts/lib/live-detail.js.map +1 -1
  31. package/dist/scripts/lib/live-model.js +28 -3
  32. package/dist/scripts/lib/live-model.js.map +1 -1
  33. package/dist/scripts/lib/live-page.js +10 -6
  34. package/dist/scripts/lib/live-page.js.map +1 -1
  35. package/dist/scripts/lib/surface.js +52 -0
  36. package/dist/scripts/lib/surface.js.map +1 -1
  37. package/dist/scripts/questions.js +10 -0
  38. package/dist/scripts/questions.js.map +1 -0
  39. package/package.json +1 -1
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.BriefAddCommand = exports.AskCommand = exports.AnswerCommand = exports.QuestionsCommand = void 0;
37
+ const project_root_1 = require("../../../lib/project-root");
38
+ const diagnostics_1 = require("../../../lib/diagnostics");
39
+ const agent_1 = require("../../../lib/agent");
40
+ const command_1 = require("../../../lib/command");
41
+ const harness_events_1 = require("../../../lib/harness-events");
42
+ const clarification_1 = require("../../../lib/clarification");
43
+ const brief_add_1 = require("../../../lib/brief-add");
44
+ const HarnessEvents_1 = require("../../../../packages/core/src/domain/HarnessEvents");
45
+ const ui = __importStar(require("../../../lib/ui"));
46
+ function parse(argv, io, shape, command) {
47
+ const out = { words: [], dir: ".", reviewed: false };
48
+ for (let i = 0; i < argv.length; i += 1) {
49
+ const a = argv[i];
50
+ if (a === "--project-dir")
51
+ out.dir = argv[++i] || ".";
52
+ else if (a === "--change")
53
+ out.change = argv[++i];
54
+ else if (a === "--reviewed")
55
+ out.reviewed = true;
56
+ else if (a === "--json")
57
+ continue;
58
+ else if (a.startsWith("-")) {
59
+ io.usage(shape, [
60
+ (0, diagnostics_1.error)("unknown_flag", `Unknown flag for ${command}: ${a}`, {
61
+ fix: `specgate ${command} --help`,
62
+ }),
63
+ ]);
64
+ }
65
+ else
66
+ out.words.push(a);
67
+ }
68
+ return out;
69
+ }
70
+ function project(dir, io, shape) {
71
+ try {
72
+ return (0, project_root_1.resolveProjectDir)(dir);
73
+ }
74
+ catch (err) {
75
+ return io.usage(shape, [
76
+ (0, diagnostics_1.error)("project_not_found", err.message, {
77
+ fix: "Run from inside a spec-driven project, or pass --project-dir.",
78
+ }),
79
+ ]);
80
+ }
81
+ }
82
+ class QuestionsCommand extends command_1.BaseCommand {
83
+ execute() {
84
+ const argv = this.args;
85
+ if (argv.includes("--help") || argv.includes("-h")) {
86
+ process.stdout.write("Usage:\n specgate questions [--project-dir <path>] [--json]\n\n" +
87
+ "Everything waiting for an answer: the open questions of every open change and of\n" +
88
+ "docs/specs/questions.md, with what each blocks, and the requirements in\n" +
89
+ "Needs Clarification no open question names. Answer with specgate answer.\n");
90
+ process.exit(0);
91
+ }
92
+ const shape = { questions: null };
93
+ const io = (0, agent_1.agentIo)((0, agent_1.wantsJson)(argv));
94
+ const p = parse(argv, io, shape, "questions");
95
+ const dir = project(p.dir, io, shape);
96
+ const w = (0, clarification_1.waiting)(dir);
97
+ io.emit({
98
+ questions: {
99
+ open: w.questions.map((q) => ({
100
+ id: q.id,
101
+ change: q.change,
102
+ text: q.text,
103
+ blocks: q.blocks,
104
+ file: q.file,
105
+ line: q.line,
106
+ })),
107
+ waitingWithoutQuestion: w.requirements,
108
+ },
109
+ }, () => {
110
+ process.stdout.write(ui.header("questions"));
111
+ if (w.questions.length === 0 && w.requirements.length === 0) {
112
+ process.stdout.write(ui.ok("Nothing waits for an answer.") + "\n");
113
+ return;
114
+ }
115
+ for (const q of w.questions) {
116
+ process.stdout.write(` ${q.id} ${ui.muted(q.change)} ${q.text}\n` +
117
+ ` ${ui.muted(q.blocks.length ? `blocks ${q.blocks.join(", ")}` : "blocks nothing")}` +
118
+ ` ${ui.muted(`→ specgate answer ${q.id} "…"${q.change !== "project" ? ` --change ${q.change}` : ""}`)}\n`);
119
+ }
120
+ if (w.requirements.length) {
121
+ process.stdout.write(`\n ${ui.muted("Needs Clarification with no open question:")}\n`);
122
+ for (const r of w.requirements) {
123
+ process.stdout.write(` ${r.requirement} ${r.title} ${ui.muted(`→ specgate ask ${r.requirement} "…"`)}\n`);
124
+ }
125
+ }
126
+ });
127
+ }
128
+ }
129
+ exports.QuestionsCommand = QuestionsCommand;
130
+ class AnswerCommand extends command_1.BaseCommand {
131
+ execute() {
132
+ const argv = this.args;
133
+ if (argv.includes("--help") || argv.includes("-h")) {
134
+ process.stdout.write('Usage:\n specgate answer <Q> "<answer>" [--change <id>] [--project-dir <path>] [--json]\n' +
135
+ " specgate answer <Q> --reviewed [--change <id>]\n\n" +
136
+ "Writes the answer into the question's row, adds it to assumptions.md as an\n" +
137
+ "assumption to review, and lists the requirements to revise. The draft checklist\n" +
138
+ "waits until --reviewed says the requirements reflect it. --change picks the\n" +
139
+ "change when more than one has that question.\n");
140
+ process.exit(0);
141
+ }
142
+ const shape = { answer: null };
143
+ const io = (0, agent_1.agentIo)((0, agent_1.wantsJson)(argv));
144
+ const p = parse(argv, io, shape, "answer");
145
+ const [id, ...rest] = p.words;
146
+ const text = rest.join(" ").trim();
147
+ if (!id || (!p.reviewed && !text)) {
148
+ io.usage(shape, [
149
+ (0, diagnostics_1.error)("missing_argument", 'answer needs a question id and the answer: specgate answer Q4 "…"', {
150
+ fix: "specgate questions lists the open ones.",
151
+ }),
152
+ ]);
153
+ }
154
+ const dir = project(p.dir, io, shape);
155
+ if (p.reviewed) {
156
+ const r = (0, clarification_1.reviewed)(dir, id, p.change);
157
+ if (!r.ok)
158
+ io.fail(shape, [(0, diagnostics_1.error)(r.code, r.message, { fix: "specgate questions" })]);
159
+ else
160
+ io.emit({ answer: { question: id, change: r.change, reviewed: r.ids } }, () => process.stdout.write(ui.ok(`${r.ids.join(", ")} decided — ${id}'s answer is in the specification.`) + "\n"));
161
+ return;
162
+ }
163
+ const r = (0, clarification_1.answer)(dir, id, text, p.change);
164
+ if (!r.ok) {
165
+ io.fail(shape, [
166
+ (0, diagnostics_1.error)(r.code, r.message, {
167
+ fix: r.changes && r.changes.length > 1 ? `--change ${r.changes[0]}` : "specgate questions",
168
+ }),
169
+ ]);
170
+ return;
171
+ }
172
+ io.emit({
173
+ answer: {
174
+ question: r.question,
175
+ change: r.change,
176
+ assumption: r.assumption,
177
+ revise: r.revise,
178
+ },
179
+ }, () => process.stdout.write(ui.ok(`${r.question} answered in ${r.change}; ${r.assumption} added to review.`) +
180
+ "\n" +
181
+ (r.revise.length
182
+ ? ` Revise ${r.revise.join(", ")} so they say it, then: specgate answer ${r.question} --reviewed\n`
183
+ : ` Then: specgate answer ${r.question} --reviewed\n`)));
184
+ }
185
+ }
186
+ exports.AnswerCommand = AnswerCommand;
187
+ class AskCommand extends command_1.BaseCommand {
188
+ execute() {
189
+ const argv = this.args;
190
+ if (argv.includes("--help") || argv.includes("-h")) {
191
+ process.stdout.write('Usage:\n specgate ask <REQ> "<question>" [--project-dir <path>] [--json]\n\n' +
192
+ "Asks instead of guessing: adds the question to the change that defines the\n" +
193
+ "requirement (docs/specs/questions.md when a capability does) and sets it\n" +
194
+ "Needs Clarification. Inside the harness it only records the question: the\n" +
195
+ "harness stops the requirement and writes it into the project.\n");
196
+ process.exit(0);
197
+ }
198
+ const shape = { ask: null };
199
+ const io = (0, agent_1.agentIo)((0, agent_1.wantsJson)(argv));
200
+ const p = parse(argv, io, shape, "ask");
201
+ const [req, ...rest] = p.words;
202
+ const text = rest.join(" ").trim();
203
+ if (!req || !/^REQ-\d+$/.test(req) || !text) {
204
+ io.usage(shape, [
205
+ (0, diagnostics_1.error)("missing_argument", 'ask needs a requirement and the question: specgate ask REQ-007 "…"', {
206
+ fix: "specgate ask --help",
207
+ }),
208
+ ]);
209
+ }
210
+ // Inside the harness the agent may not edit the specification: the
211
+ // question becomes an event, and the harness writes it (REQ-189).
212
+ const eventsFile = process.env[HarnessEvents_1.EVENTS_FILE_VAR];
213
+ if (eventsFile && process.env[HarnessEvents_1.EVENTS_REQ_VAR]) {
214
+ (0, harness_events_1.appendEvent)(eventsFile, { type: "question", text }, process.env[HarnessEvents_1.EVENTS_REQ_VAR] || req, Number(process.env[HarnessEvents_1.EVENTS_ATTEMPT_VAR]) || undefined);
215
+ io.emit({ ask: { requirement: req, recorded: "harness" } }, () => process.stdout.write(ui.ok(`Question recorded for ${req}. Stop here: the harness asks the person and ends this attempt.`) + "\n"));
216
+ return;
217
+ }
218
+ const dir = project(p.dir, io, shape);
219
+ const r = (0, clarification_1.ask)(dir, req, text);
220
+ if (!r.ok) {
221
+ io.fail(shape, [
222
+ (0, diagnostics_1.error)(r.code, r.message, { fix: "specgate status lists the requirements." }),
223
+ ]);
224
+ return;
225
+ }
226
+ io.emit({ ask: { requirement: req, change: r.change, question: r.question, file: r.file } }, () => process.stdout.write(ui.ok(`${r.question} added to ${r.file}; ${req} is Needs Clarification.`) +
227
+ "\n" +
228
+ ` Answer with: specgate answer ${r.question} "…"${r.change !== "project" ? ` --change ${r.change}` : ""}\n`));
229
+ }
230
+ }
231
+ exports.AskCommand = AskCommand;
232
+ class BriefAddCommand extends command_1.BaseCommand {
233
+ execute() {
234
+ const argv = this.args;
235
+ if (argv.includes("--help") || argv.includes("-h")) {
236
+ process.stdout.write('Usage:\n specgate brief add <module> "<text>" [--project-dir <path>] [--json]\n\n' +
237
+ "A new requirement for a module the brief lists: appends the line to the brief\n" +
238
+ "under Additions, and adds a requirement quoting it to the module's open change\n" +
239
+ "(draft-<module> or <module>-additions, created when there is none). Its title\n" +
240
+ "and statement are yours to write; specgate draft --check asks for them.\n");
241
+ process.exit(0);
242
+ }
243
+ const shape = { brief: null };
244
+ const io = (0, agent_1.agentIo)((0, agent_1.wantsJson)(argv));
245
+ const p = parse(argv, io, shape, "brief add");
246
+ const [module, ...rest] = p.words;
247
+ const text = rest.join(" ").trim();
248
+ if (!module || !text) {
249
+ io.usage(shape, [
250
+ (0, diagnostics_1.error)("missing_argument", 'brief add needs a module and the text: specgate brief add fichas "…"', {
251
+ fix: "specgate brief add --help",
252
+ }),
253
+ ]);
254
+ }
255
+ const dir = project(p.dir, io, shape);
256
+ const r = (0, brief_add_1.briefAdd)(dir, module, text, new Date().toISOString().slice(0, 10));
257
+ if (!r.ok) {
258
+ io.fail(shape, [(0, diagnostics_1.error)(r.code, r.message, { fix: r.fix })]);
259
+ return;
260
+ }
261
+ io.emit({
262
+ brief: {
263
+ module,
264
+ change: r.change,
265
+ requirement: r.requirement,
266
+ created: r.created,
267
+ delta: r.delta,
268
+ },
269
+ }, () => process.stdout.write(ui.ok(`${r.requirement} added to ${r.change}${r.created ? " (new change)" : ""}.`) +
270
+ "\n" +
271
+ ` Write its title, statement and a scenario in ${r.delta}, then: specgate draft --check ${r.change}\n`));
272
+ }
273
+ }
274
+ exports.BriefAddCommand = BriefAddCommand;
275
+ //# sourceMappingURL=ClarifyCommands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClarifyCommands.js","sourceRoot":"","sources":["../../../../../scripts/cli/commands/spec/ClarifyCommands.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,8 @@ const HARNESS_RULES = [
18
18
  ...(instructions_1.STAGES?.apply?.rules ?? []).filter((r) => !/is the queue|Close each requirement with `specgate apply/.test(r)),
19
19
  "Do not run `specgate` yourself: when you finish, the harness runs the gate and marks the " +
20
20
  "requirement. The `specgate` on your PATH may not even be this project's version.",
21
+ // REQ-189: the one command an agent runs — asking beats guessing.
22
+ 'The one exception: when the requirement leaves a decision open that its statement, scenarios and assumptions do not settle, do not guess. Run `specgate ask <REQ> "<your question>"` and stop: the harness ends the attempt without spending another and asks the person.',
21
23
  ];
22
24
  function buildPrompt(req, projectDir, opts = {}) {
23
25
  const repo = new DiskHarnessConfigRepository_1.DiskHarnessConfigRepository();
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../scripts/harness/prompt.ts"],"names":[],"mappings":";AAAA;;GAEG;;AA2BH,kCAYC;AArCD,yDAAgD;AAChD,oHAAiH;AACjH,+GAA4G;AAQ5G;;;;;;GAMG;AACH,MAAM,aAAa,GAAa;IAC9B,GAAG,CAAC,qBAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,0DAA0D,CAAC,IAAI,CAAC,CAAC,CAAC,CAC3E;IACD,2FAA2F;QACzF,kFAAkF;CACrF,CAAC;AAEF,SAAgB,WAAW,CACzB,GAA4B,EAC5B,UAAkB,EAClB,OAAsB,EAAE;IAExB,MAAM,IAAI,GAAG,IAAI,yDAA2B,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,uDAA0B,CAAC,IAAI,CAAC,CAAC;IAErD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAwB,EAAE,UAAU,EAAE;QAC3D,GAAG,IAAI;QACP,UAAU,EAAE,aAAa;KAC1B,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../scripts/harness/prompt.ts"],"names":[],"mappings":";AAAA;;GAEG;;AA6BH,kCAYC;AAvCD,yDAAgD;AAChD,oHAAiH;AACjH,+GAA4G;AAQ5G;;;;;;GAMG;AACH,MAAM,aAAa,GAAa;IAC9B,GAAG,CAAC,qBAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,0DAA0D,CAAC,IAAI,CAAC,CAAC,CAAC,CAC3E;IACD,2FAA2F;QACzF,kFAAkF;IACpF,kEAAkE;IAClE,2QAA2Q;CAC5Q,CAAC;AAEF,SAAgB,WAAW,CACzB,GAA4B,EAC5B,UAAkB,EAClB,OAAsB,EAAE;IAExB,MAAM,IAAI,GAAG,IAAI,yDAA2B,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,uDAA0B,CAAC,IAAI,CAAC,CAAC;IAErD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAwB,EAAE,UAAU,EAAE;QAC3D,GAAG,IAAI;QACP,UAAU,EAAE,aAAa;KAC1B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.briefAdd = briefAdd;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_child_process_1 = require("node:child_process");
40
+ const DraftChecklist_1 = require("../../packages/core/src/domain/DraftChecklist");
41
+ const ChangeWorkspace_1 = require("../../packages/core/src/infrastructure/ChangeWorkspace");
42
+ const project_root_1 = require("./project-root");
43
+ function briefFile(projectDir) {
44
+ for (const rel of [path.join("docs", "brief.md"), "brief.md"]) {
45
+ const file = path.join(projectDir, rel);
46
+ if (fs.existsSync(file))
47
+ return file;
48
+ }
49
+ return null;
50
+ }
51
+ function rangeOf(changeDir) {
52
+ try {
53
+ const yaml = fs.readFileSync(path.join(changeDir, "change.yaml"), "utf8");
54
+ const m = /req_range:\s*\[\s*REQ-(\d+)\s*,\s*REQ-(\d+)\s*\]/.exec(yaml);
55
+ return m ? [Number(m[1]), Number(m[2])] : null;
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ function idsIn(changeDir) {
62
+ const used = new Set();
63
+ const walk = (dir) => {
64
+ let entries = [];
65
+ try {
66
+ entries = fs.readdirSync(dir, { withFileTypes: true });
67
+ }
68
+ catch {
69
+ return;
70
+ }
71
+ for (const e of entries) {
72
+ const full = path.join(dir, e.name);
73
+ if (e.isDirectory())
74
+ walk(full);
75
+ else if (e.name.endsWith(".md")) {
76
+ for (const m of fs.readFileSync(full, "utf8").matchAll(/###\s+Requirement:\s+REQ-(\d+)/g)) {
77
+ used.add(Number(m[1]));
78
+ }
79
+ }
80
+ }
81
+ };
82
+ walk(path.join(changeDir, "specs"));
83
+ return used;
84
+ }
85
+ const pad = (n) => `REQ-${String(n).padStart(3, "0")}`;
86
+ /** The block `brief add` writes: a requirement whose title and statement are the author's to write. */
87
+ function block(id, text) {
88
+ return [
89
+ `### Requirement: ${id} — <a short name>`,
90
+ "",
91
+ "The system SHALL <what it does, from the brief line below>.",
92
+ "",
93
+ `> Brief: "${text.replace(/"/g, "'")}"`,
94
+ "",
95
+ "<!-- specgate:trace status=Draft kind=functional -->",
96
+ "",
97
+ ].join("\n");
98
+ }
99
+ function addToDelta(file, capability, req) {
100
+ if (!fs.existsSync(file)) {
101
+ fs.mkdirSync(path.dirname(file), { recursive: true });
102
+ fs.writeFileSync(file, `# Delta — ${capability}\n\n## ADDED Requirements\n\n${req}`, "utf8");
103
+ return;
104
+ }
105
+ const text = fs.readFileSync(file, "utf8").replace(/\r\n/g, "\n");
106
+ const at = text.indexOf("## ADDED Requirements");
107
+ if (at === -1) {
108
+ fs.writeFileSync(file, `${text.replace(/\n*$/, "\n")}\n## ADDED Requirements\n\n${req}`, "utf8");
109
+ return;
110
+ }
111
+ const after = text.slice(at + 3);
112
+ const next = after.search(/^## /m);
113
+ const end = next === -1 ? text.length : at + 3 + next;
114
+ const before = text.slice(0, end).replace(/\n*$/, "\n\n");
115
+ fs.writeFileSync(file, `${before}${req}${next === -1 ? "" : `\n${text.slice(end)}`}`, "utf8");
116
+ }
117
+ function briefAdd(projectDir, module, text, today) {
118
+ const brief = briefFile(projectDir);
119
+ if (!brief) {
120
+ return {
121
+ ok: false,
122
+ code: "brief_not_found",
123
+ message: "No brief: neither docs/brief.md nor brief.md exists.",
124
+ fix: "Write the brief first; specgate draft explains what it needs.",
125
+ };
126
+ }
127
+ const modules = (0, DraftChecklist_1.briefModules)(fs.readFileSync(brief, "utf8"));
128
+ if (!modules.includes(module)) {
129
+ return {
130
+ ok: false,
131
+ code: "brief_module_unknown",
132
+ message: `The brief lists no module "${module}". Its modules: ${modules.join(", ") || "none"}.`,
133
+ fix: "Use one of them, or add the module to the brief's front matter.",
134
+ };
135
+ }
136
+ const open = (0, ChangeWorkspace_1.listChangeIds)(projectDir);
137
+ let change = [`draft-${module}`, `${module}-additions`].find((c) => open.includes(c));
138
+ let created = false;
139
+ if (!change) {
140
+ change = `${module}-additions`;
141
+ const r = (0, node_child_process_1.spawnSync)(process.execPath, [
142
+ path.join((0, project_root_1.findCliRoot)(__dirname), "bin", "specgate.js"),
143
+ "change",
144
+ "new",
145
+ change,
146
+ "--reserve",
147
+ "3",
148
+ "--project-dir",
149
+ projectDir,
150
+ "--json",
151
+ ], { cwd: projectDir, encoding: "utf8" });
152
+ if (r.status !== 0) {
153
+ return {
154
+ ok: false,
155
+ code: "brief_change_not_created",
156
+ message: `Could not create ${change}: ${(r.stdout + r.stderr).trim().split("\n").pop()}`,
157
+ fix: `specgate change new ${change}`,
158
+ };
159
+ }
160
+ created = true;
161
+ }
162
+ const dir = path.join(projectDir, "docs", "specs", "changes", change);
163
+ const range = rangeOf(dir);
164
+ const used = idsIn(dir);
165
+ let id = null;
166
+ if (range) {
167
+ for (let n = range[0]; n <= range[1]; n += 1) {
168
+ if (!used.has(n)) {
169
+ id = n;
170
+ break;
171
+ }
172
+ }
173
+ }
174
+ if (id === null) {
175
+ return {
176
+ ok: false,
177
+ code: "brief_range_used_up",
178
+ message: `${change} has no free id left in its range${range ? ` ${pad(range[0])}…${pad(range[1])}` : ""}.`,
179
+ fix: `Grow it with specgate draft --reserve <n> when it is the last open draft, or open another change.`,
180
+ };
181
+ }
182
+ const delta = path.join(dir, "specs", module, "spec.md");
183
+ addToDelta(delta, module, block(pad(id), text));
184
+ const raw = fs.readFileSync(brief, "utf8");
185
+ const line = `- ${module} (${today}): ${text}`;
186
+ fs.writeFileSync(brief, /^## Additions\s*$/m.test(raw)
187
+ ? `${raw.replace(/\n*$/, "\n")}${line}\n`
188
+ : `${raw.replace(/\n*$/, "\n")}\n## Additions\n\n${line}\n`, "utf8");
189
+ return {
190
+ ok: true,
191
+ change,
192
+ requirement: pad(id),
193
+ created,
194
+ delta: path.relative(projectDir, delta).split(path.sep).join("/"),
195
+ };
196
+ }
197
+ //# sourceMappingURL=brief-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brief-add.js","sourceRoot":"","sources":["../../../scripts/lib/brief-add.ts"],"names":[],"mappings":"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"}