run402 4.93.1 → 4.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/README.md +43 -41
  2. package/cli.mjs +34 -29
  3. package/core-dist/config.js +52 -18
  4. package/core-dist/control-plane-session.js +31 -6
  5. package/core-dist/keystore.js +7 -7
  6. package/core-dist/profiles.js +9 -7
  7. package/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
  8. package/{sdk/core-dist/allowance.js → core-dist/wallet.js} +20 -20
  9. package/{sdk/core-dist/write-auth-session.js → core-dist/write-approvals.js} +19 -19
  10. package/gitvault-surface.json +1 -1
  11. package/lib/admin.mjs +1 -1
  12. package/lib/agent.mjs +20 -18
  13. package/lib/approve.mjs +81 -0
  14. package/lib/apps.mjs +3 -3
  15. package/lib/assets.mjs +2 -2
  16. package/lib/billing.mjs +6 -6
  17. package/lib/buzz-doctor.mjs +1 -1
  18. package/lib/buzz-notifications.mjs +1 -1
  19. package/lib/buzz.mjs +1 -1
  20. package/lib/buzz.test.mjs +1 -1
  21. package/lib/ci.mjs +4 -4
  22. package/lib/cold-start.mjs +21 -21
  23. package/lib/command-manifest.mjs +20 -34
  24. package/lib/config.mjs +24 -24
  25. package/lib/contacts.mjs +13 -13
  26. package/lib/contracts.mjs +1 -1
  27. package/lib/credentials.mjs +2 -2
  28. package/lib/daemon-path.mjs +1 -1
  29. package/lib/delegates.mjs +1 -1
  30. package/lib/deliveries.mjs +4 -4
  31. package/lib/deploy-rehearse-discovery.test.mjs +7 -7
  32. package/lib/deploy-v2.mjs +232 -184
  33. package/lib/deploy.mjs +21 -53
  34. package/lib/doctor-source-scan.mjs +1 -1
  35. package/lib/doctor.mjs +57 -57
  36. package/lib/escalations.mjs +1 -1
  37. package/lib/feedback.mjs +10 -10
  38. package/lib/gitvault-daemon.mjs +1 -1
  39. package/lib/image.mjs +3 -3
  40. package/lib/init.mjs +66 -66
  41. package/lib/lightning-wallet.mjs +28 -28
  42. package/lib/login.mjs +207 -0
  43. package/lib/logout.mjs +53 -0
  44. package/lib/next-actions.mjs +15 -15
  45. package/lib/org.mjs +100 -13
  46. package/lib/pay.mjs +1 -1
  47. package/lib/projects.mjs +26 -29
  48. package/lib/redeem.mjs +7 -8
  49. package/lib/remote-helper-session.mjs +12 -12
  50. package/lib/repos.mjs +62 -62
  51. package/lib/rooms.mjs +103 -67
  52. package/lib/sdk-errors.mjs +9 -4
  53. package/lib/sdk.mjs +3 -3
  54. package/lib/service.mjs +5 -5
  55. package/lib/session-proofs.mjs +21 -0
  56. package/lib/sign-in.mjs +296 -0
  57. package/lib/sites.mjs +8 -8
  58. package/lib/stats.mjs +2 -2
  59. package/lib/status.mjs +25 -25
  60. package/lib/subdomains.mjs +19 -19
  61. package/lib/subscriptions.mjs +8 -8
  62. package/lib/tier.mjs +29 -22
  63. package/lib/transfer.mjs +58 -85
  64. package/lib/up.mjs +7 -7
  65. package/lib/wallet-context.mjs +3 -3
  66. package/lib/wallet-context.test.mjs +3 -3
  67. package/lib/wallets.mjs +196 -31
  68. package/lib/webhook-secret.mjs +6 -6
  69. package/lib/whoami.mjs +75 -0
  70. package/package.json +1 -1
  71. package/sdk/core-dist/config.js +52 -18
  72. package/sdk/core-dist/control-plane-session.js +31 -6
  73. package/sdk/core-dist/keystore.js +7 -7
  74. package/sdk/core-dist/profiles.js +9 -7
  75. package/sdk/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
  76. package/{core-dist/allowance.js → sdk/core-dist/wallet.js} +20 -20
  77. package/{core-dist/write-auth-session.js → sdk/core-dist/write-approvals.js} +19 -19
  78. package/sdk/dist/actions.d.ts +1 -1
  79. package/sdk/dist/actions.d.ts.map +1 -1
  80. package/sdk/dist/control-plane-credentials.d.ts +8 -8
  81. package/sdk/dist/control-plane-credentials.js +7 -7
  82. package/sdk/dist/credentials.d.ts +19 -19
  83. package/sdk/dist/credentials.d.ts.map +1 -1
  84. package/sdk/dist/credentials.js +1 -1
  85. package/sdk/dist/errors.d.ts +24 -26
  86. package/sdk/dist/errors.d.ts.map +1 -1
  87. package/sdk/dist/errors.js +34 -37
  88. package/sdk/dist/errors.js.map +1 -1
  89. package/sdk/dist/index.d.ts +29 -16
  90. package/sdk/dist/index.d.ts.map +1 -1
  91. package/sdk/dist/index.js +29 -16
  92. package/sdk/dist/index.js.map +1 -1
  93. package/sdk/dist/kernel.d.ts +1 -1
  94. package/sdk/dist/kernel.d.ts.map +1 -1
  95. package/sdk/dist/kernel.js +10 -9
  96. package/sdk/dist/kernel.js.map +1 -1
  97. package/sdk/dist/namespaces/admin.d.ts +51 -120
  98. package/sdk/dist/namespaces/admin.d.ts.map +1 -1
  99. package/sdk/dist/namespaces/admin.js +41 -45
  100. package/sdk/dist/namespaces/admin.js.map +1 -1
  101. package/sdk/dist/namespaces/agent.d.ts +2 -2
  102. package/sdk/dist/namespaces/agent.d.ts.map +1 -1
  103. package/sdk/dist/namespaces/agent.js +2 -2
  104. package/sdk/dist/namespaces/agent.js.map +1 -1
  105. package/sdk/dist/namespaces/ai.d.ts +1 -1
  106. package/sdk/dist/namespaces/ai.js +1 -1
  107. package/sdk/dist/namespaces/billing.d.ts +6 -3
  108. package/sdk/dist/namespaces/billing.d.ts.map +1 -1
  109. package/sdk/dist/namespaces/billing.js.map +1 -1
  110. package/sdk/dist/namespaces/buzz-notifications.types.d.ts +1 -1
  111. package/sdk/dist/namespaces/buzz.d.ts +2 -2
  112. package/sdk/dist/namespaces/buzz.d.ts.map +1 -1
  113. package/sdk/dist/namespaces/buzz.js +2 -2
  114. package/sdk/dist/namespaces/buzz.js.map +1 -1
  115. package/sdk/dist/namespaces/buzz.types.d.ts +2 -2
  116. package/sdk/dist/namespaces/buzz.types.d.ts.map +1 -1
  117. package/sdk/dist/namespaces/credentials.types.d.ts +1 -1
  118. package/sdk/dist/namespaces/deploy.d.ts +1 -1
  119. package/sdk/dist/namespaces/deploy.js +5 -5
  120. package/sdk/dist/namespaces/deploy.js.map +1 -1
  121. package/sdk/dist/namespaces/deploy.types.d.ts +4 -4
  122. package/sdk/dist/namespaces/escalations.d.ts +1 -1
  123. package/sdk/dist/namespaces/escalations.js +1 -1
  124. package/sdk/dist/namespaces/escalations.types.d.ts +2 -2
  125. package/sdk/dist/namespaces/escalations.types.d.ts.map +1 -1
  126. package/sdk/dist/namespaces/events.types.d.ts +1 -1
  127. package/sdk/dist/namespaces/functions.d.ts +1 -1
  128. package/sdk/dist/namespaces/functions.js +1 -1
  129. package/sdk/dist/namespaces/gitvault.crypto.d.ts +1 -1
  130. package/sdk/dist/namespaces/gitvault.d.ts +24 -24
  131. package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
  132. package/sdk/dist/namespaces/gitvault.js +109 -109
  133. package/sdk/dist/namespaces/gitvault.js.map +1 -1
  134. package/sdk/dist/namespaces/me.d.ts +120 -0
  135. package/sdk/dist/namespaces/me.d.ts.map +1 -0
  136. package/sdk/dist/namespaces/me.js +34 -0
  137. package/sdk/dist/namespaces/me.js.map +1 -0
  138. package/sdk/dist/namespaces/org.d.ts +108 -6
  139. package/sdk/dist/namespaces/org.d.ts.map +1 -1
  140. package/sdk/dist/namespaces/org.js +63 -7
  141. package/sdk/dist/namespaces/org.js.map +1 -1
  142. package/sdk/dist/namespaces/org.types.d.ts +29 -9
  143. package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
  144. package/sdk/dist/namespaces/pay.js +3 -3
  145. package/sdk/dist/namespaces/pay.js.map +1 -1
  146. package/sdk/dist/namespaces/projects.d.ts +9 -9
  147. package/sdk/dist/namespaces/projects.js +15 -15
  148. package/sdk/dist/namespaces/projects.js.map +1 -1
  149. package/sdk/dist/namespaces/projects.types.d.ts +28 -12
  150. package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
  151. package/sdk/dist/namespaces/rooms.d.ts +7 -7
  152. package/sdk/dist/namespaces/rooms.js +17 -17
  153. package/sdk/dist/namespaces/rooms.js.map +1 -1
  154. package/sdk/dist/namespaces/rooms.types.d.ts +9 -9
  155. package/sdk/dist/namespaces/rooms.types.d.ts.map +1 -1
  156. package/sdk/dist/namespaces/service.d.ts +1 -1
  157. package/sdk/dist/namespaces/service.js +1 -1
  158. package/sdk/dist/namespaces/{operator-session.d.ts → session.d.ts} +135 -51
  159. package/sdk/dist/namespaces/session.d.ts.map +1 -0
  160. package/sdk/dist/namespaces/{operator-session.js → session.js} +118 -30
  161. package/sdk/dist/namespaces/session.js.map +1 -0
  162. package/sdk/dist/namespaces/subdomains.d.ts +5 -5
  163. package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
  164. package/sdk/dist/namespaces/subdomains.js +6 -6
  165. package/sdk/dist/namespaces/subdomains.js.map +1 -1
  166. package/sdk/dist/namespaces/tier.d.ts +43 -20
  167. package/sdk/dist/namespaces/tier.d.ts.map +1 -1
  168. package/sdk/dist/namespaces/tier.js +7 -7
  169. package/sdk/dist/namespaces/tier.js.map +1 -1
  170. package/sdk/dist/namespaces/transfers.d.ts +74 -71
  171. package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
  172. package/sdk/dist/namespaces/transfers.js +31 -38
  173. package/sdk/dist/namespaces/transfers.js.map +1 -1
  174. package/sdk/dist/namespaces/vouchers.d.ts +9 -10
  175. package/sdk/dist/namespaces/vouchers.d.ts.map +1 -1
  176. package/sdk/dist/namespaces/vouchers.js +4 -5
  177. package/sdk/dist/namespaces/vouchers.js.map +1 -1
  178. package/sdk/dist/namespaces/wallets.d.ts +72 -3
  179. package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
  180. package/sdk/dist/namespaces/wallets.js +141 -3
  181. package/sdk/dist/namespaces/wallets.js.map +1 -1
  182. package/sdk/dist/namespaces/write-approval.d.ts +101 -0
  183. package/sdk/dist/namespaces/write-approval.d.ts.map +1 -0
  184. package/sdk/dist/namespaces/write-approval.js +62 -0
  185. package/sdk/dist/namespaces/write-approval.js.map +1 -0
  186. package/sdk/dist/node/actions-node.d.ts +3 -3
  187. package/sdk/dist/node/actions-node.d.ts.map +1 -1
  188. package/sdk/dist/node/actions-node.js +36 -36
  189. package/sdk/dist/node/actions-node.js.map +1 -1
  190. package/sdk/dist/node/{bearer-claim-key.d.ts → bearer-redeem-key.d.ts} +12 -12
  191. package/sdk/dist/node/bearer-redeem-key.d.ts.map +1 -0
  192. package/sdk/dist/node/{bearer-claim-key.js → bearer-redeem-key.js} +21 -21
  193. package/sdk/dist/node/bearer-redeem-key.js.map +1 -0
  194. package/sdk/dist/node/ci.d.ts +1 -1
  195. package/sdk/dist/node/ci.d.ts.map +1 -1
  196. package/sdk/dist/node/ci.js +6 -6
  197. package/sdk/dist/node/ci.js.map +1 -1
  198. package/sdk/dist/node/credentials.d.ts +17 -16
  199. package/sdk/dist/node/credentials.d.ts.map +1 -1
  200. package/sdk/dist/node/credentials.js +28 -27
  201. package/sdk/dist/node/credentials.js.map +1 -1
  202. package/sdk/dist/node/funding-recovery.d.ts +1 -1
  203. package/sdk/dist/node/funding-recovery.d.ts.map +1 -1
  204. package/sdk/dist/node/funding-recovery.js +1 -1
  205. package/sdk/dist/node/funding-recovery.js.map +1 -1
  206. package/sdk/dist/node/gitvault-apply.d.ts +1 -1
  207. package/sdk/dist/node/gitvault-apply.d.ts.map +1 -1
  208. package/sdk/dist/node/gitvault-handoff.d.ts +22 -22
  209. package/sdk/dist/node/gitvault-handoff.d.ts.map +1 -1
  210. package/sdk/dist/node/gitvault-handoff.js +45 -45
  211. package/sdk/dist/node/gitvault-handoff.js.map +1 -1
  212. package/sdk/dist/node/gitvault-prewarm.js +7 -7
  213. package/sdk/dist/node/gitvault-prewarm.js.map +1 -1
  214. package/sdk/dist/node/gitvault-restore.d.ts +1 -1
  215. package/sdk/dist/node/gitvault-restore.js +1 -1
  216. package/sdk/dist/node/index.d.ts +16 -16
  217. package/sdk/dist/node/index.d.ts.map +1 -1
  218. package/sdk/dist/node/index.js +15 -15
  219. package/sdk/dist/node/index.js.map +1 -1
  220. package/sdk/dist/node/org-adopt.d.ts +49 -0
  221. package/sdk/dist/node/org-adopt.d.ts.map +1 -0
  222. package/sdk/dist/node/org-adopt.js +77 -0
  223. package/sdk/dist/node/org-adopt.js.map +1 -0
  224. package/sdk/dist/node/paid-fetch.d.ts +7 -7
  225. package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
  226. package/sdk/dist/node/paid-fetch.js +54 -54
  227. package/sdk/dist/node/paid-fetch.js.map +1 -1
  228. package/sdk/dist/node/preflight.d.ts +1 -1
  229. package/sdk/dist/node/preflight.d.ts.map +1 -1
  230. package/sdk/dist/node/preflight.js +1 -1
  231. package/sdk/dist/node/preflight.js.map +1 -1
  232. package/sdk/dist/node/source-scan.d.ts +1 -1
  233. package/sdk/dist/node/source-scan.js +2 -2
  234. package/sdk/dist/node/source-scan.js.map +1 -1
  235. package/sdk/dist/scoped.d.ts +3 -3
  236. package/sdk/dist/scoped.d.ts.map +1 -1
  237. package/sdk/dist/scoped.js +2 -2
  238. package/sdk/dist/scoped.js.map +1 -1
  239. package/core-dist/operator-session.js +0 -154
  240. package/lib/allowance.mjs +0 -355
  241. package/lib/operator-proofs.mjs +0 -22
  242. package/lib/operator.mjs +0 -771
  243. package/sdk/core-dist/operator-session.js +0 -154
  244. package/sdk/dist/namespaces/allowance.d.ts +0 -79
  245. package/sdk/dist/namespaces/allowance.d.ts.map +0 -1
  246. package/sdk/dist/namespaces/allowance.js +0 -149
  247. package/sdk/dist/namespaces/allowance.js.map +0 -1
  248. package/sdk/dist/namespaces/operator-session.d.ts.map +0 -1
  249. package/sdk/dist/namespaces/operator-session.js.map +0 -1
  250. package/sdk/dist/namespaces/operator.d.ts +0 -359
  251. package/sdk/dist/namespaces/operator.d.ts.map +0 -1
  252. package/sdk/dist/namespaces/operator.js +0 -272
  253. package/sdk/dist/namespaces/operator.js.map +0 -1
  254. package/sdk/dist/node/bearer-claim-key.d.ts.map +0 -1
  255. package/sdk/dist/node/bearer-claim-key.js.map +0 -1
  256. package/sdk/dist/node/operator-claim.d.ts +0 -49
  257. package/sdk/dist/node/operator-claim.d.ts.map +0 -1
  258. package/sdk/dist/node/operator-claim.js +0 -77
  259. package/sdk/dist/node/operator-claim.js.map +0 -1
