run402 2.43.0 → 2.44.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.
- package/cli.mjs +1 -1
- package/lib/admin.mjs +22 -22
- package/lib/allowance.mjs +1 -1
- package/lib/billing.mjs +48 -48
- package/lib/operator.mjs +3 -3
- package/lib/projects.mjs +4 -4
- package/lib/sdk-errors.mjs +1 -1
- package/lib/service.mjs +1 -1
- package/lib/status.mjs +5 -5
- package/lib/tier.mjs +4 -4
- package/lib/transfer.mjs +5 -5
- package/package.json +1 -1
- package/sdk/dist/errors.d.ts +8 -8
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +6 -6
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +15 -16
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +14 -15
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +47 -53
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js +59 -59
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/operator.d.ts +3 -3
- package/sdk/dist/namespaces/operator.d.ts.map +1 -1
- package/sdk/dist/namespaces/operator.js +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +2 -2
- package/sdk/dist/namespaces/org.types.js +1 -1
- package/sdk/dist/namespaces/projects.d.ts +2 -2
- package/sdk/dist/namespaces/projects.js +2 -2
- package/sdk/dist/namespaces/projects.types.d.ts +15 -15
- package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/tier.d.ts +11 -11
- package/sdk/dist/namespaces/tier.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +8 -8
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +3 -3
- package/sdk/dist/namespaces/transfers.js.map +1 -1
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
|
|
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 <
|
|
12
|
-
Toggle the
|
|
13
|
-
When enabled, the
|
|
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
|
|
23
|
-
|
|
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
|
|
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
|
|
40
|
-
run402 admin lease-perpetual
|
|
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
|
|
46
|
+
"lease-perpetual": `run402 admin lease-perpetual — Toggle the organization-level escape hatch
|
|
47
47
|
|
|
48
48
|
Usage:
|
|
49
|
-
run402 admin lease-perpetual <
|
|
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
|
|
63
|
-
run402 admin lease-perpetual
|
|
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
|
|
75
|
-
only this project goes dark; siblings on the same
|
|
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
|
-
|
|
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 <
|
|
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
|
|
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 (!
|
|
116
|
+
if (!organizationId) {
|
|
117
117
|
fail({
|
|
118
118
|
code: "BAD_USAGE",
|
|
119
|
-
message: "Missing <
|
|
120
|
-
hint: "run402 admin lease-perpetual <
|
|
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 <
|
|
127
|
+
hint: "run402 admin lease-perpetual <organization_id> --enable | --disable",
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
try {
|
|
131
|
-
const data = await getSdk().admin.setLeasePerpetual(
|
|
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
|
@@ -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
|
|
241
|
+
run402: billingRes ? { balance_usd_micros: billingRes.available_usd_micros } : "no organization",
|
|
242
242
|
}, null, 2));
|
|
243
243
|
}
|
|
244
244
|
|
package/lib/billing.mjs
CHANGED
|
@@ -2,25 +2,25 @@ 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
|
|
5
|
+
const HELP = `run402 billing — Email organizations, Stripe tier checkout, email packs
|
|
6
6
|
|
|
7
7
|
Usage:
|
|
8
8
|
run402 billing <subcommand> [args...]
|
|
9
9
|
|
|
10
10
|
Subcommands:
|
|
11
|
-
create-email <email> Create an email
|
|
12
|
-
link-wallet <
|
|
11
|
+
create-email <email> Create an email organization
|
|
12
|
+
link-wallet <org_id> <wallet> Link a wallet to an email organization
|
|
13
13
|
tier-checkout <tier> [--email <e> | --wallet <w>] Stripe tier checkout
|
|
14
14
|
buy-email-pack [--email <e> | --wallet <w>] Buy \$5 email pack (10,000 emails)
|
|
15
|
-
auto-recharge <
|
|
16
|
-
balance <identifier> Balance by
|
|
17
|
-
history <identifier> [--limit <n>] Ledger history by
|
|
15
|
+
auto-recharge <org_id> <on|off> [--threshold <n>]
|
|
16
|
+
balance <identifier> Balance by organization id (UUID), wallet (0x...), or email
|
|
17
|
+
history <identifier> [--limit <n>] Ledger history by organization id (UUID), wallet, or email
|
|
18
18
|
|
|
19
19
|
Examples:
|
|
20
20
|
run402 billing create-email user@example.com
|
|
21
21
|
run402 billing tier-checkout hobby --email user@example.com
|
|
22
22
|
run402 billing buy-email-pack --wallet 0x1234...
|
|
23
|
-
run402 billing auto-recharge
|
|
23
|
+
run402 billing auto-recharge org_abc on --threshold 2000
|
|
24
24
|
run402 billing balance user@example.com
|
|
25
25
|
`;
|
|
26
26
|
|
|
@@ -34,7 +34,7 @@ Arguments:
|
|
|
34
34
|
<tier> Tier name (e.g. hobby, pro)
|
|
35
35
|
|
|
36
36
|
Options:
|
|
37
|
-
--email <e> Email
|
|
37
|
+
--email <e> Email organization to charge
|
|
38
38
|
--wallet <w> Wallet address (0x...) to associate with the checkout
|
|
39
39
|
|
|
40
40
|
Examples:
|
|
@@ -47,7 +47,7 @@ Usage:
|
|
|
47
47
|
run402 billing buy-email-pack [--email <e> | --wallet <w>]
|
|
48
48
|
|
|
49
49
|
Options:
|
|
50
|
-
--email <e> Email
|
|
50
|
+
--email <e> Email organization to charge
|
|
51
51
|
--wallet <w> Wallet address (0x...) to associate with the purchase
|
|
52
52
|
|
|
53
53
|
Examples:
|
|
@@ -57,33 +57,33 @@ Examples:
|
|
|
57
57
|
"auto-recharge": `run402 billing auto-recharge — Toggle email-pack auto-recharge
|
|
58
58
|
|
|
59
59
|
Usage:
|
|
60
|
-
run402 billing auto-recharge <
|
|
60
|
+
run402 billing auto-recharge <org_id> <on|off> [--threshold <n>]
|
|
61
61
|
|
|
62
62
|
Arguments:
|
|
63
|
-
<
|
|
63
|
+
<org_id> Organization ID
|
|
64
64
|
<on|off> Enable or disable auto-recharge
|
|
65
65
|
|
|
66
66
|
Options:
|
|
67
67
|
--threshold <n> Remaining-email threshold that triggers auto-recharge
|
|
68
68
|
|
|
69
69
|
Examples:
|
|
70
|
-
run402 billing auto-recharge
|
|
71
|
-
run402 billing auto-recharge
|
|
70
|
+
run402 billing auto-recharge org_abc on --threshold 2000
|
|
71
|
+
run402 billing auto-recharge org_abc off
|
|
72
72
|
`,
|
|
73
|
-
history: `run402 billing history — Show ledger history for a
|
|
73
|
+
history: `run402 billing history — Show ledger history for a organization
|
|
74
74
|
|
|
75
75
|
Usage:
|
|
76
76
|
run402 billing history <identifier> [--limit <n>]
|
|
77
77
|
|
|
78
78
|
Arguments:
|
|
79
|
-
<identifier>
|
|
80
|
-
Wallet/email are resolved to the
|
|
79
|
+
<identifier> Organization id (UUID), wallet (0x...), or email.
|
|
80
|
+
Wallet/email are resolved to the organization id first.
|
|
81
81
|
|
|
82
82
|
Options:
|
|
83
83
|
--limit <n> Max entries to return (default: 50)
|
|
84
84
|
|
|
85
85
|
Auth:
|
|
86
|
-
Requires SIWX from a wallet linked to the
|
|
86
|
+
Requires SIWX from a wallet linked to the organization (signed automatically from
|
|
87
87
|
the local allowance), or an admin key. Email lookups require an admin key.
|
|
88
88
|
|
|
89
89
|
Examples:
|
|
@@ -91,17 +91,17 @@ Examples:
|
|
|
91
91
|
run402 billing history 0x1234... --limit 100
|
|
92
92
|
run402 billing history 00000000-0000-4000-8000-000000000001
|
|
93
93
|
`,
|
|
94
|
-
balance: `run402 billing balance — Show balance for a
|
|
94
|
+
balance: `run402 billing balance — Show balance for a organization
|
|
95
95
|
|
|
96
96
|
Usage:
|
|
97
97
|
run402 billing balance <identifier>
|
|
98
98
|
|
|
99
99
|
Arguments:
|
|
100
|
-
<identifier>
|
|
101
|
-
Wallet/email are resolved via the
|
|
100
|
+
<identifier> Organization id (UUID), wallet (0x...), or email.
|
|
101
|
+
Wallet/email are resolved via the organization lookup.
|
|
102
102
|
|
|
103
103
|
Auth:
|
|
104
|
-
Requires SIWX from a wallet linked to the
|
|
104
|
+
Requires SIWX from a wallet linked to the organization (signed automatically from
|
|
105
105
|
the local allowance), or an admin key. Email lookups require an admin key.
|
|
106
106
|
|
|
107
107
|
Examples:
|
|
@@ -109,38 +109,38 @@ Examples:
|
|
|
109
109
|
run402 billing balance 0x1234abcd...
|
|
110
110
|
run402 billing balance 00000000-0000-4000-8000-000000000001
|
|
111
111
|
`,
|
|
112
|
-
"create-email": `run402 billing create-email — Create an email
|
|
112
|
+
"create-email": `run402 billing create-email — Create an email organization
|
|
113
113
|
|
|
114
114
|
Usage:
|
|
115
115
|
run402 billing create-email <email>
|
|
116
116
|
|
|
117
117
|
Arguments:
|
|
118
|
-
<email> Email address to register as a
|
|
118
|
+
<email> Email address to register as a organization
|
|
119
119
|
|
|
120
120
|
Examples:
|
|
121
121
|
run402 billing create-email user@example.com
|
|
122
122
|
`,
|
|
123
|
-
"link-wallet": `run402 billing link-wallet — Link a wallet to an email
|
|
123
|
+
"link-wallet": `run402 billing link-wallet — Link a wallet to an email organization
|
|
124
124
|
|
|
125
125
|
Usage:
|
|
126
|
-
run402 billing link-wallet <
|
|
126
|
+
run402 billing link-wallet <org_id> <wallet>
|
|
127
127
|
|
|
128
128
|
Arguments:
|
|
129
|
-
<
|
|
129
|
+
<org_id> Organization ID (e.g. org_abc123)
|
|
130
130
|
<wallet> Wallet address (0x...) to link
|
|
131
131
|
|
|
132
132
|
Notes:
|
|
133
|
-
- Tier and quotas are per-
|
|
134
|
-
spend into the
|
|
135
|
-
on this
|
|
133
|
+
- Tier and quotas are per-organization. Linking a wallet merges its
|
|
134
|
+
spend into the organization-wide pool that already includes every project
|
|
135
|
+
on this organization.
|
|
136
136
|
- The response includes a 'pool_implications' block on v1.46+ gateways:
|
|
137
|
-
tier, projects_in_pool_count,
|
|
138
|
-
|
|
137
|
+
tier, projects_in_pool_count, organization_api_calls_current,
|
|
138
|
+
organization_storage_bytes_current, tier_limits, over_limit. Inspect
|
|
139
139
|
'over_limit' before linking a wallet whose existing usage might push
|
|
140
140
|
the merged pool past the tier cap.
|
|
141
141
|
|
|
142
142
|
Examples:
|
|
143
|
-
run402 billing link-wallet
|
|
143
|
+
run402 billing link-wallet org_abc123 0x1234abcd...
|
|
144
144
|
`,
|
|
145
145
|
};
|
|
146
146
|
|
|
@@ -177,7 +177,7 @@ async function createEmail(args) {
|
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
try {
|
|
180
|
-
const data = await getSdk().billing.
|
|
180
|
+
const data = await getSdk().billing.createEmailOrganization(email);
|
|
181
181
|
console.log(JSON.stringify(data, null, 2));
|
|
182
182
|
} catch (err) {
|
|
183
183
|
reportSdkError(err);
|
|
@@ -188,23 +188,23 @@ async function linkWallet(args) {
|
|
|
188
188
|
const parsedArgs = normalizeArgv(args);
|
|
189
189
|
assertKnownFlags(parsedArgs, ["--help", "-h"]);
|
|
190
190
|
const positionals = positionalArgs(parsedArgs);
|
|
191
|
-
const
|
|
191
|
+
const organizationId = positionals[0];
|
|
192
192
|
const wallet = positionals[1];
|
|
193
193
|
if (positionals.length > 2) {
|
|
194
194
|
fail({ code: "BAD_USAGE", message: `Unexpected argument for billing link-wallet: ${positionals[2]}` });
|
|
195
195
|
}
|
|
196
|
-
if (!
|
|
196
|
+
if (!organizationId || !wallet) {
|
|
197
197
|
fail({
|
|
198
198
|
code: "BAD_USAGE",
|
|
199
|
-
message: "Missing <
|
|
200
|
-
hint: "run402 billing link-wallet <
|
|
199
|
+
message: "Missing <org_id> and/or <wallet>.",
|
|
200
|
+
hint: "run402 billing link-wallet <org_id> <wallet>",
|
|
201
201
|
});
|
|
202
202
|
}
|
|
203
203
|
try {
|
|
204
|
-
const data = await getSdk().billing.linkWallet(
|
|
204
|
+
const data = await getSdk().billing.linkWallet(organizationId, wallet);
|
|
205
205
|
const output = {
|
|
206
206
|
status: data?.status ?? "ok",
|
|
207
|
-
|
|
207
|
+
organization_id: data?.organization_id ?? organizationId,
|
|
208
208
|
wallet: data?.wallet ?? wallet.toLowerCase(),
|
|
209
209
|
...(data?.pool_implications ? { pool_implications: data.pool_implications } : {}),
|
|
210
210
|
};
|
|
@@ -265,16 +265,16 @@ async function autoRecharge(args) {
|
|
|
265
265
|
const valueFlags = ["--threshold"];
|
|
266
266
|
assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
|
|
267
267
|
const positionals = positionalArgs(parsedArgs, valueFlags);
|
|
268
|
-
const
|
|
268
|
+
const organizationId = positionals[0];
|
|
269
269
|
const state = positionals[1];
|
|
270
270
|
if (positionals.length > 2) {
|
|
271
271
|
fail({ code: "BAD_USAGE", message: `Unexpected argument for billing auto-recharge: ${positionals[2]}` });
|
|
272
272
|
}
|
|
273
|
-
if (!
|
|
273
|
+
if (!organizationId || !state || !["on", "off"].includes(state)) {
|
|
274
274
|
fail({
|
|
275
275
|
code: "BAD_USAGE",
|
|
276
|
-
message: "Missing <
|
|
277
|
-
hint: "run402 billing auto-recharge <
|
|
276
|
+
message: "Missing <org_id> and/or <on|off>.",
|
|
277
|
+
hint: "run402 billing auto-recharge <org_id> <on|off> [--threshold <n>]",
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
const thresholdStr = flagValue(parsedArgs, "--threshold");
|
|
@@ -283,11 +283,11 @@ async function autoRecharge(args) {
|
|
|
283
283
|
: undefined;
|
|
284
284
|
try {
|
|
285
285
|
await getSdk().billing.setAutoRecharge({
|
|
286
|
-
|
|
286
|
+
organizationId: organizationId,
|
|
287
287
|
enabled: state === "on",
|
|
288
288
|
threshold,
|
|
289
289
|
});
|
|
290
|
-
console.log(JSON.stringify({
|
|
290
|
+
console.log(JSON.stringify({ organization_id: organizationId, enabled: state === "on", updated: true }));
|
|
291
291
|
} catch (err) {
|
|
292
292
|
reportSdkError(err);
|
|
293
293
|
}
|
|
@@ -305,11 +305,11 @@ async function balance(args) {
|
|
|
305
305
|
fail({
|
|
306
306
|
code: "BAD_USAGE",
|
|
307
307
|
message: "Missing <identifier>.",
|
|
308
|
-
hint: "run402 billing balance <
|
|
308
|
+
hint: "run402 billing balance <org-id | wallet | email>",
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
311
|
try {
|
|
312
|
-
const data = await getSdk().billing.
|
|
312
|
+
const data = await getSdk().billing.getOrganization(id);
|
|
313
313
|
console.log(JSON.stringify(data, null, 2));
|
|
314
314
|
} catch (err) {
|
|
315
315
|
reportSdkError(err);
|
|
@@ -329,7 +329,7 @@ async function history(args) {
|
|
|
329
329
|
fail({
|
|
330
330
|
code: "BAD_USAGE",
|
|
331
331
|
message: "Missing <identifier>.",
|
|
332
|
-
hint: "run402 billing history <
|
|
332
|
+
hint: "run402 billing history <org-id | wallet | email> [--limit <n>]",
|
|
333
333
|
});
|
|
334
334
|
}
|
|
335
335
|
const limit = parsedArgs.includes("--limit")
|
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
|
|
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
|
|
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.
|
|
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 (
|
|
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
|
|
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.
|
|
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
|
|
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);
|
package/lib/sdk-errors.mjs
CHANGED
|
@@ -111,7 +111,7 @@ export function reportSdkError(err) {
|
|
|
111
111
|
if (d?.required_capability) need.push(`capability \`${d.required_capability}\``);
|
|
112
112
|
const needStr = need.length > 0 ? ` (needs ${need.join(" or ")})` : "";
|
|
113
113
|
payload.hint =
|
|
114
|
-
`Authorization denied${needStr}: a wallet authenticates, but the owning org (
|
|
114
|
+
`Authorization denied${needStr}: a wallet authenticates, but the owning org (organization) ` +
|
|
115
115
|
"decides access via membership role (owner > admin > developer > billing > viewer) or a per-project grant. " +
|
|
116
116
|
"High-stakes actions (delete, transfer, membership change) require an active `owner` membership. " +
|
|
117
117
|
"Returned as 403 even when the project does not exist, so verify the project id too.";
|
package/lib/service.mjs
CHANGED
|
@@ -22,7 +22,7 @@ Usage:
|
|
|
22
22
|
Notes:
|
|
23
23
|
- Unauthenticated and free; no allowance required
|
|
24
24
|
- Returns uptime, supported capabilities, operator, and deployment info
|
|
25
|
-
- For
|
|
25
|
+
- For organization state (allowance, balance, tier, projects), use
|
|
26
26
|
'run402 status' instead
|
|
27
27
|
|
|
28
28
|
Examples:
|
package/lib/status.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { assertKnownFlags, hasHelp, normalizeArgv } from "./argparse.mjs";
|
|
|
4
4
|
import { getActiveProfile } from "../core-dist/config.js";
|
|
5
5
|
import { readMeta } from "../core-dist/profiles.js";
|
|
6
6
|
|
|
7
|
-
const HELP = `run402 status — Show full
|
|
7
|
+
const HELP = `run402 status — Show full organization state in one shot
|
|
8
8
|
|
|
9
9
|
Usage:
|
|
10
10
|
run402 status
|
|
@@ -120,7 +120,7 @@ export async function run(args = []) {
|
|
|
120
120
|
// - on_chain_usd_micros / on_chain_token: on-chain USDC (x402) or pathUSD
|
|
121
121
|
// (mpp), null if the RPC read failed
|
|
122
122
|
// - prepaid_credit_usd_micros / held_usd_micros: Run402-held credits,
|
|
123
|
-
// rail-independent, null when no
|
|
123
|
+
// rail-independent, null when no organization exists
|
|
124
124
|
const hasBilling = billing && billing.exists !== false;
|
|
125
125
|
const result = {
|
|
126
126
|
wallet: {
|
|
@@ -138,10 +138,10 @@ export async function run(args = []) {
|
|
|
138
138
|
tier: tier && tier.tier
|
|
139
139
|
? { name: tier.tier, status: tier.status, expires: tier.lease_expires_at }
|
|
140
140
|
: null,
|
|
141
|
-
// v1.57: lifecycle state and the per-
|
|
142
|
-
//
|
|
141
|
+
// v1.57: lifecycle state and the per-organization escape hatch moved to the
|
|
142
|
+
// organization. Surface them at the top level so agents don't have to
|
|
143
143
|
// dig into the projects array to read them.
|
|
144
|
-
|
|
144
|
+
organization_lifecycle_state: tier?.organization_lifecycle_state ?? null,
|
|
145
145
|
lease_perpetual: tier?.lease_perpetual ?? null,
|
|
146
146
|
projects,
|
|
147
147
|
active_project: activeId || null,
|
package/lib/tier.mjs
CHANGED
|
@@ -13,7 +13,7 @@ Subcommands:
|
|
|
13
13
|
|
|
14
14
|
Tiers: prototype ($0.10/7d, free with testnet faucet), hobby ($5/30d), team ($20/30d)
|
|
15
15
|
|
|
16
|
-
Tier is per
|
|
16
|
+
Tier is per organization. A single subscription covers every project on
|
|
17
17
|
the account; api_calls and storage_bytes are pooled across all of them.
|
|
18
18
|
|
|
19
19
|
The server auto-detects the action based on your allowance state:
|
|
@@ -35,7 +35,7 @@ Usage:
|
|
|
35
35
|
run402 tier status
|
|
36
36
|
|
|
37
37
|
Notes:
|
|
38
|
-
- Tier and quotas are per
|
|
38
|
+
- Tier and quotas are per organization. The 'pool_usage' block sums
|
|
39
39
|
api_calls and storage_bytes across every project on this account
|
|
40
40
|
(across every wallet linked to it), not just the requesting wallet.
|
|
41
41
|
- Returns the current tier name, status, expiry, and pool usage
|
|
@@ -61,7 +61,7 @@ Tiers:
|
|
|
61
61
|
team $20/30d
|
|
62
62
|
|
|
63
63
|
Notes:
|
|
64
|
-
Tier is per
|
|
64
|
+
Tier is per organization, not per project. A successful subscribe,
|
|
65
65
|
renew, or upgrade applies immediately to every project on the account.
|
|
66
66
|
|
|
67
67
|
Server auto-detects action based on current allowance state:
|
|
@@ -72,7 +72,7 @@ Notes:
|
|
|
72
72
|
Pays via x402 micropayments.
|
|
73
73
|
|
|
74
74
|
After the call, the CLI refetches /tiers/v1/status and includes the
|
|
75
|
-
refreshed
|
|
75
|
+
refreshed organization-pooled usage as 'status_after' in the JSON output.
|
|
76
76
|
|
|
77
77
|
Examples:
|
|
78
78
|
run402 tier set prototype
|
package/lib/transfer.mjs
CHANGED
|
@@ -17,7 +17,7 @@ Usage:
|
|
|
17
17
|
run402 transfer preview <transfer_id>
|
|
18
18
|
run402 transfer list [--incoming | --outgoing] [--limit N] [--offset N]
|
|
19
19
|
run402 transfer accept <transfer_id>
|
|
20
|
-
run402 transfer claim <transfer_id> [--into <
|
|
20
|
+
run402 transfer claim <transfer_id> [--into <organization_id>]
|
|
21
21
|
run402 transfer cancel <transfer_id> [--reason <text>] [--handoff]
|
|
22
22
|
|
|
23
23
|
Subcommands:
|
|
@@ -53,7 +53,7 @@ Options:
|
|
|
53
53
|
Notes:
|
|
54
54
|
- Caller's wallet must currently own the project (gateway re-checks fresh DB).
|
|
55
55
|
- Owner-side mutations on the project are frozen until accept/cancel/expiry.
|
|
56
|
-
- The project lease stays with your
|
|
56
|
+
- The project lease stays with your organization; it is NOT refunded.
|
|
57
57
|
`,
|
|
58
58
|
preview: `run402 transfer preview — Fetch the preview document
|
|
59
59
|
|
|
@@ -97,7 +97,7 @@ email->org handoff instead of a wallet transfer.
|
|
|
97
97
|
claim: `run402 transfer claim — Claim an incoming email handoff
|
|
98
98
|
|
|
99
99
|
Usage:
|
|
100
|
-
run402 transfer claim <transfer_id> [--into <
|
|
100
|
+
run402 transfer claim <transfer_id> [--into <organization_id>]
|
|
101
101
|
|
|
102
102
|
Claims a handoff addressed to your email into an org you own. Omit --into to
|
|
103
103
|
claim into a brand-new org. This is the email-handoff analog of 'accept'.
|
|
@@ -281,7 +281,7 @@ async function claim(args) {
|
|
|
281
281
|
assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
|
|
282
282
|
const positionals = positionalArgs(parsedArgs, valueFlags);
|
|
283
283
|
if (positionals.length !== 1) {
|
|
284
|
-
fail({ code: "BAD_USAGE", message: "Usage: run402 transfer claim <transfer_id> [--into <
|
|
284
|
+
fail({ code: "BAD_USAGE", message: "Usage: run402 transfer claim <transfer_id> [--into <organization_id>]" });
|
|
285
285
|
}
|
|
286
286
|
const transferId = positionals[0];
|
|
287
287
|
const into = flagValue(parsedArgs, "--into");
|
|
@@ -289,7 +289,7 @@ async function claim(args) {
|
|
|
289
289
|
|
|
290
290
|
try {
|
|
291
291
|
const data = await getSdk().admin.transfers.claimHandoff(transferId, {
|
|
292
|
-
|
|
292
|
+
organizationId: into ?? undefined,
|
|
293
293
|
});
|
|
294
294
|
console.log(JSON.stringify(data, null, 2));
|
|
295
295
|
} catch (err) {
|
package/package.json
CHANGED
package/sdk/dist/errors.d.ts
CHANGED
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
export type Run402ErrorKind = "payment_required" | "project_not_found" | "unauthorized" | "not_authorized" | "api_error" | "network_error" | "local_error" | "deploy_error" | "transfer_freeze" | "step_up_required";
|
|
19
19
|
/**
|
|
20
20
|
* Quota-denial scope discriminator (v1.46+). Indicates whether a quota-related
|
|
21
|
-
* denial was enforced against the pooled
|
|
22
|
-
* or against an orphan project whose
|
|
21
|
+
* denial was enforced against the pooled organization total (`"organization"`)
|
|
22
|
+
* or against an orphan project whose organization row has been purged but
|
|
23
23
|
* cascade has not yet run (`"project"`). Lifted from `details.scope` on the
|
|
24
24
|
* gateway envelope; absent for errors unrelated to quota.
|
|
25
25
|
*/
|
|
26
|
-
export type Run402QuotaScope = "
|
|
26
|
+
export type Run402QuotaScope = "organization" | "project";
|
|
27
27
|
export declare abstract class Run402Error extends Error {
|
|
28
28
|
/**
|
|
29
29
|
* Structural brand. Always `true` on any {@link Run402Error} subclass
|
|
@@ -61,9 +61,9 @@ export declare abstract class Run402Error extends Error {
|
|
|
61
61
|
/** Advisory next actions from the gateway. Rendering them must not execute them. */
|
|
62
62
|
readonly nextActions?: unknown[];
|
|
63
63
|
/**
|
|
64
|
-
* Quota-denial scope (v1.46+). `"
|
|
65
|
-
* denials; `"project"` for the orphan fallback (project whose
|
|
66
|
-
*
|
|
64
|
+
* Quota-denial scope (v1.46+). `"organization"` for pooled organization
|
|
65
|
+
* denials; `"project"` for the orphan fallback (project whose organization
|
|
66
|
+
* row was purged but cascade has not yet run). Lifted from
|
|
67
67
|
* `details.scope` when the gateway returned it. Undefined for errors
|
|
68
68
|
* that are not quota-related.
|
|
69
69
|
*/
|
|
@@ -104,7 +104,7 @@ export declare class Unauthorized extends Run402Error {
|
|
|
104
104
|
/**
|
|
105
105
|
* HTTP 403 `NOT_AUTHORIZED` — the org-owned control plane (gateway v1.77+)
|
|
106
106
|
* denied a control-plane action. A wallet *authenticates* (SIWX resolves it to
|
|
107
|
-
* a principal); *authorization* is an org (
|
|
107
|
+
* a principal); *authorization* is an org (organization) membership in the
|
|
108
108
|
* role lattice `owner > admin > developer > billing > viewer`, or a per-project
|
|
109
109
|
* grant for agent/CI principals — never `wallet_address == signer`. High-stakes
|
|
110
110
|
* ops (delete, transfer-of-ownership, membership change) require an active
|
|
@@ -303,7 +303,7 @@ export declare function isTransferFreezeError(e: unknown): e is TransferFreezeEr
|
|
|
303
303
|
/** True if `e` is a {@link StepUpRequiredError}. Survives duplicate SDK copies and realms. */
|
|
304
304
|
export declare function isStepUpRequired(e: unknown): e is StepUpRequiredError;
|
|
305
305
|
/**
|
|
306
|
-
* Extract the v1.46+ quota-denial scope from an error. Returns `"
|
|
306
|
+
* Extract the v1.46+ quota-denial scope from an error. Returns `"organization"`
|
|
307
307
|
* for pooled denials, `"project"` for the orphan fallback, or `undefined`
|
|
308
308
|
* when the error is not quota-related (or originated from a pre-v1.46
|
|
309
309
|
* gateway that did not set `details.scope`). Safe to call with `unknown`.
|