cleargate 0.14.0 → 0.15.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 +16 -0
- package/dist/MANIFEST.json +71 -15
- package/dist/admin-api/index.cjs +0 -1
- package/dist/admin-api/index.js +1 -2
- package/dist/auth/factory.cjs +0 -1
- package/dist/auth/factory.js +2 -3
- package/dist/auth/require-token.cjs +0 -1
- package/dist/auth/require-token.js +1 -2
- package/dist/auth/token-store.cjs +0 -1
- package/dist/auth/token-store.js +1 -2
- package/dist/{bootstrap-root-QKSA5V75.js → bootstrap-root-2H5HVTCC.js} +1 -2
- package/dist/{chunk-PDE37WFQ.js → chunk-A7MSQUU7.js} +2 -3
- package/dist/{chunk-BTSZOEWC.js → chunk-P6KEDAK2.js} +0 -1
- package/dist/{chunk-E3X7IE5E.js → chunk-PY6FHGV5.js} +1 -2
- package/dist/{chunk-5DI2Z3C2.js → chunk-Y53ZZYYU.js} +1 -2
- package/dist/cli.cjs +1564 -1414
- package/dist/cli.js +1514 -1364
- package/dist/lib/ledger.cjs +0 -1
- package/dist/lib/ledger.js +1 -2
- package/dist/lib/lifecycle-reconcile.cjs +0 -1
- package/dist/lib/lifecycle-reconcile.js +2 -3
- package/dist/{whoami-EANGN46Z.js → whoami-JKQQPABQ.js} +3 -4
- package/package.json +4 -3
- package/templates/cleargate-planning/.claude/agents/architect.md +4 -2
- package/templates/cleargate-planning/.claude/agents/developer.md +4 -11
- package/templates/cleargate-planning/.claude/agents/qa.md +14 -6
- package/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +2 -2
- package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +19 -1
- package/templates/cleargate-planning/.cleargate/config.example.yml +16 -0
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.deferred-verify.red.node.test.ts +245 -0
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +227 -0
- package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +5 -4
- package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +75 -2
- package/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +48 -0
- package/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +57 -1
- package/templates/cleargate-planning/.cleargate/scripts/provision_worktree_config.sh +155 -0
- package/templates/cleargate-planning/.cleargate/scripts/qa_red_lint.mjs +380 -0
- package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +34 -1
- package/templates/cleargate-planning/.cleargate/scripts/test/cr077_eviction.red.sh +113 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr078_init.test.sh +309 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr079_provision.red.sh +262 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr080_wrapper.test.sh +177 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr081_qa_red_lint.red.sh +348 -0
- package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/.session-totals.json +1 -0
- package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/token-ledger.jsonl +27 -0
- package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +17 -0
- package/templates/cleargate-planning/.cleargate/templates/story.md +1 -0
- package/templates/cleargate-planning/MANIFEST.json +71 -15
- package/dist/admin-api/index.cjs.map +0 -1
- package/dist/admin-api/index.js.map +0 -1
- package/dist/auth/factory.cjs.map +0 -1
- package/dist/auth/factory.js.map +0 -1
- package/dist/auth/require-token.cjs.map +0 -1
- package/dist/auth/require-token.js.map +0 -1
- package/dist/auth/token-store.cjs.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/bootstrap-root-QKSA5V75.js.map +0 -1
- package/dist/chunk-5DI2Z3C2.js.map +0 -1
- package/dist/chunk-BTSZOEWC.js.map +0 -1
- package/dist/chunk-E3X7IE5E.js.map +0 -1
- package/dist/chunk-PDE37WFQ.js.map +0 -1
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/lib/ledger.cjs.map +0 -1
- package/dist/lib/ledger.js.map +0 -1
- package/dist/lib/lifecycle-reconcile.cjs.map +0 -1
- package/dist/lib/lifecycle-reconcile.js.map +0 -1
- package/dist/templates/cleargate-planning/.claude/agents/architect-reader.md +0 -61
- package/dist/templates/cleargate-planning/.claude/agents/architect-synth.md +0 -124
- package/dist/templates/cleargate-planning/.claude/agents/architect.md +0 -230
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +0 -108
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +0 -194
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +0 -261
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-query.md +0 -143
- package/dist/templates/cleargate-planning/.claude/agents/developer.md +0 -185
- package/dist/templates/cleargate-planning/.claude/agents/devops.md +0 -257
- package/dist/templates/cleargate-planning/.claude/agents/qa.md +0 -171
- package/dist/templates/cleargate-planning/.claude/agents/reporter.md +0 -274
- package/dist/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +0 -209
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +0 -33
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +0 -58
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit.sh +0 -19
- package/dist/templates/cleargate-planning/.claude/hooks/pre-edit-gate.sh +0 -162
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-autonomy.sh +0 -58
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +0 -148
- package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +0 -75
- package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +0 -43
- package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +0 -590
- package/dist/templates/cleargate-planning/.claude/settings.json +0 -68
- package/dist/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +0 -102
- package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +0 -742
- package/dist/templates/cleargate-planning/.cleargate/FLASHCARD.md +0 -7
- package/dist/templates/cleargate-planning/.cleargate/config.example.yml +0 -67
- package/dist/templates/cleargate-planning/.cleargate/config.yml +0 -18
- package/dist/templates/cleargate-planning/.cleargate/delivery/archive/.gitkeep +0 -0
- package/dist/templates/cleargate-planning/.cleargate/delivery/pending-sync/.gitkeep +0 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +0 -551
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +0 -878
- package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +0 -160
- package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +0 -213
- package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +0 -71
- package/dist/templates/cleargate-planning/.cleargate/scripts/_migrate-schema-v3.mjs +0 -120
- package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +0 -265
- package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +0 -1012
- package/dist/templates/cleargate-planning/.cleargate/scripts/collision_surface.sh +0 -114
- package/dist/templates/cleargate-planning/.cleargate/scripts/constants.mjs +0 -62
- package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +0 -219
- package/dist/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +0 -320
- package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +0 -15
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +0 -38
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +0 -240
- package/dist/templates/cleargate-planning/.cleargate/scripts/launch_wave.mjs +0 -341
- package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +0 -54
- package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +0 -206
- package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +0 -371
- package/dist/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +0 -280
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +0 -378
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +0 -888
- package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +0 -209
- package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +0 -71
- package/dist/templates/cleargate-planning/.cleargate/scripts/state.schema.json +0 -127
- package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +0 -717
- package/dist/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +0 -27
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +0 -261
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +0 -210
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +0 -190
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +0 -482
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +0 -327
- package/dist/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +0 -261
- package/dist/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +0 -246
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +0 -111
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +0 -184
- package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +0 -172
- package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +0 -126
- package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +0 -130
- package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +0 -137
- package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +0 -166
- package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +0 -111
- package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +0 -122
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +0 -50
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +0 -224
- package/dist/templates/cleargate-planning/.cleargate/templates/story.md +0 -213
- package/dist/templates/cleargate-planning/CLAUDE.md +0 -66
- package/dist/templates/cleargate-planning/MANIFEST.json +0 -503
- package/dist/templates/synthesis/active-sprint.md +0 -30
- package/dist/templates/synthesis/open-gates.md +0 -38
- package/dist/templates/synthesis/product-state.md +0 -31
- package/dist/templates/synthesis/roadmap.md +0 -63
- package/dist/whoami-EANGN46Z.js.map +0 -1
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* assert_story_files.mjs — Gate-2 work-item file existence + approval assertion
|
|
4
|
-
*
|
|
5
|
-
* Usage: node assert_story_files.mjs <sprint-file-path>
|
|
6
|
-
*
|
|
7
|
-
* Parses the "## 1. Consolidated Deliverables" section of a sprint file for
|
|
8
|
-
* all six work-item id shapes:
|
|
9
|
-
* STORY-\d+-\d+, CR-\d+, BUG-\d+, EPIC-\d+, PROPOSAL-\d+ (PROP-\d+ normalised),
|
|
10
|
-
* HOTFIX-\d+
|
|
11
|
-
* then checks that each has a corresponding pending-sync/<ID>_*.md file under
|
|
12
|
-
* the repo root, and that each present file is approved + structurally non-empty.
|
|
13
|
-
*
|
|
14
|
-
* Exit 0: all work-item files present, approved, and non-empty (prints summary to stdout)
|
|
15
|
-
* Exit 1: one or more missing / unapproved / stub-empty (prints structured stderr)
|
|
16
|
-
* Exit 2: usage / parse error
|
|
17
|
-
*
|
|
18
|
-
* Env:
|
|
19
|
-
* CLEARGATE_REPO_ROOT override repo root (for test isolation)
|
|
20
|
-
* CLEARGATE_EXEC_MODE override execution_mode ('v1'|'v2') — for test isolation
|
|
21
|
-
*
|
|
22
|
-
* Returns (from assertWorkItemFiles):
|
|
23
|
-
* { missing: string[], present: string[], unapproved: string[], empty: string[] }
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import fs from 'node:fs';
|
|
27
|
-
import path from 'node:path';
|
|
28
|
-
import { fileURLToPath } from 'node:url';
|
|
29
|
-
|
|
30
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
-
|
|
32
|
-
// Resolve repo root: .cleargate/scripts/ -> ../../ (two levels up)
|
|
33
|
-
const REPO_ROOT = process.env.CLEARGATE_REPO_ROOT
|
|
34
|
-
? path.resolve(process.env.CLEARGATE_REPO_ROOT)
|
|
35
|
-
: path.resolve(__dirname, '..', '..');
|
|
36
|
-
|
|
37
|
-
function usage() {
|
|
38
|
-
process.stderr.write('Usage: node assert_story_files.mjs <sprint-file-path>\n');
|
|
39
|
-
process.exit(2);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Extract the "## 1. Consolidated Deliverables" section from sprint markdown.
|
|
44
|
-
* Returns the section text or null if not found.
|
|
45
|
-
*
|
|
46
|
-
* Strategy: split on ^## headings, find the one starting with "1. Consolidated Deliverables".
|
|
47
|
-
* This avoids regex lookahead pitfalls with end-of-string anchors in JS.
|
|
48
|
-
*/
|
|
49
|
-
function extractDeliverablesSection(content) {
|
|
50
|
-
// Split on lines that start a new ## section (lookahead keeps delimiter in next part)
|
|
51
|
-
const parts = content.split(/^(?=## )/m);
|
|
52
|
-
const deliverables = parts.find((p) =>
|
|
53
|
-
/^## 1\.? Consolidated Deliverables\b/m.test(p)
|
|
54
|
-
);
|
|
55
|
-
if (!deliverables) return null;
|
|
56
|
-
// Strip the header line itself, return the rest
|
|
57
|
-
return deliverables.replace(/^## [^\n]*\n/, '');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Extract deduplicated work-item IDs from a text block.
|
|
62
|
-
*
|
|
63
|
-
* ID shapes (longest-alternative-first to avoid prefix collisions):
|
|
64
|
-
* STORY-\d+-\d+ (e.g. STORY-022-07)
|
|
65
|
-
* CR-\d+ (e.g. CR-008)
|
|
66
|
-
* BUG-\d+ (e.g. BUG-007)
|
|
67
|
-
* EPIC-\d+ (e.g. EPIC-013)
|
|
68
|
-
* HOTFIX-\d+ (e.g. HOTFIX-001)
|
|
69
|
-
* PROPOSAL-\d+ (e.g. PROPOSAL-013)
|
|
70
|
-
* PROP-\d+ normalised to PROPOSAL-NNN post-extract (BUG-009 lesson)
|
|
71
|
-
*
|
|
72
|
-
* STORY before CR/BUG/EPIC/HOTFIX, PROPOSAL before PROP — BUG-010 longest-first rule.
|
|
73
|
-
*/
|
|
74
|
-
export function extractWorkItemIds(text) {
|
|
75
|
-
const re = /(STORY-\d+-\d+|(CR|BUG|EPIC|HOTFIX)-\d+|(PROPOSAL|PROP)-\d+)/g;
|
|
76
|
-
const raw = [];
|
|
77
|
-
let m;
|
|
78
|
-
while ((m = re.exec(text)) !== null) {
|
|
79
|
-
raw.push(m[0]);
|
|
80
|
-
}
|
|
81
|
-
// BUG-009 normalize: PROP-NNN → PROPOSAL-NNN
|
|
82
|
-
const normalised = raw.map((id) => id.replace(/^PROP-(\d+)$/, 'PROPOSAL-$1'));
|
|
83
|
-
return [...new Set(normalised)];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Check whether pending-sync OR archive contains a file matching <ID>_*.md
|
|
88
|
-
* Returns the matching absolute path or null.
|
|
89
|
-
*/
|
|
90
|
-
export function findWorkItemFile(repoRoot, workItemId) {
|
|
91
|
-
const searchDirs = [
|
|
92
|
-
path.join(repoRoot, '.cleargate', 'delivery', 'pending-sync'),
|
|
93
|
-
path.join(repoRoot, '.cleargate', 'delivery', 'archive'),
|
|
94
|
-
];
|
|
95
|
-
const prefix = `${workItemId}_`;
|
|
96
|
-
for (const dir of searchDirs) {
|
|
97
|
-
let entries;
|
|
98
|
-
try {
|
|
99
|
-
entries = fs.readdirSync(dir);
|
|
100
|
-
} catch {
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
const match = entries.find(
|
|
104
|
-
(e) => e.startsWith(prefix) && e.endsWith('.md')
|
|
105
|
-
);
|
|
106
|
-
if (match) return path.join(dir, match);
|
|
107
|
-
}
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Inline YAML frontmatter extractor.
|
|
113
|
-
* Returns { approved: boolean, has_heading: boolean }.
|
|
114
|
-
*
|
|
115
|
-
* - approved: frontmatter contains `approved: true` (quoted or unquoted).
|
|
116
|
-
* - has_heading: body after frontmatter contains at least one "## " line.
|
|
117
|
-
*
|
|
118
|
-
* Tolerate files with no frontmatter (approved=false, has_heading per body scan).
|
|
119
|
-
*/
|
|
120
|
-
function assertWorkItemApproved(filePath) {
|
|
121
|
-
let content;
|
|
122
|
-
try {
|
|
123
|
-
content = fs.readFileSync(filePath, 'utf8');
|
|
124
|
-
} catch {
|
|
125
|
-
return { approved: false, has_heading: false };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
let body = content;
|
|
129
|
-
let approved = false;
|
|
130
|
-
|
|
131
|
-
// Match YAML frontmatter block: starts with --- on first line
|
|
132
|
-
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
133
|
-
if (fmMatch) {
|
|
134
|
-
const fmBlock = fmMatch[1];
|
|
135
|
-
body = fmMatch[2] ?? '';
|
|
136
|
-
|
|
137
|
-
// Look for `approved: true` (unquoted) or `approved: "true"` (quoted)
|
|
138
|
-
const approvedMatch = fmBlock.match(/^approved:\s*["']?(true)["']?\s*$/m);
|
|
139
|
-
approved = approvedMatch !== null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// has_heading: body contains at least one "## " markdown heading
|
|
143
|
-
const has_heading = /^## /m.test(body);
|
|
144
|
-
|
|
145
|
-
return { approved, has_heading };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Main assertion logic.
|
|
150
|
-
* Returns { missing: string[], present: string[], unapproved: string[], empty: string[] }
|
|
151
|
-
*
|
|
152
|
-
* - missing: id referenced in §1 with no file in pending-sync/ or archive/
|
|
153
|
-
* - present: id with a file found
|
|
154
|
-
* - unapproved: present but approved: false in frontmatter
|
|
155
|
-
* - empty: present + approved but body has no ## heading (stub)
|
|
156
|
-
*/
|
|
157
|
-
function assertWorkItemFiles(sprintFilePath, repoRoot) {
|
|
158
|
-
let content;
|
|
159
|
-
try {
|
|
160
|
-
content = fs.readFileSync(sprintFilePath, 'utf8');
|
|
161
|
-
} catch (err) {
|
|
162
|
-
process.stderr.write(`Error: cannot read sprint file: ${err.message}\n`);
|
|
163
|
-
process.exit(2);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const section = extractDeliverablesSection(content);
|
|
167
|
-
if (section === null) {
|
|
168
|
-
process.stderr.write(
|
|
169
|
-
'Error: "## 1. Consolidated Deliverables" section not found in sprint file\n'
|
|
170
|
-
);
|
|
171
|
-
process.exit(2);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const workItemIds = extractWorkItemIds(section);
|
|
175
|
-
if (workItemIds.length === 0) {
|
|
176
|
-
process.stderr.write('Warning: no work-item IDs found in §1 Consolidated Deliverables\n');
|
|
177
|
-
// Return empty — no files to check, nothing is missing
|
|
178
|
-
return { missing: [], present: [], unapproved: [], empty: [] };
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const missing = [];
|
|
182
|
-
const present = [];
|
|
183
|
-
const unapproved = [];
|
|
184
|
-
const empty = [];
|
|
185
|
-
|
|
186
|
-
for (const id of workItemIds) {
|
|
187
|
-
const found = findWorkItemFile(repoRoot, id);
|
|
188
|
-
if (found) {
|
|
189
|
-
present.push(id);
|
|
190
|
-
const { approved, has_heading } = assertWorkItemApproved(found);
|
|
191
|
-
if (!approved) {
|
|
192
|
-
unapproved.push(id);
|
|
193
|
-
} else if (!has_heading) {
|
|
194
|
-
empty.push(id);
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
missing.push(id);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return { missing, present, unapproved, empty };
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function main() {
|
|
205
|
-
const args = process.argv.slice(2);
|
|
206
|
-
if (args.length === 0 || args[0].startsWith('--')) usage();
|
|
207
|
-
|
|
208
|
-
const sprintFilePath = path.resolve(args[0]);
|
|
209
|
-
|
|
210
|
-
// CR-027: --emit-json flag — extract work-item IDs and print JSON to stdout.
|
|
211
|
-
// Used by sprint.ts checkPerItemReadinessGates (path-a shell-out protocol).
|
|
212
|
-
// When this flag is present, skip the file-presence/approval triage and exit 0.
|
|
213
|
-
if (args.includes('--emit-json')) {
|
|
214
|
-
let content;
|
|
215
|
-
try {
|
|
216
|
-
content = fs.readFileSync(sprintFilePath, 'utf8');
|
|
217
|
-
} catch (err) {
|
|
218
|
-
process.stderr.write(`Error: cannot read sprint file: ${err.message}\n`);
|
|
219
|
-
process.exit(2);
|
|
220
|
-
}
|
|
221
|
-
const section = extractDeliverablesSection(content);
|
|
222
|
-
if (section === null) {
|
|
223
|
-
// No §1 section found — emit empty list (not an error for this flag)
|
|
224
|
-
process.stdout.write(JSON.stringify({ workItemIds: [] }) + '\n');
|
|
225
|
-
process.exit(0);
|
|
226
|
-
}
|
|
227
|
-
const workItemIds = extractWorkItemIds(section);
|
|
228
|
-
process.stdout.write(JSON.stringify({ workItemIds }) + '\n');
|
|
229
|
-
process.exit(0);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Allow test-isolation override of execution_mode
|
|
233
|
-
const execMode = process.env.CLEARGATE_EXEC_MODE ?? 'v2';
|
|
234
|
-
|
|
235
|
-
const { missing, present, unapproved, empty } = assertWorkItemFiles(sprintFilePath, REPO_ROOT);
|
|
236
|
-
|
|
237
|
-
const hasProblems = missing.length > 0 || unapproved.length > 0 || empty.length > 0;
|
|
238
|
-
|
|
239
|
-
if (!hasProblems) {
|
|
240
|
-
process.stdout.write(
|
|
241
|
-
`OK: all ${present.length} work-item file(s) present, approved, and non-empty in pending-sync/ or archive/\n`
|
|
242
|
-
);
|
|
243
|
-
process.exit(0);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Build structured stderr output
|
|
247
|
-
if (missing.length > 0) {
|
|
248
|
-
process.stderr.write(`MISSING (${missing.length}): ${missing.join(', ')}\n`);
|
|
249
|
-
}
|
|
250
|
-
if (unapproved.length > 0) {
|
|
251
|
-
process.stderr.write(`UNAPPROVED (${unapproved.length}): ${unapproved.join(', ')}\n`);
|
|
252
|
-
}
|
|
253
|
-
if (empty.length > 0) {
|
|
254
|
-
process.stderr.write(`STUB-EMPTY (${empty.length}): ${empty.join(', ')}\n`);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (execMode === 'v2') {
|
|
258
|
-
process.exit(1);
|
|
259
|
-
} else {
|
|
260
|
-
// v1: warn only, exit 0
|
|
261
|
-
process.exit(0);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
main();
|