@@ -14,11 +14,11 @@
14
14
  * successor, and the report must stop firing because the pipeline carries
15
15
  * those events — never because the check was removed.
16
16
  *
17
- * HTTP paths unchanged (`/agent/v1/notifications/rules*`); the allowance auth
17
+ * HTTP paths unchanged (`/agent/v1/notifications/rules*`); the SIWX auth
18
18
  * headers are PATH-scoped and must keep naming the real route.
19
19
  */
20
- import { allowanceAuthHeaders } from "./config.mjs";
21
- import { operatorProofs } from "./operator-proofs.mjs";
20
+ import { walletAuthHeaders } from "./config.mjs";
21
+ import { sessionProofs } from "./session-proofs.mjs";
22
22
  import { getSdk } from "./sdk.mjs";
23
23
  import { reportSdkError, fail } from "./sdk-errors.mjs";
24
24
  import {
@@ -96,16 +96,16 @@ async function rulesAdd(args) {
96
96
  if (typeRaw !== null) input.eventTypes = splitCsv(typeRaw);
97
97
  if (classRaw !== null) input.classes = splitCsv(classRaw);
98
98
 
99
- allowanceAuthHeaders("/agent/v1/notifications/rules");
99
+ walletAuthHeaders("/agent/v1/notifications/rules");
100
100
  try {
101
- console.log(JSON.stringify(await getSdk().admin.rules.create(input, operatorProofs("/agent/v1/notifications/rules")), null, 2));
101
+ console.log(JSON.stringify(await getSdk().admin.rules.create(input, sessionProofs("/agent/v1/notifications/rules")), null, 2));
102
102
  } catch (err) {
103
103
  reportSdkError(err);
104
104
  }
105
105
  }
106
106
 
107
107
  async function rulesList() {
108
- allowanceAuthHeaders("/agent/v1/notifications/rules");
108
+ walletAuthHeaders("/agent/v1/notifications/rules");
109
109
  try {
110
110
  console.log(JSON.stringify(await getSdk().admin.rules.list(), null, 2));
111
111
  } catch (err) {
@@ -122,9 +122,9 @@ async function rulesRm(args) {
122
122
  command: "run402 notifications rules rm <rule_id>",
123
123
  missing: "Missing <rule_id>.",
124
124
  });
125
- allowanceAuthHeaders("/agent/v1/notifications/rules");
125
+ walletAuthHeaders("/agent/v1/notifications/rules");
126
126
  try {
127
- console.log(JSON.stringify(await getSdk().admin.rules.delete(ruleId, operatorProofs("/agent/v1/notifications/rules")), null, 2));
127
+ console.log(JSON.stringify(await getSdk().admin.rules.delete(ruleId, sessionProofs("/agent/v1/notifications/rules")), null, 2));
128
128
  } catch (err) {
129
129
  reportSdkError(err);
130
130
  }
package/lib/tier.mjs CHANGED
@@ -3,30 +3,33 @@ import { reportSdkError, fail } from "./sdk-errors.mjs";
3
3
  import { assertKnownFlags, normalizeArgv, positionalArgs, flagValue, failUnknownSubcommand } from "./argparse.mjs";
4
4
  import { setTierAction } from "./next-actions.mjs";
5
5
 
6
- const HELP = `run402 tier — Manage your Run402 tier subscription
6
+ const HELP = `run402 tier — Manage your Run402 tier and its lease
7
7
 
8
8
  Usage:
9
9
  run402 tier <subcommand> [args...]
10
10
 
11
11
  Subcommands:
12
12
  status Show current tier, expiry, pool usage, and function caps when returned
13
- set <tier> Subscribe, renew, or upgrade (prepaid credit first, else x402/MPP)
13
+ set <tier> Start, renew, or upgrade the lease (the allowance first, else x402/MPP)
14
14
 
15
- Tiers: prototype ($0.10, perpetual, free with testnet faucet), hobby ($5/30d), team ($20/30d)
15
+ Tiers: prototype ($0.10 once, the free tier: no lease, never expires; covered by the testnet faucet), hobby ($5/30d), team ($20/30d)
16
16
 
17
- Prepaid credit pays first. A promo code (run402 redeem <code>) or a top-up
18
- sits on the organization's balance; 'tier set' settles from it with no payment
19
- challenge and no USDC in the wallet, and the receipt says paid_with: "credit".
20
- Only a balance that falls short goes to x402 / MPP, and that error names the
17
+ The organization's allowance pays first. A promo code (run402 redeem <code>)
18
+ or a top-up adds to the allowance; 'tier set' settles from it with no payment
19
+ challenge and no USDC in the wallet, and the receipt says paid_with: "allowance".
20
+ Only an allowance that falls short goes to x402 / MPP, and that error names the
21
21
  exact shortfall a voucher or top-up would cover.
22
22
 
23
- Tier is per organization. A single subscription covers every project on
24
- the account; api_calls and storage_bytes are pooled across all of them.
23
+ Tier is per organization. One tier covers every project on the account;
24
+ api_calls and storage_bytes are pooled across all of them. Hobby and team
25
+ are prepaid 30-day leases that end unless renewed; nothing charges again on
26
+ its own.
25
27
 
26
- The server auto-detects the action based on your allowance state:
27
- - No tier or expired → subscribe
28
+ The server auto-detects the action from the current tier state and reports
29
+ it as action: start | renew | upgrade:
30
+ - No tier or expired → start
28
31
  - Same tier, active → renew (extends from expiry)
29
- - Higher tier → upgrade (prorated refund to allowance)
32
+ - Higher tier → upgrade (prorated refund to the allowance)
30
33
  - Lower tier, active → rejected (wait for expiry)
31
34
 
32
35
  Examples:
@@ -36,7 +39,7 @@ Examples:
36
39
  `;
37
40
 
38
41
  const SUB_HELP = {
39
- status: `run402 tier status — Show current tier subscription state
42
+ status: `run402 tier status — Show current tier and lease state
40
43
 
41
44
  Usage:
42
45
  run402 tier status
@@ -49,12 +52,12 @@ Notes:
49
52
  - Newer gateways include function authoring caps such as max timeout,
50
53
  max memory, max scheduled functions, minimum cron interval, and current
51
54
  scheduled-function usage
52
- - Use 'run402 tier set <tier>' to subscribe, renew, or upgrade
55
+ - Use 'run402 tier set <tier>' to start, renew, or upgrade the lease
53
56
 
54
57
  Examples:
55
58
  run402 tier status
56
59
  `,
57
- set: `run402 tier set — Subscribe, renew, or upgrade your tier
60
+ set: `run402 tier set — Set your tier: start, renew, or upgrade the lease
58
61
 
59
62
  Usage:
60
63
  run402 tier set <tier> [--idempotency-key <key>]
@@ -63,23 +66,27 @@ Arguments:
63
66
  <tier> One of: prototype, hobby, team
64
67
 
65
68
  Options:
66
- --idempotency-key <key> Retry-safe key: re-running the same subscribe/renew
69
+ --idempotency-key <key> Retry-safe key: re-running the same start/renew
67
70
  intent with this key does not double-charge. Use a
68
71
  fresh key for a deliberate second renewal.
69
72
 
70
73
  Tiers:
71
- prototype $0.10, perpetual (free with testnet faucet)
74
+ prototype $0.10 once, the free tier: no lease, never expires
75
+ (covered by the testnet faucet)
72
76
  hobby $5/30d
73
77
  team $20/30d
74
78
 
75
79
  Notes:
76
- Tier is per organization, not per project. A successful subscribe,
80
+ Tier is per organization, not per project. A successful start,
77
81
  renew, or upgrade applies immediately to every project on the account.
82
+ Hobby and team are prepaid 30-day leases that end unless renewed;
83
+ nothing charges again on its own.
78
84
 
79
- Server auto-detects action based on current allowance state:
80
- - No tier or expired -> subscribe
85
+ Server auto-detects the action from the current tier state and reports
86
+ it as action: start | renew | upgrade:
87
+ - No tier or expired -> start
81
88
  - Same tier, active -> renew (extends from expiry)
82
- - Higher tier -> upgrade (prorated refund to allowance)
89
+ - Higher tier -> upgrade (prorated refund to the allowance)
83
90
  - Lower tier, active -> rejected (wait for expiry)
84
91
  Pays via x402 micropayments.
85
92
 
@@ -131,7 +138,7 @@ async function set(args = []) {
131
138
  next_actions: [setTierAction()],
132
139
  });
133
140
  }
