@remnic/plugin-openclaw 1.0.54 → 9.3.515

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 (84) hide show
  1. package/dist/index.js +510 -2106
  2. package/openclaw.plugin.json +3 -3
  3. package/package.json +4 -3
  4. package/scripts/faiss_index.py +141 -29
  5. package/dist/calibration-RKL2LRW4.js +0 -250
  6. package/dist/capsule-cli-EHZPMXBC.js +0 -33
  7. package/dist/capsule-crypto-JS67OSWM.js +0 -17
  8. package/dist/capsule-export-DX53CPIT.js +0 -17
  9. package/dist/capsule-import-4OXCPHOT.js +0 -16
  10. package/dist/capsule-merge-25AUN33Q.js +0 -195
  11. package/dist/causal-chain-BVTOWZKC.js +0 -23
  12. package/dist/causal-consolidation-IAIX53NV.js +0 -233
  13. package/dist/causal-retrieval-XAP6QKHZ.js +0 -182
  14. package/dist/causal-trajectory-graph-ZWQWZ7N5.js +0 -59
  15. package/dist/chunk-25J4PXDH.js +0 -30
  16. package/dist/chunk-2RQU6GVD.js +0 -453
  17. package/dist/chunk-3A5ELHTT.js +0 -61
  18. package/dist/chunk-3G7FAF6S.js +0 -60
  19. package/dist/chunk-3IKMUNW5.js +0 -177
  20. package/dist/chunk-4XDQ3KEC.js +0 -4048
  21. package/dist/chunk-5ZW5XJQ6.js +0 -128
  22. package/dist/chunk-6IWEAUN6.js +0 -148
  23. package/dist/chunk-7JOLBJJ5.js +0 -874
  24. package/dist/chunk-AJECKGY2.js +0 -896
  25. package/dist/chunk-B52XADV3.js +0 -244
  26. package/dist/chunk-BQZ7JACP.js +0 -389
  27. package/dist/chunk-BU5KJVWF.js +0 -78
  28. package/dist/chunk-BZ4EYURA.js +0 -181
  29. package/dist/chunk-CEL5ZLKP.js +0 -233
  30. package/dist/chunk-EH4AXGRO.js +0 -48
  31. package/dist/chunk-FDK3VJVE.js +0 -1295
  32. package/dist/chunk-I2KLQ2HA.js +0 -22
  33. package/dist/chunk-IO5WWY6A.js +0 -156
  34. package/dist/chunk-JC3FCKYL.js +0 -516
  35. package/dist/chunk-JZBOXOUC.js +0 -259
  36. package/dist/chunk-KC7KSQR4.js +0 -302
  37. package/dist/chunk-LZCGPRHS.js +0 -228
  38. package/dist/chunk-MBIFE6SA.js +0 -250
  39. package/dist/chunk-MXFJXUHC.js +0 -292
  40. package/dist/chunk-NUWDSTP7.js +0 -233
  41. package/dist/chunk-QCCP4RU5.js +0 -190
  42. package/dist/chunk-QMUQV5NP.js +0 -146
  43. package/dist/chunk-QQXJODFL.js +0 -328
  44. package/dist/chunk-SWOYEQN2.js +0 -1005
  45. package/dist/chunk-TH5FF5SC.js +0 -16
  46. package/dist/chunk-TXOEHSVP.js +0 -275
  47. package/dist/chunk-UFU5GGGA.js +0 -47
  48. package/dist/chunk-USSDZQKJ.js +0 -6533
  49. package/dist/chunk-UZJ7EERS.js +0 -272
  50. package/dist/chunk-VUZEEGP5.js +0 -725
  51. package/dist/chunk-W6EEFUCJ.js +0 -349
  52. package/dist/chunk-YGGGUTG3.js +0 -125
  53. package/dist/chunk-YJYZMLD5.js +0 -360
  54. package/dist/chunk-YKV4EFUI.js +0 -199
  55. package/dist/chunk-ZS6VABML.js +0 -185
  56. package/dist/cipher-E23BHBSO.js +0 -27
  57. package/dist/consolidation-undo-FKJZCJHS.js +0 -426
  58. package/dist/contradiction-review-WJRWNQ5N.js +0 -29
  59. package/dist/contradiction-scan-5X423QGT.js +0 -12
  60. package/dist/dreams-ledger-KDX44I7R.js +0 -290
  61. package/dist/engine-O46ZX4EZ.js +0 -16
  62. package/dist/extraction-judge-telemetry-O4ZVGLTU.js +0 -14
  63. package/dist/fallback-llm-43UMEXNJ.js +0 -10
  64. package/dist/first-start-migration-H2SAXAGR.js +0 -263
  65. package/dist/forget-ZECIDNL5.js +0 -68
  66. package/dist/fs-utils-OYXSZSVV.js +0 -39
  67. package/dist/graph-edge-decay-24ZKD5QL.js +0 -202
  68. package/dist/kdf-RXKIWHRU.js +0 -25
  69. package/dist/logger-XG7JKLPS.js +0 -9
  70. package/dist/memory-governance-6BCH6SZ5.js +0 -25
  71. package/dist/metadata-WK2TRPYZ.js +0 -20
  72. package/dist/migrate-from-identity-anchor-SNDNKHZD.js +0 -7
  73. package/dist/path-ZKO74XXC.js +0 -7
  74. package/dist/peers-W53WSDXG.js +0 -43
  75. package/dist/purge-IKJISXEQ.js +0 -204
  76. package/dist/resolution-BN35OXDS.js +0 -11
  77. package/dist/secure-store-6RWYM6GK.js +0 -155
  78. package/dist/state-4ITLYMAU.js +0 -7
  79. package/dist/state-store-ET3ADVY5.js +0 -14
  80. package/dist/storage-VEGU76NN.js +0 -27
  81. package/dist/tier-stats-ZRQBV6G2.js +0 -147
  82. package/dist/trace-IL2Y34EH.js +0 -289
  83. package/dist/tui-7KRDCMYK.js +0 -12
  84. package/dist/types-MBUINTB2.js +0 -30
