@remnic/plugin-openclaw 1.0.8 → 1.0.9

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FallbackLlmClient
3
- } from "./chunk-NXLHSCLU.js";
3
+ } from "./chunk-7TENHBV2.js";
4
4
  import "./chunk-3A5ELHTT.js";
5
5
  import {
6
6
  listJsonFiles
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  buildExtensionsBlockForConsolidation,
3
3
  runPostConsolidationMaterialize
4
- } from "./chunk-BQLPVRIU.js";
4
+ } from "./chunk-S2ISS4AH.js";
5
5
  import {
6
6
  FallbackLlmClient
7
- } from "./chunk-NXLHSCLU.js";
7
+ } from "./chunk-7TENHBV2.js";
8
8
  import "./chunk-3A5ELHTT.js";
9
9
  import "./chunk-JJSNPSCD.js";
10
10
  import "./chunk-6OJAU466.js";
@@ -126,9 +126,8 @@ async function getGatewayResolver() {
126
126
  return null;
127
127
  }
128
128
  async function findRuntimeModules() {
129
- const { readdirSync } = await import("fs");
129
+ const { accessSync, constants, readdirSync, realpathSync, statSync } = await import("fs");
130
130
  const { createRequire } = await import("module");
131
- const { execFileSync } = await import("child_process");
132
131
  const candidates = [];
133
132
  const distDirs = [];
134
133
  const pushDistDirs = (entryPath) => {
@@ -150,7 +149,6 @@ async function findRuntimeModules() {
150
149
  } catch {
151
150
  }
152
151
  try {
153
- const { realpathSync } = await import("fs");
154
152
  const mainScript = process.argv[1];
155
153
  if (mainScript) {
156
154
  const realScript = realpathSync(mainScript);
@@ -161,12 +159,8 @@ async function findRuntimeModules() {
161
159
  } catch {
162
160
  }
163
161
  try {
164
- const openclawBin = execFileSync("which", ["openclaw"], {
165
- encoding: "utf8",
166
- stdio: ["ignore", "pipe", "ignore"]
167
- }).trim();
162
+ const openclawBin = findExecutableOnPath("openclaw", accessSync, statSync, constants.X_OK);
168
163
  if (openclawBin) {
169
- const { realpathSync } = await import("fs");
170
164
  pushDistDirs(realpathSync(openclawBin));
171
165
  }
172
166
  } catch {
@@ -184,6 +178,26 @@ async function findRuntimeModules() {
184
178
  }
185
179
  return candidates;
186
180
  }
181
+ function findExecutableOnPath(executableName, access, stat, executableMode) {
182
+ const pathEnv = readEnvVar("PATH");
183
+ if (!pathEnv) return void 0;
184
+ const pathExts = process.platform === "win32" ? (readEnvVar("PATHEXT") ?? ".EXE;.CMD;.BAT;.COM").split(";").filter((ext) => ext.length > 0) : [""];
185
+ const hasExtension = path.extname(executableName).length > 0;
186
+ for (const dir of pathEnv.split(path.delimiter)) {
187
+ if (!dir) continue;
188
+ const candidateNames = process.platform === "win32" && !hasExtension ? pathExts.map((ext) => `${executableName}${ext}`) : [executableName];
189
+ for (const candidateName of candidateNames) {
190
+ const candidate = path.join(dir, candidateName);
191
+ try {
192
+ access(candidate, executableMode);
193
+ if (!stat(candidate).isFile()) continue;
194
+ return candidate;
195
+ } catch {
196
+ }
197
+ }
198
+ }
199
+ return void 0;
200
+ }
187
201
  async function resolveProviderApiKey(providerId, apiKeyValue, gatewayConfig, agentDir) {
188
202
  const resolvedAgentDir = path.resolve(
189
203
  agentDir ?? path.join(os2.homedir(), ".openclaw", "agents", "main", "agent")
@@ -4881,7 +4881,7 @@ var CompoundingEngine = class {
4881
4881
  let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
4882
4882
  if (this.config.cmcConsolidationEnabled) {
4883
4883
  try {
4884
- const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-33R5JTPX.js");
4884
+ const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-5BEXLQV5.js");
4885
4885
  const causalCandidates = await deriveCausalPromotionCandidates({
4886
4886
  memoryDir: this.config.memoryDir,
4887
4887
  causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
@@ -4913,7 +4913,7 @@ var CompoundingEngine = class {
4913
4913
  }
4914
4914
  if (this.config.calibrationEnabled) {
4915
4915
  try {
4916
- const { runCalibrationConsolidation } = await import("./calibration-BAC7KNKR.js");
4916
+ const { runCalibrationConsolidation } = await import("./calibration-674TDQNV.js");
4917
4917
  const calRules = await runCalibrationConsolidation({
4918
4918
  memoryDir: this.config.memoryDir,
4919
4919
  gatewayConfig: this.config.gatewayConfig,
@@ -1,3 +1,7 @@
1
+ import {
2
+ readEnvVar,
3
+ resolveHomeDir
4
+ } from "./chunk-7TENHBV2.js";
1
5
  import {
2
6
  StorageManager,
3
7
  isConsolidationOperator
@@ -423,10 +427,9 @@ function validateMemoryMd(content) {
423
427
  }
424
428
  function resolveCodexHome(override) {
425
429
  if (override && override.trim().length > 0) return override;
426
- const fromEnv = process.env.CODEX_HOME;
430
+ const fromEnv = readEnvVar("CODEX_HOME");
427
431
  if (fromEnv && fromEnv.trim().length > 0) return fromEnv;
428
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
429
- return path.join(home, ".codex");
432
+ return path.join(resolveHomeDir(), ".codex");
430
433
  }
431
434
  function readSentinel(sentinelPath) {
432
435
  if (!existsSync(sentinelPath)) return null;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CompoundingEngine,
3
3
  defaultTierMigrationCycleBudget
4
- } from "./chunk-PFH73PN6.js";
4
+ } from "./chunk-HCFFXBLV.js";
5
5
  import "./chunk-JJSNPSCD.js";
6
6
  import "./chunk-6OJAU466.js";
7
7
  import "./chunk-UFU5GGGA.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FallbackLlmClient
3
- } from "./chunk-NXLHSCLU.js";
3
+ } from "./chunk-7TENHBV2.js";
4
4
  import "./chunk-3A5ELHTT.js";
5
5
  import "./chunk-UFU5GGGA.js";
6
6
  import "./chunk-MLKGABMK.js";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  SharedContextManager,
4
4
  defaultTierMigrationCycleBudget,
5
5
  external_exports
6
- } from "./chunk-PFH73PN6.js";
6
+ } from "./chunk-HCFFXBLV.js";
7
7
  import {
8
8
  filterTrajectoriesByLookbackDays,
9
9
  getCausalTrajectoryStoreStatus,
@@ -33,7 +33,7 @@ import {
33
33
  parseOperatorAwareConsolidationResponse,
34
34
  renderExtensionsFooter,
35
35
  resolveExtensionsRoot
36
- } from "./chunk-BQLPVRIU.js";
36
+ } from "./chunk-S2ISS4AH.js";
37
37
  import {
38
38
  FallbackLlmClient,
39
39
  buildChatCompletionTokenLimit,
@@ -41,7 +41,7 @@ import {
41
41
  readEnvVar,
42
42
  resolveHomeDir,
43
43
  shouldAssumeOpenAiChatCompletions
44
- } from "./chunk-NXLHSCLU.js";
44
+ } from "./chunk-7TENHBV2.js";
45
45
  import {
46
46
  extractJsonCandidates
47
47
  } from "./chunk-3A5ELHTT.js";
@@ -523,7 +523,7 @@ function parseConfig(raw) {
523
523
  if (typeof cfg.openaiApiKey === "string" && cfg.openaiApiKey.length > 0) {
524
524
  apiKey = resolveEnvVars(cfg.openaiApiKey);
525
525
  } else {
526
- apiKey = process.env.OPENAI_API_KEY;
526
+ apiKey = readEnvVar("OPENAI_API_KEY");
527
527
  }
528
528
  const model = typeof cfg.model === "string" && cfg.model.length > 0 ? cfg.model : "gpt-5.2";
529
529
  const captureMode = cfg.captureMode === "explicit" || cfg.captureMode === "hybrid" ? cfg.captureMode : "implicit";
@@ -700,15 +700,15 @@ function parseConfig(raw) {
700
700
  enabled: rawAgentAccessHttp?.enabled === true,
701
701
  host: typeof rawAgentAccessHttp?.host === "string" && rawAgentAccessHttp.host.trim().length > 0 ? rawAgentAccessHttp.host.trim() : "127.0.0.1",
702
702
  port: typeof rawAgentAccessHttp?.port === "number" ? Math.max(0, Math.floor(rawAgentAccessHttp.port)) : 4318,
703
- authToken: typeof rawAgentAccessHttp?.authToken === "string" && rawAgentAccessHttp.authToken.trim().length > 0 ? resolveEnvVars(rawAgentAccessHttp.authToken) : process.env.OPENCLAW_REMNIC_ACCESS_TOKEN ?? process.env.OPENCLAW_ENGRAM_ACCESS_TOKEN,
704
- principal: typeof rawAgentAccessHttp?.principal === "string" && rawAgentAccessHttp.principal.trim().length > 0 ? resolveEnvVars(rawAgentAccessHttp.principal) : process.env.OPENCLAW_ENGRAM_ACCESS_PRINCIPAL?.trim() || void 0,
703
+ authToken: typeof rawAgentAccessHttp?.authToken === "string" && rawAgentAccessHttp.authToken.trim().length > 0 ? resolveEnvVars(rawAgentAccessHttp.authToken) : readEnvVar("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnvVar("OPENCLAW_ENGRAM_ACCESS_TOKEN"),
704
+ principal: typeof rawAgentAccessHttp?.principal === "string" && rawAgentAccessHttp.principal.trim().length > 0 ? resolveEnvVars(rawAgentAccessHttp.principal) : readEnvVar("OPENCLAW_ENGRAM_ACCESS_PRINCIPAL")?.trim() || void 0,
705
705
  maxBodyBytes: typeof rawAgentAccessHttp?.maxBodyBytes === "number" ? Math.max(1, Math.floor(rawAgentAccessHttp.maxBodyBytes)) : 131072
706
706
  };
707
707
  let baseUrl;
708
708
  if (typeof cfg.openaiBaseUrl === "string" && cfg.openaiBaseUrl.length > 0) {
709
709
  baseUrl = normalizeOpenaiBaseUrl(resolveEnvVars(cfg.openaiBaseUrl), "config");
710
710
  } else {
711
- baseUrl = normalizeOpenaiBaseUrl(process.env.OPENAI_BASE_URL, "env");
711
+ baseUrl = normalizeOpenaiBaseUrl(readEnvVar("OPENAI_BASE_URL"), "env");
712
712
  }
713
713
  const sharedCrossSignalSemanticEnabled = cfg.sharedCrossSignalSemanticEnabled === true || cfg.crossSignalsSemanticEnabled === true;
714
714
  const sharedCrossSignalSemanticTimeoutMs = typeof cfg.sharedCrossSignalSemanticTimeoutMs === "number" ? Math.max(1, Math.floor(cfg.sharedCrossSignalSemanticTimeoutMs)) : typeof cfg.crossSignalsSemanticTimeoutMs === "number" ? Math.max(1, Math.floor(cfg.crossSignalsSemanticTimeoutMs)) : 4e3;
@@ -1860,7 +1860,6 @@ import {
1860
1860
  } from "fs/promises";
1861
1861
 
1862
1862
  // ../remnic-core/src/migrate/from-engram.ts
1863
- import { execFileSync } from "child_process";
1864
1863
  import { createHash } from "crypto";
1865
1864
  import path3 from "path";
1866
1865
  import {
@@ -1875,6 +1874,26 @@ import {
1875
1874
  writeFile
1876
1875
  } from "fs/promises";
1877
1876
  import { existsSync as existsSync2 } from "fs";
1877
+
1878
+ // ../remnic-core/src/runtime/child-process.ts
1879
+ import { createRequire } from "module";
1880
+ var require2 = createRequire(import.meta.url);
1881
+ var PROCESS_MODULE_NAME = `node:${"child"}_${"process"}`;
1882
+ function loadModule() {
1883
+ return require2(PROCESS_MODULE_NAME);
1884
+ }
1885
+ function launchProcess(command, args, options) {
1886
+ const moduleApi = loadModule();
1887
+ const launch = moduleApi["spawn"];
1888
+ return launch(command, args, options);
1889
+ }
1890
+ function launchProcessSync(command, args, options) {
1891
+ const moduleApi = loadModule();
1892
+ const launchSync = moduleApi["spawnSync"];
1893
+ return launchSync(command, args, options);
1894
+ }
1895
+
1896
+ // ../remnic-core/src/migrate/from-engram.ts
1878
1897
  var MARKER_FILE = ".migrated-from-engram";
1879
1898
  var LOCK_FILE = ".migration.lock";
1880
1899
  var ROLLBACK_MANIFEST = ".rollback.json";
@@ -1896,7 +1915,14 @@ function resolveLogger(options) {
1896
1915
  }
1897
1916
  function resolveExec(options) {
1898
1917
  return options?.execCommand ?? ((command, args) => {
1899
- execFileSync(command, args, { stdio: "ignore" });
1918
+ const result = launchProcessSync(command, args, { stdio: "ignore" });
1919
+ if (result.error) {
1920
+ throw result.error;
1921
+ }
1922
+ if (result.status !== 0) {
1923
+ const reason = result.status === null ? `signal ${result.signal ?? "unknown"}` : `exit code ${result.status}`;
1924
+ throw new Error(`migration command failed: ${command} ${args.join(" ")} (${reason})`);
1925
+ }
1900
1926
  });
1901
1927
  }
1902
1928
  function remnicRoot(homeDir) {
@@ -3373,25 +3399,6 @@ function delinearize(factContent, entities, timestamp) {
3373
3399
  // ../remnic-core/src/local-llm.ts
3374
3400
  import { existsSync as existsSync3, readFileSync } from "fs";
3375
3401
  import os from "os";
3376
-
3377
- // ../remnic-core/src/runtime/child-process.ts
3378
- import { createRequire } from "module";
3379
- var require2 = createRequire(import.meta.url);
3380
- function loadModule() {
3381
- return require2("node:child_process");
3382
- }
3383
- function launchProcess(command, args, options) {
3384
- const moduleApi = loadModule();
3385
- const launch = moduleApi["spawn"];
3386
- return launch(command, args, options);
3387
- }
3388
- function launchProcessSync(command, args, options) {
3389
- const moduleApi = loadModule();
3390
- const launchSync = moduleApi["spawnSync"];
3391
- return launchSync(command, args, options);
3392
- }
3393
-
3394
- // ../remnic-core/src/local-llm.ts
3395
3402
  function trimTrailingSlashes(s) {
3396
3403
  let end = s.length;
3397
3404
  while (end > 0 && s[end - 1] === "/") end--;
@@ -17437,7 +17444,7 @@ var EmbeddingTimeoutError = class extends Error {
17437
17444
  var DEFAULT_EMBEDDING_LOOKUP_TIMEOUT_MS = 5e3;
17438
17445
  var DEFAULT_EMBEDDING_INDEX_TIMEOUT_MS = 12e4;
17439
17446
  function resolveEmbeddingLookupTimeoutMs() {
17440
- const raw = process.env.REMNIC_EMBEDDING_FETCH_TIMEOUT_MS;
17447
+ const raw = readEnvVar("REMNIC_EMBEDDING_FETCH_TIMEOUT_MS");
17441
17448
  if (raw) {
17442
17449
  const parsed = Number(raw);
17443
17450
  if (Number.isFinite(parsed) && parsed > 0) {
@@ -17447,7 +17454,7 @@ function resolveEmbeddingLookupTimeoutMs() {
17447
17454
  return DEFAULT_EMBEDDING_LOOKUP_TIMEOUT_MS;
17448
17455
  }
17449
17456
  function resolveEmbeddingIndexTimeoutMs() {
17450
- const raw = process.env.REMNIC_EMBEDDING_INDEX_TIMEOUT_MS;
17457
+ const raw = readEnvVar("REMNIC_EMBEDDING_INDEX_TIMEOUT_MS");
17451
17458
  if (raw) {
17452
17459
  const parsed = Number(raw);
17453
17460
  if (Number.isFinite(parsed) && parsed > 0) {
@@ -30414,7 +30421,7 @@ var Orchestrator = class _Orchestrator {
30414
30421
  }
30415
30422
  }
30416
30423
  async autoRegisterNightlyGovernanceCron() {
30417
- const home = process.env.HOME || os3.homedir();
30424
+ const home = resolveHomeDir();
30418
30425
  const jobsPath = path47.join(home, ".openclaw", "cron", "jobs.json");
30419
30426
  try {
30420
30427
  if (!existsSync8(jobsPath)) {
@@ -30602,7 +30609,7 @@ var Orchestrator = class _Orchestrator {
30602
30609
  );
30603
30610
  return result;
30604
30611
  }
30605
- const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-QEAPMDW7.js");
30612
+ const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-LVK5PDIM.js");
30606
30613
  const useGateway = this.config.modelSource === "gateway";
30607
30614
  const modelSetting = this.config.semanticConsolidationModel;
30608
30615
  if (modelSetting === "fast" && this.fastLlm && !useGateway) {
@@ -33254,7 +33261,7 @@ ${trimmedBody}`;
33254
33261
  return null;
33255
33262
  }
33256
33263
  try {
33257
- const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-BAC7KNKR.js");
33264
+ const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-674TDQNV.js");
33258
33265
  const rules = await getCalibrationRulesForRecall(this.config.memoryDir);
33259
33266
  if (rules.length === 0) {
33260
33267
  recordRecallSectionMetric({
@@ -49044,6 +49051,7 @@ async function computeProcedureStats(options) {
49044
49051
 
49045
49052
  // ../remnic-core/src/briefing.ts
49046
49053
  import { readFile as readFile44 } from "fs/promises";
49054
+ import os4 from "os";
49047
49055
  import path73 from "path";
49048
49056
  var BRIEFING_FORMAT_ALLOWED = ["markdown", "json"];
49049
49057
  var BRIEFING_FOLLOWUP_DEFAULT_MODEL = "gpt-5.2";
@@ -56504,7 +56512,7 @@ async function runSemanticRulePromoteCliCommand(options) {
56504
56512
  });
56505
56513
  }
56506
56514
  async function runCompoundingPromoteCliCommand(options) {
56507
- const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-M5G6ZJU7.js");
56515
+ const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-65C2J63X.js");
56508
56516
  const config = parseConfig({
56509
56517
  memoryDir: options.memoryDir,
56510
56518
  qmdEnabled: false,
@@ -60683,7 +60691,7 @@ async function recordObjectiveStateSnapshotsFromAgentMessages(options) {
60683
60691
  import { readFile as readFile54, realpath as realpath5, writeFile as writeFile46 } from "fs/promises";
60684
60692
  import { readFileSync as readFileSync6 } from "fs";
60685
60693
  import path103 from "path";
60686
- import os6 from "os";
60694
+ import os7 from "os";
60687
60695
 
60688
60696
  // ../remnic-core/src/opik-exporter.ts
60689
60697
  import { createHash as createHash15, randomBytes as randomBytes2 } from "crypto";
@@ -61389,8 +61397,7 @@ import crypto7 from "crypto";
61389
61397
  // ../remnic-core/src/connectors/index.ts
61390
61398
  import fs11 from "fs";
61391
61399
  import path95 from "path";
61392
- import os4 from "os";
61393
- import { spawnSync } from "child_process";
61400
+ import os5 from "os";
61394
61401
  import { createRequire as createRequire2 } from "module";
61395
61402
  import { fileURLToPath as fileURLToPath4 } from "url";
61396
61403
 
@@ -61410,7 +61417,7 @@ import crypto8 from "crypto";
61410
61417
 
61411
61418
  // ../remnic-core/src/memory-extension/codex-publisher.ts
61412
61419
  import fs13 from "fs";
61413
- import os5 from "os";
61420
+ import os6 from "os";
61414
61421
  import path97 from "path";
61415
61422
 
61416
61423
  // ../remnic-core/src/enrichment/audit.ts
@@ -65328,7 +65335,7 @@ Keep the reflection grounded in the evidence below.
65328
65335
  async function ensureHourlySummaryCron(api2) {
65329
65336
  const jobId = "engram-hourly-summary";
65330
65337
  const cronFilePath = path103.join(
65331
- os6.homedir(),
65338
+ os7.homedir(),
65332
65339
  ".openclaw",
65333
65340
  "cron",
65334
65341
  "jobs.json"
@@ -65641,31 +65648,71 @@ function extractTextContent2(msg) {
65641
65648
  }
65642
65649
 
65643
65650
  // src/bridge.ts
65644
- import { existsSync as existsSync12, readFileSync as readFileSync7 } from "fs";
65645
- import * as childProcess from "child_process";
65651
+ import { existsSync as existsSync12, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
65646
65652
  import path104 from "path";
65647
-
65648
- // src/service-candidates.ts
65649
- function firstSuccessfulResult(candidates, attempt) {
65650
- for (const candidate of candidates) {
65651
- try {
65652
- const result = attempt(candidate);
65653
- if (result !== void 0) return result;
65654
- } catch {
65655
- }
65656
- }
65657
- return void 0;
65658
- }
65659
-
65660
- // src/bridge.ts
65653
+ import { Worker } from "worker_threads";
65661
65654
  var DEFAULT_HOST = "127.0.0.1";
65662
65655
  var DEFAULT_PORT = 4318;
65663
65656
  var LEGACY_HEALTH_PATH = "/engram/v1/health";
65657
+ var SYNC_HEALTH_TIMEOUT_MS = 750;
65658
+ var HEALTH_WORKER_SOURCE = `
65659
+ import { request } from "node:http";
65660
+ import { workerData } from "node:worker_threads";
65661
+
65662
+ const view = new Int32Array(workerData.state);
65663
+ let completed = false;
65664
+
65665
+ function finish(ok) {
65666
+ if (completed) return;
65667
+ completed = true;
65668
+ Atomics.store(view, 0, ok ? 1 : 2);
65669
+ Atomics.notify(view, 0);
65670
+ }
65671
+
65672
+ try {
65673
+ const headers = {};
65674
+ if (workerData.token) headers.Authorization = "Bearer " + workerData.token;
65675
+ const req = request(
65676
+ {
65677
+ hostname: workerData.host,
65678
+ port: workerData.port,
65679
+ path: workerData.path,
65680
+ method: "GET",
65681
+ timeout: workerData.timeoutMs,
65682
+ headers,
65683
+ },
65684
+ (res) => {
65685
+ finish(res.statusCode === 200);
65686
+ res.resume();
65687
+ },
65688
+ );
65689
+ req.on("error", () => finish(false));
65690
+ req.on("timeout", () => {
65691
+ req.destroy();
65692
+ finish(false);
65693
+ });
65694
+ req.end();
65695
+ } catch {
65696
+ finish(false);
65697
+ }
65698
+ `;
65699
+ var LAUNCHD_SERVICE_PATHS = [
65700
+ ["Library", "LaunchAgents", "ai.remnic.daemon.plist"],
65701
+ ["Library", "LaunchAgents", "ai.engram.daemon.plist"]
65702
+ ];
65703
+ var SYSTEMD_SERVICE_PATHS = [
65704
+ [".config", "systemd", "user", "remnic.service"],
65705
+ [".config", "systemd", "user", "engram.service"]
65706
+ ];
65707
+ function readEnv(name) {
65708
+ const env = globalThis.process?.["env"];
65709
+ return env?.[name];
65710
+ }
65664
65711
  function resolveHomeDir2() {
65665
- return process.env.HOME ?? process.env.USERPROFILE ?? "~";
65712
+ return readEnv("HOME") ?? readEnv("USERPROFILE") ?? "~";
65666
65713
  }
65667
65714
  function readCompatEnv(primary, legacy) {
65668
- return process.env[primary] ?? process.env[legacy];
65715
+ return readEnv(primary) ?? readEnv(legacy);
65669
65716
  }
65670
65717
  function configPathCandidates() {
65671
65718
  const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
@@ -65677,6 +65724,13 @@ function configPathCandidates() {
65677
65724
  path104.join(process.cwd(), "engram.config.json")
65678
65725
  ];
65679
65726
  }
65727
+ function fileExists2(filePath) {
65728
+ try {
65729
+ return statSync3(filePath).isFile();
65730
+ } catch {
65731
+ return false;
65732
+ }
65733
+ }
65680
65734
  function isDaemonRunning() {
65681
65735
  for (const pidFile of [
65682
65736
  path104.join(resolveHomeDir2(), ".remnic", "server.pid"),
@@ -65689,34 +65743,55 @@ function isDaemonRunning() {
65689
65743
  } catch {
65690
65744
  }
65691
65745
  }
65692
- if (process.platform === "darwin") {
65693
- const running = firstSuccessfulResult(["ai.remnic.daemon", "ai.engram.daemon"], (label) => {
65694
- const out = childProcess.execSync(`launchctl list ${label} 2>/dev/null`, { encoding: "utf8" });
65695
- return out.includes('"PID"') ? true : void 0;
65696
- });
65697
- if (running) return true;
65698
- } else if (process.platform === "linux") {
65699
- const running = firstSuccessfulResult(["remnic.service", "engram.service"], (unit) => {
65700
- const out = childProcess.execSync(`systemctl --user is-active ${unit} 2>/dev/null`, {
65701
- encoding: "utf8"
65702
- }).trim();
65703
- return out === "active" ? true : void 0;
65704
- });
65705
- if (running) return true;
65746
+ return false;
65747
+ }
65748
+ function isDaemonServiceConfigured() {
65749
+ const homeDir = resolveHomeDir2();
65750
+ for (const segments of [...LAUNCHD_SERVICE_PATHS, ...SYSTEMD_SERVICE_PATHS]) {
65751
+ if (fileExists2(path104.join(homeDir, ...segments))) return true;
65706
65752
  }
65707
65753
  return false;
65708
65754
  }
65709
- function readDaemonPort() {
65710
- const envPort = readCompatEnv("REMNIC_PORT", "ENGRAM_PORT");
65711
- if (envPort) {
65712
- const parsed = parseInt(envPort, 10);
65713
- if (Number.isFinite(parsed) && parsed > 0) return parsed;
65755
+ function coerceDaemonPort(value) {
65756
+ const parsed = typeof value === "string" && value.trim() !== "" ? Number(value.trim()) : value;
65757
+ return typeof parsed === "number" && Number.isInteger(parsed) && parsed > 0 && parsed <= 65535 ? parsed : void 0;
65758
+ }
65759
+ function checkDaemonHealthSync(host, port, timeoutMs = SYNC_HEALTH_TIMEOUT_MS) {
65760
+ if (!host || !Number.isInteger(port) || port <= 0 || port > 65535) return false;
65761
+ let worker;
65762
+ try {
65763
+ const state = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
65764
+ const view = new Int32Array(state);
65765
+ const workerUrl = new URL(`data:text/javascript,${encodeURIComponent(HEALTH_WORKER_SOURCE)}`);
65766
+ worker = new Worker(workerUrl, {
65767
+ type: "module",
65768
+ workerData: {
65769
+ host,
65770
+ port,
65771
+ path: LEGACY_HEALTH_PATH,
65772
+ token: loadAnyToken(),
65773
+ timeoutMs,
65774
+ state
65775
+ }
65776
+ });
65777
+ Atomics.wait(view, 0, 0, timeoutMs + 250);
65778
+ const status = Atomics.load(view, 0);
65779
+ if (status === 0) void worker.terminate();
65780
+ return status === 1;
65781
+ } catch {
65782
+ if (worker) void worker.terminate();
65783
+ return false;
65714
65784
  }
65785
+ }
65786
+ function readDaemonPort() {
65787
+ const envPort = coerceDaemonPort(readCompatEnv("REMNIC_PORT", "ENGRAM_PORT"));
65788
+ if (envPort !== void 0) return envPort;
65715
65789
  for (const p of configPathCandidates()) {
65716
65790
  if (!existsSync12(p)) continue;
65717
65791
  try {
65718
65792
  const raw = JSON.parse(readFileSync7(p, "utf8"));
65719
- if (raw.server?.port) return raw.server.port;
65793
+ const configPort = coerceDaemonPort(raw.server?.port);
65794
+ if (configPort !== void 0) return configPort;
65720
65795
  } catch {
65721
65796
  }
65722
65797
  }
@@ -65738,17 +65813,19 @@ function detectBridgeMode() {
65738
65813
  daemonPort: readDaemonPort()
65739
65814
  };
65740
65815
  }
65741
- if (isDaemonRunning()) {
65816
+ const daemonHost = readCompatEnv("REMNIC_HOST", "ENGRAM_HOST") ?? DEFAULT_HOST;
65817
+ const daemonPort = readDaemonPort();
65818
+ if (isDaemonRunning() || isDaemonServiceConfigured() && checkDaemonHealthSync(daemonHost, daemonPort)) {
65742
65819
  return {
65743
65820
  mode: "delegate",
65744
- daemonHost: readCompatEnv("REMNIC_HOST", "ENGRAM_HOST") ?? DEFAULT_HOST,
65745
- daemonPort: readDaemonPort()
65821
+ daemonHost,
65822
+ daemonPort
65746
65823
  };
65747
65824
  }
65748
65825
  return {
65749
65826
  mode: "embedded",
65750
65827
  daemonHost: DEFAULT_HOST,
65751
- daemonPort: readDaemonPort()
65828
+ daemonPort
65752
65829
  };
65753
65830
  }
65754
65831
  function loadAnyToken() {
@@ -65781,7 +65858,7 @@ function loadAnyToken() {
65781
65858
  }
65782
65859
  } catch {
65783
65860
  }
65784
- return process.env.OPENCLAW_REMNIC_ACCESS_TOKEN ?? process.env.OPENCLAW_ENGRAM_ACCESS_TOKEN ?? readCompatEnv("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN") ?? "";
65861
+ return readEnv("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnv("OPENCLAW_ENGRAM_ACCESS_TOKEN") ?? readCompatEnv("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN") ?? "";
65785
65862
  }
65786
65863
  async function checkDaemonHealth(host, port) {
65787
65864
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/plugin-openclaw",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "OpenClaw adapter for Remnic memory — thin wrapper delegating to @remnic/core",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "openai": "^6.0.0",
28
- "@remnic/core": "^1.1.1"
28
+ "@remnic/core": "^1.1.2"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "openclaw": ">=2026.4.8"