@0dai-dev/cli 2.5.0 → 2.6.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/bin/0dai.js +58 -2
- package/package.json +1 -1
package/bin/0dai.js
CHANGED
|
@@ -7,7 +7,7 @@ const fs = require("fs");
|
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const os = require("os");
|
|
9
9
|
|
|
10
|
-
const VERSION = "2.
|
|
10
|
+
const VERSION = "2.6.0";
|
|
11
11
|
const API_URL = process.env.ODAI_API_URL || "https://api.0dai.dev";
|
|
12
12
|
const T = process.stdout.isTTY ? "\x1b[38;2;45;212;168m" : ""; // teal
|
|
13
13
|
const R = process.stdout.isTTY ? "\x1b[0m" : ""; // reset
|
|
@@ -892,6 +892,59 @@ function cmdSwarm(target, sub, args) {
|
|
|
892
892
|
log(`task created: ${id} → ${forAgent}`);
|
|
893
893
|
return;
|
|
894
894
|
}
|
|
895
|
+
if (sub === "webhook") {
|
|
896
|
+
const webhooksFile = path.join(swarmDir, "webhooks.json");
|
|
897
|
+
const loadHooks = () => { try { return JSON.parse(fs.readFileSync(webhooksFile, "utf8")); } catch { return []; } };
|
|
898
|
+
const saveHooks = (h) => { fs.mkdirSync(swarmDir, { recursive: true }); fs.writeFileSync(webhooksFile, JSON.stringify(h, null, 2)); };
|
|
899
|
+
const action = args[2] || "";
|
|
900
|
+
|
|
901
|
+
if (action === "add") {
|
|
902
|
+
const url = args[3] || args.find((_, i) => args[i-1] === "--url");
|
|
903
|
+
const event = args.find((_, i) => args[i-1] === "--event") || "all";
|
|
904
|
+
const secret = args.find((_, i) => args[i-1] === "--secret") || "";
|
|
905
|
+
if (!url || !url.startsWith("http")) { log("Usage: 0dai swarm webhook add <url> [--event task_done|task_failed|all] [--secret TOKEN]"); return; }
|
|
906
|
+
const hooks = loadHooks();
|
|
907
|
+
if (hooks.find(h => h.url === url)) { log(`already registered: ${url}`); return; }
|
|
908
|
+
hooks.push({ url, event, secret: secret || undefined, added_at: new Date().toISOString() });
|
|
909
|
+
saveHooks(hooks);
|
|
910
|
+
log(`webhook added: ${url} (event: ${event})`);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (action === "list") {
|
|
914
|
+
const hooks = loadHooks();
|
|
915
|
+
if (hooks.length === 0) { log("no webhooks registered. Use: 0dai swarm webhook add <url>"); return; }
|
|
916
|
+
console.log(`\n ${T}Registered webhooks${R}\n`);
|
|
917
|
+
hooks.forEach((h, i) => {
|
|
918
|
+
console.log(` ${i+1}. ${h.url}`);
|
|
919
|
+
console.log(` ${D}event: ${h.event} added: ${h.added_at?.slice(0,10)}${R}`);
|
|
920
|
+
});
|
|
921
|
+
console.log();
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
if (action === "remove") {
|
|
925
|
+
const url = args[3] || "";
|
|
926
|
+
if (!url) { log("Usage: 0dai swarm webhook remove <url>"); return; }
|
|
927
|
+
const hooks = loadHooks().filter(h => h.url !== url);
|
|
928
|
+
saveHooks(hooks);
|
|
929
|
+
log(`removed: ${url}`);
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
if (action === "test") {
|
|
933
|
+
const url = args[3] || loadHooks()[0]?.url;
|
|
934
|
+
if (!url) { log("Usage: 0dai swarm webhook test <url>"); return; }
|
|
935
|
+
const payload = JSON.stringify({ event: "test", task_id: "test-ping", title: "Webhook test from 0dai", status: "done", timestamp: new Date().toISOString() });
|
|
936
|
+
const req = https.request(url, { method: "POST", headers: { "Content-Type": "application/json", "User-Agent": "0dai-swarm/1.0", "Content-Length": Buffer.byteLength(payload) } }, (res) => {
|
|
937
|
+
log(`test sent to ${url} → HTTP ${res.statusCode}`);
|
|
938
|
+
});
|
|
939
|
+
req.on("error", (e) => log(`test failed: ${e.message}`));
|
|
940
|
+
req.setTimeout(5000, () => { req.destroy(); log("test timed out"); });
|
|
941
|
+
req.write(payload);
|
|
942
|
+
req.end();
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
console.log("Usage: 0dai swarm webhook [add|list|remove|test] <url> [--event all|task_done|task_failed] [--secret TOKEN]");
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
895
948
|
if (sub === "budget") {
|
|
896
949
|
const budgetFile = path.join(swarmDir, "budget.json");
|
|
897
950
|
if (!fs.existsSync(budgetFile)) { log("no budget data yet"); return; }
|
|
@@ -1000,7 +1053,10 @@ async function main() {
|
|
|
1000
1053
|
console.log(" reflect Session reflection: delivered, delegation rate, blockers");
|
|
1001
1054
|
console.log(" status Show maturity, swarm, session");
|
|
1002
1055
|
console.log(" session save Save session for roaming");
|
|
1003
|
-
console.log(" swarm status
|
|
1056
|
+
console.log(" swarm status Task queue & delegation");
|
|
1057
|
+
console.log(" swarm webhook add Register webhook (fires on task done/failed)");
|
|
1058
|
+
console.log(" swarm webhook list Show registered webhooks");
|
|
1059
|
+
console.log(" swarm webhook test Send test ping to a webhook URL");
|
|
1004
1060
|
console.log(" feedback push Send feedback to 0dai");
|
|
1005
1061
|
console.log(" models Show model ratings (--fast/--balanced/--deep/--available)");
|
|
1006
1062
|
console.log(" terminal Launch interactive agent session");
|