@deftai/directive-core 0.85.0 → 0.87.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 (50) hide show
  1. package/dist/check/gate-lists.js +1 -0
  2. package/dist/doctor/constants.d.ts +2 -2
  3. package/dist/doctor/constants.js +2 -2
  4. package/dist/doctor/main.d.ts +8 -6
  5. package/dist/doctor/main.js +102 -36
  6. package/dist/doctor/taskfile.d.ts +8 -0
  7. package/dist/doctor/taskfile.js +19 -0
  8. package/dist/doctor/types.d.ts +3 -0
  9. package/dist/hooks/dispatcher.d.ts +21 -1
  10. package/dist/hooks/dispatcher.js +85 -15
  11. package/dist/init-deposit/agent-hooks.js +14 -6
  12. package/dist/init-deposit/gitignore.js +5 -0
  13. package/dist/intake/issue-emit.d.ts +45 -2
  14. package/dist/intake/issue-emit.js +420 -17
  15. package/dist/intake/issue-ingest.js +54 -4
  16. package/dist/platform/platform-capabilities.js +3 -0
  17. package/dist/policy/org-force-on-migration.js +2 -0
  18. package/dist/render/framework-commands.d.ts +1 -1
  19. package/dist/render/framework-commands.js +6 -6
  20. package/dist/render/roadmap-render.d.ts +5 -1
  21. package/dist/render/roadmap-render.js +20 -2
  22. package/dist/render/rule-map.js +5 -0
  23. package/dist/review-monitor/constants.js +3 -2
  24. package/dist/review-monitor/tier-detection.d.ts +6 -2
  25. package/dist/review-monitor/tier-detection.js +27 -2
  26. package/dist/scope/transition.js +43 -0
  27. package/dist/session/release-availability.d.ts +2 -0
  28. package/dist/session/release-availability.js +23 -8
  29. package/dist/swarm/routing-set-cli.js +5 -10
  30. package/dist/swarm/routing.d.ts +3 -2
  31. package/dist/swarm/routing.js +16 -4
  32. package/dist/triage/help/registry-data.d.ts +7 -7
  33. package/dist/triage/help/registry-data.js +15 -6
  34. package/dist/triage/queue/index.d.ts +1 -0
  35. package/dist/triage/queue/index.js +1 -0
  36. package/dist/triage/queue/show.d.ts +69 -0
  37. package/dist/triage/queue/show.js +293 -0
  38. package/dist/triage/scope/cli.js +3 -0
  39. package/dist/triage/scope/coverage.d.ts +2 -0
  40. package/dist/triage/scope/coverage.js +18 -3
  41. package/dist/verify-env/agent-hooks-live-probe.d.ts +32 -0
  42. package/dist/verify-env/agent-hooks-live-probe.js +216 -0
  43. package/dist/verify-env/index.d.ts +1 -0
  44. package/dist/verify-env/index.js +1 -0
  45. package/dist/verify-source/index.d.ts +1 -0
  46. package/dist/verify-source/index.js +1 -0
  47. package/dist/verify-source/openclaw-tier1.d.ts +37 -0
  48. package/dist/verify-source/openclaw-tier1.js +100 -0
  49. package/dist/xbrief-migrate/migrate-project.js +35 -22
  50. package/package.json +3 -3
