@deftai/directive 0.106.0 → 0.108.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.
@@ -3,6 +3,7 @@ export declare function parseArgs(argv: readonly string[]): {
3
3
  projectRoot: string;
4
4
  confirm: boolean;
5
5
  occupant: string | null;
6
+ sessionId?: string;
6
7
  error?: string;
7
8
  };
8
9
  export declare function run(argv: readonly string[]): number;
@@ -10,25 +10,52 @@ export function parseArgs(argv) {
10
10
  }
11
11
  else if (arg === "--occupant") {
12
12
  const value = argv[i + 1];
13
- if (value === undefined) {
13
+ if (value === undefined || value.startsWith("--")) {
14
14
  return { ...parsed, error: "argument --occupant: expected one argument" };
15
15
  }
16
16
  parsed.occupant = value;
17
17
  i += 1;
18
18
  }
19
19
  else if (arg?.startsWith("--occupant=")) {
20
- parsed.occupant = arg.slice("--occupant=".length);
20
+ const value = arg.slice("--occupant=".length);
21
+ if (value.length === 0 || value.startsWith("--")) {
22
+ return { ...parsed, error: "argument --occupant: expected one argument" };
23
+ }
24
+ parsed.occupant = value;
21
25
  }
22
26
  else if (arg === "--project-root") {
23
27
  const value = argv[i + 1];
24
- if (value === undefined) {
28
+ if (value === undefined || value.startsWith("--")) {
25
29
  return { ...parsed, error: "argument --project-root: expected one argument" };
26
30
  }
27
31
  parsed.projectRoot = value;
28
32
  i += 1;
29
33
  }
30
34
  else if (arg?.startsWith("--project-root=")) {
31
- parsed.projectRoot = arg.slice("--project-root=".length);
35
+ const value = arg.slice("--project-root=".length);
36
+ if (value.length === 0 || value.startsWith("--")) {
37
+ return { ...parsed, error: "argument --project-root: expected one argument" };
38
+ }
39
+ parsed.projectRoot = value;
40
+ }
41
+ else if (arg === "--session-id") {
42
+ const value = argv[i + 1];
43
+ if (value === undefined || value.startsWith("--")) {
44
+ return { ...parsed, error: "argument --session-id: expected one argument" };
45
+ }
46
+ const sessionId = value.trim();
47
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
48
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
49
+ }
50
+ parsed.sessionId = sessionId;
51
+ i += 1;
52
+ }
53
+ else if (arg?.startsWith("--session-id=")) {
54
+ const sessionId = arg.slice("--session-id=".length).trim();
55
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
56
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
57
+ }
58
+ parsed.sessionId = sessionId;
32
59
  }
