@deftai/directive-core 0.91.0 → 0.93.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 (92) hide show
  1. package/dist/cache/fetch.js +3 -2
  2. package/dist/cache/io.d.ts +13 -2
  3. package/dist/cache/io.js +36 -7
  4. package/dist/cache/operations.js +5 -3
  5. package/dist/doctor/index.d.ts +1 -0
  6. package/dist/doctor/index.js +1 -0
  7. package/dist/doctor/main.js +49 -0
  8. package/dist/doctor/openclaw-l2-adapter.d.ts +26 -0
  9. package/dist/doctor/openclaw-l2-adapter.js +199 -0
  10. package/dist/hooks/dispatcher.d.ts +6 -1
  11. package/dist/hooks/dispatcher.js +30 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +2 -0
  14. package/dist/init-deposit/gitignore.js +3 -0
  15. package/dist/init-deposit/hygiene.d.ts +43 -1
  16. package/dist/init-deposit/hygiene.js +134 -10
  17. package/dist/init-deposit/index.d.ts +3 -0
  18. package/dist/init-deposit/index.js +3 -0
  19. package/dist/init-deposit/init-deposit.js +10 -0
  20. package/dist/init-deposit/refresh.js +11 -0
  21. package/dist/init-deposit/scaffold.js +6 -134
  22. package/dist/init-deposit/skill-discovery-deposit.d.ts +65 -0
  23. package/dist/init-deposit/skill-discovery-deposit.js +287 -0
  24. package/dist/init-deposit/skill-discovery-hosts.d.ts +94 -0
  25. package/dist/init-deposit/skill-discovery-hosts.js +217 -0
  26. package/dist/init-deposit/slash-deposit.d.ts +46 -0
  27. package/dist/init-deposit/slash-deposit.js +174 -0
  28. package/dist/orchestration/probe-session.d.ts +5 -1
  29. package/dist/orchestration/probe-session.js +24 -13
  30. package/dist/platform/agents-md.js +1 -1
  31. package/dist/policy/deft-directive-disable.d.ts +86 -0
  32. package/dist/policy/deft-directive-disable.js +167 -0
  33. package/dist/policy/delivery-branch.d.ts +33 -0
  34. package/dist/policy/delivery-branch.js +124 -0
  35. package/dist/policy/host-slash-commands.d.ts +28 -0
  36. package/dist/policy/host-slash-commands.js +103 -0
  37. package/dist/policy/index.d.ts +3 -0
  38. package/dist/policy/index.js +61 -5
  39. package/dist/scope/brief-io.d.ts +3 -1
  40. package/dist/scope/brief-io.js +5 -3
  41. package/dist/scope/delivery-evidence.d.ts +112 -0
  42. package/dist/scope/delivery-evidence.js +419 -0
  43. package/dist/scope/index.d.ts +1 -0
  44. package/dist/scope/index.js +1 -0
  45. package/dist/scope/main.d.ts +5 -0
  46. package/dist/scope/main.js +98 -3
  47. package/dist/scope/registry-artifact-sync.js +4 -1
  48. package/dist/scope/transition.d.ts +11 -1
  49. package/dist/scope/transition.js +30 -4
  50. package/dist/session/ritual-sentinel.js +21 -12
  51. package/dist/session/session-start-hook.d.ts +3 -0
  52. package/dist/session/session-start-hook.js +21 -0
  53. package/dist/session/session-start.js +31 -0
  54. package/dist/slash/emitters.d.ts +102 -0
  55. package/dist/slash/emitters.js +148 -0
  56. package/dist/slash/generator.d.ts +98 -0
  57. package/dist/slash/generator.js +145 -0
  58. package/dist/slash/index.d.ts +16 -0
  59. package/dist/slash/index.js +16 -0
  60. package/dist/slash/openclaw-adapter.d.ts +64 -0
  61. package/dist/slash/openclaw-adapter.js +198 -0
  62. package/dist/slash/openclaw-deposit.d.ts +73 -0
  63. package/dist/slash/openclaw-deposit.js +279 -0
  64. package/dist/slash/openclaw-slugs.d.ts +52 -0
  65. package/dist/slash/openclaw-slugs.js +126 -0
  66. package/dist/slash/product-set.d.ts +50 -0
  67. package/dist/slash/product-set.js +142 -0
  68. package/dist/swarm/complete-cohort.d.ts +20 -1
  69. package/dist/swarm/complete-cohort.js +56 -9
  70. package/dist/swarm/finalize-cohort-cli.js +9 -0
  71. package/dist/swarm/finalize-cohort.d.ts +8 -0
  72. package/dist/swarm/finalize-cohort.js +217 -21
  73. package/dist/user-config/experimental-rules.d.ts +43 -0
  74. package/dist/user-config/experimental-rules.js +162 -0
  75. package/dist/user-config/index.d.ts +1 -0
  76. package/dist/user-config/index.js +1 -0
  77. package/dist/vbrief-validate/plan-hooks.d.ts +4 -0
  78. package/dist/vbrief-validate/plan-hooks.js +50 -0
  79. package/dist/verify-source/contained-writes.js +1 -1
  80. package/dist/xbrief/create.d.ts +36 -0
  81. package/dist/xbrief/create.js +285 -0
  82. package/dist/xbrief/index.d.ts +14 -0
  83. package/dist/xbrief/index.js +42 -0
  84. package/dist/xbrief/paths.d.ts +37 -0
  85. package/dist/xbrief/paths.js +123 -0
  86. package/dist/xbrief/styles.d.ts +36 -0
  87. package/dist/xbrief/styles.js +235 -0
  88. package/dist/xbrief/types.d.ts +50 -0
  89. package/dist/xbrief/types.js +17 -0
  90. package/dist/xbrief/verify.d.ts +30 -0
  91. package/dist/xbrief/verify.js +251 -0
  92. package/package.json +11 -3
