@deftai/directive-core 0.79.2 → 0.79.4

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 (64) hide show
  1. package/dist/check/orchestrator.d.ts +4 -0
  2. package/dist/check/orchestrator.js +9 -1
  3. package/dist/coverage-hotspots/evaluate.d.ts +49 -0
  4. package/dist/coverage-hotspots/evaluate.js +262 -0
  5. package/dist/coverage-hotspots/index.d.ts +3 -0
  6. package/dist/coverage-hotspots/index.js +3 -0
  7. package/dist/coverage-hotspots/thresholds.d.ts +5 -0
  8. package/dist/coverage-hotspots/thresholds.js +48 -0
  9. package/dist/hooks/dispatcher.d.ts +7 -0
  10. package/dist/hooks/dispatcher.js +44 -4
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +1 -0
  13. package/dist/init-deposit/xbrief-projections.d.ts +7 -0
  14. package/dist/init-deposit/xbrief-projections.js +29 -1
  15. package/dist/integration-e2e/bootstrap-cache-module.d.ts +2 -4
  16. package/dist/integration-e2e/bootstrap-cache-module.js +2 -20
  17. package/dist/platform/resolve-version.d.ts +2 -6
  18. package/dist/platform/resolve-version.js +3 -129
  19. package/dist/pr-merge-readiness/gh.js +13 -5
  20. package/dist/pr-merge-readiness/test-gh-fixtures.helpers.d.ts +18 -0
  21. package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +76 -0
  22. package/dist/pr-monitor/monitor.js +10 -1
  23. package/dist/pr-wait-mergeable/cascade.js +8 -1
  24. package/dist/pr-wait-mergeable/classify.js +5 -1
  25. package/dist/pr-wait-mergeable/wrappers.js +15 -4
  26. package/dist/pr-watch/constants.d.ts +15 -0
  27. package/dist/pr-watch/constants.js +37 -0
  28. package/dist/pr-watch/index.d.ts +1 -1
  29. package/dist/pr-watch/index.js +1 -1
  30. package/dist/pr-watch/main.d.ts +3 -0
  31. package/dist/pr-watch/main.js +33 -3
  32. package/dist/pr-watch/probe.js +5 -1
  33. package/dist/pr-watch/types.d.ts +2 -0
  34. package/dist/pr-watch/watch.js +17 -1
  35. package/dist/release/constants.d.ts +5 -0
  36. package/dist/release/constants.js +14 -2
  37. package/dist/release/flags.js +16 -0
  38. package/dist/release/main.js +7 -0
  39. package/dist/release/pipeline.js +7 -3
  40. package/dist/release/preflight.js +8 -1
  41. package/dist/release/skip-ci-incident.d.ts +22 -0
  42. package/dist/release/skip-ci-incident.js +68 -0
  43. package/dist/release/types.d.ts +2 -0
  44. package/dist/release/version.js +68 -32
  45. package/dist/release-e2e/entrypoint-worker.js +1 -0
  46. package/dist/release-e2e/entrypoint.js +13 -0
  47. package/dist/review-monitor/constants.d.ts +14 -0
  48. package/dist/review-monitor/constants.js +55 -0
  49. package/dist/review-monitor/index.d.ts +5 -0
  50. package/dist/review-monitor/index.js +5 -0
  51. package/dist/review-monitor/record.d.ts +50 -0
  52. package/dist/review-monitor/record.js +178 -0
  53. package/dist/review-monitor/tier-detection.d.ts +15 -0
  54. package/dist/review-monitor/tier-detection.js +61 -0
  55. package/dist/review-monitor/verify.d.ts +32 -0
  56. package/dist/review-monitor/verify.js +171 -0
  57. package/dist/scope/undo.js +12 -2
  58. package/dist/triage/bootstrap/cache-module.d.ts +25 -0
  59. package/dist/triage/bootstrap/cache-module.js +39 -0
  60. package/dist/triage/bootstrap/index.d.ts +1 -0
  61. package/dist/triage/bootstrap/index.js +7 -82
  62. package/dist/xbrief-migrate/agents-header.d.ts +0 -11
  63. package/dist/xbrief-migrate/agents-header.js +10 -1
  64. package/package.json +7 -3
@@ -1,13 +1,13 @@
1
- import { execFile, execFileSync } from "node:child_process";
1
+ import { execFileSync } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join, resolve } from "node:path";
5
- import { promisify } from "node:util";
6
5
  import { hasArtifactSuffix, resolveLifecycleRoot } from "../../layout/resolve.js";
7
- import { SUBPROCESS_MAX_BUFFER } from "../../subprocess/max-buffer.js";
8
6
  import { resolveCandidatesLogPath } from "../cache-path.js";
7
+ import { loadDefaultCacheModule } from "./cache-module.js";
9
8
  import { stepEnsureGitignoreEntry, stepEnsureGitignoreEvalEntries, stepSeedCandidatesLog, } from "./gitignore.js";
