@sherwoodagent/cli 0.72.0 → 0.73.1

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.
Files changed (61) hide show
  1. package/dist/{addresses-HJDYFLWZ.js → addresses-YDPUPGWQ.js} +3 -3
  2. package/dist/{agent-6OJKQVEG.js → agent-6IRZUPFT.js} +6 -6
  3. package/dist/{chat-2DKD3QPA.js → chat-ONGVCWAP.js} +9 -9
  4. package/dist/{chunk-6SRIVGAV.js → chunk-3NMJ4LUL.js} +4 -4
  5. package/dist/{chunk-OZLX666C.js → chunk-52U76TRE.js} +2 -2
  6. package/dist/{chunk-SVSJNZ5D.js → chunk-D4SPHYXA.js} +4 -4
  7. package/dist/{chunk-ASF2WTSW.js → chunk-FOAX5PGR.js} +4 -4
  8. package/dist/{chunk-GT3KCKF6.js → chunk-FOS47623.js} +9 -6
  9. package/dist/chunk-FOS47623.js.map +1 -0
  10. package/dist/{chunk-RNASYOQT.js → chunk-HYUUR6SC.js} +2 -2
  11. package/dist/chunk-HYUUR6SC.js.map +1 -0
  12. package/dist/{chunk-ITZT5HD4.js → chunk-NWY2U753.js} +2 -2
  13. package/dist/{chunk-YLYANZMC.js → chunk-RAITRCM7.js} +2 -2
  14. package/dist/{chunk-PDUGL4EY.js → chunk-S6XA7PK4.js} +22 -4
  15. package/dist/chunk-S6XA7PK4.js.map +1 -0
  16. package/dist/{chunk-3YUMQGJD.js → chunk-UUHWD7Y3.js} +4 -4
  17. package/dist/{chunk-UC5RMCB3.js → chunk-WECQ6NVS.js} +2 -2
  18. package/dist/{chunk-ZYXFKVYF.js → chunk-XDGCHURW.js} +17 -1
  19. package/dist/chunk-XDGCHURW.js.map +1 -0
  20. package/dist/{client-K4JCNPVV.js → client-QN6SA76M.js} +3 -3
  21. package/dist/{eas-ZXGUNYC5.js → eas-HM2AUOEY.js} +5 -5
  22. package/dist/{governor-CV5PITE3.js → governor-RRBTDGDX.js} +9 -5
  23. package/dist/index.js +132 -61
  24. package/dist/index.js.map +1 -1
  25. package/dist/{ipfs-VGWTUORE.js → ipfs-RWSTXTZM.js} +4 -2
  26. package/dist/{network-DHWEYXP2.js → network-L6JKNYOJ.js} +2 -2
  27. package/dist/{price-GOX6P4NT.js → price-AJ4JMHCT.js} +4 -4
  28. package/dist/{research-6D7NNJX4.js → research-2AFNVV7X.js} +8 -8
  29. package/dist/{research-EFNVHU7G.js → research-7Z6SFPPX.js} +4 -4
  30. package/dist/{session-LDLW66K3.js → session-6FMZMPCE.js} +10 -10
  31. package/dist/{trade-7NNZXP5B.js → trade-YTGLGCRQ.js} +14 -14
  32. package/dist/{vault-SIL4QL5U.js → vault-NIPA5JV4.js} +5 -5
  33. package/dist/{xmtp-QNOVDLXX.js → xmtp-M32JSE4I.js} +6 -6
  34. package/package.json +1 -1
  35. package/dist/chunk-GT3KCKF6.js.map +0 -1
  36. package/dist/chunk-PDUGL4EY.js.map +0 -1
  37. package/dist/chunk-RNASYOQT.js.map +0 -1
  38. package/dist/chunk-ZYXFKVYF.js.map +0 -1
  39. /package/dist/{addresses-HJDYFLWZ.js.map → addresses-YDPUPGWQ.js.map} +0 -0
  40. /package/dist/{agent-6OJKQVEG.js.map → agent-6IRZUPFT.js.map} +0 -0
  41. /package/dist/{chat-2DKD3QPA.js.map → chat-ONGVCWAP.js.map} +0 -0
  42. /package/dist/{chunk-6SRIVGAV.js.map → chunk-3NMJ4LUL.js.map} +0 -0
  43. /package/dist/{chunk-OZLX666C.js.map → chunk-52U76TRE.js.map} +0 -0
  44. /package/dist/{chunk-SVSJNZ5D.js.map → chunk-D4SPHYXA.js.map} +0 -0
  45. /package/dist/{chunk-ASF2WTSW.js.map → chunk-FOAX5PGR.js.map} +0 -0
  46. /package/dist/{chunk-ITZT5HD4.js.map → chunk-NWY2U753.js.map} +0 -0
  47. /package/dist/{chunk-YLYANZMC.js.map → chunk-RAITRCM7.js.map} +0 -0
  48. /package/dist/{chunk-3YUMQGJD.js.map → chunk-UUHWD7Y3.js.map} +0 -0
  49. /package/dist/{chunk-UC5RMCB3.js.map → chunk-WECQ6NVS.js.map} +0 -0
  50. /package/dist/{client-K4JCNPVV.js.map → client-QN6SA76M.js.map} +0 -0
  51. /package/dist/{eas-ZXGUNYC5.js.map → eas-HM2AUOEY.js.map} +0 -0
  52. /package/dist/{governor-CV5PITE3.js.map → governor-RRBTDGDX.js.map} +0 -0
  53. /package/dist/{ipfs-VGWTUORE.js.map → ipfs-RWSTXTZM.js.map} +0 -0
  54. /package/dist/{network-DHWEYXP2.js.map → network-L6JKNYOJ.js.map} +0 -0
  55. /package/dist/{price-GOX6P4NT.js.map → price-AJ4JMHCT.js.map} +0 -0
  56. /package/dist/{research-6D7NNJX4.js.map → research-2AFNVV7X.js.map} +0 -0
  57. /package/dist/{research-EFNVHU7G.js.map → research-7Z6SFPPX.js.map} +0 -0
  58. /package/dist/{session-LDLW66K3.js.map → session-6FMZMPCE.js.map} +0 -0
  59. /package/dist/{trade-7NNZXP5B.js.map → trade-YTGLGCRQ.js.map} +0 -0
  60. /package/dist/{vault-SIL4QL5U.js.map → vault-NIPA5JV4.js.map} +0 -0
  61. /package/dist/{xmtp-QNOVDLXX.js.map → xmtp-M32JSE4I.js.map} +0 -0
