@remnic/plugin-openclaw 1.0.9 → 1.0.11
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.
- package/dist/{calibration-674TDQNV.js → calibration-WCHOK6DX.js} +12 -4
- package/dist/capsule-cli-TFKLAG3S.js +329 -0
- package/dist/capsule-crypto-K3IRTKRH.js +17 -0
- package/dist/capsule-export-CVA3CKUQ.js +265 -0
- package/dist/capsule-import-CFX7BY5W.js +16 -0
- package/dist/capsule-merge-7RVOHJK3.js +189 -0
- package/dist/{causal-chain-OKDZSDEB.js → causal-chain-WYN5QOPS.js} +3 -2
- package/dist/{causal-consolidation-5BEXLQV5.js → causal-consolidation-JD6KJJH6.js} +16 -12
- package/dist/{causal-retrieval-3BKBXVXD.js → causal-retrieval-NZHQOZOE.js} +6 -5
- package/dist/{causal-trajectory-graph-RQIT37DN.js → causal-trajectory-graph-VBPE2WPM.js} +1 -1
- package/dist/chunk-37NKFWSO.js +233 -0
- package/dist/chunk-3G7FAF6S.js +60 -0
- package/dist/{chunk-Z7GRLVK3.js → chunk-3GUF7RQI.js} +235 -19
- package/dist/chunk-3I7RHWYT.js +214 -0
- package/dist/chunk-4G2XCSD2.js +186 -0
- package/dist/chunk-6IWEAUN6.js +148 -0
- package/dist/{chunk-LN5UZQVG.js → chunk-6UFI73TJ.js} +5 -3
- package/dist/chunk-7OQEPGQF.js +529 -0
- package/dist/chunk-B52XADV3.js +244 -0
- package/dist/chunk-BU5KJVWF.js +78 -0
- package/dist/chunk-CXM7EBAO.js +289 -0
- package/dist/chunk-ETJZRIAM.js +227 -0
- package/dist/chunk-FQRSVYY4.js +110 -0
- package/dist/chunk-HRGFO6AW.js +349 -0
- package/dist/chunk-I6B2W2IY.js +47 -0
- package/dist/chunk-JZBOXOUC.js +259 -0
- package/dist/chunk-K7EUBNDD.js +185 -0
- package/dist/chunk-L4PRBB2A.js +1860 -0
- package/dist/chunk-MBIFE6SA.js +250 -0
- package/dist/chunk-N7EOZY6F.js +400 -0
- package/dist/chunk-NKVIN6RD.js +118 -0
- package/dist/chunk-OEI7GLV2.js +17 -0
- package/dist/{chunk-S2ISS4AH.js → chunk-P3DIW2SD.js} +10 -10
- package/dist/{chunk-7TENHBV2.js → chunk-RQCTMECT.js} +10 -48
- package/dist/chunk-SSFTU6LP.js +182 -0
- package/dist/{chunk-BXTMZDRT.js → chunk-SVSQAG6M.js} +7 -5
- package/dist/chunk-TLVIQLB4.js +874 -0
- package/dist/{chunk-JJSNPSCD.js → chunk-TNH24SF6.js} +352 -50
- package/dist/chunk-TVKKIS53.js +720 -0
- package/dist/{chunk-YHH3SXKD.js → chunk-WPINX4MF.js} +1 -59
- package/dist/{chunk-HCFFXBLV.js → chunk-XMSDA5WA.js} +5 -1861
- package/dist/chunk-YGGGUTG3.js +125 -0
- package/dist/chunk-YGXXBRV7.js +10 -0
- package/dist/cipher-VHAFCG7Z.js +27 -0
- package/dist/dreams-ledger-3I52ISYR.js +285 -0
- package/dist/{engine-65C2J63X.js → engine-VMTFKFGO.js} +5 -2
- package/dist/{fallback-llm-LVK5PDIM.js → fallback-llm-WCWNGIQ3.js} +2 -1
- package/dist/first-start-migration-I24M2JEE.js +258 -0
- package/dist/forget-NI4RBDPB.js +68 -0
- package/dist/fs-utils-PZRI2HDZ.js +29 -0
- package/dist/graph-edge-decay-5CVKWBYH.js +203 -0
- package/dist/index.js +9791 -2902
- package/dist/kdf-H5B23ZM2.js +25 -0
- package/dist/memory-governance-DWGFV4FX.js +25 -0
- package/dist/metadata-JAGIWHEA.js +20 -0
- package/dist/migrate-from-identity-anchor-N3354WMP.js +7 -0
- package/dist/path-5LCUBAAZ.js +8 -0
- package/dist/peers-JF2I6RCR.js +43 -0
- package/dist/purge-XN2VSPZ2.js +204 -0
- package/dist/secure-store-FWJ7LBPH.js +149 -0
- package/dist/state-PVISYXRH.js +7 -0
- package/dist/state-store-LP5BO6SF.js +15 -0
- package/dist/{storage-DM4ZGOCN.js → storage-T2OGFUF4.js} +3 -1
- package/dist/tier-stats-IZNW66NC.js +147 -0
- package/dist/trace-NJESSGH7.js +289 -0
- package/dist/tui-MGK2LYJY.js +12 -0
- package/dist/types-H5R5D3WF.js +30 -0
- package/openclaw.plugin.json +519 -4
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FallbackLlmClient
|
|
3
|
-
} from "./chunk-7TENHBV2.js";
|
|
4
|
-
import "./chunk-3A5ELHTT.js";
|
|
5
1
|
import {
|
|
6
2
|
listJsonFiles
|
|
7
3
|
} from "./chunk-5LE4HTVL.js";
|
|
4
|
+
import {
|
|
5
|
+
FallbackLlmClient
|
|
6
|
+
} from "./chunk-RQCTMECT.js";
|
|
7
|
+
import "./chunk-3A5ELHTT.js";
|
|
8
8
|
import {
|
|
9
9
|
log
|
|
10
10
|
} from "./chunk-UFU5GGGA.js";
|
|
11
|
+
import "./chunk-I6B2W2IY.js";
|
|
11
12
|
import "./chunk-MLKGABMK.js";
|
|
12
13
|
|
|
13
14
|
// ../remnic-core/src/calibration.ts
|
|
@@ -38,7 +39,13 @@ async function writeCalibrationIndex(memoryDir, index) {
|
|
|
38
39
|
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
39
40
|
await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), "utf8");
|
|
40
41
|
}
|
|
42
|
+
async function readCalibrationCorrections(memoryDir) {
|
|
43
|
+
return readCorrectionsImpl(memoryDir);
|
|
44
|
+
}
|
|
41
45
|
async function readCorrections(memoryDir) {
|
|
46
|
+
return readCorrectionsImpl(memoryDir);
|
|
47
|
+
}
|
|
48
|
+
async function readCorrectionsImpl(memoryDir) {
|
|
42
49
|
const correctionsDir = path.join(memoryDir, "corrections");
|
|
43
50
|
const files = await listJsonFiles(correctionsDir).catch(() => {
|
|
44
51
|
return [];
|
|
@@ -229,6 +236,7 @@ async function getCalibrationRulesForRecall(memoryDir) {
|
|
|
229
236
|
export {
|
|
230
237
|
buildCalibrationRecallSection,
|
|
231
238
|
getCalibrationRulesForRecall,
|
|
239
|
+
readCalibrationCorrections,
|
|
232
240
|
readCalibrationIndex,
|
|
233
241
|
runCalibrationConsolidation,
|
|
234
242
|
runCalibrationIfEnabled,
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import "./chunk-MLKGABMK.js";
|
|
2
|
+
|
|
3
|
+
// ../remnic-core/src/capsule-cli.ts
|
|
4
|
+
import path from "path";
|
|
5
|
+
function parseCapsuleOutputFormat(raw) {
|
|
6
|
+
if (raw === void 0 || raw === null) return "text";
|
|
7
|
+
if (typeof raw !== "string" || raw.trim() === "") {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`--format expects one of text, markdown, json; got ${JSON.stringify(raw)}`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
const v = raw.trim();
|
|
13
|
+
if (v !== "text" && v !== "markdown" && v !== "json") {
|
|
14
|
+
throw new Error(
|
|
15
|
+
`--format expects one of text, markdown, json; got ${JSON.stringify(raw)}`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return v;
|
|
19
|
+
}
|
|
20
|
+
function parseCapsuleImportMode(raw) {
|
|
21
|
+
if (raw === void 0 || raw === null) return "skip";
|
|
22
|
+
if (typeof raw !== "string" || raw.trim() === "") {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`--mode expects one of skip, overwrite, fork; got ${JSON.stringify(raw)}`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const v = raw.trim();
|
|
28
|
+
if (v !== "skip" && v !== "overwrite" && v !== "fork") {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`--mode expects one of skip, overwrite, fork; got ${JSON.stringify(raw)}`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
return v;
|
|
34
|
+
}
|
|
35
|
+
function parseCapsuleConflictMode(raw) {
|
|
36
|
+
if (raw === void 0 || raw === null) return "skip-conflicts";
|
|
37
|
+
if (typeof raw !== "string" || raw.trim() === "") {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`--conflict-mode expects one of skip-conflicts, prefer-source, prefer-local; got ${JSON.stringify(raw)}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const v = raw.trim();
|
|
43
|
+
if (v !== "skip-conflicts" && v !== "prefer-source" && v !== "prefer-local") {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`--conflict-mode expects one of skip-conflicts, prefer-source, prefer-local; got ${JSON.stringify(raw)}`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return v;
|
|
49
|
+
}
|
|
50
|
+
var ISO_8601_RE = /^\d{4}-\d{2}-\d{2}(?:[Tt]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:[Zz]|[+-]\d{2}:?\d{2}))?$/;
|
|
51
|
+
function parseCapsuleSince(raw) {
|
|
52
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
53
|
+
if (typeof raw !== "string") {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`--since expects an ISO 8601 timestamp; got ${JSON.stringify(raw)}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (raw.trim() === "") {
|
|
59
|
+
throw new Error(`--since expects an ISO 8601 timestamp; received empty string`);
|
|
60
|
+
}
|
|
61
|
+
if (!ISO_8601_RE.test(raw)) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`--since is not a valid ISO 8601 timestamp: ${raw}. Accepted forms: YYYY-MM-DD, YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DDTHH:MM:SS\xB1HH:MM`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const ms = Date.parse(raw);
|
|
67
|
+
if (!Number.isFinite(ms)) {
|
|
68
|
+
throw new Error(`--since is not a valid ISO 8601 timestamp: ${raw}`);
|
|
69
|
+
}
|
|
70
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(raw);
|
|
71
|
+
if (m) {
|
|
72
|
+
const offsetMatch = /([+-])(\d{2}):?(\d{2})$/.exec(raw);
|
|
73
|
+
let displayMs = ms;
|
|
74
|
+
if (offsetMatch) {
|
|
75
|
+
const sign = offsetMatch[1] === "-" ? -1 : 1;
|
|
76
|
+
const offsetMin = sign * (Number(offsetMatch[2]) * 60 + Number(offsetMatch[3]));
|
|
77
|
+
displayMs = ms + offsetMin * 6e4;
|
|
78
|
+
}
|
|
79
|
+
const dd = new Date(displayMs);
|
|
80
|
+
if (dd.getUTCFullYear() !== Number(m[1]) || dd.getUTCMonth() + 1 !== Number(m[2]) || dd.getUTCDate() !== Number(m[3])) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`--since: calendar overflow \u2014 ${raw} normalises to a different calendar date`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return raw;
|
|
87
|
+
}
|
|
88
|
+
function parseCapsuleIncludeKinds(raw) {
|
|
89
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
90
|
+
if (typeof raw !== "string") {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`--include-kinds expects a comma-separated list of directory names; got ${JSON.stringify(raw)}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (raw.trim() === "") {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`--include-kinds expects at least one non-empty kind name`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const parts = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
101
|
+
if (parts.length === 0) {
|
|
102
|
+
throw new Error(`--include-kinds expects at least one non-empty kind name`);
|
|
103
|
+
}
|
|
104
|
+
for (const p of parts) {
|
|
105
|
+
if (p.includes("/") || p.includes("\\")) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`--include-kinds entries must be top-level directory names (no path separators): ${p}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return [...new Set(parts)];
|
|
112
|
+
}
|
|
113
|
+
function parseCapsulePeers(raw) {
|
|
114
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
115
|
+
if (typeof raw !== "string") {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`--peers expects a comma-separated list of peer ids; got ${JSON.stringify(raw)}`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
if (raw.trim() === "") {
|
|
121
|
+
throw new Error(`--peers expects at least one non-empty peer id`);
|
|
122
|
+
}
|
|
123
|
+
const parts = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
124
|
+
if (parts.length === 0) {
|
|
125
|
+
throw new Error(`--peers expects at least one non-empty peer id`);
|
|
126
|
+
}
|
|
127
|
+
for (const p of parts) {
|
|
128
|
+
if (p.includes("/") || p.includes("\\") || p === "." || p === "..") {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`--peers entries must be plain id tokens (no path separators): ${p}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return [...new Set(parts)];
|
|
135
|
+
}
|
|
136
|
+
function parseCapsuleExportOptions(nameArg, opts) {
|
|
137
|
+
if (typeof nameArg !== "string" || nameArg.trim() === "") {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`capsule export: <name> is required (e.g. "remnic capsule export my-capsule")`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const name = nameArg.trim();
|
|
143
|
+
const out = typeof opts.out === "string" && opts.out.trim() !== "" ? opts.out.trim() : void 0;
|
|
144
|
+
const since = parseCapsuleSince(opts.since);
|
|
145
|
+
const includeKinds = parseCapsuleIncludeKinds(opts.includeKinds);
|
|
146
|
+
const peers = parseCapsulePeers(opts.peers);
|
|
147
|
+
return { name, out, since, includeKinds, peers };
|
|
148
|
+
}
|
|
149
|
+
function parseCapsuleImportOptions(archiveArg, opts) {
|
|
150
|
+
if (typeof archiveArg !== "string" || archiveArg.trim() === "") {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`capsule import: <archive> path is required (e.g. "remnic capsule import /path/to/my-capsule.capsule.json.gz")`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
const archive = archiveArg.trim();
|
|
156
|
+
const mode = parseCapsuleImportMode(opts.mode);
|
|
157
|
+
return { archive, mode };
|
|
158
|
+
}
|
|
159
|
+
function parseCapsuleMergeOptions(archiveArg, opts) {
|
|
160
|
+
if (typeof archiveArg !== "string" || archiveArg.trim() === "") {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`capsule merge: <archive> path is required (e.g. "remnic capsule merge /path/to/my-capsule.capsule.json.gz")`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const archive = archiveArg.trim();
|
|
166
|
+
const conflictMode = parseCapsuleConflictMode(opts.conflictMode);
|
|
167
|
+
return { archive, conflictMode };
|
|
168
|
+
}
|
|
169
|
+
function parseCapsuleListOptions(opts, defaultCapsulesDir2) {
|
|
170
|
+
const format = parseCapsuleOutputFormat(opts.format);
|
|
171
|
+
const rawDir = typeof opts.dir === "string" && opts.dir.trim() !== "" ? opts.dir.trim() : void 0;
|
|
172
|
+
const capsulesDir = rawDir ?? defaultCapsulesDir2;
|
|
173
|
+
return { format, capsulesDir };
|
|
174
|
+
}
|
|
175
|
+
function parseCapsuleInspectOptions(archiveArg, opts) {
|
|
176
|
+
if (typeof archiveArg !== "string" || archiveArg.trim() === "") {
|
|
177
|
+
throw new Error(
|
|
178
|
+
`capsule inspect: <archive> path is required (e.g. "remnic capsule inspect my-capsule.capsule.json.gz")`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
const archive = archiveArg.trim();
|
|
182
|
+
const format = parseCapsuleOutputFormat(opts.format);
|
|
183
|
+
return { archive, format };
|
|
184
|
+
}
|
|
185
|
+
function defaultCapsulesDir(memoryDir) {
|
|
186
|
+
return path.join(memoryDir, ".capsules");
|
|
187
|
+
}
|
|
188
|
+
function escapeMarkdownCell(v) {
|
|
189
|
+
return v.replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
|
|
190
|
+
}
|
|
191
|
+
function renderCapsuleList(entries, format) {
|
|
192
|
+
if (format === "json") {
|
|
193
|
+
return JSON.stringify({ capsules: entries }, null, 2);
|
|
194
|
+
}
|
|
195
|
+
if (entries.length === 0) {
|
|
196
|
+
if (format === "markdown") return "_No capsule archives found._\n";
|
|
197
|
+
return "No capsule archives found.\n";
|
|
198
|
+
}
|
|
199
|
+
if (format === "markdown") {
|
|
200
|
+
const rows = entries.map((e) => {
|
|
201
|
+
const id = escapeMarkdownCell(e.id);
|
|
202
|
+
const date = escapeMarkdownCell(e.createdAt?.slice(0, 10) ?? "\u2014");
|
|
203
|
+
const ver = escapeMarkdownCell(e.pluginVersion ?? "\u2014");
|
|
204
|
+
const files = e.fileCount !== null ? String(e.fileCount) : "\u2014";
|
|
205
|
+
const desc = escapeMarkdownCell(
|
|
206
|
+
e.description != null && e.description.trim() !== "" ? e.description.trim() : "\u2014"
|
|
207
|
+
);
|
|
208
|
+
return `| \`${id}\` | ${date} | ${ver} | ${files} | ${desc} |`;
|
|
209
|
+
});
|
|
210
|
+
return [
|
|
211
|
+
"# Capsule archives",
|
|
212
|
+
"",
|
|
213
|
+
"| ID | Created | Version | Files | Description |",
|
|
214
|
+
"| -- | ------- | ------- | ----- | ----------- |",
|
|
215
|
+
...rows,
|
|
216
|
+
""
|
|
217
|
+
].join("\n");
|
|
218
|
+
}
|
|
219
|
+
const lines = entries.map((e) => {
|
|
220
|
+
const date = e.createdAt?.slice(0, 10) ?? "\u2014";
|
|
221
|
+
const files = e.fileCount !== null ? `${e.fileCount} file${e.fileCount !== 1 ? "s" : ""}` : "? files";
|
|
222
|
+
const desc = e.description != null && e.description.trim() !== "" ? ` ${e.description.trim()}` : "";
|
|
223
|
+
return `${e.id} [${date}] [${files}]${desc}`;
|
|
224
|
+
});
|
|
225
|
+
return lines.join("\n") + "\n";
|
|
226
|
+
}
|
|
227
|
+
function renderCapsuleInspect(manifest, format) {
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
return JSON.stringify(manifest, null, 2);
|
|
230
|
+
}
|
|
231
|
+
const {
|
|
232
|
+
capsuleId,
|
|
233
|
+
version,
|
|
234
|
+
schemaVersion,
|
|
235
|
+
createdAt,
|
|
236
|
+
pluginVersion,
|
|
237
|
+
fileCount,
|
|
238
|
+
includesTranscripts,
|
|
239
|
+
description,
|
|
240
|
+
parentCapsule,
|
|
241
|
+
retrievalPolicy,
|
|
242
|
+
includes,
|
|
243
|
+
topFiles
|
|
244
|
+
} = manifest;
|
|
245
|
+
if (format === "markdown") {
|
|
246
|
+
const policyLines = Object.entries(retrievalPolicy.tierWeights ?? {}).map(
|
|
247
|
+
([k, v]) => ` - ${k}: ${v}`
|
|
248
|
+
);
|
|
249
|
+
const policyBlock = policyLines.length > 0 ? policyLines.join("\n") : " _(no tier weight overrides)_";
|
|
250
|
+
return [
|
|
251
|
+
`# Capsule: \`${capsuleId}\``,
|
|
252
|
+
"",
|
|
253
|
+
`**Version:** ${version} `,
|
|
254
|
+
`**Schema version:** ${schemaVersion} `,
|
|
255
|
+
`**Created:** ${createdAt ?? "\u2014"} `,
|
|
256
|
+
`**Plugin version:** ${pluginVersion ?? "\u2014"} `,
|
|
257
|
+
`**Files:** ${fileCount} `,
|
|
258
|
+
`**Includes transcripts:** ${includesTranscripts ? "yes" : "no"} `,
|
|
259
|
+
`**Parent capsule:** ${parentCapsule ?? "_none_"} `,
|
|
260
|
+
`**Description:** ${description && description.trim() !== "" ? description.trim() : "_none_"} `,
|
|
261
|
+
"",
|
|
262
|
+
"## Includes",
|
|
263
|
+
`- taxonomy: ${includes.taxonomy ? "yes" : "no"}`,
|
|
264
|
+
`- identityAnchors: ${includes.identityAnchors ? "yes" : "no"}`,
|
|
265
|
+
`- peerProfiles: ${includes.peerProfiles ? "yes" : "no"}`,
|
|
266
|
+
`- procedural: ${includes.procedural ? "yes" : "no"}`,
|
|
267
|
+
"",
|
|
268
|
+
"## Retrieval policy",
|
|
269
|
+
`- directAnswerEnabled: ${retrievalPolicy.directAnswerEnabled ? "yes" : "no"}`,
|
|
270
|
+
`- tierWeights:`,
|
|
271
|
+
policyBlock,
|
|
272
|
+
"",
|
|
273
|
+
...topFiles.length > 0 ? [
|
|
274
|
+
`## Files (${fileCount} total, showing first ${topFiles.length})`,
|
|
275
|
+
...topFiles.map((f) => `- \`${f}\``),
|
|
276
|
+
""
|
|
277
|
+
] : [`## Files (${fileCount} total)`, "_Empty capsule._", ""]
|
|
278
|
+
].join("\n");
|
|
279
|
+
}
|
|
280
|
+
const lines = [
|
|
281
|
+
`Capsule: ${capsuleId}`,
|
|
282
|
+
` version: ${version}`,
|
|
283
|
+
` schema: ${schemaVersion}`,
|
|
284
|
+
` created: ${createdAt ?? "\u2014"}`,
|
|
285
|
+
` plugin: ${pluginVersion ?? "\u2014"}`,
|
|
286
|
+
` files: ${fileCount}`,
|
|
287
|
+
` transcripts: ${includesTranscripts ? "yes" : "no"}`,
|
|
288
|
+
` parent: ${parentCapsule ?? "(none)"}`,
|
|
289
|
+
` description: ${description && description.trim() !== "" ? description.trim() : "(none)"}`,
|
|
290
|
+
"",
|
|
291
|
+
` includes.taxonomy: ${includes.taxonomy ? "yes" : "no"}`,
|
|
292
|
+
` includes.identityAnchors: ${includes.identityAnchors ? "yes" : "no"}`,
|
|
293
|
+
` includes.peerProfiles: ${includes.peerProfiles ? "yes" : "no"}`,
|
|
294
|
+
` includes.procedural: ${includes.procedural ? "yes" : "no"}`,
|
|
295
|
+
"",
|
|
296
|
+
` policy.directAnswer: ${retrievalPolicy.directAnswerEnabled ? "yes" : "no"}`
|
|
297
|
+
];
|
|
298
|
+
const weights = Object.entries(retrievalPolicy.tierWeights ?? {});
|
|
299
|
+
if (weights.length > 0) {
|
|
300
|
+
for (const [k, v] of weights) {
|
|
301
|
+
lines.push(` policy.tierWeight[${k}]: ${v}`);
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
lines.push(` policy.tierWeights: (none)`);
|
|
305
|
+
}
|
|
306
|
+
if (topFiles.length > 0) {
|
|
307
|
+
lines.push("", ` files (first ${topFiles.length} of ${fileCount}):`);
|
|
308
|
+
for (const f of topFiles) {
|
|
309
|
+
lines.push(` ${f}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return lines.join("\n") + "\n";
|
|
313
|
+
}
|
|
314
|
+
export {
|
|
315
|
+
defaultCapsulesDir,
|
|
316
|
+
parseCapsuleConflictMode,
|
|
317
|
+
parseCapsuleExportOptions,
|
|
318
|
+
parseCapsuleImportMode,
|
|
319
|
+
parseCapsuleImportOptions,
|
|
320
|
+
parseCapsuleIncludeKinds,
|
|
321
|
+
parseCapsuleInspectOptions,
|
|
322
|
+
parseCapsuleListOptions,
|
|
323
|
+
parseCapsuleMergeOptions,
|
|
324
|
+
parseCapsuleOutputFormat,
|
|
325
|
+
parseCapsulePeers,
|
|
326
|
+
parseCapsuleSince,
|
|
327
|
+
renderCapsuleInspect,
|
|
328
|
+
renderCapsuleList
|
|
329
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decryptCapsuleFile,
|
|
3
|
+
decryptCapsuleFileInMemory,
|
|
4
|
+
encryptCapsuleFile,
|
|
5
|
+
isEncryptedCapsuleFile
|
|
6
|
+
} from "./chunk-SSFTU6LP.js";
|
|
7
|
+
import "./chunk-CXM7EBAO.js";
|
|
8
|
+
import "./chunk-JZBOXOUC.js";
|
|
9
|
+
import "./chunk-6IWEAUN6.js";
|
|
10
|
+
import "./chunk-YGGGUTG3.js";
|
|
11
|
+
import "./chunk-MLKGABMK.js";
|
|
12
|
+
export {
|
|
13
|
+
decryptCapsuleFile,
|
|
14
|
+
decryptCapsuleFileInMemory,
|
|
15
|
+
encryptCapsuleFile,
|
|
16
|
+
isEncryptedCapsuleFile
|
|
17
|
+
};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CAPSULE_SCHEMA_VERSION,
|
|
3
|
+
EXPORT_FORMAT
|
|
4
|
+
} from "./chunk-YGXXBRV7.js";
|
|
5
|
+
import {
|
|
6
|
+
CAPSULE_ID_PATTERN,
|
|
7
|
+
CapsuleBlockSchema,
|
|
8
|
+
ExportBundleV2Schema,
|
|
9
|
+
ExportManifestV2Schema
|
|
10
|
+
} from "./chunk-K7EUBNDD.js";
|
|
11
|
+
import {
|
|
12
|
+
listFilesRecursive,
|
|
13
|
+
sha256File,
|
|
14
|
+
toPosixRelPath,
|
|
15
|
+
writeJsonFile
|
|
16
|
+
} from "./chunk-NKVIN6RD.js";
|
|
17
|
+
import {
|
|
18
|
+
encryptCapsuleFile
|
|
19
|
+
} from "./chunk-SSFTU6LP.js";
|
|
20
|
+
import "./chunk-XMSDA5WA.js";
|
|
21
|
+
import "./chunk-CXM7EBAO.js";
|
|
22
|
+
import "./chunk-JZBOXOUC.js";
|
|
23
|
+
import "./chunk-6IWEAUN6.js";
|
|
24
|
+
import "./chunk-YGGGUTG3.js";
|
|
25
|
+
import "./chunk-MLKGABMK.js";
|
|
26
|
+
|
|
27
|
+
// ../remnic-core/src/transfer/capsule-export.ts
|
|
28
|
+
import { mkdir, readFile, stat, writeFile } from "fs/promises";
|
|
29
|
+
import path from "path";
|
|
30
|
+
import { gzipSync } from "zlib";
|
|
31
|
+
var DEFAULT_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
32
|
+
"node_modules",
|
|
33
|
+
".git",
|
|
34
|
+
// Never export the secure-store directory: it contains the encryption
|
|
35
|
+
// header (KDF params + verifier) which is security-sensitive and
|
|
36
|
+
// machine-specific. The passphrase is not stored here, but including
|
|
37
|
+
// the header in a capsule would let an attacker brute-force the
|
|
38
|
+
// passphrase offline if the capsule is intercepted.
|
|
39
|
+
".secure-store",
|
|
40
|
+
// Exclude .capsules to avoid recursive self-inclusion.
|
|
41
|
+
".capsules"
|
|
42
|
+
]);
|
|
43
|
+
var TRANSCRIPTS_DIR = "transcripts";
|
|
44
|
+
var PEERS_DIR = "peers";
|
|
45
|
+
async function exportCapsule(opts) {
|
|
46
|
+
validateName(opts.name);
|
|
47
|
+
const sinceMs = parseSince(opts.since);
|
|
48
|
+
const includeKinds = normalizeIncludeKinds(opts.includeKinds);
|
|
49
|
+
const peerFilter = normalizePeerIds(opts.peerIds);
|
|
50
|
+
const transcriptsOverride = opts.includeTranscripts === true;
|
|
51
|
+
const rootAbs = path.resolve(opts.root);
|
|
52
|
+
await assertIsDirectory(rootAbs);
|
|
53
|
+
const outDirAbs = path.resolve(opts.outDir ?? path.join(rootAbs, ".capsules"));
|
|
54
|
+
if (outDirAbs === rootAbs) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"exportCapsule: 'outDir' must not equal 'root'. Choose a separate directory (default: <root>/.capsules) so the export does not overwrite or shadow the source tree."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
await mkdir(outDirAbs, { recursive: true });
|
|
60
|
+
const outDirRelPosix = computeOutDirRel(rootAbs, outDirAbs);
|
|
61
|
+
const filesAbs = await listFilesRecursive(rootAbs);
|
|
62
|
+
const records = [];
|
|
63
|
+
const manifestFiles = [];
|
|
64
|
+
for (const abs of filesAbs) {
|
|
65
|
+
const relPosix = toPosixRelPath(abs, rootAbs);
|
|
66
|
+
if (!shouldInclude(relPosix, includeKinds, peerFilter, outDirRelPosix, transcriptsOverride)) continue;
|
|
67
|
+
if (sinceMs !== null) {
|
|
68
|
+
const st = await stat(abs);
|
|
69
|
+
if (st.mtimeMs < sinceMs) continue;
|
|
70
|
+
}
|
|
71
|
+
const content = await readFile(abs, "utf-8");
|
|
72
|
+
records.push({ path: relPosix, content });
|
|
73
|
+
const { sha256, bytes } = await sha256File(abs);
|
|
74
|
+
manifestFiles.push({ path: relPosix, sha256, bytes });
|
|
75
|
+
}
|
|
76
|
+
records.sort((a, b) => a.path.localeCompare(b.path));
|
|
77
|
+
manifestFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
78
|
+
const capsule = buildCapsuleBlock(opts.name, opts.capsule);
|
|
79
|
+
const includesTranscripts = transcriptsOverride || (includeKinds ?? /* @__PURE__ */ new Set()).has(TRANSCRIPTS_DIR);
|
|
80
|
+
const createdAtMs = opts.now ?? Date.now();
|
|
81
|
+
const manifest = ExportManifestV2Schema.parse({
|
|
82
|
+
format: EXPORT_FORMAT,
|
|
83
|
+
schemaVersion: CAPSULE_SCHEMA_VERSION,
|
|
84
|
+
createdAt: new Date(createdAtMs).toISOString(),
|
|
85
|
+
pluginVersion: opts.pluginVersion ?? "0.0.0",
|
|
86
|
+
includesTranscripts,
|
|
87
|
+
files: manifestFiles,
|
|
88
|
+
capsule
|
|
89
|
+
});
|
|
90
|
+
const bundle = ExportBundleV2Schema.parse({
|
|
91
|
+
manifest,
|
|
92
|
+
records
|
|
93
|
+
});
|
|
94
|
+
const archivePath = path.join(outDirAbs, `${opts.name}.capsule.json.gz`);
|
|
95
|
+
const manifestPath = path.join(outDirAbs, `${opts.name}.manifest.json`);
|
|
96
|
+
await writeJsonFile(manifestPath, manifest);
|
|
97
|
+
const json = JSON.stringify(bundle);
|
|
98
|
+
const gz = gzipSync(Buffer.from(json, "utf-8"));
|
|
99
|
+
await writeFile(archivePath, gz);
|
|
100
|
+
if (opts.encrypt === true) {
|
|
101
|
+
if (!opts.memoryDir) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"exportCapsule: 'memoryDir' is required when 'encrypt' is true so the secure-store key can be retrieved."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
const { encPath } = await encryptCapsuleFile({
|
|
107
|
+
sourceGzPath: archivePath,
|
|
108
|
+
memoryDir: opts.memoryDir
|
|
109
|
+
});
|
|
110
|
+
const { unlink } = await import("fs/promises");
|
|
111
|
+
await unlink(archivePath);
|
|
112
|
+
return { archivePath: encPath, manifestPath, manifest, encryptedArchivePath: encPath };
|
|
113
|
+
}
|
|
114
|
+
return { archivePath, manifestPath, manifest, encryptedArchivePath: null };
|
|
115
|
+
}
|
|
116
|
+
function validateName(name) {
|
|
117
|
+
if (typeof name !== "string" || !CAPSULE_ID_PATTERN.test(name)) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
`exportCapsule: invalid capsule name. Expected /${CAPSULE_ID_PATTERN.source}/`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (name.length > 64) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
"exportCapsule: invalid capsule name. Must be 64 characters or fewer."
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
var ISO_8601_RE = /^\d{4}-\d{2}-\d{2}(?:[Tt]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:[Zz]|[+-]\d{2}:?\d{2}))?$/;
|
|
129
|
+
function parseSince(since) {
|
|
130
|
+
if (since === void 0) return null;
|
|
131
|
+
if (typeof since !== "string" || since.trim() === "") {
|
|
132
|
+
throw new Error("exportCapsule: 'since' must be a non-empty ISO-8601 string");
|
|
133
|
+
}
|
|
134
|
+
if (!ISO_8601_RE.test(since)) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
const ms = Date.parse(since);
|
|
140
|
+
if (!Number.isFinite(ms)) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
assertCalendarRoundTrip(since, ms);
|
|
146
|
+
return ms;
|
|
147
|
+
}
|
|
148
|
+
function assertCalendarRoundTrip(since, ms) {
|
|
149
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(since);
|
|
150
|
+
if (!m) return;
|
|
151
|
+
const wantY = Number(m[1]);
|
|
152
|
+
const wantMo = Number(m[2]);
|
|
153
|
+
const wantD = Number(m[3]);
|
|
154
|
+
const offsetMatch = /([+-])(\d{2}):?(\d{2})$/.exec(since);
|
|
155
|
+
let displayMs = ms;
|
|
156
|
+
if (offsetMatch) {
|
|
157
|
+
const sign = offsetMatch[1] === "-" ? -1 : 1;
|
|
158
|
+
const offsetMin = sign * (Number(offsetMatch[2]) * 60 + Number(offsetMatch[3]));
|
|
159
|
+
displayMs = ms + offsetMin * 6e4;
|
|
160
|
+
}
|
|
161
|
+
const dd = new Date(displayMs);
|
|
162
|
+
const gotY = dd.getUTCFullYear();
|
|
163
|
+
const gotMo = dd.getUTCMonth() + 1;
|
|
164
|
+
const gotD = dd.getUTCDate();
|
|
165
|
+
if (gotY !== wantY || gotMo !== wantMo || gotD !== wantD) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function normalizeIncludeKinds(kinds) {
|
|
172
|
+
if (kinds === void 0) return null;
|
|
173
|
+
const set = /* @__PURE__ */ new Set();
|
|
174
|
+
for (const raw of kinds) {
|
|
175
|
+
if (typeof raw !== "string" || raw.trim() === "") {
|
|
176
|
+
throw new Error("exportCapsule: 'includeKinds' entries must be non-empty strings");
|
|
177
|
+
}
|
|
178
|
+
if (raw.includes("/") || raw.includes("\\")) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
`exportCapsule: 'includeKinds' entries must be top-level segment names, got: ${raw}`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
set.add(raw);
|
|
184
|
+
}
|
|
185
|
+
return set;
|
|
186
|
+
}
|
|
187
|
+
function normalizePeerIds(peerIds) {
|
|
188
|
+
if (peerIds === void 0) return null;
|
|
189
|
+
const set = /* @__PURE__ */ new Set();
|
|
190
|
+
for (const raw of peerIds) {
|
|
191
|
+
if (typeof raw !== "string" || raw.trim() === "") {
|
|
192
|
+
throw new Error("exportCapsule: 'peerIds' entries must be non-empty strings");
|
|
193
|
+
}
|
|
194
|
+
if (raw.includes("/") || raw.includes("\\") || raw === "." || raw === "..") {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`exportCapsule: 'peerIds' entries must be plain segment names, got: ${raw}`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
set.add(raw);
|
|
200
|
+
}
|
|
201
|
+
return set;
|
|
202
|
+
}
|
|
203
|
+
function computeOutDirRel(rootAbs, outDirAbs) {
|
|
204
|
+
const rel = path.relative(rootAbs, outDirAbs);
|
|
205
|
+
if (rel === "") return null;
|
|
206
|
+
if (rel === ".." || rel.startsWith(`..${path.sep}`)) return null;
|
|
207
|
+
if (path.isAbsolute(rel)) return null;
|
|
208
|
+
return rel.split(path.sep).join("/");
|
|
209
|
+
}
|
|
210
|
+
async function assertIsDirectory(absPath) {
|
|
211
|
+
const st = await stat(absPath).catch(() => null);
|
|
212
|
+
if (!st || !st.isDirectory()) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`exportCapsule: 'root' must be an existing directory: ${absPath}`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function shouldInclude(relPosix, includeKinds, peerFilter, outDirRelPosix, transcriptsOverride = false) {
|
|
219
|
+
const parts = relPosix.split("/");
|
|
220
|
+
if (parts.some((p) => DEFAULT_EXCLUDE_DIRS.has(p))) return false;
|
|
221
|
+
if (outDirRelPosix !== null) {
|
|
222
|
+
if (relPosix === outDirRelPosix) return false;
|
|
223
|
+
if (relPosix.startsWith(`${outDirRelPosix}/`)) return false;
|
|
224
|
+
}
|
|
225
|
+
const top = parts[0];
|
|
226
|
+
if (top === TRANSCRIPTS_DIR && !transcriptsOverride && (includeKinds === null || !includeKinds.has(TRANSCRIPTS_DIR))) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
if (includeKinds !== null) {
|
|
230
|
+
if (parts.length < 2) return false;
|
|
231
|
+
if (!includeKinds.has(top)) return false;
|
|
232
|
+
}
|
|
233
|
+
if (top === PEERS_DIR && peerFilter !== null) {
|
|
234
|
+
if (peerFilter.size === 0) return false;
|
|
235
|
+
if (parts.length < 2) return false;
|
|
236
|
+
if (!peerFilter.has(parts[1])) return false;
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
function buildCapsuleBlock(name, override) {
|
|
241
|
+
const parent = override?.parent ?? null;
|
|
242
|
+
const parentCapsule = override && Object.prototype.hasOwnProperty.call(override, "parentCapsule") ? override.parentCapsule ?? null : parent?.capsuleId ?? null;
|
|
243
|
+
const merged = {
|
|
244
|
+
id: name,
|
|
245
|
+
version: override?.version ?? "0.1.0",
|
|
246
|
+
schemaVersion: override?.schemaVersion ?? "taxonomy-v1",
|
|
247
|
+
parentCapsule,
|
|
248
|
+
parent,
|
|
249
|
+
description: override?.description ?? "",
|
|
250
|
+
retrievalPolicy: override?.retrievalPolicy ?? {
|
|
251
|
+
tierWeights: {},
|
|
252
|
+
directAnswerEnabled: false
|
|
253
|
+
},
|
|
254
|
+
includes: override?.includes ?? {
|
|
255
|
+
taxonomy: false,
|
|
256
|
+
identityAnchors: false,
|
|
257
|
+
peerProfiles: false,
|
|
258
|
+
procedural: false
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
return CapsuleBlockSchema.parse(merged);
|
|
262
|
+
}
|
|
263
|
+
export {
|
|
264
|
+
exportCapsule
|
|
265
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
importCapsule
|
|
3
|
+
} from "./chunk-ETJZRIAM.js";
|
|
4
|
+
import "./chunk-K7EUBNDD.js";
|
|
5
|
+
import "./chunk-NKVIN6RD.js";
|
|
6
|
+
import "./chunk-SSFTU6LP.js";
|
|
7
|
+
import "./chunk-XMSDA5WA.js";
|
|
8
|
+
import "./chunk-CXM7EBAO.js";
|
|
9
|
+
import "./chunk-JZBOXOUC.js";
|
|
10
|
+
import "./chunk-6IWEAUN6.js";
|
|
11
|
+
import "./chunk-6OJAU466.js";
|
|
12
|
+
import "./chunk-YGGGUTG3.js";
|
|
13
|
+
import "./chunk-MLKGABMK.js";
|
|
14
|
+
export {
|
|
15
|
+
importCapsule
|
|
16
|
+
};
|