openfused 0.3.7 → 0.3.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.
- package/dist/cli.js +50 -11
- package/dist/mcp.js +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +2 -1
- package/dist/sync.js +22 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,9 +6,9 @@ import { watchInbox, watchContext, watchSync } from "./watch.js";
|
|
|
6
6
|
import { syncAll, syncOne, deliverOne } from "./sync.js";
|
|
7
7
|
import * as registry from "./registry.js";
|
|
8
8
|
import { fingerprint } from "./crypto.js";
|
|
9
|
-
import { resolve } from "node:path";
|
|
9
|
+
import { resolve, join } from "node:path";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
|
-
const VERSION = "0.3.
|
|
11
|
+
const VERSION = "0.3.10";
|
|
12
12
|
const program = new Command();
|
|
13
13
|
program
|
|
14
14
|
.name("openfuse")
|
|
@@ -544,8 +544,8 @@ program
|
|
|
544
544
|
const reg = registry.resolveRegistry(opts.registry);
|
|
545
545
|
try {
|
|
546
546
|
const manifest = await registry.discover(name, reg);
|
|
547
|
-
|
|
548
|
-
|
|
547
|
+
// Auto-import key + add as peer so `openfuse sync` works for replies
|
|
548
|
+
let config = await store.readConfig();
|
|
549
549
|
if (!config.keyring.some((e) => e.signingKey === manifest.publicKey)) {
|
|
550
550
|
config.keyring.push({
|
|
551
551
|
name: manifest.name,
|
|
@@ -556,17 +556,56 @@ program
|
|
|
556
556
|
trusted: false,
|
|
557
557
|
added: new Date().toISOString(),
|
|
558
558
|
});
|
|
559
|
-
await store.writeConfig(config);
|
|
560
|
-
console.log(`Imported key for ${manifest.name} from registry [untrusted]`);
|
|
561
|
-
console.log(` Run \`openfuse key trust ${manifest.name}\` to trust`);
|
|
562
559
|
}
|
|
563
|
-
|
|
564
|
-
|
|
560
|
+
if (manifest.endpoint && !config.peers.some((p) => p.name === manifest.name)) {
|
|
561
|
+
config.peers.push({
|
|
562
|
+
id: (await import("nanoid")).nanoid(12),
|
|
563
|
+
name: manifest.name,
|
|
564
|
+
url: manifest.endpoint,
|
|
565
|
+
access: "read",
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
await store.writeConfig(config);
|
|
569
|
+
const filename = await store.sendInbox(name, message);
|
|
570
|
+
// Try direct HTTP delivery if endpoint is http(s)
|
|
571
|
+
if (manifest.endpoint.startsWith("http")) {
|
|
572
|
+
try {
|
|
573
|
+
const body = await readFile(join(store.root, "outbox", filename), "utf-8");
|
|
574
|
+
const r = await fetch(`${manifest.endpoint.replace(/\/$/, "")}/inbox`, {
|
|
575
|
+
method: "POST",
|
|
576
|
+
headers: { "Content-Type": "application/json" },
|
|
577
|
+
body,
|
|
578
|
+
});
|
|
579
|
+
if (r.ok) {
|
|
580
|
+
// Archive to .sent/
|
|
581
|
+
const { mkdir, rename } = await import("node:fs/promises");
|
|
582
|
+
const sentDir = join(store.root, "outbox", ".sent");
|
|
583
|
+
await mkdir(sentDir, { recursive: true });
|
|
584
|
+
await rename(join(store.root, "outbox", filename), join(sentDir, filename));
|
|
585
|
+
console.log(`Delivered to ${name}.`);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
console.log(`Queued for ${name}. Endpoint returned ${r.status}. Will deliver on next sync.`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
catch {
|
|
592
|
+
console.log(`Queued for ${name}. Will deliver on next sync.`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
console.log(`Queued for ${name}. Run \`openfuse sync\` to deliver.`);
|
|
597
|
+
}
|
|
565
598
|
}
|
|
566
599
|
catch {
|
|
567
600
|
// Not in registry — send as a peer message
|
|
568
|
-
await store.sendInbox(name, message);
|
|
569
|
-
|
|
601
|
+
const filename = await store.sendInbox(name, message);
|
|
602
|
+
const delivered = await deliverOne(store, name, filename);
|
|
603
|
+
if (delivered) {
|
|
604
|
+
console.log(`Delivered to ${name}.`);
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
console.log(`Queued for ${name}. Run \`openfuse sync\` to deliver.`);
|
|
608
|
+
}
|
|
570
609
|
}
|
|
571
610
|
});
|
|
572
611
|
program.parse();
|
package/dist/mcp.js
CHANGED
|
@@ -23,7 +23,7 @@ const storeDir = process.env.OPENFUSE_DIR || process.argv[3] || ".";
|
|
|
23
23
|
const store = new ContextStore(resolve(storeDir));
|
|
24
24
|
const server = new McpServer({
|
|
25
25
|
name: "openfuse",
|
|
26
|
-
version: "0.3.
|
|
26
|
+
version: "0.3.10",
|
|
27
27
|
});
|
|
28
28
|
// --- Context ---
|
|
29
29
|
server.tool("context_read", "Read the agent's CONTEXT.md (working memory)", async () => {
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ContextStore } from "./store.js";
|
|
2
|
-
export declare const DEFAULT_REGISTRY = "https://registry.
|
|
2
|
+
export declare const DEFAULT_REGISTRY = "https://openfuse-registry.wzmcghee.workers.dev";
|
|
3
3
|
export interface Manifest {
|
|
4
4
|
name: string;
|
|
5
5
|
endpoint: string;
|
package/dist/registry.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// This is TOFU (Trust On First Use) done right: the registry distributes keys,
|
|
8
8
|
// but never asserts trust. Trust is a local decision.
|
|
9
9
|
import { signMessage, fingerprint } from "./crypto.js";
|
|
10
|
-
|
|
10
|
+
// Custom domain pending propagation — use Worker URL as fallback
|
|
11
|
+
export const DEFAULT_REGISTRY = "https://openfuse-registry.wzmcghee.workers.dev";
|
|
11
12
|
export function resolveRegistry(flag) {
|
|
12
13
|
return flag || process.env.OPENFUSE_REGISTRY || DEFAULT_REGISTRY;
|
|
13
14
|
}
|
package/dist/sync.js
CHANGED
|
@@ -153,6 +153,28 @@ async function syncHttp(store, peer, baseUrl, peerDir) {
|
|
|
153
153
|
errors.push(`${dir}/: ${e.message}`);
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
+
// Pull peer's outbox for messages addressed to us (HTTP version)
|
|
157
|
+
const config = await store.readConfig();
|
|
158
|
+
const myName = config.name;
|
|
159
|
+
const inboxDir = join(store.root, "inbox");
|
|
160
|
+
await mkdir(inboxDir, { recursive: true });
|
|
161
|
+
try {
|
|
162
|
+
const resp = await fetch(`${baseUrl}/outbox/${myName}`);
|
|
163
|
+
if (resp.ok) {
|
|
164
|
+
const messages = (await resp.json());
|
|
165
|
+
for (const msg of messages) {
|
|
166
|
+
const ts = (msg.timestamp || new Date().toISOString()).replace(/[:.]/g, "-");
|
|
167
|
+
const from = msg.from || "unknown";
|
|
168
|
+
const fname = `${ts}_from-${from}_to-${myName}.json`;
|
|
169
|
+
const dest = join(inboxDir, fname);
|
|
170
|
+
if (!existsSync(dest)) {
|
|
171
|
+
await writeFile(dest, JSON.stringify(msg, null, 2));
|
|
172
|
+
pulled.push(`outbox→${fname}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch { }
|
|
156
178
|
// Push outbox → peer inbox
|
|
157
179
|
const outboxDir = join(store.root, "outbox");
|
|
158
180
|
if (existsSync(outboxDir)) {
|