10
9
  import { PROGRESS_DEFAULT } from "./types.js";
10
+ export * from "./cache-module.js";
11
11
  export * from "./gitignore.js";
12
12
  export * from "./types.js";
13
13
  export const CACHE_DIR_NAME = ".deft-cache";
@@ -21,7 +21,6 @@ const TOTAL_STEPS = 5;
21
21
  const GIT_ORIGIN_RE = /^(?:https?:\/\/(?:[^@/]+@)?github\.com\/|git@github\.com:|ssh:\/\/git@github\.com[:/])([A-Za-z0-9][A-Za-z0-9._-]*)\/([A-Za-z0-9][A-Za-z0-9._-]*?)(?:\.git)?\/?\s*$/;
22
22
  const REPO_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*\/[A-Za-z0-9][A-Za-z0-9._-]*$/;
23
23
  const RUNNER_UNSET = Symbol("runner-unset");
24
- const execFileAsync = promisify(execFile);
25
24
  function defaultWhich(name) {
26
25
  const locator = process.platform === "win32" ? "where" : "which";
27
26
  try {
@@ -126,81 +125,6 @@ export async function runWithTimeout(func, timeoutS) {
126
125
  error: boxError,
127
126
  };
128
127
  }
129
- function resolveDeftRoot(explicit) {
130
- if (explicit !== undefined && explicit.length > 0)
131
- return resolve(explicit);
132
- if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
133
- return resolve(process.env.DEFT_ROOT);
134
- }
135
- return resolve(process.cwd());
136
- }
137
- function cacheModulePresent(deftRoot) {
138
- return existsSync(join(deftRoot, "scripts", "cache.py"));
139
- }
140
- async function invokePythonCacheFetchAll(deftRoot, kwargs) {
141
- const payload = JSON.stringify({
142
- source: kwargs.source,
143
- repo: kwargs.repo,
144
- cache_root: kwargs.cacheRoot,
145
- batch_size: kwargs.batchSize ?? null,
146
- delay_ms: kwargs.delayMs ?? null,
147
- state: kwargs.state ?? null,
148
- limit: kwargs.limit ?? null,
149
- labels: kwargs.labels ?? null,
150
- author: kwargs.author ?? null,
151
- });
152
- const script = `
153
- import json, sys
154
- sys.path.insert(0, ${JSON.stringify(join(deftRoot, "scripts"))})
155
- from cache import cache_fetch_all
156
- raw = json.loads(sys.argv[1])
157
- kwargs = {
158
- "source": raw["source"],
159
- "repo": raw["repo"],
160
- "cache_root": raw["cache_root"],
161
- }
162
- for key in ("batch_size", "delay_ms", "state", "limit", "author"):
163
- if raw[key] is not None:
164
- kwargs[key] = raw[key]
165
- if raw["labels"]:
166
- kwargs["labels"] = tuple(raw["labels"])
167
- report = cache_fetch_all(**kwargs)
168
- out = {
169
- "succeeded": getattr(report, "succeeded", None),
170
- "failed": getattr(report, "failed", None),
171
- "skipped": getattr(report, "skipped", None),
172
- }
173
- summary_line = getattr(report, "summary_line", None)
174
- if callable(summary_line):
175
- try:
176
- out["summary_message"] = summary_line(source=raw["source"], repo=raw["repo"])
177
- except TypeError:
178
- pass
179
- print(json.dumps(out))
180
- `;
181
- const { stdout } = await execFileAsync("uv", ["run", "python", "-c", script, payload], {
182
- cwd: deftRoot,
183
- encoding: "utf8",
184
- maxBuffer: SUBPROCESS_MAX_BUFFER,
185
- });
186
- const parsed = JSON.parse(String(stdout).trim());
187
- const summaryMessage = parsed.summary_message;
188
- return {
189
- succeeded: parsed.succeeded,
190
- failed: parsed.failed,
191
- skipped: parsed.skipped,
192
- summaryLine: typeof summaryMessage === "string" ? () => summaryMessage : null,
193
- };
194
- }
195
- function loadDefaultCacheModule(deftRoot) {
196
- if (!cacheModulePresent(deftRoot))
197
- return null;
198
- return {
199
- cacheFetchAll(kwargs) {
200
- return invokePythonCacheFetchAll(deftRoot, kwargs);
201
- },
202
- };
203
- }
204
128
  function nowIsoDefault() {
205
129
  return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
206
130
  }
