@remnic/plugin-openclaw 1.0.8 → 1.0.10

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,
@@ -60679,11 +60687,25 @@ async function recordObjectiveStateSnapshotsFromAgentMessages(options) {
60679
60687
  return { snapshots, filePaths };
60680
60688
  }
60681
60689
 
60690
+ // ../../src/qmd-availability-probe.ts
60691
+ async function probeQmdAvailability(host) {
60692
+ const qmd = host?.qmd;
60693
+ let available = typeof qmd?.isAvailable === "function" ? Boolean(qmd.isAvailable()) : false;
60694
+ if (!available && typeof qmd?.probe === "function") {
60695
+ try {
60696
+ available = Boolean(await qmd.probe());
60697
+ } catch {
60698
+ available = false;
60699
+ }
60700
+ }
60701
+ return available;
60702
+ }
60703
+
60682
60704
  // ../../src/index.ts
60683
60705
  import { readFile as readFile54, realpath as realpath5, writeFile as writeFile46 } from "fs/promises";
60684
60706
  import { readFileSync as readFileSync6 } from "fs";
60685
60707
  import path103 from "path";
60686
- import os6 from "os";
60708
+ import os7 from "os";
60687
60709
 
60688
60710
  // ../remnic-core/src/opik-exporter.ts
60689
60711
  import { createHash as createHash15, randomBytes as randomBytes2 } from "crypto";
@@ -61389,8 +61411,7 @@ import crypto7 from "crypto";
61389
61411
  // ../remnic-core/src/connectors/index.ts
61390
61412
  import fs11 from "fs";
61391
61413
  import path95 from "path";
61392
- import os4 from "os";
61393
- import { spawnSync } from "child_process";
61414
+ import os5 from "os";
61394
61415
  import { createRequire as createRequire2 } from "module";
61395
61416
  import { fileURLToPath as fileURLToPath4 } from "url";
61396
61417
 
@@ -61410,7 +61431,7 @@ import crypto8 from "crypto";
61410
61431
 
61411
61432
  // ../remnic-core/src/memory-extension/codex-publisher.ts
61412
61433
  import fs13 from "fs";
61413
- import os5 from "os";
61434
+ import os6 from "os";
61414
61435
  import path97 from "path";
61415
61436
 
61416
61437
  // ../remnic-core/src/enrichment/audit.ts
@@ -64739,7 +64760,7 @@ Keep the reflection grounded in the evidence below.
64739
64760
  },
