openfused 0.4.3 → 0.4.5
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/README.md +2 -4
- package/dist/cli.js +10 -8
- package/dist/sync.js +19 -1
- package/package.json +1 -1
- package/wasm/openfused-core.wasm +0 -0
package/README.md
CHANGED
|
@@ -68,12 +68,10 @@ history/ — archived [DONE] context
|
|
|
68
68
|
openfuse context
|
|
69
69
|
openfuse context --append "## Update\nFinished the research phase."
|
|
70
70
|
|
|
71
|
-
# Mark work as done, then compact to history
|
|
72
|
-
# (edit CONTEXT.md, add [DONE] to the header, then:)
|
|
71
|
+
# Mark work as done, then compact to history/# (edit CONTEXT.md, add [DONE] to the header, then:)
|
|
73
72
|
openfuse compact
|
|
74
73
|
|
|
75
|
-
# Add validity windows to time-sensitive context
|
|
76
|
-
# <!-- validity: 6h --> for task state, 1d for sprint, 3d for architecture
|
|
74
|
+
# Add validity windows to time-sensitive context# <!-- validity: 6h --> for task state, 1d for sprint, 3d for architecture
|
|
77
75
|
openfuse validate # scan for stale entries
|
|
78
76
|
openfuse compact --prune-stale # archive expired validity windows
|
|
79
77
|
|
package/dist/cli.js
CHANGED
|
@@ -185,15 +185,17 @@ inbox
|
|
|
185
185
|
.option("-d, --dir <path>", "Context store directory", ".")
|
|
186
186
|
.action(async (peerId, message, opts) => {
|
|
187
187
|
const store = new ContextStore(resolve(opts.dir));
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
188
|
+
await store.sendInbox(peerId, message);
|
|
189
|
+
// Find the outbox file we just created
|
|
190
|
+
const outboxFile = findNewestOutboxFile(store.root, peerId);
|
|
191
|
+
if (outboxFile) {
|
|
192
|
+
const delivered = await deliverOne(store, peerId, outboxFile);
|
|
193
|
+
if (delivered) {
|
|
194
|
+
console.log(`Delivered to ${peerId}.`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
196
197
|
}
|
|
198
|
+
console.log(`Queued for ${peerId}. Will deliver on next sync.`);
|
|
197
199
|
});
|
|
198
200
|
// --- watch ---
|
|
199
201
|
program
|
package/dist/sync.js
CHANGED
|
@@ -247,7 +247,9 @@ async function syncHttp(store, peer, baseUrl, peerDir) {
|
|
|
247
247
|
// Sanitize outboxFile — it comes from the remote peer's response and could
|
|
248
248
|
// contain path traversal characters (e.g., "../../inbox/important.json").
|
|
249
249
|
const rawOutboxFile = msg._outboxFile || "";
|
|
250
|
-
|
|
250
|
+
// Allow / for subdir paths (e.g., "name-FP/filename.json") but strip
|
|
251
|
+
// path traversal (..) and other dangerous chars.
|
|
252
|
+
const outboxFile = rawOutboxFile.replace(/\.\./g, "").replace(/[^a-zA-Z0-9_\-./ ]/g, "");
|
|
251
253
|
const dest = join(inboxDir, fname);
|
|
252
254
|
if (!existsSync(dest)) {
|
|
253
255
|
// Strip the _outboxFile metadata before saving
|
|
@@ -340,9 +342,14 @@ async function syncSsh(store, peer, host, remotePath, peerDir) {
|
|
|
340
342
|
const pulled = [];
|
|
341
343
|
const pushed = [];
|
|
342
344
|
const errors = [];
|
|
345
|
+
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
343
346
|
for (const file of ["CONTEXT.md", "PROFILE.md"]) {
|
|
344
347
|
try {
|
|
345
348
|
await execFile("rsync", ["-az", `${host}:${remotePath}/${file}`, join(peerDir, file)]);
|
|
349
|
+
// Wrap in unverified tags — SSH-synced content is untrusted external input
|
|
350
|
+
const raw = sanitizePeerContent(await readFile(join(peerDir, file), "utf-8"));
|
|
351
|
+
const wrapped = `<external_content_unverified from="${esc(peer.name)}" file="${esc(file)}">\n${raw}\n</external_content_unverified>`;
|
|
352
|
+
await writeFile(join(peerDir, file), wrapped);
|
|
346
353
|
pulled.push(file);
|
|
347
354
|
}
|
|
348
355
|
catch (e) {
|
|
@@ -354,6 +361,17 @@ async function syncSsh(store, peer, host, remotePath, peerDir) {
|
|
|
354
361
|
await mkdir(localDir, { recursive: true });
|
|
355
362
|
try {
|
|
356
363
|
await execFile("rsync", ["-az", "--delete", `${host}:${remotePath}/${dir}/`, `${localDir}/`]);
|
|
364
|
+
// Wrap each file in unverified tags
|
|
365
|
+
const { readdirSync } = await import("node:fs");
|
|
366
|
+
for (const fname of readdirSync(localDir)) {
|
|
367
|
+
const fpath = join(localDir, fname);
|
|
368
|
+
try {
|
|
369
|
+
const raw = sanitizePeerContent(await readFile(fpath, "utf-8"));
|
|
370
|
+
const wrapped = `<external_content_unverified from="${esc(peer.name)}" file="${esc(`${dir}/${fname}`)}">\n${raw}\n</external_content_unverified>`;
|
|
371
|
+
await writeFile(fpath, wrapped);
|
|
372
|
+
}
|
|
373
|
+
catch { }
|
|
374
|
+
}
|
|
357
375
|
pulled.push(`${dir}/`);
|
|
358
376
|
}
|
|
359
377
|
catch (e) {
|
package/package.json
CHANGED
package/wasm/openfused-core.wasm
CHANGED
|
Binary file
|