@needmoretruth/nmts-cli 0.17.2 → 0.34.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/AGENTS.md +125 -517
  2. package/CHANGELOG.md +104 -0
  3. package/README.ko.md +377 -469
  4. package/README.md +394 -474
  5. package/dist/account-proof.d.ts +29 -0
  6. package/dist/account-proof.js +6 -6
  7. package/dist/account.d.ts +18 -0
  8. package/dist/account.js +5 -5
  9. package/dist/agent-host.d.ts +71 -0
  10. package/dist/agent-host.js +169 -0
  11. package/dist/api-advice.d.ts +2 -0
  12. package/dist/api-advice.js +210 -0
  13. package/dist/api-key.d.ts +79 -0
  14. package/dist/api-key.js +7 -7
  15. package/dist/api-refusal.d.ts +14 -0
  16. package/dist/api-refusal.js +8 -0
  17. package/dist/api.d.ts +114 -0
  18. package/dist/api.js +59 -162
  19. package/dist/args.d.ts +160 -0
  20. package/dist/args.js +118 -30
  21. package/dist/artifact-about.d.ts +49 -0
  22. package/dist/autonomy.d.ts +39 -0
  23. package/dist/autonomy.js +110 -32
  24. package/dist/code-access.d.ts +29 -0
  25. package/dist/code-access.js +3 -3
  26. package/dist/code-vault.d.ts +38 -0
  27. package/dist/code-vault.js +8 -8
  28. package/dist/collision.d.ts +67 -0
  29. package/dist/collision.js +1 -1
  30. package/dist/commands/accept-terms.d.ts +11 -0
  31. package/dist/commands/accept-terms.js +106 -0
  32. package/dist/commands/balance.d.ts +7 -0
  33. package/dist/commands/balance.js +54 -1
  34. package/dist/commands/create-code-file.d.ts +24 -0
  35. package/dist/commands/create-code-file.js +93 -0
  36. package/dist/commands/create-link.d.ts +10 -0
  37. package/dist/commands/create-link.js +232 -0
  38. package/dist/commands/create.d.ts +20 -0
  39. package/dist/commands/create.js +43 -102
  40. package/dist/commands/credits.d.ts +9 -0
  41. package/dist/commands/credits.js +110 -0
  42. package/dist/commands/delete-account.d.ts +11 -0
  43. package/dist/commands/delete-account.js +63 -0
  44. package/dist/commands/deposit.d.ts +7 -0
  45. package/dist/commands/deposit.js +85 -0
  46. package/dist/commands/devices.d.ts +12 -0
  47. package/dist/commands/devices.js +144 -0
  48. package/dist/commands/documents.d.ts +35 -0
  49. package/dist/commands/documents.js +212 -0
  50. package/dist/commands/env.d.ts +5 -0
  51. package/dist/commands/env.js +10 -2
  52. package/dist/commands/erase.d.ts +13 -0
  53. package/dist/commands/erase.js +193 -0
  54. package/dist/commands/expiring.d.ts +19 -0
  55. package/dist/commands/extend.d.ts +33 -0
  56. package/dist/commands/extend.js +54 -15
  57. package/dist/commands/get.d.ts +18 -0
  58. package/dist/commands/key-manage.d.ts +11 -0
  59. package/dist/commands/key-manage.js +162 -0
  60. package/dist/commands/key.d.ts +28 -0
  61. package/dist/commands/key.js +249 -0
  62. package/dist/commands/kit.d.ts +11 -0
  63. package/dist/commands/kit.js +7 -7
  64. package/dist/commands/listfile.d.ts +13 -0
  65. package/dist/commands/listfile.js +12 -5
  66. package/dist/commands/login.d.ts +18 -0
  67. package/dist/commands/login.js +19 -19
  68. package/dist/commands/logout.d.ts +1 -0
  69. package/dist/commands/logout.js +1 -1
  70. package/dist/commands/losses.d.ts +12 -0
  71. package/dist/commands/losses.js +180 -0
  72. package/dist/commands/ls.d.ts +23 -0
  73. package/dist/commands/marks-dispatch.d.ts +2 -0
  74. package/dist/commands/marks-dispatch.js +51 -0
  75. package/dist/commands/marks.d.ts +46 -0
  76. package/dist/commands/marks.js +80 -0
  77. package/dist/commands/mcp.d.ts +24 -0
  78. package/dist/commands/mcp.js +70 -5
  79. package/dist/commands/mode.d.ts +8 -0
  80. package/dist/commands/mode.js +60 -24
  81. package/dist/commands/on-collision.d.ts +6 -0
  82. package/dist/commands/organise.d.ts +46 -0
  83. package/dist/commands/padding.d.ts +7 -0
  84. package/dist/commands/padding.js +114 -0
  85. package/dist/commands/public-code.d.ts +9 -0
  86. package/dist/commands/public-code.js +8 -8
  87. package/dist/commands/pull.d.ts +27 -0
  88. package/dist/commands/push-wallet.d.ts +19 -0
  89. package/dist/commands/push-wallet.js +69 -0
  90. package/dist/commands/push.d.ts +47 -0
  91. package/dist/commands/push.js +37 -7
  92. package/dist/commands/put-wallet.d.ts +77 -0
  93. package/dist/commands/put-wallet.js +316 -0
  94. package/dist/commands/put.d.ts +56 -0
  95. package/dist/commands/put.js +53 -6
  96. package/dist/commands/rebuild.d.ts +18 -0
  97. package/dist/commands/rebuild.js +108 -10
  98. package/dist/commands/receive.d.ts +24 -0
  99. package/dist/commands/recovery-dispatch.d.ts +2 -0
  100. package/dist/commands/recovery-dispatch.js +34 -0
  101. package/dist/commands/recovery-list.d.ts +11 -0
  102. package/dist/commands/recovery-list.js +6 -6
  103. package/dist/commands/recovery.d.ts +25 -0
  104. package/dist/commands/recovery.js +2 -2
  105. package/dist/commands/rollback.d.ts +9 -0
  106. package/dist/commands/rollback.js +118 -0
  107. package/dist/commands/s3.d.ts +23 -0
  108. package/dist/commands/s3.js +6 -6
  109. package/dist/commands/settings.d.ts +5 -0
  110. package/dist/commands/settings.js +21 -6
  111. package/dist/commands/share-dispatch.d.ts +2 -0
  112. package/dist/commands/share-dispatch.js +46 -0
  113. package/dist/commands/share.d.ts +14 -0
  114. package/dist/commands/share.js +13 -3
  115. package/dist/commands/shares-sent.d.ts +18 -0
  116. package/dist/commands/shares-sent.js +95 -0
  117. package/dist/commands/support.d.ts +24 -0
  118. package/dist/commands/support.js +321 -0
  119. package/dist/commands/sweep.d.ts +11 -0
  120. package/dist/commands/tip.d.ts +11 -0
  121. package/dist/commands/tip.js +86 -0
  122. package/dist/commands/trash.d.ts +17 -0
  123. package/dist/commands/trash.js +1 -1
  124. package/dist/commands/trial.d.ts +7 -0
  125. package/dist/commands/trial.js +16 -18
  126. package/dist/commands/unlock.d.ts +16 -0
  127. package/dist/commands/unlock.js +159 -0
  128. package/dist/commands/update.d.ts +42 -0
  129. package/dist/commands/update.js +1 -1
  130. package/dist/commands/usage.d.ts +8 -0
  131. package/dist/commands/verify.d.ts +18 -0
  132. package/dist/commands/verify.js +10 -6
  133. package/dist/commands/wallet-activity.d.ts +26 -0
  134. package/dist/commands/wallet-activity.js +117 -0
  135. package/dist/commands/wallet-donate.d.ts +26 -0
  136. package/dist/commands/wallet-donate.js +163 -0
  137. package/dist/commands/wallet-hall.d.ts +35 -0
  138. package/dist/commands/wallet-hall.js +214 -0
  139. package/dist/commands/wallet-send.d.ts +22 -0
  140. package/dist/commands/wallet-send.js +153 -0
  141. package/dist/commands/wallet-storage-ops.d.ts +24 -0
  142. package/dist/commands/wallet-storage-ops.js +215 -0
  143. package/dist/commands/wallet-storage.d.ts +18 -0
  144. package/dist/commands/wallet-storage.js +95 -0
  145. package/dist/commands/wallet-swap.d.ts +32 -0
  146. package/dist/commands/wallet-swap.js +287 -0
  147. package/dist/commands/wallet.d.ts +36 -0
  148. package/dist/commands/wallet.js +57 -15
  149. package/dist/commands/whoami.d.ts +10 -0
  150. package/dist/commands/whoami.js +24 -6
  151. package/dist/consent.d.ts +140 -0
  152. package/dist/consent.js +89 -30
  153. package/dist/credentials.d.ts +146 -0
  154. package/dist/credentials.js +10 -10
  155. package/dist/crypto-surface.d.ts +197 -0
  156. package/dist/crypto.d.ts +81 -0
  157. package/dist/crypto.js +13 -0
  158. package/dist/deposit.d.ts +25 -0
  159. package/dist/deposit.js +78 -0
  160. package/dist/download-part.d.ts +40 -0
  161. package/dist/download-sink.d.ts +76 -0
  162. package/dist/download.d.ts +79 -0
  163. package/dist/download.js +3 -3
  164. package/dist/drive-paths.d.ts +73 -0
  165. package/dist/environment.d.ts +62 -0
  166. package/dist/environment.js +29 -9
  167. package/dist/errors.d.ts +22 -0
  168. package/dist/errors.js +3 -3
  169. package/dist/exit.d.ts +44 -0
  170. package/dist/expiry.d.ts +58 -0
  171. package/dist/extend-budget.d.ts +35 -0
  172. package/dist/extend-budget.js +81 -0
  173. package/dist/extend-chain.d.ts +43 -0
  174. package/dist/extend-chain.js +40 -3
  175. package/dist/extend-plan.d.ts +148 -0
  176. package/dist/extend-plan.js +1 -1
  177. package/dist/gate.d.ts +18 -0
  178. package/dist/gate.js +100 -0
  179. package/dist/guards.d.ts +2 -0
  180. package/dist/help.d.ts +20 -0
  181. package/dist/help.js +199 -33
  182. package/dist/human-check.d.ts +23 -0
  183. package/dist/index.d.ts +42 -0
  184. package/dist/index.js +49 -0
  185. package/dist/item-trash.d.ts +1 -0
  186. package/dist/kit-file.d.ts +56 -0
  187. package/dist/kit-file.js +10 -10
  188. package/dist/list-file.d.ts +88 -0
  189. package/dist/list-file.js +90 -7
  190. package/dist/list-view-find.d.ts +15 -0
  191. package/dist/list-view-order.d.ts +32 -0
  192. package/dist/main.d.ts +12 -0
  193. package/dist/main.js +112 -113
  194. package/dist/manifest-chunk-cache.d.ts +14 -0
  195. package/dist/manifest-chunk-cache.js +103 -0
  196. package/dist/manifest-chunk-flow.d.ts +81 -0
  197. package/dist/manifest-chunk-flow.js +307 -0
  198. package/dist/manifest-create.d.ts +23 -0
  199. package/dist/manifest-create.js +26 -30
  200. package/dist/manifest-write.d.ts +161 -0
  201. package/dist/manifest-write.js +42 -33
  202. package/dist/manifest.d.ts +82 -0
  203. package/dist/manifest.js +69 -21
  204. package/dist/mark-render.d.ts +26 -0
  205. package/dist/mcp-args.d.ts +17 -0
  206. package/dist/mcp-ask.d.ts +43 -0
  207. package/dist/mcp-ask.js +100 -0
  208. package/dist/mcp-tools/context.d.ts +46 -0
  209. package/dist/mcp-tools/credits.d.ts +3 -0
  210. package/dist/mcp-tools/credits.js +61 -0
  211. package/dist/mcp-tools/files.d.ts +3 -0
  212. package/dist/mcp-tools/files.js +34 -0
  213. package/dist/mcp-tools/organise.d.ts +3 -0
  214. package/dist/mcp-tools/organise.js +82 -2
  215. package/dist/mcp-tools/reads.d.ts +3 -0
  216. package/dist/mcp-tools/reads.js +132 -4
  217. package/dist/mcp-tools/share.d.ts +3 -0
  218. package/dist/mcp-tools/share.js +26 -7
  219. package/dist/mcp-tools/support.d.ts +3 -0
  220. package/dist/mcp-tools/support.js +140 -0
  221. package/dist/mcp-tools/tiers.d.ts +31 -0
  222. package/dist/mcp-tools/tiers.js +147 -0
  223. package/dist/mcp.d.ts +80 -0
  224. package/dist/mcp.js +110 -9
  225. package/dist/net-retry.d.ts +38 -0
  226. package/dist/network.d.ts +10 -0
  227. package/dist/notice.d.ts +7 -0
  228. package/dist/notice.js +7 -7
  229. package/dist/product.d.ts +29 -0
  230. package/dist/product.js +1 -1
  231. package/dist/progress.d.ts +37 -0
  232. package/dist/prompt.d.ts +31 -0
  233. package/dist/prompt.js +1 -1
  234. package/dist/rebuild-key-check.d.ts +26 -0
  235. package/dist/rebuild-key-check.js +90 -0
  236. package/dist/rebuild.d.ts +87 -0
  237. package/dist/rebuild.js +26 -4
  238. package/dist/recovery-assemble.d.ts +40 -0
  239. package/dist/recovery-assemble.js +1 -1
  240. package/dist/recovery-build.d.ts +40 -0
  241. package/dist/recovery-map-file.d.ts +53 -0
  242. package/dist/recovery-map-file.js +4 -4
  243. package/dist/recovery-map.d.ts +197 -0
  244. package/dist/recovery-release.d.ts +104 -0
  245. package/dist/recovery-seq.d.ts +10 -0
  246. package/dist/recovery-source.d.ts +50 -0
  247. package/dist/redact.d.ts +70 -0
  248. package/dist/redact.js +212 -0
  249. package/dist/registration.d.ts +30 -0
  250. package/dist/registration.js +5 -5
  251. package/dist/risk.d.ts +380 -0
  252. package/dist/risk.js +206 -0
  253. package/dist/run-log.d.ts +78 -0
  254. package/dist/run-log.js +301 -0
  255. package/dist/s3/listing.d.ts +47 -0
  256. package/dist/s3/multipart.d.ts +21 -0
  257. package/dist/s3/response-sink.d.ts +8 -0
  258. package/dist/s3/same-file.d.ts +54 -0
  259. package/dist/s3/server.d.ts +58 -0
  260. package/dist/s3/server.js +2 -2
  261. package/dist/s3/sigv4.d.ts +46 -0
  262. package/dist/s3/sigv4.js +1 -1
  263. package/dist/s3/staging.d.ts +10 -0
  264. package/dist/s3/xml.d.ts +28 -0
  265. package/dist/safe-path.d.ts +41 -0
  266. package/dist/seal.d.ts +120 -0
  267. package/dist/secret-reader.d.ts +28 -0
  268. package/dist/server.d.ts +9 -0
  269. package/dist/session.d.ts +32 -0
  270. package/dist/session.js +1 -1
  271. package/dist/setup-questions.d.ts +7 -0
  272. package/dist/share.d.ts +108 -0
  273. package/dist/share.js +1 -1
  274. package/dist/shared/lib/crypto/size-padding.d.ts +55 -0
  275. package/dist/shared/lib/crypto/size-padding.js +5 -0
  276. package/dist/shared/lib/drive/manifest-chunks.d.ts +95 -0
  277. package/dist/shared/lib/drive/manifest-chunks.js +252 -0
  278. package/dist/shared/lib/drive/manifest-codec.d.ts +214 -0
  279. package/dist/shared/lib/drive/manifest-codec.js +7 -7
  280. package/dist/shared/lib/drive/manifest-index.d.ts +98 -0
  281. package/dist/shared/lib/drive/manifest-ops.d.ts +167 -0
  282. package/dist/shared/lib/drive/manifest-ops.js +9 -4
  283. package/dist/shared/lib/drive/manifest-pack.d.ts +65 -0
  284. package/dist/shared/lib/drive/manifest-pack.js +287 -0
  285. package/dist/shared/lib/drive/manifest-settings.d.ts +113 -0
  286. package/dist/shared/lib/drive/manifest-settings.js +87 -6
  287. package/dist/shared/lib/drive/name-conflict.d.ts +76 -0
  288. package/dist/shared/lib/drive/rebuild-verify.d.ts +73 -0
  289. package/dist/shared/lib/drive/rebuild-verify.js +112 -0
  290. package/dist/shared/lib/drive/unique-name.d.ts +9 -0
  291. package/dist/shared/lib/drive/zstd.d.ts +27 -0
  292. package/dist/shared/lib/drive/zstd.js +74 -0
  293. package/dist/shared/lib/extend/epochs.d.ts +205 -0
  294. package/dist/shared/lib/net/retry-budget.d.ts +79 -0
  295. package/dist/shared/lib/share/shared-file-info.d.ts +21 -0
  296. package/dist/shared/lib/storage-control/chain.d.ts +57 -0
  297. package/dist/shared/lib/storage-control/chain.js +82 -0
  298. package/dist/shared/lib/storage-control/plan.d.ts +40 -0
  299. package/dist/shared/lib/storage-control/plan.js +72 -0
  300. package/dist/shared/lib/storage-control/reuse.d.ts +72 -0
  301. package/dist/shared/lib/storage-control/reuse.js +95 -0
  302. package/dist/shared/lib/storage-network.d.ts +25 -0
  303. package/dist/shared/lib/upload/part-plan.d.ts +24 -0
  304. package/dist/shared/lib/wallet/activity.d.ts +138 -0
  305. package/dist/shared/lib/wallet/activity.js +208 -0
  306. package/dist/shared/lib/wallet/send-rules.d.ts +68 -0
  307. package/dist/shared/lib/wallet/send-rules.js +116 -0
  308. package/dist/shared/lib/wallet/swap-rules.d.ts +115 -0
  309. package/dist/shared/lib/wallet/swap-rules.js +199 -0
  310. package/dist/shared/lib/wallet/tip.d.ts +14 -0
  311. package/dist/shared/lib/wallet/tip.js +34 -0
  312. package/dist/shared/lib/wallet/venue-ids.d.ts +23 -0
  313. package/dist/shared/lib/wallet/venue-ids.js +53 -0
  314. package/dist/standing-tip.d.ts +24 -0
  315. package/dist/standing-tip.js +52 -0
  316. package/dist/stdout.d.ts +38 -0
  317. package/dist/storage-control-chain.d.ts +38 -0
  318. package/dist/storage-control-chain.js +78 -0
  319. package/dist/sui-rpc.d.ts +15 -0
  320. package/dist/sui-rpc.js +59 -0
  321. package/dist/support-attach.d.ts +24 -0
  322. package/dist/support-attach.js +72 -0
  323. package/dist/support-copy.d.ts +42 -0
  324. package/dist/support-copy.js +109 -0
  325. package/dist/support-wire.d.ts +49 -0
  326. package/dist/support-wire.js +194 -0
  327. package/dist/trash-sweep.d.ts +55 -0
  328. package/dist/units.d.ts +2 -0
  329. package/dist/update-check.d.ts +50 -0
  330. package/dist/update-source.d.ts +63 -0
  331. package/dist/upload-api.d.ts +3 -0
  332. package/dist/upload-file.d.ts +97 -0
  333. package/dist/upload-file.js +3 -2
  334. package/dist/upload-price.d.ts +50 -0
  335. package/dist/upload-steps.d.ts +26 -0
  336. package/dist/upload-steps.js +29 -9
  337. package/dist/upload-store.d.ts +182 -0
  338. package/dist/upload-wallet-chain.d.ts +54 -0
  339. package/dist/upload-wallet-chain.js +203 -0
  340. package/dist/upload-wallet-plan.d.ts +128 -0
  341. package/dist/upload-wallet-plan.js +184 -0
  342. package/dist/upload-wallet.d.ts +24 -0
  343. package/dist/upload-wallet.js +208 -0
  344. package/dist/upload-wire.d.ts +244 -0
  345. package/dist/upload.d.ts +18 -0
  346. package/dist/upload.js +10 -0
  347. package/dist/usage-report.d.ts +35 -0
  348. package/dist/wallet-activity-chain.d.ts +5 -0
  349. package/dist/wallet-activity-chain.js +31 -0
  350. package/dist/wallet-chain.d.ts +19 -0
  351. package/dist/wallet-chain.js +2 -2
  352. package/dist/wallet-grant.d.ts +50 -0
  353. package/dist/wallet-grant.js +218 -0
  354. package/dist/wallet-send-chain.d.ts +24 -0
  355. package/dist/wallet-send-chain.js +49 -0
  356. package/dist/wallet-sign.d.ts +133 -0
  357. package/dist/wallet-sign.js +317 -0
  358. package/dist/wallet-storage-chain.d.ts +3 -0
  359. package/dist/wallet-storage-chain.js +20 -0
  360. package/dist/wallet-swap-chain.d.ts +52 -0
  361. package/dist/wallet-swap-chain.js +186 -0
  362. package/dist/wallet-swap-quote.d.ts +22 -0
  363. package/dist/wallet-swap-quote.js +126 -0
  364. package/dist/wallet.d.ts +135 -0
  365. package/dist/wallet.js +5 -5
  366. package/dist/walrus-write.d.ts +56 -0
  367. package/dist/walrus-write.js +5 -4
  368. package/dist/walrus.d.ts +86 -0
  369. package/dist/walrus.js +48 -10
  370. package/dist/zstd-node.d.ts +11 -0
  371. package/dist/zstd-node.js +71 -0
  372. package/docs/commands/accept-terms.md +15 -0
  373. package/docs/commands/create.md +17 -0
  374. package/docs/commands/credits.md +34 -0
  375. package/docs/commands/delete-account.md +14 -0
  376. package/docs/commands/deposit.md +27 -0
  377. package/docs/commands/devices.md +9 -0
  378. package/docs/commands/documents.md +10 -0
  379. package/docs/commands/env.md +21 -0
  380. package/docs/commands/extend.md +27 -0
  381. package/docs/commands/folders.md +10 -0
  382. package/docs/commands/get.md +14 -0
  383. package/docs/commands/key.md +14 -0
  384. package/docs/commands/login.md +23 -0
  385. package/docs/commands/logout.md +11 -0
  386. package/docs/commands/losses.md +13 -0
  387. package/docs/commands/ls.md +16 -0
  388. package/docs/commands/marks.md +9 -0
  389. package/docs/commands/mcp.md +33 -0
  390. package/docs/commands/mode.md +29 -0
  391. package/docs/commands/on-collision.md +13 -0
  392. package/docs/commands/padding.md +13 -0
  393. package/docs/commands/public-code.md +9 -0
  394. package/docs/commands/pull.md +9 -0
  395. package/docs/commands/push.md +12 -0
  396. package/docs/commands/put.md +36 -0
  397. package/docs/commands/rebuild.md +13 -0
  398. package/docs/commands/recovery.md +18 -0
  399. package/docs/commands/s3.md +17 -0
  400. package/docs/commands/share.md +15 -0
  401. package/docs/commands/support.md +16 -0
  402. package/docs/commands/tip.md +21 -0
  403. package/docs/commands/trash.md +25 -0
  404. package/docs/commands/trial.md +12 -0
  405. package/docs/commands/unlock.md +25 -0
  406. package/docs/commands/update.md +14 -0
  407. package/docs/commands/usage.md +14 -0
  408. package/docs/commands/verify.md +18 -0
  409. package/docs/commands/wallet.md +67 -0
  410. package/docs/commands/whoami.md +12 -0
  411. package/package.json +67 -8
  412. package/server.json +28 -0
  413. package/vendor/nmts-crypto/nmts_crypto_wasm.d.ts +23 -2
  414. package/vendor/nmts-crypto/nmts_crypto_wasm.js +44 -2
  415. package/vendor/nmts-crypto/nmts_crypto_wasm_bg.wasm +0 -0
  416. package/vendor/nmts-crypto/nmts_crypto_wasm_bg.wasm.d.ts +1 -0
  417. package/vendor/nmts-crypto/package.json +1 -1
  418. package/dist/commands/consent.js +0 -77
  419. package/dist/extend-sign.js +0 -130
