@dev.sail.money/sailor 1.2.1-90 → 1.2.1-92

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 (101) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/packages/cli/dist/index.cjs +239 -99
  4. package/packages/sdk/dist/intelligence.d.ts +1 -1
  5. package/packages/sdk/dist/intelligence.js +1 -1
  6. package/packages/ui/dist/assets/{add-R0xP2zko.js → add-DxdePWzw.js} +1 -1
  7. package/packages/ui/dist/assets/{all-wallets-qnzttqV_.js → all-wallets-CcDyr50U.js} +1 -1
  8. package/packages/ui/dist/assets/{app-store-DpKGxR0G.js → app-store-BCSHe8EN.js} +1 -1
  9. package/packages/ui/dist/assets/{apple-Ckb9o1LK.js → apple-Cio1eVvD.js} +1 -1
  10. package/packages/ui/dist/assets/{arrow-bottom-D1FAx-yB.js → arrow-bottom-BlzVLDUl.js} +1 -1
  11. package/packages/ui/dist/assets/{arrow-bottom-circle-BH2TcYm0.js → arrow-bottom-circle-Bi45LFFD.js} +1 -1
  12. package/packages/ui/dist/assets/{arrow-left-CaaYjdtV.js → arrow-left-B3VkjnnJ.js} +1 -1
  13. package/packages/ui/dist/assets/{arrow-right-DW-rnoD_.js → arrow-right-5DrDm6ll.js} +1 -1
  14. package/packages/ui/dist/assets/{arrow-top-M7CVCSnU.js → arrow-top-wcXizC-G.js} +1 -1
  15. package/packages/ui/dist/assets/{bank-DVbh1inT.js → bank-SqJo5jS7.js} +1 -1
  16. package/packages/ui/dist/assets/{basic-BWLPh793.js → basic-BgCrxFS4.js} +1 -1
  17. package/packages/ui/dist/assets/{browser-BW0QiXeN.js → browser-DI6l7Tng.js} +1 -1
  18. package/packages/ui/dist/assets/{card-BNNvJESX.js → card-DjP6FOz-.js} +1 -1
  19. package/packages/ui/dist/assets/{ccip-C2ivRCFf.js → ccip-CKVRZdQQ.js} +1 -1
  20. package/packages/ui/dist/assets/{checkmark-FoCkBDzR.js → checkmark-CBdVh2Kg.js} +1 -1
  21. package/packages/ui/dist/assets/{checkmark-bold-B7P2Bvsd.js → checkmark-bold-DvvsfN8H.js} +1 -1
  22. package/packages/ui/dist/assets/{chevron-bottom-DOhAc7rS.js → chevron-bottom-BBTXniKn.js} +1 -1
  23. package/packages/ui/dist/assets/{chevron-left-BiWf2KCl.js → chevron-left-LL7HKhOV.js} +1 -1
  24. package/packages/ui/dist/assets/{chevron-right-BH7i9-GZ.js → chevron-right-BT3XvCea.js} +1 -1
  25. package/packages/ui/dist/assets/{chevron-top-C9zp-WFB.js → chevron-top-D3lHXBcd.js} +1 -1
  26. package/packages/ui/dist/assets/{chrome-store-vDr9wSYG.js → chrome-store-BOzOVwkP.js} +1 -1
  27. package/packages/ui/dist/assets/{clock-CZlsrGmg.js → clock-JbWtGDR2.js} +1 -1
  28. package/packages/ui/dist/assets/{close-C7369YAf.js → close-ZT_Jiw1f.js} +1 -1
  29. package/packages/ui/dist/assets/{coinPlaceholder-CEONEmQj.js → coinPlaceholder-C-Csq_lw.js} +1 -1
  30. package/packages/ui/dist/assets/{compass-DzhhABp6.js → compass-XKXG-uKY.js} +1 -1
  31. package/packages/ui/dist/assets/{copy-zuwgIOLp.js → copy-BI6jLoZK.js} +1 -1
  32. package/packages/ui/dist/assets/{core-DjR_jD64.js → core-BLwyu_UZ.js} +3 -3
  33. package/packages/ui/dist/assets/cursor-jNUI_tHN.js +3 -0
  34. package/packages/ui/dist/assets/{cursor-transparent-DQOaLcvd.js → cursor-transparent-CFZylRzv.js} +1 -1
  35. package/packages/ui/dist/assets/{desktop-Bv7fy2f-.js → desktop-Hl3xhHy9.js} +1 -1
  36. package/packages/ui/dist/assets/{disconnect-DT21kQcX.js → disconnect-DW6U-dN7.js} +1 -1
  37. package/packages/ui/dist/assets/{discord-DnM6J12l.js → discord-BkDRI6sB.js} +1 -1
  38. package/packages/ui/dist/assets/{etherscan-CkYGysSe.js → etherscan-DM0DlV8l.js} +1 -1
  39. package/packages/ui/dist/assets/{events-Bzlx_C-j.js → events-DuWTfKWm.js} +1 -1
  40. package/packages/ui/dist/assets/{exclamation-triangle-CowxL_9E.js → exclamation-triangle-BJXppW_n.js} +1 -1
  41. package/packages/ui/dist/assets/{extension-Dq3IsAUN.js → extension-CVwJSN6F.js} +1 -1
  42. package/packages/ui/dist/assets/{external-link-CVa7Or9W.js → external-link-9T1VC3J9.js} +1 -1
  43. package/packages/ui/dist/assets/{facebook-CeigZ-Dq.js → facebook-R1848HX9.js} +1 -1
  44. package/packages/ui/dist/assets/{fallback-QmdVrhdj.js → fallback-BQyFegq4.js} +1 -1
  45. package/packages/ui/dist/assets/{farcaster-CmxCGnX5.js → farcaster-C8lScwHE.js} +1 -1
  46. package/packages/ui/dist/assets/{filters-CY5pHglU.js → filters-D_hUKJc6.js} +1 -1
  47. package/packages/ui/dist/assets/{github-DrSj44zE.js → github-BUdSlQ0g.js} +1 -1
  48. package/packages/ui/dist/assets/{google-DTfyabXp.js → google-DCVSiGyR.js} +1 -1
  49. package/packages/ui/dist/assets/{help-circle-kFOxdrQz.js → help-circle-BmbA9WiR.js} +1 -1
  50. package/packages/ui/dist/assets/{id-5pW65QwE.js → id-BpZ2AesF.js} +1 -1
  51. package/packages/ui/dist/assets/{image-D2FlAtVU.js → image-D9OlBR50.js} +1 -1
  52. package/packages/ui/dist/assets/{index-DxcSXSQt.js → index-BcngInt2.js} +1 -1
  53. package/packages/ui/dist/assets/{index-C62B8KTP.js → index-BmKpVmQo.js} +30 -30
  54. package/packages/ui/dist/assets/{index-BkS9kyuf.js → index-CFdoQ0C9.js} +1 -1
  55. package/packages/ui/dist/assets/{index-DZwl1NkD.js → index-Cw74yaCx.js} +1 -1
  56. package/packages/ui/dist/assets/{index-CNJJ8w4T.js → index-DnTTITgJ.js} +3 -3
  57. package/packages/ui/dist/assets/{index-CqeISmow.js → index-VuBRR5Ee.js} +1 -1
  58. package/packages/ui/dist/assets/{index.es-CdKoInzi.js → index.es-Cwe8eYYQ.js} +4 -4
  59. package/packages/ui/dist/assets/{info-DbUUs-7h.js → info-CsTScSXv.js} +1 -1
  60. package/packages/ui/dist/assets/{info-circle-pK0azOfA.js → info-circle-C85unnhg.js} +1 -1
  61. package/packages/ui/dist/assets/{lightbulb-BapmKP8y.js → lightbulb-DNRTVt--.js} +1 -1
  62. package/packages/ui/dist/assets/{mail-CdYd0Rh9.js → mail-lo_xlG5y.js} +1 -1
  63. package/packages/ui/dist/assets/{metamask-sdk-CmHF3TFo.js → metamask-sdk-D_zgrb2L.js} +1 -1
  64. package/packages/ui/dist/assets/{mobile-DkjGiGYO.js → mobile-CeziQrHs.js} +1 -1
  65. package/packages/ui/dist/assets/{more-BsU5N8hZ.js → more-BJJ25Bco.js} +1 -1
  66. package/packages/ui/dist/assets/{network-placeholder-DLlzj024.js → network-placeholder-C2bTejHc.js} +1 -1
  67. package/packages/ui/dist/assets/{nftPlaceholder-D2naVFFA.js → nftPlaceholder-P9e90e3l.js} +1 -1
  68. package/packages/ui/dist/assets/{off-O4fs0RcI.js → off-Cf9Lcmke.js} +1 -1
  69. package/packages/ui/dist/assets/{parseSignature-Ipc8B6L-.js → parseSignature-D3jDGZxJ.js} +1 -1
  70. package/packages/ui/dist/assets/{play-store-BySsEKjB.js → play-store-CIvfWMTw.js} +1 -1
  71. package/packages/ui/dist/assets/{plus-DcwXbThh.js → plus-y4ZSXf_2.js} +1 -1
  72. package/packages/ui/dist/assets/{qr-code-DXcikaWN.js → qr-code-BHKbMyiU.js} +1 -1
  73. package/packages/ui/dist/assets/{recycle-horizontal-QHdoxezF.js → recycle-horizontal-IClLWZNS.js} +1 -1
  74. package/packages/ui/dist/assets/{refresh-CimMVwX6.js → refresh-DGceqRDA.js} +1 -1
  75. package/packages/ui/dist/assets/{reown-logo-DAmY3tUR.js → reown-logo-Bv7sNHvL.js} +1 -1
  76. package/packages/ui/dist/assets/{search-YYHOSKxV.js → search-CRgTCcsE.js} +1 -1
  77. package/packages/ui/dist/assets/{secp256k1-DziXvsDr.js → secp256k1-Cqp3PtVi.js} +1 -1
  78. package/packages/ui/dist/assets/{send-BohgZ4SZ.js → send-DU6bIrPo.js} +1 -1
  79. package/packages/ui/dist/assets/{swapHorizontal-gdiztcz1.js → swapHorizontal-gFwRhx0T.js} +1 -1
  80. package/packages/ui/dist/assets/{swapHorizontalBold-C4PPuw1r.js → swapHorizontalBold-JtBzA3Ii.js} +1 -1
  81. package/packages/ui/dist/assets/{swapHorizontalMedium-CmhTo_53.js → swapHorizontalMedium-DoYVrxv8.js} +1 -1
  82. package/packages/ui/dist/assets/{swapHorizontalRoundedBold-BPNMkAqM.js → swapHorizontalRoundedBold-CAKgeiv9.js} +1 -1
  83. package/packages/ui/dist/assets/{swapVertical-Cnulu56K.js → swapVertical-D4_Wkrmp.js} +1 -1
  84. package/packages/ui/dist/assets/{telegram-rBBqAA42.js → telegram-DezHeoAw.js} +1 -1
  85. package/packages/ui/dist/assets/{three-dots-DhYHC0m3.js → three-dots-_2l4KYeg.js} +1 -1
  86. package/packages/ui/dist/assets/{twitch-DKwUBfEi.js → twitch-D7lxAEZq.js} +1 -1
  87. package/packages/ui/dist/assets/{twitterIcon-BEW1pHCf.js → twitterIcon-y5jVQyUi.js} +1 -1
  88. package/packages/ui/dist/assets/{verify-BVZjkQ2n.js → verify-Ue3VkpeM.js} +1 -1
  89. package/packages/ui/dist/assets/{verify-filled-BGkV52th.js → verify-filled-DhQ6l5Hx.js} +1 -1
  90. package/packages/ui/dist/assets/{w3m-modal-B7m-K8vL.js → w3m-modal-Dk1A5UT_.js} +1 -1
  91. package/packages/ui/dist/assets/{wallet-BOwiO_Zr.js → wallet-Z5h6x06d.js} +1 -1
  92. package/packages/ui/dist/assets/{wallet-placeholder-C5O9rl_6.js → wallet-placeholder-C56EAJDw.js} +1 -1
  93. package/packages/ui/dist/assets/{walletconnect-CKSy8TKP.js → walletconnect-CIEAhB_r.js} +1 -1
  94. package/packages/ui/dist/assets/{warning-circle-CwXtaT0N.js → warning-circle-DhGvQBv6.js} +1 -1
  95. package/packages/ui/dist/assets/{x-32UJYpvE.js → x-BveyWTSW.js} +1 -1
  96. package/packages/ui/dist/index.html +1 -1
  97. package/scripts/clean.mjs +17 -0
  98. package/templates/default/.agents/skills/sail-onboarding/SKILL.md +7 -0
  99. package/templates/default/.agents/skills/sail-servers/SKILL.md +16 -0
  100. package/templates/default/AGENTS.md +1 -1
  101. package/packages/ui/dist/assets/cursor-DeDBddRQ.js +0 -3
