@deftai/directive 0.106.0 → 0.107.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 +15 -0
- package/dist/human-presence-mint.d.ts +6 -6
- package/dist/human-presence-mint.js +7 -6
- package/dist/occupancy-release.d.ts +7 -0
- package/dist/occupancy-release.js +38 -0
- 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/package.json +3 -3
package/dist/authz.js
CHANGED
|
@@ -225,7 +225,7 @@ function helpText() {
|
|
|
225
225
|
" (grant / uat-start / uat-suspend / revoke) — no TTY, --confirm, or phrase path.",
|
|
226
226
|
" Self-approval under UAT is impossible by construction. Mint grants BEFORE uat-start.",
|
|
227
227
|
"Outside UAT, mutating verbs require multi-factor human presence (#3110):",
|
|
228
|
-
" - Interactive TTY (stdin+stdout) + controlling terminal (/dev/tty
|
|
228
|
+
" - Interactive TTY (stdin+stdout) + controlling terminal (/dev/tty|\\\\.\\CONIN$)",
|
|
229
229
|
" - Explicit --confirm (argv flag alone never enough)",
|
|
230
230
|
" - Typed phrase 'mint' on the controlling TTY (PTY+--confirm alone never enough)",
|
|
231
231
|
" - Known agent/CI env markers always refuse (fail-closed).",
|
|
@@ -197,6 +197,9 @@ function routeNamespaceVerb(ns, verb, rest) {
|
|
|
197
197
|
return { kind: "dispatch", argv: [verifyStem, ...rest] };
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
+
if (ns === "scm" && verb === "issue:design-critique-chip") {
|
|
201
|
+
return { kind: "dispatch", argv: ["scm", "issue", "design-critique-chip", ...rest] };
|
|
202
|
+
}
|
|
200
203
|
if (ns === "issue" && verb === "ingest") {
|
|
201
204
|
return { kind: "dispatch", argv: ["issue-ingest", ...rest] };
|
|
202
205
|
}
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface DispatchIo {
|
|
|
10
10
|
writeErr: (text: string) => void;
|
|
11
11
|
}
|
|
12
12
|
/** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
|
|
13
|
-
export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "scope-record-approved-scope", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-skill-external-fetch-gate", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-lifecycle-visible", "verify-completed-tracked", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "eval-health", "eval-run", "eval-report", "eval-triggers"];
|
|
13
|
+
export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "scope-record-approved-scope", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-skill-external-fetch-gate", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "eval-health", "eval-run", "eval-report", "eval-triggers"];
|
|
14
14
|
/** Core-only CLI entrypoints without a packages/cli wrapper. */
|
|
15
15
|
export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "roadmap-render", "rule-map", "spec-render", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list"];
|
|
16
16
|
/** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
|
package/dist/dispatch.js
CHANGED
|
@@ -75,6 +75,7 @@ export const CLI_MODULE_VERBS = [
|
|
|
75
75
|
"session-start",
|
|
76
76
|
"session-ready",
|
|
77
77
|
"occupancy-steal",
|
|
78
|
+
"occupancy-release",
|
|
78
79
|
"plan-sequence",
|
|
79
80
|
"slice",
|
|
80
81
|
"subagent-monitor",
|
|
@@ -83,6 +84,7 @@ export const CLI_MODULE_VERBS = [
|
|
|
83
84
|
"triage-bootstrap",
|
|
84
85
|
"triage-bulk",
|
|
85
86
|
"triage-classify",
|
|
87
|
+
"triage-evaluate",
|
|
86
88
|
"triage-help",
|
|
87
89
|
"triage-queue",
|
|
88
90
|
"triage-reconcile",
|
|
@@ -142,6 +144,7 @@ export const CLI_MODULE_VERBS = [
|
|
|
142
144
|
"verify-orphan-active",
|
|
143
145
|
"verify-lifecycle-visible",
|
|
144
146
|
"verify-completed-tracked",
|
|
147
|
+
"verify-completed-write-guard",
|
|
145
148
|
"verify-literal-ac",
|
|
146
149
|
"verify-ac",
|
|
147
150
|
"verify-agents-md-budget",
|
|
@@ -286,6 +289,7 @@ export const VERB_ALIASES = {
|
|
|
286
289
|
"verify:orphan-active": "verify-orphan-active",
|
|
287
290
|
"verify:lifecycle-visible": "verify-lifecycle-visible",
|
|
288
291
|
"verify:completed-tracked": "verify-completed-tracked",
|
|
292
|
+
"verify:completed-write-guard": "verify-completed-write-guard",
|
|
289
293
|
"verify:literal-ac": "verify-literal-ac",
|
|
290
294
|
"verify:literal-acceptance": "verify-literal-ac",
|
|
291
295
|
"verify:ac": "verify-ac",
|
|
@@ -346,6 +350,7 @@ export const VERB_ALIASES = {
|
|
|
346
350
|
"triage:bootstrap": "triage-bootstrap",
|
|
347
351
|
"triage:summary": "triage-summary",
|
|
348
352
|
"triage:queue": "triage-queue",
|
|
353
|
+
"triage:evaluate": "triage-evaluate",
|
|
349
354
|
"triage:scope": "triage-scope",
|
|
350
355
|
...TRIAGE_ACTION_COLON_ALIASES,
|
|
351
356
|
...POLICY_ACTION_COLON_ALIASES,
|
|
@@ -363,6 +368,8 @@ export const VERB_ALIASES = {
|
|
|
363
368
|
"session:start": "session-start",
|
|
364
369
|
"session:ready": "session-ready",
|
|
365
370
|
"occupancy:steal": "occupancy-steal",
|
|
371
|
+
"occupancy:release": "occupancy-release",
|
|
372
|
+
"session:end": "occupancy-release",
|
|
366
373
|
...FRESHNESS_COLON_ALIASES,
|
|
367
374
|
"lifecycle:event": "lifecycle-event",
|
|
368
375
|
"lifecycle:stats": "lifecycle-stats",
|
|
@@ -2619,6 +2626,14 @@ const CURATED_HELP_GROUPS = [
|
|
|
2619
2626
|
name: "occupancy:steal",
|
|
2620
2627
|
summary: "Supersede a live worktree occupancy lease (--confirm --occupant)",
|
|
2621
2628
|
},
|
|
2629
|
+
{
|
|
2630
|
+
name: "occupancy:release",
|
|
2631
|
+
summary: "Release this worktree occupancy lease (owner live, or expired residue)",
|
|
2632
|
+
},
|
|
2633
|
+
{
|
|
2634
|
+
name: "session:end",
|
|
2635
|
+
summary: "End this mutation session by releasing occupancy (same as occupancy:release)",
|
|
2636
|
+
},
|
|
2622
2637
|
{
|
|
2623
2638
|
name: "freshness:report",
|
|
2624
2639
|
summary: "Bound vs live deposit generation (current|stale_soft|stale_hard)",
|
|
@@ -16,7 +16,7 @@ export interface HumanPresenceMintSeams {
|
|
|
16
16
|
/** Environ for agent-shell marker detection (default: process.env). */
|
|
17
17
|
readonly environ?: NodeJS.ProcessEnv;
|
|
18
18
|
/**
|
|
19
|
-
* True when a controlling terminal device is available (`/dev/tty` or
|
|
19
|
+
* True when a controlling terminal device is available (`/dev/tty` or `\\.\CONIN$`).
|
|
20
20
|
* Default: open/close the platform controlling terminal (fail-closed on error).
|
|
21
21
|
*/
|
|
22
22
|
readonly hasControllingTerminal?: () => boolean;
|
|
@@ -27,13 +27,13 @@ export interface HumanPresenceMintSeams {
|
|
|
27
27
|
readonly readInteractiveConfirm?: () => string | null;
|
|
28
28
|
}
|
|
29
29
|
export declare function looksLikeAgentShell(environ: NodeJS.ProcessEnv): boolean;
|
|
30
|
-
/** Platform controlling-terminal path (
|
|
30
|
+
/** Platform controlling-terminal path (`\\.\CONIN$` on win32, `/dev/tty` elsewhere). */
|
|
31
31
|
export declare function controllingTerminalPath(platform?: NodeJS.Platform): string;
|
|
32
32
|
/**
|
|
33
|
-
* Open flag for the platform controlling-terminal device (#3596).
|
|
33
|
+
* Open flag for the platform controlling-terminal device (#3596 leftover).
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* Win32 stays `r+` so the probe and phrase-read share one flag. The leftover
|
|
36
|
+
* path is the Windows device-namespace CONIN$ string, not bare CONIN$.
|
|
37
37
|
*/
|
|
38
38
|
export declare function controllingTerminalOpenFlag(platform?: NodeJS.Platform): "r" | "r+";
|
|
39
39
|
export declare function resolveHumanPresenceMintSeams(seams?: HumanPresenceMintSeams): Required<HumanPresenceMintSeams>;
|
|
@@ -52,7 +52,7 @@ export declare function refuseMintWhileUatActive(verb: string, projectRoot: stri
|
|
|
52
52
|
* Multi-factor human-presence gate (applies only when UAT lease is inactive):
|
|
53
53
|
* 1. No known agent/CI env markers
|
|
54
54
|
* 2. Interactive TTY (stdin + stdout isTTY)
|
|
55
|
-
* 3. Controlling terminal device present (`/dev/tty` /
|
|
55
|
+
* 3. Controlling terminal device present (`/dev/tty` / `\\.\CONIN$`)
|
|
56
56
|
* 4. Explicit argv `--confirm` (flag alone never enough)
|
|
57
57
|
* 5. Interactive typed phrase `mint` (argv --confirm alone never enough even on PTY)
|
|
58
58
|
*
|
|
@@ -67,15 +67,16 @@ export function looksLikeAgentShell(environ) {
|
|
|
67
67
|
function defaultIsTty() {
|
|
68
68
|
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
69
69
|
}
|
|
70
|
-
/** Platform controlling-terminal path (
|
|
70
|
+
/** Platform controlling-terminal path (`\\.\CONIN$` on win32, `/dev/tty` elsewhere). */
|
|
71
71
|
export function controllingTerminalPath(platform = process.platform) {
|
|
72
|
-
|
|
72
|
+
// Real-console diagnostic on #3596: bare CONIN$ and CON ENOENT; device-namespace path opens.
|
|
73
|
+
return platform === "win32" ? "\\\\.\\CONIN$" : "/dev/tty";
|
|
73
74
|
}
|
|
74
75
|
/**
|
|
75
|
-
* Open flag for the platform controlling-terminal device (#3596).
|
|
76
|
+
* Open flag for the platform controlling-terminal device (#3596 leftover).
|
|
76
77
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
78
|
+
* Win32 stays `r+` so the probe and phrase-read share one flag. The leftover
|
|
79
|
+
* path is the Windows device-namespace CONIN$ string, not bare CONIN$.
|
|
79
80
|
*/
|
|
80
81
|
export function controllingTerminalOpenFlag(platform = process.platform) {
|
|
81
82
|
return platform === "win32" ? "r+" : "r";
|
|
@@ -153,7 +154,7 @@ export function refuseMintWhileUatActive(verb, projectRoot) {
|
|
|
153
154
|
* Multi-factor human-presence gate (applies only when UAT lease is inactive):
|
|
154
155
|
* 1. No known agent/CI env markers
|
|
155
156
|
* 2. Interactive TTY (stdin + stdout isTTY)
|
|
156
|
-
* 3. Controlling terminal device present (`/dev/tty` /
|
|
157
|
+
* 3. Controlling terminal device present (`/dev/tty` / `\\.\CONIN$`)
|
|
157
158
|
* 4. Explicit argv `--confirm` (flag alone never enough)
|
|
158
159
|
* 5. Interactive typed phrase `mint` (argv --confirm alone never enough even on PTY)
|
|
159
160
|
*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { releaseOccupancy } from "@deftai/directive-core/session";
|
|
4
|
+
export function parseArgs(argv) {
|
|
5
|
+
const parsed = { projectRoot: "." };
|
|
6
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
7
|
+
const arg = argv[i];
|
|
8
|
+
if (arg === "--project-root") {
|
|
9
|
+
const value = argv[i + 1];
|
|
10
|
+
if (value === undefined) {
|
|
11
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
12
|
+
}
|
|
13
|
+
parsed.projectRoot = value;
|
|
14
|
+
i += 1;
|
|
15
|
+
}
|
|
16
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
17
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
export function run(argv) {
|
|
26
|
+
const args = parseArgs(argv);
|
|
27
|
+
if (args.error !== undefined) {
|
|
28
|
+
process.stderr.write(`occupancy:release: ${args.error}\n`);
|
|
29
|
+
return 2;
|
|
30
|
+
}
|
|
31
|
+
const result = releaseOccupancy(resolve(args.projectRoot), {
|
|
32
|
+
env: process.env,
|
|
33
|
+
});
|
|
34
|
+
const sink = result.code === 0 ? process.stdout : process.stderr;
|
|
35
|
+
sink.write(`${result.message}\n`);
|
|
36
|
+
return result.code;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=occupancy-release.js.map
|
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
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI for verify:completed-write-guard (#3679).
|
|
4
|
+
*/
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { evaluateCompletedWriteGuard } from "@deftai/directive-core/lifecycle";
|
|
8
|
+
/** Parse verify-completed-write-guard CLI args (#3679). */
|
|
9
|
+
export function parseArgs(argv) {
|
|
10
|
+
const parsed = {
|
|
11
|
+
projectRoot: ".",
|
|
12
|
+
baseRef: "",
|
|
13
|
+
quiet: false,
|
|
14
|
+
};
|
|
15
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
16
|
+
const arg = argv[i];
|
|
17
|
+
if (arg === "--quiet") {
|
|
18
|
+
parsed.quiet = true;
|
|
19
|
+
}
|
|
20
|
+
else if (arg === "--project-root") {
|
|
21
|
+
const value = argv[i + 1];
|
|
22
|
+
if (value === undefined) {
|
|
23
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
24
|
+
}
|
|
25
|
+
parsed.projectRoot = value;
|
|
26
|
+
i += 1;
|
|
27
|
+
}
|
|
28
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
29
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
30
|
+
}
|
|
31
|
+
else if (arg === "--base-ref") {
|
|
32
|
+
const value = argv[i + 1];
|
|
33
|
+
if (value === undefined) {
|
|
34
|
+
return { ...parsed, error: "argument --base-ref: expected one argument" };
|
|
35
|
+
}
|
|
36
|
+
parsed.baseRef = value;
|
|
37
|
+
i += 1;
|
|
38
|
+
}
|
|
39
|
+
else if (arg?.startsWith("--base-ref=")) {
|
|
40
|
+
parsed.baseRef = arg.slice("--base-ref=".length);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
/** Run the gate and return the process exit code. */
|
|
49
|
+
export function run(argv) {
|
|
50
|
+
const args = parseArgs(argv);
|
|
51
|
+
if (args.error !== undefined) {
|
|
52
|
+
process.stderr.write(`verify_completed_write_guard: ${args.error}\n`);
|
|
53
|
+
return 2;
|
|
54
|
+
}
|
|
55
|
+
const projectRoot = resolve(args.projectRoot);
|
|
56
|
+
const result = evaluateCompletedWriteGuard(projectRoot, {
|
|
57
|
+
...(args.baseRef.length > 0 ? { baseRef: args.baseRef } : {}),
|
|
58
|
+
});
|
|
59
|
+
if (result.message.length > 0 && !args.quiet) {
|
|
60
|
+
if (result.code === 0) {
|
|
61
|
+
process.stdout.write(`${result.message}\n`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
process.stderr.write(`${result.message}\n`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return result.code;
|
|
68
|
+
}
|
|
69
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
70
|
+
process.exit(run(process.argv.slice(2)));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=verify-completed-write-guard.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.107.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.107.0",
|
|
38
|
+
"@deftai/directive-content": "^0.107.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b"
|