@@ -1,18 +1,24 @@
1
1
  // `nmts mode` — how much an agent driving this tool may decide without asking.
2
2
  //
3
- // ⛔ IT IS A COMMAND, FOR THE SAME REASON CONSENT IS. A question asked in the middle of another
4
- // command cannot be answered by a container, a build step, or an agent's subprocess. A command
5
- // can, its answer is recorded with a date, and it can be looked at afterwards.
3
+ // ⛔ A PERSON SWITCHES IT, AT A TERMINAL. Turning a mode on refuses when stdin is not a terminal —
4
+ // the way an agent's subprocess usually arrives prints the whole explanation first, and takes
5
+ // one answer: y for the two auto modes, a typed sentence for skip-permissions. Turning it off is
6
+ // one line from anywhere. Short for the person, closed to the program: that is the shape the owner
7
+ // asked for (2026-09-06).
6
8
  //
7
- // ⛔ TURNING ONE ON TAKES A FLAG THAT SAYS WHAT IT IS. `nmts mode auto` alone prints what the mode
8
- // means and stops; adding the flag is the sentence nobody types by accident.
9
- import { AUTONOMY_MODES, MODE_MEANS, RISK_FLAG, currentMode, setAt, setMode, } from "../autonomy.js";
9
+ // ⛔ `nmts mode explain <mode>` PRINTS THE EXPLANATION AND CHANGES NOTHING. It exists so an agent that
10
+ // recommends a mode can show the person exactly what it is, rather than its own summary.
11
+ import { AUTONOMY_MODES, MODE_MEANS, SKIP_SENTENCE, currentMode, explain, modeFromStored, setAt, setMode, } from "../autonomy.js";
10
12
  import { NmtsError } from "../errors.js";