@@ -0,0 +1,251 @@
1
+ /**
2
+ * xbrief:verify — fail-closed check of an xBRIEF artifact at --out (#3057).
3
+ *
4
+ * Required: --format (json|md|both), --out
5
+ * Checks: schema/parse, required fields, size cap, md sections per style,
6
+ * and stem/title/id consistency when format=both.
7
+ *
8
+ * Does NOT move lifecycle folders.
9
+ */
10
+ import { existsSync, readFileSync, statSync } from "node:fs";
11
+ import { validateVbriefSchema } from "../vbrief-validate/schema.js";
12
+ import { resolveXbriefOutPaths, XbriefPathError } from "./paths.js";
13
+ import { MD_REQUIRED_SECTIONS, parseMarkdownMeta } from "./styles.js";
14
+ import { DEFAULT_XBRIEF_SIZE_CAP_BYTES, isXbriefFormat, isXbriefStyle, } from "./types.js";
15
+ export const VERIFY_USAGE = "Usage: deft xbrief:verify -- --format <json|md|both> --out <path> [--style <scope|playbook|mission|project>] [--project-root <dir>]\n" +
16
+ " Verify a dense xBRIEF artifact at --out. Required: --format and --out.\n" +
17
+ " verify ≠ lifecycle: does not promote/activate/complete (use scope:* for lifecycle).\n";
18
+ function fail(stderr, exitCode = 1) {
19
+ return { exitCode, stdout: "", stderr };
20
+ }
21
+ function parseFlagValue(argv, i, name) {
22
+ const eq = argv[i]?.startsWith(`${name}=`) ? argv[i].slice(name.length + 1) : undefined;
23
+ if (eq !== undefined) {
24
+ if (eq.length === 0)
25
+ return { error: `argument ${name}: expected one argument\n` };
26
+ return { value: eq, next: i };
27
+ }
28
+ const next = argv[i + 1];
29
+ if (next === undefined || next.startsWith("-")) {
30
+ return { error: `argument ${name}: expected one argument\n` };
31
+ }
32
+ return { value: next, next: i + 1 };
33
+ }
34
+ /** Parse verify CLI argv into options (or error string). */
35
+ export function parseVerifyArgv(argv) {
36
+ let format;
37
+ let out;
38
+ let style;
39
+ let projectRoot = process.cwd();
40
+ for (let i = 0; i < argv.length; i += 1) {
41
+ const arg = argv[i];
42
+ if (arg === undefined)
43
+ continue;
44
+ if (arg === "-h" || arg === "--help") {
45
+ return { error: VERIFY_USAGE };
46
+ }
47
+ if (arg === "--format" || arg.startsWith("--format=")) {
48
+ const parsed = parseFlagValue(argv, i, "--format");
49
+ if ("error" in parsed)
50
+ return parsed;
51
+ format = parsed.value;
52
+ i = parsed.next;
53
+ continue;
54
+ }
55
+ if (arg === "--out" || arg.startsWith("--out=")) {
56
+ const parsed = parseFlagValue(argv, i, "--out");
57
+ if ("error" in parsed)
58
+ return parsed;
59
+ out = parsed.value;
60
+ i = parsed.next;
61
+ continue;
62
+ }
63
+ if (arg === "--style" || arg.startsWith("--style=")) {
64
+ const parsed = parseFlagValue(argv, i, "--style");
65
+ if ("error" in parsed)
66
+ return parsed;
67
+ style = parsed.value;
68
+ i = parsed.next;
69
+ continue;
70
+ }
71
+ if (arg === "--project-root" || arg.startsWith("--project-root=")) {
72
+ const parsed = parseFlagValue(argv, i, "--project-root");
73
+ if ("error" in parsed)
74
+ return parsed;
75
+ projectRoot = parsed.value;
76
+ i = parsed.next;
77
+ continue;
78
+ }
79
+ if (arg === "--")
80
+ continue;
81
+ return { error: `unrecognized argument: ${arg}\n${VERIFY_USAGE}` };
82
+ }
83
+ if (format === undefined) {
84
+ return { error: `missing required --format (json|md|both)\n${VERIFY_USAGE}` };
85
+ }
86
+ if (!isXbriefFormat(format)) {
87
+ return { error: `invalid --format ${format} (expected json|md|both)\n${VERIFY_USAGE}` };
88
+ }
89
+ if (out === undefined || out.length === 0) {
90
+ return { error: `missing required --out\n${VERIFY_USAGE}` };
91
+ }
92
+ if (style !== undefined && !isXbriefStyle(style)) {
93
+ return {
94
+ error: `invalid --style ${style} (expected scope|playbook|mission|project)\n${VERIFY_USAGE}`,
95
+ };
96
+ }
97
+ return {
98
+ format,
99
+ out,
100
+ style: style,
101
+ projectRoot,
102
+ };
103
+ }
104
+ function readText(path, sizeCap) {
105
+ if (!existsSync(path)) {
106
+ return { error: `missing file: ${path}\n` };
107
+ }
108
+ try {
109
+ const st = statSync(path);
110
+ if (!st.isFile()) {
111
+ return { error: `not a file: ${path}\n` };
112
+ }
113
+ if (st.size > sizeCap) {
114
+ return { error: `file exceeds size cap (${sizeCap} bytes): ${path}\n` };
115
+ }
116
+ return readFileSync(path, "utf8");
117
+ }
118
+ catch (err) {
119
+ const msg = err instanceof Error ? err.message : String(err);
120
+ return { error: `failed to read ${path}: ${msg}\n` };
121
+ }
122
+ }
123
+ function parseJsonDoc(text, label) {
124
+ try {
125
+ const data = JSON.parse(text);
126
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
127
+ return { ok: false, error: `${label}: JSON root must be an object\n` };
128
+ }
129
+ return { ok: true, doc: data };
130
+ }
131
+ catch (err) {
132
+ const msg = err instanceof Error ? err.message : String(err);
133
+ return { ok: false, error: `${label}: invalid JSON (${msg})\n` };
134
+ }
135
+ }
136
+ function resolveStyle(explicit, doc, mdStyle) {
137
+ if (explicit !== undefined)
138
+ return explicit;
139
+ if (doc !== null) {
140
+ const meta = doc.plan.metadata;
141
+ if (typeof meta === "object" && meta !== null && !Array.isArray(meta)) {
142
+ const kind = meta.kind;
143
+ if (typeof kind === "string" && isXbriefStyle(kind))
144
+ return kind;
145
+ }
146
+ }
147
+ if (mdStyle !== null && isXbriefStyle(mdStyle))
148
+ return mdStyle;
149
+ return "scope";
150
+ }
151
+ /** Core verify implementation (testable). */
152
+ export function verifyXbrief(options) {
153
+ let paths;
154
+ try {
155
+ paths = resolveXbriefOutPaths({
156
+ projectRoot: options.projectRoot,
157
+ out: options.out,
158
+ format: options.format,
159
+ cwd: options.cwd,
160
+ home: options.home,
161
+ env: options.env,
162
+ });
163
+ }
164
+ catch (err) {
165
+ if (err instanceof XbriefPathError) {
166
+ return fail(`${err.message}\n`, 1);
167
+ }
168
+ throw err;
169
+ }
170
+ const sizeCap = options.sizeCapBytes ?? DEFAULT_XBRIEF_SIZE_CAP_BYTES;
171
+ const errors = [];
172
+ let doc = null;
173
+ let mdMeta = null;
174
+ if (paths.jsonAbs !== null) {
175
+ const text = readText(paths.jsonAbs, sizeCap);
176
+ if (typeof text !== "string") {
177
+ errors.push(text.error.trimEnd());
178
+ }
179
+ else {
180
+ const parsed = parseJsonDoc(text, paths.jsonAbs);
181
+ if (!parsed.ok) {
182
+ errors.push(parsed.error.trimEnd());
183
+ }
184
+ else {
185
+ doc = parsed.doc;
186
+ const schemaErrors = validateVbriefSchema(doc, paths.jsonAbs);
187
+ for (const e of schemaErrors)
188
+ errors.push(e);
189
+ }
190
+ }
191
+ }
192
+ if (paths.mdAbs !== null) {
193
+ const text = readText(paths.mdAbs, sizeCap);
194
+ if (typeof text !== "string") {
195
+ errors.push(text.error.trimEnd());
196
+ }
197
+ else {
198
+ mdMeta = parseMarkdownMeta(text);
199
+ const style = resolveStyle(options.style, doc, mdMeta.style);
200
+ const required = MD_REQUIRED_SECTIONS[style];
201
+ for (const section of required) {
202
+ if (!mdMeta.sections.has(section)) {
203
+ errors.push(`${paths.mdAbs}: missing required markdown section '## ${section}' (style=${style})`);
204
+ }
205
+ }
206
+ if (mdMeta.title === null || mdMeta.title.length === 0) {
207
+ errors.push(`${paths.mdAbs}: missing title`);
208
+ }
209
+ if (mdMeta.status === null || mdMeta.status.length === 0) {
210
+ errors.push(`${paths.mdAbs}: missing status`);
211
+ }
212
+ }
213
+ }
214
+ // both: stem/title/id consistency between json + md
215
+ if (options.format === "both" && doc !== null && mdMeta !== null) {
216
+ if (mdMeta.title !== null && mdMeta.title !== doc.plan.title) {
217
+ errors.push(`title mismatch: json=${JSON.stringify(doc.plan.title)} md=${JSON.stringify(mdMeta.title)}`);
218
+ }
219
+ if (mdMeta.status !== null && mdMeta.status !== String(doc.plan.status)) {
220
+ errors.push(`status mismatch: json=${JSON.stringify(doc.plan.status)} md=${JSON.stringify(mdMeta.status)}`);
221
+ }
222
+ const jsonId = typeof doc.plan.id === "string" ? doc.plan.id : null;
223
+ if (jsonId !== null && mdMeta.id !== null && jsonId !== mdMeta.id) {
224
+ errors.push(`id mismatch: json=${JSON.stringify(jsonId)} md=${JSON.stringify(mdMeta.id)}`);
225
+ }
226
+ }
227
+ if (errors.length > 0) {
228
+ return fail(`xbrief:verify failed:\n${errors.map((e) => ` - ${e}`).join("\n")}\n`, 1);
229
+ }
230
+ const checked = [paths.jsonAbs, paths.mdAbs].filter((p) => p !== null);
231
+ const lines = [
232
+ `OK xbrief:verify format=${options.format}`,
233
+ ...checked.map((p) => ` checked ${p}`),
234
+ " note: verify is not a lifecycle move (scope:* handles promote/activate/complete)",
235
+ ];
236
+ return { exitCode: 0, stdout: `${lines.join("\n")}\n`, stderr: "" };
237
+ }
238
+ /** CLI entry for dispatch wrapper. */
239
+ export function runXbriefVerifyCli(argv) {
240
+ const parsed = parseVerifyArgv(argv);
241
+ if ("error" in parsed) {
242
+ const isHelp = parsed.error === VERIFY_USAGE;
243
+ return {
244
+ exitCode: isHelp ? 0 : 2,
245
+ stdout: isHelp ? VERIFY_USAGE : "",
246
+ stderr: isHelp ? "" : parsed.error,
247
+ };
248
+ }
249
+ return verifyXbrief(parsed);
250
+ }
251
+ //# sourceMappingURL=verify.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-core",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "description": "TypeScript engine core for the Directive framework.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,6 +23,10 @@
23
23
  "types": "./dist/story-ready/index.d.ts",
