@rsaglobaltech/specgate 0.27.9 → 1.0.0-rc.2
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 +57 -0
- package/dist/packages/core/src/application/ValidateChangeUseCase.js +19 -3
- package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -1
- package/dist/packages/core/src/domain/ApiContract.js +157 -0
- package/dist/packages/core/src/domain/ApiContract.js.map +1 -0
- package/dist/packages/core/src/domain/Approvals.js +127 -0
- package/dist/packages/core/src/domain/Approvals.js.map +1 -0
- package/dist/packages/core/src/domain/ChangeLayers.js +285 -0
- package/dist/packages/core/src/domain/ChangeLayers.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessGaps.js +182 -0
- package/dist/packages/core/src/domain/HarnessGaps.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessReport.js +16 -1
- package/dist/packages/core/src/domain/HarnessReport.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
- package/dist/packages/core/src/domain/Principles.js +119 -0
- package/dist/packages/core/src/domain/Principles.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementGraph.js +12 -1
- package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -1
- package/dist/packages/core/src/domain/Workspace.js +150 -0
- package/dist/packages/core/src/domain/Workspace.js.map +1 -0
- package/dist/packages/core/src/domain/WorkspaceStory.js +176 -0
- package/dist/packages/core/src/domain/WorkspaceStory.js.map +1 -0
- package/dist/packages/core/src/index.js +1 -0
- package/dist/packages/core/src/index.js.map +1 -1
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +12 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
- package/dist/packages/mcp-spec-driven/src/tools.js +18 -0
- package/dist/packages/mcp-spec-driven/src/tools.js.map +1 -1
- package/dist/scripts/alm/cli.js +45 -4
- package/dist/scripts/alm/cli.js.map +1 -1
- package/dist/scripts/alm/clients.js +3 -1
- package/dist/scripts/alm/clients.js.map +1 -1
- package/dist/scripts/alm/phases.js +279 -0
- package/dist/scripts/alm/phases.js.map +1 -0
- package/dist/scripts/alm/port.js +33 -5
- package/dist/scripts/alm/port.js.map +1 -1
- package/dist/scripts/alm/providers/azure.js +72 -11
- package/dist/scripts/alm/providers/azure.js.map +1 -1
- package/dist/scripts/alm/providers/github.js +67 -7
- package/dist/scripts/alm/providers/github.js.map +1 -1
- package/dist/scripts/alm/providers/index.js +8 -2
- package/dist/scripts/alm/providers/index.js.map +1 -1
- package/dist/scripts/alm/providers/jira.js +86 -8
- package/dist/scripts/alm/providers/jira.js.map +1 -1
- package/dist/scripts/alm/providers/linear.js +167 -0
- package/dist/scripts/alm/providers/linear.js.map +1 -0
- package/dist/scripts/change/artifacts.js +15 -1
- package/dist/scripts/change/artifacts.js.map +1 -1
- package/dist/scripts/change/instructions.js +47 -5
- package/dist/scripts/change/instructions.js.map +1 -1
- package/dist/scripts/cli/commands/alm/PhaseCommand.js +153 -0
- package/dist/scripts/cli/commands/alm/PhaseCommand.js.map +1 -0
- package/dist/scripts/cli/commands/alm/PullCommand.js +33 -2
- package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -1
- package/dist/scripts/cli/commands/alm/pull-back.js +104 -0
- package/dist/scripts/cli/commands/alm/pull-back.js.map +1 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js +149 -15
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/change/TicketCommand.js +20 -7
- package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
- package/dist/scripts/cli/commands/harness/RunCommand.js +64 -20
- package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/AdoptCommand.js +44 -4
- package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/InitProjectCommand.js +9 -14
- package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/MigrateCommand.js +166 -0
- package/dist/scripts/cli/commands/project/MigrateCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/OnboardCommand.js +23 -5
- package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/CheckCommand.js +25 -0
- package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +15 -0
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/ContractCommand.js +117 -0
- package/dist/scripts/cli/commands/spec/ContractCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/DoneCommand.js +22 -0
- package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/DraftCommand.js +22 -8
- package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/DriftCommand.js +128 -0
- package/dist/scripts/cli/commands/spec/DriftCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js +85 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js +48 -6
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js +612 -0
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js.map +1 -0
- package/dist/scripts/contract.js +10 -0
- package/dist/scripts/contract.js.map +1 -0
- package/dist/scripts/docs/nav.js +16 -1
- package/dist/scripts/docs/nav.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +6 -0
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/draft/ticket-guide.js +5 -0
- package/dist/scripts/draft/ticket-guide.js.map +1 -1
- package/dist/scripts/drift.js +10 -0
- package/dist/scripts/drift.js.map +1 -0
- package/dist/scripts/harness/gap-evidence.js +149 -0
- package/dist/scripts/harness/gap-evidence.js.map +1 -0
- package/dist/scripts/harness/prompt.js +54 -1
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/harness/report.js +104 -5
- package/dist/scripts/harness/report.js.map +1 -1
- package/dist/scripts/lib/approvals.js +243 -0
- package/dist/scripts/lib/approvals.js.map +1 -0
- package/dist/scripts/lib/change-review.js +19 -11
- package/dist/scripts/lib/change-review.js.map +1 -1
- package/dist/scripts/lib/contracts.js +211 -0
- package/dist/scripts/lib/contracts.js.map +1 -0
- package/dist/scripts/lib/drift.js +80 -0
- package/dist/scripts/lib/drift.js.map +1 -0
- package/dist/scripts/lib/live-model.js +1 -0
- package/dist/scripts/lib/live-model.js.map +1 -1
- package/dist/scripts/lib/migrate.js +264 -0
- package/dist/scripts/lib/migrate.js.map +1 -0
- package/dist/scripts/lib/role-packages.js +230 -0
- package/dist/scripts/lib/role-packages.js.map +1 -0
- package/dist/scripts/lib/steering.js +180 -0
- package/dist/scripts/lib/steering.js.map +1 -0
- package/dist/scripts/lib/studio-app-page.js +28 -5
- package/dist/scripts/lib/studio-app-page.js.map +1 -1
- package/dist/scripts/lib/studio-app.js +29 -0
- package/dist/scripts/lib/studio-app.js.map +1 -1
- package/dist/scripts/lib/studio-route.js +20 -0
- package/dist/scripts/lib/studio-route.js.map +1 -1
- package/dist/scripts/lib/surface.js +55 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/lib/workspace-draft.js +146 -0
- package/dist/scripts/lib/workspace-draft.js.map +1 -0
- package/dist/scripts/lib/workspace-live-page.js +90 -0
- package/dist/scripts/lib/workspace-live-page.js.map +1 -0
- package/dist/scripts/lib/workspace-live.js +199 -0
- package/dist/scripts/lib/workspace-live.js.map +1 -0
- package/dist/scripts/lib/workspace.js +619 -0
- package/dist/scripts/lib/workspace.js.map +1 -0
- package/dist/scripts/migrate.js +10 -0
- package/dist/scripts/migrate.js.map +1 -0
- package/dist/scripts/schema/registry.js +12 -0
- package/dist/scripts/schema/registry.js.map +1 -1
- package/dist/scripts/workspace.js +10 -0
- package/dist/scripts/workspace.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The organization's principles (REQ-330..332): `docs/specs/principles.md`,
|
|
4
|
+
* the version a repository follows, and the principles the gate can check.
|
|
5
|
+
*
|
|
6
|
+
* ---
|
|
7
|
+
* principles_version: 1.2.0
|
|
8
|
+
* source: ../workspace/principles.md # or pack:<pack_id>
|
|
9
|
+
* ---
|
|
10
|
+
* ## P1 — No credentials in code
|
|
11
|
+
* <!-- specgate:principle forbid="password\s*=" in="src/**" -->
|
|
12
|
+
*
|
|
13
|
+
* Pure: text in, model out. Reading the source and running the checks is the
|
|
14
|
+
* command layer's.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.PRINCIPLES_FILE = void 0;
|
|
18
|
+
exports.parsePrinciples = parsePrinciples;
|
|
19
|
+
exports.compareVersions = compareVersions;
|
|
20
|
+
exports.globToRegExp = globToRegExp;
|
|
21
|
+
exports.PRINCIPLES_FILE = "docs/specs/principles.md";
|
|
22
|
+
const HEADING = /^#{2,4}\s+(.+?)\s*$/;
|
|
23
|
+
const PRINCIPLE_COMMENT = /<!--\s*specgate:principle\b([\s\S]*?)-->/;
|
|
24
|
+
/** `key="value with \" escapes"` or `key=value`, as a principle comment writes them. */
|
|
25
|
+
function attributes(body) {
|
|
26
|
+
const out = {};
|
|
27
|
+
const re = /([A-Za-z_][\w-]*)=(?:"((?:[^"\\]|\\.)*)"|(\S+))/g;
|
|
28
|
+
for (const m of body.matchAll(re)) {
|
|
29
|
+
out[m[1].toLowerCase()] = m[2] !== undefined ? m[2].replace(/\\"/g, '"') : m[3];
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
function frontMatter(text) {
|
|
34
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
|
|
35
|
+
if (!m)
|
|
36
|
+
return { fields: {}, body: text };
|
|
37
|
+
const fields = {};
|
|
38
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
39
|
+
const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*?)\s*$/.exec(line);
|
|
40
|
+
if (kv)
|
|
41
|
+
fields[kv[1]] = kv[2].replace(/^["']|["']$/g, "");
|
|
42
|
+
}
|
|
43
|
+
return { fields, body: text.slice(m[0].length) };
|
|
44
|
+
}
|
|
45
|
+
function parsePrinciples(text) {
|
|
46
|
+
const { fields, body } = frontMatter(text);
|
|
47
|
+
const principles = [];
|
|
48
|
+
let current = null;
|
|
49
|
+
for (const line of body.split(/\r?\n/)) {
|
|
50
|
+
const h = HEADING.exec(line);
|
|
51
|
+
if (h) {
|
|
52
|
+
const [, label] = h;
|
|
53
|
+
const idMatch = /^([A-Z][A-Z0-9-]*\d)\b\s*[—:-]?\s*(.*)$/.exec(label);
|
|
54
|
+
current = {
|
|
55
|
+
id: idMatch ? idMatch[1] : label.split(/\s+/)[0],
|
|
56
|
+
title: idMatch ? idMatch[2] || label : label,
|
|
57
|
+
level: "error",
|
|
58
|
+
};
|
|
59
|
+
principles.push(current);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const c = PRINCIPLE_COMMENT.exec(line);
|
|
63
|
+
if (c && current) {
|
|
64
|
+
const a = attributes(c[1]);
|
|
65
|
+
if (a.run)
|
|
66
|
+
current.run = a.run;
|
|
67
|
+
if (a.forbid)
|
|
68
|
+
current.forbid = a.forbid;
|
|
69
|
+
if (a.in)
|
|
70
|
+
current.in = a.in;
|
|
71
|
+
if (a.level === "warn")
|
|
72
|
+
current.level = "warn";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
version: fields.principles_version || "",
|
|
77
|
+
source: fields.source || "",
|
|
78
|
+
// Only a heading with a rule, or one under the title, is a principle.
|
|
79
|
+
principles: principles.filter((p) => p.run || p.forbid || /^[A-Z][A-Z0-9-]*\d$/.test(p.id)),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** -1, 0 or 1, comparing dotted versions numerically (`1.10` after `1.9`). */
|
|
83
|
+
function compareVersions(a, b) {
|
|
84
|
+
const parts = (v) => String(v || "")
|
|
85
|
+
.replace(/^v/, "")
|
|
86
|
+
.split(/[.-]/)
|
|
87
|
+
.map((p) => (/^\d+$/.test(p) ? Number(p) : 0));
|
|
88
|
+
const x = parts(a);
|
|
89
|
+
const y = parts(b);
|
|
90
|
+
for (let i = 0; i < Math.max(x.length, y.length); i++) {
|
|
91
|
+
const d = (x[i] || 0) - (y[i] || 0);
|
|
92
|
+
if (d !== 0)
|
|
93
|
+
return d > 0 ? 1 : -1;
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
/** A glob (`src/**`, `*.ts`, `apps/*\/src/**`) as a regular expression on `/` paths. */
|
|
98
|
+
function globToRegExp(glob) {
|
|
99
|
+
let re = "";
|
|
100
|
+
for (let i = 0; i < glob.length; i++) {
|
|
101
|
+
const ch = glob[i];
|
|
102
|
+
if (ch === "*") {
|
|
103
|
+
if (glob[i + 1] === "*") {
|
|
104
|
+
re += ".*";
|
|
105
|
+
i++;
|
|
106
|
+
if (glob[i + 1] === "/")
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
else
|
|
110
|
+
re += "[^/]*";
|
|
111
|
+
}
|
|
112
|
+
else if (ch === "?")
|
|
113
|
+
re += "[^/]";
|
|
114
|
+
else
|
|
115
|
+
re += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
116
|
+
}
|
|
117
|
+
return new RegExp(`^${re}$`);
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=Principles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Principles.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Principles.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AA+CH,0CAgCC;AAGD,0CAaC;AAGD,oCAcC;AA9GY,QAAA,eAAe,GAAG,0BAA0B,CAAC;AAqB1D,MAAM,OAAO,GAAG,qBAAqB,CAAC;AACtC,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AAErE,wFAAwF;AACxF,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,MAAM,EAAE,GAAG,kDAAkD,CAAC;IAC9D,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,CAAC,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,EAAE;YAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,SAAgB,eAAe,CAAC,IAAY;IAC1C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,IAAI,OAAO,GAAqB,IAAI,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACpB,MAAM,OAAO,GAAG,yCAAyC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,OAAO,GAAG;gBACR,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAChD,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK;gBAC5C,KAAK,EAAE,OAAO;aACf,CAAC;YACF,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG;gBAAE,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,CAAC,MAAM;gBAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;YACxC,IAAI,CAAC,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,kBAAkB,IAAI,EAAE;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,sEAAsE;QACtE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC5F,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAgB,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;SACZ,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACjB,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,wFAAwF;AACxF,SAAgB,YAAY,CAAC,IAAY;IACvC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxB,EAAE,IAAI,IAAI,CAAC;gBACX,CAAC,EAAE,CAAC;gBACJ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;oBAAE,CAAC,EAAE,CAAC;YAC/B,CAAC;;gBAAM,EAAE,IAAI,OAAO,CAAC;QACvB,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG;YAAE,EAAE,IAAI,MAAM,CAAC;;YAC/B,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -51,6 +51,12 @@ class RequirementGraph {
|
|
|
51
51
|
dependents;
|
|
52
52
|
unknown;
|
|
53
53
|
selfReferential;
|
|
54
|
+
/**
|
|
55
|
+
* REQ-294: `depends=contracts:REQ-003` names a requirement of another
|
|
56
|
+
* repository of the workspace. The repository cannot judge it — the
|
|
57
|
+
* workspace does (`workspace check`) — so it is neither unknown nor an edge.
|
|
58
|
+
*/
|
|
59
|
+
external;
|
|
54
60
|
ids;
|
|
55
61
|
constructor(requirementIds, declared) {
|
|
56
62
|
this.ids = requirementIds.map((id) => String(id).toUpperCase());
|
|
@@ -63,11 +69,15 @@ class RequirementGraph {
|
|
|
63
69
|
}
|
|
64
70
|
const unknown = [];
|
|
65
71
|
const selfReferential = [];
|
|
72
|
+
const external = [];
|
|
66
73
|
for (const [requirement, deps] of Object.entries(declared)) {
|
|
67
74
|
if (!known.has(requirement))
|
|
68
75
|
continue; // declared for a REQ not in this project
|
|
69
76
|
for (const dependency of deps) {
|
|
70
|
-
if (dependency
|
|
77
|
+
if (dependency.includes(":")) {
|
|
78
|
+
external.push({ requirement, dependency });
|
|
79
|
+
}
|
|
80
|
+
else if (dependency === requirement) {
|
|
71
81
|
selfReferential.push(requirement);
|
|
72
82
|
}
|
|
73
83
|
else if (!known.has(dependency)) {
|
|
@@ -83,6 +93,7 @@ class RequirementGraph {
|
|
|
83
93
|
this.dependents = dependents;
|
|
84
94
|
this.unknown = unknown;
|
|
85
95
|
this.selfReferential = selfReferential;
|
|
96
|
+
this.external = external;
|
|
86
97
|
}
|
|
87
98
|
/** Build from an adjacency map the caller already has — the harness has one. */
|
|
88
99
|
static fromDependencies(requirementIds, declared) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAYH,8CAOC;AARD,sFAAsF;AACtF,SAAgB,iBAAiB,CAAC,GAAW;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAa,gBAAgB;IAClB,SAAS,CAAqC;IAC9C,UAAU,CAAqC;IAC/C,OAAO,CAA+B;IACtC,eAAe,CAAoB;
|
|
1
|
+
{"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A workspace: the repositories of one product, named in one file (ADR-0041).
|
|
4
|
+
*
|
|
5
|
+
* Specgate's gate is a repository's. A product made of services, a web app and
|
|
6
|
+
* a contracts repository needs a place that knows them all: which repositories
|
|
7
|
+
* there are, which requirement of one another depends on, and which business
|
|
8
|
+
* story is split into a change in each. That place is a workspace repository
|
|
9
|
+
* holding `specgate.workspace.yaml`. Inside a member, `REQ-012` stays the id;
|
|
10
|
+
* across the workspace it is `fleet:REQ-012`.
|
|
11
|
+
*
|
|
12
|
+
* Pure domain: parsing and the id grammar. Reading the members is
|
|
13
|
+
* `scripts/lib/workspace.ts`.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.REPO_NAME = exports.WORKSPACE_ROLES = exports.STORIES_DIR = exports.WORKSPACE_FILE = void 0;
|
|
17
|
+
exports.qualifiedRefs = qualifiedRefs;
|
|
18
|
+
exports.splitQualified = splitQualified;
|
|
19
|
+
exports.readWorkspace = readWorkspace;
|
|
20
|
+
exports.renderWorkspace = renderWorkspace;
|
|
21
|
+
exports.readStory = readStory;
|
|
22
|
+
exports.renderStory = renderStory;
|
|
23
|
+
const YamlLite_1 = require("./YamlLite");
|
|
24
|
+
exports.WORKSPACE_FILE = "specgate.workspace.yaml";
|
|
25
|
+
/** Where a workspace keeps its business stories. */
|
|
26
|
+
exports.STORIES_DIR = "docs/stories";
|
|
27
|
+
/** What a member is to the product. `contracts` holds the APIs others depend on. */
|
|
28
|
+
exports.WORKSPACE_ROLES = ["service", "web", "library", "contracts"];
|
|
29
|
+
/** A member name: what a qualified id can carry before its colon. */
|
|
30
|
+
exports.REPO_NAME = /^[a-z][a-z0-9-]*$/;
|
|
31
|
+
/** `fleet:REQ-012` anywhere in a text. */
|
|
32
|
+
const QUALIFIED_ID = /(?<![\w./-])([a-z][a-z0-9-]*):(REQ-\d+)\b/g;
|
|
33
|
+
/** Every qualified id a text mentions, with its line (1-based). */
|
|
34
|
+
function qualifiedRefs(text) {
|
|
35
|
+
const out = [];
|
|
36
|
+
const lines = text.split(/\r?\n/);
|
|
37
|
+
lines.forEach((line, i) => {
|
|
38
|
+
for (const m of line.matchAll(QUALIFIED_ID))
|
|
39
|
+
out.push({ repo: m[1], id: m[2], line: i + 1 });
|
|
40
|
+
});
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* `contracts:REQ-003` as a `depends=` entry reads it, upper-cased by
|
|
45
|
+
* `splitDependencies`: the repository and the id, or null for a plain id.
|
|
46
|
+
*/
|
|
47
|
+
function splitQualified(dep) {
|
|
48
|
+
const m = /^([A-Za-z][A-Za-z0-9-]*):(REQ-\d+)$/i.exec(dep.trim());
|
|
49
|
+
return m ? { repo: m[1].toLowerCase(), id: m[2].toUpperCase() } : null;
|
|
50
|
+
}
|
|
51
|
+
/** The workspace file, checked: every member named once, with a path and a known role. */
|
|
52
|
+
function readWorkspace(text) {
|
|
53
|
+
const problems = [];
|
|
54
|
+
let doc;
|
|
55
|
+
try {
|
|
56
|
+
doc = (0, YamlLite_1.parseYamlLite)(text) || {};
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return {
|
|
60
|
+
config: null,
|
|
61
|
+
problems: [`${exports.WORKSPACE_FILE} does not parse: ${e.message}`],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const version = doc.workspace_version;
|
|
65
|
+
if (version !== 1 && version !== "1") {
|
|
66
|
+
problems.push(`${exports.WORKSPACE_FILE} needs workspace_version: 1.`);
|
|
67
|
+
}
|
|
68
|
+
const name = String(doc.name || "").trim();
|
|
69
|
+
if (!name)
|
|
70
|
+
problems.push(`${exports.WORKSPACE_FILE} needs a name.`);
|
|
71
|
+
const rawRepos = Array.isArray(doc.repos) ? doc.repos : [];
|
|
72
|
+
if (rawRepos.length === 0)
|
|
73
|
+
problems.push(`${exports.WORKSPACE_FILE} lists no repos.`);
|
|
74
|
+
const repos = [];
|
|
75
|
+
const seen = new Set();
|
|
76
|
+
for (const raw of rawRepos) {
|
|
77
|
+
const repoName = String((raw && raw.name) || "").trim();
|
|
78
|
+
if (!exports.REPO_NAME.test(repoName)) {
|
|
79
|
+
problems.push(`A repo is named "${repoName}": a name is lower-case letters, digits and dashes, as in fleet.`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (seen.has(repoName)) {
|
|
83
|
+
problems.push(`The repo ${repoName} is listed twice.`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
seen.add(repoName);
|
|
87
|
+
const repoPath = String(raw.path || "").trim();
|
|
88
|
+
if (!repoPath)
|
|
89
|
+
problems.push(`The repo ${repoName} has no path.`);
|
|
90
|
+
const role = String(raw.role || "service").trim();
|
|
91
|
+
if (!exports.WORKSPACE_ROLES.includes(role)) {
|
|
92
|
+
problems.push(`The repo ${repoName} has the role ${role}: a role is ${exports.WORKSPACE_ROLES.join(", ")}.`);
|
|
93
|
+
}
|
|
94
|
+
const caps = raw.capabilities;
|
|
95
|
+
repos.push({
|
|
96
|
+
name: repoName,
|
|
97
|
+
path: repoPath,
|
|
98
|
+
...(raw.url ? { url: String(raw.url) } : {}),
|
|
99
|
+
role,
|
|
100
|
+
capabilities: Array.isArray(caps) ? caps.map(String) : caps ? [String(caps)] : [],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return { config: problems.length ? null : { name, repos }, problems };
|
|
104
|
+
}
|
|
105
|
+
/** The workspace file as `workspace init` writes it. */
|
|
106
|
+
function renderWorkspace(config) {
|
|
107
|
+
const lines = [
|
|
108
|
+
"# The repositories of one product (ADR-0041). Across them a requirement is",
|
|
109
|
+
"# <repo>:REQ-NNN; inside a repository REQ-NNN stays its id.",
|
|
110
|
+
"workspace_version: 1",
|
|
111
|
+
`name: ${config.name}`,
|
|
112
|
+
"repos:",
|
|
113
|
+
];
|
|
114
|
+
for (const r of config.repos) {
|
|
115
|
+
lines.push(` - name: ${r.name}`, ` path: ${r.path}`);
|
|
116
|
+
if (r.url)
|
|
117
|
+
lines.push(` url: ${r.url}`);
|
|
118
|
+
lines.push(` role: ${r.role}`);
|
|
119
|
+
lines.push(` capabilities: [${r.capabilities.join(", ")}]`);
|
|
120
|
+
}
|
|
121
|
+
return lines.join("\n") + "\n";
|
|
122
|
+
}
|
|
123
|
+
/** `story.yaml` of a workspace story. */
|
|
124
|
+
function readStory(text) {
|
|
125
|
+
let doc;
|
|
126
|
+
try {
|
|
127
|
+
doc = (0, YamlLite_1.parseYamlLite)(text) || {};
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const id = String(doc.story || "").trim();
|
|
133
|
+
if (!id)
|
|
134
|
+
return null;
|
|
135
|
+
const subs = Array.isArray(doc.subchanges) ? doc.subchanges : [];
|
|
136
|
+
return {
|
|
137
|
+
id,
|
|
138
|
+
title: String(doc.title || id),
|
|
139
|
+
subchanges: subs
|
|
140
|
+
.map((s) => ({ repo: String(s.repo || ""), change: String(s.change || id) }))
|
|
141
|
+
.filter((s) => s.repo),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function renderStory(story) {
|
|
145
|
+
const lines = ["story_version: 1", `story: ${story.id}`, `title: ${story.title}`, "subchanges:"];
|
|
146
|
+
for (const s of story.subchanges)
|
|
147
|
+
lines.push(` - repo: ${s.repo}`, ` change: ${s.change}`);
|
|
148
|
+
return lines.join("\n") + "\n";
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=Workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Workspace.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A workspace story as text: the stories a workspace brief names, the
|
|
4
|
+
* sections of a `story.md`, and the names a workspace gives its repositories
|
|
5
|
+
* (REQ-339..348). Pure; reading and writing the files is `scripts/lib`.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.CRITERIA = exports.INTENT = void 0;
|
|
9
|
+
exports.briefFrontMatter = briefFrontMatter;
|
|
10
|
+
exports.briefText = briefText;
|
|
11
|
+
exports.briefStories = briefStories;
|
|
12
|
+
exports.workspaceBriefTemplate = workspaceBriefTemplate;
|
|
13
|
+
exports.section = section;
|
|
14
|
+
exports.criteriaLines = criteriaLines;
|
|
15
|
+
exports.storyTemplate = storyTemplate;
|
|
16
|
+
exports.shortNames = shortNames;
|
|
17
|
+
const FRONT = /^---\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/;
|
|
18
|
+
/** The YAML between a brief's leading `---` lines, or null. */
|
|
19
|
+
function briefFrontMatter(text) {
|
|
20
|
+
const m = FRONT.exec(text);
|
|
21
|
+
return m ? m[1] : null;
|
|
22
|
+
}
|
|
23
|
+
/** Everything after the front matter. */
|
|
24
|
+
function briefText(text) {
|
|
25
|
+
const m = FRONT.exec(text);
|
|
26
|
+
return (m ? text.slice(m[0].length) : text).replace(/^(?:[ \t]*\r?\n)+/, "");
|
|
27
|
+
}
|
|
28
|
+
/** `a, b, [c, d]` split on the commas outside brackets. */
|
|
29
|
+
function topLevel(s) {
|
|
30
|
+
const out = [];
|
|
31
|
+
let depth = 0;
|
|
32
|
+
let cur = "";
|
|
33
|
+
for (const ch of s) {
|
|
34
|
+
if (ch === "[")
|
|
35
|
+
depth += 1;
|
|
36
|
+
if (ch === "]")
|
|
37
|
+
depth -= 1;
|
|
38
|
+
if (ch === "," && depth === 0) {
|
|
39
|
+
out.push(cur);
|
|
40
|
+
cur = "";
|
|
41
|
+
}
|
|
42
|
+
else
|
|
43
|
+
cur += ch;
|
|
44
|
+
}
|
|
45
|
+
if (cur.trim())
|
|
46
|
+
out.push(cur);
|
|
47
|
+
return out.map((x) => x.trim()).filter(Boolean);
|
|
48
|
+
}
|
|
49
|
+
const unquote = (s) => s.trim().replace(/^(["'])(.*)\1$/, "$2");
|
|
50
|
+
/**
|
|
51
|
+
* The stories of a workspace brief's front matter (REQ-339):
|
|
52
|
+
*
|
|
53
|
+
* stories:
|
|
54
|
+
* - { id: follow-shipment, title: El cliente sigue su envío, repos: [fleet, tracking] }
|
|
55
|
+
*/
|
|
56
|
+
function briefStories(frontMatter) {
|
|
57
|
+
if (!frontMatter)
|
|
58
|
+
return [];
|
|
59
|
+
const lines = frontMatter.split(/\r?\n/);
|
|
60
|
+
const start = lines.findIndex((l) => /^stories:/.test(l));
|
|
61
|
+
if (start < 0)
|
|
62
|
+
return [];
|
|
63
|
+
const out = [];
|
|
64
|
+
for (const line of lines.slice(start + 1)) {
|
|
65
|
+
if (/^\S/.test(line))
|
|
66
|
+
break;
|
|
67
|
+
const m = /^\s*-\s*\{(.*)\}\s*$/.exec(line);
|
|
68
|
+
if (!m)
|
|
69
|
+
continue;
|
|
70
|
+
const fields = {};
|
|
71
|
+
for (const part of topLevel(m[1])) {
|
|
72
|
+
const kv = /^([a-z_]+)\s*:\s*(.*)$/.exec(part);
|
|
73
|
+
if (kv)
|
|
74
|
+
fields[kv[1]] = kv[2].trim();
|
|
75
|
+
}
|
|
76
|
+
const id = unquote(fields.id || "");
|
|
77
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(id))
|
|
78
|
+
continue;
|
|
79
|
+
const repos = /^\[(.*)\]$/.exec(fields.repos || "");
|
|
80
|
+
out.push({
|
|
81
|
+
id,
|
|
82
|
+
title: unquote(fields.title || "") || id.replace(/-/g, " "),
|
|
83
|
+
repos: repos
|
|
84
|
+
? repos[1]
|
|
85
|
+
.split(",")
|
|
86
|
+
.map((r) => unquote(r))
|
|
87
|
+
.filter(Boolean)
|
|
88
|
+
: [],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/** The front matter `workspace draft` writes above a client's brief. */
|
|
94
|
+
function workspaceBriefTemplate(product, repos) {
|
|
95
|
+
return [
|
|
96
|
+
"---",
|
|
97
|
+
`product: ${product}`,
|
|
98
|
+
"# The business stories of the brief, each split across the repositories it",
|
|
99
|
+
"# touches: `specgate workspace draft <id>` drafts one, `workspace propose <id>`",
|
|
100
|
+
"# opens its change in each repository (REQ-339).",
|
|
101
|
+
`# e.g. - { id: follow-shipment, title: The client follows a shipment, repos: [${repos.slice(0, 2).join(", ")}] }`,
|
|
102
|
+
"stories: []",
|
|
103
|
+
"---",
|
|
104
|
+
"",
|
|
105
|
+
].join("\n");
|
|
106
|
+
}
|
|
107
|
+
/** A `##` section of a Markdown text, without its comments, or "". */
|
|
108
|
+
function section(md, heading) {
|
|
109
|
+
const lines = md.split(/\r?\n/);
|
|
110
|
+
const at = lines.findIndex((l) => /^##\s/.test(l) && heading.test(l));
|
|
111
|
+
if (at < 0)
|
|
112
|
+
return "";
|
|
113
|
+
const body = [];
|
|
114
|
+
for (const l of lines.slice(at + 1)) {
|
|
115
|
+
if (/^##\s/.test(l))
|
|
116
|
+
break;
|
|
117
|
+
body.push(l);
|
|
118
|
+
}
|
|
119
|
+
return body
|
|
120
|
+
.join("\n")
|
|
121
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
122
|
+
.trim();
|
|
123
|
+
}
|
|
124
|
+
exports.INTENT = /intent|intenci[oó]n|context/i;
|
|
125
|
+
exports.CRITERIA = /acceptance criteria|criterios de aceptaci[oó]n|akzeptanzkriterien/i;
|
|
126
|
+
/** A story's (or a Discover's) `AC-n` lines, as written. */
|
|
127
|
+
function criteriaLines(md) {
|
|
128
|
+
return section(md, exports.CRITERIA)
|
|
129
|
+
.split(/\r?\n/)
|
|
130
|
+
.map((l) => l.trim())
|
|
131
|
+
.filter((l) => /^[-*]\s*AC-\d+\s*[:—–-]\s*\S/.test(l))
|
|
132
|
+
.map((l) => l.replace(/^[-*]\s*/, "").replace(/\s+/g, " "));
|
|
133
|
+
}
|
|
134
|
+
/** The `story.md` `workspace draft <id>` writes for a person, or an agent, to fill. */
|
|
135
|
+
function storyTemplate(title, repos) {
|
|
136
|
+
return [
|
|
137
|
+
`# Story: ${title}`,
|
|
138
|
+
"",
|
|
139
|
+
"## Intent",
|
|
140
|
+
"",
|
|
141
|
+
"<!-- The business story, in the words of whoever asked for it: who needs what, and why. It stays as it is while each repository's change works out the how. -->",
|
|
142
|
+
"",
|
|
143
|
+
"## Acceptance criteria",
|
|
144
|
+
"",
|
|
145
|
+
"<!-- One line each, numbered: every repository's design answers the ones it touches. -->",
|
|
146
|
+
"- AC-1:",
|
|
147
|
+
"",
|
|
148
|
+
"## Repositories",
|
|
149
|
+
"",
|
|
150
|
+
...repos.map((r) => `- \`${r}\``),
|
|
151
|
+
"",
|
|
152
|
+
].join("\n");
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The names a workspace gives sibling folders: without the prefix they all
|
|
156
|
+
* share (`truck-flote-fleet`, `truck-flote-web` → `fleet`, `web`), so ids read
|
|
157
|
+
* `fleet:REQ-012` (REQ-348). Unchanged when stripping would leave a name empty
|
|
158
|
+
* or two names equal.
|
|
159
|
+
*/
|
|
160
|
+
function shortNames(names) {
|
|
161
|
+
if (names.length < 2)
|
|
162
|
+
return names;
|
|
163
|
+
let prefix = names[0];
|
|
164
|
+
for (const n of names.slice(1)) {
|
|
165
|
+
while (prefix && !n.startsWith(prefix))
|
|
166
|
+
prefix = prefix.slice(0, -1);
|
|
167
|
+
}
|
|
168
|
+
const cut = prefix.lastIndexOf("-");
|
|
169
|
+
if (cut < 0)
|
|
170
|
+
return names;
|
|
171
|
+
const keep = prefix.slice(0, cut + 1);
|
|
172
|
+
const short = names.map((n) => n.slice(keep.length));
|
|
173
|
+
const valid = short.every((s) => /^[a-z][a-z0-9-]*$/.test(s));
|
|
174
|
+
return valid && new Set(short).size === short.length ? short : names;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=WorkspaceStory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceStory.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/WorkspaceStory.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ exports.safeResolve = exports.resetWrittenFiles = exports.getWrittenFiles = expo
|
|
|
26
26
|
// ── Domain ───────────────────────────────────────────────────────────────────
|
|
27
27
|
__exportStar(require("./domain/ArchivePlan"), exports);
|
|
28
28
|
__exportStar(require("./domain/ChangeTemplates"), exports);
|
|
29
|
+
__exportStar(require("./domain/ChangeLayers"), exports);
|
|
29
30
|
__exportStar(require("./domain/DeltaSpec"), exports);
|
|
30
31
|
__exportStar(require("./domain/CucumberMessages"), exports);
|
|
31
32
|
__exportStar(require("./domain/DeclaredArtifacts"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/core/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;AAEH,gFAAgF;AAChF,uDAAqC;AACrC,2DAAyC;AACzC,qDAAmC;AACnC,4DAA0C;AAC1C,6DAA2C;AAC3C,wDAAsC;AACtC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,mDAAiC;AACjC,2DAAyC;AACzC,0DAAwC;AACxC,uDAAqC;AACrC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,oDAAkC;AAClC,4DAA0C;AAC1C,qDAAmC;AACnC,oDAAkC;AAClC,0DAAwC;AACxC,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,2DAAyC;AACzC,gEAA8C;AAC9C,6DAA2C;AAC3C,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,sDAAoC;AACpC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,8DAA4C;AAC5C,4DAA0C;AAC1C,4DAA0C;AAC1C,oDAAkC;AAElC,gFAAgF;AAChF,4EAA0D;AAC1D,+EAA6D;AAC7D,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAY5D,gFAAgF;AAChF,sEAAoD;AACpD,qEAAmD;AACnD,wEAAsD;AACtD,2EAAyD;AACzD,oEAAkD;AAClD,uEAAqD;AACrD,kEAAgD;AAChD,+EAA6D;AAC7D,sEAAoD;AACpD,uEAAqD;AAErD,gFAAgF;AAChF,mEAAiD;AACjD,mEAAiD;AACjD,qEAAmD;AACnD,yEAAuD;AACvD,4EAA0D;AAC1D,+EAA6D;AAC7D,0EAAwD;AACxD,kEAAgD;AAChD,qEAAmD;AACnD,0EAA0E;AAC1E,gFAAgF;AAChF,wEAI4C;AAH1C,wHAAA,WAAW,OAAuB;AAClC,sHAAA,UAAU,OAAqB;AAC/B,kHAAA,aAAa,OAAA;AAEf,0EAAwD;AACxD,0EAAwD;AACxD,2EAAyD;AACzD,+EAA+E;AAC/E,oEAAoE;AACpE,0EAAmG;AAA1F,6HAAA,iBAAiB,OAA2B;AACrD,0EAQ6C;AAP3C,8GAAA,QAAQ,OAAA;AACR,sHAAA,gBAAgB,OAAA;AAChB,kHAAA,YAAY,OAAA;AACZ,+GAAA,SAAS,OAAA;AACT,qHAAA,eAAe,OAAA;AACf,uHAAA,iBAAiB,OAAA;AACjB,iHAAA,WAAW,OAAA;AAEb,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAC5D,qEAAmD;AACnD,sEAAoD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/core/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;AAEH,gFAAgF;AAChF,uDAAqC;AACrC,2DAAyC;AACzC,wDAAsC;AACtC,qDAAmC;AACnC,4DAA0C;AAC1C,6DAA2C;AAC3C,wDAAsC;AACtC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,mDAAiC;AACjC,2DAAyC;AACzC,0DAAwC;AACxC,uDAAqC;AACrC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,oDAAkC;AAClC,4DAA0C;AAC1C,qDAAmC;AACnC,oDAAkC;AAClC,0DAAwC;AACxC,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,2DAAyC;AACzC,gEAA8C;AAC9C,6DAA2C;AAC3C,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,sDAAoC;AACpC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,8DAA4C;AAC5C,4DAA0C;AAC1C,4DAA0C;AAC1C,oDAAkC;AAElC,gFAAgF;AAChF,4EAA0D;AAC1D,+EAA6D;AAC7D,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAY5D,gFAAgF;AAChF,sEAAoD;AACpD,qEAAmD;AACnD,wEAAsD;AACtD,2EAAyD;AACzD,oEAAkD;AAClD,uEAAqD;AACrD,kEAAgD;AAChD,+EAA6D;AAC7D,sEAAoD;AACpD,uEAAqD;AAErD,gFAAgF;AAChF,mEAAiD;AACjD,mEAAiD;AACjD,qEAAmD;AACnD,yEAAuD;AACvD,4EAA0D;AAC1D,+EAA6D;AAC7D,0EAAwD;AACxD,kEAAgD;AAChD,qEAAmD;AACnD,0EAA0E;AAC1E,gFAAgF;AAChF,wEAI4C;AAH1C,wHAAA,WAAW,OAAuB;AAClC,sHAAA,UAAU,OAAqB;AAC/B,kHAAA,aAAa,OAAA;AAEf,0EAAwD;AACxD,0EAAwD;AACxD,2EAAyD;AACzD,+EAA+E;AAC/E,oEAAoE;AACpE,0EAAmG;AAA1F,6HAAA,iBAAiB,OAA2B;AACrD,0EAQ6C;AAP3C,8GAAA,QAAQ,OAAA;AACR,sHAAA,gBAAgB,OAAA;AAChB,kHAAA,YAAY,OAAA;AACZ,+GAAA,SAAS,OAAA;AACT,qHAAA,eAAe,OAAA;AACf,uHAAA,iBAAiB,OAAA;AACjB,iHAAA,WAAW,OAAA;AAEb,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAC5D,qEAAmD;AACnD,sEAAoD"}
|
|
@@ -102,6 +102,11 @@ const KNOWN_KEYS = new Set([
|
|
|
102
102
|
"mutation_score",
|
|
103
103
|
"checks",
|
|
104
104
|
"commit_types",
|
|
105
|
+
// REQ-334: behaviour changed without a specification — reported, or a gate.
|
|
106
|
+
"drift",
|
|
107
|
+
// ADR-0043: who holds each role, and which layers need their approvals.
|
|
108
|
+
"roles",
|
|
109
|
+
"approvals",
|
|
105
110
|
]);
|
|
106
111
|
function readHarnessConfig(projectDir) {
|
|
107
112
|
const filePath = path.join(projectDir, exports.HARNESS_CONFIG_FILE);
|
|
@@ -208,6 +213,13 @@ function readHarnessConfig(projectDir) {
|
|
|
208
213
|
// run Cucumber, and there is no way to know from here).
|
|
209
214
|
if (parsed.e2e_dir !== undefined)
|
|
210
215
|
config.e2eDir = String(parsed.e2e_dir).trim();
|
|
216
|
+
if (parsed.drift !== undefined) {
|
|
217
|
+
const drift = String(parsed.drift).trim();
|
|
218
|
+
if (drift !== "report" && drift !== "gate" && drift !== "off") {
|
|
219
|
+
throw new Error(`${exports.HARNESS_CONFIG_FILE}: drift must be report, gate or off, not ${drift}.`);
|
|
220
|
+
}
|
|
221
|
+
config.drift = drift;
|
|
222
|
+
}
|
|
211
223
|
if (parsed.message_report !== undefined) {
|
|
212
224
|
config.messageReport = String(parsed.message_report);
|
|
213
225
|
}
|