run402 2.43.0 → 2.45.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 (40) hide show
  1. package/README.md +1 -1
  2. package/cli.mjs +1 -1
  3. package/lib/admin.mjs +22 -22
  4. package/lib/allowance.mjs +8 -4
  5. package/lib/billing.mjs +123 -125
  6. package/lib/operator.mjs +3 -3
  7. package/lib/projects.mjs +4 -4
  8. package/lib/sdk-errors.mjs +1 -1
  9. package/lib/service.mjs +1 -1
  10. package/lib/status.mjs +5 -5
  11. package/lib/tier.mjs +4 -4
  12. package/lib/transfer.mjs +5 -5
  13. package/package.json +1 -1
  14. package/sdk/dist/errors.d.ts +8 -8
  15. package/sdk/dist/errors.d.ts.map +1 -1
  16. package/sdk/dist/errors.js +6 -6
  17. package/sdk/dist/errors.js.map +1 -1
  18. package/sdk/dist/namespaces/admin.d.ts +15 -16
  19. package/sdk/dist/namespaces/admin.d.ts.map +1 -1
  20. package/sdk/dist/namespaces/admin.js +14 -15
  21. package/sdk/dist/namespaces/admin.js.map +1 -1
  22. package/sdk/dist/namespaces/billing.d.ts +66 -62
  23. package/sdk/dist/namespaces/billing.d.ts.map +1 -1
  24. package/sdk/dist/namespaces/billing.js +96 -106
  25. package/sdk/dist/namespaces/billing.js.map +1 -1
  26. package/sdk/dist/namespaces/operator.d.ts +3 -3
  27. package/sdk/dist/namespaces/operator.d.ts.map +1 -1
  28. package/sdk/dist/namespaces/operator.js +1 -1
  29. package/sdk/dist/namespaces/org.types.d.ts +2 -2
  30. package/sdk/dist/namespaces/org.types.js +1 -1
  31. package/sdk/dist/namespaces/projects.d.ts +2 -2
  32. package/sdk/dist/namespaces/projects.js +2 -2
  33. package/sdk/dist/namespaces/projects.types.d.ts +15 -15
  34. package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
  35. package/sdk/dist/namespaces/tier.d.ts +11 -11
  36. package/sdk/dist/namespaces/tier.d.ts.map +1 -1
  37. package/sdk/dist/namespaces/transfers.d.ts +8 -8
  38. package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
  39. package/sdk/dist/namespaces/transfers.js +3 -3
  40. package/sdk/dist/namespaces/transfers.js.map +1 -1
package/README.md CHANGED
@@ -188,7 +188,7 @@ Private keys never leave AWS KMS. $0.04/day rental + $0.000005/call.
188
188
  ```bash
189
189
  run402 tier set prototype # free on testnet
190
190
  run402 tier set hobby # $5 / 30 days
191
- run402 billing tier-checkout hobby --email me@example.com # Stripe alternative
191
+ run402 billing checkout <org_id> --product tier --tier hobby # Stripe alternative
192
192
  ```
193
193
 
194
194
  ## State
package/cli.mjs CHANGED
@@ -47,7 +47,7 @@ Commands:
47
47
  message Send messages to Run402 developers
48
48
  auth Manage project user authentication (magic link, passwords, settings)
49
49
  sender-domain Manage custom email sender domain (register, status, remove)
50
- billing Email billing accounts, Stripe tier checkout, email packs
50
+ billing Email organizations, Stripe tier checkout, email packs
51
51
  contracts KMS contract wallets ($0.04/day rental + $0.000005/sign)
52
52
  agent Manage agent identity (contact info)
53
53
  operator Operator (human/email) session — login, then overview across your wallets
package/lib/admin.mjs CHANGED
@@ -8,9 +8,9 @@ Usage:
8
8
  run402 admin <subcommand> [args...]
9
9
 
10
10
  Subcommands:
11
- lease-perpetual <billing_account_id> (--enable | --disable)
12
- Toggle the account-level escape hatch.
13
- When enabled, the account never advances
11
+ lease-perpetual <organization_id> (--enable | --disable)
12
+ Toggle the organization-level escape hatch.
13
+ When enabled, the organization never advances
14
14
  past 'active' regardless of lease expiry.
15
15
  If the account is currently in a grace
16
16
  state, enabling reactivates it inline
@@ -19,12 +19,12 @@ Subcommands:
19
19
 
20
20
  archive <project_id> [--reason "..."] Moderate-archive a single project. Sets
21
21
  projects.archived_at = NOW(). Independent
