@deftai/directive 0.77.0 → 0.78.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.
@@ -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", "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
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"];
16
16
  /** Colon aliases for triage-actions (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 = [
@@ -189,6 +192,7 @@ export const PLAN_SEQUENCE_ALIAS_SUBCOMMANDS = {
189
192
  const PLAN_SEQUENCE_COLON_ALIASES = Object.fromEntries(Object.keys(PLAN_SEQUENCE_ALIAS_SUBCOMMANDS).map((alias) => [alias, "plan-sequence"]));
190
193
  /** Task-style aliases (framework_commands / Taskfile names). */
191
194
  export const VERB_ALIASES = {
195
+ "hook:dispatch": "hook-dispatch",
192
196
  "verify:encoding": "verify-encoding",
193
197
  "verify:forward-coverage": "verify-forward-coverage",
194
198
  "verify:branch": "verify-branch",
@@ -197,6 +201,7 @@ export const VERB_ALIASES = {
197
201
  "verify:agents-md-budget": "verify-agents-md-budget",
198
202
  "verify:agents-md-advisory": "verify-agents-md-advisory",
199
203
  "verify:eval-health-relocation": "verify-eval-health-relocation",
204
+ "verify:eval-triggers-relocation": "verify-eval-triggers-relocation",
200
205
  "verify:hooks-installed": "verify-hooks-installed",
201
206
  "verify:no-task-runtime": "verify-no-task-runtime",
202
207
  "vbrief:validate": "vbrief-validate",
@@ -256,6 +261,7 @@ export const VERB_ALIASES = {
256
261
  "value:show": "value-readback",
257
262
  "triage:metrics": "value-readback",
258
263
  "eval:run": "eval-run",
264
+ "eval:triggers": "eval-triggers",
259
265
  "eval:report": "eval-report",
260
266
  build: "framework-commands",
261
267
  "setup:ghx": "setup-ghx",
@@ -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
@@ -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.78.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.78.0",
35
+ "@deftai/directive-content": "^0.78.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc -b"