@@ -35210,7 +35210,7 @@ var {
35210
35210
  Help
35211
35211
  } = import_index.default;
35212
35212
 
35213
- // ../sdk/dist/chains.js
35213
+ // ../sdk/src/chains.ts
35214
35214
  var chains = {
35215
35215
  // Ethereum mainnet
35216
35216
  1: {
@@ -35292,15 +35292,17 @@ var chains = {
35292
35292
  function getChain(chainId) {
35293
35293
  const config = chains[chainId];
35294
35294
  if (!config) {
35295
- throw new Error(`Chain ${chainId} is not supported. Supported chains: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 130 (Unichain), 84532 (Base Sepolia), 11155111 (Eth Sepolia).`);
35295
+ throw new Error(
35296
+ `Chain ${chainId} is not supported. Supported chains: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 130 (Unichain), 84532 (Base Sepolia), 11155111 (Eth Sepolia).`
35297
+ );
35296
35298
  }
35297
35299
  return config;
35298
35300
  }
35299
35301
 
35300
- // ../sdk/dist/client.js
35302
+ // ../sdk/src/client.ts
35301
35303
  init_esm2();
35302
35304
 
35303
- // ../sdk/dist/abis/SailKernel.js
35305
+ // ../sdk/src/abis/SailKernel.ts
35304
35306
  var SailKernelAbi = [
35305
35307
  // ── Account instantiation ────────────────────────────────────────────────
35306
35308
  {
@@ -35605,7 +35607,7 @@ var SailKernelAbi = [
35605
35607
  }
35606
35608
  ];
35607
35609
 
35608
- // ../sdk/dist/capabilities.js
35610
+ // ../sdk/src/capabilities.ts
35609
35611
  init_esm2();
35610
35612
  var DISPATCH_TYPE_STRINGS = {
35611
35613
  conjunctive: "Dispatch(address account,address target,uint256 value,bytes32 dataHash,uint256 nonce,uint256 deadline)",
@@ -35650,7 +35652,9 @@ function fromDispatchTypehash(kernel, dispatchTypehash, registerPermissionTypeha
35650
35652
  } else if (dispatchTypehash === DISPATCH_TYPEHASHES.selective) {
35651
35653
  dispatchModel = "selective";
35652
35654
  } else {
35653
- throw new Error(`Unrecognized kernel DISPATCH_TYPEHASH ${dispatchTypehash} for ${kernel}. The SDK cannot safely sign dispatches for this kernel version. Known: conjunctive=${DISPATCH_TYPEHASHES.conjunctive}, selective=${DISPATCH_TYPEHASHES.selective}.`);
35655
+ throw new Error(
35656
+ `Unrecognized kernel DISPATCH_TYPEHASH ${dispatchTypehash} for ${kernel}. The SDK cannot safely sign dispatches for this kernel version. Known: conjunctive=${DISPATCH_TYPEHASHES.conjunctive}, selective=${DISPATCH_TYPEHASHES.selective}.`
35657
+ );
35654
35658
  }
35655
35659
  let registerPermissionHasDeadline = dispatchModel === "selective";
35656
35660
  if (registerPermissionTypehash === REGISTER_PERMISSION_TYPEHASHES.withDeadline) {
@@ -35675,8 +35679,7 @@ async function detectKernelCapabilities(publicClient, kernel, opts) {
35675
35679
  const key = cacheKey2(chainId, kernel);
35676
35680
  if (!opts?.force) {
35677
35681
  const hit = cache.get(key);
35678
- if (hit)
35679
- return hit;
35682
+ if (hit) return hit;
35680
35683
  }
35681
35684
  let dispatchTypehash;
35682
35685
  let registerPermissionTypehash;
@@ -35698,17 +35701,29 @@ async function detectKernelCapabilities(publicClient, kernel, opts) {
35698
35701
  }
35699
35702
  let caps;
35700
35703
  if (dispatchTypehash) {
35701
- caps = fromDispatchTypehash(kernel, dispatchTypehash, registerPermissionTypehash, "onchain-typehash");
35704
+ caps = fromDispatchTypehash(
35705
+ kernel,
35706
+ dispatchTypehash,
35707
+ registerPermissionTypehash,
35708
+ "onchain-typehash"
35709
+ );
35702
35710
  } else if (opts?.staticModel) {
35703
- caps = fromDispatchTypehash(kernel, DISPATCH_TYPEHASHES[opts.staticModel], void 0, "static-hint");
35711
+ caps = fromDispatchTypehash(
35712
+ kernel,
35713
+ DISPATCH_TYPEHASHES[opts.staticModel],
35714
+ void 0,
35715
+ "static-hint"
35716
+ );
35704
35717
  } else {
35705
- throw new Error(`Could not read DISPATCH_TYPEHASH from kernel ${kernel}, and no staticModel hint was given. Pass opts.staticModel ('conjunctive' | 'selective') to proceed without on-chain detection.`);
35718
+ throw new Error(
35719
+ `Could not read DISPATCH_TYPEHASH from kernel ${kernel}, and no staticModel hint was given. Pass opts.staticModel ('conjunctive' | 'selective') to proceed without on-chain detection.`
35720
+ );
35706
35721
  }
35707
35722
  cache.set(key, caps);
35708
35723
  return caps;
35709
35724
  }
35710
35725
 
35711
- // ../sdk/dist/deployments.js
35726
+ // ../sdk/src/deployments.ts
35712
35727
  var CREATE2_KERNEL = "0x02ABC18B65A328de2e749F56ba79ACF2718a6659";
35713
35728
  var CREATE2_GOVERNANCE = "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC";
35714
35729
  var CREATE2_TIMELOCK = "0xE48Ba8DB6d748adafD13155c3590f62e58a77f56";
@@ -35861,7 +35876,7 @@ function getSailDeployment(chainId) {
35861
35876
  return deployment;
35862
35877
  }
35863
35878
 
35864
- // ../sdk/dist/errors.js
35879
+ // ../sdk/src/errors.ts
35865
35880
  init_esm2();
35866
35881
  var KERNEL_ERROR_SIGNATURES = [
35867
35882
  "error AccountAlreadyRegistered(address account)",
@@ -35940,14 +35955,12 @@ async function decode2(data) {
35940
35955
  }
35941
35956
  }
35942
35957
  function decodeKernelError(data) {
35943
- if (!data || data === "0x")
35944
- return Promise.resolve(null);
35958
+ if (!data || data === "0x") return Promise.resolve(null);
35945
35959
  return decode2(data);
35946
35960
  }
35947
35961
  async function explainKernelRevert(err) {
35948
35962
  const data = extractRevertData(err);
35949
- if (!data)
35950
- return null;
35963
+ if (!data) return null;
35951
35964
  return decodeKernelError(data);
35952
35965
  }
35953
35966
  function extractRevertData(err) {
@@ -35977,7 +35990,7 @@ function extractRevertData(err) {
35977
35990
  return null;
35978
35991
  }
35979
35992
 
35980
- // ../sdk/dist/eip712.js
35993
+ // ../sdk/src/eip712.ts
35981
35994
  init_esm2();
35982
35995
  function sailKernelDomain(args) {
35983
35996
  return {
@@ -36031,12 +36044,16 @@ async function buildDispatchSignature(params) {
36031
36044
  const dataHash = keccak256(call2.data);
36032
36045
  const selective = caps.dispatchModel === "selective";
36033
36046
  const message = selective ? { account: account2, permission, target: call2.target, value: call2.value, dataHash, nonce, deadline } : { account: account2, target: call2.target, value: call2.value, dataHash, nonce, deadline };
36034
- const signature = await manager.signTyped(sailKernelDomain({ chainId, kernel }), {
36035
- primaryType: "Dispatch",
36036
- types: {
36037
- Dispatch: DISPATCH_EIP712_FIELDS[caps.dispatchModel]
36038
- }
36039
- }, message);
36047
+ const signature = await manager.signTyped(
36048
+ sailKernelDomain({ chainId, kernel }),
36049
+ {
36050
+ primaryType: "Dispatch",
36051
+ types: {
36052
+ Dispatch: DISPATCH_EIP712_FIELDS[caps.dispatchModel]
36053
+ }
36054
+ },
36055
+ message
36056
+ );
36040
36057
  return { signature, nonce, deadline, dispatchModel: caps.dispatchModel };
36041
36058
  }
36042
36059
  var REGISTER_PERMISSION_TYPES = {
@@ -36115,7 +36132,7 @@ function buildRegisterPermissionsBatchTypedData(args) {
36115
36132
  };
36116
36133
  }
36117
36134
 
36118
- // ../sdk/dist/lifi.js
36135
+ // ../sdk/src/lifi.ts
36119
36136
  init_esm2();
36120
36137
  var LIFI_QUOTE_URL = "https://li.quest/v1/quote";
36121
36138
  var LIFI_ROUTERS = {
@@ -36154,7 +36171,9 @@ async function fetchLifiQuote(params) {
36154
36171
  const quote = await res.json();
36155
36172
  const tx = quote.transactionRequest;
36156
36173
  if (!tx?.to || !tx?.data) {
36157
- throw new Error("LiFi quote returned no usable transactionRequest: " + JSON.stringify(quote).slice(0, 400));
36174
+ throw new Error(
36175
+ "LiFi quote returned no usable transactionRequest: " + JSON.stringify(quote).slice(0, 400)
36176
+ );
36158
36177
  }
36159
36178
  return {
36160
36179
  target: tx.to,
@@ -36165,7 +36184,7 @@ async function fetchLifiQuote(params) {
36165
36184
  };
36166
36185
  }
36167
36186
 
36168
- // ../sdk/dist/client.js
36187
+ // ../sdk/src/client.ts
36169
36188
  function notImplemented() {
36170
36189
  throw new Error("not implemented");
36171
36190
  }
@@ -36209,17 +36228,13 @@ var CONJUNCTIVE_DISPATCH_ABI = [
36209
36228
  async function enrichKernelRevert(err) {
36210
36229
  const decoded = await explainKernelRevert(err);
36211
36230
  const base2 = err instanceof Error ? err : new Error(String(err));
36212
- if (!decoded)
36213
- return base2;
36231
+ if (!decoded) return base2;
36214
36232
  const wrapped = new Error(`Kernel reverted: ${decoded.message}`);
36215
36233
  wrapped.cause = base2;
36216
36234
  wrapped.kernelError = decoded;
36217
36235
  return wrapped;
36218
36236
  }
36219
36237
  var KernelNamespace = class {
36220
- publicClient;
36221
- config;
36222
- walletClient;
36223
36238
  constructor(publicClient, config, walletClient) {
36224
36239
  this.publicClient = publicClient;
36225
36240
  this.config = config;
@@ -36228,13 +36243,17 @@ var KernelNamespace = class {
36228
36243
  requireKernel() {
36229
36244
  const kernel = this.config.kernel;
36230
36245
  if (!kernel) {
36231
- throw new Error("SailKernel address not configured \u2014 set `kernel` in SailorClientConfig.");
36246
+ throw new Error(
36247
+ "SailKernel address not configured \u2014 set `kernel` in SailorClientConfig."
36248
+ );
36232
36249
  }
36233
36250
  return kernel;
36234
36251
  }
36235
36252
  requireSigner() {
36236
36253
  if (!this.walletClient) {
36237
- throw new Error("No signer attached \u2014 call client.withSigner(walletClient) before write operations.");
36254
+ throw new Error(
36255
+ "No signer attached \u2014 call client.withSigner(walletClient) before write operations."
36256
+ );
36238
36257
  }
36239
36258
  return this.walletClient;
36240
36259
  }
@@ -36257,7 +36276,9 @@ var AccountNamespace = class extends KernelNamespace {
36257
36276
  const kernel = this.requireKernel();
36258
36277
  const signer = this.requireSigner();
36259
36278
  if (!params.safeFactory || !params.safeSingleton || !params.safeInitializer) {
36260
- throw new Error("createAccount requires safeFactory, safeSingleton, and safeInitializer.");
36279
+ throw new Error(
36280
+ "createAccount requires safeFactory, safeSingleton, and safeInitializer."
36281
+ );
36261
36282
  }
36262
36283
  const txHash = await signer.writeContract({
36263
36284
  address: kernel,
@@ -36318,17 +36339,21 @@ var MandateNamespace = class extends KernelNamespace {
36318
36339
  functionName: "signerNonces",
36319
36340
  args: [safe]
36320
36341
  });
36321
- const sig = await signer.signTyped(sailKernelDomain({ chainId: this.config.chainId, kernel }), {
36322
- primaryType: "RegisterPermissions",
36323
- types: {
36324
- RegisterPermissions: [
36325
- { name: "account", type: "address" },
36326
- { name: "permissions", type: "address[]" },
36327
- { name: "nonce", type: "uint256" },
36328
- { name: "deadline", type: "uint256" }
36329
- ]
36330
- }
36331
- }, { account: safe, permissions, nonce, deadline });
36342
+ const sig = await signer.signTyped(
36343
+ sailKernelDomain({ chainId: this.config.chainId, kernel }),
36344
+ {
36345
+ primaryType: "RegisterPermissions",
36346
+ types: {
36347
+ RegisterPermissions: [
36348
+ { name: "account", type: "address" },
36349
+ { name: "permissions", type: "address[]" },
36350
+ { name: "nonce", type: "uint256" },
36351
+ { name: "deadline", type: "uint256" }
36352
+ ]
36353
+ }
36354
+ },
36355
+ { account: safe, permissions, nonce, deadline }
36356
+ );
36332
36357
  await wallet.writeContract({
36333
36358
  address: kernel,
36334
36359
  abi: SailKernelAbi,
@@ -36347,7 +36372,9 @@ var MandateNamespace = class extends KernelNamespace {
36347
36372
  return notImplemented();
36348
36373
  }
36349
36374
  deployAndAttachClone(_safe, _impl, _initData, _salt, _signer) {
36350
- throw new Error("deployAndAttachClone is not yet implemented in the SDK.\nUse `sailor mandate attach --address <impl>` to attach a clone template via the factory.");
36375
+ throw new Error(
36376
+ "deployAndAttachClone is not yet implemented in the SDK.\nUse `sailor mandate attach --address <impl>` to attach a clone template via the factory."
36377
+ );
36351
36378
  }
36352
36379
  async list(safe) {
36353
36380
  const kernel = this.requireKernel();
@@ -36417,11 +36444,12 @@ var DispatchNamespace = class extends KernelNamespace {
36417
36444
  let latest = 0n;
36418
36445
  for (let i = 0; i < tries; i++) {
36419
36446
  latest = await this.readManagerNonce(kernel, safe);
36420
- if (latest >= expected)
36421
- return latest;
36447
+ if (latest >= expected) return latest;
36422
36448
  await delay(1e3);
36423
36449
  }
36424
- throw new Error(`Manager nonce for ${safe} did not reach ${expected} after ${tries}s (last seen ${latest}). The prior dispatch may not have mined, or the RPC endpoint is lagging. Retry, or pass an explicit nonce via options.nonce.`);
36450
+ throw new Error(
36451
+ `Manager nonce for ${safe} did not reach ${expected} after ${tries}s (last seen ${latest}). The prior dispatch may not have mined, or the RPC endpoint is lagging. Retry, or pass an explicit nonce via options.nonce.`
36452
+ );
36425
36453
  }
36426
36454
  /**
36427
36455
  * Determine the nonce to sign with. Honors an explicit `options.nonce`
@@ -36430,8 +36458,7 @@ var DispatchNamespace = class extends KernelNamespace {
36430
36458
  * dispatch on this account) before reading the live value.
36431
36459
  */
36432
36460
  async resolveNonce(kernel, safe, options) {
36433
- if (options?.nonce !== void 0)
36434
- return options.nonce;
36461
+ if (options?.nonce !== void 0) return options.nonce;
36435
36462
  const expected = options?.awaitNonce ?? this.nextNonce.get(this.nonceKey(kernel, safe));
36436
36463
  if (expected !== void 0) {
36437
36464
  return this.waitForManagerNonce(kernel, safe, expected);
@@ -36523,7 +36550,9 @@ var DispatchNamespace = class extends KernelNamespace {
36523
36550
  const deadline = defaultDeadline();
36524
36551
  const caps = await this.capabilities();
36525
36552
  if (caps.dispatchModel === "conjunctive") {
36526
- throw new Error(`Batch dispatch is not supported by the conjunctive kernel at ${kernel} (it has no dispatchBatch). Submit calls individually via dispatch.single, ensuring the manager nonce advances between them.`);
36553
+ throw new Error(
36554
+ `Batch dispatch is not supported by the conjunctive kernel at ${kernel} (it has no dispatchBatch). Submit calls individually via dispatch.single, ensuring the manager nonce advances between them.`
36555
+ );
36527
36556
  }
36528
36557
  const nonce = await this.publicClient.readContract({
36529
36558
  address: kernel,
@@ -36531,19 +36560,25 @@ var DispatchNamespace = class extends KernelNamespace {
36531
36560
  functionName: "batchNonces",
36532
36561
  args: [safe]
36533
36562
  });
36534
- const callsHash = keccak256(encodeAbiParameters([{ type: "tuple[]", components: CALL_COMPONENTS }], [calls]));
36535
- const managerSig = await manager.signTyped(sailKernelDomain({ chainId: this.config.chainId, kernel }), {
36536
- primaryType: "DispatchBatch",
36537
- types: {
36538
- DispatchBatch: [
36539
- { name: "account", type: "address" },
36540
- { name: "permission", type: "address" },
36541
- { name: "callsHash", type: "bytes32" },
36542
- { name: "nonce", type: "uint256" },
36543
- { name: "deadline", type: "uint256" }
36544
- ]
36545
- }
36546
- }, { account: safe, permission, callsHash, nonce, deadline });
36563
+ const callsHash = keccak256(
36564
+ encodeAbiParameters([{ type: "tuple[]", components: CALL_COMPONENTS }], [calls])
36565
+ );
36566
+ const managerSig = await manager.signTyped(
36567
+ sailKernelDomain({ chainId: this.config.chainId, kernel }),
36568
+ {
36569
+ primaryType: "DispatchBatch",
36570
+ types: {
36571
+ DispatchBatch: [
36572
+ { name: "account", type: "address" },
36573
+ { name: "permission", type: "address" },
36574
+ { name: "callsHash", type: "bytes32" },
36575
+ { name: "nonce", type: "uint256" },
36576
+ { name: "deadline", type: "uint256" }
36577
+ ]
36578
+ }
36579
+ },
36580
+ { account: safe, permission, callsHash, nonce, deadline }
36581
+ );
36547
36582
  let txHash;
36548
36583
  try {
36549
36584
  txHash = await wallet.writeContract({
@@ -36568,7 +36603,9 @@ var DispatchNamespace = class extends KernelNamespace {
36568
36603
  const kernel = this.requireKernel();
36569
36604
  const caps = await this.capabilities();
36570
36605
  if (caps.dispatchModel === "conjunctive") {
36571
- throw new Error(`Dry-run preview is not supported by the conjunctive kernel at ${kernel} (it has no previewBatch view). Validate calls off-chain against each registered permission's evaluate() logic, or simulate the dispatch.single tx instead.`);
36606
+ throw new Error(
36607
+ `Dry-run preview is not supported by the conjunctive kernel at ${kernel} (it has no previewBatch view). Validate calls off-chain against each registered permission's evaluate() logic, or simulate the dispatch.single tx instead.`
36608
+ );
36572
36609
  }
36573
36610
  const [approved, reason] = await this.publicClient.readContract({
36574
36611
  address: kernel,
@@ -36580,7 +36617,6 @@ var DispatchNamespace = class extends KernelNamespace {
36580
36617
  }
36581
36618
  };
36582
36619
  var StrategyNamespace = class extends KernelNamespace {
36583
- dispatch;
36584
36620
  constructor(publicClient, config, dispatch, walletClient) {
36585
36621
  super(publicClient, config, walletClient);
36586
36622
  this.dispatch = dispatch;
@@ -36598,13 +36634,17 @@ var StrategyNamespace = class extends KernelNamespace {
36598
36634
  const slippage = params.slippage ?? DEFAULT_SLIPPAGE;
36599
36635
  const router = params.router ?? LIFI_ROUTERS[this.config.chainId];
36600
36636
  if (!router) {
36601
- throw new Error(`No LiFi router known for chain ${this.config.chainId}. Pass params.router explicitly.`);
36637
+ throw new Error(
36638
+ `No LiFi router known for chain ${this.config.chainId}. Pass params.router explicitly.`
36639
+ );
36602
36640
  }
36603
36641
  const caps = await this.capabilities();
36604
36642
  const swapPermission = params.swapPermission ?? router;
36605
36643
  const approvePermission = params.approvePermission ?? params.swapPermission ?? router;
36606
36644
  if (caps.dispatchModel === "selective" && !params.swapPermission) {
36607
- throw new Error("This kernel uses the selective dispatch model \u2014 params.swapPermission is required (the permission that authorizes the swap).");
36645
+ throw new Error(
36646
+ "This kernel uses the selective dispatch model \u2014 params.swapPermission is required (the permission that authorizes the swap)."
36647
+ );
36608
36648
  }
36609
36649
  const quote = await fetchLifiQuote({
36610
36650
  chainId: this.config.chainId,
@@ -36624,9 +36664,19 @@ var StrategyNamespace = class extends KernelNamespace {
36624
36664
  let approve;
36625
36665
  if (allowance < params.amount) {
36626
36666
  const approveAmount = params.approveAmount ?? params.amount;
36627
- approve = await this.dispatch.single(safe, approvePermission, { target: params.from, value: 0n, data: encodeApprove(router, approveAmount) }, manager);
36667
+ approve = await this.dispatch.single(
36668
+ safe,
36669
+ approvePermission,
36670
+ { target: params.from, value: 0n, data: encodeApprove(router, approveAmount) },
36671
+ manager
36672
+ );
36628
36673
  }
36629
- const swap = await this.dispatch.single(safe, swapPermission, { target: quote.target, value: quote.value, data: quote.data }, manager);
36674
+ const swap = await this.dispatch.single(
36675
+ safe,
36676
+ swapPermission,
36677
+ { target: quote.target, value: quote.value, data: quote.data },
36678
+ manager
36679
+ );
36630
36680
  return {
36631
36681
  swap,
36632
36682
  approve,
@@ -36746,7 +36796,7 @@ var SailorClient = class _SailorClient {
36746
36796
  }
36747
36797
  };
36748
36798
 
36749
- // ../sdk/dist/keyring.js
36799
+ // ../sdk/src/keyring.ts
36750
36800
  var import_node_crypto = require("node:crypto");
36751
36801
  var import_node_fs = require("node:fs");
36752
36802
  init_esm2();
@@ -37428,7 +37478,7 @@ function mnemonicToAccount(mnemonic, { passphrase, ...hdKeyOpts } = {}) {
37428
37478
  return hdKeyToAccount(HDKey.fromMasterSeed(seed), hdKeyOpts);
37429
37479
  }
37430
37480
 
37431
- // ../sdk/dist/keyring.js
37481
+ // ../sdk/src/keyring.ts
37432
37482
  var SCRYPT_N = 1 << 18;
37433
37483
  var SCRYPT_R = 8;
37434
37484
  var SCRYPT_P = 1;
@@ -37446,11 +37496,16 @@ var LocalKeyring = class _LocalKeyring {
37446
37496
  this.address = account2.address;
37447
37497
  this.privateKey = options.privateKey;
37448
37498
  } else if (options.type === "mnemonic") {
37449
- const account2 = mnemonicToAccount(options.mnemonic, options.derivationPath ? { path: options.derivationPath } : void 0);
37499
+ const account2 = mnemonicToAccount(
37500
+ options.mnemonic,
37501
+ options.derivationPath ? { path: options.derivationPath } : void 0
37502
+ );
37450
37503
  this.account = account2;
37451
37504
  this.address = account2.address;
37452
37505
  } else {
37453
- throw new Error("keystore decryption not implemented \u2014 use type: 'privateKey' or type: 'mnemonic' instead");
37506
+ throw new Error(
37507
+ "keystore decryption not implemented \u2014 use type: 'privateKey' or type: 'mnemonic' instead"
37508
+ );
37454
37509
  }
37455
37510
  }
37456
37511
  /** Returns a lightweight signer stub for read-only contexts where the key is not available. */
@@ -37480,7 +37535,9 @@ var LocalKeyring = class _LocalKeyring {
37480
37535
  }
37481
37536
  const { n, r, p, dklen, salt } = crypto3.kdfparams;
37482
37537
  if (n < 1 << 14) {
37483
- throw new Error(`Keystore scrypt N=${n} is below the minimum accepted value (16384). Refusing to decrypt.`);
37538
+ throw new Error(
37539
+ `Keystore scrypt N=${n} is below the minimum accepted value (16384). Refusing to decrypt.`
37540
+ );
37484
37541
  }
37485
37542
  if (r < 8) {
37486
37543
  throw new Error(`Keystore scrypt r=${r} is below the minimum accepted value (8).`);
@@ -37498,7 +37555,11 @@ var LocalKeyring = class _LocalKeyring {
37498
37555
  if (computedMac.length !== storedMac.length || !(0, import_node_crypto.timingSafeEqual)(computedMac, storedMac)) {
37499
37556
  throw new Error("Invalid password or corrupt keystore");
37500
37557
  }
37501
- const decipher = (0, import_node_crypto.createDecipheriv)("aes-128-ctr", derived.subarray(0, 16), Buffer.from(crypto3.cipherparams.iv, "hex"));
37558
+ const decipher = (0, import_node_crypto.createDecipheriv)(
37559
+ "aes-128-ctr",
37560
+ derived.subarray(0, 16),
37561
+ Buffer.from(crypto3.cipherparams.iv, "hex")
37562
+ );
37502
37563
  const pkBytes = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
37503
37564
  return _LocalKeyring.fromPrivateKey(`0x${pkBytes.toString("hex")}`);
37504
37565
  }
@@ -37536,7 +37597,9 @@ var LocalKeyring = class _LocalKeyring {
37536
37597
  /** Exports the private key as an encrypted keystore JSON (scrypt + aes-128-ctr, geth v3). */
37537
37598
  async exportKeystore(password) {
37538
37599
  if (!this.privateKey) {
37539
- throw new Error("Private key unavailable \u2014 only privateKey/generated keyrings can be exported");
37600
+ throw new Error(
37601
+ "Private key unavailable \u2014 only privateKey/generated keyrings can be exported"
37602
+ );
37540
37603
  }
37541
37604
  const salt = (0, import_node_crypto.randomBytes)(32);
37542
37605
  const derived = (0, import_node_crypto.scryptSync)(password, salt, SCRYPT_DKLEN, {
@@ -37573,7 +37636,7 @@ var LocalKeyring = class _LocalKeyring {
37573
37636
  }
37574
37637
  };
37575
37638
 
37576
- // ../sdk/dist/abis/SailGovernance.js
37639
+ // ../sdk/src/abis/SailGovernance.ts
37577
37640
  var SailGovernanceAbi = [
37578
37641
  {
37579
37642
  type: "function",
@@ -37619,7 +37682,7 @@ var SailGovernanceAbi = [
37619
37682
  }
37620
37683
  ];
37621
37684
 
37622
- // ../sdk/dist/safe.js
37685
+ // ../sdk/src/safe.ts
37623
37686
  init_esm2();
37624
37687
  var setManagerAbi = [
37625
37688
  {
@@ -37709,7 +37772,10 @@ function buildSafeSetupInitializer(params) {
37709
37772
  });
37710
37773
  }
37711
37774
  function buildApprovedHashSignature(owner2) {
37712
- return encodePacked(["bytes32", "bytes32", "uint8"], [pad(owner2, { size: 32 }), pad("0x", { size: 32 }), 1]);
37775
+ return encodePacked(
37776
+ ["bytes32", "bytes32", "uint8"],
37777
+ [pad(owner2, { size: 32 }), pad("0x", { size: 32 }), 1]
37778
+ );
37713
37779
  }
37714
37780
  var safeProxyFactoryAbi = [
37715
37781
  {
@@ -37722,11 +37788,15 @@ var safeProxyFactoryAbi = [
37722
37788
  ];
37723
37789
  function computeSafeProxyAddress(params) {
37724
37790
  const { initializer, saltNonce, proxyCreationCode } = params;
37725
- const initCodeHash = keccak256(concat([
37726
- proxyCreationCode,
37727
- encodeAbiParameters([{ type: "address" }], [SAFE_V141.singletonL2])
37728
- ]));
37729
- const salt = keccak256(encodePacked(["bytes32", "uint256"], [keccak256(initializer), saltNonce]));
37791
+ const initCodeHash = keccak256(
37792
+ concat([
37793
+ proxyCreationCode,
37794
+ encodeAbiParameters([{ type: "address" }], [SAFE_V141.singletonL2])
37795
+ ])
37796
+ );
37797
+ const salt = keccak256(
37798
+ encodePacked(["bytes32", "uint256"], [keccak256(initializer), saltNonce])
37799
+ );
37730
37800
  return getCreate2Address({
37731
37801
  from: SAFE_V141.proxyFactory,
37732
37802
  salt,
@@ -37735,13 +37805,20 @@ function computeSafeProxyAddress(params) {
37735
37805
  }
37736
37806
  function computeKernelBoundSalt(params) {
37737
37807
  const { saltNonce, deployer, permissionSigner, manager, feePolicy } = params;
37738
- return BigInt(keccak256(encodeAbiParameters([
37739
- { type: "uint256" },
37740
- { type: "address" },
37741
- { type: "address" },
37742
- { type: "address" },
37743
- { type: "address" }
37744
- ], [saltNonce, deployer, permissionSigner, manager, feePolicy])));
37808
+ return BigInt(
37809
+ keccak256(
37810
+ encodeAbiParameters(
37811
+ [
37812
+ { type: "uint256" },
37813
+ { type: "address" },
37814
+ { type: "address" },
37815
+ { type: "address" },
37816
+ { type: "address" }
37817
+ ],
37818
+ [saltNonce, deployer, permissionSigner, manager, feePolicy]
37819
+ )
37820
+ )
37821
+ );
37745
37822
  }
37746
37823
  function computeSailSmaAddress(params) {
37747
37824
  const boundSalt = computeKernelBoundSalt(params);
@@ -37788,7 +37865,7 @@ function buildSetManagerExecTransaction(params) {
37788
37865
  return { to: params.safe, data };
37789
37866
  }
37790
37867
 
37791
- // ../sdk/dist/discovery.js
37868
+ // ../sdk/src/discovery.ts
37792
37869
  var SAFE_TX_SERVICE_SLUGS = {
37793
37870
  1: "eth",
37794
37871
  100: "gno",
@@ -37816,7 +37893,7 @@ async function discoverSafesForOwner(owner2, chainId) {
37816
37893
  return data.safes ?? [];
37817
37894
  }
37818
37895
 
37819
- // ../sdk/dist/fees.js
37896
+ // ../sdk/src/fees.ts
37820
37897
  function min(a, b) {
37821
37898
  return a < b ? a : b;
37822
37899
  }
@@ -37852,7 +37929,7 @@ async function estimatePermissionFee(publicClient, governance, permission) {
37852
37929
  }
37853
37930
  }
37854
37931
 
37855
- // ../sdk/dist/intelligence.js
37932
+ // ../sdk/src/intelligence.ts
37856
37933
  var SAIL_INTELLIGENCE_BASE_URL = "https://api.sail.money";
37857
37934
  var SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
37858
37935
 
@@ -38519,7 +38596,7 @@ var import_websocket2 = __toESM(require_websocket2(), 1);
38519
38596
  var import_websocket_server2 = __toESM(require_websocket_server2(), 1);
38520
38597
 
38521
38598
  // src/signing/server.ts
38522
- var DEFAULT_SIGNING_PORT = 3141;
38599
+ var DEFAULT_SIGNING_PORT = Number(process.env.SAILOR_STATION_PORT ?? 3141);
38523
38600
  var RUNTIME_SUBDIR = (0, import_node_path4.join)(".sail", "runtime");
38524
38601
  var SERVER_STATE_FILE = "server.json";
38525
38602
  var REQUEST_SECRET_HEADER = "x-sailor-secret";
@@ -40693,6 +40770,8 @@ function scaffoldProjectWorkspace(dest, name, options) {
40693
40770
  import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "keys"), { recursive: true });
40694
40771
  import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "runtime"), { recursive: true });
40695
40772
  import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "state"), { recursive: true });
40773
+ const installMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
40774
+ const containerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
40696
40775
  import_node_fs9.default.writeFileSync(
40697
40776
  import_node_path8.default.join(sailDir2, "config.json"),
40698
40777
  `${JSON.stringify(
@@ -40703,6 +40782,8 @@ function scaffoldProjectWorkspace(dest, name, options) {
40703
40782
  // null = chain not yet chosen; Stage 1 will set this
40704
40783
  stateDir: ".sail/state",
40705
40784
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
40785
+ installMode,
40786
+ ...installMode === "docker" ? { containerName } : {},
40706
40787
  contracts: {
40707
40788
  kernel: "",
40708
40789
  mandateFactory: ""
@@ -40794,6 +40875,14 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
40794
40875
  "This project is already initialized.\nRun `sailor update` to re-sync template files, or `sailor init --force` to re-initialize (overwrites scaffold files; your .sail/keys/ and .sail/state/ are left in place)."
40795
40876
  );
40796
40877
  }
40878
+ const existingConfigPath = import_node_path8.default.join(dest, ".sail", "config.json");
40879
+ const previousConfig = import_node_fs9.default.existsSync(existingConfigPath) ? (() => {
40880
+ try {
40881
+ return JSON.parse(import_node_fs9.default.readFileSync(existingConfigPath, "utf-8"));
40882
+ } catch {
40883
+ return null;
40884
+ }
40885
+ })() : null;
40797
40886
  copyDirSync(templateSrc, dest);
40798
40887
  const pkgRoot = packageRoot();
40799
40888
  const examplesPermSrc = import_node_path8.default.join(pkgRoot, "examples", "permissions");
@@ -40833,6 +40922,18 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
40833
40922
  }
40834
40923
  scaffoldProjectWorkspace(dest, name, options);
40835
40924
  scaffoldFoundryWorkspace(dest);
40925
+ const newMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
40926
+ if (previousConfig?.installMode === "docker" && newMode === "local") {
40927
+ const prev = previousConfig.containerName ?? "agent";
40928
+ console.log(`
40929
+ Switched to local install. If the Docker container is still running:`);
40930
+ console.log(` docker stop ${prev}`);
40931
+ console.log(`You can restart it anytime with the standard docker run command.`);
40932
+ } else if (previousConfig?.installMode === "local" && newMode === "docker") {
40933
+ const containerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
40934
+ console.log(`
40935
+ Switched to Docker install (container: ${containerName}).`);
40936
+ }
40836
40937
  printWelcome(
40837
40938
  dest,
40838
40939
  name,
@@ -40943,6 +41044,12 @@ Created ${name}/`);
40943
41044
  "\u2551 If you skip this step, setup WILL break and you will have to \u2551",
40944
41045
  "\u2551 restart. There are no shortcuts. \u2551",
40945
41046
  "\u2551 \u2551",
41047
+ "\u2551 IF SAILOR IS RUNNING IN DOCKER: \u2551",
41048
+ "\u2551 \u2022 Read project files from your local filesystem \u2014 they are \u2551",
41049
+ "\u2551 shared via volume mount, do NOT use docker exec to read them. \u2551",
41050
+ "\u2551 \u2022 Prefix every sailor command with: \u2551",
41051
+ "\u2551 docker exec <containerName> sailor <command> \u2551",
41052
+ "\u2551 \u2551",
40946
41053
  "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D",
40947
41054
  ""
40948
41055
  ].join("\n"));
@@ -40996,6 +41103,39 @@ async function updateCommand() {
40996
41103
  }
40997
41104
  const added = [];
40998
41105
  copyDirSyncIfMissing(templateSrc, dest, added);
41106
+ const configPath = import_node_path9.default.join(dest, ".sail", "config.json");
41107
+ try {
41108
+ const config = JSON.parse(import_node_fs10.default.readFileSync(configPath, "utf-8"));
41109
+ const newMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
41110
+ const containerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
41111
+ if (config.installMode !== newMode) {
41112
+ const previousMode = config.installMode;
41113
+ const previousContainer = config.containerName;
41114
+ config.installMode = newMode;
41115
+ if (newMode === "docker") {
41116
+ config.containerName = containerName;
41117
+ } else {
41118
+ delete config.containerName;
41119
+ }
41120
+ import_node_fs10.default.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
41121
+ `, "utf-8");
41122
+ if (previousMode === "docker" && newMode === "local") {
41123
+ const prev = previousContainer ?? "agent";
41124
+ console.log(`
41125
+ Switched to local install. If the Docker container is still running:`);
41126
+ console.log(` docker stop ${prev}`);
41127
+ console.log(`You can restart it anytime with the standard docker run command.`);
41128
+ } else if (newMode === "docker") {
41129
+ console.log(`
41130
+ Switched to Docker install (container: ${containerName}).`);
41131
+ }
41132
+ } else if (newMode === "docker" && config.containerName !== containerName) {
41133
+ config.containerName = containerName;
41134
+ import_node_fs10.default.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
41135
+ `, "utf-8");
41136
+ }
41137
+ } catch {
41138
+ }
40999
41139
  if (removed.length === 0 && updated.length === 0 && added.length === 0) {
41000
41140
  console.log("Nothing to update.");
41001
41141
  return;
@@ -45148,7 +45288,7 @@ async function uiCommand() {
45148
45288
  const serverBundle = import_node_path16.default.resolve(distDir, "server.cjs");
45149
45289
  const projectRoot = process.cwd();
45150
45290
  const sailDir2 = import_node_path16.default.join(projectRoot, ".sail");
45151
- const port = await findFreePort(projectPort(projectRoot));
45291
+ const port = await findFreePort(process.env.PORT ? Number(process.env.PORT) : projectPort(projectRoot));
45152
45292
  if (!import_node_fs20.default.existsSync(serverBundle)) {
45153
45293
  throw new Error(`Server bundle not found at ${serverBundle}. Re-run the sailor build.`);
45154
45294
  }