22
- of account lifecycle; the rest of the
23
- account's projects keep serving.
22
+ of organization lifecycle; the rest of the
23
+ organization's projects keep serving.
24
24
 
25
25
  reactivate <project_id> Un-archive a project (flips archived_at
26
26
  back to NULL). In v1.57 this no longer
27
- touches account-level lifecycle — to
27
+ touches organization-level lifecycle — to
28
28
  reactivate a grace-state account, use
29
29
  \`tier set <tier>\` or enable
30
30
  lease-perpetual above.
@@ -36,17 +36,17 @@ Notes:
36
36
  - Output is JSON.
37
37
 
38
38
  Examples:
39
- run402 admin lease-perpetual ba_abc123 --enable
40
- run402 admin lease-perpetual ba_abc123 --disable
39
+ run402 admin lease-perpetual org_abc123 --enable
40
+ run402 admin lease-perpetual org_abc123 --disable
41
41
  run402 admin archive prj_abuse --reason "ToS violation"
42
42
  run402 admin reactivate prj_abuse
43
43
  `;
44
44
 
45
45
  const SUB_HELP = {
46
- "lease-perpetual": `run402 admin lease-perpetual — Toggle the account-level escape hatch
46
+ "lease-perpetual": `run402 admin lease-perpetual — Toggle the organization-level escape hatch
47
47
 
48
48
  Usage:
49
- run402 admin lease-perpetual <billing_account_id> (--enable | --disable)
49
+ run402 admin lease-perpetual <organization_id> (--enable | --disable)
50
50
 
51
51
  Options:
52
52
  --enable Set lease_perpetual = true (pins every project on the account)
@@ -59,8 +59,8 @@ Notes:
59
59
  the gateway reactivates inline and reports \`reactivated: true\`.
60
60
 
61
61
  Examples:
62
- run402 admin lease-perpetual ba_abc123 --enable
63
- run402 admin lease-perpetual ba_abc123 --disable
62
+ run402 admin lease-perpetual org_abc123 --enable
63
+ run402 admin lease-perpetual org_abc123 --disable
64
64
  `,
65
65
  archive: `run402 admin archive — Moderate-archive a single project
66
66
 
@@ -71,8 +71,8 @@ Options:
71
71
  --reason <text> Free-text moderation reason recorded in the audit log.
72
72
 
73
73
  Notes:
74
- - Sets projects.archived_at = NOW(). Independent of account-level lifecycle —
75
- only this project goes dark; siblings on the same billing account keep
74
+ - Sets projects.archived_at = NOW(). Independent of organization-level lifecycle —
75
+ only this project goes dark; siblings on the same organization keep
76
76
  serving.
77
77
  - No-op when the project is already archived (returns \`note: "already
78
78
  archived"\` without changing archived_at).
@@ -88,9 +88,9 @@ Usage:
88
88
 
89
89
  Notes:
90
90
  - Flips projects.archived_at back to NULL. In v1.57 this was narrowed:
91
- account-level lifecycle reactivation is NOT triggered. Use
91
+ organization-level lifecycle reactivation is NOT triggered. Use
92
92
  \`run402 tier set <tier>\` (the tier flow runs the lifecycle advance) or
93
- \`run402 admin lease-perpetual <ba_id> --enable\` for that.
93
+ \`run402 admin lease-perpetual <org_id> --enable\` for that.
94
94
  - No-op when the project is not archived (returns \`note: "not archived"\`).
95
95
 
96
96
  Examples:
@@ -110,25 +110,25 @@ function validateFlags(sub, args) {
110
110
  }
111
111
 
112
112
  async function leasePerpetual(args) {
113
- const accountId = args.find((a) => typeof a === "string" && !a.startsWith("--"));
113
+ const organizationId = args.find((a) => typeof a === "string" && !a.startsWith("--"));
114
114
  const enable = args.includes("--enable");
115
115
  const disable = args.includes("--disable");
116
- if (!accountId) {
116
+ if (!organizationId) {
117
117
  fail({
118
118
  code: "BAD_USAGE",
119
- message: "Missing <billing_account_id>.",
120
- hint: "run402 admin lease-perpetual <billing_account_id> --enable | --disable",
119
+ message: "Missing <organization_id>.",
120
+ hint: "run402 admin lease-perpetual <organization_id> --enable | --disable",
121
121
  });
122
122
  }
123
123
  if (enable === disable) {
124
124
  fail({
125
125
  code: "BAD_USAGE",
126
126
  message: "Pass exactly one of --enable / --disable.",
127
- hint: "run402 admin lease-perpetual <billing_account_id> --enable | --disable",
127
+ hint: "run402 admin lease-perpetual <organization_id> --enable | --disable",
128
128
  });
129
129
  }
130
130
  try {
131
- const data = await getSdk().admin.setLeasePerpetual(accountId, enable);
131
+ const data = await getSdk().admin.setLeasePerpetual(organizationId, enable);
132
132
  console.log(JSON.stringify(data, null, 2));
133
133
  } catch (err) {
134
134
  reportSdkError(err);
package/lib/allowance.mjs CHANGED
@@ -14,7 +14,7 @@ Subcommands:
14
14
  fund Request test funds from the faucet (Base Sepolia or Tempo)
15
15
  balance Show on-chain balances and Run402 billing balance
16
16
  export Print the allowance address (useful for scripting)
17
- checkout Create a billing checkout session (--amount <usd_micros>)
17
+ checkout Create an org balance checkout session (--amount <usd_micros>)
18
18
  history View billing transaction history (--limit <n>)
19
19
 
20
20
  Notes:
@@ -33,7 +33,7 @@ Examples:
33
33
  `;
34
34
 
35
35
  const SUB_HELP = {
36
- checkout: `run402 allowance checkout — Create a billing checkout session
36
+ checkout: `run402 allowance checkout — Create an org balance checkout session
37
37
 
38
38
  Usage:
39
39
  run402 allowance checkout --amount <usd_micros>
@@ -238,7 +238,7 @@ async function balance() {
238
238
  "base-sepolia_usd_micros": sepoliaUsdc,
239
239
  "tempo-moderato_pathusd_micros": tempoPathUsd,
240
240
  },
241
- run402: billingRes ? { balance_usd_micros: billingRes.available_usd_micros } : "no billing account",
241
+ run402: billingRes ? { balance_usd_micros: billingRes.available_usd_micros } : "no organization",
242
242
  }, null, 2));
