@rsaglobaltech/specgate 0.24.0 → 0.26.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/CHANGELOG.md +91 -42
- package/dist/packages/core/src/domain/AgentPrompt.js +12 -0
- package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -1
- package/dist/packages/core/src/domain/Clarification.js +178 -0
- package/dist/packages/core/src/domain/Clarification.js.map +1 -0
- package/dist/packages/core/src/domain/DraftChecklist.js +16 -16
- package/dist/packages/core/src/domain/DraftChecklist.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
- package/dist/packages/core/src/domain/RequirementPlan.js +11 -0
- package/dist/packages/core/src/domain/RequirementPlan.js.map +1 -1
- package/dist/packages/core/src/infrastructure/ChangeWorkspace.js +15 -3
- package/dist/packages/core/src/infrastructure/ChangeWorkspace.js.map +1 -1
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +5 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
- package/dist/packages/core/src/infrastructure/IdsAcrossBranches.js +4 -1
- package/dist/packages/core/src/infrastructure/IdsAcrossBranches.js.map +1 -1
- package/dist/packages/core/test/unit/clarification.test.js +161 -0
- package/dist/packages/core/test/unit/clarification.test.js.map +1 -0
- package/dist/packages/core/test/unit/rework.test.js +62 -0
- package/dist/packages/core/test/unit/rework.test.js.map +1 -0
- package/dist/scripts/answer.js +10 -0
- package/dist/scripts/answer.js.map +1 -0
- package/dist/scripts/ask.js +10 -0
- package/dist/scripts/ask.js.map +1 -0
- package/dist/scripts/brief_add.js +10 -0
- package/dist/scripts/brief_add.js.map +1 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js +124 -1
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/harness/RunCommand.js +135 -5
- package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/ClarifyCommands.js +275 -0
- package/dist/scripts/cli/commands/spec/ClarifyCommands.js.map +1 -0
- package/dist/scripts/cli/commands/spec/DraftCommand.js +44 -4
- package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StatusCommand.js +5 -1
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js +194 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
- package/dist/scripts/docs/record-journey.js +1 -0
- package/dist/scripts/docs/record-journey.js.map +1 -1
- package/dist/scripts/docs/record-terminal.js +18 -0
- package/dist/scripts/docs/record-terminal.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +11 -1
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/harness/prompt.js +2 -0
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/lib/brief-add.js +197 -0
- package/dist/scripts/lib/brief-add.js.map +1 -0
- package/dist/scripts/lib/change-impact.js +156 -0
- package/dist/scripts/lib/change-impact.js.map +1 -0
- package/dist/scripts/lib/change-review.js +145 -0
- package/dist/scripts/lib/change-review.js.map +1 -0
- package/dist/scripts/lib/clarification.js +319 -0
- package/dist/scripts/lib/clarification.js.map +1 -0
- package/dist/scripts/lib/harness-guard.js +18 -0
- package/dist/scripts/lib/harness-guard.js.map +1 -1
- package/dist/scripts/lib/in-flight.js +17 -11
- package/dist/scripts/lib/in-flight.js.map +1 -1
- package/dist/scripts/lib/live-detail.js +3 -2
- package/dist/scripts/lib/live-detail.js.map +1 -1
- package/dist/scripts/lib/live-model.js +35 -4
- package/dist/scripts/lib/live-model.js.map +1 -1
- package/dist/scripts/lib/live-page.js +80 -15
- package/dist/scripts/lib/live-page.js.map +1 -1
- package/dist/scripts/lib/screen-requirements.js +149 -0
- package/dist/scripts/lib/screen-requirements.js.map +1 -0
- package/dist/scripts/lib/studio-app-page.js +960 -0
- package/dist/scripts/lib/studio-app-page.js.map +1 -0
- package/dist/scripts/lib/studio-app.js +362 -0
- package/dist/scripts/lib/studio-app.js.map +1 -0
- package/dist/scripts/lib/studio-route.js +933 -0
- package/dist/scripts/lib/studio-route.js.map +1 -0
- package/dist/scripts/lib/surface.js +52 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/questions.js +10 -0
- package/dist/scripts/questions.js.map +1 -0
- package/package.json +1 -1
- package/templates/harness/harness.config.yaml.tpl +10 -1
|
@@ -0,0 +1,156 @@
|
|
|
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.requirementImpact = requirementImpact;
|
|
37
|
+
exports.changedBy = changedBy;
|
|
38
|
+
exports.impactOf = impactOf;
|
|
39
|
+
const fs = __importStar(require("node:fs"));
|
|
40
|
+
const path = __importStar(require("node:path"));
|
|
41
|
+
const node_child_process_1 = require("node:child_process");
|
|
42
|
+
const live_detail_1 = require("./live-detail");
|
|
43
|
+
const ChangeWorkspace_1 = require("../../packages/core/src/infrastructure/ChangeWorkspace");
|
|
44
|
+
const HEADING = /^(?:###\s+Requirement:|#{2,3})\s+(REQ-\d+)\b/;
|
|
45
|
+
function specFiles(projectDir) {
|
|
46
|
+
const out = [];
|
|
47
|
+
const spec = path.join(projectDir, "spec.md");
|
|
48
|
+
if (fs.existsSync(spec))
|
|
49
|
+
out.push(spec);
|
|
50
|
+
const walk = (dir) => {
|
|
51
|
+
let entries = [];
|
|
52
|
+
try {
|
|
53
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const e of entries) {
|
|
59
|
+
const full = path.join(dir, e.name);
|
|
60
|
+
if (e.isDirectory() && e.name !== "archive")
|
|
61
|
+
walk(full);
|
|
62
|
+
else if (e.name === "spec.md")
|
|
63
|
+
out.push(full);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
walk(path.join(projectDir, "docs", "specs"));
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/** The requirements whose statement or scenarios name `id`, other than itself. */
|
|
70
|
+
function namedBy(projectDir, id) {
|
|
71
|
+
const found = new Set();
|
|
72
|
+
const named = new RegExp(`(^|[^\\w-])${id}(?!\\d)`);
|
|
73
|
+
for (const file of specFiles(projectDir)) {
|
|
74
|
+
let current = null;
|
|
75
|
+
for (const line of fs.readFileSync(file, "utf8").split(/\r?\n/)) {
|
|
76
|
+
const h = HEADING.exec(line);
|
|
77
|
+
if (h) {
|
|
78
|
+
current = h[1];
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (current && current !== id && !line.includes("specgate:trace") && named.test(line)) {
|
|
82
|
+
found.add(current);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return [...found].sort();
|
|
87
|
+
}
|
|
88
|
+
/** The files the commits naming `id` changed, outside the specification. */
|
|
89
|
+
function filesOf(projectDir, id) {
|
|
90
|
+
const r = (0, node_child_process_1.spawnSync)("git", ["log", "-E", `--grep=${id}([^0-9]|$)`, "--name-only", "--format="], {
|
|
91
|
+
cwd: projectDir,
|
|
92
|
+
encoding: "utf8",
|
|
93
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
94
|
+
});
|
|
95
|
+
if (r.status !== 0)
|
|
96
|
+
return [];
|
|
97
|
+
return [
|
|
98
|
+
...new Set(r.stdout
|
|
99
|
+
.split("\n")
|
|
100
|
+
.map((l) => l.trim())
|
|
101
|
+
.filter(Boolean)
|
|
102
|
+
.filter((f) => !/^(docs\/specs\/|features\/|spec\.md$)/.test(f))),
|
|
103
|
+
].sort();
|
|
104
|
+
}
|
|
105
|
+
/** Feature files named after the requirement, as `archive` writes them: features/<area>/<REQ>.feature. */
|
|
106
|
+
function featuresNamed(projectDir, id) {
|
|
107
|
+
const out = [];
|
|
108
|
+
const root = path.join(projectDir, "features");
|
|
109
|
+
let areas = [];
|
|
110
|
+
try {
|
|
111
|
+
areas = fs.readdirSync(root, { withFileTypes: true });
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
for (const a of areas) {
|
|
117
|
+
if (a.isDirectory() && fs.existsSync(path.join(root, a.name, `${id}.feature`))) {
|
|
118
|
+
out.push(`features/${a.name}/${id}.feature`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
function requirementImpact(projectDir, id) {
|
|
124
|
+
const d = (0, live_detail_1.requirementDetail)(projectDir, id);
|
|
125
|
+
return {
|
|
126
|
+
requirement: id,
|
|
127
|
+
spec: d.source || null,
|
|
128
|
+
features: [...new Set([...(d.features || []), ...featuresNamed(projectDir, id)])].sort(),
|
|
129
|
+
tests: d.tests || [],
|
|
130
|
+
files: filesOf(projectDir, id),
|
|
131
|
+
namedBy: namedBy(projectDir, id),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** The requirements a change modifies or removes, in id order. */
|
|
135
|
+
function changedBy(projectDir, change) {
|
|
136
|
+
const ids = new Set();
|
|
137
|
+
for (const d of (0, ChangeWorkspace_1.listDeltas)(projectDir, change)) {
|
|
138
|
+
const text = fs.readFileSync(d.file, "utf8");
|
|
139
|
+
for (const section of text.split(/^## /m)) {
|
|
140
|
+
if (!/^(MODIFIED|REMOVED|RENAMED) Requirements/.test(section))
|
|
141
|
+
continue;
|
|
142
|
+
for (const m of section.matchAll(/^###\s+Requirement:\s+(REQ-\d+)/gm))
|
|
143
|
+
ids.add(m[1]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return [...ids].sort();
|
|
147
|
+
}
|
|
148
|
+
/** The impact of a requirement, or of each requirement a change modifies or removes. */
|
|
149
|
+
function impactOf(projectDir, target) {
|
|
150
|
+
if (/^REQ-\d+$/.test(target))
|
|
151
|
+
return [requirementImpact(projectDir, target)];
|
|
152
|
+
if (!(0, ChangeWorkspace_1.listChangeIds)(projectDir).includes(target))
|
|
153
|
+
return null;
|
|
154
|
+
return changedBy(projectDir, target).map((id) => requirementImpact(projectDir, id));
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=change-impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-impact.js","sourceRoot":"","sources":["../../../scripts/lib/change-impact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
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.approvedOn = approvedOn;
|
|
37
|
+
exports.approvalBlockers = approvalBlockers;
|
|
38
|
+
exports.approveChange = approveChange;
|
|
39
|
+
exports.reviewNotes = reviewNotes;
|
|
40
|
+
exports.noteChange = noteChange;
|
|
41
|
+
const fs = __importStar(require("node:fs"));
|
|
42
|
+
const path = __importStar(require("node:path"));
|
|
43
|
+
const Clarification_1 = require("../../packages/core/src/domain/Clarification");
|
|
44
|
+
const DraftCommand_1 = require("../cli/commands/spec/DraftCommand");
|
|
45
|
+
/**
|
|
46
|
+
* A person's review of a draft change (REQ-206, REQ-207): approving it, which
|
|
47
|
+
* Build waits for, and asking for a change in their own words.
|
|
48
|
+
*/
|
|
49
|
+
const CHANGES = path.join("docs", "specs", "changes");
|
|
50
|
+
function changeDir(projectDir, id) {
|
|
51
|
+
return path.join(projectDir, CHANGES, id);
|
|
52
|
+
}
|
|
53
|
+
function read(file) {
|
|
54
|
+
try {
|
|
55
|
+
return fs.readFileSync(file, "utf8");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** When a person approved the change, or "" when nobody has. */
|
|
62
|
+
function approvedOn(projectDir, id) {
|
|
63
|
+
const yaml = read(path.join(changeDir(projectDir, id), "change.yaml")) || "";
|
|
64
|
+
return (/^approved:\s*(\S+)/m.exec(yaml) || [])[1] || "";
|
|
65
|
+
}
|
|
66
|
+
/** What stops a change from being approved: checklist errors and open questions. */
|
|
67
|
+
function approvalBlockers(projectDir, id) {
|
|
68
|
+
const out = [];
|
|
69
|
+
const r = (0, DraftCommand_1.draftReport)(projectDir, id);
|
|
70
|
+
if ("failure" in r) {
|
|
71
|
+
out.push({ code: r.failure.code, message: r.failure.message });
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
for (const d of r.report.status) {
|
|
75
|
+
if (d.severity === "error")
|
|
76
|
+
out.push({ code: d.code, message: d.message });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const questions = read(path.join(changeDir(projectDir, id), "questions.md"));
|
|
80
|
+
for (const q of questions ? (0, Clarification_1.questionTable)(questions) : []) {
|
|
81
|
+
if (!q.answered && !out.some((b) => b.message.includes(q.id))) {
|
|
82
|
+
out.push({ code: "approve_question_open", message: `${q.id} is open: ${q.text}` });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/** Record that a person approved the change (REQ-206). */
|
|
88
|
+
function approveChange(projectDir, id, today) {
|
|
89
|
+
const file = path.join(changeDir(projectDir, id), "change.yaml");
|
|
90
|
+
if (!fs.existsSync(changeDir(projectDir, id))) {
|
|
91
|
+
return { ok: false, code: "change_not_found", message: `No open change ${id}.` };
|
|
92
|
+
}
|
|
93
|
+
const blockers = approvalBlockers(projectDir, id);
|
|
94
|
+
if (blockers.length) {
|
|
95
|
+
return {
|
|
96
|
+
ok: false,
|
|
97
|
+
code: "approve_blocked",
|
|
98
|
+
message: `${id} cannot be approved yet: ${blockers.map((b) => b.message).join("; ")}`,
|
|
99
|
+
blockers,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const yaml = read(file) || "";
|
|
103
|
+
const next = /^approved:/m.test(yaml)
|
|
104
|
+
? yaml.replace(/^approved:.*$/m, `approved: ${today}`)
|
|
105
|
+
: `${yaml.replace(/\n*$/, "\n")}approved: ${today}\n`;
|
|
106
|
+
fs.writeFileSync(file, next, "utf8");
|
|
107
|
+
return { ok: true, change: id, approved: today };
|
|
108
|
+
}
|
|
109
|
+
const NOTES_HEADER = "| Date | Requirement | Request |";
|
|
110
|
+
function cell(text) {
|
|
111
|
+
return String(text).replace(/\s+/g, " ").trim().replace(/\|/g, "\\|");
|
|
112
|
+
}
|
|
113
|
+
/** The change's review notes. */
|
|
114
|
+
function reviewNotes(projectDir, id) {
|
|
115
|
+
const md = read(path.join(changeDir(projectDir, id), "review.md")) || "";
|
|
116
|
+
return md
|
|
117
|
+
.split(/\r?\n/)
|
|
118
|
+
.filter((l) => /^\|\s*\d{4}-\d{2}-\d{2}\s*\|/.test(l))
|
|
119
|
+
.map((l) => {
|
|
120
|
+
const c = l
|
|
121
|
+
.split(/(?<!\\)\|/)
|
|
122
|
+
.slice(1, -1)
|
|
123
|
+
.map((x) => x.trim());
|
|
124
|
+
return {
|
|
125
|
+
date: c[0],
|
|
126
|
+
requirement: c[1] === "—" ? "" : c[1],
|
|
127
|
+
text: (c[2] || "").replace(/\\\|/g, "|"),
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/** Ask the draft for a change in your own words (REQ-207). */
|
|
132
|
+
function noteChange(projectDir, id, text, requirement, today) {
|
|
133
|
+
if (!fs.existsSync(changeDir(projectDir, id))) {
|
|
134
|
+
return { ok: false, code: "change_not_found", message: `No open change ${id}.` };
|
|
135
|
+
}
|
|
136
|
+
if (!text.trim())
|
|
137
|
+
return { ok: false, code: "note_empty", message: "The request is empty." };
|
|
138
|
+
const file = path.join(changeDir(projectDir, id), "review.md");
|
|
139
|
+
const md = read(file) ||
|
|
140
|
+
`# Review — ${id}\n\nWhat the person reviewing this draft asked to change.\n\n${NOTES_HEADER}\n|---|---|---|\n`;
|
|
141
|
+
const row = `| ${today} | ${requirement || "—"} | ${cell(text)} |`;
|
|
142
|
+
fs.writeFileSync(file, `${md.replace(/\n*$/, "\n")}${row}\n`, "utf8");
|
|
143
|
+
return { ok: true, change: id, notes: reviewNotes(projectDir, id).length };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=change-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-review.js","sourceRoot":"","sources":["../../../scripts/lib/change-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,319 @@
|
|
|
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.PROJECT = void 0;
|
|
37
|
+
exports.allQuestions = allQuestions;
|
|
38
|
+
exports.waiting = waiting;
|
|
39
|
+
exports.answer = answer;
|
|
40
|
+
exports.reviewed = reviewed;
|
|
41
|
+
exports.definedIn = definedIn;
|
|
42
|
+
exports.setWaiting = setWaiting;
|
|
43
|
+
exports.setStatusIn = setStatusIn;
|
|
44
|
+
exports.ask = ask;
|
|
45
|
+
const fs = __importStar(require("node:fs"));
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const Clarification_1 = require("../../packages/core/src/domain/Clarification");
|
|
48
|
+
const ChangeWorkspace_1 = require("../../packages/core/src/infrastructure/ChangeWorkspace");
|
|
49
|
+
const live_detail_1 = require("./live-detail");
|
|
50
|
+
const MatrixCommand_1 = require("../cli/commands/spec/MatrixCommand");
|
|
51
|
+
/**
|
|
52
|
+
* Questions and answers on disk (REQ-187..189): each open change's
|
|
53
|
+
* `questions.md` and `assumptions.md`, and the project's own
|
|
54
|
+
* `docs/specs/questions.md` for requirements a capability already defines.
|
|
55
|
+
*/
|
|
56
|
+
/** The change a project-level question belongs to, as `questions` prints it. */
|
|
57
|
+
exports.PROJECT = "project";
|
|
58
|
+
const PROJECT_QUESTIONS = path.join("docs", "specs", "questions.md");
|
|
59
|
+
const PROJECT_ASSUMPTIONS = path.join("docs", "specs", "assumptions.md");
|
|
60
|
+
function changeDir(projectDir, change) {
|
|
61
|
+
return path.join(projectDir, "docs", "specs", "changes", change);
|
|
62
|
+
}
|
|
63
|
+
function questionsFile(projectDir, change) {
|
|
64
|
+
return change === exports.PROJECT
|
|
65
|
+
? path.join(projectDir, PROJECT_QUESTIONS)
|
|
66
|
+
: path.join(changeDir(projectDir, change), "questions.md");
|
|
67
|
+
}
|
|
68
|
+
function assumptionsFile(projectDir, change) {
|
|
69
|
+
return change === exports.PROJECT
|
|
70
|
+
? path.join(projectDir, PROJECT_ASSUMPTIONS)
|
|
71
|
+
: path.join(changeDir(projectDir, change), "assumptions.md");
|
|
72
|
+
}
|
|
73
|
+
function read(file) {
|
|
74
|
+
try {
|
|
75
|
+
return fs.readFileSync(file, "utf8");
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function write(file, text) {
|
|
82
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
83
|
+
fs.writeFileSync(file, text.endsWith("\n") ? text : `${text}\n`, "utf8");
|
|
84
|
+
}
|
|
85
|
+
/** Every question of every open change, and of the project. */
|
|
86
|
+
function allQuestions(projectDir) {
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const change of [...(0, ChangeWorkspace_1.listChangeIds)(projectDir), exports.PROJECT]) {
|
|
89
|
+
const file = questionsFile(projectDir, change);
|
|
90
|
+
const md = read(file);
|
|
91
|
+
if (!md)
|
|
92
|
+
continue;
|
|
93
|
+
for (const q of (0, Clarification_1.questionTable)(md)) {
|
|
94
|
+
out.push({ ...q, change, file: path.relative(projectDir, file).split(path.sep).join("/") });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/** What waits for an answer: open questions, and requirements in Needs Clarification no open question names. */
|
|
100
|
+
function waiting(projectDir) {
|
|
101
|
+
const questions = allQuestions(projectDir).filter((q) => !q.answered);
|
|
102
|
+
const named = new Set(questions.flatMap((q) => q.blocks));
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
const requirements = [];
|
|
105
|
+
for (const row of (0, live_detail_1.liveMatrix)(projectDir)) {
|
|
106
|
+
if (row.status !== "Needs Clarification" || named.has(row.requirement))
|
|
107
|
+
continue;
|
|
108
|
+
if (seen.has(row.requirement))
|
|
109
|
+
continue;
|
|
110
|
+
seen.add(row.requirement);
|
|
111
|
+
requirements.push({ requirement: row.requirement, title: row.title });
|
|
112
|
+
}
|
|
113
|
+
return { questions, requirements };
|
|
114
|
+
}
|
|
115
|
+
/** The changes that have a question with this id. */
|
|
116
|
+
function changesWith(projectDir, id) {
|
|
117
|
+
return [
|
|
118
|
+
...new Set(allQuestions(projectDir)
|
|
119
|
+
.filter((q) => q.id === id)
|
|
120
|
+
.map((q) => q.change)),
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
function pickChange(projectDir, id, change) {
|
|
124
|
+
const found = changesWith(projectDir, id);
|
|
125
|
+
if (change) {
|
|
126
|
+
if (!found.includes(change)) {
|
|
127
|
+
return {
|
|
128
|
+
ok: false,
|
|
129
|
+
code: "question_not_found",
|
|
130
|
+
message: `${change} has no question ${id}.`,
|
|
131
|
+
changes: found,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return change;
|
|
135
|
+
}
|
|
136
|
+
if (found.length === 0) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
code: "question_not_found",
|
|
140
|
+
message: `No open change has a question ${id}.`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (found.length > 1) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
code: "question_ambiguous",
|
|
147
|
+
message: `${found.length} changes have a question ${id}: ${found.join(", ")}. Say which with --change.`,
|
|
148
|
+
changes: found,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return found[0];
|
|
152
|
+
}
|
|
153
|
+
/** Write the answer, add its assumption to review, and say which requirements to revise (REQ-188). */
|
|
154
|
+
function answer(projectDir, id, text, change) {
|
|
155
|
+
const picked = pickChange(projectDir, id, change);
|
|
156
|
+
if (typeof picked !== "string")
|
|
157
|
+
return picked;
|
|
158
|
+
const qFile = questionsFile(projectDir, picked);
|
|
159
|
+
const written = (0, Clarification_1.answerQuestion)(read(qFile) || "", id, text);
|
|
160
|
+
if (!written.ok) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
code: written.code,
|
|
164
|
+
message: written.code === "answer_deferred"
|
|
165
|
+
? `"${text}" puts the decision off; an answer decides. Answer when it is decided.`
|
|
166
|
+
: `${picked} has no question ${id}.`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const aFile = assumptionsFile(projectDir, picked);
|
|
170
|
+
const added = (0, Clarification_1.addAssumption)(read(aFile), picked, {
|
|
171
|
+
text,
|
|
172
|
+
usedIn: written.blocks,
|
|
173
|
+
why: id,
|
|
174
|
+
});
|
|
175
|
+
write(qFile, written.md);
|
|
176
|
+
write(aFile, added.md);
|
|
177
|
+
return { ok: true, change: picked, question: id, assumption: added.id, revise: written.blocks };
|
|
178
|
+
}
|
|
179
|
+
/** Mark the question's assumptions reviewed: the spec reflects the answer (REQ-188). */
|
|
180
|
+
function reviewed(projectDir, id, change) {
|
|
181
|
+
const picked = pickChange(projectDir, id, change);
|
|
182
|
+
if (typeof picked !== "string")
|
|
183
|
+
return picked;
|
|
184
|
+
const aFile = assumptionsFile(projectDir, picked);
|
|
185
|
+
const r = (0, Clarification_1.reviewAssumptions)(read(aFile) || "", id);
|
|
186
|
+
if (r.ids.length === 0) {
|
|
187
|
+
return {
|
|
188
|
+
ok: false,
|
|
189
|
+
code: "nothing_to_review",
|
|
190
|
+
message: `No assumption from ${id} is waiting for review in ${picked}.`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
write(aFile, r.md);
|
|
194
|
+
// The decision is in the spec: what waited only for this question can be
|
|
195
|
+
// built again (REQ-210). Another open question still holds its own.
|
|
196
|
+
const all = allQuestions(projectDir);
|
|
197
|
+
const blocks = (all.find((q) => q.id === id && q.change === picked) || { blocks: [] }).blocks;
|
|
198
|
+
const stillHeld = new Set(all.filter((q) => !q.answered).flatMap((q) => q.blocks));
|
|
199
|
+
const status = new Map((0, live_detail_1.liveMatrix)(projectDir).map((m) => [m.requirement, m.status]));
|
|
200
|
+
for (const req of blocks) {
|
|
201
|
+
if (stillHeld.has(req) || status.get(req) !== "Needs Clarification")
|
|
202
|
+
continue;
|
|
203
|
+
const where = definedIn(projectDir, req);
|
|
204
|
+
if (where)
|
|
205
|
+
setStatusIn(where.file, projectDir, req, "Draft");
|
|
206
|
+
}
|
|
207
|
+
return { ok: true, change: picked, ids: r.ids };
|
|
208
|
+
}
|
|
209
|
+
/** Where a requirement is defined: the open change that adds or modifies it, or the capability spec. */
|
|
210
|
+
function definedIn(projectDir, req) {
|
|
211
|
+
const heading = new RegExp(`^###\\s+Requirement:\\s+${req}\\b`, "m");
|
|
212
|
+
for (const change of (0, ChangeWorkspace_1.listChangeIds)(projectDir)) {
|
|
213
|
+
const specs = path.join(changeDir(projectDir, change), "specs");
|
|
214
|
+
for (const cap of safeDirs(specs)) {
|
|
215
|
+
const file = path.join(specs, cap, "spec.md");
|
|
216
|
+
if (heading.test(read(file) || ""))
|
|
217
|
+
return { change, file };
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const caps = path.join(projectDir, "docs", "specs", "capabilities");
|
|
221
|
+
for (const cap of safeDirs(caps)) {
|
|
222
|
+
const file = path.join(caps, cap, "spec.md");
|
|
223
|
+
if (heading.test(read(file) || ""))
|
|
224
|
+
return { change: exports.PROJECT, file };
|
|
225
|
+
}
|
|
226
|
+
const spec = path.join(projectDir, "spec.md");
|
|
227
|
+
if (new RegExp(`^#{2,3}\\s+${req}\\b`, "m").test(read(spec) || ""))
|
|
228
|
+
return { change: exports.PROJECT, file: spec };
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* A requirement of `spec.md` keeps its status in tables — the summary in
|
|
233
|
+
* `spec.md` and the matrix — whose last cell is the status: set both.
|
|
234
|
+
*/
|
|
235
|
+
function setStatusInTables(projectDir, req, status) {
|
|
236
|
+
let done = false;
|
|
237
|
+
for (const rel of ["spec.md", path.join("docs", "specs", "traceability.md")]) {
|
|
238
|
+
const file = path.join(projectDir, rel);
|
|
239
|
+
const text = read(file);
|
|
240
|
+
if (!text)
|
|
241
|
+
continue;
|
|
242
|
+
const row = new RegExp(`^(\\|\\s*${req}\\s*\\|.*\\|)\\s*[^|]+?\\s*\\|\\s*$`, "gm");
|
|
243
|
+
const next = text.replace(row, (_m, head) => `${head} ${status} |`);
|
|
244
|
+
if (next !== text) {
|
|
245
|
+
write(file, next);
|
|
246
|
+
done = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return done;
|
|
250
|
+
}
|
|
251
|
+
function safeDirs(dir) {
|
|
252
|
+
try {
|
|
253
|
+
return fs
|
|
254
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
255
|
+
.filter((e) => e.isDirectory())
|
|
256
|
+
.map((e) => e.name);
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* The requirement's trace status set to Needs Clarification in the file that
|
|
264
|
+
* defines it, and the derived matrix refreshed. `apply` writes only the
|
|
265
|
+
* statuses a delivery moves through, and this one is not.
|
|
266
|
+
*/
|
|
267
|
+
function setWaiting(file, projectDir, req) {
|
|
268
|
+
return setStatusIn(file, projectDir, req, "Needs Clarification");
|
|
269
|
+
}
|
|
270
|
+
/** The requirement's trace status set in the file that defines it, the matrix refreshed. */
|
|
271
|
+
function setStatusIn(file, projectDir, req, status) {
|
|
272
|
+
const value = /\s/.test(status) ? `"${status}"` : status;
|
|
273
|
+
if (path.basename(file) === "spec.md" && path.dirname(file) === projectDir) {
|
|
274
|
+
return setStatusInTables(projectDir, req, status);
|
|
275
|
+
}
|
|
276
|
+
const lines = (read(file) || "").split("\n");
|
|
277
|
+
const head = new RegExp(`^(?:###\\s+Requirement:|##)\\s+${req}\\b`);
|
|
278
|
+
const start = lines.findIndex((l) => head.test(l));
|
|
279
|
+
if (start === -1)
|
|
280
|
+
return false;
|
|
281
|
+
for (let i = start + 1; i < lines.length && !/^#{2,3}\s(?!#)/.test(lines[i]); i += 1) {
|
|
282
|
+
if (!/<!--\s*specgate:trace\b/.test(lines[i]))
|
|
283
|
+
continue;
|
|
284
|
+
lines[i] = /\bstatus=/.test(lines[i])
|
|
285
|
+
? lines[i].replace(/\bstatus=(?:"[^"]*"|[^\s"]+?)(?=\s|-->)/, `status=${value}`)
|
|
286
|
+
: lines[i].replace(/<!--\s*specgate:trace/, `<!-- specgate:trace status=${value}`);
|
|
287
|
+
write(file, lines.join("\n"));
|
|
288
|
+
try {
|
|
289
|
+
(0, MatrixCommand_1.refreshDerivedMatrix)(projectDir);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
/* the next validate refreshes it */
|
|
293
|
+
}
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
/** Add the question to where the requirement is defined, and set it waiting (REQ-189). */
|
|
299
|
+
function ask(projectDir, req, text) {
|
|
300
|
+
const where = definedIn(projectDir, req);
|
|
301
|
+
if (!where) {
|
|
302
|
+
return {
|
|
303
|
+
ok: false,
|
|
304
|
+
code: "requirement_not_found",
|
|
305
|
+
message: `${req} is not defined by an open change or a capability spec.`,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
const qFile = questionsFile(projectDir, where.change);
|
|
309
|
+
const added = (0, Clarification_1.addQuestion)(read(qFile), where.change, text, [req]);
|
|
310
|
+
write(qFile, added.md);
|
|
311
|
+
setWaiting(where.file, projectDir, req);
|
|
312
|
+
return {
|
|
313
|
+
ok: true,
|
|
314
|
+
change: where.change,
|
|
315
|
+
question: added.id,
|
|
316
|
+
file: path.relative(projectDir, qFile).split(path.sep).join("/"),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=clarification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarification.js","sourceRoot":"","sources":["../../../scripts/lib/clarification.ts"],"names":[],"mappings":"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"}
|