@rsaglobaltech/specgate 0.27.8 → 1.0.0-rc.1
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 +47 -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 +281 -0
- package/dist/packages/core/src/domain/ChangeLayers.js.map +1 -0
- package/dist/packages/core/src/domain/DraftChecklist.js +15 -2
- 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/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/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 +39 -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 +92 -14
- 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/config/ConfigSetCommand.js +2 -1
- package/dist/scripts/cli/commands/config/ConfigSetCommand.js.map +1 -1
- package/dist/scripts/cli/commands/harness/RunCommand.js +85 -21
- 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/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/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 +12 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js +43 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js +485 -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 +5 -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/agent-permission.js +19 -0
- package/dist/scripts/lib/agent-permission.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/harness-environment.js +118 -0
- package/dist/scripts/lib/harness-environment.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/quality-run.js +3 -1
- package/dist/scripts/lib/quality-run.js.map +1 -1
- 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 +42 -0
- package/dist/scripts/lib/studio-app.js.map +1 -1
- package/dist/scripts/lib/studio-route.js +54 -8
- 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-live-page.js +90 -0
- package/dist/scripts/lib/workspace-live-page.js.map +1 -0
- package/dist/scripts/lib/workspace-live.js +216 -0
- package/dist/scripts/lib/workspace-live.js.map +1 -0
- package/dist/scripts/lib/workspace.js +406 -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,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `specgate alm phase <change>` and `specgate alm move <change> [<phase>]`
|
|
4
|
+
* (REQ-309) — what an agent needs to drive the board: read where a change
|
|
5
|
+
* stands without the network, and move its ticket there.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.phaseMain = phaseMain;
|
|
42
|
+
exports.moveMain = moveMain;
|
|
43
|
+
const project_root_1 = require("../../../lib/project-root");
|
|
44
|
+
const agent_1 = require("../../../lib/agent");
|
|
45
|
+
const diagnostics_1 = require("../../../lib/diagnostics");
|
|
46
|
+
const core_1 = require("../../../alm/core");
|
|
47
|
+
const clients_1 = require("../../../alm/clients");
|
|
48
|
+
const port_1 = require("../../../alm/port");
|
|
49
|
+
const phases_1 = require("../../../alm/phases");
|
|
50
|
+
const ui = __importStar(require("../../../lib/ui"));
|
|
51
|
+
function parseArgs(argv) {
|
|
52
|
+
const opts = { projectDir: ".", json: false, positional: [] };
|
|
53
|
+
for (let i = 0; i < argv.length; i++) {
|
|
54
|
+
const a = argv[i];
|
|
55
|
+
if (a === "--project-dir" && argv[i + 1])
|
|
56
|
+
opts.projectDir = argv[++i];
|
|
57
|
+
else if (a === "--json")
|
|
58
|
+
opts.json = true;
|
|
59
|
+
else if (a.startsWith("-")) {
|
|
60
|
+
process.stderr.write(`Unknown flag: ${a}\n`);
|
|
61
|
+
process.exit(2);
|
|
62
|
+
}
|
|
63
|
+
else
|
|
64
|
+
opts.positional.push(a);
|
|
65
|
+
}
|
|
66
|
+
return opts;
|
|
67
|
+
}
|
|
68
|
+
/** `alm phase <change>`: the phase, the ticket and the board state last set. No network. */
|
|
69
|
+
async function phaseMain(argv) {
|
|
70
|
+
const opts = parseArgs(argv);
|
|
71
|
+
const io = (0, agent_1.agentIo)(opts.json || (0, agent_1.wantsJson)(argv));
|
|
72
|
+
const nullShape = { phase: null };
|
|
73
|
+
const id = opts.positional[0];
|
|
74
|
+
const projectDir = (0, project_root_1.resolveProjectDir)(opts.projectDir);
|
|
75
|
+
const change = (0, phases_1.boardChanges)(projectDir).find((c) => c.id === id);
|
|
76
|
+
if (!change) {
|
|
77
|
+
return io.fail(nullShape, [
|
|
78
|
+
(0, diagnostics_1.error)("change_not_found", `No change ${id || "(none)"}.`, {
|
|
79
|
+
target: id,
|
|
80
|
+
fix: "specgate alm phase <change-id> — see specgate change list.",
|
|
81
|
+
}),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
const record = (0, phases_1.readPhaseMap)(projectDir)[change.id];
|
|
85
|
+
const phase = {
|
|
86
|
+
change: change.id,
|
|
87
|
+
phase: change.phase,
|
|
88
|
+
ticket: change.ticket,
|
|
89
|
+
state: record && record.phase === change.phase ? (record.state ?? null) : null,
|
|
90
|
+
requirements: change.requirements,
|
|
91
|
+
};
|
|
92
|
+
io.emit({ phase }, () => process.stdout.write(ui.header("alm phase", change.id) +
|
|
93
|
+
` ${change.phase} ${change.ticket ?? ui.muted("no ticket")} ${phase.state ? `board: ${phase.state}` : ui.muted("not on the board yet")}\n\n`));
|
|
94
|
+
}
|
|
95
|
+
/** `alm move <change> [<phase>]`: move the change's ticket to its phase, or the one named. */
|
|
96
|
+
async function moveMain(argv) {
|
|
97
|
+
const opts = parseArgs(argv);
|
|
98
|
+
const io = (0, agent_1.agentIo)(opts.json || (0, agent_1.wantsJson)(argv));
|
|
99
|
+
const nullShape = { move: null };
|
|
100
|
+
const [id, named] = opts.positional;
|
|
101
|
+
if (named && !port_1.PHASES.includes(named)) {
|
|
102
|
+
return io.fail(nullShape, [
|
|
103
|
+
(0, diagnostics_1.error)("phase_unknown", `"${named}" is not a phase.`, {
|
|
104
|
+
target: named,
|
|
105
|
+
fix: `One of: ${port_1.PHASES.join(", ")}.`,
|
|
106
|
+
}),
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const projectDir = (0, project_root_1.resolveProjectDir)(opts.projectDir);
|
|
111
|
+
const change = (0, phases_1.boardChanges)(projectDir).find((c) => c.id === id);
|
|
112
|
+
if (!change) {
|
|
113
|
+
return io.fail(nullShape, [
|
|
114
|
+
(0, diagnostics_1.error)("change_not_found", `No change ${id || "(none)"}.`, {
|
|
115
|
+
target: id,
|
|
116
|
+
fix: "specgate alm move <change-id> [<phase>]",
|
|
117
|
+
}),
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
if (!change.ticket) {
|
|
121
|
+
return io.fail(nullShape, [
|
|
122
|
+
(0, diagnostics_1.error)("change_no_ticket", `${change.id} has no ticket to move.`, {
|
|
123
|
+
target: change.id,
|
|
124
|
+
fix: "Add ticket: <KEY> to its change.yaml.",
|
|
125
|
+
}),
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
const cfg = (0, core_1.readAlmConfig)(projectDir);
|
|
129
|
+
const client = (0, clients_1.makeClient)(cfg, undefined, projectDir);
|
|
130
|
+
const map = (0, phases_1.readPhaseMap)(projectDir);
|
|
131
|
+
const action = await (0, phases_1.movePhase)({ ...change, ticket: change.ticket }, map, client, cfg, {
|
|
132
|
+
phase: named || undefined,
|
|
133
|
+
force: true,
|
|
134
|
+
});
|
|
135
|
+
if (action.action === "phase-unsupported") {
|
|
136
|
+
return io.fail(nullShape, [
|
|
137
|
+
(0, diagnostics_1.error)("alm_phase_unsupported", action.detail || "", { target: cfg.provider }),
|
|
138
|
+
]);
|
|
139
|
+
}
|
|
140
|
+
(0, phases_1.writePhaseMap)(projectDir, map, false);
|
|
141
|
+
const move = {
|
|
142
|
+
change: change.id,
|
|
143
|
+
issue: action.issue,
|
|
144
|
+
phase: action.phase,
|
|
145
|
+
state: action.state,
|
|
146
|
+
};
|
|
147
|
+
io.emit({ move }, () => process.stdout.write(ui.header("alm move", change.id) + ui.ok(`${action.issue} → ${action.state}`) + "\n"));
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
return io.fail(nullShape, [(0, diagnostics_1.error)("alm_move_error", e.message || String(e))]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=PhaseCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhaseCommand.js","sourceRoot":"","sources":["../../../../../scripts/cli/commands/alm/PhaseCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,8 @@ const agent_1 = require("../../../lib/agent");
|
|
|
67
67
|
const diagnostics_1 = require("../../../lib/diagnostics");
|
|
68
68
|
const core_1 = require("../../../alm/core");
|
|
69
69
|
const clients_1 = require("../../../alm/clients");
|
|
70
|
+
const phases_1 = require("../../../alm/phases");
|
|
71
|
+
const pull_back_1 = require("./pull-back");
|
|
70
72
|
const ChangeWorkspace_1 = require("../../../../packages/core/src/infrastructure/ChangeWorkspace");
|
|
71
73
|
const InboundChange_1 = require("../../../../packages/core/src/domain/InboundChange");
|
|
72
74
|
const NULL_SHAPE = { pulled: [], skipped: [] };
|
|
@@ -151,6 +153,31 @@ async function main(argv) {
|
|
|
151
153
|
}),
|
|
152
154
|
]);
|
|
153
155
|
}
|
|
156
|
+
// REQ-306: what each open change's ticket gained since the last pull comes
|
|
157
|
+
// back as notes, before any new issue is pulled.
|
|
158
|
+
let notes;
|
|
159
|
+
try {
|
|
160
|
+
const map = (0, phases_1.readPhaseMap)(projectDir);
|
|
161
|
+
notes = await (0, pull_back_1.pullBack)(projectDir, (0, phases_1.boardChanges)(projectDir), map, client, {
|
|
162
|
+
dryRun: opts.dryRun,
|
|
163
|
+
today: new Date().toISOString().slice(0, 10),
|
|
164
|
+
});
|
|
165
|
+
(0, phases_1.writePhaseMap)(projectDir, map, opts.dryRun);
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
return io.fail(NULL_SHAPE, [
|
|
169
|
+
(0, diagnostics_1.error)("alm_pull_error", e.message || String(e), {
|
|
170
|
+
fix: "Check the ticket keys in change.yaml and your ALM configuration.",
|
|
171
|
+
}),
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
const printNotes = () => {
|
|
175
|
+
for (const n of notes) {
|
|
176
|
+
process.stdout.write(n.action === "comments-unsupported"
|
|
177
|
+
? ` ${n.change}: ${n.text}\n`
|
|
178
|
+
: ` ${n.change} <- ${n.issue}: ${n.text}\n`);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
154
181
|
// Declared, not discovered at the first request: Jira searches with JQL,
|
|
155
182
|
// GitHub with query parameters, Azure with WIQL — and a provider that cannot
|
|
156
183
|
// search says so rather than failing halfway through a pull.
|
|
@@ -164,7 +191,10 @@ async function main(argv) {
|
|
|
164
191
|
}
|
|
165
192
|
const issues = await client.listIssues(opts.label);
|
|
166
193
|
if (issues.length === 0) {
|
|
167
|
-
return io.emit({ pulled: [], skipped: [], label: opts.label }, () =>
|
|
194
|
+
return io.emit({ pulled: [], skipped: [], label: opts.label, notes }, () => {
|
|
195
|
+
printNotes();
|
|
196
|
+
process.stdout.write(`\n No open issues labelled '${opts.label}'.\n\n`);
|
|
197
|
+
});
|
|
168
198
|
}
|
|
169
199
|
const p = (0, ChangeWorkspace_1.paths)(projectDir);
|
|
170
200
|
const existing = new Set((0, ChangeWorkspace_1.listChangeIds)(projectDir));
|
|
@@ -224,7 +254,8 @@ async function main(argv) {
|
|
|
224
254
|
fix: "Delete the change to re-pull it, or edit the one that exists.",
|
|
225
255
|
}));
|
|
226
256
|
}
|
|
227
|
-
io.emit({ pulled, skipped, label: opts.label, status }, () => {
|
|
257
|
+
io.emit({ pulled, skipped, label: opts.label, status, notes }, () => {
|
|
258
|
+
printNotes();
|
|
228
259
|
process.stdout.write(`\n Pulled ${pulled.length} issue(s) labelled '${opts.label}'\n\n`);
|
|
229
260
|
for (const row of pulled) {
|
|
230
261
|
process.stdout.write(` ${row.issue} → ${row.change} (${row.requirement})\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PullCommand.js","sourceRoot":"","sources":["../../../../../scripts/cli/commands/alm/PullCommand.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"PullCommand.js","sourceRoot":"","sources":["../../../../../scripts/cli/commands/alm/PullCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What a ticket gains comes back to its change as notes (REQ-306).
|
|
4
|
+
*
|
|
5
|
+
* Outside `scripts/alm/` for the reason `alm pull` is: ADR-0021 keeps the ALM
|
|
6
|
+
* subsystem from writing the spec tree, and a note is written into the
|
|
7
|
+
* change. It is written where `change note` writes — `review.md` — and nowhere
|
|
8
|
+
* else: a comment on a ticket is a request a person reads and folds in, never
|
|
9
|
+
* a rewrite of the proposal or the delta.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.pullBack = pullBack;
|
|
46
|
+
const crypto = __importStar(require("node:crypto"));
|
|
47
|
+
const change_review_1 = require("../../../lib/change-review");
|
|
48
|
+
const hash = (text) => crypto.createHash("sha256").update(text).digest("hex");
|
|
49
|
+
/** One line of a note: a ticket's text, flattened and kept short enough to read in a table. */
|
|
50
|
+
function oneLine(text, max = 400) {
|
|
51
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
52
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Bring back each open change's new comments and changed description.
|
|
56
|
+
*
|
|
57
|
+
* The first pull of a ticket records its description and comes back with its
|
|
58
|
+
* comments; from then on only what changed is noted, so pulling twice adds
|
|
59
|
+
* nothing.
|
|
60
|
+
*/
|
|
61
|
+
async function pullBack(projectDir, changes, map, client, opts) {
|
|
62
|
+
const actions = [];
|
|
63
|
+
for (const change of changes) {
|
|
64
|
+
if (change.archived || !change.ticket)
|
|
65
|
+
continue;
|
|
66
|
+
const ticket = change.ticket;
|
|
67
|
+
const record = (map[change.id] ??= { ticket });
|
|
68
|
+
const note = (action, text) => {
|
|
69
|
+
actions.push({ change: change.id, issue: ticket, action, text });
|
|
70
|
+
if (!opts.dryRun && action !== "comments-unsupported") {
|
|
71
|
+
(0, change_review_1.noteChange)(projectDir, change.id, text, "", opts.today);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
if (client.capabilities.readText && typeof client.readIssueText === "function") {
|
|
75
|
+
const { body } = await client.readIssueText(ticket);
|
|
76
|
+
const now = hash(body);
|
|
77
|
+
if (record.description && record.description !== now) {
|
|
78
|
+
note("description", `The description of ${ticket} changed: ${oneLine(body)}`);
|
|
79
|
+
}
|
|
80
|
+
if (!opts.dryRun)
|
|
81
|
+
record.description = now;
|
|
82
|
+
}
|
|
83
|
+
if (!client.capabilities.comments || typeof client.listComments !== "function") {
|
|
84
|
+
actions.push({
|
|
85
|
+
change: change.id,
|
|
86
|
+
issue: ticket,
|
|
87
|
+
action: "comments-unsupported",
|
|
88
|
+
text: `This provider cannot read the comments of ${ticket}; read them on the board.`,
|
|
89
|
+
});
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const seen = new Set(record.comments ?? []);
|
|
93
|
+
for (const comment of await client.listComments(ticket)) {
|
|
94
|
+
if (seen.has(comment.id))
|
|
95
|
+
continue;
|
|
96
|
+
note("comment", `Comment on ${ticket}${comment.author ? ` by ${comment.author}` : ""}: ${oneLine(comment.body)}`);
|
|
97
|
+
seen.add(comment.id);
|
|
98
|
+
}
|
|
99
|
+
if (!opts.dryRun)
|
|
100
|
+
record.comments = [...seen];
|
|
101
|
+
}
|
|
102
|
+
return actions;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=pull-back.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull-back.js","sourceRoot":"","sources":["../../../../../scripts/cli/commands/alm/pull-back.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,6 +68,7 @@ const ArchiveChangeUseCase_1 = require("../../../../packages/core/src/applicatio
|
|
|
68
68
|
const DiskProjectRepository_1 = require("../../../../packages/core/src/infrastructure/DiskProjectRepository");
|
|
69
69
|
const ChangeWorkspace_1 = require("../../../../packages/core/src/infrastructure/ChangeWorkspace");
|
|
70
70
|
const ChangeTemplates_1 = require("../../../../packages/core/src/domain/ChangeTemplates");
|
|
71
|
+
const ChangeLayers_1 = require("../../../../packages/core/src/domain/ChangeLayers");
|
|
71
72
|
const ValidateChangeUseCase_1 = require("../../../../packages/core/src/application/ValidateChangeUseCase");
|
|
72
73
|
const capability_specs_1 = require("../../../lib/capability-specs");
|
|
73
74
|
const change_impact_1 = require("../../../lib/change-impact");
|
|
@@ -154,7 +155,7 @@ function usage() {
|
|
|
154
155
|
` ${ui_1.c.green}author <id>${ui_1.c.reset} ${ui_1.c.dim}Have an agent write one artefact, confined to the change.${ui_1.c.reset}\n` +
|
|
155
156
|
` ${ui_1.c.green}validate [id]${ui_1.c.reset} ${ui_1.c.dim}Check the deltas against the capability specs.${ui_1.c.reset}\n` +
|
|
156
157
|
` ${ui_1.c.green}impact <REQ|id>${ui_1.c.reset} ${ui_1.c.dim}Spec, features, tests, files and requirements a change to it touches.${ui_1.c.reset}\n` +
|
|
157
|
-
` ${ui_1.c.green}approve <id>${ui_1.c.reset} ${ui_1.c.dim}
|
|
158
|
+
` ${ui_1.c.green}approve <id>${ui_1.c.reset} ${ui_1.c.dim}Approve the layers you own (--layer discover|design|tasks): Build waits for all.${ui_1.c.reset}\n` +
|
|
158
159
|
` ${ui_1.c.green}note <id> "<text>"${ui_1.c.reset} ${ui_1.c.dim}Ask the draft for a change in your words (--req REQ).${ui_1.c.reset}\n` +
|
|
159
160
|
` ${ui_1.c.green}archive <id>${ui_1.c.reset} ${ui_1.c.dim}Once its requirements are Implemented: merge, sync traceability, archive.${ui_1.c.reset}\n\n` +
|
|
160
161
|
` ${ui_1.c.bold}OPTIONS${ui_1.c.reset}\n` +
|
|
@@ -202,6 +203,8 @@ function parseArgs(argv) {
|
|
|
202
203
|
opts.modify.push(argv[++i]);
|
|
203
204
|
else if (a === "--req" && argv[i + 1])
|
|
204
205
|
opts.req = argv[++i];
|
|
206
|
+
else if (a === "--layer" && argv[i + 1])
|
|
207
|
+
opts.layer = argv[++i];
|
|
205
208
|
else if (a === "--schema" && argv[i + 1])
|
|
206
209
|
opts.schema = argv[++i];
|
|
207
210
|
else if (a === "--reserve" && argv[i + 1])
|
|
@@ -424,7 +427,8 @@ function cmdNew(opts) {
|
|
|
424
427
|
const reqRange = (0, ChangeWorkspace_1.reserveReqRange)(projectDir, opts.reserve);
|
|
425
428
|
const config = {
|
|
426
429
|
...ChangeWorkspace_1.DEFAULT_CONFIG,
|
|
427
|
-
|
|
430
|
+
// ADR-0042: a new change is layered unless the person names a schema.
|
|
431
|
+
schema: opts.schema || ChangeLayers_1.LAYERED_SCHEMA,
|
|
428
432
|
created: new Date().toISOString().slice(0, 10),
|
|
429
433
|
rigor: opts.full ? "full" : "lite",
|
|
430
434
|
req_range: reqRange,
|
|
@@ -436,10 +440,18 @@ function cmdNew(opts) {
|
|
|
436
440
|
created.push(path.relative(projectDir, file).split(path.sep).join("/"));
|
|
437
441
|
};
|
|
438
442
|
write(path.join(dir, ChangeWorkspace_1.CHANGE_CONFIG_FILE), (0, ChangeWorkspace_1.renderConfig)(config));
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
write(path.join(dir, "design.md"), (0,
|
|
443
|
+
if (config.schema === ChangeLayers_1.LAYERED_SCHEMA) {
|
|
444
|
+
// REQ-282: each layer with its owner.
|
|
445
|
+
write(path.join(dir, "discover.md"), (0, ChangeLayers_1.templateDiscover)(changeId));
|
|
446
|
+
write(path.join(dir, "design.md"), (0, ChangeLayers_1.templateLayeredDesign)(changeId));
|
|
447
|
+
write(path.join(dir, "tasks.md"), (0, ChangeLayers_1.templateLayeredTasks)());
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
write(path.join(dir, "proposal.md"), (0, ChangeTemplates_1.templateProposal)(changeId));
|
|
451
|
+
write(path.join(dir, "tasks.md"), (0, ChangeTemplates_1.templateTasks)());
|
|
452
|
+
if (opts.full)
|
|
453
|
+
write(path.join(dir, "design.md"), (0, ChangeTemplates_1.templateDesign)(changeId));
|
|
454
|
+
}
|
|
443
455
|
if (opts.capability) {
|
|
444
456
|
write(path.join(p.changeSpecs(changeId), opts.capability, "spec.md"), (0, ChangeTemplates_1.templateDelta)(opts.capability, reqRange[0], (0, DiskLanguageRepository_1.phrases)(projectDir)));
|
|
445
457
|
}
|
|
@@ -466,7 +478,11 @@ function cmdNew(opts) {
|
|
|
466
478
|
created.map((f) => ui.fileLine("added", f)).join("") +
|
|
467
479
|
(VERB === "propose"
|
|
468
480
|
? ui.next("specgate apply", "after you write the delta, a test that names each requirement, and the code")
|
|
469
|
-
: ui.next(`specgate change validate ${changeId}`,
|
|
481
|
+
: ui.next(`specgate change validate ${changeId}`,
|
|
482
|
+
// ADR-0042: a layered change starts from its Discover.
|
|
483
|
+
config.schema === ChangeLayers_1.LAYERED_SCHEMA
|
|
484
|
+
? "after you write discover.md, the delta, then design.md and tasks.md"
|
|
485
|
+
: "after you write the proposal, then the delta")));
|
|
470
486
|
});
|
|
471
487
|
}
|
|
472
488
|
/** The open change whose delta already modifies a requirement, if one does (REQ-190). */
|
|
@@ -518,23 +534,35 @@ function cmdList(opts) {
|
|
|
518
534
|
});
|
|
519
535
|
}
|
|
520
536
|
// ── show ──────────────────────────────────────────────────────────────────────
|
|
521
|
-
/**
|
|
537
|
+
/**
|
|
538
|
+
* `change approve <id> [--layer discover|design|tasks]` — a person approves the
|
|
539
|
+
* layers they own; Build waits until every layer is approved (REQ-206, REQ-311).
|
|
540
|
+
*/
|
|
522
541
|
function cmdApprove(opts) {
|
|
523
542
|
const projectDir = (0, project_root_1.resolveProjectDir)(opts.projectDir);
|
|
524
543
|
const id = opts.positional[0];
|
|
525
544
|
const nullShape = { approve: null };
|
|
545
|
+
const layer = opts.layer;
|
|
526
546
|
const r = id
|
|
527
|
-
? (0, change_review_1.approveChange)(projectDir, id, new Date().toISOString().slice(0, 10))
|
|
547
|
+
? (0, change_review_1.approveChange)(projectDir, id, new Date().toISOString().slice(0, 10), layer)
|
|
528
548
|
: { ok: false, code: "change_not_found", message: "approve needs a change id." };
|
|
529
549
|
if (!r.ok) {
|
|
530
550
|
return fail(opts, nullShape, [
|
|
531
551
|
(0, diagnostics_1.error)(r.code, r.message, {
|
|
532
552
|
target: id,
|
|
533
|
-
fix:
|
|
553
|
+
fix: r.fix ||
|
|
554
|
+
"Answer its questions and fix what specgate draft --check reports, then approve again.",
|
|
534
555
|
}),
|
|
535
556
|
]);
|
|
536
557
|
}
|
|
537
|
-
emit(opts, { approve: r }, () =>
|
|
558
|
+
emit(opts, { approve: r }, () => {
|
|
559
|
+
const did = r.layers && r.layers.length ? ` — ${r.layers.join(", ")}` : "";
|
|
560
|
+
process.stdout.write(ui.header("change approve", id) +
|
|
561
|
+
(r.approved
|
|
562
|
+
? ui.ok(`${id} approved on ${r.approved}${did}.`)
|
|
563
|
+
: ui.ok(`Recorded${did}. Still waiting: ${(r.pending || []).join(", ")}.`)) +
|
|
564
|
+
"\n");
|
|
565
|
+
});
|
|
538
566
|
}
|
|
539
567
|
/** `change note <id> "<text>" [--req REQ]` — a change asked in the reviewer's words (REQ-207). */
|
|
540
568
|
function cmdNote(opts) {
|
|
@@ -601,8 +629,11 @@ function cmdShow(opts) {
|
|
|
601
629
|
removed: parsed.removed.map((r) => r.heading),
|
|
602
630
|
};
|
|
603
631
|
});
|
|
604
|
-
|
|
605
|
-
const
|
|
632
|
+
// The Discover of a layered change, the proposal of a 0.27 one.
|
|
633
|
+
const discoverFile = ["discover.md", ChangeLayers_1.LEGACY_DISCOVER]
|
|
634
|
+
.map((f) => path.join(p.change(changeId), f))
|
|
635
|
+
.find((f) => fs.existsSync(f));
|
|
636
|
+
const proposal = discoverFile ? fs.readFileSync(discoverFile, "utf8") : "";
|
|
606
637
|
const titleMatch = /^#\s+(.+)$/m.exec(proposal);
|
|
607
638
|
const progress = (0, ChangeWorkspace_1.taskProgress)(projectDir, changeId);
|
|
608
639
|
emit(opts, {
|
|
@@ -662,7 +693,7 @@ function cmdStatus(opts) {
|
|
|
662
693
|
const isPlanningComplete = artifacts.every((a) => a.status === "done" || a.status === "skipped");
|
|
663
694
|
const nextSteps = artifacts
|
|
664
695
|
.filter((a) => a.status === "ready")
|
|
665
|
-
.map((a) => `Write ${a.outputPath}`);
|
|
696
|
+
.map((a) => `Write ${a.outputPath}${a.owner ? ` (${a.owner})` : ""}`);
|
|
666
697
|
if (isPlanningComplete && progress.remaining > 0) {
|
|
667
698
|
nextSteps.push(`Work through tasks.md (${progress.remaining} remaining)`);
|
|
668
699
|
}
|
|
@@ -883,6 +914,50 @@ function authorPrompt(changeId, artifact, instructions) {
|
|
|
883
914
|
parts.push(`When finished, the change must pass \`specgate change validate ${changeId}\`.`);
|
|
884
915
|
return parts.join("\n");
|
|
885
916
|
}
|
|
917
|
+
/**
|
|
918
|
+
* REQ-287: a layered change's Discover as it was agreed — in the commit that
|
|
919
|
+
* recorded the approval, or else the first one that held it — against the
|
|
920
|
+
* working copy. Outside git, or before the first commit, there is nothing to
|
|
921
|
+
* compare with.
|
|
922
|
+
*/
|
|
923
|
+
function storyRewritten(projectDir, changeId) {
|
|
924
|
+
if ((0, ChangeWorkspace_1.readConfig)(projectDir, changeId).schema !== ChangeLayers_1.LAYERED_SCHEMA)
|
|
925
|
+
return null;
|
|
926
|
+
const dir = (0, ChangeWorkspace_1.paths)(projectDir).change(changeId);
|
|
927
|
+
const file = path.join(dir, "discover.md");
|
|
928
|
+
if (!fs.existsSync(file))
|
|
929
|
+
return null;
|
|
930
|
+
const git = (...args) => (0, node_child_process_1.spawnSync)("git", ["-C", projectDir, ...args], { encoding: "utf8" });
|
|
931
|
+
const top = git("rev-parse", "--show-toplevel");
|
|
932
|
+
if (top.status !== 0)
|
|
933
|
+
return null;
|
|
934
|
+
const rel = (f) => path
|
|
935
|
+
.relative(fs.realpathSync.native(top.stdout.trim()), fs.realpathSync.native(f))
|
|
936
|
+
.split(path.sep)
|
|
937
|
+
.join("/");
|
|
938
|
+
const earliest = (args) => {
|
|
939
|
+
const r = git("log", "--format=%h", ...args);
|
|
940
|
+
const shas = r.status === 0 ? r.stdout.trim().split(/\r?\n/).filter(Boolean) : [];
|
|
941
|
+
return shas[shas.length - 1] || "";
|
|
942
|
+
};
|
|
943
|
+
const config = path.join(dir, ChangeWorkspace_1.CHANGE_CONFIG_FILE);
|
|
944
|
+
const approved = (0, ChangeWorkspace_1.readConfig)(projectDir, changeId).approved
|
|
945
|
+
? earliest(["-S", "approved:", "--", rel(config)])
|
|
946
|
+
: "";
|
|
947
|
+
const sha = approved || earliest(["--diff-filter=A", "--", rel(file)]);
|
|
948
|
+
if (!sha)
|
|
949
|
+
return null;
|
|
950
|
+
const baseline = git("show", `${sha}:${rel(file)}`);
|
|
951
|
+
if (baseline.status !== 0)
|
|
952
|
+
return null;
|
|
953
|
+
if (!(0, ChangeLayers_1.discoverRewritten)(baseline.stdout, fs.readFileSync(file, "utf8")))
|
|
954
|
+
return null;
|
|
955
|
+
return (0, diagnostics_1.warning)("layer_discover_rewritten", `discover.md differs from the story agreed at ${sha}${approved ? " (approved)" : ""}.`, {
|
|
956
|
+
target: changeId,
|
|
957
|
+
file: `docs/specs/changes/${changeId}/discover.md`,
|
|
958
|
+
fix: `The business story stays put while the design changes: restore it (\`git checkout ${sha} -- ${rel(file)}\`), or have ${(0, ChangeLayers_1.layer)("discover").owner} agree the new story.`,
|
|
959
|
+
});
|
|
960
|
+
}
|
|
886
961
|
function cmdValidate(opts) {
|
|
887
962
|
const projectDir = (0, project_root_1.resolveProjectDir)(opts.projectDir);
|
|
888
963
|
const requested = opts.positional[0];
|
|
@@ -905,6 +980,9 @@ function cmdValidate(opts) {
|
|
|
905
980
|
}
|
|
906
981
|
const items = ids.map((id) => {
|
|
907
982
|
const result = new ValidateChangeUseCase_1.ValidateChangeUseCase(new DiskProjectRepository_1.DiskProjectRepository(projectDir)).execute(id, opts);
|
|
983
|
+
const rewritten = storyRewritten(projectDir, id);
|
|
984
|
+
if (rewritten)
|
|
985
|
+
result.diagnostics.push(rewritten);
|
|
908
986
|
const failed = opts.strict ? result.diagnostics.length > 0 : (0, diagnostics_1.hasErrors)(result.diagnostics);
|
|
909
987
|
// What each delta rewrites, as it reads now: on first sight, or on
|
|
910
988
|
// --rebased once the delta was rewritten over a requirement that moved (REQ-168).
|