@@ -0,0 +1,100 @@
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ export const OPENCLAW_TIER1_TARGETS = [
4
+ {
5
+ path: "content/skills/deft-directive-swarm/SKILL.md",
6
+ label: "swarm Phase 3 capability matrix",
7
+ markers: [
8
+ "Probe for the OpenClaw `sessions_spawn` tool",
9
+ "sessions_spawn",
10
+ "openclaw",
11
+ "Step 2f: OpenClaw Launch",
12
+ ],
13
+ },
14
+ {
15
+ path: "packages/core/src/swarm/routing.ts",
16
+ label: "swarm routing dispatch_provider",
17
+ // Prefer operative identifiers (function + return), not free-floating prose.
18
+ markers: [
19
+ "export function resolveDispatchProvider",
20
+ 'return "openclaw"',
21
+ "DEFT_HAS_SESSIONS_SPAWN",
22
+ "ROUTING_GATED_DISPATCH_PROVIDERS",
23
+ ],
24
+ },
25
+ {
26
+ path: "packages/core/src/swarm/routing-set-cli.ts",
27
+ label: "swarm:routing-set provider resolution",
28
+ markers: ["resolveDispatchProvider", "openclaw"],
29
+ },
30
+ ];
31
+ /** Collapse all runs of whitespace to a single space (substring-containment normalization). */
32
+ function normalizeWhitespace(text) {
33
+ return text.replace(/\s+/g, " ");
34
+ }
35
+ export function evaluateOpenclawTier1(projectRoot, options = {}) {
36
+ const root = resolve(projectRoot);
37
+ let isDir = false;
38
+ try {
39
+ isDir = statSync(root).isDirectory();
40
+ }
41
+ catch {
42
+ isDir = false;
43
+ }
44
+ if (!isDir) {
45
+ return {
46
+ code: 2,
47
+ findings: [],
48
+ message: `verify_openclaw_tier1: --project-root is not a directory: ${root}\n` +
49
+ " Recovery: pass an existing directory path.",
50
+ stream: "stderr",
51
+ };
52
+ }
53
+ const targets = options.targets ?? OPENCLAW_TIER1_TARGETS;
54
+ const findings = [];
55
+ for (const target of targets) {
56
+ const full = join(root, target.path);
57
+ if (!existsSync(full)) {
58
+ return {
59
+ code: 2,
60
+ findings: [...findings],
61
+ message: `verify_openclaw_tier1: required surface file not found: ${target.path}\n` +
62
+ " Recovery: run from the framework source root, or update OPENCLAW_TIER1_TARGETS if the path moved.",
63
+ stream: "stderr",
64
+ };
65
+ }
66
+ let normalized;
67
+ try {
68
+ normalized = normalizeWhitespace(readFileSync(full, { encoding: "utf8" }));
69
+ }
70
+ catch (err) {
71
+ const msg = err instanceof Error ? err.message : String(err);
72
+ return {
73
+ code: 2,
74
+ findings: [...findings],
75
+ message: `verify_openclaw_tier1: could not read ${target.path}: ${msg}`,
76
+ stream: "stderr",
77
+ };
78
+ }
79
+ const missing = target.markers.filter((marker) => !normalized.includes(normalizeWhitespace(marker)));
80
+ if (missing.length > 0) {
81
+ findings.push({ path: target.path, label: target.label, missingMarkers: missing });
82
+ }
83
+ }
84
+ if (findings.length > 0) {
85
+ const header = "verify_openclaw_tier1: OpenClaw is not fully enumerated as a Tier-1 descriptor (#2875).\n" +
86
+ " Root cause: an OpenClaw agent has a first-class backgroundable sub-agent primitive (sessions_spawn) and\n" +
87
+ " is therefore Tier 1 / Approach 1. If the matrix or routing surfaces drop the openclaw descriptor, an\n" +
88
+ " OpenClaw session silently degrades to grok-build misclassification or generic-terminal. Re-add the missing marker(s):";
89
+ const body = findings
90
+ .map((f) => ` ${f.path} (${f.label}) missing: ${f.missingMarkers.map((m) => `"${m}"`).join(", ")}`)
91
+ .join("\n");
92
+ return { code: 1, findings, message: `${header}\n${body}`, stream: "stderr" };
93
+ }
94
+ const msg = `verify_openclaw_tier1: OpenClaw enumerated as a Tier-1 descriptor in ${targets.length} surface(s) (#2875).`;
95
+ if (options.quiet) {
96
+ return { code: 0, findings: [], message: "", stream: "stdout" };
97
+ }
98
+ return { code: 0, findings: [], message: msg, stream: "stdout" };
99
+ }
100
+ //# sourceMappingURL=openclaw-tier1.js.map
@@ -1,7 +1,8 @@
1
1
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
2
  import { dirname, join, relative, resolve } from "node:path";
3
+ import { assertWriteTargetSafe, ProjectionContainmentError } from "../fs/projection-containment.js";
3
4
  import { checkGitClean } from "../migrate-preflight/index.js";
4
- import { agentsRefreshPlan } from "../platform/agents-md.js";
5
+ import { applyAgentsRefresh } from "../platform/agents-md.js";
5
6
  import { patchAgentsMdHeader, renderHeaderPatchSummary } from "./agents-header.js";
6
7
  import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, OBSOLETE_FRAMEWORK_NARRATIVE_FILENAME, VBRIEF_DEPRECATION_MARKER_BODY, VBRIEF_DEPRECATION_MARKER_FILENAME, } from "./constants.js";
7
8
  import { detectLegacyVbriefLayout, detectXbriefConvergence } from "./detect.js";