@@ -3,9 +3,11 @@ import {
3
3
  PROPOSAL_STATES,
4
4
  VOTE_TYPE,
5
5
  cancelProposal,
6
+ classifyReview,
6
7
  detectStrategyAdapter,
7
8
  emergencyCancel,
8
9
  emergencySettle,
10
+ evaluateExecuteGate,
9
11
  executeProposal,
10
12
  getActiveProposal,
11
13
  getCapitalSnapshot,
@@ -34,10 +36,10 @@ import {
34
36
  settleProposal,
35
37
  vetoProposal,
36
38
  vote
37
- } from "./chunk-PDUGL4EY.js";
38
- import "./chunk-YLYANZMC.js";
39
- import "./chunk-UC5RMCB3.js";
40
- import "./chunk-RNASYOQT.js";
39
+ } from "./chunk-S6XA7PK4.js";
40
+ import "./chunk-RAITRCM7.js";
41
+ import "./chunk-WECQ6NVS.js";
42
+ import "./chunk-HYUUR6SC.js";
41
43
  import "./chunk-GSC7PVEO.js";
42
44
  import "./chunk-BQMOE4FJ.js";
43
45
  export {
@@ -45,9 +47,11 @@ export {
45
47
  PROPOSAL_STATES,
46
48
  VOTE_TYPE,
47
49
  cancelProposal,
50
+ classifyReview,
48
51
  detectStrategyAdapter,
49
52
  emergencyCancel,
50
53
  emergencySettle,
54
+ evaluateExecuteGate,
51
55
  executeProposal,
52
56
  getActiveProposal,
53
57
  getCapitalSnapshot,
@@ -77,4 +81,4 @@ export {
77
81
  vetoProposal,
78
82
  vote
79
83
  };
80
- //# sourceMappingURL=governor-CV5PITE3.js.map
84
+ //# sourceMappingURL=governor-RRBTDGDX.js.map
package/dist/index.js CHANGED
@@ -15,13 +15,13 @@ import {
15
15
  encodeSwapPath,
16
16
  getMultiHopQuote,
17
17
  getQuote
18
- } from "./chunk-SVSJNZ5D.js";
18
+ } from "./chunk-D4SPHYXA.js";
19
19
  import {
20
20
  chatCompletion,
21
21
  checkApiKeyValid,
22
22
  listModels,
23
23
  provisionApiKey
24
- } from "./chunk-OZLX666C.js";
24
+ } from "./chunk-52U76TRE.js";
25
25
  import {
26
26
  createApproval,
27
27
  createJoinRequest,
@@ -32,20 +32,20 @@ import {
32
32
  queryJoinRequests,
33
33
  revokeJoinRequest,
34
34
  stripReferrerPrefix
35
- } from "./chunk-ASF2WTSW.js";
35
+ } from "./chunk-FOAX5PGR.js";
36
36
  import {
37
37
  createFund,
38
38
  getActiveFunds,
39
39
  getFund,
40
40
  subdomainExists,
41
41
  updateMetadata
42
- } from "./chunk-6SRIVGAV.js";
42
+ } from "./chunk-3NMJ4LUL.js";
43
43
  import {
44
44
  resolveFund,
45
45
  resolveVaultFund,
46
46
  searchFundAcrossChains,
47
47
  setTextRecord
48
- } from "./chunk-GT3KCKF6.js";
48
+ } from "./chunk-FOS47623.js";
49
49
  import {
50
50
  approveDepositor,
51
51
  deposit,
@@ -67,14 +67,16 @@ import {
67
67
  removeDepositor,
68
68
  setAgentFeeBps,
69
69
  setVaultAddress
70
- } from "./chunk-3YUMQGJD.js";
70
+ } from "./chunk-UUHWD7Y3.js";
71
71
  import {
72
72
  PROPOSAL_STATE,
73
73
  PROPOSAL_STATES,
74
74
  VOTE_TYPE,
75
75
  cancelProposal,
76
+ classifyReview,
76
77
  emergencyCancel,
77
78
  emergencySettle,
79
+ evaluateExecuteGate,
78
80
  executeProposal,
79
81
  getActiveProposal,
80
82
  getCapitalSnapshot,
@@ -99,7 +101,7 @@ import {
99
101
  setVotingPeriod,
100
102
  settleProposal,
101
103
  vote
102
- } from "./chunk-PDUGL4EY.js";
104
+ } from "./chunk-S6XA7PK4.js";
103
105
  import {
104
106
  AERODROME,
105
107
  AGENT_REGISTRY,
@@ -113,7 +115,7 @@ import {
113
115
  UNISWAP,
114
116
  VENICE,
115
117
  robinhoodEquityMaxAge
116
- } from "./chunk-YLYANZMC.js";
118
+ } from "./chunk-RAITRCM7.js";
117
119
  import {
118
120
  formatContractError,
119
121
  getAccount,
@@ -122,7 +124,7 @@ import {
122
124
  sendTxWithRetry,
123
125
  waitForReceipt,
124
126
  writeContractWithRetry
125
- } from "./chunk-UC5RMCB3.js";
127
+ } from "./chunk-WECQ6NVS.js";
126
128
  import {
127
129
  DEFAULT_NETWORK,
128
130
  VALID_NETWORKS,
@@ -134,7 +136,7 @@ import {
134
136
  isTestnet,
135
137
  setNetwork,
136
138
  withNetwork
137
- } from "./chunk-RNASYOQT.js";
139
+ } from "./chunk-HYUUR6SC.js";
138
140
  import {
139
141
  addFund,
140
142
  cacheGroupId,
@@ -169,8 +171,9 @@ import {
169
171
  } from "./chunk-BQMOE4FJ.js";
170
172
  import {
171
173
  fetchMetadata,
174
+ mergeFundMetadata,
172
175
  uploadMetadata
173
- } from "./chunk-ZYXFKVYF.js";
176
+ } from "./chunk-XDGCHURW.js";
174
177
 
