clawvault 3.0.0-beta.3 → 3.0.0-beta.5

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.
@@ -4,8 +4,6 @@ import * as path from "path";
4
4
  import matter from "gray-matter";
5
5
  import { spawnSync } from "child_process";
6
6
  import { fileURLToPath } from "url";
7
- var REQUIRED_HOOK_EVENTS = ["gateway:startup", "command:new", "session:start"];
8
- var REQUIRED_HOOK_BIN = "clawvault";
9
7
  function readOptionalFile(filePath) {
10
8
  try {
11
9
  if (!fs.existsSync(filePath)) return null;
@@ -24,19 +22,6 @@ function findPackageRoot() {
24
22
  }
25
23
  return path.dirname(fileURLToPath(import.meta.url));
26
24
  }
27
- function resolveOpenClawHooksDir() {
28
- const candidates = [
29
- path.join(process.env.HOME || "", ".openclaw", "hooks", "clawvault"),
30
- path.join(process.env.OPENCLAW_HOME || "", "hooks", "clawvault"),
31
- path.join(process.env.OPENCLAW_STATE_DIR || "", "hooks", "clawvault")
32
- ].filter((p) => p && !p.startsWith(path.sep + "hooks"));
33
- for (const candidate of candidates) {
34
- if (fs.existsSync(candidate)) {
35
- return candidate;
36
- }
37
- }
38
- return null;
39
- }
40
25
  function resolveProjectFile(relativePath, baseDir) {
41
26
  if (baseDir) {
42
27
  return path.resolve(baseDir, relativePath);
@@ -45,20 +30,6 @@ function resolveProjectFile(relativePath, baseDir) {
45
30
  if (fs.existsSync(fromCwd)) {
46
31
  return fromCwd;
47
32
  }
48
- if (relativePath.startsWith("hooks/clawvault/")) {
49
- const hooksDir = resolveOpenClawHooksDir();
50
- if (hooksDir) {
51
- const hookRelative = relativePath.replace("hooks/clawvault/", "");
52
- const fromHooks = path.resolve(hooksDir, hookRelative);
53
- if (fs.existsSync(fromHooks)) {
54
- return fromHooks;
55
- }
56
- const fromNestedHooks = path.resolve(hooksDir, "hooks", "clawvault", hookRelative);
57
- if (fs.existsSync(fromNestedHooks)) {
58
- return fromNestedHooks;
59
- }
60
- }
61
- }
62
33
  return path.resolve(findPackageRoot(), relativePath);
63
34
  }
64
35
  function checkOpenClawCli() {
@@ -68,7 +39,7 @@ function checkOpenClawCli() {
68
39
  label: "openclaw CLI available",
69
40
  status: "warn",
70
41
  detail: "openclaw binary not found",
71
- hint: "Install OpenClaw CLI to enable hook runtime validation."
42
+ hint: "Install OpenClaw CLI to enable plugin runtime validation."
72
43
  };
73
44
  }
74
45
  if (typeof result.status === "number" && result.status !== 0) {
@@ -89,152 +60,106 @@ function checkOpenClawCli() {
89
60
  }
90
61
  return { label: "openclaw CLI available", status: "ok" };
91
62
  }
92
- function checkPackageHookRegistration(options) {
93
- let packageRaw = readOptionalFile(resolveProjectFile("package.json", options.baseDir));
94
- if (packageRaw && !options.baseDir) {
95
- try {
96
- const parsed = JSON.parse(packageRaw);
97
- if (!parsed.openclaw?.hooks) {
98
- const fallbackPath = path.resolve(findPackageRoot(), "package.json");
99
- const fallbackRaw = readOptionalFile(fallbackPath);
100
- if (fallbackRaw) packageRaw = fallbackRaw;
101
- }
102
- } catch {
103
- }
104
- }
105
- if (!packageRaw) {
63
+ function checkPluginManifest(options) {
64
+ const manifestRaw = readOptionalFile(
65
+ resolveProjectFile("openclaw.plugin.json", options.baseDir)
66
+ );
67
+ if (!manifestRaw) {
106
68
  return {
107
- label: "package hook registration",
69
+ label: "plugin manifest",
108
70
  status: "error",
109
- detail: "package.json not found"
71
+ detail: "openclaw.plugin.json not found",
72
+ hint: "Create openclaw.plugin.json with id, kind, and configSchema fields."
110
73
  };
111
74
  }
112
75
  try {
113
- const parsed = JSON.parse(packageRaw);
114
- const registeredHooks = parsed.openclaw?.hooks ?? [];
115
- if (registeredHooks.includes("./hooks/clawvault")) {
76
+ const manifest = JSON.parse(manifestRaw);
77
+ const issues = [];
78
+ if (!manifest.id) issues.push("missing id");
79
+ if (!manifest.kind) issues.push("missing kind");
80
+ if (!manifest.configSchema) issues.push("missing configSchema");
81
+ if (issues.length > 0) {
116
82
  return {
117
- label: "package hook registration",
118
- status: "ok",
119
- detail: "./hooks/clawvault"
83
+ label: "plugin manifest",
84
+ status: "error",
85
+ detail: issues.join(", ")
120
86
  };
121
87
  }
122
88
  return {
123
- label: "package hook registration",
124
- status: "error",
125
- detail: "Missing ./hooks/clawvault in package openclaw.hooks"
89
+ label: "plugin manifest",
90
+ status: "ok",
91
+ detail: `id=${manifest.id} kind=${manifest.kind}`
126
92
  };
127
93
  } catch (err) {
128
94
  return {
129
- label: "package hook registration",
95
+ label: "plugin manifest",
130
96
  status: "error",
131
- detail: err?.message || "Unable to parse package.json"
97
+ detail: err?.message || "Unable to parse openclaw.plugin.json"
132
98
  };
133
99
  }
134
100
  }
135
- function checkHookManifest(options) {
136
- const hookRaw = readOptionalFile(resolveProjectFile("hooks/clawvault/HOOK.md", options.baseDir));
137
- if (!hookRaw) {
101
+ function checkPluginExtensions(options) {
102
+ let packageRaw = readOptionalFile(
103
+ resolveProjectFile("package.json", options.baseDir)
104
+ );
105
+ if (packageRaw && !options.baseDir) {
106
+ try {
107
+ const parsed = JSON.parse(packageRaw);
108
+ if (!parsed.openclaw?.extensions) {
109
+ const fallbackPath = path.resolve(findPackageRoot(), "package.json");
110
+ const fallbackRaw = readOptionalFile(fallbackPath);
111
+ if (fallbackRaw) packageRaw = fallbackRaw;
112
+ }
113
+ } catch {
114
+ }
115
+ }
116
+ if (!packageRaw) {
138
117
  return {
139
- label: "hook manifest",
118
+ label: "plugin extensions registration",
140
119
  status: "error",
141
- detail: "HOOK.md not found"
120
+ detail: "package.json not found"
142
121
  };
143
122
  }
144
123
  try {
145
- const parsed = matter(hookRaw);
146
- const openclaw = parsed.data?.metadata?.openclaw;
147
- const events = Array.isArray(openclaw?.events) ? openclaw?.events ?? [] : [];
148
- const missingEvents = REQUIRED_HOOK_EVENTS.filter((event) => !events.includes(event));
149
- if (missingEvents.length === 0) {
124
+ const parsed = JSON.parse(packageRaw);
125
+ const extensions = parsed.openclaw?.extensions ?? [];
126
+ if (extensions.length === 0) {
150
127
  return {
151
- label: "hook manifest events",
152
- status: "ok",
153
- detail: events.join(", ")
128
+ label: "plugin extensions registration",
129
+ status: "error",
130
+ detail: "Missing openclaw.extensions in package.json",
131
+ hint: 'Add openclaw.extensions: ["./dist/plugin/index.js"] to package.json.'
154
132
  };
155
133
  }
156
- return {
157
- label: "hook manifest events",
158
- status: "error",
159
- detail: `Missing events: ${missingEvents.join(", ")}`
160
- };
161
- } catch (err) {
162
- return {
163
- label: "hook manifest events",
164
- status: "error",
165
- detail: err?.message || "Unable to parse HOOK.md frontmatter"
166
- };
167
- }
168
- }
169
- function checkHookManifestRequirements(options) {
170
- const hookRaw = readOptionalFile(resolveProjectFile("hooks/clawvault/HOOK.md", options.baseDir));
171
- if (!hookRaw) {
172
- return {
173
- label: "hook manifest requirements",
174
- status: "error",
175
- detail: "HOOK.md not found"
176
- };
177
- }
178
- try {
179
- const parsed = matter(hookRaw);
180
- const requiresBins = parsed.data?.metadata?.openclaw?.requires?.bins;
181
- const bins = Array.isArray(requiresBins) ? requiresBins : [];
182
- if (bins.includes(REQUIRED_HOOK_BIN)) {
134
+ const baseDir = options.baseDir || findPackageRoot();
135
+ const missing = extensions.filter(
136
+ (ext) => !fs.existsSync(path.resolve(baseDir, ext))
137
+ );
138
+ if (missing.length > 0) {
183
139
  return {
184
- label: "hook manifest requirements",
185
- status: "ok",
186
- detail: `bins: ${bins.join(", ")}`
140
+ label: "plugin extensions registration",
141
+ status: "error",
142
+ detail: `Entry file(s) not found: ${missing.join(", ")}`,
143
+ hint: "Run npm run build to generate dist files."
187
144
  };
188
145
  }
189
146
  return {
190
- label: "hook manifest requirements",
191
- status: "warn",
192
- detail: `Missing required hook bin "${REQUIRED_HOOK_BIN}"`,
193
- hint: 'Add metadata.openclaw.requires.bins: ["clawvault"] to hooks/clawvault/HOOK.md.'
147
+ label: "plugin extensions registration",
148
+ status: "ok",
149
+ detail: extensions.join(", ")
194
150
  };
195
151
  } catch (err) {
196
152
  return {
197
- label: "hook manifest requirements",
198
- status: "error",
199
- detail: err?.message || "Unable to parse HOOK.md frontmatter"
200
- };
201
- }
202
- }
203
- function checkHookHandlerSafety(options) {
204
- const handlerRaw = readOptionalFile(resolveProjectFile("hooks/clawvault/handler.js", options.baseDir));
205
- if (!handlerRaw) {
206
- return {
207
- label: "hook handler script",
153
+ label: "plugin extensions registration",
208
154
  status: "error",
209
- detail: "handler.js not found"
210
- };
211
- }
212
- const usesExecFileSync = handlerRaw.includes("execFileSync");
213
- const usesExecSync = /\bexecSync\b/.test(handlerRaw);
214
- const enablesShell = /\bshell\s*:\s*true\b/.test(handlerRaw);
215
- const delegatesAutoProfile = /['"]--profile['"]\s*,\s*['"]auto['"]/.test(handlerRaw);
216
- const violations = [];
217
- if (!usesExecFileSync || usesExecSync) {
218
- violations.push("execFileSync-only execution path");
219
- }
220
- if (enablesShell) {
221
- violations.push("shell:false execution option");
222
- }
223
- if (!delegatesAutoProfile) {
224
- violations.push("shared context profile delegation (--profile auto)");
225
- }
226
- if (violations.length > 0) {
227
- return {
228
- label: "hook handler safety",
229
- status: "warn",
230
- detail: `Missing conventions: ${violations.join(", ")}`,
231
- hint: "Use execFileSync (no shell), avoid execSync, and delegate profile inference via --profile auto."
155
+ detail: err?.message || "Unable to parse package.json"
232
156
  };
233
157
  }
234
- return { label: "hook handler safety", status: "ok" };
235
158
  }
236
159
  function checkSkillMetadata(options) {
237
- const skillRaw = readOptionalFile(resolveProjectFile("SKILL.md", options.baseDir));
160
+ const skillRaw = readOptionalFile(
161
+ resolveProjectFile("SKILL.md", options.baseDir)
162
+ );
238
163
  if (!skillRaw) {
239
164
  return {
240
165
  label: "skill metadata",
@@ -273,10 +198,8 @@ function checkSkillMetadata(options) {
273
198
  function checkOpenClawCompatibility(options = {}) {
274
199
  const checks = [
275
200
  checkOpenClawCli(),
276
- checkPackageHookRegistration(options),
277
- checkHookManifest(options),
278
- checkHookManifestRequirements(options),
279
- checkHookHandlerSafety(options),
201
+ checkPluginManifest(options),
202
+ checkPluginExtensions(options),
280
203
  checkSkillMetadata(options)
281
204
  ];
282
205
  const warnings = checks.filter((check) => check.status === "warn").length;
@@ -296,7 +219,9 @@ function formatCompatibilityReport(report) {
296
219
  lines.push("");
297
220
  for (const check of report.checks) {
298
221
  const prefix = check.status === "ok" ? "\u2713" : check.status === "warn" ? "\u26A0" : "\u2717";
299
- lines.push(`${prefix} ${check.label}${check.detail ? ` \u2014 ${check.detail}` : ""}`);
222
+ lines.push(
223
+ `${prefix} ${check.label}${check.detail ? ` \u2014 ${check.detail}` : ""}`
224
+ );
300
225
  if (check.hint) {
301
226
  lines.push(` ${check.hint}`);
302
227
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ClawVault
3
- } from "./chunk-WGRQ6HDV.js";
3
+ } from "./chunk-LI4O6NVK.js";
4
4
  import {
5
5
  getMemoryGraph
6
6
  } from "./chunk-ZZA73MFY.js";
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  hasQmd,
7
7
  withQmdIndexArgs
8
- } from "./chunk-K234IDRJ.js";
8
+ } from "./chunk-D2H45LON.js";
9
9
  import {
10
10
  DEFAULT_CATEGORIES
11
11
  } from "./chunk-2CDEETQN.js";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-SJSFRIYS.js";
10
10
  import {
11
11
  registerEmbedCommand
12
- } from "./chunk-7R7O6STJ.js";
12
+ } from "./chunk-OCGVIN3L.js";
13
13
  import {
14
14
  registerInjectCommand
15
15
  } from "./chunk-U55BGUAU.js";
@@ -18,10 +18,10 @@ import {
18
18
  } from "./chunk-MXSSG3QU.js";
19
19
  import {
20
20
  registerContextCommand
21
- } from "./chunk-ZVVFWOLW.js";
21
+ } from "./chunk-3WRJEKN4.js";
22
22
  import {
23
23
  reweave
24
- } from "./chunk-K234IDRJ.js";
24
+ } from "./chunk-D2H45LON.js";
25
25
 
26
26
  // src/commands/reweave.ts
27
27
  async function reweaveCommand(options) {
@@ -334,6 +334,7 @@ function stripQmdNoise(raw) {
334
334
  function parseQmdOutput(raw) {
335
335
  const trimmed = stripQmdNoise(raw).trim();
336
336
  if (!trimmed) return [];
337
+ if (trimmed.startsWith("No results") || trimmed.startsWith("No matches")) return [];
337
338
  const direct = tryParseJson(trimmed);
338
339
  const extracted = direct ? null : extractJsonPayload(trimmed);
339
340
  const parsed = direct ?? (extracted ? tryParseJson(extracted) : null);
@@ -9,14 +9,14 @@ import {
9
9
  } from "./chunk-LNJA2UGL.js";
10
10
  import {
11
11
  checkOpenClawCompatibility
12
- } from "./chunk-3D6BCTP6.js";
12
+ } from "./chunk-33UGEQRT.js";
13
13
  import {
14
14
  ClawVault,
15
15
  findVault
16
- } from "./chunk-WGRQ6HDV.js";
16
+ } from "./chunk-LI4O6NVK.js";
17
17
  import {
18
18
  hasQmd
19
- } from "./chunk-K234IDRJ.js";
19
+ } from "./chunk-D2H45LON.js";
20
20
  import {
21
21
  loadMemoryGraphIndex
22
22
  } from "./chunk-ZZA73MFY.js";
@@ -6,7 +6,7 @@ import {
6
6
  hasQmd,
7
7
  qmdEmbed,
8
8
  qmdUpdate
9
- } from "./chunk-K234IDRJ.js";
9
+ } from "./chunk-D2H45LON.js";
10
10
  import {
11
11
  DEFAULT_CATEGORIES,
12
12
  TYPE_TO_CATEGORY
@@ -5,7 +5,7 @@ import {
5
5
  QmdUnavailableError,
6
6
  hasQmd,
7
7
  qmdEmbed
8
- } from "./chunk-K234IDRJ.js";
8
+ } from "./chunk-D2H45LON.js";
9
9
 
10
10
  // src/lib/vault-qmd-config.ts
11
11
  import * as fs from "fs";
@@ -712,6 +712,7 @@ function stripQmdNoise(raw) {
712
712
  function parseQmdOutput(raw) {
713
713
  const trimmed = stripQmdNoise(raw).trim();
714
714
  if (!trimmed) return [];
715
+ if (trimmed.startsWith("No results") || trimmed.startsWith("No matches")) return [];
715
716
  const direct = tryParseJson(trimmed);
716
717
  const extracted = direct ? null : extractJsonPayload(trimmed);
717
718
  const parsed = direct ?? (extracted ? tryParseJson(extracted) : null);
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  registerCliCommands
3
- } from "../chunk-GAJV4IGR.js";
3
+ } from "../chunk-CZVQ3D2R.js";
4
4
  import "../chunk-THRJVD4L.js";
5
5
  import "../chunk-TIGW564L.js";
6
6
  import "../chunk-IVRIKYFE.js";
@@ -12,7 +12,7 @@ import "../chunk-LNJA2UGL.js";
12
12
  import "../chunk-3NSBOUT3.js";
13
13
  import "../chunk-62YTUT6J.js";
14
14
  import "../chunk-HRLWZGMA.js";
15
- import "../chunk-7R7O6STJ.js";
15
+ import "../chunk-OCGVIN3L.js";
16
16
  import "../chunk-U55BGUAU.js";
17
17
  import "../chunk-E7MFQB6D.js";
18
18
  import "../chunk-ITPEXLHA.js";
@@ -22,9 +22,9 @@ import "../chunk-MXSSG3QU.js";
22
22
  import "../chunk-N2AXRYLC.js";
23
23
  import "../chunk-LYHGEHXG.js";
24
24
  import "../chunk-7766SIJP.js";
25
- import "../chunk-ZVVFWOLW.js";
26
- import "../chunk-WGRQ6HDV.js";
27
- import "../chunk-K234IDRJ.js";
25
+ import "../chunk-3WRJEKN4.js";
26
+ import "../chunk-LI4O6NVK.js";
27
+ import "../chunk-D2H45LON.js";
28
28
  import "../chunk-2CDEETQN.js";
29
29
  import "../chunk-ZZA73MFY.js";
30
30
  import "../chunk-QK3UCXWL.js";