@@ -107,7 +108,7 @@ function migrateLegacyTree(projectRoot, legacyDir, options) {
107
108
  // either removed (default) or retained for read-compat behind an explicit
108
109
  // deprecation marker so it never looks like an active source of truth (#2270).
109
110
  if (options.keepLegacy) {
110
- writeVbriefDeprecationMarker(legacyDir);
111
+ writeVbriefDeprecationMarker(projectRoot, legacyDir);
111
112
  }
112
113
  else {
113
114
  rmSync(legacyDir, { recursive: true, force: true });
@@ -119,13 +120,17 @@ function migrateLegacyTree(projectRoot, legacyDir, options) {
119
120
  throw err;
120
121
  }
121
122
  }
122
- /** Idempotently write the legacy-root deprecation marker (#2270). */
123
- function writeVbriefDeprecationMarker(legacyDir) {
123
+ /** Idempotently write the legacy-root deprecation marker (#2270 / #2869). */
124
+ function writeVbriefDeprecationMarker(projectRoot, legacyDir) {
125
+ const markerPath = join(legacyDir, VBRIEF_DEPRECATION_MARKER_FILENAME);
126
+ // Refuse leaf or parent-dir symlink escapes before mkdir/write (#2869).
127
+ assertWriteTargetSafe(projectRoot, legacyDir);
128
+ assertWriteTargetSafe(projectRoot, markerPath);
124
129
  mkdirSync(legacyDir, { recursive: true });
125
130
  if (hasVbriefDeprecationMarker(legacyDir)) {
126
131
  return;
127
132
  }
128
- writeFileSync(join(legacyDir, VBRIEF_DEPRECATION_MARKER_FILENAME), VBRIEF_DEPRECATION_MARKER_BODY, "utf8");
133
+ writeFileSync(markerPath, VBRIEF_DEPRECATION_MARKER_BODY, "utf8");
129
134
  }
130
135
  /**
131
136
  * Converge a leftover legacy `vbrief/` root to an unambiguous state (#2270).
@@ -146,7 +151,7 @@ export function convergeLegacyVbriefRoot(projectRoot, options) {
146
151
  rmSync(legacyDir, { recursive: true, force: true });
147
152
  return "removed";
148
153
  }
149
- writeVbriefDeprecationMarker(legacyDir);
154
+ writeVbriefDeprecationMarker(projectRoot, legacyDir);
150
155
  return "marker";
151
156
  }
152
157
  function renameOrReplace(src, dest) {
@@ -157,25 +162,33 @@ function renameOrReplace(src, dest) {
157
162
  rmSync(src, { recursive: true, force: true });
158
163
  }
159
164
  function runAgentsRefresh(projectRoot, frameworkRoot, io) {
160
- const plan = agentsRefreshPlan(projectRoot, { frameworkRoot });
161
- const state = String(plan.state ?? "unknown");
162
- if (state === "current") {
163
- io.writeOut("AGENTS.md managed section is current — no changes.\n");
165
+ try {
166
+ assertWriteTargetSafe(projectRoot, join(projectRoot, "AGENTS.md"));
167
+ const { state, wrote, writable } = applyAgentsRefresh(projectRoot, {}, { frameworkRoot });
168
+ if (state === "current") {
169
+ io.writeOut("AGENTS.md managed section is current — no changes.\n");
170
+ return 0;
171
+ }
172
+ if (state === "template-missing" || state === "template-malformed" || state === "unreadable") {
173
+ io.writeErr(`agents:refresh failed: ${state}\n`);
174
+ return 2;
175
+ }
176
+ if (!writable) {
177
+ io.writeErr("agents:refresh failed: plan produced no new_content\n");
178
+ return 2;
179
+ }
180
+ if (wrote) {
181
+ io.writeOut(`AGENTS.md updated (state=${state}).\n`);
182
+ }
164
183
  return 0;
165
184
  }
166
- if (state === "template-missing" || state === "template-malformed" || state === "unreadable") {
167
- io.writeErr(`agents:refresh failed: ${state}\n`);
168
- return 2;
169
- }
170
- const newContent = plan.new_content;
171
- if (typeof newContent !== "string") {
172
- io.writeErr("agents:refresh failed: plan produced no new_content\n");
173
- return 2;
185
+ catch (err) {
186
+ if (err instanceof ProjectionContainmentError) {
187
+ io.writeErr(`agents:refresh failed: ${err.message}\n`);
188
+ return 2;
189
+ }
190
+ throw err;
174
191
  }
175
- const path = String(plan.path ?? join(projectRoot, "AGENTS.md"));
176
- writeFileSync(path, newContent, "utf8");
177
- io.writeOut(`AGENTS.md updated (state=${state}).\n`);
178
- return 0;
179
192
  }
180
193
  /** Core orchestrator for the consumer xbrief rename (#2110) + convergence (#2270). */
181
194
  export function runXbriefMigration(args, _io) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-core",
3
- "version": "0.85.0",
3
+ "version": "0.87.0",
4
4
  "description": "TypeScript engine core for the Directive framework.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -317,8 +317,8 @@
317
317
  "provenance": true
318
318
  },
319
319
  "dependencies": {
320
- "@deftai/directive-content": "^0.85.0",
321
- "@deftai/directive-types": "^0.85.0",
320
+ "@deftai/directive-content": "^0.87.0",
321
+ "@deftai/directive-types": "^0.87.0",
322
322
  "archiver": "^8.0.0"
323
323
  },
324
324
  "scripts": {