@encore-os/eos-spec 0.8.0 → 0.10.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/dist/commands/archive.js +1 -1
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/close-out.d.ts +2 -0
- package/dist/commands/close-out.js +167 -0
- package/dist/commands/close-out.js.map +1 -0
- package/dist/commands/complete.js +81 -4
- package/dist/commands/complete.js.map +1 -1
- package/dist/commands/conformance.js +20 -1
- package/dist/commands/conformance.js.map +1 -1
- package/dist/commands/create.js +6 -6
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/funnel.js +7 -0
- package/dist/commands/funnel.js.map +1 -1
- package/dist/commands/metrics.js +15 -0
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/next.d.ts +10 -4
- package/dist/commands/next.js +23 -12
- package/dist/commands/next.js.map +1 -1
- package/dist/commands/proceed.d.ts +48 -0
- package/dist/commands/proceed.js +144 -0
- package/dist/commands/proceed.js.map +1 -0
- package/dist/commands/reconcile.js +7 -1
- package/dist/commands/reconcile.js.map +1 -1
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +238 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scorecard.d.ts +24 -0
- package/dist/commands/scorecard.js +49 -3
- package/dist/commands/scorecard.js.map +1 -1
- package/dist/commands/signoff.js +3 -2
- package/dist/commands/signoff.js.map +1 -1
- package/dist/commands/status.js +7 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tasks.d.ts +7 -0
- package/dist/commands/tasks.js +13 -1
- package/dist/commands/tasks.js.map +1 -1
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +46 -7
- package/dist/commands/validate.js.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ai-call.d.ts +12 -0
- package/dist/lib/ai-call.js +6 -0
- package/dist/lib/ai-call.js.map +1 -1
- package/dist/lib/closeout-core.d.ts +46 -0
- package/dist/lib/closeout-core.js +34 -0
- package/dist/lib/closeout-core.js.map +1 -0
- package/dist/lib/closeout-predicate.d.ts +36 -0
- package/dist/lib/closeout-predicate.js +130 -0
- package/dist/lib/closeout-predicate.js.map +1 -0
- package/dist/lib/config.d.ts +10 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cost.js +7 -0
- package/dist/lib/cost.js.map +1 -1
- package/dist/lib/coverage-gate.d.ts +43 -0
- package/dist/lib/coverage-gate.js +54 -0
- package/dist/lib/coverage-gate.js.map +1 -0
- package/dist/lib/events.d.ts +12 -0
- package/dist/lib/events.js +8 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +23 -1
- package/dist/lib/frontmatter.js +37 -0
- package/dist/lib/frontmatter.js.map +1 -1
- package/dist/lib/funnel.d.ts +5 -0
- package/dist/lib/funnel.js +2 -1
- package/dist/lib/funnel.js.map +1 -1
- package/dist/lib/gate-executor.d.ts +80 -0
- package/dist/lib/gate-executor.js +311 -0
- package/dist/lib/gate-executor.js.map +1 -0
- package/dist/lib/llm-health.d.ts +28 -0
- package/dist/lib/llm-health.js +46 -0
- package/dist/lib/llm-health.js.map +1 -0
- package/dist/lib/metrics.d.ts +26 -0
- package/dist/lib/metrics.js +35 -0
- package/dist/lib/metrics.js.map +1 -1
- package/dist/lib/next-action.d.ts +10 -4
- package/dist/lib/next-action.js +10 -4
- package/dist/lib/next-action.js.map +1 -1
- package/dist/lib/ollama-embed.d.ts +5 -0
- package/dist/lib/ollama-embed.js +5 -0
- package/dist/lib/ollama-embed.js.map +1 -1
- package/dist/lib/output.d.ts +3 -0
- package/dist/lib/output.js +3 -0
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/pipeline-config.js +10 -0
- package/dist/lib/pipeline-config.js.map +1 -1
- package/dist/lib/pipeline-map.d.ts +24 -0
- package/dist/lib/pipeline-map.js +54 -5
- package/dist/lib/pipeline-map.js.map +1 -1
- package/dist/lib/predicate-registry.js +7 -0
- package/dist/lib/predicate-registry.js.map +1 -1
- package/dist/lib/reconcile-core.d.ts +20 -3
- package/dist/lib/reconcile-core.js +16 -6
- package/dist/lib/reconcile-core.js.map +1 -1
- package/dist/lib/run-pipeline.d.ts +118 -0
- package/dist/lib/run-pipeline.js +106 -0
- package/dist/lib/run-pipeline.js.map +1 -0
- package/dist/lib/scorecard.d.ts +5 -0
- package/dist/lib/scorecard.js +1 -0
- package/dist/lib/scorecard.js.map +1 -1
- package/dist/lib/spec-pure.d.ts +69 -4
- package/dist/lib/spec-pure.js +129 -15
- package/dist/lib/spec-pure.js.map +1 -1
- package/dist/lib/specs.d.ts +9 -3
- package/dist/lib/specs.js +43 -20
- package/dist/lib/specs.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/with-event-log.js +17 -3
- package/dist/lib/with-event-log.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { addClaim, DEFAULT_TTL_MINUTES, releaseClaim } from '../lib/claims.js';
|
|
4
|
+
import { DEFAULT_LLM_BASE_URL, DEFAULT_LOCAL_MODEL, directModelExecutor, } from '../lib/gate-executor.js';
|
|
5
|
+
import { ErrorCode, emit, getGlobalOptions } from '../lib/output.js';
|
|
6
|
+
import { computeStage, isComplianceGated, PIPELINE, rank, stageApplies } from '../lib/pipeline-map.js';
|
|
7
|
+
import { reconcileSpec } from '../lib/reconcile-core.js';
|
|
8
|
+
import { getRepoRoot } from '../lib/repo.js';
|
|
9
|
+
import { runPipeline } from '../lib/run-pipeline.js';
|
|
10
|
+
import { diagnoseMissingSpec, findSpec } from '../lib/specs.js';
|
|
11
|
+
import { withEventLog } from '../lib/with-event-log.js';
|
|
12
|
+
import { recommendAction } from './next.js';
|
|
13
|
+
/** The cloud model used when a gate escalates off an unhealthy local endpoint —
|
|
14
|
+
* the same resolution ac-backfill uses (gateway via the `ai` SDK). */
|
|
15
|
+
function resolveCloudModel() {
|
|
16
|
+
return process.env.AC_DRAFT_MODEL ?? process.env.JUDGE_MODEL ?? 'anthropic/claude-sonnet-4';
|
|
17
|
+
}
|
|
18
|
+
/** The default LOCAL model — overridable via EOS_SPEC_LLM_MODEL. */
|
|
19
|
+
function resolveLocalModel() {
|
|
20
|
+
return process.env.EOS_SPEC_LLM_MODEL ?? DEFAULT_LOCAL_MODEL;
|
|
21
|
+
}
|
|
22
|
+
/** The LOCAL OpenAI-compatible base URL (Ollama). */
|
|
23
|
+
function resolveBaseUrl() {
|
|
24
|
+
return process.env.EOS_SPEC_LLM_BASE_URL ?? DEFAULT_LLM_BASE_URL;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The planned document-gate sequence from a spec's current state to `until`.
|
|
28
|
+
* Walks the SAME PIPELINE the navigator uses (optional + already-done gates
|
|
29
|
+
* skipped; strictOnly gates skipped UNLESS `strict`), stopping once the gate
|
|
30
|
+
* that completes `until` is included. Used by `--autonomy suggest` (executes
|
|
31
|
+
* nothing) and surfaced on the drive payload. `strict` should be
|
|
32
|
+
* `isComplianceGated(spec)` so regulated/PHI-sensitive specs surface the
|
|
33
|
+
* strictOnly parity gates instead of skipping past them.
|
|
34
|
+
*/
|
|
35
|
+
export function planGates(spec, until, strict) {
|
|
36
|
+
const out = [];
|
|
37
|
+
for (const t of PIPELINE) {
|
|
38
|
+
if (t.optional || (t.strictOnly && !strict))
|
|
39
|
+
continue;
|
|
40
|
+
if (!stageApplies(t, spec))
|
|
41
|
+
continue;
|
|
42
|
+
if (t.isDone(spec))
|
|
43
|
+
continue;
|
|
44
|
+
out.push(t.id);
|
|
45
|
+
if (t.completesStatus && rank(t.completesStatus) >= rank(until))
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
/** Offline/test executor seam: when EOS_SPEC_LLM_FAKE=1 the gate executor skips
|
|
51
|
+
* the network entirely (probe reports healthy, the model returns canned text) so
|
|
52
|
+
* a drive can be exercised end-to-end without a live model. The REAL artifact
|
|
53
|
+
* writers + telemetry still run, so the recommend→execute→reconcile loop is
|
|
54
|
+
* genuinely exercised. */
|
|
55
|
+
function fakeExecutorDeps() {
|
|
56
|
+
return {
|
|
57
|
+
probe: async () => ({ healthy: true, status: 200, ms: 0 }),
|
|
58
|
+
callModel: async ({ endpoint, model }) => ({
|
|
59
|
+
text: `[fake ${endpoint} output from ${model}]`,
|
|
60
|
+
tokens: { prompt: 1, completion: 1, total: 2 },
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Reasons that count as a clean, expected outcome (exit 0). */
|
|
65
|
+
const SUCCESS_REASONS = new Set(['suggested', 'reached-target', 'halt-before-implement']);
|
|
66
|
+
export function registerRun(program) {
|
|
67
|
+
program
|
|
68
|
+
.command('run')
|
|
69
|
+
.description('Autonomously drive a spec next→execute-gate→reconcile to tasks_generated, HALTING before implement. Routes each gate to a LOCAL model (Ollama) by default, escalating to the cloud gateway unless --strict-local.')
|
|
70
|
+
.requiredOption('--spec <id>', 'Spec id to drive (e.g. LO-50)')
|
|
71
|
+
.option('--autonomy <mode>', 'suggest (plan only, write nothing) | drive (advance the spec)', 'drive')
|
|
72
|
+
.option('--until <stage>', 'Stop once the computed stage reaches this status', 'tasks_generated')
|
|
73
|
+
.option('--max-gates <n>', 'Hard bound on executed gates', '8')
|
|
74
|
+
.option('--strict-local', 'Require the local model; HALT (no cloud fallback) if it is unhealthy', false)
|
|
75
|
+
.action(withEventLog('run', async (options, cmd) => {
|
|
76
|
+
const global = getGlobalOptions(cmd);
|
|
77
|
+
const repoRoot = getRepoRoot(global.repoRoot);
|
|
78
|
+
const autonomy = String(options.autonomy);
|
|
79
|
+
if (autonomy !== 'suggest' && autonomy !== 'drive') {
|
|
80
|
+
emit(global, {
|
|
81
|
+
ok: false,
|
|
82
|
+
error: {
|
|
83
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
84
|
+
message: `run: --autonomy must be 'suggest' or 'drive' (got "${autonomy}")`,
|
|
85
|
+
},
|
|
86
|
+
data: null,
|
|
87
|
+
text: `run: --autonomy must be 'suggest' or 'drive' (got "${autonomy}")`,
|
|
88
|
+
});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const until = String(options.until);
|
|
92
|
+
if (rank(until) < 0) {
|
|
93
|
+
emit(global, {
|
|
94
|
+
ok: false,
|
|
95
|
+
error: {
|
|
96
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
97
|
+
message: `run: --until "${until}" is not a known pipeline status`,
|
|
98
|
+
},
|
|
99
|
+
data: null,
|
|
100
|
+
text: `run: --until "${until}" is not a known pipeline status`,
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const maxGates = Number.parseInt(String(options.maxGates), 10);
|
|
105
|
+
if (!Number.isFinite(maxGates) || maxGates < 0) {
|
|
106
|
+
emit(global, {
|
|
107
|
+
ok: false,
|
|
108
|
+
error: {
|
|
109
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
110
|
+
message: `run: --max-gates must be a non-negative integer (got "${options.maxGates}")`,
|
|
111
|
+
},
|
|
112
|
+
data: null,
|
|
113
|
+
text: `run: --max-gates must be a non-negative integer (got "${options.maxGates}")`,
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const spec0 = findSpec(repoRoot, String(options.spec));
|
|
118
|
+
if (!spec0) {
|
|
119
|
+
const diag = diagnoseMissingSpec(repoRoot, String(options.spec));
|
|
120
|
+
emit(global, {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: { code: ErrorCode.SPEC_NOT_FOUND, message: `run: spec ${options.spec} not found (${diag.reason})` },
|
|
123
|
+
data: null,
|
|
124
|
+
text: `run: spec ${options.spec} not found (${diag.reason})`,
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const specId = spec0.id;
|
|
129
|
+
// Compliance-gated specs (regulated core OR PHI/PII-sensitive, #1372) walk the
|
|
130
|
+
// pipeline STRICT: the strictOnly parity gates (research-before-review,
|
|
131
|
+
// revalidate-after-review, compliance-for-sensitive) become blocking instead of
|
|
132
|
+
// being skipped. Non-gated specs get strict=false — byte-identical to today.
|
|
133
|
+
const strict = isComplianceGated(spec0);
|
|
134
|
+
const strictLocal = Boolean(options.strictLocal);
|
|
135
|
+
const baseURL = resolveBaseUrl();
|
|
136
|
+
const localModel = resolveLocalModel();
|
|
137
|
+
const cloudModel = resolveCloudModel();
|
|
138
|
+
const fake = process.env.EOS_SPEC_LLM_FAKE === '1';
|
|
139
|
+
const execDeps = fake ? fakeExecutorDeps() : {};
|
|
140
|
+
// ── suggest: plan only, NO claim, NO writes (AC-7) ───────────────────
|
|
141
|
+
if (autonomy === 'suggest') {
|
|
142
|
+
const result = await runPipeline({
|
|
143
|
+
recommend: () => recommendAction(findSpec(repoRoot, specId), null, repoRoot, { strict }),
|
|
144
|
+
stage: () => computeStage(findSpec(repoRoot, specId)),
|
|
145
|
+
rank,
|
|
146
|
+
execute: async () => ({ ok: true, executor: 'noop' }),
|
|
147
|
+
reconcile: () => { },
|
|
148
|
+
plan: () => planGates(spec0, until, strict),
|
|
149
|
+
}, { autonomy, until, maxGates });
|
|
150
|
+
emit(global, {
|
|
151
|
+
ok: true,
|
|
152
|
+
data: { specId, autonomy, until, plan: result.plan, finalStage: result.finalStage, reason: result.reason },
|
|
153
|
+
text: `run (suggest) ${specId}: ${result.plan?.length ? result.plan.join(' → ') : '(already at/past target — nothing to do)'}\n` +
|
|
154
|
+
` from stage: ${result.finalStage} target: ${until} (executes nothing)`,
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// ── drive: claim, then loop recommend→execute→reconcile ──────────────
|
|
159
|
+
addClaim(repoRoot, specId, {
|
|
160
|
+
by: process.env.EOS_SPEC_CLAIMED_BY ?? basename(repoRoot),
|
|
161
|
+
ttlMinutes: DEFAULT_TTL_MINUTES,
|
|
162
|
+
});
|
|
163
|
+
const execute = async (action) => {
|
|
164
|
+
const fresh = findSpec(repoRoot, specId);
|
|
165
|
+
const specText = readFileSync(fresh.path, 'utf8');
|
|
166
|
+
const r = await directModelExecutor({
|
|
167
|
+
gate: action.type,
|
|
168
|
+
spec: fresh,
|
|
169
|
+
repoRoot,
|
|
170
|
+
specText,
|
|
171
|
+
baseURL,
|
|
172
|
+
localModel,
|
|
173
|
+
cloudModel,
|
|
174
|
+
strictLocal,
|
|
175
|
+
autonomy,
|
|
176
|
+
}, execDeps);
|
|
177
|
+
return {
|
|
178
|
+
ok: r.ok,
|
|
179
|
+
executor: r.executor,
|
|
180
|
+
model: r.model,
|
|
181
|
+
escalatedToCloud: r.escalatedToCloud,
|
|
182
|
+
artifacts: r.artifacts,
|
|
183
|
+
error: r.error,
|
|
184
|
+
halt: r.halt,
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
let result;
|
|
188
|
+
try {
|
|
189
|
+
result = await runPipeline({
|
|
190
|
+
recommend: () => recommendAction(findSpec(repoRoot, specId), null, repoRoot, { strict }),
|
|
191
|
+
stage: () => computeStage(findSpec(repoRoot, specId)),
|
|
192
|
+
rank,
|
|
193
|
+
execute,
|
|
194
|
+
reconcile: () => {
|
|
195
|
+
reconcileSpec(repoRoot, findSpec(repoRoot, specId), true);
|
|
196
|
+
},
|
|
197
|
+
plan: () => planGates(spec0, until, strict),
|
|
198
|
+
}, { autonomy, until, maxGates });
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
// Always release the lease, even if the loop threw — emit() never returns.
|
|
202
|
+
releaseClaim(repoRoot, specId);
|
|
203
|
+
}
|
|
204
|
+
const ok = SUCCESS_REASONS.has(result.reason);
|
|
205
|
+
const localGates = result.events.filter((e) => !e.escalatedToCloud).length;
|
|
206
|
+
const cloudGates = result.events.length - localGates;
|
|
207
|
+
const artifacts = result.events.flatMap((e) => e.artifacts ?? []);
|
|
208
|
+
const lines = [
|
|
209
|
+
`run (drive) ${specId}: ${result.reason} at stage ${result.finalStage}`,
|
|
210
|
+
` gates executed: ${result.events.length} (local=${localGates}, cloud=${cloudGates})`,
|
|
211
|
+
...result.events.map((e) => ` - ${e.gate}: ${e.ok ? 'ok' : `FAILED (${e.error ?? 'unknown'})`}${e.escalatedToCloud ? ' [escalated→cloud]' : ''}`),
|
|
212
|
+
...(result.resumeHint ? [` resume: ${result.resumeHint}`] : []),
|
|
213
|
+
...(artifacts.length ? [` wrote: ${artifacts.join(', ')}`] : []),
|
|
214
|
+
];
|
|
215
|
+
emit(global, {
|
|
216
|
+
ok,
|
|
217
|
+
data: {
|
|
218
|
+
specId,
|
|
219
|
+
autonomy,
|
|
220
|
+
until,
|
|
221
|
+
strictLocal,
|
|
222
|
+
reason: result.reason,
|
|
223
|
+
finalStage: result.finalStage,
|
|
224
|
+
haltedAt: result.haltedAt ?? null,
|
|
225
|
+
resumeHint: result.resumeHint ?? null,
|
|
226
|
+
gatesExecuted: result.events.length,
|
|
227
|
+
localGates,
|
|
228
|
+
cloudGates,
|
|
229
|
+
events: result.events,
|
|
230
|
+
artifacts,
|
|
231
|
+
},
|
|
232
|
+
exitCode: ok ? 0 : 1,
|
|
233
|
+
text: lines.join('\n'),
|
|
234
|
+
...(ok ? {} : { error: { code: ErrorCode.SUBPROCESS_ERROR, message: `run halted: ${result.reason}` } }),
|
|
235
|
+
});
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
+
import { evaluateCoverageGate, resolveCoverageThreshold } from '../lib/coverage-gate.js';
|
|
3
|
+
import type { ScorecardRow } from '../lib/scorecard.js';
|
|
4
|
+
/** Per-spec coverage-vs-threshold gate fields (Component 3 of the D2 design):
|
|
5
|
+
* surfaced on `eos-spec scorecard` so a spec's `complete` gate verdict is
|
|
6
|
+
* visible BEFORE completion is attempted. Reuses the exact pure functions
|
|
7
|
+
* `complete` gates on (`resolveCoverageThreshold` / `evaluateCoverageGate`),
|
|
8
|
+
* so the two never drift. `coverageGate: 'no-gate'` (and null ratio/threshold
|
|
9
|
+
* fields) when the consuming repo never opted into `gate_thresholds` —
|
|
10
|
+
* matches the gate's fully-opt-in design. */
|
|
11
|
+
export type ScorecardCoverageFields = {
|
|
12
|
+
coverageRatio: number;
|
|
13
|
+
coverageThreshold: number | null;
|
|
14
|
+
coverageGate: ReturnType<typeof evaluateCoverageGate>['gate'];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Attach coverage-gate fields to every scorecard row. `config` is `null` when
|
|
18
|
+
* the repo has no `specs/config.yaml` (or it failed to load) — every row then
|
|
19
|
+
* reads as `no-gate`, matching `complete`'s fail-open behavior.
|
|
20
|
+
*/
|
|
21
|
+
export declare function withCoverageGate(rows: ScorecardRow[], config: Parameters<typeof resolveCoverageThreshold>[0] | null): (ScorecardRow & ScorecardCoverageFields)[];
|
|
22
|
+
/** Short human-readable coverage suffix for one row, e.g. ` cov 3/5 (60%) ⛔blocked`.
|
|
23
|
+
* Omitted entirely (returns '') for `no-gate` rows — the common case for a repo
|
|
24
|
+
* that never opted into `gate_thresholds` should not get noisy per-row suffixes. */
|
|
25
|
+
export declare function coverageSuffix(row: ScorecardRow & ScorecardCoverageFields): string;
|
|
2
26
|
/**
|
|
3
27
|
* Validate `--core` against the canonical cores list. A bogus core used to fall through to
|
|
4
28
|
* listSpecs() → 0 specs → an all-zero scorecard with exit 0 — dangerously plausible output.
|
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
import { loadConfig } from '../lib/config.js';
|
|
2
|
+
import { evaluateCoverageGate, resolveCoverageThreshold } from '../lib/coverage-gate.js';
|
|
1
3
|
import { ErrorCode, emit, getGlobalOptions } from '../lib/output.js';
|
|
2
4
|
import { coresList, getRepoRoot, isKnownCore } from '../lib/repo.js';
|
|
3
5
|
import { buildScorecardForCore } from '../lib/scorecard-run.js';
|
|
4
6
|
import { scanVerifies } from '../lib/verifies-scan.js';
|
|
5
7
|
import { withEventLog } from '../lib/with-event-log.js';
|
|
8
|
+
/**
|
|
9
|
+
* Attach coverage-gate fields to every scorecard row. `config` is `null` when
|
|
10
|
+
* the repo has no `specs/config.yaml` (or it failed to load) — every row then
|
|
11
|
+
* reads as `no-gate`, matching `complete`'s fail-open behavior.
|
|
12
|
+
*/
|
|
13
|
+
export function withCoverageGate(rows, config) {
|
|
14
|
+
return rows.map((row) => {
|
|
15
|
+
const coverageRatio = row.requirementsTotal === 0 ? 1 : row.requirementsVerified / row.requirementsTotal;
|
|
16
|
+
const coverageThreshold = config ? resolveCoverageThreshold(config, row.core) : null;
|
|
17
|
+
const coverageGate = evaluateCoverageGate({
|
|
18
|
+
ratio: coverageRatio,
|
|
19
|
+
threshold: coverageThreshold,
|
|
20
|
+
hasWaiver: row.hasCoverageWaiver,
|
|
21
|
+
}).gate;
|
|
22
|
+
return { ...row, coverageRatio, coverageThreshold, coverageGate };
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** Short human-readable coverage suffix for one row, e.g. ` cov 3/5 (60%) ⛔blocked`.
|
|
26
|
+
* Omitted entirely (returns '') for `no-gate` rows — the common case for a repo
|
|
27
|
+
* that never opted into `gate_thresholds` should not get noisy per-row suffixes. */
|
|
28
|
+
export function coverageSuffix(row) {
|
|
29
|
+
if (row.coverageGate === 'no-gate')
|
|
30
|
+
return '';
|
|
31
|
+
const pct = Math.round(row.coverageRatio * 100);
|
|
32
|
+
const badge = row.coverageGate === 'pass' ? '✓pass' : row.coverageGate === 'waived' ? 'waived' : '⛔blocked';
|
|
33
|
+
return ` cov ${row.requirementsVerified}/${row.requirementsTotal} (${pct}%) ${badge}`;
|
|
34
|
+
}
|
|
6
35
|
/**
|
|
7
36
|
* Validate `--core` against the canonical cores list. A bogus core used to fall through to
|
|
8
37
|
* listSpecs() → 0 specs → an all-zero scorecard with exit 0 — dangerously plausible output.
|
|
@@ -35,7 +64,21 @@ export function registerScorecard(program) {
|
|
|
35
64
|
}
|
|
36
65
|
const verifiedBySpec = scanVerifies(repoRoot);
|
|
37
66
|
const report = buildScorecardForCore(repoRoot, resolved.core, verifiedBySpec);
|
|
38
|
-
|
|
67
|
+
// D2 Component 3: surface each spec's coverage-vs-threshold gate status —
|
|
68
|
+
// the same verdict `eos-spec complete` would reach — so it's visible BEFORE
|
|
69
|
+
// completion is attempted. Fail-open (mirrors complete.ts): a repo with no
|
|
70
|
+
// specs/config.yaml (or an override that doesn't resolve) sees every row as
|
|
71
|
+
// 'no-gate', matching the fully opt-in gate design.
|
|
72
|
+
let config = null;
|
|
73
|
+
try {
|
|
74
|
+
config = loadConfig(repoRoot, global.config);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
config = null;
|
|
78
|
+
}
|
|
79
|
+
const rows = withCoverageGate(report.rows, config);
|
|
80
|
+
const gated = rows.filter((r) => r.coverageGate !== 'no-gate');
|
|
81
|
+
const flagged = rows.filter((r) => r.claimedCompleteButUnverified);
|
|
39
82
|
const text = [
|
|
40
83
|
`Readiness scorecard (${report.core}): ${report.total} specs`,
|
|
41
84
|
` claims complete : ${report.claimsComplete}`,
|
|
@@ -45,11 +88,14 @@ export function registerScorecard(program) {
|
|
|
45
88
|
...(flagged.length
|
|
46
89
|
? [
|
|
47
90
|
' Claimed complete but unverified:',
|
|
48
|
-
...flagged.map((r) => ` ${r.id} (${r.stage}, ${r.requirementsVerified}/${r.requirementsTotal} reqs verified)`),
|
|
91
|
+
...flagged.map((r) => ` ${r.id} (${r.stage}, ${r.requirementsVerified}/${r.requirementsTotal} reqs verified)${coverageSuffix(r)}`),
|
|
49
92
|
]
|
|
50
93
|
: [' None claimed-complete-but-unverified.']),
|
|
94
|
+
...(gated.length
|
|
95
|
+
? ['', ' Coverage vs threshold:', ...gated.map((r) => ` ${r.id}${coverageSuffix(r)}`)]
|
|
96
|
+
: []),
|
|
51
97
|
].join('\n');
|
|
52
|
-
emit(global, { ok: true, data: report, text });
|
|
98
|
+
emit(global, { ok: true, data: { ...report, rows }, text });
|
|
53
99
|
}));
|
|
54
100
|
}
|
|
55
101
|
//# sourceMappingURL=scorecard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scorecard.js","sourceRoot":"","sources":["../../src/commands/scorecard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"scorecard.js","sourceRoot":"","sources":["../../src/commands/scorecard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAexD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAoB,EACpB,MAA6D;IAE7D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,MAAM,aAAa,GAAG,GAAG,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,oBAAoB,GAAG,GAAG,CAAC,iBAAiB,CAAC;QACzG,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrF,MAAM,YAAY,GAAG,oBAAoB,CAAC;YACxC,KAAK,EAAE,aAAa;YACpB,SAAS,EAAE,iBAAiB;YAC5B,SAAS,EAAE,GAAG,CAAC,iBAAiB;SACjC,CAAC,CAAC,IAAI,CAAC;QACR,OAAO,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;qFAEqF;AACrF,MAAM,UAAU,cAAc,CAAC,GAA2C;IACxE,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;IAC5G,OAAO,QAAQ,GAAG,CAAC,oBAAoB,IAAI,GAAG,CAAC,iBAAiB,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwB,EAAE,QAAgB;IAC1E,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACnE,OAAO,EAAE,KAAK,EAAE,4BAA4B,IAAI,mBAAmB,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CACV,yJAAyJ,CAC1J;SACA,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC;SAC5C,MAAM,CACL,YAAY,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAc,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,EAAE;gBACX,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE;gBAChE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;gBAC7D,IAAI,EAAE,QAAQ,CAAC,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAE9E,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,4EAA4E;QAC5E,oDAAoD;QACpD,IAAI,MAAM,GAAyC,IAAI,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG;YACX,wBAAwB,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,QAAQ;YAC7D,mCAAmC,MAAM,CAAC,cAAc,EAAE;YAC1D,mCAAmC,MAAM,CAAC,4BAA4B,0CAA0C;YAChH,mCAAmC,MAAM,CAAC,wBAAwB,EAAE;YACpE,EAAE;YACF,GAAG,CAAC,OAAO,CAAC,MAAM;gBAChB,CAAC,CAAC;oBACE,oCAAoC;oBACpC,GAAG,OAAO,CAAC,GAAG,CACZ,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,iBAAiB,kBAAkB,cAAc,CAAC,CAAC,CAAC,EAAE,CAClH;iBACF;gBACH,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC;YAChD,GAAG,CAAC,KAAK,CAAC,MAAM;gBACd,CAAC,CAAC,CAAC,EAAE,EAAE,0BAA0B,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1F,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
|
package/dist/commands/signoff.js
CHANGED
|
@@ -16,6 +16,7 @@ const VALID_TYPES = [
|
|
|
16
16
|
'ui-gate-waived',
|
|
17
17
|
'submit-e2e-waived',
|
|
18
18
|
'compliance',
|
|
19
|
+
'coverage-waived',
|
|
19
20
|
];
|
|
20
21
|
/** Today's date in YYYY-MM-DD form in the operator's LOCAL timezone, suitable for
|
|
21
22
|
* sign-off markers. Local (not UTC) so an evening sign-off doesn't stamp tomorrow. */
|
|
@@ -26,9 +27,9 @@ function isoToday() {
|
|
|
26
27
|
export function registerSignoff(program) {
|
|
27
28
|
program
|
|
28
29
|
.command('signoff')
|
|
29
|
-
.description("Write a sign-off marker (validated | spec-reviewed | revalidated-after-review | ux-reviewed | heal-verified | docshots | ui-gate-waived | submit-e2e-waived | compliance) to a spec; idempotent. By default recomputes the spec's pipeline_status afterward (--no-reconcile to skip).")
|
|
30
|
+
.description("Write a sign-off marker (validated | spec-reviewed | revalidated-after-review | ux-reviewed | heal-verified | docshots | ui-gate-waived | submit-e2e-waived | compliance | coverage-waived) to a spec; idempotent. By default recomputes the spec's pipeline_status afterward (--no-reconcile to skip).")
|
|
30
31
|
.requiredOption('--spec <id>', 'Spec id (e.g. PM-21)')
|
|
31
|
-
.requiredOption('--type <type>', 'Marker: validated | spec-reviewed | revalidated-after-review | ux-reviewed | heal-verified | docshots | ui-gate-waived | submit-e2e-waived | compliance')
|
|
32
|
+
.requiredOption('--type <type>', 'Marker: validated | spec-reviewed | revalidated-after-review | ux-reviewed | heal-verified | docshots | ui-gate-waived | submit-e2e-waived | compliance | coverage-waived')
|
|
32
33
|
.option('--date <YYYY-MM-DD>', 'Override the marker date (default: today)')
|
|
33
34
|
.option('--reviewer <name>', 'Reviewer name (compliance sign-off only)')
|
|
34
35
|
// Finding A item 4: a sign-off is THE artifact-writing transition; auto-reconcile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signoff.js","sourceRoot":"","sources":["../../src/commands/signoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,mBAAmB,EAAoB,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,WAAW,GAA2B;IAC1C,WAAW;IACX,eAAe;IACf,0BAA0B;IAC1B,aAAa;IACb,eAAe;IACf,UAAU;IACV,gBAAgB;IAChB,mBAAmB;IACnB,YAAY;
|
|
1
|
+
{"version":3,"file":"signoff.js","sourceRoot":"","sources":["../../src/commands/signoff.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/status.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
import { loadConfig } from '../lib/config.js';
|
|
3
4
|
import { ErrorCode, emit, getGlobalOptions } from '../lib/output.js';
|
|
4
|
-
import {
|
|
5
|
+
import { isComplianceGated, pipelineForConfig } from '../lib/pipeline-map.js';
|
|
5
6
|
import { getRepoRoot } from '../lib/repo.js';
|
|
6
7
|
import { isClaimedCompleteUnverified } from '../lib/spec-debt.js';
|
|
7
8
|
import { findSpec, listSpecs } from '../lib/specs.js';
|
|
@@ -16,6 +17,10 @@ export function registerStatus(program) {
|
|
|
16
17
|
.action(withEventLog('status', async (options, cmd) => {
|
|
17
18
|
const global = getGlobalOptions(cmd);
|
|
18
19
|
const repoRoot = getRepoRoot(global.repoRoot);
|
|
20
|
+
// Build once per invocation from the repo's own config, so a
|
|
21
|
+
// `pipeline.layout: builder` config computes stage against the builder
|
|
22
|
+
// order instead of the static ENCORE1 default (F-4, #35).
|
|
23
|
+
const { computeStage } = pipelineForConfig(loadConfig(repoRoot, global.config));
|
|
19
24
|
if (options.spec) {
|
|
20
25
|
const spec = findSpec(repoRoot, options.spec, { includeArchived: options.includeArchived });
|
|
21
26
|
if (!spec) {
|
|
@@ -45,6 +50,7 @@ export function registerStatus(program) {
|
|
|
45
50
|
paths: { spec: spec.path, hasContext: spec.hasContext, hasPlan: spec.hasPlan, hasTasks: spec.hasTasks },
|
|
46
51
|
tasks: { total: totalTasks, completed: completedTasks },
|
|
47
52
|
claimedCompleteButUnverified: claimedCompleteUnverified,
|
|
53
|
+
isComplianceGated: isComplianceGated(spec),
|
|
48
54
|
};
|
|
49
55
|
emit(global, {
|
|
50
56
|
ok: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/tasks.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
export declare function registerTasks(program: Command): void;
|
|
3
|
+
/**
|
|
4
|
+
* The per-core insertion guide at `.cursor/skills/_shared/module-phases-tasks.md` is an
|
|
5
|
+
* encoreos-repo artifact, not something every consumer ships. Only append the "review it"
|
|
6
|
+
* suggestion when the file actually exists (F-25) so a repo without it doesn't get a
|
|
7
|
+
* dangling pointer. Exported for unit testing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function moduleTasksHint(repoRoot: string): string;
|
|
3
10
|
/**
|
|
4
11
|
* Rebase relative markdown-link targets written relative to `fromDir` so they
|
|
5
12
|
* resolve from `toDir` instead. In-document (`#…`), absolute (`/…`), and external
|
package/dist/commands/tasks.js
CHANGED
|
@@ -45,10 +45,22 @@ export function registerTasks(program) {
|
|
|
45
45
|
emit(global, {
|
|
46
46
|
ok: true,
|
|
47
47
|
data: { target, spec: spec.id },
|
|
48
|
-
text: `tasks: wrote ${relPath(repoRoot, target)}
|
|
48
|
+
text: `tasks: wrote ${relPath(repoRoot, target)}${moduleTasksHint(repoRoot)}`,
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The per-core insertion guide at `.cursor/skills/_shared/module-phases-tasks.md` is an
|
|
54
|
+
* encoreos-repo artifact, not something every consumer ships. Only append the "review it"
|
|
55
|
+
* suggestion when the file actually exists (F-25) so a repo without it doesn't get a
|
|
56
|
+
* dangling pointer. Exported for unit testing.
|
|
57
|
+
*/
|
|
58
|
+
export function moduleTasksHint(repoRoot) {
|
|
59
|
+
const hintRel = '.cursor/skills/_shared/module-phases-tasks.md';
|
|
60
|
+
return existsSync(join(repoRoot, '.cursor', 'skills', '_shared', 'module-phases-tasks.md'))
|
|
61
|
+
? `\nReview the per-core insertions in ${hintRel}`
|
|
62
|
+
: '';
|
|
63
|
+
}
|
|
52
64
|
function relPath(repoRoot, p) {
|
|
53
65
|
return p.startsWith(repoRoot) ? p.slice(repoRoot.length + 1) : p;
|
|
54
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,13 @@ export type ValidateIssue = {
|
|
|
5
5
|
rule: string;
|
|
6
6
|
message: string;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Build the `ValidateIssue`s for any spec id claimed by more than one primary spec
|
|
10
|
+
* (issue #27, mode b). One issue per colliding id, naming every offending path, so the
|
|
11
|
+
* old silent lowest-path-wins drop becomes a loud, actionable failure. Pure over the
|
|
12
|
+
* already-listed corpus — `findDuplicateSpecIds` does the fs-free grouping.
|
|
13
|
+
*/
|
|
14
|
+
export declare function duplicateIdIssues(specs: SpecFile[]): ValidateIssue[];
|
|
8
15
|
export type TemplateValidatorDecision = {
|
|
9
16
|
run: true;
|
|
10
17
|
} | {
|