134
- // Caller-supplied idempotency key makes a retried subscribe/renew safe from
141
+ // Caller-supplied idempotency key makes a retried start/renew safe from
135
142
  // double-charge. Not auto-derived: the SDK cannot tell a retry from a new
136
143
  // renewal intent (that boundary is the caller's).
137
144
  const idempotencyKey = flagValue(parsedArgs, "--idempotency-key") ?? undefined;
package/lib/transfer.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { allowanceAuthHeaders, resolveProjectId } from "./config.mjs";
1
+ import { walletAuthHeaders, resolveProjectId } from "./config.mjs";
2
2
  import { getSdk } from "./sdk.mjs";
3
3
  import { reportSdkError, fail } from "./sdk-errors.mjs";
4
4
  import {
@@ -14,21 +14,21 @@ import {
14
14
  const HELP = `run402 transfer — Project transfer, one noun for wallet, email, and owned-org recipients
15
15
 
16
16
  Usage:
17
- run402 transfer init (--to <wallet|email> | --to-org <org_id>) [--project <id>] [--billing-policy migrate] [--message <text>] [--kysigned <record_id>] [--retain-collaborator developer]
17
+ run402 transfer init (--to <wallet|email> | --to-org <org_id>) [--project <project_id>] [--billing-policy migrate] [--message <text>] [--kysigned <record_id>] [--retain-member developer]
18
18
  run402 transfer preview <transfer_id>
19
19
  run402 transfer list [--incoming | --outgoing] [--limit N] [--after <cursor>]
20
- run402 transfer accept <transfer_id>
21
- run402 transfer claim <transfer_id> [--into <org_id>] [--accept-retained-collaborator]
20
+ run402 transfer accept <transfer_id> [--org <org_id>] [--accept-retained-member]
22
21
  run402 transfer cancel <transfer_id> [--reason <text>]
23
22
 
24
23
  Subcommands:
25
- init Initiate ownership change. --to <wallet> = two-party wallet transfer
26
- (completed by 'accept'); --to <email> = email->org transfer (completed by 'claim');
24
+ init Initiate ownership change. --to <wallet> = two-party wallet transfer;
25
+ --to <email> = email-addressed transfer; both are completed by 'accept'.
27
26
  --to-org <org_id> = same-actor move to an owned org (completes immediately).
28
27
  preview Fetch the safe review document (pending transfer — kind-agnostic)
29
28
  list List pending transfers (incoming default, or --outgoing) — pending rows unioned
30
- accept Accept an incoming WALLET transfer (your wallet must be the to_wallet)
31
- claim Claim an incoming EMAIL transfer into an org (--into <id>; omit = new org)
29
+ accept Accept an incoming transfer, whatever its address (wallet: your wallet must be
30
+ the to_wallet; email: your verified email must match; --org <org_id> picks the
31
+ receiving org, omit = new org)
32
32
  cancel Cancel a pending transfer of any kind
33
33
 
34
34
  Notes:
@@ -44,24 +44,24 @@ const SUB_HELP = {
44
44
  init: `run402 transfer init — Initiate a project transfer
45
45
 
46
46
  Usage:
47
- run402 transfer init (--to <wallet|email> | --to-org <org_id>) [--project <id>] [--billing-policy migrate] [--message <text>] [--kysigned <record_id>] [--retain-collaborator developer]
47
+ run402 transfer init (--to <wallet|email> | --to-org <org_id>) [--project <project_id>] [--billing-policy migrate] [--message <text>] [--kysigned <record_id>] [--retain-member developer]
48
48
 
49
49
  Options:
50
- --project <id> Project id (defaults to the active project)
51
- --to <wallet|email> Recipient (required). A wallet uses the two-party rail (completed by
52
- 'accept'); an email uses the email->org rail (completed by 'claim').
50
+ --project <project_id> Project id (defaults to the active project)
51
+ --to <wallet|email> Recipient (required). A wallet is accepted by that wallet's signature;
52
+ an email is accepted by a principal whose verified email matches.
53
53
  --to-org <org_id> Destination org you already own. Same-actor only in the first gateway
54
54
  release; completes immediately and returns project keys.
55
55
  --billing-policy <p> Billing policy (wallet rail). Phase 1A only allows 'migrate' (default).
56
56
  --message <text> Optional note shown to the recipient in preview + emails.
57
57
  --kysigned <record_id> Optional KySigned record id (wallet rail; Phase 1A: informational only).
58
- --retain-collaborator <role> Email recipients only (v1.91): keep a 'developer' membership in
59
- the recipient's org after the transfer. The recipient must accept it at
60
- claim (--accept-retained-collaborator); omit for full severance.
58
+ --retain-member <role> Email recipients only: keep a 'developer' membership in the
59
+ recipient's org after the transfer. The recipient must accept it at
60
+ accept (--accept-retained-member); omit for full severance.
61
61
 
62
62
  Notes:
63
63
  - Caller's wallet/session must currently own or admin the project (gateway re-checks fresh DB).
64
- - Owner-side mutations on the project are frozen until accept/claim/cancel/expiry.
64
+ - Owner-side mutations on the project are frozen until accept/cancel/expiry.
65
65
  Owned-org moves complete immediately and do not create a pending window.
66
66
  - The project lease stays with your organization; it is NOT refunded.
67
67
  `,
@@ -88,16 +88,23 @@ Options:
88
88
  --limit N Page size (default 50).
89
89
  --after <cursor> Opaque keyset cursor (next_cursor from a prior page).
90
90
  `,
91
- accept: `run402 transfer accept — Accept an incoming WALLET transfer
91
+ accept: `run402 transfer accept — Accept an incoming transfer, whatever its address
92
92
 
93
93
  Usage:
94
- run402 transfer accept <transfer_id>
94
+ run402 transfer accept <transfer_id> [--org <org_id>] [--accept-retained-member]
95
95
 
96
- Your wallet must equal the transfer's to_wallet. The accept transaction
97
- atomically: flips ownership, revokes the previous owner's CI bindings on the
98
- project, enqueues notifications to both parties, and stamps a
99
- 'secrets_rotation_advised' advisory on the project. (Email transfers complete
100
- via 'claim', not 'accept'.)
96
+ The one completion. A wallet-addressed transfer is accepted by the to_wallet's
97
+ signature; an email-addressed transfer by a principal whose verified email
98
+ matches, into an org you own (--org) or, omitted, a brand-new org. Either way
99
+ the accept transaction atomically: flips ownership, revokes the previous
100
+ owner's CI bindings on the project, enqueues notifications to both parties,
101
+ stamps a 'secrets_rotation_advised' advisory on the project, and returns the
102
+ project keys (saved to your keystore).
103
+
104
+ Options:
105
+ --org <org_id> Email-addressed only: the org to receive the project (omit = new org).
106
+ --accept-retained-member Email-addressed only: accept the sender's retained-developer-membership
107
+ offer (see 'transfer preview' retain_member). Omit = full severance.
101
108
  `,
102
109
  cancel: `run402 transfer cancel — Cancel a pending transfer
103
110
 
@@ -108,19 +115,6 @@ Cancels a pending transfer of any kind. You must be authorized for the row's
108
115
  kind (a wallet signing party, or an owner/admin of the offering org / the
109
116
  addressed-email principal). Already-processed transfers return 409
110
117
  TRANSFER_ALREADY_PROCESSED.
111
- `,
112
- claim: `run402 transfer claim — Claim an incoming EMAIL transfer
113
-
114
- Usage:
115
- run402 transfer claim <transfer_id> [--into <org_id>] [--accept-retained-collaborator]
116
-
117
- Claims an email-addressed transfer into an org you own. Omit --into to claim into
118
- a brand-new org. This is the email analog of 'accept'.
119
-
120
- Options:
121
- --into <org_id> Org to claim into (omit = brand-new org).
122
- --accept-retained-collaborator Accept the sender's v1.91 retained-developer-membership offer
123
- (see 'transfer preview' retain_collaborator). Omit = full severance.
124
118
  `,
125
119
  };
126
120
 
@@ -129,7 +123,7 @@ const RETAIN_ROLES = new Set(["developer"]);
129
123
 
130
124
  async function init(args) {
131
125
  const parsedArgs = normalizeArgv(args);
132
- const valueFlags = ["--project", "--to", "--to-org", "--billing-policy", "--message", "--kysigned", "--retain-collaborator"];
126
+ const valueFlags = ["--project", "--to", "--to-org", "--billing-policy", "--message", "--kysigned", "--retain-member"];
133
127
  assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
134
128
  const extra = positionalArgs(parsedArgs, valueFlags);
135
129
  if (extra.length > 0) {
@@ -158,27 +152,27 @@ async function init(args) {
158
152
  }
159
153
  const message = flagValue(parsedArgs, "--message");
160
154
  const kysigned = flagValue(parsedArgs, "--kysigned");
161
- const retainCollaborator = flagValue(parsedArgs, "--retain-collaborator");
155
+ const retainMember = flagValue(parsedArgs, "--retain-member");
162
156
 
163
157
  // One noun, three recipient shapes. --to keeps wallet/email auto-detection;
164
158
  // --to-org is explicit because org ids are not human-recipient addresses.
165
159
  const recipientKind = toOrg ? "org" : (to.includes("@") ? "email" : "wallet");
166
160
 
167
- // --retain-collaborator (v1.91) is an email-only opt-in: the sender keeps a
168
- // developer membership in the recipient's org (recipient must accept at claim).
169
- if (retainCollaborator !== null) {
161
+ // --retain-member is an email-only opt-in: the sender keeps a developer
162
+ // membership in the recipient's org (the recipient must accept it at accept).
163
+ if (retainMember !== null) {
170
164
  if (recipientKind !== "email") {
171
165
  fail({
172
166
  code: "BAD_FLAG",
173
- message: "--retain-collaborator applies only to email recipients.",
174
- details: { flag: "--retain-collaborator" },
167
+ message: "--retain-member applies only to email recipients.",
168
+ details: { flag: "--retain-member" },
175
169
  });
176
170
  }
177
- if (!RETAIN_ROLES.has(retainCollaborator)) {
171
+ if (!RETAIN_ROLES.has(retainMember)) {
178
172
  fail({
179
173
  code: "BAD_FLAG",
180
- message: `Unsupported --retain-collaborator role: ${retainCollaborator}. Allowed: ${[...RETAIN_ROLES].join(", ")}.`,
181
- details: { flag: "--retain-collaborator", value: retainCollaborator, allowed: [...RETAIN_ROLES] },
174
+ message: `Unsupported --retain-member role: ${retainMember}. Allowed: ${[...RETAIN_ROLES].join(", ")}.`,
175
+ details: { flag: "--retain-member", value: retainMember, allowed: [...RETAIN_ROLES] },
182
176
  });
183
177
  }
184
178
  }
@@ -198,7 +192,7 @@ async function init(args) {
198
192
  }
199
193
 
200
194
  // All recipient shapes initiate on the unified transfer endpoint — sign that path.
201
- allowanceAuthHeaders(`/projects/v1/${projectId}/transfers`);
195
+ walletAuthHeaders(`/projects/v1/${projectId}/transfers`);
202
196
 
203
197
  try {
204
198
  let res;
@@ -213,7 +207,7 @@ async function init(args) {
213
207
  projectId,
214
208
  toEmail: to,
215
209
  message: message ?? undefined,
216
- retainCollaborator: retainCollaborator ? { role: retainCollaborator } : undefined,
210
+ retainMember: retainMember ? { role: retainMember } : undefined,
217
211
  });
218
212
  } else {
219
213
  res = await getSdk().admin.transfers.initiate({
@@ -239,7 +233,7 @@ async function preview(args) {
239
233
  }
240
234
  const transferId = positionals[0];
241
235
  // Preview is kind-agnostic — one route serves wallet, email, and future org transfers.
242
- allowanceAuthHeaders(`/agent/v1/transfers/${transferId}`);
236
+ walletAuthHeaders(`/agent/v1/transfers/${transferId}`);
243
237
 
244
238
  try {
245
239
  const data = await getSdk().admin.transfers.preview(transferId);
@@ -274,7 +268,7 @@ async function list(args) {
274
268
 
275
269
  // Incoming/outgoing are kind-agnostic — each returns the union of pending
276
270
  // wallet/email/future-org rows, tagged with recipient_kind.
277
- allowanceAuthHeaders(`/agent/v1/transfers/${direction}`);
271
+ walletAuthHeaders(`/agent/v1/transfers/${direction}`);
278
272
 
279
273
  try {
280
274
  const result =
@@ -300,16 +294,24 @@ async function list(args) {
300
294
 
301
295
  async function accept(args) {
302
296
  const parsedArgs = normalizeArgv(args);
303
- assertKnownFlags(parsedArgs, ["--help", "-h"]);
304
- const positionals = positionalArgs(parsedArgs);
297
+ const valueFlags = ["--org"];
298
+ assertKnownFlags(parsedArgs, [...valueFlags, "--accept-retained-member", "--help", "-h"], valueFlags);
299
+ const positionals = positionalArgs(parsedArgs, valueFlags);
305
300
  if (positionals.length !== 1) {
306
- fail({ code: "BAD_USAGE", message: "Usage: run402 transfer accept <transfer_id>" });
301
+ fail({ code: "BAD_USAGE", message: "Usage: run402 transfer accept <transfer_id> [--org <org_id>] [--accept-retained-member]" });
307
302
  }
308
303
  const transferId = positionals[0];
309
- allowanceAuthHeaders(`/agent/v1/transfers/${transferId}/accept`);
304
+ const orgId = flagValue(parsedArgs, "--org");
305
+ // Email-addressed rows only: accept the sender's retained-developer-membership
306
+ // offer (see the preview's `retain_member` block). Absent = full severance.
307
+ const acceptRetain = parsedArgs.includes("--accept-retained-member");
308
+ walletAuthHeaders(`/agent/v1/transfers/${transferId}/accept`);
310
309
 
311
310
  try {
312
- const data = await getSdk().admin.transfers.accept(transferId);
311
+ const data = await getSdk().admin.transfers.accept(transferId, {
312
+ orgId: orgId ?? undefined,
313
+ acceptRetainedMember: acceptRetain || undefined,
314
+ });
313
315
  console.log(JSON.stringify(data, null, 2));
314
316
  } catch (err) {
315
317
  reportSdkError(err);
@@ -327,7 +329,7 @@ async function cancel(args) {
327
329
  const transferId = positionals[0];
328
330
  const reason = flagValue(parsedArgs, "--reason");
329
331
  // Cancel is kind-agnostic — one route serves wallet and email transfers.
330
- allowanceAuthHeaders(`/agent/v1/transfers/${transferId}/cancel`);
332
+ walletAuthHeaders(`/agent/v1/transfers/${transferId}/cancel`);
331
333
 
332
334
  try {
333
335
  const data = await getSdk().admin.transfers.cancel(transferId, { reason: reason ?? undefined });
@@ -337,32 +339,6 @@ async function cancel(args) {
337
339
  }
338
340
  }
339
341
 
340
- async function claim(args) {
341
- const parsedArgs = normalizeArgv(args);
342
- const valueFlags = ["--into"];
343
- assertKnownFlags(parsedArgs, [...valueFlags, "--accept-retained-collaborator", "--help", "-h"], valueFlags);
344
- const positionals = positionalArgs(parsedArgs, valueFlags);
345
- if (positionals.length !== 1) {
346
- fail({ code: "BAD_USAGE", message: "Usage: run402 transfer claim <transfer_id> [--into <org_id>] [--accept-retained-collaborator]" });
347
- }
348
- const transferId = positionals[0];
349
- const into = flagValue(parsedArgs, "--into");
350
- // v1.91: accept the sender's retained-developer-membership offer (see the
351
- // preview's `retain_collaborator` block). Absent = full severance (default).
352
- const acceptRetain = parsedArgs.includes("--accept-retained-collaborator");
353
- allowanceAuthHeaders(`/agent/v1/transfers/${transferId}/claim`);
354
-
355
- try {
356
- const data = await getSdk().admin.transfers.claim(transferId, {
357
- organizationId: into ?? undefined,
358
- acceptRetainedCollaborator: acceptRetain || undefined,
359
- });
360
- console.log(JSON.stringify(data, null, 2));
361
- } catch (err) {
362
- reportSdkError(err);
363
- }
364
- }
365
-
366
342
  export async function run(sub, args) {
367
343
  if (!sub || sub === "--help" || sub === "-h") {
368
344
  console.log(HELP);
@@ -385,9 +361,6 @@ export async function run(sub, args) {
385
361
  case "accept":
386
362
  await accept(args);
387
363
  return;
388
- case "claim":
389
- await claim(args);
390
- return;
391
364
  case "cancel":
392
365
  await cancel(args);
393
366
  return;
package/lib/up.mjs CHANGED
@@ -7,7 +7,7 @@ import { getSdk } from "./sdk.mjs";
7
7
  import { reportSdkError, fail } from "./sdk-errors.mjs";
8
8
  import { assertKnownFlags, flagValue, normalizeArgv, positionalArgs } from "./argparse.mjs";
9
9
  import { createUpdateCheckScheduler, emitUpdateNotice } from "./update-check.mjs";
10
- import { allowanceAuthHeaders, isCoreApiTarget, updateProject } from "./config.mjs";
10
+ import { walletAuthHeaders, isCoreApiTarget, updateProject } from "./config.mjs";
11
11
  import { loadLiveControlPlaneSession } from "../core-dist/control-plane-session.js";
12
12
 
13
13
  const HELP = `run402 up — Provision/link/deploy the current app
@@ -27,7 +27,7 @@ Options:
27
27
  --dir <path> Workspace directory to inspect (default: current dir).
28
28
  --tier <tier> Bootstrap tier if no active Cloud tier exists
29
29
  (prototype, hobby, team; default prototype).
30
- -y, --yes Approve recursive prerequisites/local writes (allowance,
30
+ -y, --yes Approve recursive prerequisites/local writes (wallet,
31
31
  tier, project creation, workspace link) for non-interactive runs.
32
32
  --check Validate the manifest/config locally and print the
33
33
  preflight, including the site inventory by content type
@@ -53,7 +53,7 @@ Options:
53
53
  --propagation-budget-s <n>
54
54
  Maximum wall-clock seconds to wait for fresh edge
55
55
  propagation during app HTTP verification (default 120).
56
- --verify After a deploy apply, wait for gateway/edge release
56
+ --verify After the deploy, wait for gateway/edge release
57
57
  coherence and attach the report to the final result.
58
58
  --no-propagation-wait
59
59
  Return propagation_pending immediately when the edge is
@@ -373,7 +373,7 @@ export async function run(args = []) {
373
373
  ? undefined
374
374
  : undefined,
375
375
  });
376
- // Cache the activated deployment id so `run402 subdomains claim` can
376
+ // Cache the activated deployment id so `run402 subdomains add` can
377
377
  // pass it as an optimization (the gateway binds the live release
378
378
  // without it). Best-effort: a keystore hiccup never fails `up`.
379
379
  {
@@ -773,12 +773,12 @@ async function readLocalGitState(workDir) {
773
773
  * inside `up`'s mental model" entry point to the same outcome.
774
774
  */
775
775
  async function runRepoOnly({ sdk, workDir, createdRepository, nested = false, opts, tier, idempotencyKey }) {
776
- // `sdk.up()`'s action graph auto-approves prerequisites (allowance, tier)
776
+ // `sdk.up()`'s action graph auto-approves prerequisites (wallet, tier)
777
777
  // for a cold start; calling projects.provision directly bypasses that, so
778
778
  // this mirrors the SAME gate `run402 projects provision` itself uses —
779
- // fail with the actionable NO_ALLOWANCE guidance rather than an opaque
779
+ // fail with the actionable NO_WALLET guidance rather than an opaque
780
780
  // auth error from the gateway.
781
- if (!isCoreApiTarget() && !loadLiveControlPlaneSession()) allowanceAuthHeaders("/projects/v1");
781
+ if (!isCoreApiTarget() && !loadLiveControlPlaneSession()) walletAuthHeaders("/projects/v1");
782
782
  const name = flagValue(opts, "--name") ?? undefined;
783
783
  const provisioned = await sdk.projects.provision({ tier, name, idempotencyKey });
784
784
  createdRepository = await gitInitIfNeeded(workDir);
@@ -25,7 +25,7 @@ import { join } from "node:path";
25
25
  import { fail } from "./sdk-errors.mjs";
26
26
  import { isValidProfileName } from "../core-dist/config.js";
27
27
  import { getDefaultWallet, profileExists, readMeta, profileDir } from "../core-dist/profiles.js";
28
- import { readAllowance } from "../core-dist/allowance.js";
28
+ import { readWallet } from "../core-dist/wallet.js";
29
29
  import { describeRejectedValue } from "../core-dist/redact.js";
30
30
  // The binding file is a CHECKOUT-LEVEL CONTRACT read by more than one surface,
31
31
  // so its reader lives in core — `run402-mcp` ships core/dist but not cli/, and
@@ -301,12 +301,12 @@ function shortAddr(a) {
301
301
  return typeof a === "string" && a.length >= 12 ? `${a.slice(0, 6)}…${a.slice(-4)}` : a;
302
302
  }
303
303
 
304
- /** Best-effort address for display: meta.json (no key) first, allowance second. */
304
+ /** Best-effort address for display: meta.json (no key) first, wallet second. */
305
305
  function walletAddress(name) {
306
306
  const meta = readMeta(name);
307
307
  if (meta?.address) return meta.address;
308
308
  try {
309
- return readAllowance(join(profileDir(name), "allowance.json"))?.address ?? null;
309
+ return readWallet(join(profileDir(name), "wallet.json"))?.address ?? null;
310
310
  } catch {
311
311
  return null;
312
312
  }
@@ -67,8 +67,8 @@ describe("splitWalletFlag", () => {
67
67
  assert.deepEqual(r.walletFlag, { flag: "--wallet", value: "kychon" });
68
68
  });
69
69
  it("strips --wallet=<value> mid-args", () => {
70
- const r = splitWalletFlag(["deploy", "apply", "--wallet=foo", "--manifest", "x"]);
71
- assert.deepEqual(r.argv, ["deploy", "apply", "--manifest", "x"]);
70
+ const r = splitWalletFlag(["deploy", "--wallet=foo", "--manifest", "x"]);
71
+ assert.deepEqual(r.argv, ["deploy", "--manifest", "x"]);
72
72
  assert.equal(r.walletFlag.value, "foo");
73
73
  });
74
74
  it("leaves --profile to `repos`, which owns it as the AWS credential profile", () => {
@@ -238,7 +238,7 @@ describe("enforceWalletExists — fail closed", () => {
238
238
  });
239
239
  it("no-op for an existing wallet", () => {
240
240
  ensureProfileDir("client-a");
241
- writeFileSync(join(tmp, "profiles", "client-a", "allowance.json"), "{}");
241
+ writeFileSync(join(tmp, "profiles", "client-a", "wallet.json"), "{}");
242
242
  assert.doesNotThrow(() => enforceWalletExists({ name: "client-a", source: "binding" }, "deploy"));
243
243
  });
244
244
  it("fails closed for a missing wallet on a normal command", () => {