243
243
  }
244
244
 
@@ -280,7 +280,11 @@ async function checkout(args) {
280
280
  }
281
281
  const amount = parseIntegerFlag("--amount", amountRaw, { min: 1 });
282
282
  try {
283
- const data = await getSdk().billing.createCheckout(w.address, amount);
283
+ const org = await getSdk().billing.lookupOrganization(w.address);
284
+ const data = await getSdk().billing.createCheckout(org.organization_id, {
285
+ product: "balance_topup",
286
+ amountUsdMicros: amount,
287
+ });
284
288
  console.log(JSON.stringify(data, null, 2));
285
289
  } catch (err) {
286
290
  reportSdkError(err);
package/lib/billing.mjs CHANGED
@@ -2,88 +2,78 @@ import { getSdk } from "./sdk.mjs";
2
2
  import { reportSdkError, fail } from "./sdk-errors.mjs";
3
3
  import { assertKnownFlags, flagValue, normalizeArgv, parseIntegerFlag, positionalArgs } from "./argparse.mjs";
4
4
 
5
- const HELP = `run402 billing — Email billing accounts, Stripe tier checkout, email packs
5
+ const HELP = `run402 billing — Email organizations and org checkouts
6
6
 
7
7
  Usage:
8
8
  run402 billing <subcommand> [args...]
9
9
 
10
10
  Subcommands:
11
- create-email <email> Create an email billing account
12
- link-wallet <account_id> <wallet> Link a wallet to an email account
13
- tier-checkout <tier> [--email <e> | --wallet <w>] Stripe tier checkout
14
- buy-email-pack [--email <e> | --wallet <w>] Buy \$5 email pack (10,000 emails)
15
- auto-recharge <account_id> <on|off> [--threshold <n>]
16
- balance <identifier> Balance by account id (UUID), wallet (0x...), or email
17
- history <identifier> [--limit <n>] Ledger history by account id (UUID), wallet, or email
11
+ create-email <email> Create an email organization
12
+ link-wallet <org_id> <wallet> Link a wallet to an email organization
13
+ checkout <identifier> --product <p> Create an org checkout
14
+ auto-recharge <org_id> <on|off> [--threshold <n>]
15
+ balance <identifier> Balance by organization id (UUID), wallet (0x...), or email
16
+ history <identifier> [--limit <n>] Ledger history by organization id (UUID), wallet, or email
18
17
 
19
18
  Examples:
20
19
  run402 billing create-email user@example.com
21
- run402 billing tier-checkout hobby --email user@example.com
22
- run402 billing buy-email-pack --wallet 0x1234...
23
- run402 billing auto-recharge acct_abc on --threshold 2000
20
+ run402 billing checkout 00000000-0000-4000-8000-000000000001 --product tier --tier hobby
21
+ run402 billing checkout 0x1234... --product email-pack
22
+ run402 billing checkout 0x1234... --product balance-topup --amount 5000000
23
+ run402 billing auto-recharge org_abc on --threshold 2000
24
24
  run402 billing balance user@example.com
25
25
  `;
26
26
 
27
27
  const SUB_HELP = {
28
- "tier-checkout": `run402 billing tier-checkout — Create a Stripe tier checkout session
28
+ checkout: `run402 billing checkout — Create an org checkout
29
29
 
30
30
  Usage:
31
- run402 billing tier-checkout <tier> [--email <e> | --wallet <w>]
31
+ run402 billing checkout <identifier> --product <tier|email-pack|balance-topup> [options]
32
32
 
33
33
  Arguments:
34
- <tier> Tier name (e.g. hobby, pro)
34
+ <identifier> Organization id (UUID), wallet (0x...), or email.
35
+ Wallet/email are resolved to the organization id first.
35
36
 
36
37
  Options:
37
- --email <e> Email billing account to charge
38
- --wallet <w> Wallet address (0x...) to associate with the checkout
38
+ --product <p> tier, email-pack, or balance-topup
39
+ --tier <tier> Tier name for --product tier
40
+ --amount <n> USD micros for --product balance-topup
39
41
 
40
42
  Examples:
41
- run402 billing tier-checkout hobby --email user@example.com
42
- run402 billing tier-checkout pro --wallet 0x1234...
43
- `,
44
- "buy-email-pack": `run402 billing buy-email-pack — Buy a $5 email pack (10,000 emails)
45
-
46
- Usage:
47
- run402 billing buy-email-pack [--email <e> | --wallet <w>]
48
-
49
- Options:
50
- --email <e> Email billing account to charge
51
- --wallet <w> Wallet address (0x...) to associate with the purchase
52
-
53
- Examples:
54
- run402 billing buy-email-pack --email user@example.com
55
- run402 billing buy-email-pack --wallet 0x1234...
43
+ run402 billing checkout 00000000-0000-4000-8000-000000000001 --product tier --tier hobby
44
+ run402 billing checkout 0x1234... --product email-pack
45
+ run402 billing checkout 0x1234... --product balance-topup --amount 5000000
56
46
  `,
57
47
  "auto-recharge": `run402 billing auto-recharge — Toggle email-pack auto-recharge
58
48
 
59
49
  Usage:
60
- run402 billing auto-recharge <account_id> <on|off> [--threshold <n>]
50
+ run402 billing auto-recharge <org_id> <on|off> [--threshold <n>]
61
51
 
62
52
  Arguments:
63
- <account_id> Billing account ID
53
+ <org_id> Organization ID
64
54
  <on|off> Enable or disable auto-recharge
65
55
 
66
56
  Options:
67
57
  --threshold <n> Remaining-email threshold that triggers auto-recharge
68
58
 
69
59
  Examples:
70
- run402 billing auto-recharge acct_abc on --threshold 2000
71
- run402 billing auto-recharge acct_abc off
60
+ run402 billing auto-recharge org_abc on --threshold 2000
61
+ run402 billing auto-recharge org_abc off
72
62
  `,
73
- history: `run402 billing history — Show ledger history for a billing account
63
+ history: `run402 billing history — Show ledger history for a organization
74
64
 
75
65
  Usage:
76
66
  run402 billing history <identifier> [--limit <n>]
77
67
 
78
68
  Arguments:
79
- <identifier> Billing account id (UUID), wallet (0x...), or email.
80
- Wallet/email are resolved to the account id first.
69
+ <identifier> Organization id (UUID), wallet (0x...), or email.
70
+ Wallet/email are resolved to the organization id first.
81
71
 
82
72
  Options:
83
73
  --limit <n> Max entries to return (default: 50)
84
74
 
85
75
  Auth:
86
- Requires SIWX from a wallet linked to the account (signed automatically from
76
+ Requires SIWX from a wallet linked to the organization (signed automatically from
87
77
  the local allowance), or an admin key. Email lookups require an admin key.
88
78
 
89
79
  Examples:
@@ -91,17 +81,17 @@ Examples:
91
81
  run402 billing history 0x1234... --limit 100
92
82
  run402 billing history 00000000-0000-4000-8000-000000000001
93
83
  `,
94
- balance: `run402 billing balance — Show balance for a billing account
84
+ balance: `run402 billing balance — Show balance for a organization
95
85
 
96
86
  Usage:
97
87
  run402 billing balance <identifier>
98
88
 
99
89
  Arguments:
100
- <identifier> Billing account id (UUID), wallet (0x...), or email.
101
- Wallet/email are resolved via the accounts lookup.
90
+ <identifier> Organization id (UUID), wallet (0x...), or email.
91
+ Wallet/email are resolved via the organization lookup.
102
92
 
103
93
  Auth:
104
- Requires SIWX from a wallet linked to the account (signed automatically from
94
+ Requires SIWX from a wallet linked to the organization (signed automatically from
105
95
  the local allowance), or an admin key. Email lookups require an admin key.
106
96
 
107
97
  Examples:
@@ -109,56 +99,111 @@ Examples:
109
99
  run402 billing balance 0x1234abcd...
110
100
  run402 billing balance 00000000-0000-4000-8000-000000000001
111
101
  `,
112
- "create-email": `run402 billing create-email — Create an email billing account
102
+ "create-email": `run402 billing create-email — Create an email organization
113
103
 
114
104
  Usage:
115
105
  run402 billing create-email <email>
116
106
 
117
107
  Arguments:
118
- <email> Email address to register as a billing account
108
+ <email> Email address to register as a organization
119
109
 
120
110
  Examples:
121
111
  run402 billing create-email user@example.com
122
112
  `,
123
- "link-wallet": `run402 billing link-wallet — Link a wallet to an email billing account
113
+ "link-wallet": `run402 billing link-wallet — Link a wallet to an email organization
124
114
 
125
115
  Usage:
126
- run402 billing link-wallet <account_id> <wallet>
116
+ run402 billing link-wallet <org_id> <wallet>
127
117
 
128
118
  Arguments:
129
- <account_id> Billing account ID (e.g. acct_abc123)
119
+ <org_id> Organization ID (e.g. org_abc123)
130
120
  <wallet> Wallet address (0x...) to link
131
121
 
132
122
  Notes:
133
- - Tier and quotas are per-billing-account. Linking a wallet merges its
134
- spend into the account-wide pool that already includes every project
135
- on this billing account.
123
+ - Tier and quotas are per-organization. Linking a wallet merges its
124
+ spend into the organization-wide pool that already includes every project
125
+ on this organization.
136
126
  - The response includes a 'pool_implications' block on v1.46+ gateways:
137
- tier, projects_in_pool_count, account_api_calls_current,
138
- account_storage_bytes_current, tier_limits, over_limit. Inspect
127
+ tier, projects_in_pool_count, organization_api_calls_current,
128
+ organization_storage_bytes_current, tier_limits, over_limit. Inspect
139
129
  'over_limit' before linking a wallet whose existing usage might push
140
130
  the merged pool past the tier cap.
141
131
 
142
132
  Examples:
143
- run402 billing link-wallet acct_abc123 0x1234abcd...
133
+ run402 billing link-wallet org_abc123 0x1234abcd...
144
134
  `,
145
135
  };
146
136
 
147
- function requireSingleBillingIdentifier(email, wallet) {
148
- if (email && wallet) {
137
+ function normalizeCheckoutProduct(raw) {
138
+ if (!raw) {
149
139
  fail({
150
140
  code: "BAD_USAGE",
151
- message: "Provide either --email or --wallet, not both.",
152
- hint: "[--email <e> | --wallet <w>]",
141
+ message: "Missing --product.",
142
+ hint: "Use --product tier, --product email-pack, or --product balance-topup.",
153
143
  });
154
144
  }
155
- if (!email && !wallet) {
145
+ const product = String(raw).replace(/-/g, "_");
146
+ if (product === "tier" || product === "email_pack" || product === "balance_topup") {
147
+ return product;
148
+ }
149
+ fail({
150
+ code: "BAD_USAGE",
151
+ message: `Unknown checkout product: ${raw}`,
152
+ hint: "Use tier, email-pack, or balance-topup.",
153
+ });
154
+ }
155
+
156
+ async function checkout(args) {
157
+ const parsedArgs = normalizeArgv(args);
158
+ const valueFlags = ["--product", "--tier", "--amount"];
159
+ assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
160
+ const positionals = positionalArgs(parsedArgs, valueFlags);
161
+ const identifier = positionals[0];
162
+ if (positionals.length > 1) {
163
+ fail({ code: "BAD_USAGE", message: `Unexpected argument for billing checkout: ${positionals[1]}` });
164
+ }
165
+ if (!identifier) {
156
166
  fail({
157
167
  code: "BAD_USAGE",
158
- message: "Must provide --email or --wallet",
159
- hint: "[--email <e> | --wallet <w>]",
168
+ message: "Missing <identifier>.",
169
+ hint: "run402 billing checkout <identifier> --product <tier|email-pack|balance-topup>",
160
170
  });
161
171
  }
172
+ const product = normalizeCheckoutProduct(flagValue(parsedArgs, "--product"));
173
+ let checkoutRequest;
174
+ if (product === "tier") {
175
+ const tier = flagValue(parsedArgs, "--tier");
176
+ if (!tier) {
177
+ fail({
178
+ code: "BAD_USAGE",
179
+ message: "Missing --tier for tier checkout.",
180
+ hint: "run402 billing checkout <identifier> --product tier --tier hobby",
181
+ });
182
+ }
183
+ checkoutRequest = { product: "tier", tier };
184
+ } else if (product === "email_pack") {
185
+ checkoutRequest = { product: "email_pack" };
186
+ } else {
187
+ const amountRaw = flagValue(parsedArgs, "--amount");
188
+ if (amountRaw === null) {
189
+ fail({
190
+ code: "BAD_USAGE",
191
+ message: "Missing --amount for balance-topup checkout.",
192
+ hint: "run402 billing checkout <identifier> --product balance-topup --amount 5000000",
193
+ });
194
+ }
195
+ checkoutRequest = {
196
+ product: "balance_topup",
197
+ amountUsdMicros: parseIntegerFlag("--amount", amountRaw, { min: 1 }),
198
+ };
199
+ }
200
+ try {
201
+ const org = await getSdk().billing.lookupOrganization(identifier);
202
+ const data = await getSdk().billing.createCheckout(org.organization_id, checkoutRequest);
203
+ console.log(JSON.stringify(data, null, 2));
204
+ } catch (err) {
205
+ reportSdkError(err);
206
+ }
162
207
  }
163
208
 
164
209
  async function createEmail(args) {
@@ -177,7 +222,7 @@ async function createEmail(args) {
177
222
  });
178
223
  }
179
224
  try {
180
- const data = await getSdk().billing.createEmailAccount(email);
225
+ const data = await getSdk().billing.createEmailOrganization(email);
181
226
  console.log(JSON.stringify(data, null, 2));
182
227
  } catch (err) {
183
228
  reportSdkError(err);
@@ -188,23 +233,23 @@ async function linkWallet(args) {
188
233
  const parsedArgs = normalizeArgv(args);
189
234
  assertKnownFlags(parsedArgs, ["--help", "-h"]);
190
235
  const positionals = positionalArgs(parsedArgs);
191
- const accountId = positionals[0];
236
+ const organizationId = positionals[0];
192
237
  const wallet = positionals[1];
193
238
  if (positionals.length > 2) {
194
239
  fail({ code: "BAD_USAGE", message: `Unexpected argument for billing link-wallet: ${positionals[2]}` });
195
240
  }
196
- if (!accountId || !wallet) {
241
+ if (!organizationId || !wallet) {
197
242
  fail({
198
243
  code: "BAD_USAGE",
199
- message: "Missing <account_id> and/or <wallet>.",
200
- hint: "run402 billing link-wallet <account_id> <wallet>",
244
+ message: "Missing <org_id> and/or <wallet>.",
245
+ hint: "run402 billing link-wallet <org_id> <wallet>",
201
246
  });
202
247
  }
203
248
  try {
204
- const data = await getSdk().billing.linkWallet(accountId, wallet);
249
+ const data = await getSdk().billing.linkWallet(organizationId, wallet);
205
250
  const output = {
206
251
  status: data?.status ?? "ok",
207
- billing_account_id: data?.billing_account_id ?? accountId,
252
+ organization_id: data?.organization_id ?? organizationId,
208
253
  wallet: data?.wallet ?? wallet.toLowerCase(),
209
254
  ...(data?.pool_implications ? { pool_implications: data.pool_implications } : {}),
210
255
  };
@@ -214,67 +259,21 @@ async function linkWallet(args) {
214
259
  }
215
260
  }
216
261
 
217
- async function tierCheckout(args) {
218
- const parsedArgs = normalizeArgv(args);
219
- const valueFlags = ["--email", "--wallet"];
220
- assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
221
- const positionals = positionalArgs(parsedArgs, valueFlags);
222
- const tier = positionals[0];
223
- if (positionals.length > 1) {
224
- fail({ code: "BAD_USAGE", message: `Unexpected argument for billing tier-checkout: ${positionals[1]}` });
225
- }
226
- if (!tier) {
227
- fail({
228
- code: "BAD_USAGE",
229
- message: "Missing <tier>.",
230
- hint: "run402 billing tier-checkout <tier> [--email <e> | --wallet <w>]",
231
- });
232
- }
233
- const email = flagValue(parsedArgs, "--email");
234
- const wallet = flagValue(parsedArgs, "--wallet");
235
- requireSingleBillingIdentifier(email, wallet);
236
- try {
237
- const data = await getSdk().billing.tierCheckout(tier, { email: email ?? undefined, wallet: wallet ?? undefined });
238
- console.log(JSON.stringify(data, null, 2));
239
- } catch (err) {
240
- reportSdkError(err);
241
- }
242
- }
243
-
244
- async function buyPack(args) {
245
- const parsedArgs = normalizeArgv(args);
246
- const valueFlags = ["--email", "--wallet"];
247
- assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
248
- const extra = positionalArgs(parsedArgs, valueFlags);
249
- if (extra.length > 0) {
250
- fail({ code: "BAD_USAGE", message: `Unexpected argument for billing buy-email-pack: ${extra[0]}` });
251
- }
252
- const email = flagValue(parsedArgs, "--email");
253
- const wallet = flagValue(parsedArgs, "--wallet");
254
- requireSingleBillingIdentifier(email, wallet);
255
- try {
256
- const data = await getSdk().billing.buyEmailPack({ email: email ?? undefined, wallet: wallet ?? undefined });
257
- console.log(JSON.stringify(data, null, 2));
258
- } catch (err) {
259
- reportSdkError(err);
260
- }
261
- }
262
-
263
262
  async function autoRecharge(args) {
264
263
  const parsedArgs = normalizeArgv(args);
265
264
  const valueFlags = ["--threshold"];
266
265
  assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
267
266
  const positionals = positionalArgs(parsedArgs, valueFlags);
268
- const accountId = positionals[0];
267
+ const organizationId = positionals[0];
269
268
  const state = positionals[1];
270
269
  if (positionals.length > 2) {
271
270
  fail({ code: "BAD_USAGE", message: `Unexpected argument for billing auto-recharge: ${positionals[2]}` });
272
271
  }
273
- if (!accountId || !state || !["on", "off"].includes(state)) {
272
+ if (!organizationId || !state || !["on", "off"].includes(state)) {
274
273
  fail({
275
274
  code: "BAD_USAGE",
276
- message: "Missing <account_id> and/or <on|off>.",
277
- hint: "run402 billing auto-recharge <account_id> <on|off> [--threshold <n>]",
275
+ message: "Missing <org_id> and/or <on|off>.",
276
+ hint: "run402 billing auto-recharge <org_id> <on|off> [--threshold <n>]",
278
277
  });
279
278
  }
280
279
  const thresholdStr = flagValue(parsedArgs, "--threshold");
@@ -283,11 +282,11 @@ async function autoRecharge(args) {
283
282
  : undefined;
284
283
  try {
285
284
  await getSdk().billing.setAutoRecharge({
286
- billingAccountId: accountId,
285
+ organizationId: organizationId,
287
286
  enabled: state === "on",
288
287
  threshold,
289
288
  });
290
- console.log(JSON.stringify({ billing_account_id: accountId, enabled: state === "on", updated: true }));
289
+ console.log(JSON.stringify({ organization_id: organizationId, enabled: state === "on", updated: true }));
291
290
  } catch (err) {
292
291
  reportSdkError(err);
293
292
  }
@@ -305,11 +304,11 @@ async function balance(args) {
305
304
  fail({
306
305
  code: "BAD_USAGE",
307
306
  message: "Missing <identifier>.",
308
- hint: "run402 billing balance <account-id | wallet | email>",
307
+ hint: "run402 billing balance <org-id | wallet | email>",
309
308
  });
310
309
  }
311
310
  try {
312
- const data = await getSdk().billing.getAccount(id);
311
+ const data = await getSdk().billing.getOrganization(id);
313
312
  console.log(JSON.stringify(data, null, 2));
314
313
  } catch (err) {
315
314
  reportSdkError(err);
@@ -329,7 +328,7 @@ async function history(args) {
329
328
  fail({
330
329
  code: "BAD_USAGE",
331
330
  message: "Missing <identifier>.",
332
- hint: "run402 billing history <account-id | wallet | email> [--limit <n>]",
331
+ hint: "run402 billing history <org-id | wallet | email> [--limit <n>]",
333
332
  });
334
333
  }
335
334
  const limit = parsedArgs.includes("--limit")
@@ -349,8 +348,7 @@ export async function run(sub, args) {
349
348
  switch (sub) {
350
349
  case "create-email": await createEmail(args); break;
351
350
  case "link-wallet": await linkWallet(args); break;
352
- case "tier-checkout": await tierCheckout(args); break;
353
- case "buy-email-pack": await buyPack(args); break;
351
+ case "checkout": await checkout(args); break;
354
352
  case "auto-recharge": await autoRecharge(args); break;
355
353
  case "balance": await balance(args); break;
356
354
  case "history": await history(args); break;
package/lib/operator.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  * The operator is YOU, the human, identified by email — distinct from the
5
5
  * AGENT (your wallet / SIWX identity). One browser login spans every wallet
6
6
  * that verified your email, so `operator overview` returns the cross-wallet
7
- * union. For a single wallet's account state, use `run402 status`.
7
+ * union. For a single wallet's organization state, use `run402 status`.
8
8
  *
9
9
  * Auth: browser-delegated device-authorization grant (RFC 8628, the
10
10
  * `aws sso login` model). The CLI never performs WebAuthn — the browser does,
@@ -47,7 +47,7 @@ const HELP = `run402 operator — operator (human / email) session
47
47
 
48
48
  The operator is YOU, the human, identified by email — distinct from the agent
49
49
  (your wallet). One browser login spans every wallet that verified your email.
50
- For a single wallet's account state, use 'run402 status'.
50
+ For a single wallet's organization state, use 'run402 status'.
51
51
 
52
52
  Usage:
53
53
  run402 operator login [--no-open] (read session, device-flow)
@@ -289,7 +289,7 @@ async function loopbackLogin(args, { stepUp }) {
289
289
  if (memberships.length) {
290
290
  process.stderr.write(
291
291
  `Member of ${memberships.length} org(s):\n` +
292
- memberships.map((m) => ` - ${m.billing_account_id} (${m.role}, ${m.status})`).join("\n") +
292
+ memberships.map((m) => ` - ${m.display_name || m.org_id || m.organization_id || "unknown"} (${m.role}, ${m.status})`).join("\n") +
293
293
  "\n",
294
294
  );
295
295
  }
package/lib/projects.mjs CHANGED
@@ -101,7 +101,7 @@ Usage:
101
101
  run402 projects list [--org <id>] [--all]
102
102
 
103
103
  Options:
104
- --org <id> Filter to projects owned by one org (billing account).
104
+ --org <id> Filter to projects owned by one org (organization).
105
105
  Authorize-before-reveal: a non-member or guessed id is a
106
106
  403; a non-UUID id is a 400.
107
107
  --all Read the cross-wallet inventory across every wallet
@@ -114,7 +114,7 @@ Notes:
114
114
  - This is a SERVER read (membership-scoped), not the local keystore. Each row
115
115
  has project_id, name, site_url, custom_domains, org_id, status, and an
116
116
  'active' marker derived from local state.
117
- - Tier and lifecycle live on the billing account, not each project — use
117
+ - Tier and lifecycle live on the organization, not each project — use
118
118
  'run402 status' or 'run402 tier status' for the account view.
119
119
 
120
120
  Examples:
@@ -478,7 +478,7 @@ async function list(args = []) {
478
478
  active: p.id === activeId,
479
479
  site_url: p.site_url ?? null,
480
480
  custom_domains: p.custom_domains ?? [],
481
- org_id: p.billing_account_id ?? null,
481
+ org_id: p.organization_id ?? null,
482
482
  status: p.status ?? p.effective_status ?? null,
483
483
  }));
484
484
  const out = { projects: rows };
@@ -724,7 +724,7 @@ export async function run(sub, args) {
724
724
  fail({
725
725
  code: "REMOVED_COMMAND",
726
726
  message: "`run402 projects pin` was removed in v1.57.",
727
- hint: "Per-project pin is superseded by the account-level escape hatch. Use `run402 admin lease-perpetual <billing_account_id> --enable` (platform-admin only).",
727
+ hint: "Per-project pin is superseded by the organization-level escape hatch. Use `run402 admin lease-perpetual <organization_id> --enable` (platform-admin only).",
728
728
  });
729
729
  }
730
730
  args = normalizeArgv(args);