@deftai/directive 0.103.0 → 0.105.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/authz.d.ts +4 -29
- package/dist/authz.js +16 -181
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +16 -0
- package/dist/human-presence-mint.d.ts +61 -0
- package/dist/human-presence-mint.js +192 -0
- package/dist/occupancy-steal.d.ts +9 -0
- package/dist/occupancy-steal.js +54 -0
- package/dist/scm-sync-default.d.ts +34 -0
- package/dist/scm-sync-default.js +210 -0
- package/dist/scope-record-approved-scope.d.ts +6 -1
- package/dist/scope-record-approved-scope.js +72 -24
- package/dist/session-start.d.ts +4 -0
- package/dist/session-start.js +23 -0
- package/dist/verify-ac.d.ts +2 -0
- package/dist/verify-ac.js +74 -8
- package/dist/verify-completed-tracked.d.ts +2 -1
- package/dist/verify-completed-tracked.js +31 -1
- package/dist/verify-literal-ac.js +7 -0
- package/dist/verify-orphan-active.d.ts +1 -0
- package/dist/verify-orphan-active.js +30 -0
- package/dist/verify-session-ritual.d.ts +10 -2
- package/dist/verify-session-ritual.js +16 -3
- package/dist/verify-source-cli/verify-telemetry-coverage.d.ts +13 -0
- package/dist/verify-source-cli/verify-telemetry-coverage.js +67 -0
- package/package.json +3 -3
package/dist/verify-ac.js
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
10
10
|
import { join, resolve } from "node:path";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { resolveSessionCompletedVerifyAcTarget } from "@deftai/directive-core/check";
|
|
12
13
|
import { formatRejectedLedger, resolveLiteralAcceptanceDetailed, } from "@deftai/directive-core/literal-acceptance";
|
|
13
|
-
import { evaluateVerifyAcFromPath, readPlanAcceptance, } from "@deftai/directive-core/product-first-done-gate";
|
|
14
|
+
import { emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, readPlanAcceptance, resolveAcceptanceGateProfile, } from "@deftai/directive-core/product-first-done-gate";
|
|
14
15
|
/** Parse verify:ac CLI args. */
|
|
15
16
|
export function parseArgs(argv) {
|
|
16
17
|
const parsed = {
|
|
@@ -102,9 +103,20 @@ function listActiveXbriefs(projectRoot) {
|
|
|
102
103
|
dir: dirs.join(" + "),
|
|
103
104
|
};
|
|
104
105
|
}
|
|
106
|
+
/** Three-state exit: pass=0, fail=1, config=2. A printed pass must not leak 201. */
|
|
107
|
+
export function clampVerifyAcExit(ok, code) {
|
|
108
|
+
if (ok)
|
|
109
|
+
return 0;
|
|
110
|
+
if (code === 2)
|
|
111
|
+
return 2;
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
105
114
|
/** Evaluate one or many xBRIEF paths; return worst non-zero code (fail closed). */
|
|
106
115
|
function evaluatePaths(paths, options) {
|
|
107
116
|
let worst = 0;
|
|
117
|
+
// One shared option profile per reader (#3497) — scope:complete resolves its own
|
|
118
|
+
// profile from the same table, so the two readers cannot drift apart again.
|
|
119
|
+
const profile = resolveAcceptanceGateProfile(options.softMissingXbrief ? "check" : "standalone");
|
|
108
120
|
for (const path of paths) {
|
|
109
121
|
if (!options.quiet && paths.length > 1) {
|
|
110
122
|
process.stdout.write(`verify:ac — evaluating ${path}\n`);
|
|
@@ -113,7 +125,9 @@ function evaluatePaths(paths, options) {
|
|
|
113
125
|
projectRoot: options.projectRoot,
|
|
114
126
|
quiet: options.quiet,
|
|
115
127
|
softMissingXbrief: options.softMissingXbrief,
|
|
116
|
-
checkIntegrated:
|
|
128
|
+
checkIntegrated: profile.checkIntegrated,
|
|
129
|
+
captureFromNarratives: profile.captureFromNarratives,
|
|
130
|
+
reuseMode: profile.reuseMode,
|
|
117
131
|
env: process.env,
|
|
118
132
|
});
|
|
119
133
|
if (result.message.length > 0) {
|
|
@@ -124,9 +138,10 @@ function evaluatePaths(paths, options) {
|
|
|
124
138
|
process.stderr.write(`${result.message}\n`);
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
|
-
|
|
141
|
+
const code = clampVerifyAcExit(result.ok, result.code);
|
|
142
|
+
if (code !== 0 && (worst === 0 || code > worst)) {
|
|
128
143
|
// Prefer code 1 (fail) over 2 when both present — still non-zero.
|
|
129
|
-
worst =
|
|
144
|
+
worst = code;
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
return worst;
|
|
@@ -142,6 +157,11 @@ export function run(argv) {
|
|
|
142
157
|
const args = parseArgs(argv);
|
|
143
158
|
if (args.error !== undefined) {
|
|
144
159
|
process.stderr.write(`verify_ac: ${args.error}\n`);
|
|
160
|
+
emitVerifyAcTerminalOutcome({
|
|
161
|
+
projectRoot: resolve(args.projectRoot),
|
|
162
|
+
env: process.env,
|
|
163
|
+
outcome: "config-error",
|
|
164
|
+
});
|
|
145
165
|
return 2;
|
|
146
166
|
}
|
|
147
167
|
const projectRoot = resolve(args.projectRoot);
|
|
@@ -167,19 +187,55 @@ export function run(argv) {
|
|
|
167
187
|
" Pass an explicit path, or use check composition (--soft-missing-xbrief) to evaluate all.\n" +
|
|
168
188
|
" Usage: task verify:ac -- <path-to-active.xbrief.json>\n" +
|
|
169
189
|
" Refs #3284 product-first done-gate\n");
|
|
190
|
+
emitVerifyAcTerminalOutcome({
|
|
191
|
+
projectRoot,
|
|
192
|
+
env: process.env,
|
|
193
|
+
outcome: "config-error",
|
|
194
|
+
});
|
|
170
195
|
return 1;
|
|
171
196
|
}
|
|
172
197
|
}
|
|
173
198
|
else if (args.softMissingXbrief) {
|
|
174
|
-
|
|
199
|
+
const completed = resolveSessionCompletedVerifyAcTarget({
|
|
200
|
+
projectRoot,
|
|
201
|
+
env: process.env,
|
|
202
|
+
});
|
|
203
|
+
if (completed.kind === "target") {
|
|
204
|
+
paths = [completed.path];
|
|
205
|
+
if (!args.quiet) {
|
|
206
|
+
process.stdout.write(`verify:ac targeting just-completed brief (#3357): ${completed.path}\n`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (completed.kind === "cannot") {
|
|
210
|
+
process.stderr.write(`${completed.message}\n`);
|
|
211
|
+
emitVerifyAcTerminalOutcome({
|
|
212
|
+
projectRoot,
|
|
213
|
+
env: process.env,
|
|
214
|
+
outcome: "config-error",
|
|
215
|
+
});
|
|
216
|
+
return 1;
|
|
217
|
+
}
|
|
218
|
+
else if (!args.quiet) {
|
|
175
219
|
process.stdout.write("verify:ac skipped (#3284 soft-missing): no active xBRIEF in xbrief/active/\n");
|
|
176
220
|
}
|
|
177
|
-
|
|
221
|
+
if (completed.kind === "none") {
|
|
222
|
+
emitVerifyAcTerminalOutcome({
|
|
223
|
+
projectRoot,
|
|
224
|
+
env: process.env,
|
|
225
|
+
outcome: "soft-missing",
|
|
226
|
+
});
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
178
229
|
}
|
|
179
230
|
else {
|
|
180
231
|
process.stderr.write("verify_ac: pass an xBRIEF path or ensure exactly one artifact in xbrief/active/\n" +
|
|
181
232
|
" Usage: task verify:ac -- <path-to-active.xbrief.json>\n" +
|
|
182
233
|
" Refs #3284 product-first done-gate (mechanism #3267)\n");
|
|
234
|
+
emitVerifyAcTerminalOutcome({
|
|
235
|
+
projectRoot,
|
|
236
|
+
env: process.env,
|
|
237
|
+
outcome: "config-error",
|
|
238
|
+
});
|
|
183
239
|
return 2;
|
|
184
240
|
}
|
|
185
241
|
}
|
|
@@ -200,14 +256,24 @@ export function run(argv) {
|
|
|
200
256
|
}
|
|
201
257
|
const acceptance = readPlanAcceptance(plan);
|
|
202
258
|
const resolved = resolveLiteralAcceptanceDetailed(plan, { captureFromNarratives: true });
|
|
259
|
+
// Executor reads plan.acceptance.commands when the #3267 ledger is empty (#3449).
|
|
260
|
+
const executorCommands = resolved.commands.length > 0
|
|
261
|
+
? resolved.commands
|
|
262
|
+
: acceptance.commands.map((c) => ({
|
|
263
|
+
command: c.command,
|
|
264
|
+
source: "explicit",
|
|
265
|
+
sourceSpan: "plan.acceptance.commands",
|
|
266
|
+
cwd: c.cwd ?? null,
|
|
267
|
+
expectedExitCode: c.expectedExitCode ?? 0,
|
|
268
|
+
}));
|
|
203
269
|
reports.push({
|
|
204
270
|
xbrief: xbriefPath,
|
|
205
271
|
source_rung: acceptance.source_rung,
|
|
206
272
|
none_stated: acceptance.none_stated,
|
|
207
273
|
acceptance_commands: acceptance.commands,
|
|
208
|
-
count:
|
|
274
|
+
count: executorCommands.length,
|
|
209
275
|
rejected_count: resolved.rejected.length,
|
|
210
|
-
commands:
|
|
276
|
+
commands: executorCommands.map((c) => ({
|
|
211
277
|
command: c.command,
|
|
212
278
|
source: c.source,
|
|
213
279
|
sourceSpan: c.sourceSpan ?? null,
|
|
@@ -3,11 +3,12 @@ interface ParsedArgs {
|
|
|
3
3
|
projectRoot: string;
|
|
4
4
|
repo: string | null;
|
|
5
5
|
tip: string | null;
|
|
6
|
+
issue: number | null;
|
|
6
7
|
quiet: boolean;
|
|
7
8
|
skipGh: boolean;
|
|
8
9
|
error?: string;
|
|
9
10
|
}
|
|
10
|
-
/** Parse verify-completed-tracked CLI args (#3264). */
|
|
11
|
+
/** Parse verify-completed-tracked CLI args (#3264 / #3476). */
|
|
11
12
|
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
12
13
|
/** Run the gate and return the process exit code. */
|
|
13
14
|
export declare function run(argv: string[]): number;
|
|
@@ -2,12 +2,21 @@
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { evaluateCompletedTracked } from "@deftai/directive-core/lifecycle";
|
|
5
|
-
|
|
5
|
+
function parseIssueNumber(raw) {
|
|
6
|
+
const trimmed = raw.startsWith("#") ? raw.slice(1) : raw;
|
|
7
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const value = Number(trimmed);
|
|
11
|
+
return Number.isInteger(value) && value > 0 ? value : null;
|
|
12
|
+
}
|
|
13
|
+
/** Parse verify-completed-tracked CLI args (#3264 / #3476). */
|
|
6
14
|
export function parseArgs(argv) {
|
|
7
15
|
const parsed = {
|
|
8
16
|
projectRoot: ".",
|
|
9
17
|
repo: null,
|
|
10
18
|
tip: null,
|
|
19
|
+
issue: null,
|
|
11
20
|
quiet: false,
|
|
12
21
|
skipGh: false,
|
|
13
22
|
};
|
|
@@ -52,6 +61,26 @@ export function parseArgs(argv) {
|
|
|
52
61
|
else if (arg?.startsWith("--tip=")) {
|
|
53
62
|
parsed.tip = arg.slice("--tip=".length);
|
|
54
63
|
}
|
|
64
|
+
else if (arg === "--issue") {
|
|
65
|
+
const value = argv[i + 1];
|
|
66
|
+
if (value === undefined) {
|
|
67
|
+
return { ...parsed, error: "argument --issue: expected one argument" };
|
|
68
|
+
}
|
|
69
|
+
const issue = parseIssueNumber(value);
|
|
70
|
+
if (issue === null) {
|
|
71
|
+
return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
|
|
72
|
+
}
|
|
73
|
+
parsed.issue = issue;
|
|
74
|
+
i += 1;
|
|
75
|
+
}
|
|
76
|
+
else if (arg?.startsWith("--issue=")) {
|
|
77
|
+
const value = arg.slice("--issue=".length);
|
|
78
|
+
const issue = parseIssueNumber(value);
|
|
79
|
+
if (issue === null) {
|
|
80
|
+
return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
|
|
81
|
+
}
|
|
82
|
+
parsed.issue = issue;
|
|
83
|
+
}
|
|
55
84
|
else {
|
|
56
85
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
57
86
|
}
|
|
@@ -70,6 +99,7 @@ export function run(argv) {
|
|
|
70
99
|
quiet: args.quiet,
|
|
71
100
|
repo: args.repo,
|
|
72
101
|
tip: args.tip,
|
|
102
|
+
issue: args.issue,
|
|
73
103
|
skipGh: args.skipGh,
|
|
74
104
|
});
|
|
75
105
|
if (result.message.length > 0) {
|
|
@@ -128,6 +128,13 @@ export function run(argv) {
|
|
|
128
128
|
reason: r.reason,
|
|
129
129
|
sourceSpan: r.sourceSpan ?? null,
|
|
130
130
|
})),
|
|
131
|
+
// Prose-derived captures demoted by structured acceptance commands (#3484).
|
|
132
|
+
advisory_rejected_count: resolved.advisoryRejected.length,
|
|
133
|
+
advisory_rejected: resolved.advisoryRejected.map((r) => ({
|
|
134
|
+
command: r.command,
|
|
135
|
+
reason: r.reason,
|
|
136
|
+
sourceSpan: r.sourceSpan ?? null,
|
|
137
|
+
})),
|
|
131
138
|
};
|
|
132
139
|
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
133
140
|
if (resolved.rejected.length > 0) {
|
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { evaluate } from "@deftai/directive-core/orphan-active";
|
|
5
|
+
function parseIssueNumber(raw) {
|
|
6
|
+
const trimmed = raw.startsWith("#") ? raw.slice(1) : raw;
|
|
7
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const value = Number(trimmed);
|
|
11
|
+
return Number.isInteger(value) && value > 0 ? value : null;
|
|
12
|
+
}
|
|
5
13
|
/** Parse verify-orphan-active CLI args. */
|
|
6
14
|
export function parseArgs(argv) {
|
|
7
15
|
const parsed = {
|
|
8
16
|
projectRoot: ".",
|
|
9
17
|
repo: null,
|
|
18
|
+
issue: null,
|
|
10
19
|
quiet: false,
|
|
11
20
|
skipGh: false,
|
|
12
21
|
};
|
|
@@ -40,6 +49,26 @@ export function parseArgs(argv) {
|
|
|
40
49
|
else if (arg?.startsWith("--repo=")) {
|
|
41
50
|
parsed.repo = arg.slice("--repo=".length);
|
|
42
51
|
}
|
|
52
|
+
else if (arg === "--issue") {
|
|
53
|
+
const value = argv[i + 1];
|
|
54
|
+
if (value === undefined) {
|
|
55
|
+
return { ...parsed, error: "argument --issue: expected one argument" };
|
|
56
|
+
}
|
|
57
|
+
const issue = parseIssueNumber(value);
|
|
58
|
+
if (issue === null) {
|
|
59
|
+
return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
|
|
60
|
+
}
|
|
61
|
+
parsed.issue = issue;
|
|
62
|
+
i += 1;
|
|
63
|
+
}
|
|
64
|
+
else if (arg?.startsWith("--issue=")) {
|
|
65
|
+
const value = arg.slice("--issue=".length);
|
|
66
|
+
const issue = parseIssueNumber(value);
|
|
67
|
+
if (issue === null) {
|
|
68
|
+
return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
|
|
69
|
+
}
|
|
70
|
+
parsed.issue = issue;
|
|
71
|
+
}
|
|
43
72
|
else {
|
|
44
73
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
45
74
|
}
|
|
@@ -58,6 +87,7 @@ export function run(argv) {
|
|
|
58
87
|
quiet: args.quiet,
|
|
59
88
|
repo: args.repo,
|
|
60
89
|
skipGh: args.skipGh,
|
|
90
|
+
issue: args.issue,
|
|
61
91
|
});
|
|
62
92
|
if (result.message.length > 0) {
|
|
63
93
|
if (result.stream === "stdout") {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { type DirectivePosture } from "@deftai/directive-core/session";
|
|
2
|
+
import { type DirectivePosture, type VerifyResult } from "@deftai/directive-core/session";
|
|
3
|
+
export interface VerifySessionRitualRunDeps {
|
|
4
|
+
readonly verifySessionRitual?: (projectRoot: string, options: {
|
|
5
|
+
tier: "quick" | "gated";
|
|
6
|
+
posture?: DirectivePosture;
|
|
7
|
+
}) => VerifyResult;
|
|
8
|
+
}
|
|
3
9
|
interface ParsedArgs {
|
|
4
10
|
projectRoot: string;
|
|
5
11
|
tier: "quick" | "gated";
|
|
@@ -9,7 +15,9 @@ interface ParsedArgs {
|
|
|
9
15
|
}
|
|
10
16
|
/** Parse verify-session-ritual CLI args, mirroring scripts/verify_session_ritual.py. */
|
|
11
17
|
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
18
|
+
/** True when the ritual failure is the gated cache_fresh step (#3506 / #3507). */
|
|
19
|
+
export declare function isCacheFreshFailureMessage(message: string): boolean;
|
|
12
20
|
/** Run the gate and return the process exit code. */
|
|
13
|
-
export declare function run(argv: string[]): number;
|
|
21
|
+
export declare function run(argv: string[], deps?: VerifySessionRitualRunDeps): number;
|
|
14
22
|
export {};
|
|
15
23
|
//# sourceMappingURL=verify-session-ritual.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { emitBypassWarning, emitVerifyJson, verifySessionRitual, } from "@deftai/directive-core/session";
|
|
4
|
+
import { emitBypassWarning, emitVerifyJson, formatCacheFreshDeferSoftPath, formatRitualRecoveryInstruction, verifySessionRitual, } from "@deftai/directive-core/session";
|
|
5
5
|
function parsePosture(value) {
|
|
6
6
|
if (value === "read-only")
|
|
7
7
|
return "read-only";
|
|
@@ -86,15 +86,20 @@ export function parseArgs(argv) {
|
|
|
86
86
|
}
|
|
87
87
|
return parsed;
|
|
88
88
|
}
|
|
89
|
+
/** True when the ritual failure is the gated cache_fresh step (#3506 / #3507). */
|
|
90
|
+
export function isCacheFreshFailureMessage(message) {
|
|
91
|
+
return message.includes("cache_fresh") || message.includes("cache-fresh");
|
|
92
|
+
}
|
|
89
93
|
/** Run the gate and return the process exit code. */
|
|
90
|
-
export function run(argv) {
|
|
94
|
+
export function run(argv, deps = {}) {
|
|
91
95
|
const args = parseArgs(argv);
|
|
92
96
|
if (args.error !== undefined) {
|
|
93
97
|
process.stderr.write(`verify_session_ritual: ${args.error}\n`);
|
|
94
98
|
return 2;
|
|
95
99
|
}
|
|
96
100
|
const projectRoot = resolve(args.projectRoot);
|
|
97
|
-
const
|
|
101
|
+
const verify = deps.verifySessionRitual ?? verifySessionRitual;
|
|
102
|
+
const result = verify(projectRoot, {
|
|
98
103
|
tier: args.tier,
|
|
99
104
|
posture: args.posture ?? undefined,
|
|
100
105
|
});
|
|
@@ -108,6 +113,14 @@ export function run(argv) {
|
|
|
108
113
|
process.stdout.write(`${result.message}\n`);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
116
|
+
else if (result.code === 1) {
|
|
117
|
+
const recovery = formatRitualRecoveryInstruction(result.recoveryTier ?? "cold");
|
|
118
|
+
const lines = [result.message, recovery];
|
|
119
|
+
if (isCacheFreshFailureMessage(result.message)) {
|
|
120
|
+
lines.push(formatCacheFreshDeferSoftPath());
|
|
121
|
+
}
|
|
122
|
+
process.stderr.write(`${lines.join("\n")}\n`);
|
|
123
|
+
}
|
|
111
124
|
else {
|
|
112
125
|
process.stderr.write(`${result.message}\n`);
|
|
113
126
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface ParsedArgs {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
enforce: boolean;
|
|
5
|
+
help?: boolean;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Parse verify-telemetry-coverage CLI args (#3362). */
|
|
9
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
10
|
+
/** Run the gate and return the process exit code. */
|
|
11
|
+
export declare function run(argv: string[]): number;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=verify-telemetry-coverage.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI for task verify:telemetry-coverage (#3362).
|
|
4
|
+
* Warn-only by default; pass --enforce to fail closed.
|
|
5
|
+
*/
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { evaluateTelemetryCoverage } from "@deftai/directive-core/verify-source";
|
|
9
|
+
/** Parse verify-telemetry-coverage CLI args (#3362). */
|
|
10
|
+
export function parseArgs(argv) {
|
|
11
|
+
const parsed = { projectRoot: ".", enforce: false };
|
|
12
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
13
|
+
const arg = argv[i];
|
|
14
|
+
if (arg === "--project-root") {
|
|
15
|
+
const value = argv[i + 1];
|
|
16
|
+
if (value === undefined) {
|
|
17
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
18
|
+
}
|
|
19
|
+
parsed.projectRoot = value;
|
|
20
|
+
i += 1;
|
|
21
|
+
}
|
|
22
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
23
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
24
|
+
}
|
|
25
|
+
else if (arg === "--enforce") {
|
|
26
|
+
parsed.enforce = true;
|
|
27
|
+
}
|
|
28
|
+
else if (arg === "--help" || arg === "-h") {
|
|
29
|
+
return { ...parsed, help: true };
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
const HELP_TEXT = "Usage: verify-telemetry-coverage [--project-root <path>] [--enforce]\n" +
|
|
38
|
+
" Dead-surface detector for run-summary event kinds (#3362).\n" +
|
|
39
|
+
" Default: warn-only (exit 0 with advisory report).\n" +
|
|
40
|
+
" --enforce: fail closed (exit 1) when a kind has no caller or fixture.\n";
|
|
41
|
+
/** Run the gate and return the process exit code. */
|
|
42
|
+
export function run(argv) {
|
|
43
|
+
const args = parseArgs(argv);
|
|
44
|
+
if (args.help === true) {
|
|
45
|
+
process.stdout.write(HELP_TEXT);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
if (args.error !== undefined) {
|
|
49
|
+
process.stderr.write(`verify_telemetry_coverage: ${args.error}\n`);
|
|
50
|
+
return 2;
|
|
51
|
+
}
|
|
52
|
+
const result = evaluateTelemetryCoverage({
|
|
53
|
+
projectRoot: resolve(args.projectRoot),
|
|
54
|
+
enforce: args.enforce,
|
|
55
|
+
});
|
|
56
|
+
if (result.stream === "stdout") {
|
|
57
|
+
process.stdout.write(`${result.message}\n`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
process.stderr.write(`${result.message}\n`);
|
|
61
|
+
}
|
|
62
|
+
return result.code;
|
|
63
|
+
}
|
|
64
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
65
|
+
process.exit(run(process.argv.slice(2)));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=verify-telemetry-coverage.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.105.0",
|
|
4
4
|
"description": "Directive CLI — npm install path for the Deft Directive framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://deftai.github.io/directive/",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"provenance": true
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@deftai/directive-core": "^0.
|
|
38
|
-
"@deftai/directive-content": "^0.
|
|
37
|
+
"@deftai/directive-core": "^0.105.0",
|
|
38
|
+
"@deftai/directive-content": "^0.105.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b"
|