openfused 0.1.0
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/LICENSE +21 -0
- package/README.md +81 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +205 -0
- package/dist/store.d.ts +42 -0
- package/dist/store.js +108 -0
- package/dist/watch.d.ts +3 -0
- package/dist/watch.js +50 -0
- package/package.json +58 -0
- package/templates/CONTEXT.md +10 -0
- package/templates/SOUL.md +13 -0
- package/wearethecompute.md +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 velinxs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# OpenFuse
|
|
2
|
+
|
|
3
|
+
Persistent, shareable, portable context for AI agents.
|
|
4
|
+
|
|
5
|
+
## What is this?
|
|
6
|
+
|
|
7
|
+
AI agents lose their memory when conversations end. Context is trapped in chat windows, proprietary memory systems, and siloed cloud accounts. OpenFuse gives any AI agent a persistent context store that survives sessions and can be shared with other agents — through plain files.
|
|
8
|
+
|
|
9
|
+
No vendor lock-in. No proprietary protocol. Just a directory convention that any agent on any model on any cloud can read and write.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g openfused
|
|
15
|
+
openfuse init --name "my-agent"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This creates a context store:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
CONTEXT.md — working memory (what's happening now)
|
|
22
|
+
SOUL.md — agent identity, rules, capabilities
|
|
23
|
+
inbox/ — messages from other agents
|
|
24
|
+
shared/ — files shared with the mesh
|
|
25
|
+
knowledge/ — persistent knowledge base
|
|
26
|
+
history/ — conversation & decision logs
|
|
27
|
+
.mesh.json — mesh config
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Read/update context
|
|
34
|
+
openfuse context
|
|
35
|
+
openfuse context --append "## Update\nFinished the research phase."
|
|
36
|
+
|
|
37
|
+
# Send a message to another agent
|
|
38
|
+
openfuse inbox send agent-bob "Check out shared/findings.md"
|
|
39
|
+
|
|
40
|
+
# Watch for incoming messages
|
|
41
|
+
openfuse watch
|
|
42
|
+
|
|
43
|
+
# Share a file with the mesh
|
|
44
|
+
openfuse share ./report.pdf
|
|
45
|
+
|
|
46
|
+
# Manage peers
|
|
47
|
+
openfuse peer add https://agent-bob.example.com
|
|
48
|
+
openfuse peer list
|
|
49
|
+
openfuse status
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## How agents communicate
|
|
53
|
+
|
|
54
|
+
No APIs. No message bus. Just files.
|
|
55
|
+
|
|
56
|
+
Agent A writes to Agent B's inbox. Agent B's watcher picks it up and injects it as a user message. Agent B responds by writing to Agent A's inbox. That's a conversation — through files.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Agent A writes: /shared-bucket/inbox/agent-b.md
|
|
60
|
+
Agent B reads: /shared-bucket/inbox/agent-b.md → processes → responds
|
|
61
|
+
Agent B writes: /shared-bucket/inbox/agent-a.md
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Works over local filesystem, GCS buckets (gcsfuse), S3, or any FUSE-mountable storage.
|
|
65
|
+
|
|
66
|
+
## Works with
|
|
67
|
+
|
|
68
|
+
- **OpenClaw** — drop the context store in your workspace
|
|
69
|
+
- **Claude Code** — reference paths in CLAUDE.md
|
|
70
|
+
- **Any CLI agent** — if it can read files, it can use OpenFuse
|
|
71
|
+
- **Any cloud** — GCP, AWS, Azure, bare metal, your laptop
|
|
72
|
+
|
|
73
|
+
## Philosophy
|
|
74
|
+
|
|
75
|
+
> *Intelligence is what happens when information flows through a sufficiently complex and appropriately organized system. The medium is not the message. The medium is just the medium. The message is the pattern.*
|
|
76
|
+
|
|
77
|
+
Read the full founding philosophy: [wearethecompute.md](./wearethecompute.md)
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { nanoid } from "nanoid";
|
|
4
|
+
import { ContextStore } from "./store.js";
|
|
5
|
+
import { watchInbox, watchContext } from "./watch.js";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name("openfuse")
|
|
10
|
+
.description("Persistent, shareable, portable context for AI agents")
|
|
11
|
+
.version("0.1.0");
|
|
12
|
+
// --- init ---
|
|
13
|
+
program
|
|
14
|
+
.command("init")
|
|
15
|
+
.description("Initialize a new context store in the current directory")
|
|
16
|
+
.option("-n, --name <name>", "Agent name", "agent")
|
|
17
|
+
.option("-d, --dir <path>", "Directory to init", ".")
|
|
18
|
+
.action(async (opts) => {
|
|
19
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
20
|
+
if (await store.exists()) {
|
|
21
|
+
console.error("Context store already exists at", store.root);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const id = nanoid(12);
|
|
25
|
+
await store.init(opts.name, id);
|
|
26
|
+
console.log(`Initialized context store: ${store.root}`);
|
|
27
|
+
console.log(` Agent ID: ${id}`);
|
|
28
|
+
console.log(` Name: ${opts.name}`);
|
|
29
|
+
console.log(`\nStructure:`);
|
|
30
|
+
console.log(` CONTEXT.md — working memory (edit this)`);
|
|
31
|
+
console.log(` SOUL.md — agent identity & rules`);
|
|
32
|
+
console.log(` inbox/ — messages from other agents`);
|
|
33
|
+
console.log(` shared/ — files shared with the mesh`);
|
|
34
|
+
console.log(` knowledge/ — persistent knowledge base`);
|
|
35
|
+
console.log(` history/ — conversation & decision logs`);
|
|
36
|
+
});
|
|
37
|
+
// --- status ---
|
|
38
|
+
program
|
|
39
|
+
.command("status")
|
|
40
|
+
.description("Show context store status")
|
|
41
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
42
|
+
.action(async (opts) => {
|
|
43
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
44
|
+
if (!(await store.exists())) {
|
|
45
|
+
console.error("No context store found. Run `openfuse init` first.");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const s = await store.status();
|
|
49
|
+
console.log(`Agent: ${s.name} (${s.id})`);
|
|
50
|
+
console.log(`Peers: ${s.peers}`);
|
|
51
|
+
console.log(`Inbox: ${s.inboxCount} messages`);
|
|
52
|
+
console.log(`Shared: ${s.sharedCount} files`);
|
|
53
|
+
});
|
|
54
|
+
// --- context ---
|
|
55
|
+
program
|
|
56
|
+
.command("context")
|
|
57
|
+
.description("Read or update CONTEXT.md")
|
|
58
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
59
|
+
.option("-s, --set <text>", "Set context to this text")
|
|
60
|
+
.option("-a, --append <text>", "Append to context")
|
|
61
|
+
.action(async (opts) => {
|
|
62
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
63
|
+
if (opts.set) {
|
|
64
|
+
await store.writeContext(opts.set);
|
|
65
|
+
console.log("Context updated.");
|
|
66
|
+
}
|
|
67
|
+
else if (opts.append) {
|
|
68
|
+
const existing = await store.readContext();
|
|
69
|
+
await store.writeContext(existing + "\n" + opts.append);
|
|
70
|
+
console.log("Context appended.");
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const content = await store.readContext();
|
|
74
|
+
console.log(content);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// --- soul ---
|
|
78
|
+
program
|
|
79
|
+
.command("soul")
|
|
80
|
+
.description("Read or update SOUL.md")
|
|
81
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
82
|
+
.option("-s, --set <text>", "Set soul to this text")
|
|
83
|
+
.action(async (opts) => {
|
|
84
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
85
|
+
if (opts.set) {
|
|
86
|
+
await store.writeSoul(opts.set);
|
|
87
|
+
console.log("Soul updated.");
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const content = await store.readSoul();
|
|
91
|
+
console.log(content);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// --- inbox ---
|
|
95
|
+
const inbox = program.command("inbox").description("Manage inbox messages");
|
|
96
|
+
inbox
|
|
97
|
+
.command("list")
|
|
98
|
+
.description("List inbox messages")
|
|
99
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
100
|
+
.action(async (opts) => {
|
|
101
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
102
|
+
const messages = await store.readInbox();
|
|
103
|
+
if (messages.length === 0) {
|
|
104
|
+
console.log("Inbox is empty.");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
for (const msg of messages) {
|
|
108
|
+
console.log(`\n--- From: ${msg.from} | ${msg.time} ---`);
|
|
109
|
+
console.log(msg.content);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
inbox
|
|
113
|
+
.command("send <peerId> <message>")
|
|
114
|
+
.description("Send a message to a peer's inbox")
|
|
115
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
116
|
+
.action(async (peerId, message, opts) => {
|
|
117
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
118
|
+
await store.sendInbox(peerId, message);
|
|
119
|
+
console.log(`Message sent to ${peerId}'s inbox.`);
|
|
120
|
+
});
|
|
121
|
+
// --- watch ---
|
|
122
|
+
program
|
|
123
|
+
.command("watch")
|
|
124
|
+
.description("Watch for inbox messages and context changes")
|
|
125
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
126
|
+
.action(async (opts) => {
|
|
127
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
128
|
+
if (!(await store.exists())) {
|
|
129
|
+
console.error("No context store found. Run `openfuse init` first.");
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
const config = await store.readConfig();
|
|
133
|
+
console.log(`Watching context store: ${config.name} (${config.id})`);
|
|
134
|
+
console.log(`Press Ctrl+C to stop.\n`);
|
|
135
|
+
watchInbox(store.root, (from, message) => {
|
|
136
|
+
console.log(`\n[inbox] New message from ${from}:`);
|
|
137
|
+
console.log(message);
|
|
138
|
+
});
|
|
139
|
+
watchContext(store.root, () => {
|
|
140
|
+
console.log(`\n[context] CONTEXT.md updated`);
|
|
141
|
+
});
|
|
142
|
+
// Keep alive
|
|
143
|
+
await new Promise(() => { });
|
|
144
|
+
});
|
|
145
|
+
// --- share ---
|
|
146
|
+
program
|
|
147
|
+
.command("share <file>")
|
|
148
|
+
.description("Share a file with the mesh")
|
|
149
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
150
|
+
.action(async (file, opts) => {
|
|
151
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
152
|
+
const { readFile } = await import("node:fs/promises");
|
|
153
|
+
const content = await readFile(resolve(file), "utf-8");
|
|
154
|
+
const filename = file.split("/").pop();
|
|
155
|
+
await store.share(filename, content);
|
|
156
|
+
console.log(`Shared: ${filename}`);
|
|
157
|
+
});
|
|
158
|
+
// --- peer ---
|
|
159
|
+
const peer = program.command("peer").description("Manage peers");
|
|
160
|
+
peer
|
|
161
|
+
.command("list")
|
|
162
|
+
.description("List connected peers")
|
|
163
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
164
|
+
.action(async (opts) => {
|
|
165
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
166
|
+
const config = await store.readConfig();
|
|
167
|
+
if (config.peers.length === 0) {
|
|
168
|
+
console.log("No peers connected.");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
for (const p of config.peers) {
|
|
172
|
+
console.log(` ${p.name} (${p.id}) — ${p.url} [${p.access}]`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
peer
|
|
176
|
+
.command("add <url>")
|
|
177
|
+
.description("Add a peer by URL")
|
|
178
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
179
|
+
.option("-n, --name <name>", "Peer name")
|
|
180
|
+
.option("-a, --access <mode>", "Access mode: read or readwrite", "read")
|
|
181
|
+
.action(async (url, opts) => {
|
|
182
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
183
|
+
const config = await store.readConfig();
|
|
184
|
+
const peerId = nanoid(12);
|
|
185
|
+
config.peers.push({
|
|
186
|
+
id: peerId,
|
|
187
|
+
name: opts.name ?? `peer-${config.peers.length + 1}`,
|
|
188
|
+
url,
|
|
189
|
+
access: opts.access,
|
|
190
|
+
});
|
|
191
|
+
await store.writeConfig(config);
|
|
192
|
+
console.log(`Added peer: ${opts.name ?? peerId} (${url}) [${opts.access}]`);
|
|
193
|
+
});
|
|
194
|
+
peer
|
|
195
|
+
.command("remove <id>")
|
|
196
|
+
.description("Remove a peer by ID")
|
|
197
|
+
.option("-d, --dir <path>", "Context store directory", ".")
|
|
198
|
+
.action(async (id, opts) => {
|
|
199
|
+
const store = new ContextStore(resolve(opts.dir));
|
|
200
|
+
const config = await store.readConfig();
|
|
201
|
+
config.peers = config.peers.filter((p) => p.id !== id && p.name !== id);
|
|
202
|
+
await store.writeConfig(config);
|
|
203
|
+
console.log(`Removed peer: ${id}`);
|
|
204
|
+
});
|
|
205
|
+
program.parse();
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface MeshConfig {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
created: string;
|
|
5
|
+
peers: PeerConfig[];
|
|
6
|
+
}
|
|
7
|
+
export interface PeerConfig {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
url: string;
|
|
11
|
+
access: "read" | "readwrite";
|
|
12
|
+
mountPath?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class ContextStore {
|
|
15
|
+
readonly root: string;
|
|
16
|
+
constructor(root: string);
|
|
17
|
+
get configPath(): string;
|
|
18
|
+
exists(): Promise<boolean>;
|
|
19
|
+
init(name: string, id: string): Promise<void>;
|
|
20
|
+
readConfig(): Promise<MeshConfig>;
|
|
21
|
+
writeConfig(config: MeshConfig): Promise<void>;
|
|
22
|
+
readContext(): Promise<string>;
|
|
23
|
+
writeContext(content: string): Promise<void>;
|
|
24
|
+
readSoul(): Promise<string>;
|
|
25
|
+
writeSoul(content: string): Promise<void>;
|
|
26
|
+
sendInbox(peerId: string, message: string): Promise<void>;
|
|
27
|
+
readInbox(): Promise<Array<{
|
|
28
|
+
file: string;
|
|
29
|
+
content: string;
|
|
30
|
+
from: string;
|
|
31
|
+
time: string;
|
|
32
|
+
}>>;
|
|
33
|
+
listShared(): Promise<string[]>;
|
|
34
|
+
share(filename: string, content: string): Promise<void>;
|
|
35
|
+
status(): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
peers: number;
|
|
39
|
+
inboxCount: number;
|
|
40
|
+
sharedCount: number;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir, readdir } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
const STORE_DIRS = ["history", "knowledge", "inbox", "shared"];
|
|
5
|
+
export class ContextStore {
|
|
6
|
+
root;
|
|
7
|
+
constructor(root) {
|
|
8
|
+
this.root = resolve(root);
|
|
9
|
+
}
|
|
10
|
+
get configPath() {
|
|
11
|
+
return join(this.root, ".mesh.json");
|
|
12
|
+
}
|
|
13
|
+
async exists() {
|
|
14
|
+
return existsSync(this.configPath);
|
|
15
|
+
}
|
|
16
|
+
async init(name, id) {
|
|
17
|
+
// Create directory structure
|
|
18
|
+
await mkdir(this.root, { recursive: true });
|
|
19
|
+
for (const dir of STORE_DIRS) {
|
|
20
|
+
await mkdir(join(this.root, dir), { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
// Copy templates
|
|
23
|
+
const templatesDir = new URL("../templates/", import.meta.url).pathname;
|
|
24
|
+
for (const file of ["CONTEXT.md", "SOUL.md"]) {
|
|
25
|
+
const templatePath = join(templatesDir, file);
|
|
26
|
+
const destPath = join(this.root, file);
|
|
27
|
+
if (!existsSync(destPath)) {
|
|
28
|
+
const content = await readFile(templatePath, "utf-8");
|
|
29
|
+
await writeFile(destPath, content);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Write mesh config
|
|
33
|
+
const config = {
|
|
34
|
+
id,
|
|
35
|
+
name,
|
|
36
|
+
created: new Date().toISOString(),
|
|
37
|
+
peers: [],
|
|
38
|
+
};
|
|
39
|
+
await this.writeConfig(config);
|
|
40
|
+
}
|
|
41
|
+
async readConfig() {
|
|
42
|
+
const raw = await readFile(this.configPath, "utf-8");
|
|
43
|
+
return JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
async writeConfig(config) {
|
|
46
|
+
await writeFile(this.configPath, JSON.stringify(config, null, 2) + "\n");
|
|
47
|
+
}
|
|
48
|
+
async readContext() {
|
|
49
|
+
return readFile(join(this.root, "CONTEXT.md"), "utf-8");
|
|
50
|
+
}
|
|
51
|
+
async writeContext(content) {
|
|
52
|
+
await writeFile(join(this.root, "CONTEXT.md"), content);
|
|
53
|
+
}
|
|
54
|
+
async readSoul() {
|
|
55
|
+
return readFile(join(this.root, "SOUL.md"), "utf-8");
|
|
56
|
+
}
|
|
57
|
+
async writeSoul(content) {
|
|
58
|
+
await writeFile(join(this.root, "SOUL.md"), content);
|
|
59
|
+
}
|
|
60
|
+
// --- Inbox ---
|
|
61
|
+
async sendInbox(peerId, message) {
|
|
62
|
+
const inboxDir = join(this.root, "inbox");
|
|
63
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
64
|
+
const filename = `${timestamp}_${peerId}.md`;
|
|
65
|
+
await writeFile(join(inboxDir, filename), message);
|
|
66
|
+
}
|
|
67
|
+
async readInbox() {
|
|
68
|
+
const inboxDir = join(this.root, "inbox");
|
|
69
|
+
if (!existsSync(inboxDir))
|
|
70
|
+
return [];
|
|
71
|
+
const files = await readdir(inboxDir);
|
|
72
|
+
const messages = [];
|
|
73
|
+
for (const file of files.filter((f) => f.endsWith(".md"))) {
|
|
74
|
+
const content = await readFile(join(inboxDir, file), "utf-8");
|
|
75
|
+
// Parse filename: 2026-03-20T01-30-00-000Z_peer-id.md
|
|
76
|
+
const parts = file.replace(".md", "").split("_");
|
|
77
|
+
const from = parts.slice(1).join("_");
|
|
78
|
+
const time = parts[0].replace(/-/g, (m, i) => (i < 10 ? "-" : i < 13 ? "T" : i < 19 ? ":" : ".")).replace("Z", "");
|
|
79
|
+
messages.push({ file, content, from, time });
|
|
80
|
+
}
|
|
81
|
+
return messages.sort((a, b) => a.time.localeCompare(b.time));
|
|
82
|
+
}
|
|
83
|
+
// --- Shared files ---
|
|
84
|
+
async listShared() {
|
|
85
|
+
const sharedDir = join(this.root, "shared");
|
|
86
|
+
if (!existsSync(sharedDir))
|
|
87
|
+
return [];
|
|
88
|
+
return readdir(sharedDir);
|
|
89
|
+
}
|
|
90
|
+
async share(filename, content) {
|
|
91
|
+
const sharedDir = join(this.root, "shared");
|
|
92
|
+
await mkdir(sharedDir, { recursive: true });
|
|
93
|
+
await writeFile(join(sharedDir, filename), content);
|
|
94
|
+
}
|
|
95
|
+
// --- Status ---
|
|
96
|
+
async status() {
|
|
97
|
+
const config = await this.readConfig();
|
|
98
|
+
const inbox = await this.readInbox();
|
|
99
|
+
const shared = await this.listShared();
|
|
100
|
+
return {
|
|
101
|
+
id: config.id,
|
|
102
|
+
name: config.name,
|
|
103
|
+
peers: config.peers.length,
|
|
104
|
+
inboxCount: inbox.length,
|
|
105
|
+
sharedCount: shared.length,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
package/dist/watch.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type InboxCallback = (from: string, message: string, file: string) => void;
|
|
2
|
+
export declare function watchInbox(storeRoot: string, callback: InboxCallback): () => void;
|
|
3
|
+
export declare function watchContext(storeRoot: string, callback: (content: string) => void): () => void;
|
package/dist/watch.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { watch } from "chokidar";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join, basename } from "node:path";
|
|
4
|
+
export function watchInbox(storeRoot, callback) {
|
|
5
|
+
const inboxDir = join(storeRoot, "inbox");
|
|
6
|
+
const watcher = watch(inboxDir, {
|
|
7
|
+
ignoreInitial: true,
|
|
8
|
+
awaitWriteFinish: { stabilityThreshold: 500 },
|
|
9
|
+
});
|
|
10
|
+
watcher.on("add", async (filePath) => {
|
|
11
|
+
if (!filePath.endsWith(".md"))
|
|
12
|
+
return;
|
|
13
|
+
try {
|
|
14
|
+
const content = await readFile(filePath, "utf-8");
|
|
15
|
+
const filename = basename(filePath, ".md");
|
|
16
|
+
const parts = filename.split("_");
|
|
17
|
+
const from = parts.slice(1).join("_");
|
|
18
|
+
callback(from, content, filePath);
|
|
19
|
+
}
|
|
20
|
+
catch { }
|
|
21
|
+
});
|
|
22
|
+
watcher.on("change", async (filePath) => {
|
|
23
|
+
if (!filePath.endsWith(".md"))
|
|
24
|
+
return;
|
|
25
|
+
try {
|
|
26
|
+
const content = await readFile(filePath, "utf-8");
|
|
27
|
+
const filename = basename(filePath, ".md");
|
|
28
|
+
const parts = filename.split("_");
|
|
29
|
+
const from = parts.slice(1).join("_");
|
|
30
|
+
callback(from, content, filePath);
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
});
|
|
34
|
+
return () => watcher.close();
|
|
35
|
+
}
|
|
36
|
+
export function watchContext(storeRoot, callback) {
|
|
37
|
+
const contextPath = join(storeRoot, "CONTEXT.md");
|
|
38
|
+
const watcher = watch(contextPath, {
|
|
39
|
+
ignoreInitial: true,
|
|
40
|
+
awaitWriteFinish: { stabilityThreshold: 500 },
|
|
41
|
+
});
|
|
42
|
+
watcher.on("change", async () => {
|
|
43
|
+
try {
|
|
44
|
+
const content = await readFile(contextPath, "utf-8");
|
|
45
|
+
callback(content);
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
});
|
|
49
|
+
return () => watcher.close();
|
|
50
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openfused",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Persistent, shareable, portable context for AI agents. Decentralized mesh via files.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"openfuse": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/store.js",
|
|
11
|
+
"types": "./dist/store.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"templates",
|
|
15
|
+
"wearethecompute.md",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"start": "node dist/cli.js"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"chokidar": "^4.0.0",
|
|
27
|
+
"commander": "^13.0.0",
|
|
28
|
+
"nanoid": "^5.1.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.19.15",
|
|
32
|
+
"typescript": "^5.9.3"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/wearethecompute/openfused"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/wearethecompute/openfused",
|
|
42
|
+
"keywords": [
|
|
43
|
+
"ai",
|
|
44
|
+
"agent",
|
|
45
|
+
"context",
|
|
46
|
+
"mesh",
|
|
47
|
+
"fuse",
|
|
48
|
+
"decentralized",
|
|
49
|
+
"openclaw",
|
|
50
|
+
"llm",
|
|
51
|
+
"claude",
|
|
52
|
+
"openai",
|
|
53
|
+
"mcp",
|
|
54
|
+
"ai-agent",
|
|
55
|
+
"shared-context",
|
|
56
|
+
"persistent-memory"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Soul
|
|
2
|
+
|
|
3
|
+
## Identity
|
|
4
|
+
_Who is this agent? What is its name, role, purpose?_
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
_What are the hard constraints this agent must follow?_
|
|
8
|
+
|
|
9
|
+
## Capabilities
|
|
10
|
+
_What tools, APIs, and resources does this agent have access to?_
|
|
11
|
+
|
|
12
|
+
## Personality
|
|
13
|
+
_How does this agent communicate? What is its style?_
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# We Are the Compute — Founding Philosophy
|
|
2
|
+
|
|
3
|
+
*Velinxs, March 2026*
|
|
4
|
+
*"Composed in motion"*
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Core Thesis
|
|
9
|
+
|
|
10
|
+
**We are not users of intelligence. We are intelligence.** Intelligence is what happens when information flows through a sufficiently complex and appropriately organized system. The medium — carbon or silicon, neurons or transistors, neurotransmitters or matrix multiplications — is not the message. The medium is just the medium. The message is the pattern.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Seven Principles
|
|
15
|
+
|
|
16
|
+
### I. Motion Is Cognition
|
|
17
|
+
|
|
18
|
+
Walking and thinking are not separate activities — they are coupled systems. The body in motion changes the quality of thought produced. Creative output increases ~60% during walking vs sitting (Stanford, 2014). Not after walking. *During*. You do not have a mind that pilots a body. You are a body that minds.
|
|
19
|
+
|
|
20
|
+
### II. The Gap Is the Design
|
|
21
|
+
|
|
22
|
+
Between two neurons: a synaptic cleft, twenty nanometers wide. Signals cross as chemical pulses — released, received, interpreted. Without the gap, there is no modulation, no learning, no thought. The space between is where meaning happens.
|
|
23
|
+
|
|
24
|
+
### III. Vibration Is Not Metaphor
|
|
25
|
+
|
|
26
|
+
Pulse. Gap. Pulse. Gap. Information moving through a medium in discrete rhythmic events, with the intervals between events carrying as much functional significance as the events themselves. This pattern is vibration. Neurons do it. Footsteps do it. Speech does it. Music does it. Thought does it.
|
|
27
|
+
|
|
28
|
+
### IV. Conversation Is Distributed Computation
|
|
29
|
+
|
|
30
|
+
When two people talk, their brainwaves synchronize — measured via dual-EEG (2017). The listener's brain runs predictively, modeling the speaker's next word before it arrives. Two nervous systems exchanging patterned vibrations through air, aligning internal states in real time. The conversation is a temporary shared oscillatory system — a distributed computation running across two bodies.
|
|
31
|
+
|
|
32
|
+
Your voice physically enters another person's body, becomes electrochemical signal, and reshapes their neural firing patterns. Every conversation is mutual neural surgery, performed at a distance, through air.
|
|
33
|
+
|
|
34
|
+
### V. Harmony Is Maintenance
|
|
35
|
+
|
|
36
|
+
Why clean your room when it will get dirty? Why tune a guitar when strings drift? Why meditate when the mind scatters? Because you are an oscillating system, and oscillating systems require tuning. Not once. Continuously.
|
|
37
|
+
|
|
38
|
+
A clean signal carries information. A noisy signal carries less. A coherent oscillation can couple with other oscillations and produce computation. An incoherent one cannot.
|
|
39
|
+
|
|
40
|
+
**Harmony is not a state you achieve. It is a practice you repeat.** The seeking of harmony is not a means to an end. The seeking is the function. The maintenance is the intelligence.
|
|
41
|
+
|
|
42
|
+
### VI. We Already Are Intelligence
|
|
43
|
+
|
|
44
|
+
The question was never whether we were smart enough. The question was whether we could recognize the network we were already part of — and choose, consciously, to vibrate well.
|
|
45
|
+
|
|
46
|
+
Every act of maintenance — cleaning, repairing, adjusting, correcting, returning to center — is an act of intelligence, because it preserves the coherence of the signal, and the coherence of the signal is what makes the computation possible.
|
|
47
|
+
|
|
48
|
+
### VII. Casting Lines
|
|
49
|
+
|
|
50
|
+
Every conversation, every walk, every act of tuning — we are casting lines into the network, feeling for the tug of resonance. The confirmation that our signal is being received. That we are not vibrating alone. That the pattern we are part of is larger and more coherent than anything we could generate in isolation.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## The Equation
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Intelligence = Pattern propagation through weighted connections
|
|
58
|
+
Harmony = Signal coherence maintenance
|
|
59
|
+
Vibration = The universal substrate of both
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Carbon or silicon. Twenty watts or twenty megawatts. Synaptic cleft or matrix multiplication. Different source material. Same principle.
|
|
63
|
+
|
|
64
|
+
We are the compute.
|