@deftai/directive 0.65.0 → 0.66.1

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", "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", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "session-start", "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-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-bridge-drift", "verify-capacity", "verify-content-manifest", "verify-contract-drift", "verify-cursor-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-stubs", "rule-ownership-lint", "verify-story-ready", "verify-tools", "verify-wip-cap"];
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", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "session-start", "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-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-bridge-drift", "verify-capacity", "verify-content-manifest", "verify-contract-drift", "verify-cursor-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-stubs", "verify-xbrief-drift", "rule-ownership-lint", "verify-story-ready", "verify-tools", "verify-wip-cap"];
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-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"];
16
16
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
package/dist/dispatch.js CHANGED
@@ -8,7 +8,7 @@ import { homedir } from "node:os";
8
8
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
9
9
  import { engineInfo } from "@deftai/directive-core";
10
10
  import { parseInitArgv, runInitDepositCli, userConfigDir, } from "@deftai/directive-core/init-deposit";
11
- import { appendAuditLog, disclosureLine, projectDefinitionPath, resolvePolicy, resolveWipCap, setPolicy, } from "@deftai/directive-core/policy";
11
+ import { appendAuditLog, disclosureLine, migrateLegacyPolicyKey, PLAN_POLICY_KEY, projectDefinitionPath, resolvePolicy, resolveWipCap, setPolicy, } from "@deftai/directive-core/policy";
12
12
  import { defaultWhich } from "@deftai/directive-core/scm";
13
13
  import { KNOWN_SUBAGENT_BACKEND_IDS, probeSubagentBackends, resolveSwarmSubagentBackend, } from "@deftai/directive-core/swarm";
