@deftai/directive-core 0.59.0 → 0.61.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.
Files changed (45) hide show
  1. package/dist/deposit/python-free.d.ts +21 -0
  2. package/dist/deposit/python-free.js +149 -0
  3. package/dist/doctor/constants.d.ts +2 -0
  4. package/dist/doctor/constants.js +2 -0
  5. package/dist/doctor/main.js +22 -8
  6. package/dist/init-deposit/init-deposit.js +2 -0
  7. package/dist/init-deposit/refresh.js +2 -0
  8. package/dist/install-upgrade/index.d.ts +11 -0
  9. package/dist/install-upgrade/index.js +146 -0
  10. package/dist/migrate-preflight/index.d.ts +36 -0
  11. package/dist/migrate-preflight/index.js +193 -0
  12. package/dist/release-e2e/greenfield-python-free-smoke-cli.d.ts +3 -0
  13. package/dist/release-e2e/greenfield-python-free-smoke-cli.js +10 -0
  14. package/dist/release-e2e/greenfield-python-free-smoke.d.ts +12 -0
  15. package/dist/release-e2e/greenfield-python-free-smoke.js +183 -0
  16. package/dist/render/export-spec.d.ts +17 -0
  17. package/dist/render/export-spec.js +104 -0
  18. package/dist/render/index.d.ts +3 -1
  19. package/dist/render/index.js +3 -1
  20. package/dist/render/project-render.d.ts +24 -0
  21. package/dist/render/project-render.js +111 -7
  22. package/dist/render/scope-outlook.d.ts +9 -0
  23. package/dist/render/scope-outlook.js +248 -0
  24. package/dist/render/spec-render.js +3 -192
  25. package/dist/spec-authority/constants.d.ts +12 -0
  26. package/dist/spec-authority/constants.js +34 -0
  27. package/dist/spec-authority/index.d.ts +5 -0
  28. package/dist/spec-authority/index.js +5 -0
  29. package/dist/spec-authority/migration-fidelity.d.ts +6 -0
  30. package/dist/spec-authority/migration-fidelity.js +96 -0
  31. package/dist/spec-authority/narratives.d.ts +6 -0
  32. package/dist/spec-authority/narratives.js +84 -0
  33. package/dist/spec-authority/resolver.d.ts +15 -0
  34. package/dist/spec-authority/resolver.js +52 -0
  35. package/dist/task-surface/index.d.ts +13 -0
  36. package/dist/task-surface/index.js +126 -0
  37. package/dist/validate-content/validate-strategy-output.js +5 -26
  38. package/dist/vbrief-validate/main.js +5 -0
  39. package/dist/vbrief-validate/precutover.d.ts +8 -18
  40. package/dist/vbrief-validate/precutover.js +39 -23
  41. package/dist/verify-env/toolchain-check.d.ts +9 -2
  42. package/dist/verify-env/toolchain-check.js +15 -4
  43. package/dist/verify-env/verify-hooks-installed.d.ts +3 -3
  44. package/dist/verify-env/verify-hooks-installed.js +59 -27
  45. package/package.json +15 -3
@@ -1,6 +1,6 @@
1
1
  import * as childProcess from "node:child_process";
2
2
  import { nodeRuntimeRemediationLines } from "./node-runtime.js";