11
13
  import { BINARY_NAME, VERSION } from "../product.js";
12
- function isMode(value) {
13
- return AUTONOMY_MODES.includes(value);
14
+ import { promptLine, stdinIsATerminal } from "../prompt.js";
15
+ /** A name a person may type, including the two older spellings. */
16
+ function wantedMode(raw) {
17
+ if (raw === "off" || raw === "auto")
18
+ return modeFromStored(raw);
19
+ return AUTONOMY_MODES.includes(raw) ? raw : null;
14
20
  }
15
- export function mode(wanted, options = {}) {
21
+ export async function mode(wanted, target, options = {}) {
16
22
  const say = options.write ?? ((line) => process.stdout.write(`${line}\n`));
17
23
  const now = options.now ?? (() => new Date());
18
24
  if (wanted === undefined || wanted === "") {
@@ -22,33 +28,63 @@ export function mode(wanted, options = {}) {
22
28
  return 0;
23
29
  }
24
30
  say(`${at} — ${MODE_MEANS[at]}`);
25
- // ⛔ The way to change it is said HERE. Listing what exists without saying how to pick one
26
- // sends the reader back to the help text and leaves an agent to guess.
27
31
  for (const other of AUTONOMY_MODES) {
28
32
  if (other !== at)
29
33
  say(`${other} — ${MODE_MEANS[other]}`);
30
34
  }
31
- say(`Change it: ${BINARY_NAME} mode <${AUTONOMY_MODES.join("|")}> ${RISK_FLAG}`);
35
+ say(`Change it, at a terminal: ${BINARY_NAME} mode <${AUTONOMY_MODES.join("|")}>`);
36
+ say(`Read one in full first: ${BINARY_NAME} mode explain <mode>`);
32
37
  return 0;
33
38
  }
34
- if (!isMode(wanted)) {
39
+ if (wanted === "explain") {
40
+ const which = target === undefined ? null : wantedMode(target);
41
+ if (which === null) {
42
+ throw new NmtsError(`Say which mode to explain.`, { exitCode: 2, nextStep: `One of: ${AUTONOMY_MODES.join(" · ")}` });
43
+ }
44
+ for (const line of explain(which))
45
+ say(line);
46
+ return 0;
47
+ }
48
+ const next = wantedMode(wanted);
49
+ if (next === null) {
35
50
  throw new NmtsError(`There is no mode called "${wanted}".`, {
36
51
  exitCode: 2,
37
52
  nextStep: `One of: ${AUTONOMY_MODES.join(" · ")}`,
38
53
  });
39
54
  }
40
- // ⛔ Turning one OFF never needs the flag. Making the safe direction harder than the risky one
41
- // is how somebody leaves it on.
42
- if (wanted !== "off" && options.accepted !== true) {
43
- throw new NmtsError(MODE_MEANS[wanted], {
44
- exitCode: 2,
45
- nextStep: [
46
- "You bear what an agent does with your files and your credits while this is on.",
47
- `Turn it on: ${BINARY_NAME} mode ${wanted} ${RISK_FLAG}`,
48
- ].join("\n "),
55
+ // ⛔ OFF IS ONE LINE FROM ANYWHERE. Making the safe direction harder than the risky one is how
56
+ // somebody leaves it on.
57
+ if (next === "default") {
58
+ setMode("default", VERSION, now());
59
+ say(`default — ${MODE_MEANS.default}`);
60
+ return 0;
61
+ }
62
+ if (options.readLine === undefined && !stdinIsATerminal()) {
63
+ throw new NmtsError(`A person switches modes, at a terminal — stdin here is not one.`, {
64
+ exitCode: 5,
65
+ nextStep: `If you are an agent: do not switch modes. You may recommend one — show the person ` +
66
+ `\`${BINARY_NAME} mode explain ${next}\` in full and let them decide.`,
49
67
  });
50
68
  }
51
- setMode(wanted, VERSION, now());
52
- say(wanted === "off" ? `off — ${MODE_MEANS.off}` : `${wanted} — ${MODE_MEANS[wanted]}`);
69
+ const ask = options.readLine ?? promptLine;
70
+ for (const line of explain(next))
71
+ say(line);
72
+ say(``);
73
+ if (next === "skip-permissions") {
74
+ const typed = (await ask(`Type exactly: ${SKIP_SENTENCE}\n> `)).trim();
75
+ if (typed !== SKIP_SENTENCE) {
76
+ say(`Nothing was changed.`);
77
+ return 1;
78
+ }
79
+ }
80
+ else {
81
+ const answer = (await ask(`Turn ${next} on? [y/N] `)).trim();
82
+ if (answer !== "y" && answer !== "Y") {
83
+ say(`Nothing was changed.`);
84
+ return 1;
85
+ }
86
+ }
87
+ setMode(next, VERSION, now());
88
+ say(`${next} — ${MODE_MEANS[next]}`);
53
89
  return 0;
54
90
  }
@@ -0,0 +1,6 @@
1
+ export interface OnCollisionOptions {
2
+ json?: boolean;
3
+ write?: (line: string) => void;
4
+ now?: () => Date;
5
+ }
6
+ export declare function onCollision(wanted: string | undefined, options?: OnCollisionOptions): number;
@@ -0,0 +1,46 @@
1
+ import { openSession } from "../session.ts";
2
+ export interface OrganiseOptions {
3
+ server?: string | undefined;
4
+ network?: string | undefined;
5
+ json?: boolean;
6
+ write?: (line: string) => void;
7
+ }
8
+ /**
9
+ * Make a folder, and any folder above it that is missing.
10
+ *
11
+ * ⚠ MISSING PARENTS ARE CREATED, and that is a decision rather than a convenience. A folder costs
12
+ * nothing, holds nothing and can be moved to the trash, so the failure mode of creating one too
13
+ * many is a tidy-up; the failure mode of refusing is an agent that has to discover the tree one
14
+ * command at a time. Every folder made is named in the output, so it is never a surprise.
15
+ */
16
+ /**
17
+ * Make a folder path, and every folder above it that is missing, under an OPEN session.
18
+ *
19
+ * ⛔ SPLIT OUT SO AN UPLOAD OF A WHOLE DIRECTORY CAN USE IT. The rules below are the ones a second
20
+ * copy would get subtly wrong: a folder that is already there IS the folder asked for (never a
21
+ * numbered one), the decision is taken inside each attempt so a lost race cannot make two, and
22
+ * what was made before a failure is named rather than silently kept.
23
+ */
24
+ export declare function ensureFolderPath(session: Awaited<ReturnType<typeof openSession>>, wanted: string): Promise<{
25
+ parentId: string | null;
26
+ made: string[];
27
+ }>;
28
+ export declare function mkdir(path: string | undefined, options?: OrganiseOptions): Promise<number>;
29
+ /**
30
+ * Move things into a folder. Every operand but the last is something to move; the last is where
31
+ * they go, and an empty one means the top of the drive.
32
+ *
33
+ * ⛔ ONE WRITE FOR THE WHOLE RUN, however many things are named. The list is rewritten whole on
34
+ * every save, so a second thing costs nothing extra — while a second WRITE is a second chance
35
+ * to lose the compare-and-swap, and losing it half way through a run leaves some things moved
36
+ * and some not, which is a state the caller cannot tell apart from the one it asked for.
37
+ *
38
+ * ⛔ AND THE NAME CHECK RUNS AGAINST WHAT THIS RUN HAS ALREADY MOVED, not against the list as it
39
+ * was read. Two files called `notes.txt` in two folders, moved into one folder by one command,
40
+ * would otherwise both be written — two entries at one path, which no command in this tool can
41
+ * address afterwards: every one of them answers "names 2 things in this account". So the loop
42
+ * folds each move onto a working copy and asks the working copy the next question.
43
+ */
44
+ export declare function mv(operands: readonly string[], options?: OrganiseOptions): Promise<number>;
45
+ /** Give one thing a new name. The path stays the same otherwise. */
46
+ export declare function rename(path: string | undefined, name: string | undefined, options?: OrganiseOptions): Promise<number>;
@@ -0,0 +1,7 @@
1
+ export interface PaddingOptions {
2
+ server?: string | undefined;
3
+ network?: string | undefined;
4
+ json?: boolean;
5
+ write?: (line: string) => void;
6
+ }
7
+ export declare function padding(wanted: string | undefined, options?: PaddingOptions): Promise<number>;
@@ -0,0 +1,114 @@
1
+ // `nmts padding` — how coarsely a file's stored size is rounded up before it is uploaded.
2
+ //
3
+ // ⛔ IT IS NOT A SETTING ABOUT ENCRYPTION. The bytes are sealed either way; what this decides is
4
+ // how much blank space goes inside the seal, and therefore what SIZE the storage network can be
5
+ // seen holding. A size is the one property of a stored piece that is public no matter what, so
6
+ // the choice is between two rules for hiding it — or `off`, which hides nothing and stores the
7
+ // file at its exact size. Walrus itself stores a blob at whatever size it is handed, so this
8
+ // tool has to be able to as well (2026-09-06); the sentence it prints is what makes it a
9
+ // choice rather than a trap, and no agent gets there without asking (the act is still tiered).
10
+ //
11
+ // ⛔ IT LIVES IN THE SEALED FILE LIST, NOT ON THIS MACHINE. The server must not learn it — a
12
+ // per-account padding rule is a fingerprint a server could keep — and it follows the ACCOUNT,
13
+ // so a phone and a laptop pad the same way. That is why reading it costs a list read and
14
+ // setting it costs a list write, where `nmts on-collision` costs neither.
15
+ //
16
+ // ⚠ AND IT APPLIES TO WHAT IS UPLOADED NEXT. Bytes already on the storage network cannot be
17
+ // re-padded: they were sealed at the size they were sealed at, and nothing re-uploads them. Every
18
+ // sentence this command prints about a change says so.
19
+ import { NmtsError } from "../errors.js";
20
+ import { readFileList } from "../manifest.js";
21
+ import { applyManyToList } from "../manifest-write.js";
22
+ import { BINARY_NAME } from "../product.js";
23
+ import { openSession } from "../session.js";
24
+ /**
25
+ * What a person types, and what the sealed list spells it as.
26
+ *
27
+ * ⚠ THE TWO VOCABULARIES ARE NOT THE SAME AND THAT IS DELIBERATE. The list's default rule is
28
+ * called Padmé inside the format (`"padme"`), which is the name of an algorithm and not
29
+ * something to put in front of somebody choosing a setting. On the command line the default is
30
+ * `standard`, and the format's own spelling never reaches the screen.
31
+ */
32
+ const WORDS = ["standard", "pow2", "off"];
33
+ /** What each one is called in a sentence. */
34
+ const CALLED = {
35
+ standard: "standard",
36
+ pow2: "powers of two",
37
+ off: "off (exact size)",
38
+ };
39
+ /** The word the sealed list spells each answer as. The two vocabularies never meet on screen. */
40
+ const SPELT = {
41
+ standard: "padme",
42
+ pow2: "pow2",
43
+ off: "none",
44
+ };
45
+ function isWord(value) {
46
+ return WORDS.includes(value);
47
+ }
48
+ export async function padding(wanted, options = {}) {
49
+ const say = options.write ?? ((line) => process.stdout.write(`${line}\n`));
50
+ // ⛔ BEFORE THE NETWORK. A misspelled rule is a command line to fix, not a question to ask the
51
+ // server, and rounding `pow-2` down to the default would look like it worked.
52
+ if (wanted !== undefined && wanted !== "" && !isWord(wanted)) {
53
+ throw new NmtsError(`\`${BINARY_NAME} padding\` takes standard, pow2 or off, not "${wanted}".`, {
54
+ exitCode: 2,
55
+ nextStep: `Run \`${BINARY_NAME} padding\` with no argument to see which one this account uses.`,
56
+ });
57
+ }
58
+ const session = await openSession({ server: options.server, network: options.network });
59
+ if (wanted === undefined || wanted === "") {
60
+ const list = await readFileList(session.server, session.apiKey, session.code, session.accountId);
61
+ // ⛔ ANYTHING THIS BUILD DOES NOT KNOW IS THE DEFAULT, which is the same rule the uploader and
62
+ // the browser read it by. A rule this build does not know is not guessed at: padding by one
63
+ // nothing here can undo would give a file a size no reader can account for.
64
+ const stored = list.manifest?.settings?.paddingMode;
65
+ const at = stored === "pow2" ? "pow2" : stored === "none" ? "off" : "standard";
66
+ if (options.json === true) {
67
+ say(JSON.stringify({ padding: at }));
68
+ return 0;
69
+ }
70
+ if (at === "off") {
71
+ say(`File sizes are not hidden: a stored piece states the file's exact length.`);
72
+ say(`Anyone can read the size of a piece stored on the storage network, and with padding off ` +
73
+ `that size is the file's own.`);
74
+ return 0;
75
+ }
76
+ say(at === "pow2"
77
+ ? `File sizes are hidden with powers of two: a stored size shows as one value per doubling.`
78
+ : `File sizes are hidden the standard way: a stored size shows as one of a few fixed values per doubling.`);
79
+ say(`Anyone can read the size of a piece stored on the storage network; the blank bytes make it ` +
80
+ `one of a set of fixed values instead of the exact number.`);
81
+ return 0;
82
+ }
83
+ // ⛔ THE WRITE DECIDES WHETHER ANYTHING CHANGED, rather than a read before it. Two reads with a
84
+ // write between them is a race with every other device on the account; the one write already
85
+ // knows whether the setting it landed on was the one that was there.
86
+ const mode = SPELT[wanted];
87
+ // ⛔ NO LIST, NO SETTING. The mode lives inside the sealed list, and an account that has never
88
+ // uploaded has no list. Writing an empty one just to hold a setting would make a first `ls`
89
+ // say "a list exists" about an account nothing was ever put in — refuse instead, and say why.
90
+ const before = await readFileList(session.server, session.apiKey, session.code, session.accountId);
91
+ if (before.manifest === null) {
92
+ throw new NmtsError(`This account has no file list yet; the setting lives in the list, and there is nothing to write it into.`, { exitCode: 4, nextStep: `Upload once (\`${BINARY_NAME} put\`) and set it after.` });
93
+ }
94
+ const result = await applyManyToList(session, () => [], { paddingMode: mode });
95
+ if (options.json === true) {
96
+ say(JSON.stringify({ padding: wanted }));
97
+ return 0;
98
+ }
99
+ if (!result.changed) {
100
+ say(`Already ${CALLED[wanted]}. Nothing changed.`);
101
+ return 0;
102
+ }
103
+ // ⛔ TURNING IT OFF SAYS WHAT IT COSTS, not that it was set. Nothing else here gives anything
104
+ // away, and a person who chose this has to be told in the same breath what is now legible —
105
+ // that sentence is the confirmation, which is why there is no second question (owner: safety must not shackle the person).
106
+ if (wanted === "off") {
107
+ say(`Uploads from now on are stored at their exact size: the file's length is visible to the ` +
108
+ `network and to anyone who reads the blob. About 1 % less storage.`);
109
+ return 0;
110
+ }
111
+ say(`Set to ${CALLED[wanted]}. It applies to what is uploaded next, from every device; files ` +
112
+ `already uploaded keep the size they were stored at.`);
113
+ return 0;
114
+ }
@@ -0,0 +1,9 @@
1
+ export interface PublicCodeOptions {
2
+ server?: string | undefined;
3
+ network?: string | undefined;
4
+ /** Publish it, so other accounts can send to it. Permanent. */
5
+ publish?: boolean;
6
+ json?: boolean;
7
+ write?: (line: string) => void;
8
+ }
9
+ export declare function publicCode(options?: PublicCodeOptions): Promise<number>;
@@ -14,13 +14,13 @@
14
14
  // says whether it can be sent to, and names the flag; `--publish` is the deliberate act.
15
15
  //
16
16
  // ⛔ WHAT "PERMANENT" DOES AND DOES NOT MEAN HERE. The record cannot be withdrawn or replaced. It
17
- // is also not a choice: the code and the identity behind it are derived from the account code,
18
- // so the same account code produces the same bytes on any device, and the server refuses a
17
+ // is also not a choice: the code and the identity behind it are derived from the NMTS key,
18
+ // so the same NMTS key produces the same bytes on any device, and the server refuses a
19
19
  // bundle whose claimed value is not the fingerprint of its own root. The only way to publish a
20
- // wrong one is to be holding a different account code. That is worth saying plainly rather than
20
+ // wrong one is to be holding a different NMTS key. That is worth saying plainly rather than
21
21
  // warning vaguely — a warning that cannot be acted on just teaches people to click through.
22
22
  //
23
- // ⚠ IT IS NOT THE ACCOUNT CODE. That one opens every file in the account and must never be given
23
+ // ⚠ IT IS NOT THE NMTS KEY. That one opens every file in the account and must never be given
24
24
  // to anybody; this one is meant to be given away, and on its own it opens nothing.
25
25
  import { request } from "../api.js";
26
26
  import { NmtsError } from "../errors.js";
@@ -45,13 +45,13 @@ export async function publicCode(options = {}) {
45
45
  let published = isRecord(seen) && seen["published"] === true;
46
46
  // ⛔ IF THE SERVER ALREADY HOLDS A DIFFERENT ONE, STOP. Publishing is first-writer-wins and the
47
47
  // server would refuse the write anyway, but the useful thing to report is not "the write
48
- // failed" — it is that the account code this machine is holding is not the one this account
48
+ // failed" — it is that the NMTS key this machine is holding is not the one this account
49
49
  // was made with, which is a much bigger fact than a failed request.
50
50
  const held = isRecord(seen) ? seen["share_address"] : null;
51
51
  if (typeof held === "string" && held !== mine) {
52
52
  throw new NmtsError("This account already publishes a different public code.", {
53
53
  exitCode: 4,
54
- nextStep: "The public code is derived from the account code, so a different one means this machine " +
54
+ nextStep: "The public code is derived from the NMTS key, so a different one means this machine " +
55
55
  "is holding a different account's code than the key beside it. Check which account you meant.",
56
56
  });
57
57
  }
@@ -73,7 +73,7 @@ export async function publicCode(options = {}) {
73
73
  if (published) {
74
74
  say(` published — another account can send files to it`);
75
75
  say(``);
76
- say(`Give it to whoever is sending. ⛔ It is NOT your account code — that one opens`);
76
+ say(`Give it to whoever is sending. ⛔ It is NOT your NMTS key — that one opens`);
77
77
  say(`every file you have and is never given to anybody. This one opens nothing.`);
78
78
  return 0;
79
79
  }
@@ -81,7 +81,7 @@ export async function publicCode(options = {}) {
81
81
  say(``);
82
82
  say(`Publishing writes it on the server so a sender can find the key to seal to.`);
83
83
  say(`It is permanent: it cannot be withdrawn or changed afterwards. It is also not a`);
84
- say(`choice — it comes from your account code, so the same account code always gives`);
84
+ say(`choice — it comes from your NMTS key, so the same NMTS key always gives`);
85
85
  say(`the same public code, on this machine or any other.`);
86
86
  say(``);
87
87
  say(` ${BINARY_NAME} public-code --publish`);
@@ -0,0 +1,27 @@
1
+ export interface PullOptions {
2
+ server?: string | undefined;
3
+ network?: string | undefined;
4
+ /** Where the tree goes. Defaults to the working directory. */
5
+ out?: string | undefined;
6
+ /** Replace files that are already there. Without it they are skipped and counted. */
7
+ force?: boolean;
8
+ json?: boolean;
9
+ write?: (line: string) => void;
10
+ }
11
+ export declare function pull(target: string | undefined, options?: PullOptions): Promise<number>;
12
+ /**
13
+ * Join a drive path onto a local directory, refusing anything that would leave it.
14
+ *
15
+ * ⛔ THE NAMES COME FROM THE SEALED LIST, which is written by whoever holds the account — including
16
+ * an account somebody else set up. A name with a separator in it, or one made of dots, would
17
+ * otherwise write outside the directory that was asked for, which is a file appearing somewhere
18
+ * nobody chose.
19
+ */
20
+ /**
21
+ * Where one drive path lands under `base`, or a refusal.
22
+ *
23
+ * ⚠ `platform` exists so the Windows branch can be exercised from any machine. Without it the
24
+ * ordering below is only ever checked by the Windows runner, and it was wrong there for one
25
+ * release.
26
+ */
27
+ export declare function safeJoin(base: string, drivePath: string, platform?: NodeJS.Platform): string;
@@ -0,0 +1,19 @@
1
+ import type { OnCollision } from "../collision.ts";
2
+ import type { openSession } from "../session.ts";
3
+ import type { PaddingRule } from "../shared/lib/crypto/size-padding.ts";
4
+ import type { AccountSettings } from "../shared/lib/drive/manifest-settings.ts";
5
+ import { type PlannedFile, type PushOptions } from "./push.ts";
6
+ /** The wallet rail, one file at a time, stopping at the first failure as the credit rail does. */
7
+ export declare function pushWithWallet(session: Awaited<ReturnType<typeof openSession>>, options: PushOptions, run: {
8
+ todo: PlannedFile[];
9
+ already: PlannedFile[];
10
+ found: number;
11
+ bytes: number;
12
+ partSize: number;
13
+ rule: PaddingRule;
14
+ asked: OnCollision | undefined;
15
+ /** The sealed list's account settings, read once by `push.ts` — the standing tip lives in them. */
16
+ settings: AccountSettings | undefined;
17
+ folderIds: Map<string, string | null>;
18
+ say: (line: string) => void;
19
+ }): Promise<number>;
@@ -0,0 +1,69 @@
1
+ // `nmts push <directory> --pay wallet` — the wallet rail of `push`: each file priced, agreed to and
2
+ // signed for on its own by `put-wallet.ts`, stopping at the first failure as the credit rail does.
3
+ //
4
+ // ⛔ SPLIT OUT OF `push.ts` FOR THE LENGTH GATE, and along the one seam that was already there:
5
+ // `push.ts` decides WHICH files go and where; this decides how the wallet pays for each.
6
+ import { loadCrypto } from "../crypto.js";
7
+ import { NmtsError } from "../errors.js";
8
+ import { resolveNetwork } from "../network.js";
9
+ import { Progress, silentSink, stderrSink } from "../progress.js";
10
+ import { folderFor } from "./push.js";
11
+ /** The wallet rail, one file at a time, stopping at the first failure as the credit rail does. */
12
+ export async function pushWithWallet(session, options, run) {
13
+ const { say } = run;
14
+ const { uploadOneWithWallet } = await import("./put-wallet.js");
15
+ const ctx = {
16
+ code: session.code,
17
+ apiKey: session.apiKey,
18
+ server: session.server,
19
+ // ⛔ Narrowed, not asserted: the session carries the name as text and the rail types it.
20
+ network: resolveNetwork(session.server, session.network),
21
+ accountId: session.accountId,
22
+ crypt: await loadCrypto(),
23
+ partSize: run.partSize,
24
+ rule: run.rule,
25
+ onCollision: run.asked,
26
+ settings: run.settings,
27
+ progress: new Progress(options.json === true ? silentSink() : stderrSink(), "uploading"),
28
+ say,
29
+ json: options.json === true,
30
+ };
31
+ if (!options.json) {
32
+ say(`${run.todo.length} file${run.todo.length === 1 ? "" : "s"} ${run.bytes} bytes → paid from the wallet, one file at a time`);
33
+ if (run.already.length > 0)
34
+ say(` ${run.already.length} already there, not sent again`);
35
+ }
36
+ const uploaded = [];
37
+ try {
38
+ for (const one of run.todo) {
39
+ // ⛔ On a dry run no folder is made either: the destination is resolved only when the
40
+ // upload is really going to happen, exactly as the credit rail does it.
41
+ const parentId = options.dryRun === true ? null : await folderFor(session, run.folderIds, one.folder);
42
+ if (!options.json)
43
+ say(` ${one.folder}/${one.name}`);
44
+ const done = await uploadOneWithWallet(ctx, { localPath: one.local, size: one.size, name: one.name, parentId, destination: one.folder }, { ...options, dryRun: options.dryRun === true });
45
+ if (done !== null)
46
+ uploaded.push(`${one.folder}/${done.savedAs}`);
47
+ }
48
+ }
49
+ catch (error) {
50
+ ctx.progress.done();
51
+ const because = error instanceof NmtsError ? error : null;
52
+ throw new NmtsError(error instanceof Error ? error.message : String(error), {
53
+ exitCode: because?.exitCode ?? 1,
54
+ nextStep: uploaded.length === 0
55
+ ? (because?.nextStep ?? "Nothing was uploaded.")
56
+ : `${uploaded.length} file${uploaded.length === 1 ? " is" : "s are"} uploaded and signed for. Running the same command again sends only what is missing.`,
57
+ });
58
+ }
59
+ finally {
60
+ ctx.progress.done();
61
+ }
62
+ if (options.json) {
63
+ say(JSON.stringify({ files: run.found, uploaded: uploaded.length, skipped: run.already.length, bytes: run.bytes, paidFrom: "wallet", dryRun: options.dryRun === true }));
64
+ return 0;
65
+ }
66
+ say(``);
67
+ say(options.dryRun === true ? ` Nothing was signed and nothing was sent.` : `${uploaded.length} sent · ${run.already.length} already there`);
68
+ return 0;
69
+ }
@@ -0,0 +1,47 @@
1
+ import { openSession } from "../session.ts";
2
+ export interface PushOptions {
3
+ server?: string | undefined;
4
+ network?: string | undefined;
5
+ /** Where the tree goes in the drive. The top of the drive when absent. */
6
+ to?: string | undefined;
7
+ /** Say what it would cost and stop. Nothing is sealed, sent, or charged. */
8
+ dryRun?: boolean;
9
+ /** Include entries whose name begins with a dot. */
10
+ hidden?: boolean;
11
+ partSize?: string | number | undefined;
12
+ /** What THIS run does about a name already in use. Absent = this machine's setting. */
13
+ onCollision?: string | undefined;
14
+ /** Credits EACH file in this run sets aside as a deposit, 0 to 64. Absent = the account's own. */
15
+ deposit?: string | number | undefined;
16
+ /** Who pays: `credits` (absent) or `wallet`. See `put.ts`. */
17
+ pay?: string | undefined;
18
+ /** `--pay wallet`: how many epochs to buy for every file. */
19
+ epochs?: string | number | undefined;
20
+ /** ⛔ Refused here: a held resource holds ONE blob, and a directory is many. */
21
+ storage?: string | undefined;
22
+ json?: boolean;
23
+ write?: (line: string) => void;
24
+ /**
25
+ * Send ONE file. The real one seals, buys, uploads and records it.
26
+ *
27
+ * ⛔ A SEAM, NOT A CONVENIENCE. What is worth testing here is the decisions AROUND the upload —
28
+ * which files are skipped, what is priced, and what a run says after it stops half way — and
29
+ * every one of those needs a failure that costs no money to produce.
30
+ */
31
+ send?: (one: PlannedFile, parentId: string | null) => Promise<string>;
32
+ }
33
+ /** One local file, and where it goes in the drive. */
34
+ export interface PlannedFile {
35
+ /** Absolute path on this machine. */
36
+ local: string;
37
+ /** Folder path inside the drive. */
38
+ folder: string;
39
+ name: string;
40
+ size: number;
41
+ }
42
+ export declare function push(target: string | undefined, options?: PushOptions): Promise<number>;
43
+ /** The folder id for a drive path, made if it is not there yet. Remembered for the next file. */
44
+ export declare function folderFor(session: Awaited<ReturnType<typeof openSession>>, known: Map<string, string | null>, folder: string): Promise<string | null>;
45
+ export { walk as filesUnderDirectory };
46
+ /** Every file under a local directory, with the drive folder each one belongs in. */
47
+ declare function walk(dir: string, driveFolder: string, hidden: boolean): PlannedFile[];