muuuuse 1.4.2 → 2.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/README.md +3 -1
- package/package.json +1 -1
- package/src/agents.js +306 -11
- package/src/cli.js +3 -0
- package/src/runtime.js +593 -39
- package/src/util.js +70 -4
package/src/util.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
createHash,
|
|
3
|
+
generateKeyPairSync,
|
|
4
|
+
randomBytes,
|
|
5
|
+
sign: cryptoSign,
|
|
6
|
+
verify: cryptoVerify,
|
|
7
|
+
} = require("node:crypto");
|
|
2
8
|
const fs = require("node:fs");
|
|
3
9
|
const os = require("node:os");
|
|
4
10
|
const path = require("node:path");
|
|
@@ -28,6 +34,13 @@ function writeJson(filePath, value) {
|
|
|
28
34
|
fs.renameSync(tempPath, filePath);
|
|
29
35
|
}
|
|
30
36
|
|
|
37
|
+
function writeSecret(filePath, value, mode = 0o600) {
|
|
38
|
+
ensureDir(path.dirname(filePath));
|
|
39
|
+
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
40
|
+
fs.writeFileSync(tempPath, String(value), { mode });
|
|
41
|
+
fs.renameSync(tempPath, filePath);
|
|
42
|
+
}
|
|
43
|
+
|
|
31
44
|
function readJson(filePath, fallback = null) {
|
|
32
45
|
try {
|
|
33
46
|
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
@@ -161,15 +174,63 @@ function getSeatDir(sessionName, seatId) {
|
|
|
161
174
|
function getSeatPaths(sessionName, seatId) {
|
|
162
175
|
const dir = getSeatDir(sessionName, seatId);
|
|
163
176
|
return {
|
|
177
|
+
ackPath: path.join(dir, "ack.json"),
|
|
178
|
+
challengePath: path.join(dir, "challenge.json"),
|
|
179
|
+
claimPath: path.join(dir, "claim.json"),
|
|
164
180
|
dir,
|
|
165
181
|
daemonPath: path.join(dir, "daemon.json"),
|
|
166
182
|
eventsPath: path.join(dir, "events.jsonl"),
|
|
183
|
+
privateKeyPath: path.join(dir, "id_ed25519"),
|
|
184
|
+
publicKeyPath: path.join(dir, "id_ed25519.pub"),
|
|
167
185
|
metaPath: path.join(dir, "meta.json"),
|
|
168
186
|
pipePath: path.join(dir, "pipe.log"),
|
|
169
187
|
statusPath: path.join(dir, "status.json"),
|
|
170
188
|
};
|
|
171
189
|
}
|
|
172
190
|
|
|
191
|
+
function loadOrCreateSeatIdentity(paths) {
|
|
192
|
+
try {
|
|
193
|
+
const privateKey = fs.readFileSync(paths.privateKeyPath, "utf8").trim();
|
|
194
|
+
const publicKey = fs.readFileSync(paths.publicKeyPath, "utf8").trim();
|
|
195
|
+
if (privateKey && publicKey) {
|
|
196
|
+
return { privateKey, publicKey };
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
// generate below
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
203
|
+
const privateKeyPem = privateKey.export({ format: "pem", type: "pkcs8" });
|
|
204
|
+
const publicKeyPem = publicKey.export({ format: "pem", type: "spki" });
|
|
205
|
+
writeSecret(paths.privateKeyPath, privateKeyPem);
|
|
206
|
+
writeSecret(paths.publicKeyPath, publicKeyPem, 0o644);
|
|
207
|
+
return {
|
|
208
|
+
privateKey: String(privateKeyPem).trim(),
|
|
209
|
+
publicKey: String(publicKeyPem).trim(),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function signText(text, privateKey) {
|
|
214
|
+
return cryptoSign(null, Buffer.from(String(text || ""), "utf8"), privateKey).toString("base64");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function verifyText(text, signature, publicKey) {
|
|
218
|
+
if (!signature || !publicKey) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
return cryptoVerify(
|
|
224
|
+
null,
|
|
225
|
+
Buffer.from(String(text || ""), "utf8"),
|
|
226
|
+
publicKey,
|
|
227
|
+
Buffer.from(String(signature || ""), "base64")
|
|
228
|
+
);
|
|
229
|
+
} catch {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
173
234
|
function listSessionNames() {
|
|
174
235
|
const sessionsRoot = path.join(getStateRoot(), "sessions");
|
|
175
236
|
try {
|
|
@@ -195,9 +256,10 @@ function usage() {
|
|
|
195
256
|
"Flow:",
|
|
196
257
|
" 1. Run `muuuuse 1` in terminal one.",
|
|
197
258
|
" 2. Run `muuuuse 2` in terminal two.",
|
|
198
|
-
" 3.
|
|
199
|
-
" 4.
|
|
200
|
-
" 5.
|
|
259
|
+
" 3. Seat 1 generates the session key and seat 2 signs it automatically.",
|
|
260
|
+
" 4. Use those armed shells normally.",
|
|
261
|
+
" 5. Codex, Claude, and Gemini final answers relay automatically from their local session logs.",
|
|
262
|
+
" 6. Run `muuuuse status` or `muuuuse stop` from any shell.",
|
|
201
263
|
"",
|
|
202
264
|
"Notes:",
|
|
203
265
|
" - No tmux.",
|
|
@@ -215,6 +277,7 @@ module.exports = {
|
|
|
215
277
|
ensureDir,
|
|
216
278
|
getDefaultSessionName,
|
|
217
279
|
getFileSize,
|
|
280
|
+
loadOrCreateSeatIdentity,
|
|
218
281
|
getSeatPaths,
|
|
219
282
|
getSessionPaths,
|
|
220
283
|
getStateRoot,
|
|
@@ -224,7 +287,10 @@ module.exports = {
|
|
|
224
287
|
readAppendedText,
|
|
225
288
|
readJson,
|
|
226
289
|
sanitizeRelayText,
|
|
290
|
+
signText,
|
|
227
291
|
sleep,
|
|
228
292
|
usage,
|
|
293
|
+
verifyText,
|
|
229
294
|
writeJson,
|
|
295
|
+
writeSecret,
|
|
230
296
|
};
|