24
24
  "default": "./dist/story-ready/index.js"
25
25
  },
26
+ "./slash": {
27
+ "types": "./dist/slash/index.d.ts",
28
+ "default": "./dist/slash/index.js"
29
+ },
26
30
  "./branch": {
27
31
  "types": "./dist/branch/index.d.ts",
28
32
  "default": "./dist/branch/index.js"
@@ -55,6 +59,10 @@
55
59
  "types": "./dist/xbrief-migrate/index.d.ts",
56
60
  "default": "./dist/xbrief-migrate/index.js"
57
61
  },
62
+ "./xbrief": {
63
+ "types": "./dist/xbrief/index.d.ts",
64
+ "default": "./dist/xbrief/index.js"
65
+ },
58
66
  "./category-b-namespace": {
59
67
  "types": "./dist/category-b-namespace/index.d.ts",
60
68
  "default": "./dist/category-b-namespace/index.js"
@@ -334,8 +342,8 @@
334
342
  "provenance": true
335
343
  },
336
344
  "dependencies": {
337
- "@deftai/directive-content": "^0.91.0",
338
- "@deftai/directive-types": "^0.91.0",
345
+ "@deftai/directive-content": "^0.93.0",
346
+ "@deftai/directive-types": "^0.93.0",
339
347
  "archiver": "^8.0.0"
340
348
  },
341
349
  "scripts": {