@digitalforgestudios/openclaw-sulcus 5.3.0 → 5.4.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 (2) hide show
  1. package/index.ts +33 -9
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { resolve } from "node:path";
2
- import { existsSync } from "node:fs";
2
+ import { existsSync, mkdirSync } from "node:fs";
3
3
  import * as https from "node:https";
4
4
  import * as http from "node:http";
5
5
  import { URL } from "node:url";
@@ -1271,6 +1271,17 @@ const sulcusPlugin = {
1271
1271
  ? resolve(pluginConfig.libDir as string)
1272
1272
  : resolve(process.env.HOME || "~", ".sulcus/lib");
1273
1273
 
1274
+ // Auto-create directories on first run (self-healing)
1275
+ const dataDir = resolve(process.env.HOME || "~", ".sulcus/data");
1276
+ for (const dir of [libDir, dataDir]) {
1277
+ if (!existsSync(dir)) {
1278
+ try {
1279
+ mkdirSync(dir, { recursive: true });
1280
+ logger.info(`sulcus: created directory ${dir}`);
1281
+ } catch { /* best effort — may be read-only in containers */ }
1282
+ }
1283
+ }
1284
+
1274
1285
  const storeLibPath = pluginConfig?.storeLibPath
1275
1286
  ? resolve(pluginConfig.storeLibPath as string)
1276
1287
  : resolve(libDir, process.platform === "darwin" ? "libsulcus_store.dylib" : "libsulcus_store.so");
@@ -1303,7 +1314,6 @@ const sulcusPlugin = {
1303
1314
  // ── Backend init ──
1304
1315
  let sulcusMem: SulcusCloudClient | null = null;
1305
1316
  let backendMode = "unavailable";
1306
- const nativeLoader = new NativeLibLoader(storeLibPath, vectorsLibPath);
1307
1317
 
1308
1318
  if (serverUrl && apiKey) {
1309
1319
  try {
@@ -1315,7 +1325,11 @@ const sulcusPlugin = {
1315
1325
  }
1316
1326
  }
1317
1327
 
1318
- if (sulcusMem === null) {
1328
+ // Only attempt native/WASM fallback if cloud mode was NOT configured or failed.
1329
+ // When serverUrl+apiKey are set, the user intends cloud mode — don't warn about
1330
+ // missing native libs that they never intended to use.
1331
+ const nativeLoader = new NativeLibLoader(storeLibPath, vectorsLibPath);
1332
+ if (sulcusMem === null && !(serverUrl && apiKey)) {
1319
1333
  nativeLoader.init(logger);
1320
1334
  if (nativeLoader.loaded) {
1321
1335
  const wasmJsPath = resolve(wasmDir, "sulcus_wasm.js");
@@ -1346,14 +1360,24 @@ const sulcusPlugin = {
1346
1360
 
1347
1361
  // ── Startup summary ──
1348
1362
  if (isAvailable) {
1349
- logger.info(`sulcus: registered (backend: ${backendMode}, namespace: ${namespace}, autoRecall: ${autoRecall}, autoCapture: ${autoCapture})`);
1363
+ logger.info(`sulcus: ready (backend: ${backendMode}, namespace: ${namespace}, autoRecall: ${autoRecall}, autoCapture: ${autoCapture})`);
1350
1364
  } else {
1365
+ // Give clear, actionable guidance instead of cryptic error chains
1351
1366
  const hints: string[] = [];
1352
- if (!serverUrl && !apiKey) hints.push("no serverUrl/apiKey for cloud mode");
1353
- else if (serverUrl && !apiKey) hints.push("serverUrl set but apiKey missing");
1354
- else if (!serverUrl && apiKey) hints.push("apiKey set but serverUrl missing");
1355
- if (nativeLoader.error) hints.push(`local: ${nativeLoader.error}`);
1356
- logger.warn(`sulcus: unavailable${hints.join("; ") || "unknown reason"}`);
1367
+ if (!serverUrl && !apiKey) {
1368
+ hints.push("To use Sulcus cloud: set serverUrl and apiKey in plugin config");
1369
+ hints.push("Get an API key at https://sulcus.ca/dashboard/settings");
1370
+ } else if (serverUrl && !apiKey) {
1371
+ hints.push("serverUrl is set but apiKey is missing add your API key to plugin config");
1372
+ } else if (!serverUrl && apiKey) {
1373
+ hints.push("apiKey is set but serverUrl is missing — add serverUrl (e.g. https://api.sulcus.ca)");
1374
+ } else {
1375
+ hints.push("Cloud connection failed — check serverUrl and apiKey are correct");
1376
+ }
1377
+ if (!serverUrl && !apiKey && nativeLoader.error) {
1378
+ hints.push(`Local mode: ${nativeLoader.error}`);
1379
+ }
1380
+ logger.warn(`sulcus: not ready — ${hints.join(". ")}`);
1357
1381
  }
1358
1382
 
1359
1383
  // ── SIU v2 request helper ──
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalforgestudios/openclaw-sulcus",
3
- "version": "5.3.0",
3
+ "version": "5.4.0",
4
4
  "description": "Sulcus — thermodynamic memory + Apache AGE knowledge graph for OpenClaw agents. v5: before_prompt_build hook migration (replaces before_agent_start), registerMemoryEmbeddingProvider (BGE-small-en-v1.5 via cloud API), registerMemoryRuntime, prependContext recall, registerMemoryPromptSection, registerService lifecycle, uiHints, provider-filtered auto-capture. SIU v2 pipeline auto-classifies and scores memories. Interaction-based decay (3 modes). Curator sleep-cycle. Relevance-weighted recall. Cross-agent sync.",
5
5
  "keywords": [
6
6
  "openclaw",