3
- export const TOOLS = [
3
+ export const MAINTAINER_TOOLS = [
4
4
  { name: "go", command: ["go", "version"] },
5
5
  { name: "uv", command: ["uv", "--version"] },
6
6
  { name: "git", command: ["git", "--version"] },
@@ -8,6 +8,16 @@ export const TOOLS = [
8
8
  { name: "node", command: ["node", "--version"] },
9
9
  { name: "pnpm", command: ["pnpm", "--version"] },
10
10
  ];
11
+ /** Consumer npm-deposit toolchain (#2022 Phase 3) -- no Python/go/uv maintainer tools. */
12
+ export const CONSUMER_TOOLS = [
13
+ { name: "git", command: ["git", "--version"] },
14
+ { name: "gh", command: ["gh", "--version"] },
15
+ { name: "node", command: ["node", "--version"] },
16
+ { name: "pnpm", command: ["pnpm", "--version"] },
17
+ { name: "task", command: ["task", "--version"] },
18
+ ];
19
+ /** @deprecated use MAINTAINER_TOOLS */
20
+ export const TOOLS = MAINTAINER_TOOLS;
11
21
  const DEFAULT_TIMEOUT_MS = 10_000;
12
22
  export function defaultCommandRunner(command, timeoutMs) {
13
23
  try {
@@ -30,11 +40,12 @@ export function defaultCommandRunner(command, timeoutMs) {
30
40
  };
31
41
  }
32
42
  }
33
- /** Run maintainer toolchain probe (mirrors scripts/toolchain-check.py). */
34
- export function runToolchainCheck(runner = defaultCommandRunner, tools = TOOLS) {
43
+ /** Run maintainer or consumer toolchain probe (mirrors scripts/toolchain-check.py). */
44
+ export function runToolchainCheck(runner = defaultCommandRunner, options = {}, tools) {
45
+ const selectedTools = tools ?? (options.consumer ? CONSUMER_TOOLS : MAINTAINER_TOOLS);
35
46
  const lines = [];
36
47
  const failed = [];
37
- for (const tool of tools) {
48
+ for (const tool of selectedTools) {
38
49
  const result = runner(tool.command, DEFAULT_TIMEOUT_MS);
39
50
  if ("error" in result) {
40
51
  if (result.error === "not-found") {
@@ -5,9 +5,9 @@ export interface EvaluateResult {
5
5
  readonly stream: OutputStream;
6
6
  }
7
7
  export declare const REQUIRED_HOOKS: readonly ["pre-commit", "pre-push"];
8
- export declare const SCRIPTS_PROBE = "preflight_branch.py";
9
- export declare const GATE_SCRIPTS: readonly ["preflight_branch.py", "verify_encoding.py", "preflight_gh.py"];
10
- export declare const SCRIPTS_DIR_CANDIDATES: readonly ["scripts", ".deft/core/scripts", "deft/scripts"];
8
+ /** Substrings each hook must contain when it dispatches through the deft CLI (#2049). */
9
+ export declare const PRE_COMMIT_DEFT_COMMANDS: readonly ["verify:branch", "verify:encoding"];
10
+ export declare const PRE_PUSH_DEFT_COMMANDS: readonly ["preflight-gh"];
11
11
  export type GitConfigReader = (projectRoot: string) => {
12
12
  hooksPath: string | null;
13
13
  error: string | null;
@@ -1,14 +1,18 @@
1
1
  import * as childProcess from "node:child_process";
2
- import { accessSync, constants, statSync } from "node:fs";
2
+ import { accessSync, constants, readFileSync, statSync } from "node:fs";
3
3
  import { join, resolve } from "node:path";
4
4
  export const REQUIRED_HOOKS = ["pre-commit", "pre-push"];
5
- export const SCRIPTS_PROBE = "preflight_branch.py";
6
- export const GATE_SCRIPTS = [
7
- "preflight_branch.py",
8
- "verify_encoding.py",
9
- "preflight_gh.py",
5
+ /** Substrings each hook must contain when it dispatches through the deft CLI (#2049). */
6
+ export const PRE_COMMIT_DEFT_COMMANDS = ["verify:branch", "verify:encoding"];
7
+ export const PRE_PUSH_DEFT_COMMANDS = ["preflight-gh"];
8
+ /** Patterns that indicate legacy Python-dispatched hooks (pre-#2049). */
9
+ const LEGACY_HOOK_PATTERNS = [
10
+ /\.py\b/i,
11
+ /\bpython\b/i,
12
+ /\bdeft_py\b/,
13
+ /\bSCRIPTS_DIR\b/,
14
+ /\bpreflight_branch\.py\b/,
10
15
  ];
11
- export const SCRIPTS_DIR_CANDIDATES = ["scripts", ".deft/core/scripts", "deft/scripts"];
12
16
  function defaultGitConfigReader(projectRoot) {
13
17
  try {
14
18
  const stdout = childProcess.execFileSync("git", ["-C", projectRoot, "config", "--get", "core.hooksPath"], {
@@ -45,15 +49,6 @@ function isDirectory(path) {
45
49
  return false;
46
50
  }
47
51
  }
48
- function resolveScriptsDir(projectRoot) {
49
- for (const rel of SCRIPTS_DIR_CANDIDATES) {
50
- const candidate = join(projectRoot, rel);
51
- if (isFile(join(candidate, SCRIPTS_PROBE))) {
52
- return candidate;
53
- }
54
- }
55
- return null;
56
- }
57
52
  function isPosix(platform) {
58
53
  return platform !== "win32";
59
54
  }
@@ -66,6 +61,36 @@ function hookExecutable(hookPath) {
66
61
  return false;
67
62
  }
68
63
  }
64
+ function readHookContent(hookPath) {
65
+ try {
66
+ return readFileSync(hookPath, "utf8");
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ function usesLegacyPythonDispatch(content) {
73
+ return LEGACY_HOOK_PATTERNS.some((pattern) => pattern.test(content));
74
+ }
75
+ function hookInvokesDeftCli(content, requiredCommands) {
76
+ if (!/\bdeft\b/.test(content))
77
+ return false;
78
+ if (usesLegacyPythonDispatch(content))
79
+ return false;
80
+ return requiredCommands.every((cmd) => content.includes(cmd));
81
+ }
82
+ function validateHookContent(hookName, content, requiredCommands) {
83
+ if (content === null) {
84
+ return `${hookName}: unreadable hook file`;
85
+ }
86
+ if (usesLegacyPythonDispatch(content)) {
87
+ return `${hookName}: still dispatches through Python scripts (expected deft CLI only, #2049)`;
88
+ }
89
+ if (!hookInvokesDeftCli(content, requiredCommands)) {
90
+ return `${hookName}: missing required deft CLI gate(s): ${requiredCommands.join(", ")}`;
91
+ }
92
+ return null;
93
+ }
69
94
  /** Pure evaluator mirroring scripts/verify_hooks_installed.py::evaluate. */
70
95
  export function evaluate(projectRoot, options = {}) {
71
96
  const root = resolve(projectRoot);
@@ -132,30 +157,37 @@ export function evaluate(projectRoot, options = {}) {
132
157
  };
133
158
  }
134
159
  }
135
- const scriptsDir = resolveScriptsDir(root);
136
- if (scriptsDir === null) {
160
+ const preCommitIssue = validateHookContent("pre-commit", readHookContent(join(hooksDir, "pre-commit")), PRE_COMMIT_DEFT_COMMANDS);
161
+ if (preCommitIssue) {
162
+ return {
163
+ code: 1,
164
+ message: `❌ deft hooks wired but NON-FUNCTIONAL: ${preCommitIssue} (#2049).\n` +
165
+ " Recovery: re-run the deft installer / `task setup` to refresh .githooks/.",
166
+ stream: "stderr",
167
+ };
168
+ }
169
+ const prePushContent = readHookContent(join(hooksDir, "pre-push"));
170
+ const prePushIssue = validateHookContent("pre-push", prePushContent, PRE_PUSH_DEFT_COMMANDS);
171
+ if (prePushIssue) {
137
172
  return {
138
173
  code: 1,
139
- message: "❌ deft hooks wired but NON-FUNCTIONAL: the gate scripts cannot be resolved.\n" +
140
- ` Looked for ${SCRIPTS_PROBE} under: ${SCRIPTS_DIR_CANDIDATES.join(", ")} (relative to ${root}).\n` +
141
- " Recovery: re-run the deft installer so the payload is present.",
174
+ message: `❌ deft hooks wired but NON-FUNCTIONAL: ${prePushIssue} (#2049).\n` +
175
+ " Recovery: re-run the deft installer / `task setup` to refresh .githooks/.",
142
176
  stream: "stderr",
143
177
  };
144
178
  }
145
- const missingScripts = GATE_SCRIPTS.filter((s) => !isFile(join(scriptsDir, s)));
146
- if (missingScripts.length > 0) {
179
+ if (prePushContent?.includes("verify:branch")) {
147
180
  return {
148
181
  code: 1,
149
- message: `❌ deft hooks wired but NON-FUNCTIONAL: ${scriptsDir} is missing ` +
150
- `gate script(s): ${missingScripts.join(", ")} (#1463 false-green).\n` +
151
- " Recovery: re-run the deft installer to restore the payload.",
182
+ message: "❌ deft hooks wired but NON-FUNCTIONAL: pre-push must not invoke verify:branch (#1814).\n" +
183
+ " Recovery: re-run the deft installer / `task setup` to refresh .githooks/.",
152
184
  stream: "stderr",
153
185
  };
154
186
  }
155
187
  return {
156
188
  code: 0,
157
189
  message: `✓ deft hooks installed and functional: core.hooksPath=${hooksPath}, ` +
158
- `hooks ${REQUIRED_HOOKS.join(", ")} present, gate scripts resolve under ${scriptsDir}.`,
190
+ `hooks ${REQUIRED_HOOKS.join(", ")} present and dispatch via deft CLI (#2049).`,
159
191
  stream: "stdout",
160
192
  };
161
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-core",
3
- "version": "0.59.0",
3
+ "version": "0.61.0",
4
4
  "description": "TypeScript engine core for the Directive framework.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -190,6 +190,18 @@
190
190
  "types": "./dist/init-deposit/index.d.ts",
191
191
  "default": "./dist/init-deposit/index.js"
192
192
  },
193
+ "./migrate-preflight": {
194
+ "types": "./dist/migrate-preflight/index.d.ts",
195
+ "default": "./dist/migrate-preflight/index.js"
196
+ },
197
+ "./install-upgrade": {
198
+ "types": "./dist/install-upgrade/index.d.ts",
199
+ "default": "./dist/install-upgrade/index.js"
200
+ },
201
+ "./task-surface": {
202
+ "types": "./dist/task-surface/index.d.ts",
203
+ "default": "./dist/task-surface/index.js"
204
+ },
193
205
  "./dist/*.js": {
194
206
  "types": "./dist/*.d.ts",
195
207
  "default": "./dist/*.js"
@@ -209,8 +221,8 @@
209
221
  "provenance": true
210
222
  },
211
223
  "dependencies": {
212
- "@deftai/directive-content": "^0.59.0",
213
- "@deftai/directive-types": "^0.59.0"
224
+ "@deftai/directive-content": "^0.61.0",
225
+ "@deftai/directive-types": "^0.61.0"
214
226
  },
215
227
  "scripts": {
216
228
  "build": "tsc -b",