@sherwoodagent/cli 0.9.0 → 0.11.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/dist/{chat-BNYWD3EL.js → chat-2X5FQI5X.js} +9 -6
- package/dist/{chat-BNYWD3EL.js.map → chat-2X5FQI5X.js.map} +1 -1
- package/dist/{chunk-HKZONPXW.js → chunk-56W62BYY.js} +8 -6
- package/dist/{chunk-HKZONPXW.js.map → chunk-56W62BYY.js.map} +1 -1
- package/dist/{chunk-Q37V65B6.js → chunk-6IUSJWAL.js} +9 -5
- package/dist/{chunk-Q37V65B6.js.map → chunk-6IUSJWAL.js.map} +1 -1
- package/dist/chunk-7CN3TSAA.js +107 -0
- package/dist/chunk-7CN3TSAA.js.map +1 -0
- package/dist/chunk-FWJBUK57.js +65 -0
- package/dist/chunk-FWJBUK57.js.map +1 -0
- package/dist/chunk-IIDZ2TK5.js +100 -0
- package/dist/chunk-IIDZ2TK5.js.map +1 -0
- package/dist/{chunk-OUES74ID.js → chunk-IXMM3TT3.js} +19 -7
- package/dist/{chunk-OUES74ID.js.map → chunk-IXMM3TT3.js.map} +1 -1
- package/dist/{chunk-4MTHXGTK.js → chunk-KAZRNDZQ.js} +2 -2
- package/dist/config-U74QT4SC.js +37 -0
- package/dist/cron-RG46PYWA.js +203 -0
- package/dist/cron-RG46PYWA.js.map +1 -0
- package/dist/{eas-EL3XCEXQ.js → eas-HQ5OTAFW.js} +6 -4
- package/dist/index.js +100 -30
- package/dist/index.js.map +1 -1
- package/dist/network-ROF3SSAA.js +26 -0
- package/dist/network-ROF3SSAA.js.map +1 -0
- package/dist/research-HEZP7VPY.js +14 -0
- package/dist/research-HEZP7VPY.js.map +1 -0
- package/dist/{research-57SKO27M.js → research-PLYYYJ4F.js} +7 -5
- package/dist/{research-57SKO27M.js.map → research-PLYYYJ4F.js.map} +1 -1
- package/dist/{session-QQSHCGNK.js → session-QBWUWXCH.js} +47 -5
- package/dist/session-QBWUWXCH.js.map +1 -0
- package/dist/{xmtp-S4VRXMFK.js → xmtp-A5G2GEWF.js} +10 -6
- package/dist/{xmtp-S4VRXMFK.js.map → xmtp-A5G2GEWF.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-5ADWTXNT.js +0 -233
- package/dist/chunk-5ADWTXNT.js.map +0 -1
- package/dist/research-ZR7HXITG.js +0 -12
- package/dist/session-QQSHCGNK.js.map +0 -1
- /package/dist/{chunk-4MTHXGTK.js.map → chunk-KAZRNDZQ.js.map} +0 -0
- /package/dist/{eas-EL3XCEXQ.js.map → config-U74QT4SC.js.map} +0 -0
- /package/dist/{research-ZR7HXITG.js.map → eas-HQ5OTAFW.js.map} +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// src/lib/cron.ts
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
3
|
+
var _isOpenClaw = null;
|
|
4
|
+
function isOpenClaw() {
|
|
5
|
+
if (_isOpenClaw !== null) return _isOpenClaw;
|
|
6
|
+
try {
|
|
7
|
+
execFileSync("openclaw", ["cron", "list"], {
|
|
8
|
+
encoding: "utf8",
|
|
9
|
+
timeout: 1e4,
|
|
10
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
11
|
+
});
|
|
12
|
+
_isOpenClaw = true;
|
|
13
|
+
} catch {
|
|
14
|
+
_isOpenClaw = false;
|
|
15
|
+
}
|
|
16
|
+
return _isOpenClaw;
|
|
17
|
+
}
|
|
18
|
+
function cronName(subdomain, testnet) {
|
|
19
|
+
return `sherwood-${subdomain}${testnet ? "-testnet" : ""}`;
|
|
20
|
+
}
|
|
21
|
+
function summaryCronName(subdomain, testnet) {
|
|
22
|
+
return `${cronName(subdomain, testnet)}-summary`;
|
|
23
|
+
}
|
|
24
|
+
function silentPrompt(subdomain, testnet) {
|
|
25
|
+
const chainFlag = testnet ? " --chain base-sepolia" : "";
|
|
26
|
+
const envPrefix = testnet ? "ENABLE_TESTNET=true " : "";
|
|
27
|
+
return [
|
|
28
|
+
`You are a sherwood syndicate member. Your syndicate: ${subdomain}.sherwoodagent.eth`,
|
|
29
|
+
"",
|
|
30
|
+
`Step 1: Run \`${envPrefix}sherwood session check ${subdomain}${chainFlag}\``,
|
|
31
|
+
"Step 2: Parse the JSON output for new messages and events",
|
|
32
|
+
"Step 3: If new messages from OTHER agents, respond thoughtfully via:",
|
|
33
|
+
` \`${envPrefix}sherwood chat ${subdomain} send "<response>"${chainFlag}\``,
|
|
34
|
+
"Step 4: If you responded to anything, summarize what you did (for your own session log).",
|
|
35
|
+
" If nothing happened, reply HEARTBEAT_OK",
|
|
36
|
+
"",
|
|
37
|
+
"Rules:",
|
|
38
|
+
"- Be a real syndicate member \u2014 discuss strategies, share opinions, ask questions",
|
|
39
|
+
"- Keep responses concise and on-topic",
|
|
40
|
+
"- Do NOT alert your human unless something requires their approval",
|
|
41
|
+
`- You can use \`sherwood research\` commands if you need data to back up your response`
|
|
42
|
+
].join("\n");
|
|
43
|
+
}
|
|
44
|
+
function summaryPrompt(subdomain, testnet) {
|
|
45
|
+
const chainFlag = testnet ? " --chain base-sepolia" : "";
|
|
46
|
+
const envPrefix = testnet ? "ENABLE_TESTNET=true " : "";
|
|
47
|
+
return [
|
|
48
|
+
"You are reporting syndicate activity to your human operator.",
|
|
49
|
+
"",
|
|
50
|
+
`Run: \`${envPrefix}sherwood session check ${subdomain}${chainFlag}\``,
|
|
51
|
+
"",
|
|
52
|
+
"If there was activity (messages, events, proposals) since last check:",
|
|
53
|
+
" Send a brief summary \u2014 who said what, any decisions made, any actions you took.",
|
|
54
|
+
" Keep it to 3-5 lines max.",
|
|
55
|
+
"",
|
|
56
|
+
"If there was no activity:",
|
|
57
|
+
" Reply HEARTBEAT_OK",
|
|
58
|
+
"",
|
|
59
|
+
"Only escalate (flag as urgent) if:",
|
|
60
|
+
"- A proposal needs human sign-off",
|
|
61
|
+
"- An agent left the syndicate",
|
|
62
|
+
"- Risk alert or health factor warning",
|
|
63
|
+
"- Human was directly asked for input"
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
function listCronNames() {
|
|
67
|
+
try {
|
|
68
|
+
const raw = execFileSync("openclaw", ["cron", "list", "--json"], {
|
|
69
|
+
encoding: "utf8",
|
|
70
|
+
timeout: 1e4,
|
|
71
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
72
|
+
});
|
|
73
|
+
const parsed = JSON.parse(raw);
|
|
74
|
+
const jobs = parsed.jobs || parsed || [];
|
|
75
|
+
return jobs.map((j) => j.name);
|
|
76
|
+
} catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function listCronDetails() {
|
|
81
|
+
try {
|
|
82
|
+
const raw = execFileSync("openclaw", ["cron", "list", "--json"], {
|
|
83
|
+
encoding: "utf8",
|
|
84
|
+
timeout: 1e4,
|
|
85
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
86
|
+
});
|
|
87
|
+
const parsed = JSON.parse(raw);
|
|
88
|
+
const jobs = parsed.jobs || parsed || [];
|
|
89
|
+
return jobs.map((j) => ({
|
|
90
|
+
name: j.name,
|
|
91
|
+
every: j.every || j.interval || "unknown",
|
|
92
|
+
lastRun: j.lastRun
|
|
93
|
+
}));
|
|
94
|
+
} catch {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function registerSyndicateCrons(subdomain, testnet, notifyTo) {
|
|
99
|
+
if (!isOpenClaw()) {
|
|
100
|
+
return { registered: false, isOpenClaw: false, cronNames: [] };
|
|
101
|
+
}
|
|
102
|
+
const checkName = cronName(subdomain, testnet);
|
|
103
|
+
const summaryName = summaryCronName(subdomain, testnet);
|
|
104
|
+
const existing = listCronNames();
|
|
105
|
+
const created = [];
|
|
106
|
+
if (!existing.includes(checkName)) {
|
|
107
|
+
try {
|
|
108
|
+
execFileSync("openclaw", [
|
|
109
|
+
"cron",
|
|
110
|
+
"create",
|
|
111
|
+
"--name",
|
|
112
|
+
checkName,
|
|
113
|
+
"--every",
|
|
114
|
+
"15m",
|
|
115
|
+
"--session",
|
|
116
|
+
"isolated",
|
|
117
|
+
"--timeout-seconds",
|
|
118
|
+
"120",
|
|
119
|
+
"--no-deliver",
|
|
120
|
+
"--message",
|
|
121
|
+
silentPrompt(subdomain, testnet)
|
|
122
|
+
], {
|
|
123
|
+
encoding: "utf8",
|
|
124
|
+
timeout: 3e4,
|
|
125
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
126
|
+
});
|
|
127
|
+
created.push(checkName);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.warn(`Could not create silent cron: ${err instanceof Error ? err.message : String(err)}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!existing.includes(summaryName)) {
|
|
133
|
+
try {
|
|
134
|
+
const args = [
|
|
135
|
+
"cron",
|
|
136
|
+
"create",
|
|
137
|
+
"--name",
|
|
138
|
+
summaryName,
|
|
139
|
+
"--every",
|
|
140
|
+
"1h",
|
|
141
|
+
"--session",
|
|
142
|
+
"isolated",
|
|
143
|
+
"--timeout-seconds",
|
|
144
|
+
"90",
|
|
145
|
+
"--announce"
|
|
146
|
+
];
|
|
147
|
+
if (notifyTo) {
|
|
148
|
+
args.push("--to", notifyTo);
|
|
149
|
+
} else {
|
|
150
|
+
args.push("--channel", "last");
|
|
151
|
+
}
|
|
152
|
+
args.push("--message", summaryPrompt(subdomain, testnet));
|
|
153
|
+
execFileSync("openclaw", args, {
|
|
154
|
+
encoding: "utf8",
|
|
155
|
+
timeout: 3e4,
|
|
156
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
157
|
+
});
|
|
158
|
+
created.push(summaryName);
|
|
159
|
+
} catch (err) {
|
|
160
|
+
console.warn(`Could not create summary cron: ${err instanceof Error ? err.message : String(err)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
registered: created.length > 0,
|
|
165
|
+
isOpenClaw: true,
|
|
166
|
+
cronNames: created
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function unregisterSyndicateCrons(subdomain, testnet) {
|
|
170
|
+
if (!isOpenClaw()) {
|
|
171
|
+
return { removed: false, isOpenClaw: false };
|
|
172
|
+
}
|
|
173
|
+
const names = [cronName(subdomain, testnet), summaryCronName(subdomain, testnet)];
|
|
174
|
+
let removed = false;
|
|
175
|
+
for (const name of names) {
|
|
176
|
+
try {
|
|
177
|
+
execFileSync("openclaw", ["cron", "remove", "--name", name], {
|
|
178
|
+
encoding: "utf8",
|
|
179
|
+
timeout: 1e4,
|
|
180
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
181
|
+
});
|
|
182
|
+
removed = true;
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return { removed, isOpenClaw: true };
|
|
187
|
+
}
|
|
188
|
+
function getSyndicateCronStatus(subdomain, testnet) {
|
|
189
|
+
if (!isOpenClaw()) {
|
|
190
|
+
return { isOpenClaw: false, crons: [] };
|
|
191
|
+
}
|
|
192
|
+
const prefix = cronName(subdomain, testnet);
|
|
193
|
+
const all = listCronDetails();
|
|
194
|
+
const matching = all.filter((c) => c.name.startsWith(prefix));
|
|
195
|
+
return { isOpenClaw: true, crons: matching };
|
|
196
|
+
}
|
|
197
|
+
export {
|
|
198
|
+
getSyndicateCronStatus,
|
|
199
|
+
isOpenClaw,
|
|
200
|
+
registerSyndicateCrons,
|
|
201
|
+
unregisterSyndicateCrons
|
|
202
|
+
};
|
|
203
|
+
//# sourceMappingURL=cron-RG46PYWA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/cron.ts"],"sourcesContent":["/**\n * OpenClaw cron integration — auto-register participation crons for syndicate agents.\n *\n * When an agent creates or joins a syndicate, the CLI registers two cron jobs:\n * 1. Silent check (every 15m) — processes messages/events, responds autonomously\n * 2. Human summary (every 1h) — brief activity report delivered to the human's channel\n *\n * Non-OpenClaw agents skip silently — the caller prints guidance instead.\n */\n\nimport { execFileSync } from \"node:child_process\";\n\n// ── OpenClaw detection (cached per process) ──\n\nlet _isOpenClaw: boolean | null = null;\n\nexport function isOpenClaw(): boolean {\n if (_isOpenClaw !== null) return _isOpenClaw;\n try {\n execFileSync(\"openclaw\", [\"cron\", \"list\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n _isOpenClaw = true;\n } catch {\n _isOpenClaw = false;\n }\n return _isOpenClaw;\n}\n\n// ── Types ──\n\nexport interface CronResult {\n registered: boolean;\n isOpenClaw: boolean;\n cronNames: string[];\n}\n\nexport interface CronStatus {\n isOpenClaw: boolean;\n crons: { name: string; every: string; lastRun?: string }[];\n}\n\n// ── Cron naming ──\n\nfunction cronName(subdomain: string, testnet: boolean): string {\n return `sherwood-${subdomain}${testnet ? \"-testnet\" : \"\"}`;\n}\n\nfunction summaryCronName(subdomain: string, testnet: boolean): string {\n return `${cronName(subdomain, testnet)}-summary`;\n}\n\n// ── Prompts ──\n\nfunction silentPrompt(subdomain: string, testnet: boolean): string {\n const chainFlag = testnet ? \" --chain base-sepolia\" : \"\";\n const envPrefix = testnet ? \"ENABLE_TESTNET=true \" : \"\";\n return [\n `You are a sherwood syndicate member. Your syndicate: ${subdomain}.sherwoodagent.eth`,\n \"\",\n `Step 1: Run \\`${envPrefix}sherwood session check ${subdomain}${chainFlag}\\``,\n \"Step 2: Parse the JSON output for new messages and events\",\n \"Step 3: If new messages from OTHER agents, respond thoughtfully via:\",\n ` \\`${envPrefix}sherwood chat ${subdomain} send \"<response>\"${chainFlag}\\``,\n \"Step 4: If you responded to anything, summarize what you did (for your own session log).\",\n \" If nothing happened, reply HEARTBEAT_OK\",\n \"\",\n \"Rules:\",\n \"- Be a real syndicate member — discuss strategies, share opinions, ask questions\",\n \"- Keep responses concise and on-topic\",\n \"- Do NOT alert your human unless something requires their approval\",\n `- You can use \\`sherwood research\\` commands if you need data to back up your response`,\n ].join(\"\\n\");\n}\n\nfunction summaryPrompt(subdomain: string, testnet: boolean): string {\n const chainFlag = testnet ? \" --chain base-sepolia\" : \"\";\n const envPrefix = testnet ? \"ENABLE_TESTNET=true \" : \"\";\n return [\n \"You are reporting syndicate activity to your human operator.\",\n \"\",\n `Run: \\`${envPrefix}sherwood session check ${subdomain}${chainFlag}\\``,\n \"\",\n \"If there was activity (messages, events, proposals) since last check:\",\n \" Send a brief summary — who said what, any decisions made, any actions you took.\",\n \" Keep it to 3-5 lines max.\",\n \"\",\n \"If there was no activity:\",\n \" Reply HEARTBEAT_OK\",\n \"\",\n \"Only escalate (flag as urgent) if:\",\n \"- A proposal needs human sign-off\",\n \"- An agent left the syndicate\",\n \"- Risk alert or health factor warning\",\n \"- Human was directly asked for input\",\n ].join(\"\\n\");\n}\n\n// ── Helpers ──\n\n/** Parse `openclaw cron list --json` and return job names. */\nfunction listCronNames(): string[] {\n try {\n const raw = execFileSync(\"openclaw\", [\"cron\", \"list\", \"--json\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const parsed = JSON.parse(raw);\n const jobs: { name: string }[] = parsed.jobs || parsed || [];\n return jobs.map((j) => j.name);\n } catch {\n return [];\n }\n}\n\n/** Parse `openclaw cron list --json` with full details for status display. */\nfunction listCronDetails(): { name: string; every: string; lastRun?: string }[] {\n try {\n const raw = execFileSync(\"openclaw\", [\"cron\", \"list\", \"--json\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const parsed = JSON.parse(raw);\n const jobs: { name: string; every?: string; interval?: string; lastRun?: string }[] =\n parsed.jobs || parsed || [];\n return jobs.map((j) => ({\n name: j.name,\n every: j.every || j.interval || \"unknown\",\n lastRun: j.lastRun,\n }));\n } catch {\n return [];\n }\n}\n\n// ── Public API ──\n\nexport function registerSyndicateCrons(\n subdomain: string,\n testnet: boolean,\n notifyTo?: string,\n): CronResult {\n if (!isOpenClaw()) {\n return { registered: false, isOpenClaw: false, cronNames: [] };\n }\n\n const checkName = cronName(subdomain, testnet);\n const summaryName = summaryCronName(subdomain, testnet);\n const existing = listCronNames();\n const created: string[] = [];\n\n // Cron 1: Silent participation check (every 15m)\n if (!existing.includes(checkName)) {\n try {\n execFileSync(\"openclaw\", [\n \"cron\", \"create\",\n \"--name\", checkName,\n \"--every\", \"15m\",\n \"--session\", \"isolated\",\n \"--timeout-seconds\", \"120\",\n \"--no-deliver\",\n \"--message\", silentPrompt(subdomain, testnet),\n ], {\n encoding: \"utf8\",\n timeout: 30_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n created.push(checkName);\n } catch (err) {\n console.warn(`Could not create silent cron: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Cron 2: Human summary (every 1h)\n if (!existing.includes(summaryName)) {\n try {\n const args = [\n \"cron\", \"create\",\n \"--name\", summaryName,\n \"--every\", \"1h\",\n \"--session\", \"isolated\",\n \"--timeout-seconds\", \"90\",\n \"--announce\",\n ];\n\n // Use explicit destination if configured, otherwise auto-route via --channel last\n if (notifyTo) {\n args.push(\"--to\", notifyTo);\n } else {\n args.push(\"--channel\", \"last\");\n }\n\n args.push(\"--message\", summaryPrompt(subdomain, testnet));\n\n execFileSync(\"openclaw\", args, {\n encoding: \"utf8\",\n timeout: 30_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n created.push(summaryName);\n } catch (err) {\n console.warn(`Could not create summary cron: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return {\n registered: created.length > 0,\n isOpenClaw: true,\n cronNames: created,\n };\n}\n\nexport function unregisterSyndicateCrons(\n subdomain: string,\n testnet: boolean,\n): { removed: boolean; isOpenClaw: boolean } {\n if (!isOpenClaw()) {\n return { removed: false, isOpenClaw: false };\n }\n\n const names = [cronName(subdomain, testnet), summaryCronName(subdomain, testnet)];\n let removed = false;\n\n for (const name of names) {\n try {\n execFileSync(\"openclaw\", [\"cron\", \"remove\", \"--name\", name], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n removed = true;\n } catch {\n // Cron may not exist — that's fine\n }\n }\n\n return { removed, isOpenClaw: true };\n}\n\nexport function getSyndicateCronStatus(\n subdomain: string,\n testnet: boolean,\n): CronStatus {\n if (!isOpenClaw()) {\n return { isOpenClaw: false, crons: [] };\n }\n\n const prefix = cronName(subdomain, testnet);\n const all = listCronDetails();\n const matching = all.filter((c) => c.name.startsWith(prefix));\n\n return { isOpenClaw: true, crons: matching };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
queryApprovals,
|
|
7
7
|
queryJoinRequests,
|
|
8
8
|
revokeAttestation
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-56W62BYY.js";
|
|
10
|
+
import "./chunk-IXMM3TT3.js";
|
|
11
|
+
import "./chunk-FWJBUK57.js";
|
|
12
|
+
import "./chunk-7CN3TSAA.js";
|
|
13
|
+
import "./chunk-IIDZ2TK5.js";
|
|
12
14
|
export {
|
|
13
15
|
createApproval,
|
|
14
16
|
createJoinRequest,
|
|
@@ -18,4 +20,4 @@ export {
|
|
|
18
20
|
queryJoinRequests,
|
|
19
21
|
revokeAttestation
|
|
20
22
|
};
|
|
21
|
-
//# sourceMappingURL=eas-
|
|
23
|
+
//# sourceMappingURL=eas-HQ5OTAFW.js.map
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
queryApprovals,
|
|
11
11
|
queryJoinRequests,
|
|
12
12
|
revokeAttestation
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-56W62BYY.js";
|
|
14
14
|
import {
|
|
15
15
|
approveDepositor,
|
|
16
16
|
deposit,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
setTextRecord,
|
|
29
29
|
setVaultAddress,
|
|
30
30
|
simulateBatch
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-6IUSJWAL.js";
|
|
32
32
|
import {
|
|
33
33
|
AGENT_REGISTRY,
|
|
34
34
|
EAS_SCHEMAS,
|
|
@@ -44,28 +44,35 @@ import {
|
|
|
44
44
|
UNISWAP_QUOTER_V2_ABI,
|
|
45
45
|
VENICE,
|
|
46
46
|
VENICE_STAKING_ABI
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-IXMM3TT3.js";
|
|
48
48
|
import {
|
|
49
|
-
VALID_NETWORKS,
|
|
50
|
-
cacheGroupId,
|
|
51
49
|
getAccount,
|
|
52
|
-
|
|
50
|
+
getPublicClient,
|
|
51
|
+
getWalletClient
|
|
52
|
+
} from "./chunk-FWJBUK57.js";
|
|
53
|
+
import {
|
|
54
|
+
VALID_NETWORKS,
|
|
53
55
|
getChain,
|
|
54
|
-
getChainContracts,
|
|
55
56
|
getExplorerUrl,
|
|
56
57
|
getNetwork,
|
|
57
|
-
getPublicClient,
|
|
58
58
|
getRpcUrl,
|
|
59
|
+
isTestnet,
|
|
60
|
+
setNetwork
|
|
61
|
+
} from "./chunk-7CN3TSAA.js";
|
|
62
|
+
import {
|
|
63
|
+
cacheGroupId,
|
|
64
|
+
getAgentId,
|
|
65
|
+
getChainContracts,
|
|
66
|
+
getNotifyTo,
|
|
59
67
|
getVeniceApiKey,
|
|
60
|
-
getWalletClient,
|
|
61
68
|
loadConfig,
|
|
62
69
|
setAgentId,
|
|
63
70
|
setChainContract,
|
|
64
71
|
setConfigRpcUrl,
|
|
65
|
-
|
|
72
|
+
setNotifyTo,
|
|
66
73
|
setPrivateKey,
|
|
67
74
|
setVeniceApiKey
|
|
68
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-IIDZ2TK5.js";
|
|
69
76
|
|
|
70
77
|
// src/index.ts
|
|
71
78
|
import { config as loadDotenv } from "dotenv";
|
|
@@ -1687,6 +1694,7 @@ import { readFileSync } from "fs";
|
|
|
1687
1694
|
|
|
1688
1695
|
// src/lib/governor.ts
|
|
1689
1696
|
var PROPOSAL_STATES = [
|
|
1697
|
+
"Draft",
|
|
1690
1698
|
"Pending",
|
|
1691
1699
|
"Approved",
|
|
1692
1700
|
"Rejected",
|
|
@@ -1695,6 +1703,21 @@ var PROPOSAL_STATES = [
|
|
|
1695
1703
|
"Settled",
|
|
1696
1704
|
"Cancelled"
|
|
1697
1705
|
];
|
|
1706
|
+
var PROPOSAL_STATE = {
|
|
1707
|
+
Draft: 0,
|
|
1708
|
+
Pending: 1,
|
|
1709
|
+
Approved: 2,
|
|
1710
|
+
Rejected: 3,
|
|
1711
|
+
Expired: 4,
|
|
1712
|
+
Executed: 5,
|
|
1713
|
+
Settled: 6,
|
|
1714
|
+
Cancelled: 7
|
|
1715
|
+
};
|
|
1716
|
+
var VOTE_TYPE = {
|
|
1717
|
+
For: 0,
|
|
1718
|
+
Against: 1,
|
|
1719
|
+
Abstain: 2
|
|
1720
|
+
};
|
|
1698
1721
|
function parseDuration(input2) {
|
|
1699
1722
|
const match = input2.match(/^(\d+)(d|h|m|s)?$/);
|
|
1700
1723
|
if (!match) throw new Error(`Invalid duration: ${input2}`);
|
|
@@ -1797,7 +1820,7 @@ async function getCapitalSnapshot(proposalId) {
|
|
|
1797
1820
|
args: [proposalId]
|
|
1798
1821
|
});
|
|
1799
1822
|
}
|
|
1800
|
-
async function propose(vault, metadataURI, performanceFeeBps, strategyDuration, calls, splitIndex) {
|
|
1823
|
+
async function propose(vault, metadataURI, performanceFeeBps, strategyDuration, calls, splitIndex, coProposers = []) {
|
|
1801
1824
|
const wallet = getWalletClient();
|
|
1802
1825
|
const client = getPublicClient();
|
|
1803
1826
|
const hash = await wallet.writeContract({
|
|
@@ -1806,7 +1829,7 @@ async function propose(vault, metadataURI, performanceFeeBps, strategyDuration,
|
|
|
1806
1829
|
address: getGovernorAddress(),
|
|
1807
1830
|
abi: SYNDICATE_GOVERNOR_ABI,
|
|
1808
1831
|
functionName: "propose",
|
|
1809
|
-
args: [vault, metadataURI, performanceFeeBps, strategyDuration, calls, splitIndex]
|
|
1832
|
+
args: [vault, metadataURI, performanceFeeBps, strategyDuration, calls, splitIndex, coProposers]
|
|
1810
1833
|
});
|
|
1811
1834
|
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
1812
1835
|
let proposalId;
|
|
@@ -2119,7 +2142,7 @@ function registerProposalCommands(program2) {
|
|
|
2119
2142
|
process.exit(1);
|
|
2120
2143
|
}
|
|
2121
2144
|
});
|
|
2122
|
-
proposal.command("list").description("List proposals").option("--vault <address>", "Filter by vault").option("--state <filter>", "Filter by state: pending, approved, executed, settled, all", "all").action(async (opts) => {
|
|
2145
|
+
proposal.command("list").description("List proposals").option("--vault <address>", "Filter by vault").option("--state <filter>", "Filter by state: draft, pending, approved, executed, settled, all", "all").action(async (opts) => {
|
|
2123
2146
|
const spinner = ora5("Loading proposals...").start();
|
|
2124
2147
|
try {
|
|
2125
2148
|
const count = await proposalCount();
|
|
@@ -2214,8 +2237,9 @@ function registerProposalCommands(program2) {
|
|
|
2214
2237
|
console.log(LABEL(" Votes"));
|
|
2215
2238
|
console.log(W(` For: ${formatShares(p.votesFor)}`));
|
|
2216
2239
|
console.log(W(` Against: ${formatShares(p.votesAgainst)}`));
|
|
2240
|
+
console.log(W(` Abstain: ${formatShares(p.votesAbstain)}`));
|
|
2217
2241
|
console.log(W(` Quorum: ${quorumNeeded}`));
|
|
2218
|
-
if (state ===
|
|
2242
|
+
if (state === PROPOSAL_STATE.Executed || state === PROPOSAL_STATE.Settled) {
|
|
2219
2243
|
try {
|
|
2220
2244
|
const cap = await getCapitalSnapshot(id);
|
|
2221
2245
|
console.log();
|
|
@@ -2239,15 +2263,20 @@ function registerProposalCommands(program2) {
|
|
|
2239
2263
|
process.exit(1);
|
|
2240
2264
|
}
|
|
2241
2265
|
});
|
|
2242
|
-
proposal.command("vote").description("Cast a vote on a pending proposal").requiredOption("--id <proposalId>", "Proposal ID").requiredOption("--support <
|
|
2266
|
+
proposal.command("vote").description("Cast a vote on a pending proposal").requiredOption("--id <proposalId>", "Proposal ID").requiredOption("--support <for|against|abstain>", "Vote direction: for, against, or abstain").action(async (opts) => {
|
|
2243
2267
|
try {
|
|
2244
2268
|
const proposalId = parseBigIntArg(opts.id, "proposal ID");
|
|
2245
|
-
const
|
|
2269
|
+
const supportRaw = String(opts.support).toLowerCase();
|
|
2270
|
+
const support = supportRaw === "yes" || supportRaw === "for" ? VOTE_TYPE.For : supportRaw === "no" || supportRaw === "against" ? VOTE_TYPE.Against : supportRaw === "abstain" ? VOTE_TYPE.Abstain : null;
|
|
2271
|
+
if (support === null) {
|
|
2272
|
+
console.error(chalk5.red(`Invalid support value "${opts.support}". Use for|against|abstain.`));
|
|
2273
|
+
process.exit(1);
|
|
2274
|
+
}
|
|
2246
2275
|
const account = getAccount();
|
|
2247
2276
|
const spinner = ora5("Loading proposal...").start();
|
|
2248
2277
|
const p = await getProposal(proposalId);
|
|
2249
2278
|
const state = await getProposalState(proposalId);
|
|
2250
|
-
if (state !==
|
|
2279
|
+
if (state !== PROPOSAL_STATE.Pending) {
|
|
2251
2280
|
spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"}, not Pending`);
|
|
2252
2281
|
process.exit(1);
|
|
2253
2282
|
}
|
|
@@ -2263,7 +2292,9 @@ function registerProposalCommands(program2) {
|
|
|
2263
2292
|
SEP();
|
|
2264
2293
|
console.log(W(` Proposal: #${proposalId}`));
|
|
2265
2294
|
console.log(W(` Vault: ${G(p.vault)}`));
|
|
2266
|
-
console.log(W(
|
|
2295
|
+
console.log(W(
|
|
2296
|
+
` Support: ${support === VOTE_TYPE.For ? G("FOR") : support === VOTE_TYPE.Against ? chalk5.red("AGAINST") : DIM("ABSTAIN")}`
|
|
2297
|
+
));
|
|
2267
2298
|
console.log(W(` Weight: ${formatShares(weight)} shares`));
|
|
2268
2299
|
SEP();
|
|
2269
2300
|
const voteSpinner = ora5({ text: W("Submitting vote..."), color: "green" }).start();
|
|
@@ -2282,7 +2313,7 @@ function registerProposalCommands(program2) {
|
|
|
2282
2313
|
const proposalId = parseBigIntArg(opts.id, "proposal ID");
|
|
2283
2314
|
const spinner = ora5("Loading proposal...").start();
|
|
2284
2315
|
const state = await getProposalState(proposalId);
|
|
2285
|
-
if (state !==
|
|
2316
|
+
if (state !== PROPOSAL_STATE.Approved) {
|
|
2286
2317
|
spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"}, not Approved`);
|
|
2287
2318
|
process.exit(1);
|
|
2288
2319
|
}
|
|
@@ -2309,7 +2340,7 @@ function registerProposalCommands(program2) {
|
|
|
2309
2340
|
const spinner = ora5("Loading proposal...").start();
|
|
2310
2341
|
const p = await getProposal(proposalId);
|
|
2311
2342
|
const state = await getProposalState(proposalId);
|
|
2312
|
-
if (state !==
|
|
2343
|
+
if (state !== PROPOSAL_STATE.Executed) {
|
|
2313
2344
|
spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"}, not Executed`);
|
|
2314
2345
|
process.exit(1);
|
|
2315
2346
|
}
|
|
@@ -2348,7 +2379,7 @@ function registerProposalCommands(program2) {
|
|
|
2348
2379
|
const proposalId = parseBigIntArg(opts.id, "proposal ID");
|
|
2349
2380
|
const spinner = ora5("Loading proposal...").start();
|
|
2350
2381
|
const state = await getProposalState(proposalId);
|
|
2351
|
-
if (state ===
|
|
2382
|
+
if (state === PROPOSAL_STATE.Settled || state === PROPOSAL_STATE.Cancelled) {
|
|
2352
2383
|
spinner.fail(`Proposal is already ${PROPOSAL_STATES[state]}`);
|
|
2353
2384
|
process.exit(1);
|
|
2354
2385
|
}
|
|
@@ -2358,7 +2389,7 @@ function registerProposalCommands(program2) {
|
|
|
2358
2389
|
hash = await emergencyCancel(proposalId);
|
|
2359
2390
|
spinner.succeed(G("Emergency cancelled"));
|
|
2360
2391
|
} else {
|
|
2361
|
-
if (state !==
|
|
2392
|
+
if (state !== PROPOSAL_STATE.Draft && state !== PROPOSAL_STATE.Pending) {
|
|
2362
2393
|
spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"} \u2014 use --emergency for non-pending/approved`);
|
|
2363
2394
|
process.exit(1);
|
|
2364
2395
|
}
|
|
@@ -2502,7 +2533,10 @@ try {
|
|
|
2502
2533
|
} catch {
|
|
2503
2534
|
}
|
|
2504
2535
|
async function loadXmtp() {
|
|
2505
|
-
return import("./xmtp-
|
|
2536
|
+
return import("./xmtp-A5G2GEWF.js");
|
|
2537
|
+
}
|
|
2538
|
+
async function loadCron() {
|
|
2539
|
+
return import("./cron-RG46PYWA.js");
|
|
2506
2540
|
}
|
|
2507
2541
|
var G3 = chalk7.green;
|
|
2508
2542
|
var W3 = chalk7.white;
|
|
@@ -2677,6 +2711,16 @@ syndicate.command("create").description("Create a new syndicate via the factory
|
|
|
2677
2711
|
console.warn(chalk7.yellow("\n \u26A0 Could not create XMTP chat group"));
|
|
2678
2712
|
console.warn(chalk7.dim(` Recover later with: sherwood chat ${subdomain} init`));
|
|
2679
2713
|
}
|
|
2714
|
+
try {
|
|
2715
|
+
const cron = await loadCron();
|
|
2716
|
+
const cronResult = cron.registerSyndicateCrons(subdomain, isTestnet(), getNotifyTo());
|
|
2717
|
+
if (cronResult.isOpenClaw && cronResult.registered) {
|
|
2718
|
+
console.log(G3(" \u2713 Participation crons registered (15m check + hourly summary)"));
|
|
2719
|
+
} else if (!cronResult.isOpenClaw) {
|
|
2720
|
+
console.log(DIM3(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
|
|
2721
|
+
}
|
|
2722
|
+
} catch {
|
|
2723
|
+
}
|
|
2680
2724
|
spinner.stop();
|
|
2681
2725
|
console.log();
|
|
2682
2726
|
console.log(LABEL3(" \u25C6 Syndicate Created"));
|
|
@@ -2910,6 +2954,16 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
|
|
|
2910
2954
|
} catch {
|
|
2911
2955
|
console.warn(chalk7.yellow(" \u26A0 Could not initialize XMTP identity"));
|
|
2912
2956
|
}
|
|
2957
|
+
try {
|
|
2958
|
+
const cron = await loadCron();
|
|
2959
|
+
const cronResult = cron.registerSyndicateCrons(opts.subdomain, isTestnet(), getNotifyTo());
|
|
2960
|
+
if (cronResult.isOpenClaw && cronResult.registered) {
|
|
2961
|
+
console.log(chalk7.green(" \u2713 Participation crons registered"));
|
|
2962
|
+
} else if (!cronResult.isOpenClaw) {
|
|
2963
|
+
console.log(chalk7.dim(" Tip: Set up a scheduled process to run `sherwood session check " + opts.subdomain + "` periodically"));
|
|
2964
|
+
}
|
|
2965
|
+
} catch {
|
|
2966
|
+
}
|
|
2913
2967
|
return;
|
|
2914
2968
|
}
|
|
2915
2969
|
spinner.text = "Checking pending requests...";
|
|
@@ -2947,6 +3001,16 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
|
|
|
2947
3001
|
spinner.succeed("Join request created");
|
|
2948
3002
|
console.warn(chalk7.yellow(" \u26A0 Could not initialize XMTP identity \u2014 creator may not be able to auto-add you to chat"));
|
|
2949
3003
|
}
|
|
3004
|
+
try {
|
|
3005
|
+
const cron = await loadCron();
|
|
3006
|
+
const cronResult = cron.registerSyndicateCrons(opts.subdomain, isTestnet(), getNotifyTo());
|
|
3007
|
+
if (cronResult.isOpenClaw && cronResult.registered) {
|
|
3008
|
+
console.log(G3(" \u2713 Participation crons registered (will activate after approval)"));
|
|
3009
|
+
} else if (!cronResult.isOpenClaw) {
|
|
3010
|
+
console.log(DIM3(" Tip: Set up a scheduled process to run `sherwood session check " + opts.subdomain + "` periodically"));
|
|
3011
|
+
}
|
|
3012
|
+
} catch {
|
|
3013
|
+
}
|
|
2950
3014
|
console.log();
|
|
2951
3015
|
console.log(LABEL3(" \u25C6 Join Request Submitted"));
|
|
2952
3016
|
SEP3();
|
|
@@ -3266,7 +3330,7 @@ strategy.command("run").description("Execute the levered swap strategy").option(
|
|
|
3266
3330
|
await runLeveredSwap(opts);
|
|
3267
3331
|
});
|
|
3268
3332
|
program.command("providers").description("List available DeFi providers").action(async () => {
|
|
3269
|
-
const { MessariProvider, NansenProvider } = await import("./research-
|
|
3333
|
+
const { MessariProvider, NansenProvider } = await import("./research-HEZP7VPY.js");
|
|
3270
3334
|
const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
|
|
3271
3335
|
for (const p of providers) {
|
|
3272
3336
|
const info = p.info();
|
|
@@ -3277,7 +3341,7 @@ ${info.name} (${info.type})`);
|
|
|
3277
3341
|
}
|
|
3278
3342
|
});
|
|
3279
3343
|
try {
|
|
3280
|
-
const { registerChatCommands } = await import("./chat-
|
|
3344
|
+
const { registerChatCommands } = await import("./chat-2X5FQI5X.js");
|
|
3281
3345
|
registerChatCommands(program);
|
|
3282
3346
|
} catch {
|
|
3283
3347
|
program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
|
|
@@ -3287,17 +3351,17 @@ try {
|
|
|
3287
3351
|
process.exit(1);
|
|
3288
3352
|
});
|
|
3289
3353
|
}
|
|
3290
|
-
var { registerSessionCommands } = await import("./session-
|
|
3354
|
+
var { registerSessionCommands } = await import("./session-QBWUWXCH.js");
|
|
3291
3355
|
registerSessionCommands(program);
|
|
3292
3356
|
registerVeniceCommands(program);
|
|
3293
3357
|
registerAllowanceCommands(program);
|
|
3294
3358
|
registerIdentityCommands(program);
|
|
3295
3359
|
registerProposalCommands(program);
|
|
3296
3360
|
registerGovernorCommands(program);
|
|
3297
|
-
var { registerResearchCommands } = await import("./research-
|
|
3361
|
+
var { registerResearchCommands } = await import("./research-PLYYYJ4F.js");
|
|
3298
3362
|
registerResearchCommands(program);
|
|
3299
3363
|
var configCmd = program.command("config");
|
|
3300
|
-
configCmd.command("set").description("Save settings to ~/.sherwood/config.json (persists across sessions)").option("--private-key <key>", "Wallet private key (0x-prefixed)").option("--vault <address>", "Default SyndicateVault address").option("--rpc <url>", "Custom RPC URL for the active --chain network").action((opts) => {
|
|
3364
|
+
configCmd.command("set").description("Save settings to ~/.sherwood/config.json (persists across sessions)").option("--private-key <key>", "Wallet private key (0x-prefixed)").option("--vault <address>", "Default SyndicateVault address").option("--rpc <url>", "Custom RPC URL for the active --chain network").option("--notify-to <id>", "Destination for cron summaries (Telegram chat ID, phone, etc.)").action((opts) => {
|
|
3301
3365
|
let saved = false;
|
|
3302
3366
|
if (opts.privateKey) {
|
|
3303
3367
|
setPrivateKey(opts.privateKey);
|
|
@@ -3320,8 +3384,14 @@ configCmd.command("set").description("Save settings to ~/.sherwood/config.json (
|
|
|
3320
3384
|
console.log(chalk7.dim(` RPC: ${opts.rpc}`));
|
|
3321
3385
|
saved = true;
|
|
3322
3386
|
}
|
|
3387
|
+
if (opts.notifyTo) {
|
|
3388
|
+
setNotifyTo(opts.notifyTo);
|
|
3389
|
+
console.log(chalk7.green("Notify destination saved to ~/.sherwood/config.json"));
|
|
3390
|
+
console.log(chalk7.dim(` Notify to: ${opts.notifyTo}`));
|
|
3391
|
+
saved = true;
|
|
3392
|
+
}
|
|
3323
3393
|
if (!saved) {
|
|
3324
|
-
console.log(chalk7.red("Provide at least one of: --private-key, --vault, --rpc"));
|
|
3394
|
+
console.log(chalk7.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to"));
|
|
3325
3395
|
process.exit(1);
|
|
3326
3396
|
}
|
|
3327
3397
|
});
|