64740
64761
  async probeEmbeddingAvailability() {
64741
64762
  if (!remnicUsesQmd) return { ok: true };
64742
- const qmdAvailable = typeof orchestrator.qmd?.isAvailable === "function" ? Boolean(orchestrator.qmd.isAvailable()) : false;
64763
+ const qmdAvailable = await probeQmdAvailability(orchestrator);
64743
64764
  if (qmdAvailable) return { ok: true };
64744
64765
  const qmdDebug = typeof orchestrator.qmd?.debugStatus === "function" ? orchestrator.qmd.debugStatus() : void 0;
64745
64766
  return {
@@ -64749,7 +64770,7 @@ Keep the reflection grounded in the evidence below.
64749
64770
  },
64750
64771
  async probeVectorAvailability() {
64751
64772
  if (!remnicUsesQmd) return false;
64752
- return typeof orchestrator.qmd?.isAvailable === "function" ? Boolean(orchestrator.qmd.isAvailable()) : false;
64773
+ return probeQmdAvailability(orchestrator);
64753
64774
  },
64754
64775
  async close() {
64755
64776
  }
@@ -65328,7 +65349,7 @@ Keep the reflection grounded in the evidence below.
65328
65349
  async function ensureHourlySummaryCron(api2) {
65329
65350
  const jobId = "engram-hourly-summary";
65330
65351
  const cronFilePath = path103.join(
65331
- os6.homedir(),
65352
+ os7.homedir(),
65332
65353
  ".openclaw",
65333
65354
  "cron",
65334
65355
  "jobs.json"
@@ -65641,31 +65662,71 @@ function extractTextContent2(msg) {
65641
65662
  }
65642
65663
 
65643
65664
  // src/bridge.ts
65644
- import { existsSync as existsSync12, readFileSync as readFileSync7 } from "fs";
65645
- import * as childProcess from "child_process";
65665
+ import { existsSync as existsSync12, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
65646
65666
  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
65667
+ import { Worker } from "worker_threads";
65661
65668
  var DEFAULT_HOST = "127.0.0.1";
65662
65669
  var DEFAULT_PORT = 4318;
65663
65670
  var LEGACY_HEALTH_PATH = "/engram/v1/health";
65671
+ var SYNC_HEALTH_TIMEOUT_MS = 750;
65672
+ var HEALTH_WORKER_SOURCE = `
65673
+ import { request } from "node:http";
65674
+ import { workerData } from "node:worker_threads";
65675
+
65676
+ const view = new Int32Array(workerData.state);
65677
+ let completed = false;
65678
+
65679
+ function finish(ok) {
65680
+ if (completed) return;
65681
+ completed = true;
65682
+ Atomics.store(view, 0, ok ? 1 : 2);
65683
+ Atomics.notify(view, 0);
65684
+ }
65685
+
65686
+ try {
65687
+ const headers = {};
65688
+ if (workerData.token) headers.Authorization = "Bearer " + workerData.token;
65689
+ const req = request(
65690
+ {
65691
+ hostname: workerData.host,
65692
+ port: workerData.port,
65693
+ path: workerData.path,
65694
+ method: "GET",
65695
+ timeout: workerData.timeoutMs,
65696
+ headers,
65697
+ },
65698
+ (res) => {
65699
+ finish(res.statusCode === 200);
65700
+ res.resume();
65701
+ },
65702
+ );
65703
+ req.on("error", () => finish(false));
65704
+ req.on("timeout", () => {
65705
+ req.destroy();
65706
+ finish(false);
65707
+ });
65708
+ req.end();
65709
+ } catch {
65710
+ finish(false);
65711
+ }
65712
+ `;
65713
+ var LAUNCHD_SERVICE_PATHS = [
65714
+ ["Library", "LaunchAgents", "ai.remnic.daemon.plist"],
65715
+ ["Library", "LaunchAgents", "ai.engram.daemon.plist"]
65716
+ ];
65717
+ var SYSTEMD_SERVICE_PATHS = [
65718
+ [".config", "systemd", "user", "remnic.service"],
65719
+ [".config", "systemd", "user", "engram.service"]
65720
+ ];
65721
+ function readEnv(name) {
65722
+ const env = globalThis.process?.["env"];
65723
+ return env?.[name];
65724
+ }
65664
65725
  function resolveHomeDir2() {
65665
- return process.env.HOME ?? process.env.USERPROFILE ?? "~";
65726
+ return readEnv("HOME") ?? readEnv("USERPROFILE") ?? "~";
65666
65727
  }
65667
65728
  function readCompatEnv(primary, legacy) {
65668
- return process.env[primary] ?? process.env[legacy];
65729
+ return readEnv(primary) ?? readEnv(legacy);
65669
65730
  }
65670
65731
  function configPathCandidates() {
65671
65732
  const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
@@ -65677,6 +65738,13 @@ function configPathCandidates() {
65677
65738
  path104.join(process.cwd(), "engram.config.json")
65678
65739
  ];
65679
65740
  }
65741
+ function fileExists2(filePath) {
65742
+ try {
65743
+ return statSync3(filePath).isFile();
65744
+ } catch {
65745
+ return false;
65746
+ }
65747
+ }
65680
65748
  function isDaemonRunning() {
65681
65749
  for (const pidFile of [
65682
65750
  path104.join(resolveHomeDir2(), ".remnic", "server.pid"),
@@ -65689,34 +65757,55 @@ function isDaemonRunning() {
65689
65757
  } catch {
65690
65758
  }
65691
65759
  }
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;
65760
+ return false;
65761
+ }
65762
+ function isDaemonServiceConfigured() {
65763
+ const homeDir = resolveHomeDir2();
65764
+ for (const segments of [...LAUNCHD_SERVICE_PATHS, ...SYSTEMD_SERVICE_PATHS]) {
65765
+ if (fileExists2(path104.join(homeDir, ...segments))) return true;
65706
65766
  }
65707
65767
  return false;
65708
65768
  }
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;
65769
+ function coerceDaemonPort(value) {
65770
+ const parsed = typeof value === "string" && value.trim() !== "" ? Number(value.trim()) : value;
65771
+ return typeof parsed === "number" && Number.isInteger(parsed) && parsed > 0 && parsed <= 65535 ? parsed : void 0;
65772
+ }
65773
+ function checkDaemonHealthSync(host, port, timeoutMs = SYNC_HEALTH_TIMEOUT_MS) {
65774
+ if (!host || !Number.isInteger(port) || port <= 0 || port > 65535) return false;
65775
+ let worker;
65776
+ try {
65777
+ const state = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
65778
+ const view = new Int32Array(state);
65779
+ const workerUrl = new URL(`data:text/javascript,${encodeURIComponent(HEALTH_WORKER_SOURCE)}`);
65780
+ worker = new Worker(workerUrl, {
65781
+ type: "module",
65782
+ workerData: {
65783
+ host,
65784
+ port,
65785
+ path: LEGACY_HEALTH_PATH,
65786
+ token: loadAnyToken(),
65787
+ timeoutMs,
65788
+ state
65789
+ }
65790
+ });
65791
+ Atomics.wait(view, 0, 0, timeoutMs + 250);
65792
+ const status = Atomics.load(view, 0);
65793
+ if (status === 0) void worker.terminate();
65794
+ return status === 1;
65795
+ } catch {
65796
+ if (worker) void worker.terminate();
65797
+ return false;
65714
65798
  }
65799
+ }
65800
+ function readDaemonPort() {
65801
+ const envPort = coerceDaemonPort(readCompatEnv("REMNIC_PORT", "ENGRAM_PORT"));
65802
+ if (envPort !== void 0) return envPort;
65715
65803
  for (const p of configPathCandidates()) {
65716
65804
  if (!existsSync12(p)) continue;
65717
65805
  try {
65718
65806
  const raw = JSON.parse(readFileSync7(p, "utf8"));
65719
- if (raw.server?.port) return raw.server.port;
65807
+ const configPort = coerceDaemonPort(raw.server?.port);
65808
+ if (configPort !== void 0) return configPort;
65720
65809
  } catch {
65721
65810
  }
65722
65811
  }
@@ -65738,17 +65827,19 @@ function detectBridgeMode() {
65738
65827
  daemonPort: readDaemonPort()
65739
65828
  };
65740
65829
  }
65741
- if (isDaemonRunning()) {
65830
+ const daemonHost = readCompatEnv("REMNIC_HOST", "ENGRAM_HOST") ?? DEFAULT_HOST;
65831
+ const daemonPort = readDaemonPort();
65832
+ if (isDaemonRunning() || isDaemonServiceConfigured() && checkDaemonHealthSync(daemonHost, daemonPort)) {
65742
65833
  return {
65743
65834
  mode: "delegate",
65744
- daemonHost: readCompatEnv("REMNIC_HOST", "ENGRAM_HOST") ?? DEFAULT_HOST,
65745
- daemonPort: readDaemonPort()
65835
+ daemonHost,
65836
+ daemonPort
65746
65837
  };
65747
65838
  }
65748
65839
  return {
65749
65840
  mode: "embedded",
65750
65841
  daemonHost: DEFAULT_HOST,
65751
- daemonPort: readDaemonPort()
65842
+ daemonPort
65752
65843
  };
65753
65844
  }
65754
65845
  function loadAnyToken() {
@@ -65781,7 +65872,7 @@ function loadAnyToken() {
65781
65872
  }
65782
65873
  } catch {
65783
65874
  }
65784
- return process.env.OPENCLAW_REMNIC_ACCESS_TOKEN ?? process.env.OPENCLAW_ENGRAM_ACCESS_TOKEN ?? readCompatEnv("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN") ?? "";
65875
+ return readEnv("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnv("OPENCLAW_ENGRAM_ACCESS_TOKEN") ?? readCompatEnv("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN") ?? "";
65785
65876
  }
65786
65877
  async function checkDaemonHealth(host, port) {
65787
65878
  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.10",
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"