@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.
- package/dist/authz.js +1 -1
- package/dist/cli-router/route-argv.js +3 -0
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +90 -51
- package/dist/human-presence-mint.d.ts +6 -6
- package/dist/human-presence-mint.js +7 -6
- package/dist/occupancy-grant.d.ts +18 -0
- package/dist/occupancy-grant.js +120 -0
- package/dist/occupancy-heartbeat.d.ts +8 -0
- package/dist/occupancy-heartbeat.js +62 -0
- package/dist/occupancy-release.d.ts +8 -0
- package/dist/occupancy-release.js +62 -0
- package/dist/occupancy-steal.d.ts +1 -0
- package/dist/occupancy-steal.js +32 -4
- package/dist/render-cli/prd-render-cli.js +6 -10
- package/dist/session-ready.d.ts +2 -0
- package/dist/session-ready.js +37 -5
- package/dist/session-start.d.ts +2 -0
- package/dist/session-start.js +39 -6
- package/dist/toolchain-check.d.ts +1 -0
- package/dist/toolchain-check.js +41 -2
- package/dist/triage-actions.js +2 -3
- package/dist/triage-evaluate.d.ts +14 -0
- package/dist/triage-evaluate.js +153 -0
- package/dist/verify-completed-tracked.js +34 -1
- package/dist/verify-completed-write-guard.d.ts +13 -0
- package/dist/verify-completed-write-guard.js +72 -0
- package/dist/verify-pr-closeout-attestable.d.ts +14 -0
- package/dist/verify-pr-closeout-attestable.js +96 -0
- package/dist/verify-subagent-alive.js +5 -1
- package/package.json +3 -3
package/dist/occupancy-steal.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
5
|
-
* resolver (#2132
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
: projectRoot
|
|
36
|
-
|
|
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
|
package/dist/session-ready.d.ts
CHANGED
|
@@ -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. */
|
package/dist/session-ready.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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,
|
package/dist/session-start.d.ts
CHANGED
|
@@ -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. */
|
package/dist/session-start.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/dist/toolchain-check.js
CHANGED
|
@@ -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
|
|
6
|
-
|
|
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
|
}
|
package/dist/triage-actions.js
CHANGED
|
@@ -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
|
-
|
|
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
|