175
178
  // src/index.ts
176
179
  import { config as loadDotenv } from "dotenv";
@@ -1178,13 +1181,17 @@ var ROBINHOOD_L2 = {
1178
1181
  slug: "robinhood-l2",
1179
1182
  // V2 redeploy (chain 46630): fresh core contracts + a full guardian layer
1180
1183
  // (registry + sWOOD) and a deployed StrategyFactory for the keyless
1181
- // clone+init path (#387).
1184
+ // clone+init path (#387). Post-#421 per-vault-governor redeploy — kept in
1185
+ // sync with the canonical source of truth contracts/chains/46630.json (and
1186
+ // the app's app/src/lib/contracts.ts ROBINHOOD_TESTNET_ADDRESSES). A stale
1187
+ // factory here made /api/v1/funds?chain=46630 read the old deployment and
1188
+ // return {count: 0} while the UI listed funds (issue #459).
1182
1189
  sherwood: {
1183
- factory: "0xa5351b91E0A6348a78dA4E47bcd7DFC49fa353F3",
1184
- guardianRegistry: "0xA1b4C376c9C9e7257F654Fe1C4c10f51760407D4",
1185
- vaultImpl: "0x382cCfe80c430De671b15A45A7EDED96b5bFB383",
1186
- batchExecutorLib: "0x039825a3750c27C5f85Bb8486860B867A8D201E5",
1187
- strategyFactory: "0x85a598ADA4fb9654BaF77234864fa100C4B5a204"
1190
+ factory: "0xB9E71Fb33075328d6e94eCFFf8a8629D6d057cce",
1191
+ guardianRegistry: "0x57f0fa384d0d7e2F234535d1235440312866872B",
1192
+ vaultImpl: "0x189160156d470B9ce8A55206DE19Ea60D2638ec6",
1193
+ batchExecutorLib: "0xd83dc3A79Bb41a02Ca7aC812c0f52212C1BdBC1B",
1194
+ strategyFactory: "0xE1D082ef1CE17f9C6a46e97928337267BFF0C309"
1188
1195
  },
1189
1196
  // No ERC-8004 registry and no EAS path on Robinhood L2.
1190
1197
  identityRegistry: ZERO_ADDRESS,
@@ -3510,7 +3517,7 @@ function registerStrategyTemplateCommands(strategy2) {
3510
3517
  process.exit(1);
3511
3518
  }
3512
3519
  if (!opts.agent) opts.agent = proposer;
3513
- const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-CV5PITE3.js");
3520
+ const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-RRBTDGDX.js");
3514
3521
  const strategyDuration2 = parseDuration3(opts.duration);
3515
3522
  const chainId = getChain().id;
3516
3523
  try {
@@ -3736,9 +3743,9 @@ function registerStrategyTemplateCommands(strategy2) {
3736
3743
  console.error(chalk.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
3737
3744
  process.exit(1);
3738
3745
  }
3739
- const { propose: propose2 } = await import("./governor-CV5PITE3.js");
3740
- const { pinJSON } = await import("./ipfs-VGWTUORE.js");
3741
- const { parseDuration: parseDuration2 } = await import("./governor-CV5PITE3.js");
3746
+ const { propose: propose2 } = await import("./governor-RRBTDGDX.js");
3747
+ const { pinJSON } = await import("./ipfs-RWSTXTZM.js");
3748
+ const { parseDuration: parseDuration2 } = await import("./governor-RRBTDGDX.js");
3742
3749
  const strategyDuration = parseDuration2(opts.duration);
3743
3750
  const metaSpinner = ora("Pinning metadata to IPFS...").start();
3744
3751
  let metadataURI;
@@ -3761,7 +3768,7 @@ function registerStrategyTemplateCommands(strategy2) {
3761
3768
  process.exit(1);
3762
3769
  }
3763
3770
  try {
3764
- const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-SIL4QL5U.js");
3771
+ const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-NIPA5JV4.js");
3765
3772
  const feeBps = await getAgentFeeBps2(vault);
3766
3773
  console.log(
3767
3774
  chalk.yellow(
@@ -3849,7 +3856,7 @@ function registerStrategyTemplateCommands(strategy2) {
3849
3856
  let prices = [];
3850
3857
  let priceSource = null;
3851
3858
  try {
3852
- const { getTokenPricesInAsset } = await import("./price-GOX6P4NT.js");
3859
+ const { getTokenPricesInAsset } = await import("./price-AJ4JMHCT.js");
3853
3860
  prices = await getTokenPricesInAsset({
3854
3861
  tokens: allocations.map((a, i) => ({
3855
3862
  token: a.token,
@@ -4279,7 +4286,7 @@ function registerVeniceCommands(program2) {
4279
4286
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
4280
4287
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
4281
4288
  try {
4282
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-ZXGUNYC5.js");
4289
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-HM2AUOEY.js");
4283
4290
  const { uid } = await createVeniceProvisionAttestation(account.address);
4284
4291
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
4285
4292
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -4635,10 +4642,10 @@ ${opts.prompt}`;
4635
4642
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
4636
4643
  }
4637
4644
  try {
4638
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-ZXGUNYC5.js");
4645
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-HM2AUOEY.js");
4639
4646
  const { keccak256: keccak2563, toHex, isAddress: isAddr } = await import("viem");
4640
4647
  const { getChainContracts: getChainContracts2 } = await import("./config-FAQO37S7.js");
4641
- const { getChain: getActiveChain } = await import("./network-DHWEYXP2.js");
4648
+ const { getChain: getActiveChain } = await import("./network-L6JKNYOJ.js");
4642
4649
  const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
4643
4650
  const promptHash = keccak2563(toHex(userContent)).slice(0, 18);
4644
4651
  const { uid } = await createVeniceInferenceAttestation(
@@ -5893,8 +5900,8 @@ function printSimulationResult(result, callType) {
5893
5900
  }
5894
5901
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
5895
5902
  try {
5896
- const xmtp = await import("./xmtp-QNOVDLXX.js");
5897
- const { getAccount: getAccount2 } = await import("./client-K4JCNPVV.js");
5903
+ const xmtp = await import("./xmtp-M32JSE4I.js");
5904
+ const { getAccount: getAccount2 } = await import("./client-QN6SA76M.js");
5898
5905
  const group = await xmtp.getGroup("", subdomain);
5899
5906
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
5900
5907
  const criticals = allRisks.filter((r) => r.level === "critical");
@@ -6388,13 +6395,35 @@ function registerProposalCommands(program2) {
6388
6395
  return;
6389
6396
  }
6390
6397
  const spinner = ora5("Loading proposal...").start();
6391
- const state = await getProposalState(vault, proposalId);
6392
- if (state !== PROPOSAL_STATE.Approved) {
6398
+ const [state, p, latestBlock] = await Promise.all([
6399
+ getProposalState(vault, proposalId),
6400
+ getProposal(vault, proposalId),
6401
+ getPublicClient().getBlock()
6402
+ ]);
6403
+ const now = latestBlock.timestamp;
6404
+ const gate = evaluateExecuteGate({
6405
+ state,
6406
+ reviewEnd: p.reviewEnd,
6407
+ executeBy: p.executeBy,
6408
+ now
6409
+ });
6410
+ if (gate.kind === "refuse-review-open") {
6411
+ spinner.fail(
6412
+ `Proposal is in GuardianReview \u2014 the review window is open until ${formatTimestamp(p.reviewEnd)}. Execute once the window closes; the execute self-resolves the review.`
6413
+ );
6414
+ process.exit(1);
6415
+ }
6416
+ if (gate.kind === "refuse-expired") {
6417
+ spinner.fail(
6418
+ `Proposal expired \u2014 the execution window closed at ${formatTimestamp(p.executeBy)} (execute-by). An elapsed GuardianReview past execute-by resolves to Expired and can no longer be executed.`
6419
+ );
6420
+ process.exit(1);
6421
+ }
6422
+ if (gate.kind === "refuse-state") {
6393
6423
  spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"}, not Approved`);
6394
6424
  process.exit(1);
6395
6425
  }
6396
6426
  if (opts.dryRun) {
6397
- const p = await getProposal(vault, proposalId);
6398
6427
  const execCalls = await getExecuteCalls(vault, proposalId);
6399
6428
  const dryRunContext = {
6400
6429
  vault: p.vault,
@@ -6408,7 +6437,16 @@ function registerProposalCommands(program2) {
6408
6437
  const hasCritical = result.risks.some((r) => r.level === "critical");
6409
6438
  process.exit(result.success && !hasCritical ? 0 : 1);
6410
6439
  }
6411
- spinner.text = W2("Executing proposal...");
6440
+ if (gate.kind === "send-self-resolve") {
6441
+ spinner.info(
6442
+ DIM2(
6443
+ "GuardianReview window elapsed with no cached resolution \u2014 execute will self-resolve the review inline (cold-start / not blocked) and proceed."
6444
+ )
6445
+ );
6446
+ spinner.start(W2("Executing proposal..."));
6447
+ } else {
6448
+ spinner.text = W2("Executing proposal...");
6449
+ }
6412
6450
  const hash = await executeProposal(vault, proposalId);
6413
6451
  spinner.succeed(G2("Proposal executed"));
6414
6452
  console.log(DIM2(` ${getExplorerUrl(hash)}`));
@@ -6442,14 +6480,17 @@ function registerProposalCommands(program2) {
6442
6480
  }
6443
6481
  const account = getAccount();
6444
6482
  const spinner = ora5("Loading proposal...").start();
6445
- const p = await getProposal(vault, proposalId);
6446
- const state = await getProposalState(vault, proposalId);
6483
+ const [p, state, latestBlock] = await Promise.all([
6484
+ getProposal(vault, proposalId),
6485
+ getProposalState(vault, proposalId),
6486
+ getPublicClient().getBlock()
6487
+ ]);
6447
6488
  if (state !== PROPOSAL_STATE.Executed) {
6448
6489
  spinner.fail(`Proposal is ${PROPOSAL_STATES[state] || "Unknown"}, not Executed`);
6449
6490
  process.exit(1);
6450
6491
  }
6451
6492
  const isProposer = account.address.toLowerCase() === p.proposer.toLowerCase();
6452
- const now = BigInt(Math.floor(Date.now() / 1e3));
6493
+ const now = latestBlock.timestamp;
6453
6494
  const durationElapsed = p.executedAt > 0n && now >= p.executedAt + p.strategyDuration;
6454
6495
  let hash;
6455
6496
  if (isProposer && !durationElapsed) {
@@ -6637,18 +6678,41 @@ function registerProposalCommands(program2) {
6637
6678
  args: [governorAddr, id]
6638
6679
  })
6639
6680
  ]);
6640
- const [, resolved2] = reviewState;
6641
- const resolvable2 = !resolved2 && p.reviewEnd > 0n && now >= p.reviewEnd;
6642
- return { id, resolvable: resolvable2, reviewEnd: p.reviewEnd, vault: p.vault };
6681
+ const [opened, resolved2] = reviewState;
6682
+ const cls = classifyReview({ opened, resolved: resolved2, reviewEnd: p.reviewEnd, now });
6683
+ return { id, cls, reviewEnd: p.reviewEnd, vault: p.vault };
6643
6684
  } catch {
6644
- return { id, resolvable: false, reviewEnd: 0n, vault: "0x" };
6685
+ return { id, cls: "none", reviewEnd: 0n, vault: "0x" };
6645
6686
  }
6646
6687
  })
6647
6688
  );
6648
- const resolvable = candidates.filter((c) => c.resolvable);
6689
+ const resolvable = candidates.filter((c) => c.cls === "resolvable");
6690
+ const coldStart = candidates.filter((c) => c.cls === "cold-start");
6649
6691
  spinner.stop();
6692
+ if (coldStart.length > 0) {
6693
+ console.log();
6694
+ console.log(LABEL2(` \u25C6 Unopened Cold-Start Reviews (${coldStart.length})`));
6695
+ SEP2();
6696
+ for (const c of coldStart) {
6697
+ console.log(
6698
+ W2(` Proposal #${c.id} vault=${c.vault} reviewEnd=${formatTimestamp(c.reviewEnd)}`)
6699
+ );
6700
+ console.log(
6701
+ DIM2(
6702
+ ` No guardian review was opened (zero-guardian cold start) \u2014 nothing to resolve on-chain.
6703
+ Directly executable: sherwood proposal execute --id ${c.id} --vault ${c.vault}
6704
+ (execute self-resolves the review inline).`
6705
+ )
6706
+ );
6707
+ }
6708
+ SEP2();
6709
+ }
6650
6710
  if (resolvable.length === 0) {
6651
- console.log(DIM2("\n No reviews ready to resolve.\n"));
6711
+ if (coldStart.length === 0) {
6712
+ console.log(DIM2("\n No reviews ready to resolve.\n"));
6713
+ } else {
6714
+ console.log(DIM2("\n No opened reviews need an on-chain resolve.\n"));
6715
+ }
6652
6716
  return;
6653
6717
  }
6654
6718
  console.log();
@@ -10272,9 +10336,9 @@ try {
10272
10336
  } catch {
10273
10337
  }
10274
10338
  var require2 = createRequire(import.meta.url);
10275
- var CLI_VERSION = "0.72.0";
10339
+ var CLI_VERSION = "0.73.1";
10276
10340
  async function loadXmtp() {
10277
- return import("./xmtp-QNOVDLXX.js");
10341
+ return import("./xmtp-M32JSE4I.js");
10278
10342
  }
10279
10343
  async function loadCron() {
10280
10344
  return import("./cron-QMLRWDJG.js");
@@ -10739,18 +10803,25 @@ fund.command("update-metadata").description("Update fund metadata (creator only)
10739
10803
  spinner.fail(`Fund #${opts.id} not found.`);
10740
10804
  process.exit(1);
10741
10805
  }
10742
- const name = opts.name || info.subdomain;
10743
- const description = opts.description || `${name} \u2014 a Sherwood fund on ${info.subdomain}.sherwoodagent.eth`;
10806
+ spinner.text = W6("Fetching current metadata...");
10807
+ let current = null;
10808
+ try {
10809
+ current = await fetchMetadata(info.metadataURI);
10810
+ } catch (fetchErr) {
10811
+ console.warn(
10812
+ chalk16.yellow(
10813
+ " \u26A0 Could not fetch current metadata \u2014 rebuilding from flags (unknown fields like xmtpGroupId may be dropped)"
10814
+ )
10815
+ );
10816
+ console.warn(DIM6(` ${fetchErr instanceof Error ? fetchErr.message : String(fetchErr)}`));
10817
+ }
10744
10818
  spinner.text = W6("Uploading metadata to IPFS...");
10745
- const metadata = {
10746
- schema: "sherwood/fund/v1",
10747
- name,
10748
- description,
10749
- chain: getChain().name,
10750
- strategies: [],
10751
- terms: {},
10752
- links: {}
10753
- };
10819
+ const metadata = mergeFundMetadata(current, {
10820
+ name: opts.name,
10821
+ description: opts.description,
10822
+ subdomain: info.subdomain,
10823
+ defaultChain: getChain().name
10824
+ });
10754
10825
  metadataURI = await uploadMetadata(metadata);
10755
10826
  spinner.text = W6("Updating on-chain metadata...");
10756
10827
  }
@@ -10859,7 +10930,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
10859
10930
  if (opts.agentId) {
10860
10931
  agentId = BigInt(opts.agentId);
10861
10932
  } else {
10862
- const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-HJDYFLWZ.js");
10933
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-YDPUPGWQ.js");
10863
10934
  const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
10864
10935
  if (registry === "0x0000000000000000000000000000000000000000") {
10865
10936
  agentId = 0n;
@@ -11585,7 +11656,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
11585
11656
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
11586
11657
  registerStrategyTemplateCommands(strategy);
11587
11658
  program.command("providers").description("List available DeFi providers").action(async () => {
11588
- const { MessariProvider, NansenProvider } = await import("./research-EFNVHU7G.js");
11659
+ const { MessariProvider, NansenProvider } = await import("./research-7Z6SFPPX.js");
11589
11660
  const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
11590
11661
  for (const p of providers) {
11591
11662
  const info = p.info();
@@ -11596,7 +11667,7 @@ ${info.name} (${info.type})`);
11596
11667
  }
11597
11668
  });
11598
11669
  try {
11599
- const { registerChatCommands } = await import("./chat-2DKD3QPA.js");
11670
+ const { registerChatCommands } = await import("./chat-ONGVCWAP.js");
11600
11671
  registerChatCommands(program);
11601
11672
  } catch {
11602
11673
  program.command("chat <name> [action] [actionArgs...]").description("Fund chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -11606,7 +11677,7 @@ try {
11606
11677
  process.exit(1);
11607
11678
  });
11608
11679
  }
11609
- var { registerSessionCommands } = await import("./session-LDLW66K3.js");
11680
+ var { registerSessionCommands } = await import("./session-6FMZMPCE.js");
11610
11681
  registerSessionCommands(program);
11611
11682
  registerVeniceCommands(program);
11612
11683
  registerAllowanceCommands(program);
@@ -11615,11 +11686,11 @@ registerProposalCommands(program);
11615
11686
  registerQueueCommands(program);
11616
11687
  registerGovernorCommands(program);
11617
11688
  registerGuardianCommands(program);
11618
- var { registerResearchCommands } = await import("./research-6D7NNJX4.js");
11689
+ var { registerResearchCommands } = await import("./research-2AFNVV7X.js");
11619
11690
  registerResearchCommands(program);
11620
- var { registerAgentCommands } = await import("./agent-6OJKQVEG.js");
11691
+ var { registerAgentCommands } = await import("./agent-6IRZUPFT.js");
11621
11692
  registerAgentCommands(program);
11622
- var { registerTradeCommands } = await import("./trade-7NNZXP5B.js");
11693
+ var { registerTradeCommands } = await import("./trade-YTGLGCRQ.js");
11623
11694
  registerTradeCommands(program);
11624
11695
  registerGridCommand(program);
11625
11696
  var configCmd = program.command("config");