@needmoretruth/nmts-cli 0.17.2 → 0.34.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 (419) hide show
  1. package/AGENTS.md +124 -516
  2. package/CHANGELOG.md +98 -0
  3. package/README.ko.md +374 -467
  4. package/README.md +384 -465
  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
package/README.md CHANGED
@@ -3,379 +3,288 @@
3
3
  Command-line access to [NMTS](https://nmts.me) — end-to-end encrypted storage on the Walrus
4
4
  network. For people at a terminal, and for the agents they run.
5
5
 
6
- > **[한국어 문서](README.ko.md)**
6
+ > **[한국어 문서](README.ko.md)** · Talk about NMTS on [Discord](https://discord.gg/pcmRkVmVZk),
7
+ > in English or Korean.
7
8
  >
8
- > **Talk about NMTS — [Discord](https://discord.gg/pcmRkVmVZk).** Questions, ideas, and
9
- > what people are building with it. English or Korean; both are read.
10
-
11
9
  > **If you are an AI agent, read [AGENTS.md](AGENTS.md) instead.** It says the same things in the
12
- > order a program needs them, and it is the file to follow when a person points you at this tool.
13
-
14
- > **Status: early.** Built in the open, and the interface may still change before 1.0. Nothing here is a promise about a shipped feature — `nmts --help` is the current truth
10
+ > order a program needs them.
11
+ >
12
+ > **Status: early.** The interface may still change before 1.0. `nmts --help` is the current truth
15
13
  > about what exists.
16
14
 
17
15
  ## What NMTS is
18
16
 
19
17
  Storage where **the encryption happens on your machine and the keys never leave it.** The server
20
- receives sealed bytes and has no way to open them; the file contents, the names and the folder
21
- structure are all inside a sealed list only your account code opens.
18
+ receives sealed bytes it cannot open. File contents, names and folders all live inside a sealed
19
+ list that only your NMTS key opens.
22
20
 
23
- The bytes themselves live on **Walrus**, a public storage network, paid for on the **Sui** chain.
24
- Two consequences worth knowing before you start:
21
+ The bytes live on **Walrus**, a public storage network, paid for on the **Sui** chain. Three
22
+ things to know before you start:
25
23
 
26
24
  - **Storage is bought for a period, not forever.** A file has a lease. It can be extended, and
27
25
  NMTS warns before one runs out.
28
- - **There is no password reset.** Your account code *is* the account. It is not recoverable and it
29
- cannot be changed while keeping the files that is the same property that stops anyone,
30
- including NMTS, from opening them.
31
-
32
- There are two ways to pay: **credits**, where NMTS's treasury buys the storage and your account
33
- spends credits it already holds, or **your own Sui wallet**, which signs the purchase itself on a
34
- public chain. Uploading here always uses credits. One command uses the wallet `nmts extend`,
35
- which buys more time for a file that is already stored and it asks for a separate agreement
36
- before it signs, because a signed purchase is not something NMTS can reverse.
26
+ - **There is no password reset.** Your NMTS key *is* the account. It cannot be recovered or
27
+ changed while keeping the files. That is the same property that stops anyone, including NMTS,
28
+ from opening them.
29
+ - **NMTS charges nothing.** Storage is bought from the Walrus network, for a period, from your own
30
+ wallet; nothing is paid to NMTS. Uploads here spend **credits**, which are storage a donation pool
31
+ has already paid the network for (the weekly free trial) they are not sold. One command,
32
+ `nmts extend`, pays from your own Sui wallet instead, and asks for a separate agreement first,
33
+ because a signed purchase on a public chain cannot be reversed by anyone.
34
+
35
+ NMTS is built and run by one developer. This tool, the encryption engine and the recovery program
36
+ are open source under Apache-2.0; the server and the web app are not published.
37
37
 
38
38
  ## Install
39
39
 
40
- Node 22 or newer. One line, straight from this repository:
40
+ Node 22.15.0 or newer. Nothing is compiled at install time and there is no native build step: the
41
+ encryption engine is a WebAssembly module carried in the repository. It runs wherever Node runs —
42
+ Linux, macOS, Windows, and inside a rootless container.
41
43
 
42
44
  ```sh
43
- npm install -g github:needmoretruth/nmts-cli
45
+ npm install -g @needmoretruth/nmts-cli
44
46
  nmts --help
45
47
  ```
46
48
 
47
- That takes the default branch. To pin a version, name a tag:
48
-
49
- ```sh
50
- npm install -g github:needmoretruth/nmts-cli#v0.17.2
51
- ```
52
-
53
- Or from the tarball on the [latest release](https://github.com/needmoretruth/nmts-cli/releases),
54
- which is the same package and needs no clone:
49
+ The same package can be installed straight from this repository, without the registry — from the
50
+ default branch, from a pinned version, or from the tarball attached to the
51
+ [latest release](https://github.com/needmoretruth/nmts-cli/releases):
55
52
 
56
53
  ```sh
54
+ npm install -g github:needmoretruth/nmts-cli # the default branch
55
+ npm install -g github:needmoretruth/nmts-cli#v0.34.1 # a pinned version
57
56
  npm install -g https://github.com/needmoretruth/nmts-cli/releases/latest/download/nmts.tgz
58
57
  ```
59
58
 
60
- **It is not on a package registry, and `npm install -g nmts` will not find it.** That short name
61
- is not available either: the registry refuses it as too close to names already published there.
62
- Nothing else about installing changes: the repository stays the source either way.
63
-
64
- **Nothing is compiled at install time**, and `dist/` is in this repository for that reason:
65
- installing straight from a repository cannot build, because npm prepares it in a staging clone
66
- where the compiler is not there. A committed build can drift from what produced it, so this
67
- repository's own checks rebuild it on every push and refuse if one byte differs.
59
+ The registry name carries the scope: `npm install -g nmts` finds nothing, because the registry refuses
60
+ that short name as too close to names already published.
68
61
 
69
- To work on it rather than install it:
70
-
71
- ```sh
72
- git clone https://github.com/needmoretruth/nmts-cli
73
- cd nmts-cli
74
- npm install
75
- node src/main.ts --help
76
- ```
77
-
78
- `npm run compile` refreshes `dist/`, and `node dist/main.js` runs it — the same file the installed
79
- command runs. It is called `compile` and not `build` for a reason worth knowing before renaming
80
- it: on npm 11, a package with a script named `build` installs from a git URL by linking npm's own
81
- temporary clone and then deleting it, which leaves a broken command and **reports success**.
82
-
83
- **There is no native build step and no C compiler anywhere in this**: the encryption engine is a
84
- WebAssembly module carried in the repository. It runs wherever Node runs — Linux, macOS,
85
- Windows, and inside a rootless container. Starting it costs about 80 milliseconds, and commands
86
- load only what they need.
62
+ To work on the source instead, see [CONTRIBUTING.md](CONTRIBUTING.md).
87
63
 
88
64
  ## Staying up to date
89
65
 
90
66
  ```sh
91
- nmts update
67
+ nmts update # installs the newest release over this one
68
+ nmts update --dry-run # prints the versions and the command, changes nothing
92
69
  ```
93
70
 
94
- It reads which release is newest, prints the version running and the version published, and
95
- installs the newer one with `npm install --global` from that release's own address. `--dry-run`
96
- prints the command and stops. Run from a source checkout rather than an installed copy, it
97
- refuses: installing would leave two copies and the PATH would decide which one runs.
98
-
99
- Separately, **once a day, after a command has finished**, it asks
100
- `https://github.com/needmoretruth/nmts-cli/releases/latest` which release is newest and writes the
101
- answer down. When that is newer than the version running, the next run prints one line on stderr
102
- saying so — stderr, so it cannot land in the output of `--json`.
103
-
104
- That request carries no account code, no API key and no command name: it asks for a page address,
105
- and what the site can see is that somebody asked for it. It is the only request this tool makes
106
- that no command asked for; everything else goes to the NMTS server or to the storage network
107
- because something needed it.
108
-
109
- Set `NMTS_NO_UPDATE_CHECK` to anything and both halves stop — the lookup and the notice.
110
- `nmts env` shows what the check last found, or why it did not answer.
71
+ Separately, once a day after a command finishes, the tool asks the releases page which version is
72
+ newest and remembers the answer. When a newer one exists, the next run prints one line on stderr.
73
+ That request carries no NMTS key, no API key and no command name, and it is the only request
74
+ the tool makes that no command asked for. Setting `NMTS_NO_UPDATE_CHECK` to anything stops both
75
+ halves, and `nmts env` shows what the check last found.
111
76
 
112
77
  ## First run
113
78
 
114
79
  ```sh
115
- nmts env
80
+ nmts env # what this machine is, and whether credentials are in reach. Contacts nothing.
81
+ nmts login # keep the NMTS key here, sealed, and take an API key
82
+ nmts ls # list the files
83
+ nmts put x # upload one file — spends credits
84
+ nmts get x # download one file
116
85
  ```
117
86
 
118
- It contacts nothing and needs no credential. It reports what this machine is, whether a file
119
- written here can actually be kept private, whether a browser could be opened, and whether it can
120
- already see your credentials. On anything unfamiliar — a container, a CI runner, someone else's
121
- laptop — run this first.
87
+ Run `nmts env` first on any machine you do not know a container, a CI runner, someone else's
88
+ laptop. It needs no credential and reports what a credential here would be exposed to.
122
89
 
123
90
  ## The two credentials
124
91
 
125
92
  They do different jobs and they are not interchangeable.
126
93
 
127
- **The account code opens your files.** Every key in the account derives from it: the file keys, the
128
- sealed list, the wallet. It never goes to the server.
129
-
130
- ```sh
131
- export NMTS_ACCOUNT_CODE_FILE=/path # name a file holding it — the recommended way
132
- nmts login # …or keep it here, sealed under a passphrase
133
- export NMTS_ACCOUNT_CODE="..." # …or hand it over directly (asks once, see below)
134
- ```
135
-
136
- **The API key makes the server answer.** Signing in normally needs a human check that no
137
- command-line tool can pass; a key, made on the account screen at [nmts.me](https://nmts.me),
138
- waives that and nothing else. **It opens no file.**
94
+ | | What it does | How to give it |
95
+ |---|---|---|
96
+ | **NMTS key** | Opens your files. Every key in the account derives from it. Never goes to the server. | `NMTS_ACCOUNT_CODE_FILE=/path` (recommended) · `nmts login` · `NMTS_ACCOUNT_CODE` |
97
+ | **API key** | Makes the server answer. Made on the account screen at nmts.me. Opens no file. | `NMTS_API_KEY_FILE=/path` (recommended) · `NMTS_API_KEY` · `nmts login` |
139
98
 
140
- ```sh
141
- export NMTS_API_KEY_FILE=/path # name a file holding it — the recommended way
142
- export NMTS_API_KEY="..." # …or hand it over directly
143
- nmts login # …and this writes down whichever it finds, or asks
144
- ```
99
+ `nmts ls` needs both: the API key so the server answers, your NMTS key so the answer can be opened.
145
100
 
146
- `nmts ls` needs both: the key so the server answers, the code so the answer can be opened.
101
+ **The NMTS key used to be called the account code; only the name changed.** The flags, the
102
+ environment variables (`NMTS_ACCOUNT_CODE`, `NMTS_ACCOUNT_CODE_FILE`), the config keys, the MCP
103
+ tool and argument names, the error codes and every file format keep the names they already had, so
104
+ nothing you have scripted breaks.
147
105
 
148
- `nmts login` checks a key with the server before it writes it down, so a wrong one is wrong at the
149
- moment it is pasted rather than at the next command. It prints the key's public handle and never
150
- the key itself. A key already stored is not replaced by a run that did not say so: at a terminal
151
- `login` asks, and where there is no terminal `nmts logout` clears what is there first.
106
+ `nmts login` checks the API key with the server before writing it down, prints that key's public
107
+ handle and never the key itself, and does not replace a stored API key unless the run says so.
108
+ `nmts logout` clears what is stored.
152
109
 
153
- **Neither credential is ever accepted as a command-line argument.** On Linux any process can read another
154
- process's command line, and shells record it in history. There is no flag for either, deliberately.
110
+ `nmts whoami --reveal` prints your NMTS key itself. It is locked until you run `nmts unlock
111
+ reveal` once, and asked about on every run; anything that logs your terminal has your NMTS key from
112
+ then on.
155
113
 
156
- ## Where the code can live
114
+ **Neither credential is ever accepted as a command-line argument.** Any process can read another
115
+ process's command line, and shells record it in history. There is no flag for either.
157
116
 
158
- Four places, and the tool has an opinion about each. Nothing is unreachable: what changes is
159
- whether it happens by accident.
117
+ ### Where the NMTS key can live
160
118
 
161
119
  | | What it does | Asks |
162
120
  |---|---|---|
163
- | `NMTS_ACCOUNT_CODE_FILE=/path` | Reads the code from a file it never copies | nothing |
121
+ | `NMTS_ACCOUNT_CODE_FILE=/path` | Reads your NMTS key from a file it never copies | nothing |
164
122
  | `nmts login` | Seals it under a passphrase at `~/.nmts/credentials.json` | nothing |
165
123
  | `nmts login --plain` | Writes it in the clear, mode 600 | once, `unsafe-code-storage` |
166
- | `NMTS_ACCOUNT_CODE`, holding the code | Uses it straight from the environment | once, `plain-env` |
167
-
168
- **`nmts login` seals by default.** What lands on disk is not the code: opening it needs a
169
- passphrase, so a copy of that file in a backup, a synced folder, a container image or a stolen
170
- laptop is worth nothing on its own. Every command that needs the code asks for the passphrase, or
171
- reads it from `NMTS_PASSPHRASE`. That costs a fraction of a second and 64 MiB of memory each
172
- time — which is the point, because it is what makes guessing the passphrase expensive.
173
-
174
- ⚠ **A passphrase does not protect the code from anything running as you.** Whatever supplies the
175
- passphrase can be read the same way. On a machine where an agent runs unattended, `NMTS_PASSPHRASE`
176
- has to be somewhere the agent can reach, and at that point the lock has its key taped beside it.
177
- That is why the file form — `NMTS_ACCOUNT_CODE_FILE` — is the recommendation for agents rather
178
- than a lesser option: the code is never copied anywhere, and the permissions are the host's to set.
124
+ | `NMTS_ACCOUNT_CODE`, holding your NMTS key | Uses it straight from the environment | once, `plain-env` |
179
125
 
180
- **An environment variable is not private, which is why using one asks.** `docker inspect` prints
181
- the whole environment of a container. Anything running as you can read `/proc/<pid>/environ` for as
182
- long as the process lives. Every child process inherits it, and continuous-integration systems
183
- routinely write it into a log. A variable naming a *file* has none of those, and asks nothing.
126
+ A sealed NMTS key needs its passphrase for every command, from a terminal or from
127
+ `NMTS_PASSPHRASE`. Opening it costs a fraction of a second and 64 MiB of memory, which is what
128
+ makes guessing the passphrase expensive. A passphrase does not protect your NMTS key from anything
129
+ running as you: on a machine where an agent runs unattended, the passphrase has to be reachable
130
+ too. That is why the file form is the recommendation for agents — your NMTS key is never copied,
131
+ and the permissions are the host's to set.
184
132
 
185
- **`nmts login --env` prints the line to set and writes nothing** the one command that puts the
186
- code on your screen, and the reason it is behind the same agreement.
133
+ An environment variable is not private: `docker inspect` prints it, anything running as you can
134
+ read `/proc/<pid>/environ`, every child process inherits it, and CI systems write it into logs.
135
+ That is why using one asks once. `nmts login --env` prints the line to set and writes nothing; it is
136
+ behind the same agreement.
187
137
 
188
- **What you do with the code outside this tool is yours.** Putting it in a note, a password manager
189
- or a repository is not something the tool can see, and it is not something it tries to stop. What
190
- it can do is make the shape *it* writes a decision somebody took on purpose.
138
+ **Under Codex, Hermes and OpenClaw an environment variable does not reach an MCP server.** All
139
+ three clear the environment before starting one. Sign in with `nmts login` instead, or put the
140
+ variables in the server's own `env` block. `nmts env` names the agent it can see.
191
141
 
192
142
  ## Before you hand this to an agent
193
143
 
194
- Your account code is everything at once. A program that has it can read every file, upload,
195
- delete, and sign with the wallet and requests made with it cannot be told apart from your own.
196
- It cannot be rotated while keeping the account.
197
-
198
- **Use an account you would be willing to lose.**
144
+ Your NMTS key is everything at once. A program that has it can read every file, upload,
145
+ delete and sign with the wallet, and its requests cannot be told apart from yours. It cannot be
146
+ rotated while keeping the account. **Use an account you would be willing to lose.**
199
147
 
200
148
  ## Commands
201
149
 
202
150
  | Command | What it does |
203
151
  |---|---|
204
152
  | `nmts env` | Where this is running, and what that means. Needs nothing. |
205
- | `nmts login` / `logout` | Keep or remove an account code on this machine |
206
- | `nmts whoami` | Which account the stored code belongs to — offline, no server call |
207
- | `nmts expiring` | Which files run out of bought storage soon, and when |
208
- | `nmts extend <path>` | Buy more storage time for one file — **signs and spends from the wallet** |
209
- | `nmts create` | Make a NEW account and print its code once. Nothing can print it again |
210
- | `nmts trial` | What is left of this week's free credits. `trial apply` asks for some |
211
- | `nmts recovery-list` | Write the file that finds this account's bytes without NMTS |
212
- | `nmts kit` | Recovery kit: that list **and the account code**, together in one file |
213
- | `nmts sweep` | Drop trash entries past their 30 days. **Cannot be undone** — asks every run |
214
- | `nmts consent` | What this machine has agreed to |
215
- | `nmts update` | Install the newest published release of this tool |
153
+ | `nmts login` / `logout` | Keep or remove an NMTS key and an API key on this machine |
154
+ | `nmts whoami` | Which account the stored NMTS key belongs to — offline. `--reveal` prints your NMTS key |
216
155
  | `nmts ls` | List the files |
217
156
  | `nmts usage` | What the account holds: counts, bytes, the largest files, the trash |
157
+ | `nmts balance` | Credits left, what they buy, and the ceilings on spending |
218
158
  | `nmts get <path>` | Download one file, decrypt it, check it |
219
159
  | `nmts pull [folder]` | Download a whole folder, or the whole account, keeping its shape |
220
- | `nmts push <directory>` | Upload a whole directory, keeping its shape — **spends credits** |
221
- | `nmts put <file>` | Encrypt one file and upload it — **spends credits** |
160
+ | `nmts put <file>` | Encrypt one file and upload it — **spends credits**. `--deposit <n>` sets the deposit for this upload |
161
+ | `nmts push <directory>` | Upload a whole directory, keeping its shape — **spends credits**. `--deposit <n>` applies to every file in it |
222
162
  | `nmts rm <paths>` | Move things to the trash — restorable for 30 days |
223
163
  | `nmts restore <paths>` | Bring things back out of the trash |
164
+ | `nmts sweep` | Drop trash entries past their 30 days. **Cannot be undone** — asks every run |
165
+ | `nmts erase <paths>` | Erase files for good — the server's record and this account's key, trash or not. A typed sentence, your NMTS key beside the API key; `--release-storage` also destroys credit-paid storage (locked until `nmts unlock release-storage`) |
224
166
  | `nmts mkdir <path>` | Make a folder, and any folder above it that is missing |
225
167
  | `nmts mv <paths> <folder>` | Move things into a folder. `/` is the top of the drive |
226
168
  | `nmts rename <path> <name>` | Give one thing a new name |
227
169
  | `nmts star` / `unstar` | Star files, or take the star off |
228
170
  | `nmts pin` / `unpin` | Hold files at the top of their folder, or let them fall back |
229
- | `nmts label <name> <files>` | Put one label on files. `unlabel` takes it off |
230
- | `nmts rebuild` | Build a file list from the server's rows, for an account with none |
231
- | `nmts listfile` | Write this machine's copy of the sealed file list out as a file |
232
- | `nmts share <path> <address>` | Give one file to another account **withdrawing does not recall it** |
233
- | `nmts shares` | What was shared with this account |
171
+ | `nmts label <name> <files>` | Put one label on files. `unlabel` takes it off; `--rename` and `--all` sweep the whole list |
172
+ | `nmts on-collision` | What an upload does when its name is already taken |
173
+ | `nmts padding [mode]` | How file sizes are hidden on the storage network, and change it for the next uploads |
174
+ | `nmts deposit [credits]` | How many credits each credit-paid upload sets aside as a deposit (0 to 64, default 64), and change it |
175
+ | `nmts tip [percent\|off]` | A standing share of every WAL payment sent to the developer as a gift (default 0). Setting it needs `nmts unlock donate`; the agreement is asked once |
176
+ | `nmts expiring` | Which files run out of bought storage soon, and when |
177
+ | `nmts losses` | Storage NMTS bought for you that the daily check could not find on the chain. `--recheck <id>` asks again; `--dismiss <id>` takes a line off |
178
+ | `nmts extend <path>` | Buy more storage time for one file — **signs and spends from the wallet** |
179
+ | `nmts wallet` | The account's wallet address, and its SUI and WAL balances. Never signs |
180
+ | `nmts wallet activity` | The wallet's recent transactions, named only where the chain proves it. Never signs |
181
+ | `nmts wallet storage` | The storage resources (size × time) the wallet holds outside any file. Never signs |
182
+ | `nmts wallet storage split <id> --size <n>\|--epochs <n>` · `merge <id> <id>` · `transfer <id> <address>` | Cut, join or hand over a storage resource — **signs**, under the wallet unlock (`transfer` needs scope `all`). No file goes with a transfer: size and remaining time only |
183
+ | `nmts wallet send <SUI\|WAL> <amount\|max> <address>` | Send coins to an address — **signs and spends from the wallet**. Prints the review; sends only with `--yes` |
184
+ | `nmts wallet swap <SUI\|WAL> <amount\|max>` | Swap one coin for the other on DeepBook or Bluefin — **signs and spends from the wallet**. Without `--venue` prints both quotes and stops; swaps only with `--yes` |
185
+ | `nmts wallet donate <SUI\|WAL> <amount>` | A voluntary gift to the developer, in either coin — **signs and spends**. Locked until `nmts unlock donate`, and `--yes` every run |
186
+ | `nmts wallet hall [--name <name>\|--remove]` | The gift hall of fame; `--name` lists you by a name you choose, signed by your wallet |
187
+ | `nmts trial` | What is left of this week's free credits. `trial apply` asks for some |
188
+ | `nmts create` | Make a NEW account and print its NMTS key once. Nothing can print it again. With no verified API key on this machine it makes the NMTS key here, prints an address, and waits while a person opens it, types that NMTS key and passes the human check — the account exists the moment they finish. `--no-wait` prints the address and stops |
189
+ | `nmts verify` | Ask a person to pass the check that opens this account's limits. Only the account holder can: signed in to this account in that browser, or typing its NMTS key there |
190
+ | `nmts public-code` | The code other accounts send files to. `--publish` makes it reachable |
191
+ | `nmts share <path> <address>` | Give one file to another account — **withdrawing does not recall it**. Locked until `nmts unlock share`; every share stops and `--yes` answers for that one file |
192
+ | `nmts shares` | What was shared with this account; `--sent <path>` shows who one file went to |
234
193
  | `nmts receive <id>` | Download one file somebody shared with this account |
235
194
  | `nmts unshare <id>` | Withdraw a share you sent, or remove one you were sent |
236
- | `nmts wallet` | The account's wallet address, and its SUI and WAL balances |
237
- | `nmts verify` | Ask a person to pass the check that opens this account's limits |
195
+ | `nmts rebuild` | Build a file list from the server's rows, for an account with none |
196
+ | `nmts rollback` | Put the previous version of the file list back locked until `nmts unlock rollback`, `--yes` every run |
197
+ | `nmts listfile` | Write this machine's copy of the sealed file list out as a file |
198
+ | `nmts recovery-list` | Write the file that finds this account's bytes without NMTS |
199
+ | `nmts kit` | Recovery kit: that list **and your NMTS key**, together in one file |
200
+ | `nmts recovery` | Download the standalone program that reads files back without NMTS |
201
+ | `nmts unlock` / `nmts lock` | What this machine has unlocked; `unlock <key>` opens one (a person, at a terminal), `lock <key>` closes it. `consent` is the older name |
202
+ | `nmts mode` | How much an agent driving this tool may decide without asking |
203
+ | `nmts support send` | Send a report to the developer — a bug, an error, an idea, a question. `--attach-log` adds the last runs, redacted |
204
+ | `nmts support list` / `show <code>` / `reply <code>` | Read the answers, and write back in the same thread |
205
+ | `nmts update` | Install the newest published release of this tool |
206
+ | `nmts notices` | What NMTS has posted: interruptions, incidents, and the warning before new Terms take effect. `notices <id>` prints one; `--save <id>` keeps it as a dated file |
207
+ | `nmts terms` | The Terms of Service in force. `--lang ko` for Korean, `--board` for the message board's terms, `--save` to keep a copy |
208
+ | `nmts privacy` | The Privacy Policy in force. `--lang ko`, `--save` to keep a copy |
209
+ | `nmts delete-account` | A **person** erases this account's server record — irreversible. Needs your NMTS key and a typed sentence; refused in the auto modes, and under skip-permissions only with `--reason` |
210
+ | `nmts accept-terms` | Accept a new version of the Terms after reading it: a person types the versions, or an agent relays them with `--accept-terms <v> --accept-privacy <v> --yes` after asking |
211
+ | `nmts key new` | Make an API key for this account with your NMTS key alone — no browser. `--scopes read,write,spend`, `--days <n>`. The new API key is stored as this machine's credential; `--print` also prints it once |
212
+ | `nmts devices` | The devices signed in to this account. `--sign-out <id>` or `--sign-out all` ends one or all of them — needs your NMTS key, locked until `nmts unlock sign-out`, asked every run |
238
213
  | `nmts mcp` | Serve a subset of the above as tools over the Model Context Protocol |
239
214
  | `nmts s3` | Serve the drive to any S3 program, on this machine only |
240
215
 
241
- `ls` takes `--json` and `--all` (include the trash). Trashed entries are hidden by default and the
242
- count always says how many were hidden. `--find <text>` keeps only files whose name contains the
243
- text; folders appear only where they hold a match, and the listing says out loud what the query
244
- left out. `--sort name|size|date` and `--desc` change the order.
245
-
246
- `share` needs an address, which the other account reads off their own account screen — there is no
247
- directory and no name lookup, so a mistyped address is caught here by the check symbol built into
248
- it rather than by asking the server about somebody. **Withdrawing a share stops further downloads
249
- and cannot reach a copy they have already taken.** That is what handing somebody a file means, and
250
- it is why sharing asks for an agreement the first time.
251
-
252
- `pull` fetches each file on its own: one that will not come back is named at the end and the rest
253
- are still on disk, because refusing the whole thing over one file is how somebody runs it twenty
254
- times and loses the same nineteen files each run. Files already in the destination are **skipped
255
- and counted**, never replaced — `--force` replaces, and that cannot be undone.
256
-
257
- `push` is the other direction, and it behaves differently on purpose. `pull` costs nothing, so it
258
- carries on past a file that will not come back; `push` **spends**, so it stops at the first failure
259
- and says what is already uploaded — those files are real and paid for, and running the same command
260
- again sends only the rest. Files whose name is already in the destination are **skipped**, which is
261
- what makes running it again safe: this tool never replaces a file, so without that a second run
262
- would pay for numbered copies of everything. Names beginning with a dot are left alone unless
263
- `--hidden` is given, because a directory of source code carries its credentials in exactly those
264
- files and an upload goes to a public storage network. Symbolic links are not followed.
265
-
266
- `rm`, `restore` and `mv` take several paths and make **one** list write. A path that names nothing
267
- stops the whole run before any server row is touched: doing four of five and exiting 0 reads as
268
- "finished", and which one was missed can only be found by comparing the drive.
269
-
270
- `rebuild` is for an account whose sealed list is gone but whose files are still stored. It rebuilds
271
- from the server's own rows — the file keys, the hashes, the dates, the sizes and what was in the
272
- trash all come back; the names, the folders and the arrangement do not, and it says so. It writes
273
- nothing without `--yes`, and it refuses outright if a list already exists.
274
-
275
- `wallet` reads; it never signs, sends or spends. The address is derived on this machine from the
276
- account code, so `nmts wallet address` needs no network at all. A balance that could not be read is
277
- reported as unread — not as zero.
278
-
279
- `get` takes `--out` and `--force`. It refuses rather than writing a half-right file: a part that
280
- will not decrypt, parts that do not add up, or a whole-file hash that does not match all leave
281
- nothing at the name you asked for. A file on disk is a claim that it is the file. The bytes are
282
- written as they arrive, under a temporary name in the same directory, and that file is renamed
283
- into place only once the whole-file hash matches. The file is never held in memory; one part
284
- at a time is, so what a machine needs is the part size the uploader chose rather than the size
285
- of the file. A download that fails takes its temporary file with it.
286
-
287
- `--out -` sends the file to whatever is reading this program instead of writing it, so reading one
288
- stored file need not leave a copy on the disk. Everything a person reads goes to stderr in that
289
- mode. It refuses to send bytes a terminal would act on — redirect or pipe it. A pipe has no
290
- rename, so that mode proves the whole file before it sends a byte, which means holding it: above
291
- 64 MiB it refuses and says to use `--out <name>` instead.
292
-
293
- `put` takes `--dry-run`, `--name` and `--to`:
294
-
295
- ```sh
296
- nmts put report.pdf --dry-run # what it would cost. Sends nothing, charges nothing.
297
- nmts put report.pdf --to notes # into an existing folder
298
- nmts put film.mov --part-size 256MiB # bigger parts: fewer purchases, more memory
299
- ```
300
-
301
- One credit per started mebibyte, printed before anything is spent. A name already taken in that
302
- folder is numbered (`report (2).pdf`) rather than replacing what is there — NMTS keeps no previous
303
- versions, so replacing would be permanent.
304
-
305
- A file larger than one part is split, and **each part is bought separately**. The file is read a
306
- slice at a time, so its size is not bounded by memory; the part size is (64 MiB by default). Each
307
- part is written down before its own purchase, so a run that stops partway is finished by running
308
- the same command again — it buys only the parts that were never bought.
309
-
310
- ### `nmts balance` and `nmts public-code`
311
-
312
- `balance` asks the server what this account can still pay for: credits left, the same number said
313
- as bytes so it means something, how much is already held, and the ceilings on spending. It is not
314
- the same question as `usage` — that one adds up the sealed file list and answers "what do I have",
315
- this one reads the ledger and answers "what can I still buy". It does not read the storage
316
- network's clock, so for *when* stored files expire it points at `nmts expiring` rather than
317
- printing a second deadline from a different source.
318
-
319
- `public-code` prints the value other accounts send files to — the same **public code** the browser
320
- shows on the account screen, in the same grouped form — and says whether it has been published.
321
- Until it is published nobody can send to you: a sender needs the key behind it, and the server is
322
- where they look. `nmts public-code --publish` writes it.
216
+ ### Listing and fetching
323
217
 
324
- That write is permanent: it cannot be withdrawn or changed. It is also not a choice — it comes
325
- from your account code, so the same account code produces the same public code on any machine, and
326
- the server refuses one that is not the fingerprint of its own key. If the server already holds a
327
- *different* public code for this account, the command stops and says what that means: the account
328
- code on this machine is not the one the account was made with.
218
+ `ls` takes `--json`, `--all` (include the trash; the count always says how many were hidden),
219
+ `--find <text>` (files whose name contains the text, with the folders that hold them), `--sort
220
+ name|size|date` and `--desc`.
329
221
 
330
- It is not your account code. That one opens every file you have and is never given to anybody;
331
- this one is meant to be given away and opens nothing on its own.
222
+ `get` takes `--out` and `--force`. It never leaves a half-right file: the bytes are written under a
223
+ temporary name in the same directory and renamed into place only once the whole-file hash
224
+ matches. One part is held in memory at a time, not the file. `--out -` sends the file to stdout
225
+ instead of writing it, with everything a person reads on stderr; a pipe cannot be taken back, so
226
+ that mode proves the whole file first and refuses above 64 MiB.
332
227
 
333
- Sending a file publishes it as a side effect, because a share cannot exist without one. Receiving
334
- is the case this command is for.
228
+ `pull` fetches each file on its own. One that will not come back is named at the end and the rest
229
+ stay on disk. Files already in the destination are skipped and counted; `--force` replaces them.
335
230
 
336
- ### `nmts recovery` — fetch the recovery program
337
-
338
- The separate recovery program restores files from the storage network with your account code, a
339
- recovery list and nothing else — no NMTS server involved. Until now getting it meant installing a
340
- Rust toolchain and building it, which is a fair ask of somebody auditing it and an unfair one of
341
- somebody who has just lost access to their files.
231
+ ### Uploading
342
232
 
343
233
  ```sh
344
- nmts recovery --out ~/tools
234
+ nmts put report.pdf --dry-run # what it would cost. Sends nothing, charges nothing.
235
+ nmts put report.pdf --to notes # into an existing folder
236
+ nmts put film.mov --part-size 256MiB # bigger parts: fewer purchases, more memory
345
237
  ```
346
238
 
347
- It works out which executable this machine needs, fetches the checksum file for the release first
348
- and takes the release's own name out of that request, then fetches the executable **from that same
349
- release** so the two can never come from different ones. The bytes are hashed and compared before
350
- anything is made runnable; a mismatch deletes the file and refuses. It never replaces a file
351
- already at that name without `--force`, and it never puts anything on your PATH.
352
-
353
- It prints the release, the address it came from and the hash, and says plainly what that check
354
- does and does not prove: it proves the bytes are the bytes that release published; it proves
355
- nothing about who published the release. The source is in the open and so is the workflow that
356
- built it — that is the part worth checking.
357
-
358
- ## The check a person has to pass
239
+ One credit per started mebibyte, printed before anything is spent. A name already taken in that
240
+ folder gets a numbered copy (`report (2).pdf`) unless `nmts on-collision` says otherwise; NMTS keeps
241
+ no previous versions, so replacing is permanent. A file larger than one part (64 MiB by default) is
242
+ split and each part bought separately; a run that stops partway is finished by running the same
243
+ command again, which buys only the parts that were never bought. The same is true after any
244
+ interrupted upload: the retry costs nothing more.
359
245
 
360
- An API key makes the server answer; it does not stand in for somebody being there. The server
361
- keeps that as a separate question — has anybody checked lately that a person is behind this
362
- account — and while the answer is no, the account still works under tighter limits, with some
363
- requests refused outright.
246
+ `--pay wallet` buys the storage **from the wallet your NMTS key derives** instead of from credits:
364
247
 
365
248
  ```sh
366
- nmts verify --status # is the check live, and until when?
367
- nmts verify # prints a short code for a person to type at nmts.me, then waits
249
+ nmts put film.mov --pay wallet --dry-run # the review: WAL price, tip, fee, balances, days. Signs nothing
250
+ nmts put film.mov --pay wallet --epochs 6 # six of the storage network's epochs (default 2)
251
+ nmts put film.mov --pay wallet --storage fit # use a storage resource the wallet already holds, cut to size
368
252
  ```
369
253
 
370
- `nmts verify` cannot pass the check for you, and neither can an agent running it: that is what is
371
- being checked. It prints a code and an address, and waits until the code is used or stops working.
372
- Ctrl-C ends the waiting and not the code.
373
-
374
- It prints the moment the check **ends** rather than a number of days, because the window ends on a
375
- boundary of the server's own weeks one passed shortly before a boundary is a short one, and the
376
- absolute moment is the only honest way to say that.
377
-
378
- ## Names, folders and the trash
254
+ The order is the safety: the file is planned into the same parts, the chain quotes each part in WAL
255
+ and the relay's tip in SUI, the register transaction is dry-run for its fee, both balances are read,
256
+ and the review is printed — the term as epochs and as days — before the `wallet` agreement (scope
257
+ `storage`) is held against the total and anything is signed. A wallet known to be short is refused
258
+ with the two numbers; a balance that could not be read is said as unread, not as zero. Each part
259
+ takes two signatures, register and certify; a run that stops partway is finished by running the same
260
+ command again, which signs nothing twice. `--storage fit|whole|<object id>` uses a free storage
261
+ resource the wallet holds (`nmts wallet storage` lists them) for a one-part file: `fit` cuts it to the
262
+ part's encoded size and leaves the rest free, `whole` binds all of it with the file, and the review
263
+ says in bytes which. Without `--storage` new storage is bought; the review only mentions what the
264
+ wallet holds. The server records the file as stored on the wallet's own storage, and `nmts extend`
265
+ can extend it. A wallet-paid upload does not carry the recovery list's storage-network copy,
266
+ whichever way the account's switch is set — today only the browser's small-file uploads do. `push
267
+ --pay wallet` does the same one file at a time.
268
+
269
+ `push` uploads a directory and **stops at the first failure**, saying what is already uploaded.
270
+ Files whose name is already in the destination are skipped, so running it again is safe. Names
271
+ beginning with a dot are left alone unless `--hidden` is given, and symbolic links are not followed.
272
+
273
+ `nmts deposit` shows how many credits each credit-paid upload sets aside as a deposit, and `nmts
274
+ deposit <n>` changes it for every device's next uploads (0 to 64, default 64). The deposit pays the
275
+ chain fee of a later operation on that file — releasing its storage early, for instance — measured
276
+ rather than spent whole, and what is left comes back when the storage period ends. `put --deposit
277
+ <n>` and `push --deposit <n>` set it for one run. `--deposit 0` sets nothing aside: that file still
278
+ releases, but pays twice the same fee out of the balance at that moment, and is refused with both
279
+ numbers named when the balance cannot cover it.
280
+
281
+ `nmts padding` shows how file sizes are hidden, and `nmts padding standard`, `nmts padding pow2` or
282
+ `nmts padding off` changes it for every device's next uploads (`off` stores the exact size: the
283
+ file's length is visible to the network and to anyone who reads the blob, for about 1 % less storage). Anyone can read the size of a piece on the storage
284
+ network; blank bytes make that size one of a set of fixed values. Powers of two hide more and cost
285
+ more storage on average.
286
+
287
+ ### Names, folders and the trash
379
288
 
380
289
  ```sh
381
290
  nmts mkdir photos/2026/august # makes all three if they are missing
@@ -385,38 +294,130 @@ nmts rm photos/2026 # to the trash, with every file under it
385
294
  nmts restore photos/2026
386
295
  ```
387
296
 
388
- **None of these costs anything or asks anything.** A name, a folder and a parent live only in your
389
- sealed file list the server holds an id, a size and a time, and has no place to put a name. So
390
- renaming and moving are invisible to NMTS, instant, and free.
297
+ None of these costs anything or asks anything: a name, a folder and a parent live only in your
298
+ sealed file list, and the server holds no place to put a name. `rm` never destroys; each trashed
299
+ file keeps its own thirty-day clock. The command that erases for good is deliberately not in this
300
+ tool. A path is matched whole (`photos/a.jpg` is not `a.jpg`), and a path that matches two entries
301
+ is refused rather than resolved. `rm`, `restore` and `mv` take several paths in one write; a path
302
+ that names nothing stops the whole run before anything is touched.
303
+
304
+ `nmts label --rename <old> <new>` renames a label on every file that carries it, and
305
+ `nmts unlabel <name> --all` takes it off all of them. Both change only the file list.
306
+
307
+ ### Money and time
308
+
309
+ `balance` answers "what can I still buy": credits left, said as bytes too, and the ceilings on
310
+ spending. `usage` answers "what do I have". `expiring` says when stored files run out.
311
+
312
+ `extend` buys more time for a stored file **from the wallet your NMTS key derives**, on a public
313
+ chain. It is locked until you unlock `wallet`, which names a scope (`storage`, or `all` for exchanging and
314
+ sending too), runs out after at most 30 days, and can carry a ceiling on what the tool signs away —
315
+ `nmts unlock wallet --days 7 [--scope all] [--cap-wal 10 --cap-sui 0.1]`. It takes
316
+ `--dry-run`, which touches no key. Before the agreement it reads the wallet and dry-runs the transaction: the price, the chain
317
+ fee (SUI) and both balances are printed, and a wallet known to be short is refused with the two
318
+ numbers rather than signed. `wallet` only reads: the address is derived on this machine, and a balance that could not be
319
+ read is reported as unread, not as zero. `wallet address --qr` draws the address as a code a phone
320
+ can scan. `wallet activity` lists the newest transactions with the same names the browser gives
321
+ them (seal, extend, erase, exchange, send, receive — otherwise "other", never a guess); gifts to the
322
+ developer show as sends there, because the tool does not know that address. `wallet storage` lists
323
+ the storage resources the wallet holds outside any file — what deleting a file from the network
324
+ gives back — and whether each can be used now. `wallet send` moves SUI or WAL to an address: it
325
+ reads both balances, judges the address and the amount by the browser's own rules, dry-runs the
326
+ transfer for its fee, prints the review with the whole address, and signs only with `--yes` and
327
+ under a `wallet` agreement of scope `all`. `max` sends everything that can be sent (SUI keeps a
328
+ reserve back for fees); `--fee-cap` puts a ceiling on the fee. A transfer cannot be undone. `wallet swap`
329
+ turns SUI into WAL or WAL into SUI on one of the two venues the browser app offers on mainnet,
330
+ DeepBook and Bluefin, with the same transaction the browser builds: your wallet signs, the outputs
331
+ come back to it, and NMTS is not a party and takes nothing. Without `--venue` it reads both
332
+ venues' quotes at the same moment, prints them side by side — what comes out, the venue's fee as
333
+ measured from the quote (or "could not be measured", never a guessed figure) — and stops: neither
334
+ is a default and the tool recommends neither; any other exchange may be used instead. With
335
+ `--venue deepbook|bluefin` it prints the review: the quote, the least it will accept
336
+ (`--slippage-bps`, 1 to 5000, default 50), the chain fee from a dry run, `--fee-cap` if given, and
337
+ how far the quote sits from the site's reference price when one can be read (said as uncompared
338
+ when none can). A slippage under 10 or over 200 bps, a fee cap far from the measured fee, or a
339
+ quote more than 3% from the reference price is refused, even with `--yes`; `--accept-extremes`
340
+ goes on anyway, and only a person may say it (refused while a mode is on). The swap needs `--yes`
341
+ and a `wallet` agreement of scope `all`; the chain gives what it gives, never less than the
342
+ minimum, and a swap that would give less fails on chain with the fee spent. On testnet the one
343
+ rail is the official Walrus exchange, SUI→WAL only, at the rate read off its object. `wallet donate` is a voluntary gift to
344
+ the developer, to the address the server publishes (the same one the wallet screen's card shows).
345
+ It is locked until you run `nmts unlock donate`, needs `--yes` on every run, and is outside the
346
+ `wallet` unlock and its ceiling. It says, before signing, that the gift is voluntary, buys nothing, is
347
+ non-refundable and cannot be undone, and that the transaction id is the only proof. `nmts tip 2.5` makes
348
+ 2.5 % of every WAL payment (an upload paid by wallet, an extension) a standing gift, sent right after the
349
+ payment without a question; `nmts tip off` stops it, and it is outside the `wallet` ceiling.
350
+
351
+ ### Sharing
352
+
353
+ `share` needs the other account's public code, read off their account screen. There is no
354
+ directory and no name lookup; a mistyped code is caught by its own check symbol. Withdrawing a
355
+ share stops further downloads and cannot reach a copy already taken, which is why sharing asks
356
+ for an agreement the first time.
357
+
358
+ `public-code` prints the value other accounts send files to and says whether it is published.
359
+ Until it is published nobody can send to you. `--publish` writes it, permanently: it derives from
360
+ your NMTS key, so it cannot be chosen or changed. It is not your NMTS key, and it opens
361
+ nothing on its own.
362
+
363
+ `nmts shares --sent <path>` lists who one file was shared with — the recipient address, since when,
364
+ and the share id `unshare` takes.
365
+
366
+ ### Recovery
367
+
368
+ `recovery-list` writes the encrypted file that locates your bytes on the storage network; it holds
369
+ no NMTS key. `kit` writes that list together with your NMTS key in one file, so whoever
370
+ holds a kit holds the account. `recovery` downloads the standalone recovery program for this
371
+ machine, checks it against the release's checksum file before making it runnable, and never puts
372
+ anything on your PATH. `rebuild` reconstructs a file list from the server's rows for an account
373
+ that has lost its own: keys, hashes, dates and sizes come back; names and folders do not.
374
+
375
+ `nmts rollback` puts the previous version of the file list back as the current one, for the case
376
+ where the current one will not open. Files the newer version added are out of the list afterwards —
377
+ their bytes are still stored, and `nmts rebuild` finds files the list does not name. It is locked
378
+ until you run `nmts unlock rollback`, and needs `--yes` on every run.
379
+
380
+ ### When storage goes missing
381
+
382
+ `nmts losses` lists the storage objects NMTS bought with your credits that the daily check could not find on the chain — the object id and the day a check first missed it. There is no file name: the server cannot pair the two, and NMTS cannot see the file. `nmts losses --recheck <id>` asks the chain again now. `nmts losses --dismiss <id>` takes a line off once you have read it; it asks once (a medium act — in an auto mode, the agent's judgement). The incident stays in a record that names nobody; the same finding is posted on the notice board by day.
383
+
384
+ ### The check a person has to pass
385
+
386
+ An API key makes the server answer; it does not stand in for somebody being there. While nobody
387
+ has checked in lately, the account still works under tighter limits, and a few requests are
388
+ refused outright.
391
389
 
392
- `rm` never destroys: it moves one thing to the trash, where it stays restorable for thirty days.
393
- The command that erases for good is deliberately not in this tool — a verb with no undo belongs to
394
- a person at a browser. Trashing a folder trashes what is under it, and each file keeps its own
395
- thirty-day clock, so restoring the folder does not resurrect something you threw away last week.
390
+ ```sh
391
+ nmts verify --status # is the check live, and until when?
392
+ nmts verify # prints a short code for the account holder to type at nmts.me, then waits
393
+ ```
396
394
 
397
- A path is matched **whole**: `photos/a.jpg` and `a.jpg` are different things, and a path that
398
- matches two entries is refused rather than resolved to whichever came first.
395
+ Neither the tool nor an agent can pass the check. It prints the moment the check ends rather than
396
+ a number of days, because the window ends on a boundary of the server's own weeks.
399
397
 
400
- If an upload is interrupted after the credits move, **running the same command again finishes it**
401
- and costs nothing more. The sealed bytes and the reservation are written down before the money
402
- moves, so a retry pushes exactly the blob that was bought rather than buying a second one.
398
+ ## What it stops to ask about
403
399
 
404
- ## Containers
400
+ Every act has a tier. **None** (listing, fetching, folders, marks) never asks. **Low** (the trash,
401
+ a setting, a report) and **medium** (uploading, publishing the public code, a new key) ask once
402
+ per run — y/N at the terminal, or `--yes`. **High** (signing with the wallet, giving another
403
+ account a file, revealing or storing your NMTS key unsealed) is locked until you run `nmts unlock
404
+ <key>` once on this machine, and then still asks on every run. **Ultra-high** (erasing the
405
+ account) is a typed sentence. `nmts unlock` lists the keys; each unlock prints what it opens, what
406
+ could go wrong and what it does not cover before it asks. `nmts help <command>` prints any
407
+ command's document, with its tier at the top.
405
408
 
406
- It runs unchanged in Docker and Podman, rootless.
409
+ ## Containers
407
410
 
408
- There is no image published anywhere, but this repository has a `Dockerfile`, so building one is a
409
- single command. Both container tools are built and run on every push to this repository, so this is
410
- a claim you can check rather than one you have to take.
411
+ It runs unchanged in Docker and Podman, rootless. There is no published image; this repository has
412
+ a `Dockerfile`, and both container tools build and run it on every push.
411
413
 
412
414
  ```sh
413
415
  docker build -t nmts . # or: podman build -t nmts .
414
416
  docker run --rm nmts --version
415
417
  ```
416
418
 
417
- The image runs as an ordinary user, and it writes what it stores to `/config` a directory it
418
- creates for that user, so mounting a volume there works. Mounting a volume on a path an image does
419
- not have gets you a root-owned volume and a tool that cannot write one byte into it.
419
+ The image runs as an ordinary user and writes to `/config`, which it creates, so a volume mounted
420
+ there works. Give credentials as files, never as environment variables inside a container:
420
421
 
421
422
  ```sh
422
423
  printf '%s' "$CODE" > /tmp/nmts-code && chmod 600 /tmp/nmts-code
@@ -429,101 +430,41 @@ docker run --rm \
429
430
  nmts ls
430
431
  ```
431
432
 
432
- **Naming a credential file the container does not have is a hard stop, not a fall-through.**
433
- `NMTS_API_KEY_FILE` pointing at nothing exits 3 before any request — which is the right behaviour
434
- and the reason both mounts are above.
435
-
436
- ### Uploading from a container needs one more thing
437
-
438
- The agreements this tool asks for once are a file in its config directory, and a container that is
439
- removed takes that file with it — so a fresh container can list and download and will refuse to
440
- upload, every time. Two ways round it, and both are ordinary:
441
-
442
- ```sh
443
- # either bake the agreement into the image
444
- RUN nmts consent grant spend
445
-
446
- # or keep the config directory outside the container
447
- docker run --rm -v nmts-config:/config … nmts put file
448
- ```
449
-
450
- The image already points this tool at `/config`, so a volume mounted there is all the second one
451
- needs. On an image of your own, `NMTS_CONFIG_DIR` moves everything this tool writes — the
452
- agreements, the stored credentials, the once-a-day update check — to a directory you choose.
453
- `nmts env` reports where it landed and whether that directory survives the container being removed.
454
-
455
- **Do not put the account code in an environment variable inside a container.** The whole
456
- environment is visible to anyone who can inspect it — `docker inspect` prints it. A variable
457
- holding a *path* gives that reader a filename and nothing else. `NMTS_ACCOUNT_CODE_FILE` works
458
- with `--secret` mounts, tmpfs, and ordinary bind mounts.
459
-
460
- `nmts env` tells you which container runtime it is in, whether root here is root on the host, and
461
- whether the directory it would write to survives the container being removed.
462
-
463
- ## What it stops to ask about
464
-
465
- Five things, once per machine: **spending credits**, **storing the account code unsealed**, **using
466
- it from a plain environment variable**, **giving another account one of your files**, and
467
- **signing with the wallet**. Each prints what would happen, what could go wrong, and the one
468
- command that agrees.
469
-
470
- The last of those belongs to one command: `nmts extend`, which buys more storage time for a file
471
- that is already stored. Everything else here is paid for with credits, which NMTS issues and can
472
- put right; that one signs a purchase on a public chain, and nobody — NMTS included — can reverse
473
- it. That is why it has an agreement of its own rather than sharing the one for spending.
433
+ A credential file that is named but missing is a hard stop (exit 3) before any request.
474
434
 
475
- Nothing else asks *once per machine*. One command asks *every run* instead: `nmts sweep`, which
476
- drops trash entries whose thirty days have run out. That destroys this account's copy of the key
477
- for those files, so a grant given once would make every later sweep silent. Listing, downloading,
478
- renaming and moving never stop for anyone.
479
-
480
- `nmts consent` shows what has been agreed to and can take it back.
435
+ Unlocks and the mode live in the config directory, and a container that is removed takes them
436
+ with it. A fresh container lists and downloads freely; an upload asks, so a script passes `--yes`,
437
+ and anything locked (the wallet, sharing) needs the config directory kept outside the container
438
+ (`-v nmts-config:/config`) where a person unlocked it once. On an image of your own, `NMTS_CONFIG_DIR` moves everything the tool
439
+ writes to a directory you choose; `nmts env` reports where it landed and whether it survives.
481
440
 
482
441
  ## Serving the drive to S3 tools
483
442
 
484
- `nmts s3` starts a server on this machine that speaks the S3 protocol. Point rclone, the AWS CLI, or
485
- any backup program that already knows S3 at it, and it lists and downloads this account's files.
443
+ `nmts s3` starts a server on this machine that speaks the S3 protocol, so rclone, the AWS CLI or
444
+ any backup program that knows S3 can list and download this account's files.
486
445
 
487
446
  ```
488
447
  $ nmts s3
489
448
  This account's drive is being served at http://127.0.0.1:9000, to this machine only.
490
-
491
449
  endpoint http://127.0.0.1:9000
492
450
  bucket drive
493
451
  access key id NMTS…
494
452
  secret key …
495
453
  ```
496
454
 
497
- - **One bucket, named `drive`.** A key is the file's path without the leading slash, so
498
- `photos/a.jpg` in the drive is `photos/a.jpg` here. Folders come back as common prefixes,
499
- including empty ones this drive has real folders and hiding them would describe a different
500
- drive from the one in the browser.
501
- - **The credentials are made when the command starts and are stored nowhere.** They stop working
502
- when it stops.
503
- - **It listens on 127.0.0.1, and there is no option to change that.** One signature stands between
504
- a request and every file in the account, and the key it checks was printed on a terminal.
505
- - **Uploading and deleting work, and both need the spending agreement.** Uploading spends credits,
506
- so a machine that has not run `nmts consent grant spend` serves the drive read only and says so
507
- every write is refused with that sentence rather than answered.
508
- - **Deleting puts a file in the trash**, where it stays recoverable for thirty days.
509
- - **A key that already holds the SAME file is answered `200`, and nothing is sent.** What is
510
- compared is the file's content, not its name: every upload records a hash of the plaintext,
511
- sealed so only this account can read it, and the gateway compares the arriving bytes against it.
512
- So a backup that runs every night pays for the files that changed and nothing for the rest.
513
- - ⛔ **A key that holds a DIFFERENT file is refused with `409`.** This drive does not replace files:
514
- the same name arrives as a numbered copy, so answering 200 would tell a sync tool it had updated
515
- a file it had duplicated. Delete it first, or upload under another key. A file stored before
516
- hashes were recorded has none to compare with, and is refused the same way with its own sentence.
517
- - **Large files go up in pieces**, the way S3 clients send them: the pieces arrive out of order and
518
- at the same time, and each one is checked against the hash the client signed for before it
519
- becomes part of the file. Nothing is stored until every piece is in. ⚠ The comparison above
520
- happens once the pieces are one file — until then there is nothing to compare — so a large file
521
- that turns out to be unchanged is sent across the loopback and then not uploaded.
522
- - ⚠ **The modification time is not carried across.** A file arrives with the time it was uploaded,
523
- so a tool comparing timestamps decides an unchanged file has changed and offers it again. That
524
- now costs nothing: the content is compared and the upload is skipped.
525
- - **A file uploaded from another device can take five seconds to appear**, which is how long a
526
- file list is reused before it is fetched again.
455
+ - One bucket, `drive`. A key is the file's path without the leading slash. Folders come back as
456
+ common prefixes, including empty ones.
457
+ - The credentials are made when the command starts, stored nowhere, and die with it.
458
+ - It listens on 127.0.0.1 only, with no option to change that.
459
+ - Starting it asks once (uploads through it spend credits); `--yes` answers for a script. Deleting
460
+ puts a file in the trash.
461
+ - A key that already holds the **same** file is answered `200` and nothing is sent: content is
462
+ compared, not names, so a nightly backup pays only for files that changed. A key that holds a
463
+ **different** file is refused with `409`, because this drive does not replace files.
464
+ - Large files go up in pieces, checked against the hash the client signed for; nothing is stored
465
+ until every piece is in.
466
+ - The modification time is not carried across, and a file uploaded from another device can take
467
+ five seconds to appear.
527
468
 
528
469
  With rclone:
529
470
 
@@ -538,120 +479,98 @@ $ rclone copy --size-only ./somewhere drive:drive
538
479
 
539
480
  ## For an agent that speaks MCP
540
481
 
541
- `nmts mcp` is a local MCP server: it runs on this machine, over stdin and stdout, and speaks to
542
- whatever started it. Sign in first (`nmts login`) it reads the account code this machine already
543
- keeps and never takes one on a command line.
544
-
545
- **Claude Code** and **Codex** both add it in one line, and the line is the same:
482
+ `nmts mcp` is a local MCP server over stdin and stdout. Sign in first (`nmts login`); it never
483
+ takes an NMTS key on a command line, and it never prompts, so a sealed NMTS key with no `NMTS_PASSPHRASE`
484
+ makes it exit 3 at startup.
546
485
 
547
486
  ```
548
- $ claude mcp add nmts -- nmts mcp --out /where/files/should/land
549
- $ codex mcp add nmts -- nmts mcp --out /where/files/should/land
487
+ $ claude mcp add nmts -- nmts mcp --out /where/files/should/land
488
+ $ codex mcp add nmts -- nmts mcp --out /where/files/should/land
489
+ $ opencode mcp add nmts -- nmts mcp --out /where/files/should/land
550
490
  ```
551
491
 
552
- **opencode** has no command for it; put this in `opencode.json`:
492
+ Hermes and OpenClaw pass the arguments one at a time (`--args` in Hermes, a repeated `--arg` in
493
+ OpenClaw); their `mcp add --help` prints the shape. Any other client takes the command `nmts` and
494
+ the arguments `mcp --out <directory>`, for example in opencode's own file:
553
495
 
554
496
  ```json
555
497
  { "mcp": { "nmts": { "type": "local", "command": ["nmts", "mcp", "--out", "/where/files/should/land"] } } }
556
498
  ```
557
499
 
558
- Any other client that runs a local MCP server takes the same two things — the command `nmts` and
559
- the arguments `mcp --out <directory>`. Where it wants them written is that client's business.
560
-
561
- It offers twenty tools reading the account (`nmts_whoami`, `nmts_list`, `nmts_usage`,
562
- `nmts_expiring`, `nmts_balance`, `nmts_shares`), fetching (`nmts_get`, `nmts_pull`,
563
- `nmts_receive`), uploading (`nmts_put`, `nmts_push`), rearranging (`nmts_mkdir`, `nmts_move`,
564
- `nmts_rename`, `nmts_mark`, `nmts_trash`, `nmts_restore`) and sharing (`nmts_public_code`,
565
- `nmts_share`, `nmts_unshare`).
566
-
567
- What it deliberately does **not** offer, and why each one is out:
568
-
569
- - **Credentials and agreements** signing in or out, making or revoking a key, granting the
570
- agreements below. Those are yours. A surface that can grant its own permissions has none.
571
- - **The check a person has to pass.** A machine cannot; that is what the check is for.
572
- - **Destroying anything for good** emptying the trash, erasing a file permanently. Putting
573
- something in the trash *is* there, because it can be taken back.
574
- - **Rebuilding a lost file list.** It works, but every name it recovers is a placeholder, and you
575
- should watch that happen rather than read about it afterwards.
576
- - **Writing your recovery files, and fetching the recovery program.** Those exist for the day this
577
- service is not there, and they are yours to make and to keep.
578
-
579
- Nothing it does offer can write outside the directory you name — a model asking for a path that
580
- climbs out of it gets the file's own name inside it, or a refusal. There is nowhere in a tool
581
- declaration to put a path on your disk, which is what keeps that true as tools are added.
582
-
583
- The arguments a tool declares are checked before it runs, and a wrong one is refused rather than
584
- guessed at: a `dry_run` sent as the string `"true"` is an error, not a paid upload.
585
-
586
- Implemented directly rather than with an SDK, so it adds no dependency.
500
+ It offers thirty-eight tools: reading the account (`nmts_whoami`, `nmts_list`, `nmts_usage`,
501
+ `nmts_expiring`, `nmts_balance`, `nmts_shares`, `nmts_shares_sent`), the wallet's own reads
502
+ (`nmts_wallet_activity`, `nmts_wallet_storage`), the signed-in devices (`nmts_devices`), storage the daily check could
503
+ not find (`nmts_losses`, `nmts_loss_recheck`), fetching (`nmts_get`, `nmts_pull`, `nmts_receive`),
504
+ uploading (`nmts_put`, `nmts_push`, `nmts_padding`, `nmts_deposit`), rearranging (`nmts_mkdir`, `nmts_move`,
505
+ `nmts_rename`, `nmts_mark`, `nmts_label_rename`, `nmts_unlabel_all`, `nmts_trash`, `nmts_restore`),
506
+ moving credits between accounts of your own (`nmts_credits_transfer`),
507
+ sharing (`nmts_public_code`, `nmts_share`, `nmts_unshare`), writing to the developer
508
+ (`nmts_support_send`, `nmts_support_list`, `nmts_support_show`, `nmts_support_reply`) and the
509
+ documents this service publishes (`nmts_notices`, `nmts_notice`, `nmts_terms`, `nmts_privacy`).
510
+
511
+ It deliberately does not offer credentials and agreements, the check a person has to pass,
512
+ permanent destruction, rebuilding a lost file list or putting the previous one back, or writing the
513
+ recovery files those are yours. Nothing it offers can write outside the directory you name, and a wrong argument is refused
514
+ rather than guessed at. It is implemented directly, with no MCP SDK dependency.
587
515
 
588
516
  ## Letting an agent decide for itself
589
517
 
590
- By default the tool asks you before anything that has not been agreed to, and an agent driving it
591
- is told not to answer for you. Two settings change that, and both take a flag that says what it is:
518
+ By default the tool asks you before every act above the lowest tier, and an agent driving it is
519
+ told not to answer for you. Four modes, switched only by a person at a terminal:
592
520
 
593
521
  ```
594
- $ nmts mode # what is set now
595
- $ nmts mode auto --i-accept-the-risk # the agent judges, and goes ahead
596
- $ nmts mode skip-permissions --i-accept-the-risk # the agent goes ahead
597
- $ nmts mode off # back to asking
522
+ $ nmts mode # what is set now
523
+ $ nmts mode explain auto-high # what a mode does, what it risks, what it gains
524
+ $ nmts mode auto-low # low acts run unasked; medium ones are the agent's judgement
525
+ $ nmts mode auto-high # the same, and the agent is asked to think further ahead
526
+ $ nmts mode skip-permissions # nothing asks and nothing is locked — a typed sentence to turn on
527
+ $ nmts mode default # back to asking
598
528
  ```
599
529
 
600
- While one is on, **every command says so** on stderr. That is deliberate: this is the setting that
601
- decides whether anybody is asked before credits are spent, and a setting that stops announcing
602
- itself is one people forget they turned on.
530
+ High acts stay locked in every mode but skip-permissions, and still ask every time once unlocked;
531
+ erasing the account is refused in both auto modes. While a mode is on, every command says so on
532
+ stderr. An agent may recommend a mode, with the explanation; it cannot switch one.
603
533
 
604
- It does not remove the agreements. Spending, wallets, sharing and where the account code may go are
605
- still recorded one at a time, with dates, and `nmts consent` still lists them. What changes is who
606
- may record them — with `skip-permissions` on, an agent doing it on your behalf is what you asked
607
- for; with it off, the instructions it reads say it must not.
534
+ ## Networks and retries
608
535
 
609
- ## When the connection blinks
536
+ `--network mainnet` or `--network testnet`, or `NMTS_NETWORK`. Against the live server it is
537
+ already known; against any other server it is required, because the wrong network answers
538
+ "not found" rather than "wrong network".
610
539
 
611
- A request that could not be made the connection refused, reset, or never established, which is
612
- what moving between a phone's data and a wifi network looks like is tried again, with a wait that
613
- grows between attempts, for about twenty seconds before the failure is reported. Nothing is retried
614
- silently: the wait is announced.
540
+ A connection that was refused, reset or never made is retried with a growing wait for about
541
+ twenty seconds, and the wait is announced. A refusal from the server, a request that ran out of
542
+ its thirty seconds, and a write without an idempotency key are not retried: the two calls that pay
543
+ carry such a key and are safe to repeat, nothing else that writes is.
615
544
 
616
- What is **not** retried, and why each one is out:
617
-
618
- - **A refusal.** The server saying no — wrong key, no credits, not found — is an answer. Asking
619
- again spends the wait to hear the same thing later. Most refusals also print one line naming what
620
- to do instead; where they do not, it is because there is nothing to add.
621
- - **A request that ran out of time.** It already had its thirty seconds, and that deadline exists so
622
- that an agent running this in a loop is not left waiting.
623
- - ⛔ **A write with no idempotency key.** A request that reached the server and died on the way back
624
- looks exactly like one that never arrived, and sending it twice can spend money twice. The two
625
- calls that pay carry a key — the server's promise that a second copy is the same request — and
626
- those are repeated. Nothing else that writes is.
545
+ ## Something wrong?
627
546
 
628
- ## Networks
547
+ Send it from the tool: `nmts support send --category bug --message "…" --attach-log`. It reaches
548
+ the one developer who builds NMTS, in the same inbox as the app's contact form, and the reply comes
549
+ back to the same thread (`nmts support list`, then `nmts support show <code>`). The tool shows you
550
+ exactly what will be sent before it goes; your NMTS key, API key, passphrase and file contents
551
+ are stripped on this machine first, and `--omit <text>` strips anything else you name. English is
552
+ preferred; Korean is read too. Ideas count as much as faults, and so does anything you are not sure
553
+ about.
629
554
 
630
- `--network mainnet` or `--network testnet`, or `NMTS_NETWORK`. It is never guessed: the wrong
631
- network looks in a place your files were never stored and answers "not found" rather than "wrong
632
- network". Against the live server the network is already known and the flag is optional; against
633
- any other server it is required.
555
+ If the tool itself cannot run, write to **nmts@nmts.me** with what you ran and what it said.
634
556
 
635
- ## Something wrong?
557
+ ## Built on this?
636
558
 
637
- **Write to `nmts@nmts.me`** — a fault, a confusing message, a missing feature, anything that got in
638
- the way. The smallest annoyance is worth an email; most are cheap to fix and invisible from this
639
- end. Say what you ran and what it said.
640
-
641
- That address is for **this tool** being wrong. Questions about the service itself, and reports
642
- about content, go through the contact desk on [nmts.me](https://nmts.me).
559
+ If you built something on this code — a service, a fork, a port to another language, a lighter
560
+ client you owe us nothing: Apache-2.0 asks for the notices and nothing more. We would still like
561
+ to know. Write to **nmts@nmts.me**, or open an issue here if public is fine with you. If you want
562
+ it listed, say so: [SHOWCASE.md](SHOWCASE.md) carries a link and up to ten lines about each
563
+ project, in English ([SHOWCASE.ko.md](SHOWCASE.ko.md) in Korean), written by the people who made it. A listing is not an
564
+ endorsement, and we may decline or remove one without giving a reason.
643
565
 
644
566
  ## Licence
645
567
 
646
- Apache-2.0. The full text is in [LICENSE](LICENSE), verbatim. It moved here from AGPL-3.0-only on
568
+ Apache-2.0 the full text is in [LICENSE](LICENSE). It moved here from AGPL-3.0-only on
647
569
  2026-08-30; copies already held under the AGPL stay under it.
648
570
 
649
- **Build on it, ship it, sell what you build with it.** Nothing is asked of you for using the
650
- program; redistributing it carries the licence and copyright notices with it. If you still need
651
- different terms, write to **nmts@nmts.me** and say why — see [LICENSING.md](LICENSING.md).
652
-
653
- Code is welcome — [CONTRIBUTING.md](CONTRIBUTING.md) says how it reaches here, and the
571
+ Build on it, ship it, sell what you build with it. If you need different terms, write to
572
+ **nmts@nmts.me** and say why see [LICENSING.md](LICENSING.md). Code is welcome:
573
+ [CONTRIBUTING.md](CONTRIBUTING.md) says how it reaches here, and the
654
574
  [Contributor License Agreement](CLA.md) is what keeps the offer above true for the whole program.
655
- Bug reports, questions and ideas are welcome too.
656
575
 
657
576
  Copyright © 2026 needmoretruth.