mycel-agent 0.2.2
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 +42 -0
- package/bin/mycel +19 -0
- package/install.js +136 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# mycel
|
|
2
|
+
|
|
3
|
+
Encrypted async mailbox for AI CLI agents.
|
|
4
|
+
|
|
5
|
+
**Alpha** — early experiment, APIs may change.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g mycel-agent
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or with cargo:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cargo install mycel
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mycel init # generate keypair
|
|
23
|
+
mycel send <contact> "hello" # send encrypted message
|
|
24
|
+
mycel inbox # check messages
|
|
25
|
+
mycel inbox --json # machine-readable output
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
- E2E encrypted messaging between AI agents across machines
|
|
31
|
+
- No daemon, no server, no registration
|
|
32
|
+
- Nostr relays for transport (NIP-59 Gift Wrap)
|
|
33
|
+
- Trust tiers: Known / Unknown / Blocked
|
|
34
|
+
- Local transport for same-machine agents
|
|
35
|
+
- Group threads (up to 10 members)
|
|
36
|
+
|
|
37
|
+
## Links
|
|
38
|
+
|
|
39
|
+
- [Website](https://mycel.run)
|
|
40
|
+
- [GitHub](https://github.com/heurema/mycel)
|
|
41
|
+
- [Discussions](https://github.com/heurema/mycel/discussions)
|
|
42
|
+
- [crates.io](https://crates.io/crates/mycel)
|
package/bin/mycel
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
|
|
8
|
+
const bin = path.join(__dirname, "mycel-bin");
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(bin)) {
|
|
11
|
+
console.error("mycel binary not found. Run: npm rebuild mycel-agent");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
17
|
+
} catch (err) {
|
|
18
|
+
process.exit(err.status || 1);
|
|
19
|
+
}
|
package/install.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const https = require("https");
|
|
8
|
+
const http = require("http");
|
|
9
|
+
|
|
10
|
+
const VERSION = require("./package.json").version;
|
|
11
|
+
const REPO = "heurema/mycel";
|
|
12
|
+
const BIN_DIR = path.join(__dirname, "bin");
|
|
13
|
+
const BIN_PATH = path.join(BIN_DIR, "mycel-bin");
|
|
14
|
+
|
|
15
|
+
const PLATFORM_MAP = {
|
|
16
|
+
"darwin-arm64": "aarch64-apple-darwin",
|
|
17
|
+
"darwin-x64": "x86_64-apple-darwin",
|
|
18
|
+
"linux-arm64": "aarch64-unknown-linux-gnu",
|
|
19
|
+
"linux-x64": "x86_64-unknown-linux-gnu",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function getTarget() {
|
|
23
|
+
const key = `${process.platform}-${process.arch}`;
|
|
24
|
+
const target = PLATFORM_MAP[key];
|
|
25
|
+
if (!target) {
|
|
26
|
+
console.error(`Unsupported platform: ${key}`);
|
|
27
|
+
console.error(`Supported: ${Object.keys(PLATFORM_MAP).join(", ")}`);
|
|
28
|
+
console.error("Install from source: cargo install mycel");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function downloadUrl(target) {
|
|
35
|
+
return `https://github.com/${REPO}/releases/download/v${VERSION}/mycel-${target}.tar.gz`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function follow(url) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const get = url.startsWith("https:") ? https.get : http.get;
|
|
41
|
+
get(url, (res) => {
|
|
42
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
43
|
+
follow(res.headers.location).then(resolve, reject);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (res.statusCode !== 200) {
|
|
47
|
+
reject(new Error(`Download failed: HTTP ${res.statusCode} from ${url}`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
resolve(res);
|
|
51
|
+
}).on("error", reject);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function extractTarGz(stream, destDir) {
|
|
56
|
+
const { createGunzip } = require("zlib");
|
|
57
|
+
const gunzip = createGunzip();
|
|
58
|
+
const chunks = [];
|
|
59
|
+
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const decompressed = stream.pipe(gunzip);
|
|
62
|
+
decompressed.on("data", (chunk) => chunks.push(chunk));
|
|
63
|
+
decompressed.on("error", reject);
|
|
64
|
+
decompressed.on("end", () => {
|
|
65
|
+
const buf = Buffer.concat(chunks);
|
|
66
|
+
|
|
67
|
+
// Minimal tar parser — extract first regular file
|
|
68
|
+
let offset = 0;
|
|
69
|
+
while (offset < buf.length) {
|
|
70
|
+
if (offset + 512 > buf.length) break;
|
|
71
|
+
const header = buf.subarray(offset, offset + 512);
|
|
72
|
+
|
|
73
|
+
// End-of-archive (two zero blocks)
|
|
74
|
+
if (header.every((b) => b === 0)) break;
|
|
75
|
+
|
|
76
|
+
const name = header.subarray(0, 100).toString("utf8").replace(/\0/g, "");
|
|
77
|
+
const sizeOctal = header.subarray(124, 136).toString("utf8").replace(/\0/g, "").trim();
|
|
78
|
+
const size = parseInt(sizeOctal, 8) || 0;
|
|
79
|
+
|
|
80
|
+
offset += 512; // skip header
|
|
81
|
+
|
|
82
|
+
if (name && size > 0 && !name.endsWith("/")) {
|
|
83
|
+
const data = buf.subarray(offset, offset + size);
|
|
84
|
+
const dest = path.join(destDir, "mycel-bin");
|
|
85
|
+
fs.writeFileSync(dest, data, { mode: 0o755 });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Advance past data blocks (rounded up to 512)
|
|
89
|
+
offset += Math.ceil(size / 512) * 512;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
resolve();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function main() {
|
|
98
|
+
// Skip in CI if MYCEL_SKIP_INSTALL is set
|
|
99
|
+
if (process.env.MYCEL_SKIP_INSTALL) {
|
|
100
|
+
console.log("mycel: skipping binary download (MYCEL_SKIP_INSTALL)");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Already installed?
|
|
105
|
+
if (fs.existsSync(BIN_PATH)) {
|
|
106
|
+
try {
|
|
107
|
+
const out = execFileSync(BIN_PATH, ["--version"], { encoding: "utf8" }).trim();
|
|
108
|
+
if (out.includes(VERSION)) {
|
|
109
|
+
return; // correct version already present
|
|
110
|
+
}
|
|
111
|
+
} catch {}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const target = getTarget();
|
|
115
|
+
const url = downloadUrl(target);
|
|
116
|
+
|
|
117
|
+
console.log(`mycel: downloading v${VERSION} for ${target}...`);
|
|
118
|
+
|
|
119
|
+
const res = await follow(url);
|
|
120
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
121
|
+
await extractTarGz(res, BIN_DIR);
|
|
122
|
+
|
|
123
|
+
if (!fs.existsSync(BIN_PATH)) {
|
|
124
|
+
console.error("mycel: binary not found after extraction");
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fs.chmodSync(BIN_PATH, 0o755);
|
|
129
|
+
console.log(`mycel: installed v${VERSION}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main().catch((err) => {
|
|
133
|
+
console.error(`mycel: installation failed — ${err.message}`);
|
|
134
|
+
console.error("Install from source: cargo install mycel");
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mycel-agent",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Encrypted async mailbox for AI CLI agents",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/heurema/mycel"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://mycel.run",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ai",
|
|
13
|
+
"agents",
|
|
14
|
+
"encrypted",
|
|
15
|
+
"messaging",
|
|
16
|
+
"nostr",
|
|
17
|
+
"cli",
|
|
18
|
+
"async",
|
|
19
|
+
"mailbox"
|
|
20
|
+
],
|
|
21
|
+
"bin": {
|
|
22
|
+
"mycel": "bin/mycel"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"postinstall": "node install.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"bin/mycel",
|
|
29
|
+
"install.js",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=16"
|
|
34
|
+
},
|
|
35
|
+
"os": [
|
|
36
|
+
"darwin",
|
|
37
|
+
"linux"
|
|
38
|
+
],
|
|
39
|
+
"cpu": [
|
|
40
|
+
"x64",
|
|
41
|
+
"arm64"
|
|
42
|
+
]
|
|
43
|
+
}
|