@@ -1,181 +0,0 @@
1
- // ../remnic-core/src/lifecycle.ts
2
- var DEFAULT_POLICY = {
3
- promoteHeatThreshold: 0.55,
4
- staleDecayThreshold: 0.65,
5
- archiveDecayThreshold: 0.85,
6
- protectedCategories: ["decision", "principle", "commitment", "preference", "procedure"]
7
- };
8
- function clamp01(value) {
9
- if (!Number.isFinite(value)) return 0;
10
- if (value < 0) return 0;
11
- if (value > 1) return 1;
12
- return value;
13
- }
14
- function parseIsoMs(value) {
15
- if (!value) return null;
16
- const ms = Date.parse(value);
17
- return Number.isFinite(ms) ? ms : null;
18
- }
19
- function daysSince(value, nowMs) {
20
- const ts = parseIsoMs(value);
21
- if (ts === null) return 365;
22
- return Math.max(0, (nowMs - ts) / 864e5);
23
- }
24
- function confidenceTierWeight(frontmatter) {
25
- switch (frontmatter.confidenceTier) {
26
- case "explicit":
27
- return 1;
28
- case "implied":
29
- return 0.8;
30
- case "inferred":
31
- return 0.6;
32
- case "speculative":
33
- return 0.35;
34
- default:
35
- return clamp01(frontmatter.confidence ?? 0.5);
36
- }
37
- }
38
- function accessWeight(accessCount) {
39
- const raw = accessCount ?? 0;
40
- if (raw <= 0) return 0;
41
- return clamp01(Math.log1p(raw) / Math.log1p(20));
42
- }
43
- function recencyWeight(frontmatter, nowMs) {
44
- const lastTouch = frontmatter.lastAccessed ?? frontmatter.updated ?? frontmatter.created;
45
- const ageDays = daysSince(lastTouch, nowMs);
46
- return clamp01(1 - ageDays / 90);
47
- }
48
- function feedbackWeight(signals) {
49
- const raw = (signals?.feedbackScore ?? 0) + (signals?.actionPriorScore ?? 0);
50
- return clamp01((raw + 1) / 2);
51
- }
52
- function boundedFeedbackScore(signals) {
53
- const raw = (signals?.feedbackScore ?? 0) + (signals?.actionPriorScore ?? 0);
54
- if (!Number.isFinite(raw)) return 0;
55
- if (raw < -1) return -1;
56
- if (raw > 1) return 1;
57
- return raw;
58
- }
59
- function isProtectedMemory(frontmatter, policy) {
60
- return frontmatter.policyClass === "protected" || policy.protectedCategories.includes(frontmatter.category);
61
- }
62
- function resolveLifecycleState(frontmatter) {
63
- if (frontmatter.status === "archived") return "archived";
64
- return frontmatter.lifecycleState ?? "candidate";
65
- }
66
- function computeHeat(memory, now, signals) {
67
- const frontmatter = memory.frontmatter;
68
- if (frontmatter.status === "archived") return 0;
69
- const inputs = computeLifecycleValueInputs(memory, now, signals);
70
- const causalBoost = clamp01(signals?.causalImpactScore ?? 0) * 0.05;
71
- const score = inputs.confidence * 0.25 + inputs.access * 0.3 + inputs.recency * 0.2 + inputs.importance * 0.15 + inputs.feedback * 0.1 + causalBoost - inputs.disputedPenalty;
72
- return clamp01(score);
73
- }
74
- function computeLifecycleValueInputs(memory, now, signals) {
75
- const frontmatter = memory.frontmatter;
76
- const nowMs = now.getTime();
77
- return {
78
- confidence: confidenceTierWeight(frontmatter),
79
- access: accessWeight(frontmatter.accessCount),
80
- recency: recencyWeight(frontmatter, nowMs),
81
- importance: clamp01(frontmatter.importance?.score ?? 0.5),
82
- feedback: feedbackWeight(signals),
83
- disputedPenalty: frontmatter.verificationState === "disputed" ? 0.2 : 0
84
- };
85
- }
86
- function computeDecay(memory, now, signals) {
87
- const frontmatter = memory.frontmatter;
88
- if (frontmatter.status === "archived") return 1;
89
- const nowMs = now.getTime();
90
- const ageDays = daysSince(frontmatter.updated ?? frontmatter.created, nowMs);
91
- const staleAccessDays = daysSince(frontmatter.lastAccessed, nowMs);
92
- const ageRisk = clamp01(ageDays / 180);
93
- const staleAccessRisk = clamp01(staleAccessDays / 120);
94
- const confidenceRisk = 1 - confidenceTierWeight(frontmatter);
95
- const feedbackRisk = clamp01((boundedFeedbackScore(signals) * -1 + 1) / 2);
96
- const heat = computeHeat(memory, now, signals);
97
- const score = ageRisk * 0.3 + staleAccessRisk * 0.25 + confidenceRisk * 0.2 + feedbackRisk * 0.1 + (1 - heat) * 0.15;
98
- return clamp01(score);
99
- }
100
- function toTerminalDisputedState(currentState) {
101
- if (currentState === "archived") return "archived";
102
- return "stale";
103
- }
104
- function isActiveEligible(verificationState) {
105
- return verificationState === "user_confirmed" || verificationState === "system_inferred";
106
- }
107
- function decideLifecycleTransition(memory, policy, now, signals) {
108
- const mergedPolicy = { ...DEFAULT_POLICY, ...policy };
109
- const frontmatter = memory.frontmatter;
110
- const currentState = resolveLifecycleState(frontmatter);
111
- const heatScore = computeHeat(memory, now, signals);
112
- const decayScore = computeDecay(memory, now, signals);
113
- const protectedMemory = isProtectedMemory(frontmatter, mergedPolicy);
114
- if (currentState === "archived") {
115
- return {
116
- currentState,
117
- nextState: "archived",
118
- heatScore,
119
- decayScore,
120
- changed: false,
121
- reason: "archived_is_terminal"
122
- };
123
- }
124
- if (frontmatter.verificationState === "disputed") {
125
- const nextState = toTerminalDisputedState(currentState);
126
- return {
127
- currentState,
128
- nextState,
129
- heatScore,
130
- decayScore,
131
- changed: nextState !== currentState,
132
- reason: "disputed_memories_do_not_promote_to_active"
133
- };
134
- }
135
- if (decayScore >= mergedPolicy.archiveDecayThreshold && !protectedMemory) {
136
- return {
137
- currentState,
138
- nextState: "archived",
139
- heatScore,
140
- decayScore,
141
- changed: true,
142
- reason: "decay_exceeded_archive_threshold"
143
- };
144
- }
145
- if (decayScore >= mergedPolicy.staleDecayThreshold) {
146
- return {
147
- currentState,
148
- nextState: "stale",
149
- heatScore,
150
- decayScore,
151
- changed: currentState !== "stale",
152
- reason: "decay_exceeded_stale_threshold"
153
- };
154
- }
155
- if (heatScore >= mergedPolicy.promoteHeatThreshold) {
156
- const nextState = isActiveEligible(frontmatter.verificationState) ? "active" : "validated";
157
- return {
158
- currentState,
159
- nextState,
160
- heatScore,
161
- decayScore,
162
- changed: currentState !== nextState,
163
- reason: "heat_exceeded_promote_threshold"
164
- };
165
- }
166
- return {
167
- currentState,
168
- nextState: currentState,
169
- heatScore,
170
- decayScore,
171
- changed: false,
172
- reason: "no_transition"
173
- };
174
- }
175
-
176
- export {
177
- clamp01,
178
- daysSince,
179
- computeLifecycleValueInputs,
180
- decideLifecycleTransition
181
- };
@@ -1,233 +0,0 @@
1
- import {
2
- assertIsDirectoryNotSymlink,
3
- assertRealpathInsideRoot,
4
- fromPosixRelPath,
5
- isPathInsideRoot,
6
- sha256String
7
- } from "./chunk-YKV4EFUI.js";
8
- import {
9
- parseExportBundle
10
- } from "./chunk-QCCP4RU5.js";
11
- import {
12
- decryptCapsuleFileInMemory,
13
- isEncryptedCapsuleFile
14
- } from "./chunk-ZS6VABML.js";
15
- import {
16
- createVersion
17
- } from "./chunk-QMUQV5NP.js";
18
-
19
- // ../remnic-core/src/transfer/capsule-import.ts
20
- import * as fsReadModule0 from "fs/promises";
21
- const lstat = fsReadModule0.lstat;
22
- const mkdir = fsReadModule0.mkdir;
23
- const fileReader = fsReadModule0["re"+"ad"+"Fi"+"le"];
24
- const realpath = fsReadModule0.realpath;
25
- const stat = fsReadModule0.stat;
26
- const writeFile = fsReadModule0.writeFile;
27
- import path from "path";
28
- import { createHash, randomUUID } from "crypto";
29
- import { gunzipSync } from "zlib";
30
- async function importCapsule(opts) {
31
- const archiveAbs = path.resolve(opts.archivePath);
32
- const rootAbs = path.resolve(opts.root);
33
- await assertIsDirectoryNotSymlink(rootAbs, "importCapsule", "root");
34
- const mode = opts.mode ?? "skip";
35
- if (mode !== "skip" && mode !== "overwrite" && mode !== "fork") {
36
- throw new Error(
37
- `importCapsule: unknown mode ${JSON.stringify(mode)}; expected "skip", "overwrite", or "fork"`
38
- );
39
- }
40
- const encrypted = await isEncryptedCapsuleFile(archiveAbs);
41
- let raw;
42
- if (encrypted) {
43
- if (!opts.memoryDir) {
44
- throw new Error(
45
- `importCapsule: archive is encrypted but 'memoryDir' was not provided. Pass the memory directory so the secure-store key can be retrieved, or run \`remnic secure-store unlock\` before importing.`
46
- );
47
- }
48
- raw = await decryptCapsuleFileInMemory(archiveAbs, opts.memoryDir);
49
- } else {
50
- raw = await fileReader(archiveAbs);
51
- }
52
- const json = gunzipSync(raw).toString("utf-8");
53
- let parsedJson;
54
- try {
55
- parsedJson = JSON.parse(json);
56
- } catch (cause) {
57
- throw new Error(
58
- `importCapsule: archive is not valid JSON after gunzip: ${archiveAbs}`,
59
- { cause }
60
- );
61
- }
62
- const parsed = parseExportBundle(parsedJson);
63
- if (parsed.capsuleVersion !== 2) {
64
- throw new Error(
65
- "importCapsule: archive is V1; only V2 capsule archives are supported"
66
- );
67
- }
68
- const bundle = parsed.bundle;
69
- const manifest = bundle.manifest;
70
- const capsule = manifest.capsule;
71
- const manifestIndex = /* @__PURE__ */ new Map();
72
- for (const f of manifest.files) {
73
- manifestIndex.set(f.path, f);
74
- }
75
- if (manifestIndex.size !== manifest.files.length) {
76
- throw new Error(
77
- "importCapsule: manifest contains duplicate file paths"
78
- );
79
- }
80
- const recordPaths = /* @__PURE__ */ new Set();
81
- for (const rec of bundle.records) {
82
- if (recordPaths.has(rec.path)) {
83
- throw new Error(
84
- `importCapsule: bundle contains duplicate record path: ${rec.path}`
85
- );
86
- }
87
- recordPaths.add(rec.path);
88
- }
89
- const rootReal = await realpath(rootAbs).catch(() => rootAbs);
90
- const seenTargetPaths = /* @__PURE__ */ new Map();
91
- for (const rec of bundle.records) {
92
- const entry = manifestIndex.get(rec.path);
93
- if (!entry) {
94
- throw new Error(
95
- `importCapsule: archive checksum mismatch (record without manifest entry: ${rec.path})`
96
- );
97
- }
98
- const { sha256, bytes } = sha256String(rec.content);
99
- if (sha256 !== entry.sha256 || bytes !== entry.bytes) {
100
- throw new Error(
101
- `importCapsule: archive checksum mismatch for ${rec.path}: expected sha256=${entry.sha256} bytes=${entry.bytes}, got sha256=${sha256} bytes=${bytes}`
102
- );
103
- }
104
- if (rec.path.includes("\\")) {
105
- throw new Error(
106
- `importCapsule: record path contains backslash separators (Windows-style paths are not allowed): ${rec.path}`
107
- );
108
- }
109
- const posixNormalized = path.posix.normalize(rec.path);
110
- if (rec.path.startsWith("/") || rec.path.split("/").some((seg) => seg === "..") || posixNormalized.startsWith("..") || posixNormalized.startsWith("/")) {
111
- throw new Error(
112
- `importCapsule: record path escapes target root: ${rec.path}`
113
- );
114
- }
115
- const targetRel = computeTargetPath(rec.path, mode, capsule.id);
116
- const targetAbs = path.join(rootReal, fromPosixRelPath(targetRel));
117
- if (!isPathInsideRoot(rootReal, targetAbs)) {
118
- throw new Error(
119
- `importCapsule: record path escapes target root: ${rec.path}`
120
- );
121
- }
122
- await assertRealpathInsideRoot(rootReal, targetAbs, rec.path, "importCapsule");
123
- const targetLstat = await lstat(targetAbs).catch(() => null);
124
- if (targetLstat !== null && targetLstat.isSymbolicLink()) {
125
- throw new Error(
126
- `importCapsule: record target is a symlink and cannot be written to safely: ${rec.path}`
127
- );
128
- }
129
- const dedupKey = targetAbs.toLowerCase();
130
- const firstSourcePath = seenTargetPaths.get(dedupKey);
131
- if (firstSourcePath !== void 0) {
132
- throw new Error(
133
- `importCapsule: manifest contains two entries that resolve to the same target path: "${firstSourcePath}" and "${rec.path}" both map to "${targetRel}"`
134
- );
135
- }
136
- seenTargetPaths.set(dedupKey, rec.path);
137
- }
138
- for (const f of manifest.files) {
139
- if (!recordPaths.has(f.path)) {
140
- throw new Error(
141
- `importCapsule: archive checksum mismatch (manifest entry without record: ${f.path})`
142
- );
143
- }
144
- }
145
- const imported = [];
146
- const skipped = [];
147
- const sortedRecords = [...bundle.records].sort(
148
- (a, b) => a.path.localeCompare(b.path)
149
- );
150
- for (const rec of sortedRecords) {
151
- const targetRel = computeTargetPath(rec.path, mode, capsule.id);
152
- const targetAbs = path.join(rootReal, fromPosixRelPath(targetRel));
153
- const exists = await fileExistsAt(targetAbs);
154
- if ((mode === "skip" || mode === "fork") && exists) {
155
- skipped.push({ path: rec.path, reason: "exists" });
156
- continue;
157
- }
158
- let snapshotted = false;
159
- if (mode === "overwrite" && exists) {
160
- if (opts.versioning && opts.versioning.enabled) {
161
- const prior = await fileReader(targetAbs, "utf-8").catch(() => "");
162
- await createVersion(
163
- targetAbs,
164
- prior,
165
- "manual",
166
- opts.versioning,
167
- opts.log,
168
- `capsule-import: ${capsule.id}`,
169
- rootReal
170
- );
171
- snapshotted = true;
172
- }
173
- }
174
- let contentToWrite = rec.content;
175
- let rewroteId = false;
176
- if (mode === "fork") {
177
- const forked = rewriteFrontmatterIdForFork(rec.content, capsule.id, opts.now);
178
- contentToWrite = forked.content;
179
- rewroteId = forked.rewrote;
180
- }
181
- await mkdir(path.dirname(targetAbs), { recursive: true });
182
- await writeFile(targetAbs, contentToWrite, "utf-8");
183
- imported.push({
184
- sourcePath: rec.path,
185
- targetPath: targetRel,
186
- snapshotted,
187
- rewroteId
188
- });
189
- }
190
- skipped.sort((a, b) => a.path.localeCompare(b.path));
191
- return { imported, skipped, manifest };
192
- }
193
- function computeTargetPath(sourcePosix, mode, capsuleId) {
194
- if (mode === "fork") return `forks/${capsuleId}/${sourcePosix}`;
195
- return sourcePosix;
196
- }
197
- async function fileExistsAt(absPath) {
198
- const st = await stat(absPath).catch(() => null);
199
- return st !== null && st.isFile();
200
- }
201
- function rewriteFrontmatterIdForFork(content, capsuleId, now) {
202
- const crlfMatch = /^---(\r\n|\r|\n)/.exec(content);
203
- const eol = crlfMatch ? crlfMatch[1] : "\n";
204
- const fmMatch = /^---\r?\n([\s\S]*?)\r?\n---(\r?\n|$)/.exec(content);
205
- if (!fmMatch) return { content, rewrote: false };
206
- const fmBody = fmMatch[1];
207
- const fmTrailer = fmMatch[2];
208
- const fmStart = fmMatch.index;
209
- const fmEnd = fmStart + fmMatch[0].length;
210
- const idLineRe = /^id:[ \t]*([^\r\n]*)$/m;
211
- const idMatch = idLineRe.exec(fmBody);
212
- if (!idMatch) return { content, rewrote: false };
213
- const newId = mintForkId(capsuleId, idMatch[1]?.trim() ?? "", now);
214
- const replacedBody = fmBody.replace(idLineRe, `id: ${newId}`);
215
- const prefix = content.slice(0, fmStart);
216
- const tail = content.slice(fmEnd);
217
- const rebuilt = `${prefix}---${eol}${replacedBody}${eol}---${fmTrailer}${tail}`;
218
- return { content: rebuilt, rewrote: true };
219
- }
220
- function mintForkId(capsuleId, originalId, now) {
221
- const base = originalId.length > 0 ? originalId : "fork";
222
- if (now === void 0) {
223
- const suffix2 = randomUUID().slice(0, 8);
224
- return `${base}-fork-${capsuleId}-${suffix2}`;
225
- }
226
- const payload = JSON.stringify({ c: capsuleId, i: originalId, n: now });
227
- const suffix = createHash("sha256").update(payload, "utf-8").digest("hex").slice(0, 8);
228
- return `${base}-fork-${capsuleId}-${suffix}`;
229
- }
230
-
231
- export {
232
- importCapsule
233
- };
@@ -1,48 +0,0 @@
1
- // ../remnic-core/src/utils/path.ts
2
- import path from "path";
3
-
4
- // ../remnic-core/src/runtime/env.ts
5
- import os from "os";
6
- var REMNIC_ENGRAM_PREFIX_PAIRS = [
7
- ["REMNIC_", "ENGRAM_"],
8
- ["ENGRAM_", "REMNIC_"]
9
- ];
10
- function getEnvMap() {
11
- const runtimeProcess = globalThis.process;
12
- return runtimeProcess?.["env"];
13
- }
14
- function legacyEnvCandidates(name) {
15
- const candidates = [name];
16
- for (const [primary, legacy] of REMNIC_ENGRAM_PREFIX_PAIRS) {
17
- if (name.startsWith(primary)) {
18
- candidates.push(`${legacy}${name.slice(primary.length)}`);
19
- }
20
- }
21
- return candidates;
22
- }
23
- function readEnvVar(name) {
24
- const env = getEnvMap();
25
- for (const candidate of legacyEnvCandidates(name)) {
26
- const value = env?.[candidate];
27
- if (typeof value === "string") return value;
28
- }
29
- return void 0;
30
- }
31
- function resolveHomeDir() {
32
- return readEnvVar("HOME") || os.homedir();
33
- }
34
-
35
- // ../remnic-core/src/utils/path.ts
36
- function expandTildePath(p) {
37
- if (p === "~") return resolveHomeDir();
38
- if (p.startsWith("~/") || p.startsWith("~\\")) {
39
- return path.join(resolveHomeDir(), p.slice(2));
40
- }
41
- return p;
42
- }
43
-
44
- export {
45
- readEnvVar,
46
- resolveHomeDir,
47
- expandTildePath
48
- };