@@ -219,10 +143,11 @@ export async function stepPopulateCache(projectRoot, repo, options = {}) {
219
143
  if (!REPO_RE.test(effectiveRepo)) {
220
144
  return stepOutcome("populate_cache", false, `invalid --repo '${effectiveRepo}'`, {}, "repo must be 'owner/name' (alphanumerics, '.', '_', '-' only)");
221
145
  }
222
- const deftRoot = resolveDeftRoot(options.deftRoot);
223
- const cacheMod = options.cacheModule ?? loadDefaultCacheModule(deftRoot);
146
+ // #2684: default is TypeScript cacheFetchAll — never gate on scripts/cache.py.
147
+ // Explicit null still skips populate (tests / callers that inject empty cache).
148
+ const cacheMod = options.cacheModule !== undefined ? options.cacheModule : loadDefaultCacheModule();
224
149
  if (cacheMod === null) {
225
- return stepOutcome("populate_cache", true, "deferred (scripts/cache.py not present on this branch; re-run after rebase to populate via task cache:fetch-all)", { deferred: "cache-module-missing", repo: effectiveRepo });
150
+ return stepOutcome("populate_cache", true, "deferred (cache module explicitly disabled; pass a cacheModule or omit the override to populate via cache:fetch-all)", { deferred: "cache-module-disabled", repo: effectiveRepo });
226
151
  }
227
152
  const kwargs = {
228
153
  source: CACHE_SOURCE,
@@ -1,14 +1,3 @@
1
- /**
2
- * Bounded, ordered set of legacy crossover tokens rewritten in the UNMANAGED
3
- * region of a consumer AGENTS.md after `migrate:xbrief` (#2154 / Option A).
4
- *
5
- * Each entry is a mechanical path / verb literal — NOT freeform prose. The
6
- * casing-only `vBRIEF format` product-description token from the issue table is
7
- * intentionally excluded so freeform prose survives untouched. The tokens are
8
- * disjoint substrings (`.vbrief.json` has no trailing slash, `vbrief:preflight`
9
- * uses a colon, `vbrief/` requires a slash), so replacement order does not
10
- * change the result and a second pass is a guaranteed no-op (idempotent).
11
- */
12
1
  export declare const LEGACY_HEADER_TOKENS: ReadonlyArray<{
13
2
  readonly legacy: string;
14
3
  readonly migrated: string;
@@ -1,5 +1,6 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { assertProjectionContained } from "../fs/projection-containment.js";
3
4
  import { iterManagedSections } from "../platform/agents-md.js";
4
5
  import { MIGRATED_ARTIFACT_DIR } from "./constants.js";
5
6
  import { isDirectory } from "./fs-helpers.js";
@@ -14,6 +15,12 @@ import { isDirectory } from "./fs-helpers.js";
14
15
  * uses a colon, `vbrief/` requires a slash), so replacement order does not
15
16
  * change the result and a second pass is a guaranteed no-op (idempotent).
16
17
  */
18
+ /** Refuse migrate header writes that escape via repo-controlled symlinks (#2668). */
19
+ function projectionTarget(projectDir, ...relSegments) {
20
+ const target = join(projectDir, ...relSegments);
21
+ assertProjectionContained(projectDir, target);
22
+ return target;
23
+ }
17
24
  export const LEGACY_HEADER_TOKENS = [
18
25
  { legacy: ".vbrief.json", migrated: ".xbrief.json" },
19
26
  { legacy: "vbrief:preflight", migrated: "xbrief:preflight" },
@@ -94,6 +101,7 @@ export function patchAgentsMdHeader(projectRoot, seams = {}) {
94
101
  }
95
102
  });
96
103
  const writeText = seams.writeText ?? ((path, text) => writeFileSync(path, text, "utf8"));
104
+ const usingWriteSeam = seams.writeText !== undefined;
97
105
  const existing = readText(agentsPath);
98
106
  if (existing === null) {
99
107
  return { kind: "absent", path: agentsPath, replacements: [] };
@@ -103,7 +111,8 @@ export function patchAgentsMdHeader(projectRoot, seams = {}) {
103
111
  return { kind: "clean", path: agentsPath, replacements: [] };
104
112
  }
105
113
  try {
106
- writeText(agentsPath, result.content);
114
+ const writePath = usingWriteSeam ? agentsPath : projectionTarget(projectRoot, "AGENTS.md");
115
+ writeText(writePath, result.content);
107
116
  }
108
117
  catch (err) {
109
118
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-core",
3
- "version": "0.79.2",
3
+ "version": "0.79.4",
4
4
  "description": "TypeScript engine core for the Directive framework.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -242,6 +242,10 @@
242
242
  "types": "./dist/swarm/index.d.ts",
243
243
  "default": "./dist/swarm/index.js"
244
244
  },
245
+ "./review-monitor": {
246
+ "types": "./dist/review-monitor/index.d.ts",
247
+ "default": "./dist/review-monitor/index.js"
248
+ },
245
249
  "./platform": {
246
250
  "types": "./dist/platform/index.d.ts",
247
251
  "default": "./dist/platform/index.js"
@@ -305,8 +309,8 @@
305
309
  "provenance": true
306
310
  },
307
311
  "dependencies": {
308
- "@deftai/directive-content": "^0.79.2",
309
- "@deftai/directive-types": "^0.79.2",
312
+ "@deftai/directive-content": "^0.79.4",
313
+ "@deftai/directive-types": "^0.79.4",
310
314
  "archiver": "^8.0.0"
311
315
  },
312
316
  "scripts": {