33
60
  else {
34
61
  return { ...parsed, error: `unrecognized argument: ${arg}` };
@@ -43,6 +70,7 @@ export function run(argv) {
43
70
  return 2;
44
71
  }
45
72
  const result = stealOccupancy(resolve(args.projectRoot), {
73
+ sessionId: args.sessionId,
46
74
  confirm: args.confirm,
47
75
  occupant: args.occupant ?? undefined,
48
76
  env: process.env,
@@ -1,13 +1,11 @@
1
1
  /**
2
2
  * Thin CLI wrapper for prd-render (mirrors ``scripts/prd_render.py``).
3
3
  *
4
- * Supports `--project-root <dir>` to resolve the spec artifact via the layout
5
- * resolver (#2132), preferring `xbrief/specification.xbrief.json` on migrated
6
- * trees and falling back to `vbrief/specification.vbrief.json` on legacy trees.
4
+ * Supports `--project-root <dir>` to resolve full-spec or greenfield authority
5
+ * through the shared authority resolver (#2132 / #3598).
7
6
  * When `--spec` is explicitly provided it takes precedence over `--project-root`.
8
7
  * Direct `--spec` / `--output` / `--force` flags are still accepted unchanged.
9
8
  */
10
- import { layout } from "@deftai/directive-core";
11
9
  import { parsePrdArgv, prdRenderMain } from "@deftai/directive-core/render";
12
10
  function parsePrdRenderCliArgv(argv) {
13
11
  const remaining = [];
@@ -30,12 +28,10 @@ function parsePrdRenderCliArgv(argv) {
30
28
  export function runPrdRenderCli(argv) {
31
29
  const { projectRoot, remaining } = parsePrdRenderCliArgv(argv);
32
30
  const parsedArgs = parsePrdArgv(remaining);
33
- const spec = parsedArgs.spec !== undefined
34
- ? parsedArgs.spec
35
- : projectRoot !== undefined
36
- ? layout.resolveSpecArtifactPath(projectRoot)
37
- : undefined;
38
- prdRenderMain({ ...parsedArgs, spec });
31
+ prdRenderMain({
32
+ ...parsedArgs,
33
+ projectRoot: parsedArgs.spec === undefined ? projectRoot : undefined,
34
+ });
39
35
  return 0;
40
36
  }
41
37
  //# sourceMappingURL=prd-render-cli.js.map
@@ -4,6 +4,8 @@ export interface ParsedSessionReadyArgs {
4
4
  emitJson: boolean;
5
5
  withNetwork: boolean;
6
6
  repo: string | null;
7
+ /** #3611: explicit lifecycle owner injected by a host hook bridge. */
8
+ sessionId: string | null;
7
9
  error?: string;
8
10
  }
9
11
  /** Parse session:ready CLI args. */
@@ -15,6 +15,7 @@ export function parseArgs(argv) {
15
15
  emitJson: false,
16
16
  withNetwork: false,
17
17
  repo: null,
18
+ sessionId: null,
18
19
  };
19
20
  for (let i = 0; i < argv.length; i += 1) {
20
21
  const arg = argv[i];
@@ -33,13 +34,13 @@ export function parseArgs(argv) {
33
34
  if (arg === "--help" || arg === "-h") {
34
35
  return {
35
36
  ...parsed,
36
- error: "usage: session:ready [--project-root <path>] [--repo OWNER/NAME] [--with-network] [--json]\n" +
37
+ error: "usage: session:ready [--project-root <path>] [--repo OWNER/NAME] [--session-id <id>] [--with-network] [--json]\n" +
37
38
  " One-shot recovery: session:start (if needed) + gated ritual + cache recovery (#2993).",
38
39
  };
39
40
  }
40
41
  if (arg === "--project-root") {
41
42
  const value = argv[i + 1];
42
- if (value === undefined) {
43
+ if (value === undefined || value.startsWith("--")) {
43
44
  return { ...parsed, error: "argument --project-root: expected one argument" };
44
45
  }
45
46
  parsed.projectRoot = value;
@@ -47,12 +48,37 @@ export function parseArgs(argv) {
47
48
  continue;
48
49
  }
49
50
  if (arg.startsWith("--project-root=")) {
50
- parsed.projectRoot = arg.slice("--project-root=".length);
51
+ const value = arg.slice("--project-root=".length);
52
+ if (value.length === 0 || value.startsWith("--")) {
53
+ return { ...parsed, error: "argument --project-root: expected one argument" };
54
+ }
55
+ parsed.projectRoot = value;
56
+ continue;
57
+ }
58
+ if (arg === "--session-id") {
59
+ const value = argv[i + 1];
60
+ if (value === undefined || value.startsWith("--")) {
61
+ return { ...parsed, error: "argument --session-id: expected one argument" };
62
+ }
63
+ const sessionId = value.trim();
64
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
65
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
66
+ }
67
+ parsed.sessionId = sessionId;
68
+ i += 1;
69
+ continue;
70
+ }
71
+ if (arg.startsWith("--session-id=")) {
72
+ const sessionId = arg.slice("--session-id=".length).trim();
73
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
74
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
75
+ }
76
+ parsed.sessionId = sessionId;
51
77
  continue;
52
78
  }
53
79
  if (arg === "--repo") {
54
80
  const value = argv[i + 1];
55
- if (value === undefined) {
81
+ if (value === undefined || value.startsWith("--")) {
56
82
  return { ...parsed, error: "argument --repo: expected one argument" };
57
83
  }
58
84
  parsed.repo = value;
@@ -60,7 +86,11 @@ export function parseArgs(argv) {
60
86
  continue;
61
87
  }
62
88
  if (arg.startsWith("--repo=")) {
63
- parsed.repo = arg.slice("--repo=".length);
89
+ const value = arg.slice("--repo=".length);
90
+ if (value.length === 0 || value.startsWith("--")) {
91
+ return { ...parsed, error: "argument --repo: expected one argument" };
92
+ }
93
+ parsed.repo = value;
64
94
  continue;
65
95
  }
66
96
  if (arg.startsWith("-")) {
@@ -80,6 +110,7 @@ export function run(argv = process.argv.slice(2)) {
80
110
  const projectRoot = resolve(args.projectRoot);
81
111
  const result = runSessionReady(projectRoot, {
82
112
  repo: args.repo,
113
+ sessionId: args.sessionId ?? undefined,
83
114
  sessionStartOptions: {
84
115
  allowOptionalNetwork: args.withNetwork ? true : undefined,
85
116
  writeHistory: false,
@@ -89,6 +120,7 @@ export function run(argv = process.argv.slice(2)) {
89
120
  process.stdout.write(`${JSON.stringify({
90
121
  ready: result.code === 0,
91
122
  exit_code: result.code,
123
+ session_id: result.sessionId,
92
124
  path: result.path,
93
125
  message: result.message,
94
126
  steps: result.steps,
@@ -36,6 +36,8 @@ export interface ParsedSessionStartArgs {
36
36
  steal: boolean;
37
37
  confirm: boolean;
38
38
  occupant: string | null;
39
+ /** #3611: explicit lifecycle owner injected by a host hook bridge. */
40
+ sessionId: string | null;
39
41
  error?: string;
40
42
  }
41
43
  /** Parse session:start CLI args, mirroring scripts/session_start.py. */
@@ -34,6 +34,7 @@ export function parseArgs(argv) {
34
34
  steal: false,
35
35
  confirm: false,
36
36
  occupant: null,
37
+ sessionId: null,
37
38
  };
38
39
  const dialInputs = {};
39
40
  for (let i = 0; i < argv.length; i += 1) {
@@ -82,25 +83,33 @@ export function parseArgs(argv) {
82
83
  }
83
84
  else if (arg === "--project-root") {
84
85
  const value = argv[i + 1];
85
- if (value === undefined) {
86
+ if (value === undefined || value.startsWith("--")) {
86
87
  return { ...parsed, error: "argument --project-root: expected one argument" };
87
88
  }
88
89
  parsed.projectRoot = value;
89
90
  i += 1;
90
91
  }
91
92
  else if (arg?.startsWith("--project-root=")) {
92
- parsed.projectRoot = arg.slice("--project-root=".length);
93
+ const value = arg.slice("--project-root=".length);
94
+ if (value.length === 0 || value.startsWith("--")) {
95
+ return { ...parsed, error: "argument --project-root: expected one argument" };
96
+ }
97
+ parsed.projectRoot = value;
93
98
  }
94
99
  else if (arg === "--defer") {
95
100
  const value = argv[i + 1];
96
- if (value === undefined) {
101
+ if (value === undefined || value.startsWith("--")) {
97
102
  return { ...parsed, error: "argument --defer: expected one argument" };
98
103
  }
99
104
  parsed.deferValues.push(value);
100
105
  i += 1;
101
106
  }
102
107
  else if (arg?.startsWith("--defer=")) {
103
- parsed.deferValues.push(arg.slice("--defer=".length));
108
+ const value = arg.slice("--defer=".length);
109
+ if (value.length === 0 || value.startsWith("--")) {
110
+ return { ...parsed, error: "argument --defer: expected one argument" };
111
+ }
112
+ parsed.deferValues.push(value);
104
113
  }
105
114
  else if (arg === "--task-size" || arg === "--ceremony-task-size") {
106
115
  const value = argv[i + 1];
@@ -282,16 +291,39 @@ export function parseArgs(argv) {
282
291
  else if (arg === "--confirm") {
283
292
  parsed.confirm = true;
284
293
  }
294
+ else if (arg === "--session-id") {
295
+ const value = argv[i + 1];
296
+ if (value === undefined || value.startsWith("--")) {
297
+ return { ...parsed, error: "argument --session-id: expected one argument" };
298
+ }
299
+ const sessionId = value.trim();
300
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
301
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
302
+ }
303
+ parsed.sessionId = sessionId;
304
+ i += 1;
305
+ }
306
+ else if (arg?.startsWith("--session-id=")) {
307
+ const sessionId = arg.slice("--session-id=".length).trim();
308
+ if (sessionId.length === 0 || sessionId.startsWith("--")) {
309
+ return { ...parsed, error: "argument --session-id: expected a non-empty value" };
310
+ }
311
+ parsed.sessionId = sessionId;
312
+ }
285
313
  else if (arg === "--occupant") {
286
314
  const value = argv[i + 1];
287
- if (value === undefined) {
315
+ if (value === undefined || value.startsWith("--")) {
288
316
  return { ...parsed, error: "argument --occupant: expected one argument" };
289
317
  }
290
318
  parsed.occupant = value;
291
319
  i += 1;
292
320
  }
293
321
  else if (arg?.startsWith("--occupant=")) {
294
- parsed.occupant = arg.slice("--occupant=".length);
322
+ const value = arg.slice("--occupant=".length);
323
+ if (value.length === 0 || value.startsWith("--")) {
324
+ return { ...parsed, error: "argument --occupant: expected one argument" };
325
+ }
326
+ parsed.occupant = value;
295
327
  }
296
328
  else {
297
329
  return { ...parsed, error: `unrecognized argument: ${arg}` };
@@ -358,6 +390,7 @@ export function run(argv) {
358
390
  steal: args.steal ? true : undefined,
359
391
  confirm: args.confirm ? true : undefined,
360
392
  occupant: args.occupant ?? undefined,
393
+ sessionId: args.sessionId ?? undefined,
361
394
  ...(args.ceremonyDepthOverride !== null
362
395
  ? {
363
396
  ceremonyDial: selectCeremonyDepth({
@@ -2,6 +2,7 @@
2
2
  import { type CommandRunner } from "@deftai/directive-core/verify-env";
3
3
  export interface ToolchainCheckRunOptions {
4
4
  readonly runner?: CommandRunner;
5
+ readonly env?: NodeJS.ProcessEnv;
5
6
  }
6
7
  export declare function run(argv?: readonly string[], options?: ToolchainCheckRunOptions): number;
7
8
  //# sourceMappingURL=toolchain-check.d.ts.map
@@ -1,9 +1,48 @@
1
1
  #!/usr/bin/env node
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { runToolchainCheck } from "@deftai/directive-core/verify-env";
4
+ function parseArgs(argv) {
5
+ let consumer = false;
6
+ let projectRoot = process.cwd();
7
+ for (let index = 0; index < argv.length; index += 1) {
8
+ const arg = argv[index] ?? "";
9
+ if (arg === "--consumer") {
10
+ consumer = true;
11
+ continue;
12
+ }
13
+ if (arg === "--project-root") {
14
+ const value = argv[index + 1];
15
+ if (value === undefined || value.trim() === "" || value.startsWith("-")) {
16
+ return { consumer, projectRoot, error: "--project-root requires a path" };
17
+ }
18
+ projectRoot = value;
19
+ index += 1;
20
+ continue;
21
+ }
22
+ if (arg.startsWith("--project-root=")) {
23
+ const value = arg.slice("--project-root=".length);
24
+ if (value.trim() === "") {
25
+ return { consumer, projectRoot, error: "--project-root requires a path" };
26
+ }
27
+ projectRoot = value;
28
+ continue;
29
+ }
30
+ return { consumer, projectRoot, error: `unrecognized argument: ${arg}` };
31
+ }
32
+ return { consumer, projectRoot };
33
+ }
4
34
  export function run(argv = process.argv.slice(2), options = {}) {
5
- const consumer = argv.includes("--consumer");
6
- const result = runToolchainCheck(options.runner, { consumer });
35
+ const parsed = parseArgs(argv);
36
+ if (parsed.error !== undefined) {
37
+ process.stderr.write(`toolchain-check: ${parsed.error}\n`);
38
+ process.stderr.write("Usage: deft toolchain-check [--consumer] [--project-root <path>]\n");
39
+ return 2;
40
+ }
41
+ const result = runToolchainCheck(options.runner, {
42
+ consumer: parsed.consumer,
43
+ projectRoot: parsed.projectRoot,
44
+ env: options.env ?? process.env,
45
+ });
7
46
  for (const line of result.lines) {
8
47
  process.stdout.write(`${line}\n`);
9
48
  }
@@ -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 { accept, createDefaultDeps, deferAction, formatDecision, history, markDuplicate, needsAc, reject, reset, status, TriageError, UpstreamCloseError, } from "@deftai/directive-core/dist/triage/actions/index.js";
4
+ import { accept, createDefaultDeps, deferAction, formatAcceptOutput, formatDecision, history, markDuplicate, needsAc, reject, reset, status, TriageError, UpstreamCloseError, } from "@deftai/directive-core/dist/triage/actions/index.js";
5
5
  const VALID_CMDS = new Set([
6
6
  "accept",
7
7
  "reject",
@@ -158,8 +158,7 @@ export function run(argv) {
158
158
  autoPromote: args.autoPromote === true,
159
159
  force: args.force === true,
160
160
  });
161
- const promoteNote = args.autoPromote === true ? " + auto-promote" : "";
162
- process.stdout.write(`accept #${n} (${repo}) -> ${decisionId}${promoteNote}\n`);
161
+ process.stdout.write(`${formatAcceptOutput(n, repo, decisionId, { autoPromote: args.autoPromote === true })}\n`);
163
162
  }
164
163
  else if (args.cmd === "reject") {
165
164
  const decisionId = reject(n, repo, args.reason ?? "", deps, {
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ interface Parsed {
3
+ projectRoot: string;
4
+ repo: string | null;
5
+ issues: number[];
6
+ concurrency: number;
7
+ json: boolean;
8
+ error?: string;
9
+ }
10
+ export declare function parseArgs(argv: string[]): Parsed;
11
+ export declare function run(argv: string[]): Promise<number>;
12
+ export declare function main(argv: string[]): Promise<number>;
13
+ export {};
14
+ //# sourceMappingURL=triage-evaluate.d.ts.map
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { DEFAULT_CONCURRENCY, EvaluateError, evaluateIssues, renderEvaluateText, } from "@deftai/directive-core/dist/triage/evaluate/index.js";
5
+ import { interceptHelp } from "@deftai/directive-core/dist/triage/help/index.js";
6
+ import { resolveRepo } from "@deftai/directive-core/dist/triage/queue/repo.js";
7
+ export function parseArgs(argv) {
8
+ const parsed = {
9
+ projectRoot: process.env.DEFT_PROJECT_ROOT ?? process.cwd(),
10
+ repo: process.env.DEFT_TRIAGE_REPO ?? null,
11
+ issues: [],
12
+ concurrency: DEFAULT_CONCURRENCY,
13
+ json: false,
14
+ };
15
+ for (let i = 0; i < argv.length; i += 1) {
16
+ const arg = argv[i];
17
+ if (arg === undefined || arg === "--") {
18
+ continue;
19
+ }
20
+ if (arg === "--project-root") {
21
+ if (i + 1 >= argv.length) {
22
+ return { ...parsed, error: "--project-root requires a path" };
23
+ }
24
+ i += 1;
25
+ const value = argv[i];
26
+ if (value === undefined) {
27
+ return { ...parsed, error: "--project-root requires a path" };
28
+ }
29
+ parsed.projectRoot = value;
30
+ }
31
+ else if (arg.startsWith("--project-root=")) {
32
+ parsed.projectRoot = arg.slice("--project-root=".length);
33
+ }
34
+ else if (arg === "--repo") {
35
+ if (i + 1 >= argv.length) {
36
+ return { ...parsed, error: "--repo requires owner/name" };
37
+ }
38
+ i += 1;
39
+ const value = argv[i];
40
+ if (value === undefined) {
41
+ return { ...parsed, error: "--repo requires owner/name" };
42
+ }
43
+ parsed.repo = value;
44
+ }
45
+ else if (arg.startsWith("--repo=")) {
46
+ parsed.repo = arg.slice("--repo=".length);
47
+ }
48
+ else if (arg === "--issue") {
49
+ if (i + 1 >= argv.length) {
50
+ return { ...parsed, error: "--issue requires a number" };
51
+ }
52
+ i += 1;
53
+ const value = argv[i];
54
+ if (value === undefined) {
55
+ return { ...parsed, error: "--issue requires a number" };
56
+ }
57
+ const n = Number.parseInt(value, 10);
58
+ if (!Number.isInteger(n) || n < 1) {
59
+ return { ...parsed, error: `--issue invalid: ${value}` };
60
+ }
61
+ parsed.issues.push(n);
62
+ }
63
+ else if (arg.startsWith("--issue=")) {
64
+ const n = Number.parseInt(arg.slice("--issue=".length), 10);
65
+ if (!Number.isInteger(n) || n < 1) {
66
+ return { ...parsed, error: `--issue invalid: ${arg}` };
67
+ }
68
+ parsed.issues.push(n);
69
+ }
70
+ else if (arg === "--concurrency") {
71
+ if (i + 1 >= argv.length) {
72
+ return { ...parsed, error: "--concurrency requires a positive integer" };
73
+ }
74
+ i += 1;
75
+ const value = argv[i];
76
+ if (value === undefined) {
77
+ return { ...parsed, error: "--concurrency requires a positive integer" };
78
+ }
79
+ const n = Number.parseInt(value, 10);
80
+ if (!Number.isInteger(n) || n < 1) {
81
+ return { ...parsed, error: `--concurrency invalid: ${value}` };
82
+ }
83
+ parsed.concurrency = n;
84
+ }
85
+ else if (arg.startsWith("--concurrency=")) {
86
+ const n = Number.parseInt(arg.slice("--concurrency=".length), 10);
87
+ if (!Number.isInteger(n) || n < 1) {
88
+ return { ...parsed, error: `--concurrency invalid: ${arg}` };
89
+ }
90
+ parsed.concurrency = n;
91
+ }
92
+ else if (arg === "--json") {
93
+ parsed.json = true;
94
+ }
95
+ else if (arg.startsWith("-")) {
96
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
97
+ }
98
+ else {
99
+ const n = Number.parseInt(arg.replace(/^#/u, ""), 10);
100
+ if (!Number.isInteger(n) || n < 1) {
101
+ return { ...parsed, error: `invalid issue number: ${arg}` };
102
+ }
103
+ parsed.issues.push(n);
104
+ }
105
+ }
106
+ return parsed;
107
+ }
108
+ export async function run(argv) {
109
+ const help = interceptHelp("triage_evaluate", argv);
110
+ if (help !== null) {
111
+ return help;
112
+ }
113
+ const parsed = parseArgs(argv);
114
+ if (parsed.error !== undefined) {
115
+ process.stderr.write(`triage:evaluate: ${parsed.error}\n`);
116
+ return 2;
117
+ }
118
+ const projectRoot = resolve(parsed.projectRoot);
119
+ const repo = resolveRepo(parsed.repo, projectRoot);
120
+ if (repo === null) {
121
+ process.stderr.write("triage:evaluate: --repo owner/name is required\n");
122
+ return 2;
123
+ }
124
+ try {
125
+ const result = await evaluateIssues({
126
+ projectRoot,
127
+ repo,
128
+ issues: parsed.issues,
129
+ concurrency: parsed.concurrency,
130
+ });
131
+ if (parsed.json) {
132
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
133
+ }
134
+ else {
135
+ process.stdout.write(renderEvaluateText(result));
136
+ }
137
+ return result.verdicts.some((v) => v.error !== null) ? 1 : 0;
138
+ }
139
+ catch (err) {
140
+ const message = err instanceof EvaluateError ? err.message : String(err);
141
+ process.stderr.write(`triage:evaluate: ${message}\n`);
142
+ return err instanceof EvaluateError ? 2 : 1;
143
+ }
144
+ }
145
+ export async function main(argv) {
146
+ return run(argv);
147
+ }
148
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
149
+ void run(process.argv.slice(2)).then((code) => {
150
+ process.exit(code);
151
+ });
152
+ }
153
+ //# sourceMappingURL=triage-evaluate.js.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 { evaluateCompletedTracked } from "@deftai/directive-core/lifecycle";
4
+ import { COMPLETED_TRACKED_PROGRESS_MIN_BLOBS, COMPLETED_TRACKED_PROGRESS_THRESHOLD_MS, evaluateCompletedTracked, shouldAnnounceProgress, shouldAnnounceUpFrontCount, } from "@deftai/directive-core/lifecycle";
5
5
  function parseIssueNumber(raw) {
6
6
  const trimmed = raw.startsWith("#") ? raw.slice(1) : raw;
7
7
  if (!/^\d+$/.test(trimmed)) {
@@ -95,12 +95,27 @@ export function run(argv) {
95
95
  return 2;
96
96
  }
97
97
  const projectRoot = resolve(args.projectRoot);
98
+ const thresholdMs = resolveProgressThresholdMs();
99
+ let announced = false;
98
100
  const result = evaluateCompletedTracked(projectRoot, {
99
101
  quiet: args.quiet,
100
102
  repo: args.repo,
101
103
  tip: args.tip,
102
104
  issue: args.issue,
103
105
  skipGh: args.skipGh,
106
+ onProgress: (event) => {
107
+ if (args.quiet || announced) {
108
+ return;
109
+ }
110
+ const minBlobs = resolveProgressMinBlobs();
111
+ const upFront = event.phase === "listed" &&
112
+ shouldAnnounceUpFrontCount(event.terminalCount, event.nonterminalCount, minBlobs);
113
+ if (!upFront && !shouldAnnounceProgress(event.elapsedMs, thresholdMs)) {
114
+ return;
115
+ }
116
+ announced = true;
117
+ writeProgress(event);
118
+ },
104
119
  });
105
120
  if (result.message.length > 0) {
106
121
  if (result.stream === "stdout") {
@@ -112,6 +127,24 @@ export function run(argv) {
112
127
  }
113
128
  return result.code;
114
129
  }
130
+ function resolveProgressThresholdMs() {
131
+ const raw = process.env.DEFT_COMPLETED_TRACKED_PROGRESS_MS;
132
+ if (raw !== undefined && /^\d+$/.test(raw)) {
133
+ return Number(raw);
134
+ }
135
+ return COMPLETED_TRACKED_PROGRESS_THRESHOLD_MS;
136
+ }
137
+ function resolveProgressMinBlobs() {
138
+ const raw = process.env.DEFT_COMPLETED_TRACKED_PROGRESS_MIN_BLOBS;
139
+ if (raw !== undefined && /^\d+$/.test(raw)) {
140
+ return Number(raw);
141
+ }
142
+ return COMPLETED_TRACKED_PROGRESS_MIN_BLOBS;
143
+ }
144
+ function writeProgress(event) {
145
+ process.stderr.write(`verify:completed-tracked: still running (${event.elapsedMs}ms); ` +
146
+ `reading ${event.terminalCount} terminal and ${event.nonterminalCount} nonterminal blobs.\n`);
147
+ }
115
148
  if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
116
149
  process.exit(run(process.argv.slice(2)));
117
150
  }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ baseRef: string;
5
+ quiet: boolean;
6
+ error?: string;
7
+ }
8
+ /** Parse verify-completed-write-guard CLI args (#3679). */
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-completed-write-guard.d.ts.map