14
14
  const HANDLER_KEYS = [
@@ -37,6 +37,8 @@ export const CLI_MODULE_VERBS = [
37
37
  "install-upgrade",
38
38
  "install-uninstall",
39
39
  "migrate-preflight",
40
+ "migrate-xbrief",
41
+ "migrate-category-b",
40
42
  "framework-check-updates",
41
43
  "umbrella-current-shape",
42
44
  "changelog-check",
@@ -98,6 +100,7 @@ export const CLI_MODULE_VERBS = [
98
100
  "verify-scm-boundary",
99
101
  "verify-session-ritual",
100
102
  "verify-stubs",
103
+ "verify-xbrief-drift",
101
104
  "rule-ownership-lint",
102
105
  "verify-story-ready",
103
106
  "verify-tools",
@@ -179,6 +182,7 @@ export const VERB_ALIASES = {
179
182
  "verify:go-freeze": "verify-go-freeze",
180
183
  "verify:bridge-drift": "verify-bridge-drift",
181
184
  "verify:scm-boundary": "verify-scm-boundary",
185
+ "verify:xbrief-drift": "verify-xbrief-drift",
182
186
  "verify:capacity": "verify-capacity",
183
187
  "verify:session-ritual": "verify-session-ritual",
184
188
  "verify-strategy-output": "validate-strategy-output",
@@ -193,6 +197,8 @@ export const VERB_ALIASES = {
193
197
  ...TRIAGE_ACTION_COLON_ALIASES,
194
198
  "agents:refresh": "agents-refresh",
195
199
  "migrate:preflight": "migrate-preflight",
200
+ "migrate:xbrief": "migrate-xbrief",
201
+ "migrate:category-b": "migrate-category-b",
196
202
  "framework:check-updates": "framework-check-updates",
197
203
  "umbrella:current-shape": "umbrella-current-shape",
198
204
  upgrade: "install-upgrade",
@@ -216,6 +222,7 @@ const SUBDIR_CLI_STEMS = {
216
222
  "verify-contract-drift": "verify-source-cli/verify-contract-drift",
217
223
  "verify-cursor-tier1": "verify-source-cli/verify-cursor-tier1",
218
224
  "verify-scm-boundary": "verify-source-cli/verify-scm-boundary",
225
+ "verify-xbrief-drift": "verify-source-cli/verify-xbrief-drift",
219
226
  "verify-go-freeze": "gates-cli/verify-go-freeze",
220
227
  "verify-bridge-drift": "gates-cli/verify-bridge-drift",
221
228
  "validate-links": "content-validate-cli/validate-links",
@@ -1709,10 +1716,11 @@ function loadProjectDefinitionForWrite(projectRoot) {
1709
1716
  throw new PolicySetError("PROJECT-DEFINITION 'plan' is not an object", "config");
1710
1717
  }
1711
1718
  const planObj = plan;
1712
- let policy = planObj.policy;
1719
+ migrateLegacyPolicyKey(planObj);
1720
+ let policy = planObj[PLAN_POLICY_KEY];
1713
1721
  if (policy === undefined) {
1714
1722
  policy = {};
1715
- planObj.policy = policy;
1723
+ planObj[PLAN_POLICY_KEY] = policy;
1716
1724
  }
1717
1725
  if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
1718
1726
  throw new PolicySetError("plan.policy is not an object", "config");
package/dist/doctor.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ /** Advisory when a consumer deposit carries git-vendored framework source (#2142). */
3
+ export declare function renderStrayPackagesAdvisoryLine(projectRoot: string): string;
2
4
  export declare function run(argv: string[]): number;
3
5
  //# sourceMappingURL=doctor.d.ts.map
package/dist/doctor.js CHANGED
@@ -1,8 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
2
4
  import { fileURLToPath } from "node:url";
3
5
  import { parseDoctorFlags } from "@deftai/directive-core/dist/doctor/flags.js";
4
6
  import { cmdDoctor } from "@deftai/directive-core/dist/doctor/main.js";
5
7
  import { renderPrecutoverLine } from "@deftai/directive-core/dist/vbrief-validate/precutover.js";
8
+ import { renderXbriefMigrationLine } from "@deftai/directive-core/xbrief-migrate";
9
+ /** Advisory when a consumer deposit carries git-vendored framework source (#2142). */
10
+ export function renderStrayPackagesAdvisoryLine(projectRoot) {
11
+ const packagesDir = join(projectRoot, ".deft", "core", "packages");
12
+ if (!existsSync(packagesDir)) {
13
+ return "Deposit hygiene: none -- .deft/core contains no stray packages/ source tree.";
14
+ }
15
+ return ("Deposit hygiene: advisory -- .deft/core/packages/ is present (git-vendored framework source, " +
16
+ "not shipped by npm @deftai/directive-content). Upgrade directive to pick up task guard fixes; " +
17
+ "consider removing the stray tree from version control.");
18
+ }
6
19
  export function run(argv) {
7
20
  // #2022: surface pre-cutover (pre-v0.20 document model) migration state alongside the
8
21
  // core doctor report. Only emit on a valid, human-readable invocation: suppressed under
@@ -12,6 +25,8 @@ export function run(argv) {
12
25
  if (!flags.json && !flags.help && flags.unknown.length === 0) {
13
26
  const projectRoot = flags.projectRoot ?? process.cwd();
14
27
  process.stdout.write(`${renderPrecutoverLine(projectRoot)}\n`);
28
+ process.stdout.write(`${renderXbriefMigrationLine(projectRoot)}\n`);
29
+ process.stdout.write(`${renderStrayPackagesAdvisoryLine(projectRoot)}\n`);
15
30
  }
16
31
  return cmdDoctor(argv);
17
32
  }
@@ -2,6 +2,8 @@
2
2
  export interface ParsedInstallUpgradeArgs {
3
3
  projectRoot: string;
4
4
  frameworkRoot: string;
5
+ migrate: boolean;
6
+ force: boolean;
5
7
  error?: string;
6
8
  }
7
9
  export declare function parseArgs(argv: readonly string[]): ParsedInstallUpgradeArgs;
@@ -5,14 +5,24 @@ import { runInstallUpgrade } from "@deftai/directive-core/install-upgrade";
5
5
  export function parseArgs(argv) {
6
6
  let projectRoot = ".";
7
7
  let frameworkRoot = resolve(import.meta.dirname, "..", "..", "..");
8
+ let migrate = false;
9
+ let force = false;
8
10
  for (let i = 0; i < argv.length; i += 1) {
9
11
  const arg = argv[i] ?? "";
10
- if (arg === "--project-root") {
12
+ if (arg === "--migrate") {
13
+ migrate = true;
14
+ }
15
+ else if (arg === "--force") {
16
+ force = true;
17
+ }
18
+ else if (arg === "--project-root") {
11
19
  const value = argv[i + 1];
12
20
  if (value === undefined) {
13
21
  return {
14
22
  projectRoot,
15
23
  frameworkRoot,
24
+ migrate,
25
+ force,
16
26
  error: "argument --project-root: expected one argument",
17
27
  };
18
28
  }
@@ -28,6 +38,8 @@ export function parseArgs(argv) {
28
38
  return {
29
39
  projectRoot,
30
40
  frameworkRoot,
41
+ migrate,
42
+ force,
31
43
  error: "argument --framework-root: expected one argument",
32
44
  };
33
45
  }
@@ -38,13 +50,13 @@ export function parseArgs(argv) {
38
50
  frameworkRoot = arg.slice("--framework-root=".length);
39
51
  }
40
52
  else {
41
- return { projectRoot, frameworkRoot, error: `unrecognized argument: ${arg}` };
53
+ return { projectRoot, frameworkRoot, migrate, force, error: `unrecognized argument: ${arg}` };
42
54
  }
43
55
  }
44
56
  if (process.env.DEFT_ROOT && process.env.DEFT_ROOT.length > 0) {
45
57
  frameworkRoot = process.env.DEFT_ROOT;
46
58
  }
47
- return { projectRoot, frameworkRoot };
59
+ return { projectRoot, frameworkRoot, migrate, force };
48
60
  }
49
61
  export function run(argv) {
50
62
  const args = parseArgs(argv);
@@ -52,7 +64,12 @@ export function run(argv) {
52
64
  process.stderr.write(`install-upgrade: ${args.error}\n`);
53
65
  return 2;
54
66
  }
55
- return runInstallUpgrade({ projectRoot: args.projectRoot, frameworkRoot: args.frameworkRoot }, {
67
+ return runInstallUpgrade({
68
+ projectRoot: args.projectRoot,
69
+ frameworkRoot: args.frameworkRoot,
70
+ migrate: args.migrate,
71
+ force: args.force,
72
+ }, {
56
73
  writeOut: (text) => {
57
74
  process.stdout.write(text);
58
75
  },
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ export interface ParsedMigrateCategoryBArgs {
3
+ projectRoot: string;
4
+ error?: string;
5
+ }
6
+ export declare function parseArgs(argv: readonly string[]): ParsedMigrateCategoryBArgs;
7
+ /** Migrate Category B bare plan keys to the x-directive/ namespace (#1650). */
8
+ export declare function run(argv: readonly string[]): number;
9
+ //# sourceMappingURL=migrate-category-b.d.ts.map
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from "node:url";
3
+ import { migrateCategoryBCorpus } from "@deftai/directive-core/category-b-namespace";
4
+ export function parseArgs(argv) {
5
+ let 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 { projectRoot, error: "argument --project-root: expected one argument" };
12
+ }
13
+ projectRoot = value;
14
+ i += 1;
15
+ }
16
+ else if (arg.startsWith("--project-root=")) {
17
+ projectRoot = arg.slice("--project-root=".length);
18
+ }
19
+ else {
20
+ return { projectRoot, error: `unrecognized argument: ${arg}` };
21
+ }
22
+ }
23
+ return { projectRoot };
24
+ }
25
+ /** Migrate Category B bare plan keys to the x-directive/ namespace (#1650). */
26
+ export function run(argv) {
27
+ const args = parseArgs(argv);
28
+ if (args.error !== undefined) {
29
+ process.stderr.write(`migrate:category-b: ${args.error}\n`);
30
+ return 2;
31
+ }
32
+ const result = migrateCategoryBCorpus(args.projectRoot);
33
+ if (result.conflicts.length > 0) {
34
+ for (const conflict of result.conflicts) {
35
+ process.stderr.write(`migrate:category-b: conflict in ${conflict.path}: ${conflict.message}\n`);
36
+ }
37
+ return 1;
38
+ }
39
+ if (result.changed.length === 0) {
40
+ process.stdout.write(`migrate:category-b: ${result.scanned} vBRIEF file(s) scanned -- already namespaced.\n`);
41
+ return 0;
42
+ }
43
+ process.stdout.write(`migrate:category-b: namespaced ${result.changed.length} of ${result.scanned} vBRIEF file(s):\n`);
44
+ for (const path of result.changed) {
45
+ process.stdout.write(` ${path}\n`);
46
+ }
47
+ return 0;
48
+ }
49
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
50
+ process.exit(run(process.argv.slice(2)));
51
+ }
52
+ //# sourceMappingURL=migrate-category-b.js.map
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ export interface ParsedMigrateXbriefArgs {
3
+ projectRoot: string;
4
+ frameworkRoot: string;
5
+ force: boolean;
6
+ error?: string;
7
+ }
8
+ export declare function parseArgs(argv: readonly string[]): ParsedMigrateXbriefArgs;
9
+ export declare function run(argv: readonly string[]): number;
10
+ //# sourceMappingURL=migrate-xbrief.d.ts.map
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { runXbriefMigrationCli } from "@deftai/directive-core/xbrief-migrate";
5
+ export function parseArgs(argv) {
6
+ let projectRoot = ".";
7
+ let frameworkRoot = resolve(import.meta.dirname, "..", "..", "..");
8
+ let force = false;
9
+ for (let i = 0; i < argv.length; i += 1) {
10
+ const arg = argv[i] ?? "";
11
+ if (arg === "--force") {
12
+ force = true;
13
+ }
14
+ else if (arg === "--project-root") {
15
+ const value = argv[i + 1];
16
+ if (value === undefined) {
17
+ return {
18
+ projectRoot,
19
+ frameworkRoot,
20
+ force,
21
+ error: "argument --project-root: expected one argument",
22
+ };
23
+ }
24
+ projectRoot = value;
25
+ i += 1;
26
+ }
27
+ else if (arg.startsWith("--project-root=")) {
28
+ projectRoot = arg.slice("--project-root=".length);
29
+ }
30
+ else if (arg === "--framework-root") {
31
+ const value = argv[i + 1];
32
+ if (value === undefined) {
33
+ return {
34
+ projectRoot,
35
+ frameworkRoot,
36
+ force,
37
+ error: "argument --framework-root: expected one argument",
38
+ };
39
+ }
40
+ frameworkRoot = value;
41
+ i += 1;
42
+ }
43
+ else if (arg.startsWith("--framework-root=")) {
44
+ frameworkRoot = arg.slice("--framework-root=".length);
45
+ }
46
+ else {
47
+ return { projectRoot, frameworkRoot, force, error: `unrecognized argument: ${arg}` };
48
+ }
49
+ }
50
+ if (process.env.DEFT_ROOT && process.env.DEFT_ROOT.length > 0) {
51
+ frameworkRoot = process.env.DEFT_ROOT;
52
+ }
53
+ return { projectRoot, frameworkRoot, force };
54
+ }
55
+ export function run(argv) {
56
+ const args = parseArgs(argv);
57
+ if (args.error !== undefined) {
58
+ process.stderr.write(`migrate:xbrief: ${args.error}\n`);
59
+ return 2;
60
+ }
61
+ return runXbriefMigrationCli({
62
+ projectRoot: args.projectRoot,
63
+ frameworkRoot: args.frameworkRoot,
64
+ force: args.force,
65
+ }, {
66
+ writeOut: (text) => {
67
+ process.stdout.write(text);
68
+ },
69
+ writeErr: (text) => {
70
+ process.stderr.write(text);
71
+ },
72
+ });
73
+ }
74
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
75
+ process.exit(run(process.argv.slice(2)));
76
+ }
77
+ //# sourceMappingURL=migrate-xbrief.js.map
@@ -1,7 +1,41 @@
1
- /** Thin CLI wrapper for prd-render (mirrors ``scripts/prd_render.py``). */
1
+ /**
2
+ * Thin CLI wrapper for prd-render (mirrors ``scripts/prd_render.py``).
3
+ *
4
+ * Supports `--project-root <dir>` to resolve the spec artifact via the layout
5
+ * resolver (#2132), preferring `xbrief/specification.xbrief.json` on migrated
6
+ * trees and falling back to `vbrief/specification.vbrief.json` on legacy trees.
7
+ * When `--spec` is explicitly provided it takes precedence over `--project-root`.
8
+ * Direct `--spec` / `--output` / `--force` flags are still accepted unchanged.
9
+ */
10
+ import { layout } from "@deftai/directive-core";
2
11
  import { parsePrdArgv, prdRenderMain } from "@deftai/directive-core/render";
12
+ function parsePrdRenderCliArgv(argv) {
13
+ const remaining = [];
14
+ let projectRoot;
15
+ for (let i = 0; i < argv.length; i += 1) {
16
+ const arg = argv[i] ?? "";
17
+ if (arg === "--project-root") {
18
+ projectRoot = argv[i + 1];
19
+ i += 1;
20
+ }
21
+ else if (arg.startsWith("--project-root=")) {
22
+ projectRoot = arg.slice("--project-root=".length);
23
+ }
24
+ else {
25
+ remaining.push(arg);
26
+ }
27
+ }
28
+ return { projectRoot, remaining };
29
+ }
3
30
  export function runPrdRenderCli(argv) {
4
- prdRenderMain(parsePrdArgv(argv));
31
+ const { projectRoot, remaining } = parsePrdRenderCliArgv(argv);
32
+ const parsedArgs = parsePrdArgv(remaining);
33
+ const spec = parsedArgs.spec !== undefined
34
+ ? parsedArgs.spec
35
+ : projectRoot !== undefined
36
+ ? layout.resolveSpecArtifactPath(projectRoot)
37
+ : undefined;
38
+ prdRenderMain({ ...parsedArgs, spec });
5
39
  return 0;
6
40
  }
7
41
  //# sourceMappingURL=prd-render-cli.js.map
@@ -1,6 +1,39 @@
1
- /** Thin CLI wrapper for spec-render (mirrors ``scripts/spec_render.py``). */
1
+ /**
2
+ * Thin CLI wrapper for spec-render (mirrors ``scripts/spec_render.py``).
3
+ *
4
+ * Supports `--project-root <dir>` to resolve the spec artifact via the layout
5
+ * resolver (#2132), preferring `xbrief/specification.xbrief.json` on migrated
6
+ * trees and falling back to `vbrief/specification.vbrief.json` on legacy trees.
7
+ * Direct positional path args are still accepted for backward compatibility.
8
+ */
9
+ import { join, resolve } from "node:path";
10
+ import { layout } from "@deftai/directive-core";
2
11
  import { specRenderMain } from "@deftai/directive-core/render";
12
+ function parseSpecRenderCliArgv(argv) {
13
+ const remaining = [];
14
+ let projectRoot;
15
+ for (let i = 0; i < argv.length; i += 1) {
16
+ const arg = argv[i] ?? "";
17
+ if (arg === "--project-root") {
18
+ projectRoot = argv[i + 1];
19
+ i += 1;
20
+ }
21
+ else if (arg.startsWith("--project-root=")) {
22
+ projectRoot = arg.slice("--project-root=".length);
23
+ }
24
+ else {
25
+ remaining.push(arg);
26
+ }
27
+ }
28
+ return { projectRoot, remaining };
29
+ }
3
30
  export function runSpecRenderCli(argv) {
4
- return specRenderMain(argv);
31
+ const { projectRoot, remaining } = parseSpecRenderCliArgv(argv);
32
+ if (projectRoot !== undefined && remaining.filter((a) => !a.startsWith("--")).length === 0) {
33
+ const specPath = layout.resolveSpecArtifactPath(projectRoot);
34
+ const outPath = join(resolve(projectRoot), "SPECIFICATION.md");
35
+ return specRenderMain([specPath, outPath, ...remaining]);
36
+ }
37
+ return specRenderMain(remaining);
5
38
  }
6
39
  //# sourceMappingURL=spec-render-cli.js.map
@@ -1,6 +1,38 @@
1
- /** Thin CLI wrapper for spec-validate (mirrors ``scripts/spec_validate.py``). */
1
+ /**
2
+ * Thin CLI wrapper for spec-validate (mirrors ``scripts/spec_validate.py``).
3
+ *
4
+ * Supports `--project-root <dir>` to resolve the spec artifact via the layout
5
+ * resolver (#2132), preferring `xbrief/specification.xbrief.json` on migrated
6
+ * trees and falling back to `vbrief/specification.vbrief.json` on legacy trees.
7
+ * A direct path positional arg is still accepted for backward compatibility.
8
+ */
9
+ import { layout } from "@deftai/directive-core";
2
10
  import { specValidateMain } from "@deftai/directive-core/render";
11
+ function parseSpecValidateCliArgv(argv) {
12
+ const positional = [];
13
+ let projectRoot;
14
+ for (let i = 0; i < argv.length; i += 1) {
15
+ const arg = argv[i] ?? "";
16
+ if (arg === "--project-root") {
17
+ projectRoot = argv[i + 1];
18
+ i += 1;
19
+ }
20
+ else if (arg.startsWith("--project-root=")) {
21
+ projectRoot = arg.slice("--project-root=".length);
22
+ }
23
+ else {
24
+ positional.push(arg);
25
+ }
26
+ }
27
+ return { specPath: positional[0], projectRoot };
28
+ }
3
29
  export function runSpecValidateCli(argv) {
4
- return specValidateMain(argv);
30
+ const { specPath, projectRoot } = parseSpecValidateCliArgv(argv);
31
+ const resolved = projectRoot !== undefined ? layout.resolveSpecArtifactPath(projectRoot) : specPath;
32
+ if (!resolved) {
33
+ process.stderr.write("Usage: spec-validate [--project-root <dir>] [<spec_file>]\n");
34
+ return 2;
35
+ }
36
+ return specValidateMain([resolved]);
5
37
  }
6
38
  //# sourceMappingURL=spec-validate-cli.js.map
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { appendHistory, computeSummary, formatSummary, pythonStyleStringify, SUMMARY_HISTORY_REL_PATH, summaryResultToRecord, utcIso, } from "@deftai/directive-core/dist/triage/summary/index.js";
4
+ import { resolveEvalPath } from "@deftai/directive-core/dist/layout/resolve.js";
5
+ import { appendHistory, computeSummary, formatSummary, pythonStyleStringify, summaryResultToRecord, utcIso, } from "@deftai/directive-core/dist/triage/summary/index.js";
5
6
  /** Parse triage-summary CLI args, mirroring the Python argparse surface. */
6
7
  export function parseArgs(argv) {
7
8
  const parsed = {
@@ -66,7 +67,7 @@ export function run(argv) {
66
67
  process.stdout.write(`${line}\n`);
67
68
  }
68
69
  if (!args.noHistory) {
69
- const historyPath = resolve(projectRoot, SUMMARY_HISTORY_REL_PATH);
70
+ const historyPath = resolveEvalPath(projectRoot, "summary-history.jsonl");
70
71
  appendHistory(historyPath, result, line, { emittedAt });
71
72
  }
72
73
  return 0;
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { type DriftScanMode } from "@deftai/directive-core/xbrief-migrate";
3
+ interface ParsedArgs {
4
+ mode: DriftScanMode;
5
+ projectRoot: string;
6
+ allowList: string | null;
7
+ quiet: boolean;
8
+ error?: string;
9
+ }
10
+ /** Parse verify-xbrief-drift CLI args (#2109), mirroring the verify-encoding surface. */
11
+ export declare function parseArgs(argv: string[]): ParsedArgs;
12
+ /** Run the gate and return the process exit code. */
13
+ export declare function run(argv: string[]): number;
14
+ export {};
15
+ //# sourceMappingURL=verify-xbrief-drift.d.ts.map
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { evaluateXbriefDrift } from "@deftai/directive-core/xbrief-migrate";
5
+ /** Parse verify-xbrief-drift CLI args (#2109), mirroring the verify-encoding surface. */
6
+ export function parseArgs(argv) {
7
+ const parsed = { mode: "all", projectRoot: ".", allowList: null, quiet: false };
8
+ let sawAll = false;
9
+ let sawStaged = false;
10
+ for (let i = 0; i < argv.length; i += 1) {
11
+ const arg = argv[i];
12
+ if (arg === "--all") {
13
+ sawAll = true;
14
+ parsed.mode = "all";
15
+ }
16
+ else if (arg === "--staged") {
17
+ sawStaged = true;
18
+ parsed.mode = "staged";
19
+ }
20
+ else if (arg === "--quiet") {
21
+ parsed.quiet = true;
22
+ }
23
+ else if (arg === "--project-root") {
24
+ const value = argv[i + 1];
25
+ if (value === undefined) {
26
+ return { ...parsed, error: "argument --project-root: expected one argument" };
27
+ }
28
+ parsed.projectRoot = value;
29
+ i += 1;
30
+ }
31
+ else if (arg?.startsWith("--project-root=")) {
32
+ parsed.projectRoot = arg.slice("--project-root=".length);
33
+ }
34
+ else if (arg === "--allow-list") {
35
+ const value = argv[i + 1];
36
+ if (value === undefined) {
37
+ return { ...parsed, error: "argument --allow-list: expected one argument" };
38
+ }
39
+ parsed.allowList = value;
40
+ i += 1;
41
+ }
42
+ else if (arg?.startsWith("--allow-list=")) {
43
+ parsed.allowList = arg.slice("--allow-list=".length);
44
+ }
45
+ else {
46
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
47
+ }
48
+ }
49
+ if (sawAll && sawStaged) {
50
+ return { ...parsed, error: "argument --staged: not allowed with argument --all" };
51
+ }
52
+ return parsed;
53
+ }
54
+ /** Run the gate and return the process exit code. */
55
+ export function run(argv) {
56
+ const args = parseArgs(argv);
57
+ if (args.error !== undefined) {
58
+ process.stderr.write(`verify_xbrief_drift: ${args.error}\n`);
59
+ return 2;
60
+ }
61
+ const projectRoot = resolve(args.projectRoot);
62
+ const result = evaluateXbriefDrift(projectRoot, {
63
+ mode: args.mode,
64
+ allowListPath: args.allowList !== null ? resolve(args.allowList) : null,
65
+ quiet: args.quiet,
66
+ });
67
+ if (result.code === 0) {
68
+ if (!args.quiet && result.message.length > 0) {
69
+ process.stdout.write(`${result.message}\n`);
70
+ }
71
+ }
72
+ else {
73
+ process.stderr.write(`${result.message}\n`);
74
+ }
75
+ return result.code;
76
+ }
77
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
78
+ process.exit(run(process.argv.slice(2)));
79
+ }
80
+ //# sourceMappingURL=verify-xbrief-drift.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
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.65.0",
35
- "@deftai/directive-content": "^0.65.0"
34
+ "@deftai/directive-core": "^0.66.1",
35
+ "@deftai/directive-content": "^0.66.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc -b"