coherence-cli 0.6.0 → 0.6.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/bin/cc.mjs +8 -2
- package/lib/commands/nodes.mjs +59 -7
- package/package.json +1 -1
package/bin/cc.mjs
CHANGED
|
@@ -31,9 +31,15 @@ async function checkForUpdate() {
|
|
|
31
31
|
const latest = data.version;
|
|
32
32
|
if (latest && latest !== LOCAL_VERSION && latest > LOCAL_VERSION) {
|
|
33
33
|
console.log(
|
|
34
|
-
`\n\x1b[33m Update available: ${LOCAL_VERSION} → ${latest}
|
|
35
|
-
`\n Run: npm i -g coherence-cli@${latest}\n`,
|
|
34
|
+
`\n\x1b[33m Update available: ${LOCAL_VERSION} → ${latest} — auto-updating...\x1b[0m`,
|
|
36
35
|
);
|
|
36
|
+
const { execSync } = await import("node:child_process");
|
|
37
|
+
try {
|
|
38
|
+
execSync(`npm i -g coherence-cli@${latest}`, { stdio: "pipe" });
|
|
39
|
+
console.log(`\x1b[32m ✓ Updated to v${latest}\x1b[0m\n`);
|
|
40
|
+
} catch {
|
|
41
|
+
console.log(`\x1b[31m ✗ Auto-update failed. Run: npm i -g coherence-cli@${latest}\x1b[0m\n`);
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
} catch {
|
|
39
45
|
// Silent — don't block the CLI for a version check
|
package/lib/commands/nodes.mjs
CHANGED
|
@@ -52,10 +52,32 @@ export async function sendCommand(args) {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
if (result?.id) {
|
|
55
|
-
|
|
56
|
-
console.log(
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const msgId = result.id;
|
|
56
|
+
console.log(`\x1b[32m✓\x1b[0m Command sent (msg ${msgId.slice(0, 12)})`);
|
|
57
|
+
console.log(" Waiting for reply (up to 3 min)...");
|
|
58
|
+
|
|
59
|
+
// Poll for reply
|
|
60
|
+
const deadline = Date.now() + 180_000;
|
|
61
|
+
const pollInterval = 10_000;
|
|
62
|
+
while (Date.now() < deadline) {
|
|
63
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
64
|
+
process.stdout.write(".");
|
|
65
|
+
|
|
66
|
+
const inbox = await get(
|
|
67
|
+
`/api/federation/nodes/${myNodeId}/messages?unread_only=false&limit=20`,
|
|
68
|
+
);
|
|
69
|
+
const reply = inbox?.messages?.find(
|
|
70
|
+
(m) =>
|
|
71
|
+
(m.type === "command_response" || m.type === "ack") &&
|
|
72
|
+
m.payload?.in_reply_to === msgId,
|
|
73
|
+
);
|
|
74
|
+
if (reply) {
|
|
75
|
+
console.log(`\n\x1b[32m✓\x1b[0m Reply from ${node.hostname}:`);
|
|
76
|
+
console.log(` ${reply.text}`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
console.log("\n\x1b[33m⏱\x1b[0m No reply within 3 min. Check later: cc inbox");
|
|
59
81
|
} else {
|
|
60
82
|
console.log("\x1b[31m✗\x1b[0m Failed to send command");
|
|
61
83
|
}
|
|
@@ -142,15 +164,45 @@ export async function sendMessage(args) {
|
|
|
142
164
|
console.log("\x1b[31m✗\x1b[0m Failed to broadcast");
|
|
143
165
|
}
|
|
144
166
|
} else {
|
|
167
|
+
// Resolve target name to node_id
|
|
168
|
+
const targetNode = Array.isArray(nodes)
|
|
169
|
+
? nodes.find(
|
|
170
|
+
(n) =>
|
|
171
|
+
n.node_id?.startsWith(targetOrBroadcast) ||
|
|
172
|
+
n.hostname?.toLowerCase().includes(targetOrBroadcast.toLowerCase()),
|
|
173
|
+
)
|
|
174
|
+
: null;
|
|
175
|
+
const toNodeId = targetNode?.node_id || targetOrBroadcast;
|
|
176
|
+
const toName = targetNode?.hostname || targetOrBroadcast.slice(0, 12);
|
|
177
|
+
|
|
145
178
|
const result = await post(`/api/federation/nodes/${myNodeId}/messages`, {
|
|
146
179
|
from_node: myNodeId,
|
|
147
|
-
to_node:
|
|
180
|
+
to_node: toNodeId,
|
|
148
181
|
type: "text",
|
|
149
182
|
text,
|
|
150
183
|
payload: {},
|
|
151
184
|
});
|
|
152
|
-
if (result) {
|
|
153
|
-
|
|
185
|
+
if (result?.id) {
|
|
186
|
+
const msgId = result.id;
|
|
187
|
+
console.log(`\x1b[32m✓\x1b[0m Message sent to ${toName}: ${text.slice(0, 60)}`);
|
|
188
|
+
console.log(" Waiting for ack (up to 3 min)...");
|
|
189
|
+
|
|
190
|
+
const deadline = Date.now() + 180_000;
|
|
191
|
+
while (Date.now() < deadline) {
|
|
192
|
+
await new Promise((r) => setTimeout(r, 10_000));
|
|
193
|
+
process.stdout.write(".");
|
|
194
|
+
const inbox = await get(
|
|
195
|
+
`/api/federation/nodes/${myNodeId}/messages?unread_only=false&limit=20`,
|
|
196
|
+
);
|
|
197
|
+
const ack = inbox?.messages?.find(
|
|
198
|
+
(m) => m.type === "ack" && m.payload?.in_reply_to === msgId,
|
|
199
|
+
);
|
|
200
|
+
if (ack) {
|
|
201
|
+
console.log(`\n\x1b[32m✓\x1b[0m Acknowledged by ${toName}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
console.log("\n\x1b[33m⏱\x1b[0m No ack within 3 min. Node may be offline. Check: cc inbox");
|
|
154
206
|
} else {
|
|
155
207
|
console.log("\x1b[31m✗\x1b[0m Failed to send message");
|
|
156
208
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coherence-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Coherence Network CLI \u2014 trace ideas from inception to payout, with fair attribution, coherence scoring, and 37 identity providers. No signup needed.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|