@deftai/directive 0.77.0 → 0.79.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.
@@ -167,6 +167,9 @@ function routeNamespaceVerb(ns, verb, rest) {
167
167
  if (ns === "issue" && verb === "emit") {
168
168
  return { kind: "dispatch", argv: ["issue-emit", ...rest] };
169
169
  }
170
+ if (ns === "issue" && verb === "sync-from-xbrief") {
171
+ return { kind: "dispatch", argv: ["issue-sync-from-xbrief", ...rest] };
172
+ }
170
173
  if (ns === "triage" && verb.startsWith("bulk-")) {
171
174
  return { kind: "dispatch", argv: ["triage-bulk", verb.slice("bulk-".length), ...rest] };
172
175
  }
@@ -10,9 +10,9 @@ 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", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "policy", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "session-start", "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", "verify-branch", "verify-encoding", "verify-forward-coverage", "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-content-manifest", "verify-contract-drift", "verify-cursor-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-tools", "verify-wip-cap", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "eval-health", "eval-run", "eval-report"];
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", "policy", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "session-start", "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", "verify-branch", "verify-encoding", "verify-forward-coverage", "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-content-manifest", "verify-contract-drift", "verify-cursor-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-tools", "verify-wip-cap", "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
- export declare const CORE_MODULE_VERBS: readonly ["scm", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "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", "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"];
15
+ export declare const CORE_MODULE_VERBS: readonly ["scm", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "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", "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"];
16
16
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
17
17
  export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
18
18
  /** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
package/dist/dispatch.js CHANGED
@@ -41,6 +41,7 @@ export const CLI_MODULE_VERBS = [
41
41
  "migrate-xbrief",
42
42
  "migrate-category-b",
43
43
  "framework-check-updates",
44
+ "hook-dispatch",
44
45
  "umbrella-current-shape",
45
46
  "changelog-check",
46
47
  "change-init",
@@ -114,9 +115,11 @@ export const CLI_MODULE_VERBS = [
114
115
  "verify-agents-md-budget",
115
116
  "verify-agents-md-advisory",
116
117
  "verify-eval-health-relocation",
118
+ "verify-eval-triggers-relocation",
117
119
  "eval-health",
118
120
  "eval-run",
119
121
  "eval-report",
122
+ "eval-triggers",
120
123
  ];
121
124
  /** Core-only CLI entrypoints without a packages/cli wrapper. */
122
125
  export const CORE_MODULE_VERBS = [
@@ -125,6 +128,7 @@ export const CORE_MODULE_VERBS = [
125
128
  "github-body",
126
129
  "issue-emit",
127
130
  "issue-ingest",
131
+ "issue-sync-from-xbrief",
128
132
  "reconcile-issues",
129
133
  "swarm-launch",
130
134
  "swarm-complete-cohort",
@@ -189,6 +193,7 @@ export const PLAN_SEQUENCE_ALIAS_SUBCOMMANDS = {
189
193
  const PLAN_SEQUENCE_COLON_ALIASES = Object.fromEntries(Object.keys(PLAN_SEQUENCE_ALIAS_SUBCOMMANDS).map((alias) => [alias, "plan-sequence"]));
190
194
  /** Task-style aliases (framework_commands / Taskfile names). */
191
195
  export const VERB_ALIASES = {
196
+ "hook:dispatch": "hook-dispatch",
192
197
  "verify:encoding": "verify-encoding",
193
198
  "verify:forward-coverage": "verify-forward-coverage",
194
199
  "verify:branch": "verify-branch",
@@ -197,6 +202,7 @@ export const VERB_ALIASES = {
197
202
  "verify:agents-md-budget": "verify-agents-md-budget",
198
203
  "verify:agents-md-advisory": "verify-agents-md-advisory",
199
204
  "verify:eval-health-relocation": "verify-eval-health-relocation",
205
+ "verify:eval-triggers-relocation": "verify-eval-triggers-relocation",
200
206
  "verify:hooks-installed": "verify-hooks-installed",
201
207
  "verify:no-task-runtime": "verify-no-task-runtime",
202
208
  "vbrief:validate": "vbrief-validate",
@@ -241,6 +247,7 @@ export const VERB_ALIASES = {
241
247
  "migrate:category-b": "migrate-category-b",
242
248
  "framework:check-updates": "framework-check-updates",
243
249
  "umbrella:current-shape": "umbrella-current-shape",
250
+ "issue:sync-from-xbrief": "issue-sync-from-xbrief",
244
251
  upgrade: "install-upgrade",
245
252
  "session:start": "session-start",
246
253
  "toolchain:check": "toolchain-check",
@@ -256,6 +263,7 @@ export const VERB_ALIASES = {
256
263
  "value:show": "value-readback",
257
264
  "triage:metrics": "value-readback",
258
265
  "eval:run": "eval-run",
266
+ "eval:triggers": "eval-triggers",
259
267
  "eval:report": "eval-report",
260
268
  build: "framework-commands",
261
269
  "setup:ghx": "setup-ghx",
@@ -2193,6 +2201,10 @@ async function loadCoreModuleHandler(verb, io) {
2193
2201
  const { mainEntry } = await import("@deftai/directive-core/dist/intake/issue-ingest-cli.js");
2194
2202
  return mainEntry;
2195
2203
  }
2204
+ case "issue-sync-from-xbrief": {
2205
+ const { mainEntry } = await import("@deftai/directive-core/dist/issue-sync/sync-from-xbrief-cli.js");
2206
+ return mainEntry;
2207
+ }
2196
2208
  case "reconcile-issues": {
2197
2209
  const { mainEntry } = await import("@deftai/directive-core/dist/intake/reconcile-issues-cli.js");
2198
2210
  return mainEntry;
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ json: boolean;
5
+ error?: string;
6
+ }
7
+ /** Parse eval-triggers CLI args. */
8
+ export declare function parseArgs(argv: string[]): ParsedArgs;
9
+ /** Run eval:triggers (offline skill-pi-trigger-eval routing) and return exit code. */
10
+ export declare function run(argv: string[]): number;
11
+ export {};
12
+ //# sourceMappingURL=eval-triggers.d.ts.map
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { runTriggerEval } from "@deftai/directive-core/eval/triggers";
5
+ /** Parse eval-triggers CLI args. */
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: ".",
9
+ json: false,
10
+ };
11
+ for (let i = 0; i < argv.length; i += 1) {
12
+ const arg = argv[i];
13
+ if (arg === "--json") {
14
+ parsed.json = true;
15
+ }
16
+ else if (arg === "--project-root") {
17
+ const value = argv[i + 1];
18
+ if (value === undefined) {
19
+ return { ...parsed, error: "argument --project-root: expected one argument" };
20
+ }
21
+ parsed.projectRoot = value;
22
+ i += 1;
23
+ }
24
+ else if (arg?.startsWith("--project-root=")) {
25
+ parsed.projectRoot = arg.slice("--project-root=".length);
26
+ }
27
+ else {
28
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
29
+ }
30
+ }
31
+ return parsed;
32
+ }
33
+ /** Run eval:triggers (offline skill-pi-trigger-eval routing) and return exit code. */
34
+ export function run(argv) {
35
+ const args = parseArgs(argv);
36
+ if (args.error !== undefined) {
37
+ process.stderr.write(`eval:triggers: ${args.error}\n`);
38
+ return 2;
39
+ }
40
+ const result = runTriggerEval({ projectRoot: resolve(args.projectRoot) });
41
+ if (result.report === null) {
42
+ process.stderr.write(`${result.message}\n`);
43
+ return result.code;
44
+ }
45
+ if (args.json) {
46
+ process.stdout.write(`${JSON.stringify(result.report, null, 2)}\n`);
47
+ }
48
+ else {
49
+ process.stdout.write(`${result.message}\n`);
50
+ }
51
+ return result.code;
52
+ }
53
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
54
+ process.exit(run(process.argv.slice(2)));
55
+ }
56
+ //# sourceMappingURL=eval-triggers.js.map
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { type HookEvent, type HookHost } from "@deftai/directive-core/hooks";
3
+ interface ParsedArgs {
4
+ host?: HookHost;
5
+ event?: HookEvent;
6
+ projectRoot?: string;
7
+ error?: string;
8
+ }
9
+ export interface HookDispatchCliSeams {
10
+ readonly readStdin?: () => string;
11
+ readonly writeOut?: (text: string) => void;
12
+ readonly writeErr?: (text: string) => void;
13
+ readonly cwd?: () => string;
14
+ }
15
+ export declare function parseArgs(argv: readonly string[]): ParsedArgs;
16
+ export declare function run(argv: string[], seams?: HookDispatchCliSeams): number;
17
+ export {};
18
+ //# sourceMappingURL=hook-dispatch.d.ts.map
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { decideHook, isHookEvent, isHookHost, projectRootFromHookPayload, renderHostDecision, } from "@deftai/directive-core/hooks";
6
+ function takeValue(argv, index, flag) {
7
+ const token = argv[index];
8
+ const prefix = `${flag}=`;
9
+ if (token?.startsWith(prefix))
10
+ return { value: token.slice(prefix.length), next: index };
11
+ const value = argv[index + 1];
12
+ if (value === undefined)
13
+ return { next: index, error: `argument ${flag}: expected one argument` };
14
+ return { value, next: index + 1 };
15
+ }
16
+ export function parseArgs(argv) {
17
+ const parsed = {};
18
+ for (let i = 0; i < argv.length; i += 1) {
19
+ const token = argv[i];
20
+ if (token === "--host" || token?.startsWith("--host=")) {
21
+ const taken = takeValue(argv, i, "--host");
22
+ if (taken.error)
23
+ return { error: taken.error };
24
+ const value = taken.value ?? "";
25
+ if (!isHookHost(value)) {
26
+ return { error: `unsupported host: ${JSON.stringify(taken.value)}` };
27
+ }
28
+ parsed.host = value;
29
+ i = taken.next;
30
+ continue;
31
+ }
32
+ if (token === "--event" || token?.startsWith("--event=")) {
33
+ const taken = takeValue(argv, i, "--event");
34
+ if (taken.error)
35
+ return { error: taken.error };
36
+ const value = taken.value ?? "";
37
+ if (!isHookEvent(value)) {
38
+ return { error: `unsupported event: ${JSON.stringify(taken.value)}` };
39
+ }
40
+ parsed.event = value;
41
+ i = taken.next;
42
+ continue;
43
+ }
44
+ if (token === "--project-root" || token?.startsWith("--project-root=")) {
45
+ const taken = takeValue(argv, i, "--project-root");
46
+ if (taken.error)
47
+ return { error: taken.error };
48
+ parsed.projectRoot = taken.value;
49
+ i = taken.next;
50
+ continue;
51
+ }
52
+ return { error: `unrecognized argument: ${token}` };
53
+ }
54
+ if (parsed.host === undefined)
55
+ return { error: "--host is required" };
56
+ if (parsed.event === undefined)
57
+ return { error: "--event is required" };
58
+ return parsed;
59
+ }
60
+ function parsePayload(raw) {
61
+ if (raw.trim().length === 0)
62
+ return {};
63
+ try {
64
+ return JSON.parse(raw);
65
+ }
66
+ catch {
67
+ // tool.before is installed only on direct-write matchers, so an unreadable
68
+ // payload becomes a missing-tool denial rather than a fail-open crash.
69
+ return {};
70
+ }
71
+ }
72
+ export function run(argv, seams = {}) {
73
+ const args = parseArgs(argv);
74
+ const writeOut = seams.writeOut ?? ((text) => process.stdout.write(text));
75
+ const writeErr = seams.writeErr ?? ((text) => process.stderr.write(text));
76
+ if (args.error !== undefined || args.host === undefined || args.event === undefined) {
77
+ writeErr(`${args.error ?? "invalid hook-dispatch arguments"}\n`);
78
+ return 2;
79
+ }
80
+ const readStdin = seams.readStdin ?? (() => readFileSync(0, "utf8"));
81
+ const cwd = (seams.cwd ?? process.cwd)();
82
+ const payload = parsePayload(readStdin());
83
+ const projectRoot = args.projectRoot
84
+ ? resolve(args.projectRoot)
85
+ : projectRootFromHookPayload(payload, cwd);
86
+ const decision = decideHook({
87
+ host: args.host,
88
+ event: args.event,
89
+ projectRoot,
90
+ payload,
91
+ });
92
+ const rendered = renderHostDecision(args.host, decision);
93
+ if (rendered.length > 0)
94
+ writeOut(`${rendered}\n`);
95
+ if (decision.code === "session-start-degraded")
96
+ writeErr(`${decision.message}\n`);
97
+ return 0;
98
+ }
99
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
100
+ process.exit(run(process.argv.slice(2)));
101
+ }
102
+ //# sourceMappingURL=hook-dispatch.js.map
@@ -1,7 +1,7 @@
1
1
  export const PARITY_SCENARIOS = [
2
2
  { name: "help", argv: ["--help"], compareStdout: true },
3
3
  { name: "dry-run", argv: ["--dry-run"] },
4
- { name: "dry-run-keep-repo", argv: ["--dry-run", "--keep-repo"] },
4
+ { name: "dry-run-destroy-repo", argv: ["--dry-run", "--destroy-repo"] },
5
5
  {
6
6
  name: "dry-run-project-root",
7
7
  argv: ["--dry-run", "--owner", "deftai", "--project-root", "/tmp/deft-e2e-parity-root"],
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { ensureTriageCacheHydrated } from "@deftai/directive-core/dist/cache/empty-populate.js";
4
5
  import { resolveTriageCachePath } from "@deftai/directive-core/dist/triage/cache-path.js";
5
6
  import { activeReferencedIssueNumbers, buildQueue, collectOrphanIssueNumbers, DEFAULT_QUEUE_LIMIT, loadCachedIssues, loadSliceRecords, readAuditEntries, reconcileLiveOpenState, renderQueue, resolveRankingLabels, resolveRepo, } from "@deftai/directive-core/dist/triage/queue/index.js";
6
7
  import { resolveScopeIgnores } from "@deftai/directive-core/dist/triage/scope-drift/index.js";
@@ -135,6 +136,7 @@ export function run(argv, options = {}) {
135
136
  process.stderr.write("triage:queue: --repo OWNER/NAME (or $DEFT_TRIAGE_REPO) is required.\n");
136
137
  return 2;
137
138
  }
139
+ ensureTriageCacheHydrated(projectRoot, { repo });
138
140
  const cachedForQueue = loadCachedIssues(repo, { projectRoot });
139
141
  // Reconcile the cached candidate set against live open/closed state so a
140
142
  // just-closed/merged issue never lingers in the queue as [untriaged] until
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { ensureTriageCacheHydrated } from "@deftai/directive-core/dist/cache/empty-populate.js";
4
5
  import { resolveTriageCachePath } from "@deftai/directive-core/dist/triage/cache-path.js";
5
6
  import { appendHistory, computeSummary, formatSummary, pythonStyleStringify, summaryResultToRecord, utcIso, } from "@deftai/directive-core/dist/triage/summary/index.js";
6
7
  /** Parse triage-summary CLI args, mirroring the Python argparse surface. */
@@ -56,6 +57,10 @@ export function run(argv) {
56
57
  }
57
58
  const projectRoot = resolve(args.projectRoot);
58
59
  const cacheRoot = args.cacheRoot !== null ? resolve(args.cacheRoot) : undefined;
60
+ ensureTriageCacheHydrated(projectRoot, {
61
+ cacheRoot,
62
+ repo: process.env.DEFT_TRIAGE_REPO ?? null,
63
+ });
59
64
  const result = computeSummary(projectRoot, { cacheRoot });
60
65
  const line = formatSummary(result);
61
66
  const emittedAt = utcIso();
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ baseRef?: string;
5
+ staged: boolean;
6
+ quiet: boolean;
7
+ error?: string;
8
+ }
9
+ /** Parse verify-eval-triggers-relocation CLI args. */
10
+ export declare function parseArgs(argv: string[]): ParsedArgs;
11
+ /** Run verify:eval-triggers-relocation and return exit code. */
12
+ export declare function run(argv: string[]): number;
13
+ export {};
14
+ //# sourceMappingURL=verify-eval-triggers-relocation.d.ts.map
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { evaluate } from "@deftai/directive-core/eval-triggers-relocation";
5
+ /** Parse verify-eval-triggers-relocation CLI args. */
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: ".",
9
+ staged: false,
10
+ quiet: false,
11
+ };
12
+ for (let i = 0; i < argv.length; i += 1) {
13
+ const arg = argv[i];
14
+ if (arg === "--staged") {
15
+ parsed.staged = true;
16
+ }
17
+ else if (arg === "--quiet") {
18
+ parsed.quiet = true;
19
+ }
20
+ else if (arg === "--base-ref") {
21
+ const value = argv[i + 1];
22
+ if (value === undefined) {
23
+ return { ...parsed, error: "argument --base-ref: expected one argument" };
24
+ }
25
+ parsed.baseRef = value;
26
+ i += 1;
27
+ }
28
+ else if (arg?.startsWith("--base-ref=")) {
29
+ parsed.baseRef = arg.slice("--base-ref=".length);
30
+ }
31
+ else if (arg === "--project-root") {
32
+ const value = argv[i + 1];
33
+ if (value === undefined) {
34
+ return { ...parsed, error: "argument --project-root: expected one argument" };
35
+ }
36
+ parsed.projectRoot = value;
37
+ i += 1;
38
+ }
39
+ else if (arg?.startsWith("--project-root=")) {
40
+ parsed.projectRoot = arg.slice("--project-root=".length);
41
+ }
42
+ else {
43
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
44
+ }
45
+ }
46
+ return parsed;
47
+ }
48
+ /** Run verify:eval-triggers-relocation and return exit code. */
49
+ export function run(argv) {
50
+ const args = parseArgs(argv);
51
+ if (args.error !== undefined) {
52
+ process.stderr.write(`verify:eval-triggers-relocation: ${args.error}\n`);
53
+ return 2;
54
+ }
55
+ const result = evaluate({
56
+ projectRoot: resolve(args.projectRoot),
57
+ baseRef: args.baseRef,
58
+ staged: args.staged,
59
+ quiet: args.quiet,
60
+ });
61
+ if (result.message.length > 0) {
62
+ if (result.stream === "stderr") {
63
+ process.stderr.write(`${result.message}\n`);
64
+ }
65
+ else if (result.stream === "stdout") {
66
+ process.stdout.write(`${result.message}\n`);
67
+ }
68
+ }
69
+ return result.code;
70
+ }
71
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
72
+ process.exit(run(process.argv.slice(2)));
73
+ }
74
+ //# sourceMappingURL=verify-eval-triggers-relocation.js.map
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ type HookScope = "git" | "agent" | "all";
2
3
  interface ParsedArgs {
3
4
  projectRoot: string;
4
5
  quiet: boolean;
6
+ scope: HookScope;
5
7
  error?: string;
6
8
  }
7
9
  export declare function parseArgs(argv: string[]): ParsedArgs;
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { evaluate } from "@deftai/directive-core/verify-env";
4
+ import { evaluate, evaluateAgentHooks } from "@deftai/directive-core/verify-env";
5
5
  export function parseArgs(argv) {
6
- const parsed = { projectRoot: ".", quiet: false };
6
+ const parsed = { projectRoot: ".", quiet: false, scope: "git" };
7
7
  for (let i = 0; i < argv.length; i += 1) {
8
8
  const arg = argv[i];
9
9
  if (arg === "--quiet")
@@ -19,6 +19,24 @@ export function parseArgs(argv) {
19
19
  else if (arg?.startsWith("--project-root=")) {
20
20
  parsed.projectRoot = arg.slice("--project-root=".length);
21
21
  }
22
+ else if (arg === "--scope") {
23
+ const value = argv[i + 1];
24
+ if (value === undefined) {
25
+ return { ...parsed, error: "argument --scope: expected one argument" };
26
+ }
27
+ if (value !== "git" && value !== "agent" && value !== "all") {
28
+ return { ...parsed, error: `argument --scope: invalid choice: '${value}'` };
29
+ }
30
+ parsed.scope = value;
31
+ i += 1;
32
+ }
33
+ else if (arg?.startsWith("--scope=")) {
34
+ const value = arg.slice("--scope=".length);
35
+ if (value !== "git" && value !== "agent" && value !== "all") {
36
+ return { ...parsed, error: `argument --scope: invalid choice: '${value}'` };
37
+ }
38
+ parsed.scope = value;
39
+ }
22
40
  else {
23
41
  return { ...parsed, error: `unrecognized arguments: ${arg}` };
24
42
  }
@@ -31,16 +49,22 @@ export function run(argv) {
31
49
  process.stderr.write(`${args.error}\n`);
32
50
  return 2;
33
51
  }
34
- const result = evaluate(resolve(args.projectRoot));
52
+ const projectRoot = resolve(args.projectRoot);
53
+ const results = [
54
+ ...(args.scope === "git" || args.scope === "all" ? [evaluate(projectRoot)] : []),
55
+ ...(args.scope === "agent" || args.scope === "all" ? [evaluateAgentHooks(projectRoot)] : []),
56
+ ];
35
57
  if (!args.quiet) {
36
- if (result.stream === "stdout") {
37
- process.stdout.write(`${result.message}\n`);
38
- }
39
- else if (result.stream === "stderr") {
40
- process.stderr.write(`${result.message}\n`);
58
+ for (const result of results) {
59
+ if (result.stream === "stdout") {
60
+ process.stdout.write(`${result.message}\n`);
61
+ }
62
+ else if (result.stream === "stderr") {
63
+ process.stderr.write(`${result.message}\n`);
64
+ }
41
65
  }
42
66
  }
43
- return result.code;
67
+ return Math.max(...results.map((result) => result.code));
44
68
  }
45
69
  if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
46
70
  process.exit(run(process.argv.slice(2)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.77.0",
3
+ "version": "0.79.0",
4
4
  "description": "Directive CLI — npm install path for the Deft Directive framework.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,8 +31,8 @@
31
31
  "provenance": true
32
32
  },
33
33
  "dependencies": {
34
- "@deftai/directive-core": "^0.77.0",
35
- "@deftai/directive-content": "^0.77.0"
34
+ "@deftai/directive-core": "^0.79.0",
35
+ "@deftai/directive-content": "^0.79.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc -b"