@openclawbrain/openclaw 0.1.11 → 0.2.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.
@@ -0,0 +1,60 @@
1
+ import { type FeedbackEventV1, type InteractionEventV1, type NormalizedEventExportV1 } from "@openclawbrain/contracts";
2
+ import { type FeedbackEventExtractionResultV1 } from "@openclawbrain/event-export";
3
+ import type { OpenClawSessionIndex, OpenClawSessionIndexEntry, OpenClawSessionRecord } from "./session-store.js";
4
+ export interface OpenClawPassiveLearningPrivacySummaryV1 {
5
+ sanitized: true;
6
+ rules: string[];
7
+ strippedMetadataBlockCount: number;
8
+ strippedThinkingBlockCount: number;
9
+ droppedToolResultCount: number;
10
+ }
11
+ export interface OpenClawPassiveLearningSessionEvidenceV1 {
12
+ sessionKey: string;
13
+ sessionId: string;
14
+ updatedAt: string;
15
+ channel: string;
16
+ sourceStream: string;
17
+ sessionFileBasename: string | null;
18
+ model: string | null;
19
+ modelProvider: string | null;
20
+ chatType: string | null;
21
+ systemPromptFingerprint: {
22
+ available: boolean;
23
+ workspaceDirBasename: string | null;
24
+ injectedWorkspaceFileCount: number;
25
+ missingInjectedWorkspaceFileCount: number;
26
+ toolNames: string[];
27
+ };
28
+ }
29
+ export interface OpenClawPassiveLearningSessionExportV1 {
30
+ session: OpenClawPassiveLearningSessionEvidenceV1;
31
+ privacy: OpenClawPassiveLearningPrivacySummaryV1;
32
+ interactionEvents: InteractionEventV1[];
33
+ feedbackEvents: FeedbackEventV1[];
34
+ interactionContentsById: Record<string, string>;
35
+ feedbackExtraction: FeedbackEventExtractionResultV1;
36
+ normalizedEventExport: NormalizedEventExportV1;
37
+ warnings: string[];
38
+ }
39
+ export interface OpenClawPassiveLearningStoreExportV1 {
40
+ sessions: OpenClawPassiveLearningSessionExportV1[];
41
+ interactionEvents: InteractionEventV1[];
42
+ feedbackEvents: FeedbackEventV1[];
43
+ normalizedEventExport: NormalizedEventExportV1;
44
+ warnings: string[];
45
+ }
46
+ export declare function buildPassiveLearningSessionExportFromOpenClawSessionStore(input: {
47
+ sessionKey: string;
48
+ indexEntry: OpenClawSessionIndexEntry;
49
+ records: readonly OpenClawSessionRecord[];
50
+ agentId?: string;
51
+ sequenceStart?: number;
52
+ }): OpenClawPassiveLearningSessionExportV1 & {
53
+ nextSequence: number;
54
+ };
55
+ export declare function buildPassiveLearningStoreExportFromOpenClawSessionIndex(input: {
56
+ sessionIndex: OpenClawSessionIndex;
57
+ readSessionRecords: (sessionKey: string, entry: OpenClawSessionIndexEntry) => readonly OpenClawSessionRecord[];
58
+ sessionKeys?: readonly string[];
59
+ agentId?: string;
60
+ }): OpenClawPassiveLearningStoreExportV1;
@@ -0,0 +1,359 @@
1
+ import path from "node:path";
2
+ import { buildNormalizedEventExport, createInteractionEvent } from "@openclawbrain/contracts";
3
+ import { extractFeedbackEventsFromInteractionRecords } from "@openclawbrain/event-export";
4
+ const DEFAULT_AGENT_ID = "openclaw-session-store";
5
+ const KNOWN_PRINCIPALS = {
6
+ bihua: {
7
+ teacherIdentity: "bihua",
8
+ teacherRole: "principal",
9
+ teacherAuthority: "binding",
10
+ priorityClass: "critical"
11
+ },
12
+ "jonathan gu": {
13
+ teacherIdentity: "jonathan",
14
+ teacherRole: "admin",
15
+ teacherAuthority: "high",
16
+ priorityClass: "high"
17
+ },
18
+ jonathan: {
19
+ teacherIdentity: "jonathan",
20
+ teacherRole: "admin",
21
+ teacherAuthority: "high",
22
+ priorityClass: "high"
23
+ }
24
+ };
25
+ const DEFAULT_PRIVACY_RULES = [
26
+ "session-store fixtures stay sanitized and use fake ids, paths, and workspace roots",
27
+ "leading Conversation info / Sender untrusted metadata blocks are stripped before feedback extraction",
28
+ "assistant thinking blocks and raw tool-result payloads are excluded from passive-learning content",
29
+ "sender names are treated as hints for principal resolution, not source-of-truth identity proof"
30
+ ];
31
+ function normalizeString(value) {
32
+ if (typeof value !== "string") {
33
+ return null;
34
+ }
35
+ const trimmed = value.trim();
36
+ return trimmed.length === 0 ? null : trimmed;
37
+ }
38
+ function sanitizeToken(value) {
39
+ const sanitized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
40
+ return sanitized.length === 0 ? "unknown" : sanitized;
41
+ }
42
+ function slugifyIdentity(value) {
43
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
44
+ }
45
+ function deriveChannel(sessionKey, entry) {
46
+ const deliveryChannel = normalizeString(entry.deliveryContext?.channel);
47
+ if (deliveryChannel !== null) {
48
+ return deliveryChannel;
49
+ }
50
+ const originSurface = normalizeString(entry.origin?.surface);
51
+ if (originSurface !== null) {
52
+ return originSurface;
53
+ }
54
+ const keyParts = sessionKey.split(":");
55
+ const transportPart = keyParts[2];
56
+ if (transportPart !== undefined && transportPart.length > 0) {
57
+ return transportPart;
58
+ }
59
+ return entry.chatType ?? "unknown";
60
+ }
61
+ function messageText(record) {
62
+ const parts = [];
63
+ let thinkingBlocks = 0;
64
+ let toolCalls = 0;
65
+ for (const part of record.message.content) {
66
+ if (part.type === "text") {
67
+ const normalized = normalizeString(part.text);
68
+ if (normalized !== null) {
69
+ parts.push(normalized);
70
+ }
71
+ continue;
72
+ }
73
+ if (part.type === "thinking") {
74
+ thinkingBlocks += 1;
75
+ continue;
76
+ }
77
+ if (part.type === "toolCall") {
78
+ toolCalls += 1;
79
+ }
80
+ }
81
+ return {
82
+ content: parts.join("\n").trim(),
83
+ thinkingBlocks,
84
+ toolCalls
85
+ };
86
+ }
87
+ function stripLeadingUntrustedMetadata(text) {
88
+ const blocks = text.replace(/\r\n/g, "\n").trim();
89
+ if (blocks.length === 0) {
90
+ return {
91
+ content: "",
92
+ senderName: null,
93
+ strippedMetadataBlockCount: 0
94
+ };
95
+ }
96
+ const sections = blocks
97
+ .split(/\n\s*\n/g)
98
+ .map((section) => section.trim())
99
+ .filter((section) => section.length > 0);
100
+ const remaining = [];
101
+ let senderName = null;
102
+ let strippedMetadataBlockCount = 0;
103
+ for (const section of sections) {
104
+ const lines = section.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
105
+ const header = lines[0] ?? "";
106
+ if (header === "Conversation info (untrusted metadata)" || header === "Sender (untrusted metadata)") {
107
+ strippedMetadataBlockCount += 1;
108
+ if (header === "Sender (untrusted metadata)") {
109
+ const senderLine = lines.find((line) => /^name:/iu.test(line) || /^display name:/iu.test(line));
110
+ const extracted = senderLine?.split(":").slice(1).join(":").trim() ?? null;
111
+ if (extracted !== null && extracted.length > 0) {
112
+ senderName = extracted;
113
+ }
114
+ }
115
+ continue;
116
+ }
117
+ remaining.push(section);
118
+ }
119
+ return {
120
+ content: remaining.join("\n\n").trim(),
121
+ senderName,
122
+ strippedMetadataBlockCount
123
+ };
124
+ }
125
+ function buildPrincipalScope(sessionId, relatedInteractionId) {
126
+ const scopeKey = [
127
+ "profile:current_profile",
128
+ `session:${sessionId}`,
129
+ relatedInteractionId === null ? null : `interaction:${relatedInteractionId}`
130
+ ]
131
+ .filter((value) => value !== null)
132
+ .join("|");
133
+ if (relatedInteractionId !== null) {
134
+ return {
135
+ kind: "interaction",
136
+ profileSelector: "current_profile",
137
+ sessionId,
138
+ interactionId: relatedInteractionId,
139
+ scopeKey
140
+ };
141
+ }
142
+ return {
143
+ kind: "session",
144
+ profileSelector: "current_profile",
145
+ sessionId,
146
+ scopeKey
147
+ };
148
+ }
149
+ function resolveSenderIdentity(sessionId, senderName, relatedInteractionId) {
150
+ if (senderName === null) {
151
+ return {
152
+ actorRole: "user",
153
+ principal: undefined
154
+ };
155
+ }
156
+ const normalized = senderName.toLowerCase().replace(/\s+/g, " ").trim();
157
+ const known = KNOWN_PRINCIPALS[normalized];
158
+ if (known !== undefined) {
159
+ return {
160
+ actorRole: known.teacherRole,
161
+ principal: {
162
+ teacherIdentity: known.teacherIdentity,
163
+ teacherRole: known.teacherRole,
164
+ teacherAuthority: known.teacherAuthority,
165
+ priorityClass: known.priorityClass,
166
+ principalScope: buildPrincipalScope(sessionId, relatedInteractionId)
167
+ }
168
+ };
169
+ }
170
+ const actorIdentity = slugifyIdentity(normalized);
171
+ return {
172
+ actorRole: "user",
173
+ principal: actorIdentity.length === 0
174
+ ? undefined
175
+ : {
176
+ teacherIdentity: `scanner/actor/${actorIdentity}`,
177
+ teacherRole: "user",
178
+ teacherAuthority: "normal",
179
+ priorityClass: "normal",
180
+ principalScope: buildPrincipalScope(sessionId, relatedInteractionId)
181
+ }
182
+ };
183
+ }
184
+ export function buildPassiveLearningSessionExportFromOpenClawSessionStore(input) {
185
+ const agentId = input.agentId ?? DEFAULT_AGENT_ID;
186
+ const sequenceStart = input.sequenceStart ?? 1;
187
+ const channel = deriveChannel(input.sessionKey, input.indexEntry);
188
+ const sourceStream = `openclaw/runtime/${sanitizeToken(channel)}`;
189
+ const warnings = [];
190
+ const interactionEvents = [];
191
+ const interactionContentsById = {};
192
+ const feedbackRecords = [];
193
+ let strippedMetadataBlockCount = 0;
194
+ let strippedThinkingBlockCount = 0;
195
+ let droppedToolResultCount = 0;
196
+ let nextSequence = sequenceStart;
197
+ let latestAssistantInteractionId = null;
198
+ for (const record of input.records) {
199
+ if (record.type !== "message") {
200
+ continue;
201
+ }
202
+ if (record.message.role === "toolResult") {
203
+ droppedToolResultCount += 1;
204
+ continue;
205
+ }
206
+ const resolvedText = messageText(record);
207
+ strippedThinkingBlockCount += resolvedText.thinkingBlocks;
208
+ if (record.message.role === "assistant") {
209
+ if (resolvedText.content.length === 0) {
210
+ if (resolvedText.toolCalls > 0) {
211
+ warnings.push(`assistant message ${record.id} only contained tool calls; skipped from passive-learning interactions`);
212
+ }
213
+ continue;
214
+ }
215
+ const eventId = `evt-session-store-assistant-${input.indexEntry.sessionId}-${record.id}`;
216
+ const interaction = createInteractionEvent({
217
+ eventId,
218
+ agentId,
219
+ sessionId: input.indexEntry.sessionId,
220
+ channel,
221
+ sequence: nextSequence,
222
+ kind: "message_delivered",
223
+ createdAt: record.timestamp,
224
+ source: {
225
+ runtimeOwner: "openclaw",
226
+ stream: sourceStream
227
+ },
228
+ messageId: record.id
229
+ });
230
+ nextSequence += 1;
231
+ latestAssistantInteractionId = interaction.eventId;
232
+ interactionEvents.push(interaction);
233
+ interactionContentsById[interaction.eventId] = resolvedText.content;
234
+ continue;
235
+ }
236
+ if (record.message.role !== "user") {
237
+ warnings.push(`unsupported session-store message role skipped: ${record.message.role}`);
238
+ continue;
239
+ }
240
+ const sanitized = stripLeadingUntrustedMetadata(resolvedText.content);
241
+ strippedMetadataBlockCount += sanitized.strippedMetadataBlockCount;
242
+ const { actorRole, principal } = resolveSenderIdentity(input.indexEntry.sessionId, sanitized.senderName, latestAssistantInteractionId);
243
+ if (sanitized.content.length === 0) {
244
+ warnings.push(`user message ${record.id} had no passive-learning content after metadata stripping`);
245
+ nextSequence += 1;
246
+ continue;
247
+ }
248
+ feedbackRecords.push({
249
+ recordId: record.id,
250
+ format: "raw",
251
+ createdAt: record.timestamp,
252
+ content: sanitized.content,
253
+ sequence: nextSequence,
254
+ messageId: record.id,
255
+ relatedInteractionId: latestAssistantInteractionId,
256
+ actorRole,
257
+ ...(principal === undefined ? {} : { principal })
258
+ });
259
+ nextSequence += 1;
260
+ }
261
+ const feedbackExtraction = extractFeedbackEventsFromInteractionRecords({
262
+ agentId,
263
+ sessionId: input.indexEntry.sessionId,
264
+ channel,
265
+ source: {
266
+ runtimeOwner: "openclaw",
267
+ stream: sourceStream
268
+ },
269
+ records: feedbackRecords
270
+ });
271
+ const feedbackEvents = feedbackExtraction.events.map((entry) => entry.feedbackEvent);
272
+ const normalizedEventExport = buildNormalizedEventExport({
273
+ interactionEvents,
274
+ feedbackEvents
275
+ });
276
+ return {
277
+ session: {
278
+ sessionKey: input.sessionKey,
279
+ sessionId: input.indexEntry.sessionId,
280
+ updatedAt: new Date(input.indexEntry.updatedAt).toISOString(),
281
+ channel,
282
+ sourceStream,
283
+ sessionFileBasename: input.indexEntry.sessionFile === undefined ? null : path.basename(input.indexEntry.sessionFile),
284
+ model: input.indexEntry.model ?? null,
285
+ modelProvider: input.indexEntry.modelProvider ?? null,
286
+ chatType: input.indexEntry.chatType ?? null,
287
+ systemPromptFingerprint: {
288
+ available: input.indexEntry.systemPromptReport !== undefined,
289
+ workspaceDirBasename: input.indexEntry.systemPromptReport?.workspaceDir === undefined
290
+ ? null
291
+ : path.basename(input.indexEntry.systemPromptReport.workspaceDir),
292
+ injectedWorkspaceFileCount: input.indexEntry.systemPromptReport?.injectedWorkspaceFiles?.length ?? 0,
293
+ missingInjectedWorkspaceFileCount: input.indexEntry.systemPromptReport?.injectedWorkspaceFiles?.filter((file) => file.missing).length ?? 0,
294
+ toolNames: (input.indexEntry.systemPromptReport?.tools?.entries ?? [])
295
+ .map((entry) => entry.name)
296
+ .filter((name) => typeof name === "string")
297
+ }
298
+ },
299
+ privacy: {
300
+ sanitized: true,
301
+ rules: [...DEFAULT_PRIVACY_RULES],
302
+ strippedMetadataBlockCount,
303
+ strippedThinkingBlockCount,
304
+ droppedToolResultCount
305
+ },
306
+ interactionEvents,
307
+ feedbackEvents,
308
+ interactionContentsById,
309
+ feedbackExtraction,
310
+ normalizedEventExport,
311
+ warnings,
312
+ nextSequence
313
+ };
314
+ }
315
+ export function buildPassiveLearningStoreExportFromOpenClawSessionIndex(input) {
316
+ const sessionKeys = input.sessionKeys ?? Object.keys(input.sessionIndex);
317
+ const orderedEntries = sessionKeys
318
+ .map((sessionKey) => {
319
+ const entry = input.sessionIndex[sessionKey];
320
+ if (entry === undefined) {
321
+ throw new Error(`missing session index entry for ${sessionKey}`);
322
+ }
323
+ return {
324
+ sessionKey,
325
+ entry
326
+ };
327
+ })
328
+ .sort((left, right) => {
329
+ if (left.entry.updatedAt !== right.entry.updatedAt) {
330
+ return left.entry.updatedAt - right.entry.updatedAt;
331
+ }
332
+ return left.sessionKey.localeCompare(right.sessionKey);
333
+ });
334
+ let nextSequence = 1;
335
+ const sessions = orderedEntries.map(({ sessionKey, entry }) => {
336
+ const built = buildPassiveLearningSessionExportFromOpenClawSessionStore({
337
+ sessionKey,
338
+ indexEntry: entry,
339
+ records: input.readSessionRecords(sessionKey, entry),
340
+ sequenceStart: nextSequence,
341
+ ...(input.agentId === undefined ? {} : { agentId: input.agentId })
342
+ });
343
+ nextSequence = built.nextSequence;
344
+ return built;
345
+ });
346
+ const interactionEvents = sessions.flatMap((session) => session.interactionEvents);
347
+ const feedbackEvents = sessions.flatMap((session) => session.feedbackEvents);
348
+ return {
349
+ sessions,
350
+ interactionEvents,
351
+ feedbackEvents,
352
+ normalizedEventExport: buildNormalizedEventExport({
353
+ interactionEvents,
354
+ feedbackEvents
355
+ }),
356
+ warnings: sessions.flatMap((session) => session.warnings)
357
+ };
358
+ }
359
+ //# sourceMappingURL=local-session-passive-learning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-session-passive-learning.js","sourceRoot":"","sources":["../../src/local-session-passive-learning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Auto-detect the OpenClawBrain activation root.
3
+ *
4
+ * Resolution order:
5
+ * 1. Explicit `--activation-root <path>` (passed as `explicit` arg)
6
+ * 2. A selected OpenClaw profile home (`openclawHome` option or OPENCLAW_HOME env)
7
+ * 3. Default location: ~/.openclawbrain/activation
8
+ * 4. Scan ~/.openclaw-*​/extensions/openclawbrain/index.ts for hardcoded activation paths
9
+ * 5. Fail with a clear error message
10
+ *
11
+ * Exported for use by CLI commands and other agents' code.
12
+ */
13
+ export interface ResolveActivationRootOptions {
14
+ /** Value from --activation-root flag, if provided. null/undefined/"" means not provided. */
15
+ explicit?: string | null;
16
+ /** Specific OpenClaw profile home to inspect for the installed extension. */
17
+ openclawHome?: string | null;
18
+ /** If true, return null instead of throwing when nothing is found. */
19
+ quiet?: boolean;
20
+ }
21
+ /**
22
+ * Resolve the activation root path through the detection chain.
23
+ *
24
+ * @returns Absolute path to the activation root.
25
+ * @throws If no activation root can be found (unless `quiet` is true).
26
+ */
27
+ export declare function resolveActivationRoot(options?: ResolveActivationRootOptions): string;
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Auto-detect the OpenClawBrain activation root.
3
+ *
4
+ * Resolution order:
5
+ * 1. Explicit `--activation-root <path>` (passed as `explicit` arg)
6
+ * 2. A selected OpenClaw profile home (`openclawHome` option or OPENCLAW_HOME env)
7
+ * 3. Default location: ~/.openclawbrain/activation
8
+ * 4. Scan ~/.openclaw-*​/extensions/openclawbrain/index.ts for hardcoded activation paths
9
+ * 5. Fail with a clear error message
10
+ *
11
+ * Exported for use by CLI commands and other agents' code.
12
+ */
13
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
14
+ import path from "node:path";
15
+ function getHomeDir() {
16
+ return process.env.HOME ?? process.env.USERPROFILE ?? "~";
17
+ }
18
+ function normalizeOptionalString(value) {
19
+ if (typeof value !== "string") {
20
+ return null;
21
+ }
22
+ const trimmed = value.trim();
23
+ return trimmed.length > 0 ? trimmed : null;
24
+ }
25
+ /**
26
+ * Attempt to extract an activationRoot string from an extension index.ts file.
27
+ * These files contain a hardcoded JSON string like:
28
+ * activationRoot: "/Users/foo/.openclawbrain/activation",
29
+ */
30
+ function extractActivationRootFromExtension(filePath) {
31
+ try {
32
+ const content = readFileSync(filePath, "utf8");
33
+ // Match patterns like: activationRoot: "/some/path" or activationRoot: '/some/path'
34
+ const match = content.match(/activationRoot:\s*["'`]([^"'`]+)["'`]/);
35
+ if (match && match[1]) {
36
+ const candidate = match[1];
37
+ // Only return if the path actually exists on disk
38
+ if (existsSync(candidate)) {
39
+ return candidate;
40
+ }
41
+ }
42
+ }
43
+ catch {
44
+ // File unreadable — skip
45
+ }
46
+ return null;
47
+ }
48
+ function readActivationRootFromOpenClawHome(openclawHome) {
49
+ const extensionIndex = path.join(path.resolve(openclawHome), "extensions", "openclawbrain", "index.ts");
50
+ if (!existsSync(extensionIndex)) {
51
+ return null;
52
+ }
53
+ return extractActivationRootFromExtension(extensionIndex);
54
+ }
55
+ /**
56
+ * Scan ~/.openclaw-* directories for extension index.ts files that
57
+ * contain hardcoded activation root paths.
58
+ */
59
+ function scanExtensionsForActivationRoot() {
60
+ const homeDir = path.resolve(getHomeDir());
61
+ let entries;
62
+ try {
63
+ entries = readdirSync(homeDir);
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ for (const entry of entries) {
69
+ if (!entry.startsWith(".openclaw-"))
70
+ continue;
71
+ const extensionIndex = path.join(homeDir, entry, "extensions", "openclawbrain", "index.ts");
72
+ if (!existsSync(extensionIndex))
73
+ continue;
74
+ const found = extractActivationRootFromExtension(extensionIndex);
75
+ if (found !== null)
76
+ return found;
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Resolve the activation root path through the detection chain.
82
+ *
83
+ * @returns Absolute path to the activation root.
84
+ * @throws If no activation root can be found (unless `quiet` is true).
85
+ */
86
+ export function resolveActivationRoot(options = {}) {
87
+ const { explicit, openclawHome, quiet } = options;
88
+ // 1. Explicit flag
89
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
90
+ return path.resolve(explicit);
91
+ }
92
+ const selectedOpenClawHome = normalizeOptionalString(openclawHome) ?? normalizeOptionalString(process.env.OPENCLAW_HOME);
93
+ // 2. A selected OpenClaw profile home is authoritative on many-profile hosts.
94
+ if (selectedOpenClawHome !== null) {
95
+ const selectedActivationRoot = readActivationRootFromOpenClawHome(selectedOpenClawHome);
96
+ if (selectedActivationRoot !== null) {
97
+ return path.resolve(selectedActivationRoot);
98
+ }
99
+ if (quiet) {
100
+ return "";
101
+ }
102
+ throw new Error(`No brain found for OpenClaw profile home ${path.resolve(selectedOpenClawHome)}. Run: openclawbrain setup --openclaw-home <path>`);
103
+ }
104
+ // 3. Default location: ~/.openclawbrain/activation
105
+ const defaultPath = path.join(getHomeDir(), ".openclawbrain", "activation");
106
+ if (existsSync(defaultPath)) {
107
+ return path.resolve(defaultPath);
108
+ }
109
+ // 4. Scan extensions
110
+ const scanned = scanExtensionsForActivationRoot();
111
+ if (scanned !== null) {
112
+ return path.resolve(scanned);
113
+ }
114
+ // 5. Nothing found
115
+ if (quiet) {
116
+ return "";
117
+ }
118
+ throw new Error('No brain found. Run: openclawbrain setup --openclaw-home <path>');
119
+ }
120
+ //# sourceMappingURL=resolve-activation-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-activation-root.js","sourceRoot":"","sources":["../../src/resolve-activation-root.ts"],"names":[],"mappings":"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"}