@openclawbrain/openclaw 0.3.2 → 0.3.3

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.
@@ -0,0 +1,25 @@
1
+ export type OpenClawBrainHookInstallState = "installed" | "not_installed" | "blocked_by_allowlist" | "unverified";
2
+ export type OpenClawBrainHookLoadability = "loadable" | "blocked" | "not_installed" | "unverified";
3
+ export type OpenClawBrainHookLoadProof = "status_probe_ready" | "not_ready";
4
+ export type OpenClawBrainPluginAllowlistState = "unrestricted" | "allowed" | "blocked" | "invalid" | "unverified";
5
+ export interface OpenClawBrainHookInspection {
6
+ scope: "exact_openclaw_home" | "activation_root_only";
7
+ openclawHome: string | null;
8
+ hookPath: string | null;
9
+ runtimeGuardPath: string | null;
10
+ manifestPath: string | null;
11
+ installState: OpenClawBrainHookInstallState;
12
+ loadability: OpenClawBrainHookLoadability;
13
+ pluginAllowlistState: OpenClawBrainPluginAllowlistState;
14
+ desynced: boolean;
15
+ detail: string;
16
+ }
17
+ export interface OpenClawBrainHookLoadSummary extends OpenClawBrainHookInspection {
18
+ loadProof: OpenClawBrainHookLoadProof;
19
+ }
20
+ export declare function inspectOpenClawBrainPluginAllowlist(openclawHome: string): {
21
+ state: Exclude<OpenClawBrainPluginAllowlistState, "unverified">;
22
+ detail: string;
23
+ };
24
+ export declare function inspectOpenClawBrainHookStatus(openclawHome: string | null | undefined): OpenClawBrainHookInspection;
25
+ export declare function summarizeOpenClawBrainHookLoad(inspection: OpenClawBrainHookInspection, statusProbeReady: boolean): OpenClawBrainHookLoadSummary;
@@ -0,0 +1,154 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ function toErrorMessage(error) {
4
+ return error instanceof Error ? error.message : String(error);
5
+ }
6
+ function readJsonObjectRecord(value) {
7
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
8
+ return null;
9
+ }
10
+ return value;
11
+ }
12
+ function readOpenClawJsonConfig(openclawHome) {
13
+ const openclawJsonPath = path.join(openclawHome, "openclaw.json");
14
+ let parsed;
15
+ try {
16
+ parsed = JSON.parse(readFileSync(openclawJsonPath, "utf8"));
17
+ }
18
+ catch (error) {
19
+ throw new Error(`Failed to read ${openclawJsonPath}: ${toErrorMessage(error)}`);
20
+ }
21
+ const config = readJsonObjectRecord(parsed);
22
+ if (config === null) {
23
+ throw new Error(`Failed to read ${openclawJsonPath}: openclaw.json must contain a top-level object`);
24
+ }
25
+ return {
26
+ path: openclawJsonPath,
27
+ config
28
+ };
29
+ }
30
+ function shortenPath(fullPath) {
31
+ const homeDir = process.env.HOME ?? "";
32
+ if (homeDir.length > 0 && fullPath.startsWith(homeDir)) {
33
+ return "~" + fullPath.slice(homeDir.length);
34
+ }
35
+ return fullPath;
36
+ }
37
+ export function inspectOpenClawBrainPluginAllowlist(openclawHome) {
38
+ const { path: openclawJsonPath, config } = readOpenClawJsonConfig(openclawHome);
39
+ const plugins = readJsonObjectRecord(config.plugins);
40
+ if (plugins === null) {
41
+ return {
42
+ state: "unrestricted",
43
+ detail: `${shortenPath(openclawJsonPath)} has no plugins object; the on-disk hook is not blocked by an allowlist`
44
+ };
45
+ }
46
+ if (!Object.prototype.hasOwnProperty.call(plugins, "allow")) {
47
+ return {
48
+ state: "unrestricted",
49
+ detail: `${shortenPath(openclawJsonPath)} does not pin plugins.allow; the on-disk hook is not blocked by an allowlist`
50
+ };
51
+ }
52
+ if (!Array.isArray(plugins.allow)) {
53
+ return {
54
+ state: "invalid",
55
+ detail: `${shortenPath(openclawJsonPath)} has a non-array plugins.allow value, so OpenClawBrain load cannot be proven from config`
56
+ };
57
+ }
58
+ return plugins.allow.includes("openclawbrain")
59
+ ? {
60
+ state: "allowed",
61
+ detail: `${shortenPath(openclawJsonPath)} plugins.allow explicitly includes openclawbrain`
62
+ }
63
+ : {
64
+ state: "blocked",
65
+ detail: `${shortenPath(openclawJsonPath)} plugins.allow excludes openclawbrain`
66
+ };
67
+ }
68
+ export function inspectOpenClawBrainHookStatus(openclawHome) {
69
+ if (openclawHome === null || openclawHome === undefined || openclawHome.trim().length === 0) {
70
+ return {
71
+ scope: "activation_root_only",
72
+ openclawHome: null,
73
+ hookPath: null,
74
+ runtimeGuardPath: null,
75
+ manifestPath: null,
76
+ installState: "unverified",
77
+ loadability: "unverified",
78
+ pluginAllowlistState: "unverified",
79
+ desynced: false,
80
+ detail: "profile hook state is unknown from activation-root-only status; pin --openclaw-home to prove install state"
81
+ };
82
+ }
83
+ const resolvedHome = path.resolve(openclawHome);
84
+ const extensionDir = path.join(resolvedHome, "extensions", "openclawbrain");
85
+ const hookPath = path.join(extensionDir, "index.ts");
86
+ const runtimeGuardPath = path.join(extensionDir, "runtime-guard.js");
87
+ const manifestPath = path.join(extensionDir, "openclaw.plugin.json");
88
+ if (!(existsSync(hookPath) && existsSync(runtimeGuardPath) && existsSync(manifestPath))) {
89
+ return {
90
+ scope: "exact_openclaw_home",
91
+ openclawHome: resolvedHome,
92
+ hookPath,
93
+ runtimeGuardPath,
94
+ manifestPath,
95
+ installState: "not_installed",
96
+ loadability: "not_installed",
97
+ pluginAllowlistState: "unverified",
98
+ desynced: false,
99
+ detail: `profile hook is not present at ${shortenPath(extensionDir)}`
100
+ };
101
+ }
102
+ const allowlist = inspectOpenClawBrainPluginAllowlist(resolvedHome);
103
+ if (allowlist.state === "blocked") {
104
+ return {
105
+ scope: "exact_openclaw_home",
106
+ openclawHome: resolvedHome,
107
+ hookPath,
108
+ runtimeGuardPath,
109
+ manifestPath,
110
+ installState: "blocked_by_allowlist",
111
+ loadability: "blocked",
112
+ pluginAllowlistState: allowlist.state,
113
+ desynced: true,
114
+ detail: `profile hook files exist at ${shortenPath(extensionDir)}, but ${allowlist.detail}; ` +
115
+ "the on-disk hook is desynced and OpenClaw will not load it"
116
+ };
117
+ }
118
+ if (allowlist.state === "invalid") {
119
+ return {
120
+ scope: "exact_openclaw_home",
121
+ openclawHome: resolvedHome,
122
+ hookPath,
123
+ runtimeGuardPath,
124
+ manifestPath,
125
+ installState: "blocked_by_allowlist",
126
+ loadability: "blocked",
127
+ pluginAllowlistState: allowlist.state,
128
+ desynced: true,
129
+ detail: `profile hook files exist at ${shortenPath(extensionDir)}, but ${allowlist.detail}; ` +
130
+ "treat hook-load state as broken until install/attach repairs the config"
131
+ };
132
+ }
133
+ return {
134
+ scope: "exact_openclaw_home",
135
+ openclawHome: resolvedHome,
136
+ hookPath,
137
+ runtimeGuardPath,
138
+ manifestPath,
139
+ installState: "installed",
140
+ loadability: "loadable",
141
+ pluginAllowlistState: allowlist.state,
142
+ desynced: false,
143
+ detail: `profile hook is installed at ${shortenPath(extensionDir)}`
144
+ };
145
+ }
146
+ export function summarizeOpenClawBrainHookLoad(inspection, statusProbeReady) {
147
+ return {
148
+ ...inspection,
149
+ loadProof: inspection.loadability === "loadable" && statusProbeReady
150
+ ? "status_probe_ready"
151
+ : "not_ready"
152
+ };
153
+ }
154
+ //# sourceMappingURL=openclaw-hook-truth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-hook-truth.js","sourceRoot":"","sources":["../../src/openclaw-hook-truth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAElE,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,gBAAgB,KAAK,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kBAAkB,gBAAgB,iDAAiD,CAAC,CAAC;IACvG,CAAC;IAED,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACvC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,OAAO,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAwBD,MAAM,UAAU,mCAAmC,CAAC,YAAoB;IAItE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAErD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,GAAG,WAAW,CAAC,gBAAgB,CAAC,yEAAyE;SAClH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,GAAG,WAAW,CAAC,gBAAgB,CAAC,8EAA8E;SACvH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,GAAG,WAAW,CAAC,gBAAgB,CAAC,0FAA0F;SACnI,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC5C,CAAC,CAAC;YACE,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,GAAG,WAAW,CAAC,gBAAgB,CAAC,kDAAkD;SAC3F;QACH,CAAC,CAAC;YACE,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,GAAG,WAAW,CAAC,gBAAgB,CAAC,uCAAuC;SAChF,CAAC;AACR,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,YAAuC;IACpF,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5F,OAAO;YACL,KAAK,EAAE,sBAAsB;YAC7B,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,IAAI;YACd,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,YAAY;YAC1B,WAAW,EAAE,YAAY;YACzB,oBAAoB,EAAE,YAAY;YAClC,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,4GAA4G;SACrH,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC;IAErE,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACxF,OAAO;YACL,KAAK,EAAE,qBAAqB;YAC5B,YAAY,EAAE,YAAY;YAC1B,QAAQ;YACR,gBAAgB;YAChB,YAAY;YACZ,YAAY,EAAE,eAAe;YAC7B,WAAW,EAAE,eAAe;YAC5B,oBAAoB,EAAE,YAAY;YAClC,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,kCAAkC,WAAW,CAAC,YAAY,CAAC,EAAE;SACtE,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,mCAAmC,CAAC,YAAY,CAAC,CAAC;IACpE,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,qBAAqB;YAC5B,YAAY,EAAE,YAAY;YAC1B,QAAQ;YACR,gBAAgB;YAChB,YAAY;YACZ,YAAY,EAAE,sBAAsB;YACpC,WAAW,EAAE,SAAS;YACtB,oBAAoB,EAAE,SAAS,CAAC,KAAK;YACrC,QAAQ,EAAE,IAAI;YACd,MAAM,EACJ,+BAA+B,WAAW,CAAC,YAAY,CAAC,SAAS,SAAS,CAAC,MAAM,IAAI;gBACrF,4DAA4D;SAC/D,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,qBAAqB;YAC5B,YAAY,EAAE,YAAY;YAC1B,QAAQ;YACR,gBAAgB;YAChB,YAAY;YACZ,YAAY,EAAE,sBAAsB;YACpC,WAAW,EAAE,SAAS;YACtB,oBAAoB,EAAE,SAAS,CAAC,KAAK;YACrC,QAAQ,EAAE,IAAI;YACd,MAAM,EACJ,+BAA+B,WAAW,CAAC,YAAY,CAAC,SAAS,SAAS,CAAC,MAAM,IAAI;gBACrF,yEAAyE;SAC5E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,qBAAqB;QAC5B,YAAY,EAAE,YAAY;QAC1B,QAAQ;QACR,gBAAgB;QAChB,YAAY;QACZ,YAAY,EAAE,WAAW;QACzB,WAAW,EAAE,UAAU;QACvB,oBAAoB,EAAE,SAAS,CAAC,KAAK;QACrC,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,gCAAgC,WAAW,CAAC,YAAY,CAAC,EAAE;KACpE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,UAAuC,EACvC,gBAAyB;IAEzB,OAAO;QACL,GAAG,UAAU;QACb,SAAS,EACP,UAAU,CAAC,WAAW,KAAK,UAAU,IAAI,gBAAgB;YACvD,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,WAAW;KAClB,CAAC;AACJ,CAAC"}
@@ -11,7 +11,10 @@
11
11
  */
12
12
  import { fileURLToPath } from "node:url";
13
13
 
14
- import { compileRuntimeContext } from "@openclawbrain/openclaw";
14
+ import {
15
+ compileRuntimeContext,
16
+ recordOpenClawProfileRuntimeLoadProof
17
+ } from "@openclawbrain/openclaw";
15
18
  import {
16
19
  createBeforePromptBuildHandler,
17
20
  isActivationRootPlaceholder,
@@ -94,6 +97,21 @@ export default function register(api: unknown) {
94
97
  }),
95
98
  { priority: 5 }
96
99
  );
100
+ if (!isActivationRootPlaceholder(ACTIVATION_ROOT)) {
101
+ try {
102
+ recordOpenClawProfileRuntimeLoadProof({
103
+ activationRoot: ACTIVATION_ROOT,
104
+ extensionEntryPath: EXTENSION_ENTRY_PATH
105
+ });
106
+ } catch (error) {
107
+ const detail = error instanceof Error ? error.message : String(error);
108
+ void reportDiagnostic({
109
+ key: `runtime-load-proof:${detail}`,
110
+ once: true,
111
+ message: `[openclawbrain] runtime load proof failed: ${detail}`
112
+ });
113
+ }
114
+ }
97
115
  announceStartupBreadcrumb();
98
116
  } catch (error) {
99
117
  const detail = error instanceof Error ? error.stack ?? error.message : String(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclawbrain/openclaw",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Primary OpenClawBrain front door for OpenClaw attach, compile, event export, status, and rollback.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -45,12 +45,12 @@
45
45
  "access": "public"
46
46
  },
47
47
  "dependencies": {
48
- "@openclawbrain/compiler": "0.3.2",
49
- "@openclawbrain/contracts": "0.3.2",
50
- "@openclawbrain/events": "0.3.2",
51
- "@openclawbrain/learner": "0.3.2",
52
- "@openclawbrain/pack-format": "0.3.2",
53
- "@openclawbrain/event-export": "0.3.2"
48
+ "@openclawbrain/compiler": "^0.3.3",
49
+ "@openclawbrain/contracts": "^0.3.3",
50
+ "@openclawbrain/events": "^0.3.3",
51
+ "@openclawbrain/learner": "^0.3.3",
52
+ "@openclawbrain/pack-format": "^0.3.3",
53
+ "@openclawbrain/event-export": "^0.3.3"
54
54
  },
55
55
  "bin": {
56
56
  "openclawbrain": "./dist/src/cli.js",