run402 4.93.2 → 4.95.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/README.md +61 -59
- package/cli.mjs +40 -47
- package/core-dist/config.js +52 -18
- package/core-dist/control-plane-session.js +31 -6
- package/core-dist/keystore.js +7 -7
- package/core-dist/profiles.js +9 -7
- package/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{sdk/core-dist/allowance.js → core-dist/wallet.js} +20 -20
- package/{sdk/core-dist/write-auth-session.js → core-dist/write-approvals.js} +19 -19
- package/gitvault-surface.json +2 -2
- package/lib/admin.mjs +6 -6
- package/lib/agent.mjs +20 -18
- package/lib/ai.mjs +5 -5
- package/lib/approve.mjs +81 -0
- package/lib/apps.mjs +12 -12
- package/lib/archives.mjs +371 -8
- package/lib/argparse.mjs +5 -5
- package/lib/assets.mjs +14 -14
- package/lib/auth.mjs +34 -34
- package/lib/billing.mjs +6 -6
- package/lib/branches.mjs +7 -7
- package/lib/buzz-doctor.mjs +2 -2
- package/lib/buzz-notifications.mjs +5 -5
- package/lib/buzz.mjs +3 -3
- package/lib/buzz.test.mjs +1 -1
- package/lib/cache.mjs +1 -1
- package/lib/cdn.mjs +2 -2
- package/lib/ci.mjs +12 -12
- package/lib/claims.mjs +2 -2
- package/lib/cold-start.mjs +21 -21
- package/lib/command-manifest.mjs +55 -70
- package/lib/config.mjs +28 -28
- package/lib/contacts.mjs +16 -16
- package/lib/contracts.mjs +12 -12
- package/lib/credentials.mjs +33 -33
- package/lib/daemon-path.mjs +1 -1
- package/lib/delegates.mjs +14 -14
- package/lib/deliveries.mjs +6 -6
- package/lib/deploy-rehearse-discovery.test.mjs +7 -7
- package/lib/deploy-v2.mjs +241 -193
- package/lib/deploy.mjs +21 -53
- package/lib/dev.mjs +3 -3
- package/lib/doctor-source-scan.mjs +1 -1
- package/lib/doctor.mjs +63 -63
- package/lib/domains.mjs +27 -27
- package/lib/email.mjs +38 -38
- package/lib/errors.mjs +40 -24
- package/lib/escalations.mjs +5 -5
- package/lib/events.mjs +32 -25
- package/lib/feedback.mjs +12 -12
- package/lib/functions.mjs +34 -34
- package/lib/gitvault-daemon.mjs +1 -1
- package/lib/gitvault-scaffold.mjs +2 -2
- package/lib/gitvault.mjs +2 -2
- package/lib/grants.mjs +7 -7
- package/lib/image.mjs +10 -10
- package/lib/init.mjs +69 -69
- package/lib/jobs.mjs +15 -15
- package/lib/lightning-wallet.mjs +28 -28
- package/lib/live.mjs +1 -1
- package/lib/login.mjs +207 -0
- package/lib/logout.mjs +53 -0
- package/lib/logs.mjs +8 -8
- package/lib/messages.mjs +5 -5
- package/lib/next-actions.mjs +16 -16
- package/lib/org-context.mjs +13 -13
- package/lib/{org.mjs → orgs.mjs} +215 -167
- package/lib/pay.mjs +1 -1
- package/lib/projects.mjs +70 -84
- package/lib/redeem.mjs +7 -8
- package/lib/remote-helper-session.mjs +12 -12
- package/lib/repos.mjs +83 -83
- package/lib/rooms.mjs +105 -69
- package/lib/sdk-errors.mjs +10 -5
- package/lib/sdk.mjs +3 -3
- package/lib/secrets.mjs +13 -13
- package/lib/service.mjs +5 -5
- package/lib/session-proofs.mjs +21 -0
- package/lib/sign-in.mjs +296 -0
- package/lib/sites.mjs +22 -22
- package/lib/snapshots.mjs +10 -10
- package/lib/stats.mjs +2 -2
- package/lib/status.mjs +25 -25
- package/lib/subdomains.mjs +30 -30
- package/lib/subscriptions.mjs +10 -10
- package/lib/tier.mjs +29 -22
- package/lib/transfer.mjs +59 -86
- package/lib/up.mjs +14 -14
- package/lib/wallet-context.mjs +4 -4
- package/lib/wallet-context.test.mjs +3 -3
- package/lib/wallets.mjs +197 -32
- package/lib/webhook-secret.mjs +6 -6
- package/lib/webhooks.mjs +8 -8
- package/lib/whoami.mjs +102 -0
- package/package.json +1 -1
- package/sdk/core-dist/config.js +52 -18
- package/sdk/core-dist/control-plane-session.js +31 -6
- package/sdk/core-dist/keystore.js +7 -7
- package/sdk/core-dist/profiles.js +9 -7
- package/sdk/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{core-dist/allowance.js → sdk/core-dist/wallet.js} +20 -20
- package/{core-dist/write-auth-session.js → sdk/core-dist/write-approvals.js} +19 -19
- package/sdk/dist/actions.d.ts +4 -4
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/app-up.d.ts +2 -2
- package/sdk/dist/app-up.d.ts.map +1 -1
- package/sdk/dist/config.d.ts +1 -2
- package/sdk/dist/config.d.ts.map +1 -1
- package/sdk/dist/config.js.map +1 -1
- package/sdk/dist/control-plane-credentials.d.ts +8 -8
- package/sdk/dist/control-plane-credentials.js +7 -7
- package/sdk/dist/credentials.d.ts +20 -20
- package/sdk/dist/credentials.d.ts.map +1 -1
- package/sdk/dist/credentials.js +1 -1
- package/sdk/dist/errors.d.ts +26 -28
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +35 -38
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/index.d.ts +29 -16
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +30 -17
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/kernel.d.ts +1 -1
- package/sdk/dist/kernel.d.ts.map +1 -1
- package/sdk/dist/kernel.js +10 -9
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +52 -121
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +41 -45
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/agent.d.ts +2 -2
- package/sdk/dist/namespaces/agent.d.ts.map +1 -1
- package/sdk/dist/namespaces/agent.js +2 -2
- package/sdk/dist/namespaces/agent.js.map +1 -1
- package/sdk/dist/namespaces/ai.d.ts +2 -2
- package/sdk/dist/namespaces/ai.js +3 -3
- package/sdk/dist/namespaces/ai.js.map +1 -1
- package/sdk/dist/namespaces/assets.js +1 -1
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +6 -3
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/buzz-notifications.types.d.ts +1 -1
- package/sdk/dist/namespaces/buzz.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.d.ts.map +1 -1
- package/sdk/dist/namespaces/buzz.js +2 -2
- package/sdk/dist/namespaces/buzz.js.map +1 -1
- package/sdk/dist/namespaces/buzz.types.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +3 -3
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/credentials.types.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +31 -32
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +6 -6
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +10 -2
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +10 -5
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/errors.js +1 -1
- package/sdk/dist/namespaces/escalations.d.ts +1 -1
- package/sdk/dist/namespaces/escalations.js +1 -1
- package/sdk/dist/namespaces/escalations.types.d.ts +2 -2
- package/sdk/dist/namespaces/escalations.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/events.types.d.ts +1 -1
- package/sdk/dist/namespaces/functions.d.ts +1 -1
- package/sdk/dist/namespaces/functions.js +2 -2
- package/sdk/dist/namespaces/functions.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +26 -26
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +113 -113
- package/sdk/dist/namespaces/gitvault.js.map +1 -1
- package/sdk/dist/namespaces/me.d.ts +120 -0
- package/sdk/dist/namespaces/me.d.ts.map +1 -0
- package/sdk/dist/namespaces/me.js +34 -0
- package/sdk/dist/namespaces/me.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +108 -6
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +63 -7
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +29 -9
- package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js +3 -3
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +9 -9
- package/sdk/dist/namespaces/projects.js +15 -15
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/projects.types.d.ts +28 -12
- package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/rooms.d.ts +7 -7
- package/sdk/dist/namespaces/rooms.js +17 -17
- package/sdk/dist/namespaces/rooms.js.map +1 -1
- package/sdk/dist/namespaces/rooms.types.d.ts +9 -9
- package/sdk/dist/namespaces/rooms.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/service.d.ts +1 -1
- package/sdk/dist/namespaces/service.js +1 -1
- package/sdk/dist/namespaces/{operator-session.d.ts → session.d.ts} +135 -51
- package/sdk/dist/namespaces/session.d.ts.map +1 -0
- package/sdk/dist/namespaces/{operator-session.js → session.js} +118 -30
- package/sdk/dist/namespaces/session.js.map +1 -0
- package/sdk/dist/namespaces/subdomains.d.ts +5 -5
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +6 -6
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/tier.d.ts +44 -21
- package/sdk/dist/namespaces/tier.d.ts.map +1 -1
- package/sdk/dist/namespaces/tier.js +7 -7
- package/sdk/dist/namespaces/tier.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +119 -85
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +31 -38
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/vouchers.d.ts +9 -10
- package/sdk/dist/namespaces/vouchers.d.ts.map +1 -1
- package/sdk/dist/namespaces/vouchers.js +4 -5
- package/sdk/dist/namespaces/vouchers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +72 -3
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +141 -3
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/namespaces/write-approval.d.ts +101 -0
- package/sdk/dist/namespaces/write-approval.d.ts.map +1 -0
- package/sdk/dist/namespaces/write-approval.js +62 -0
- package/sdk/dist/namespaces/write-approval.js.map +1 -0
- package/sdk/dist/node/actions-node.d.ts +3 -3
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +44 -44
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/assets-node.js +6 -6
- package/sdk/dist/node/assets-node.js.map +1 -1
- package/sdk/dist/node/{bearer-claim-key.d.ts → bearer-redeem-key.d.ts} +12 -12
- package/sdk/dist/node/bearer-redeem-key.d.ts.map +1 -0
- package/sdk/dist/node/{bearer-claim-key.js → bearer-redeem-key.js} +21 -21
- package/sdk/dist/node/bearer-redeem-key.js.map +1 -0
- package/sdk/dist/node/ci.d.ts +1 -1
- package/sdk/dist/node/ci.d.ts.map +1 -1
- package/sdk/dist/node/ci.js +6 -6
- package/sdk/dist/node/ci.js.map +1 -1
- package/sdk/dist/node/credentials.d.ts +18 -17
- package/sdk/dist/node/credentials.d.ts.map +1 -1
- package/sdk/dist/node/credentials.js +29 -28
- package/sdk/dist/node/credentials.js.map +1 -1
- package/sdk/dist/node/deploy-manifest.d.ts +3 -5
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +3 -12
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/funding-recovery.d.ts +1 -1
- package/sdk/dist/node/funding-recovery.d.ts.map +1 -1
- package/sdk/dist/node/funding-recovery.js +1 -1
- package/sdk/dist/node/funding-recovery.js.map +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-apply.js +1 -1
- package/sdk/dist/node/gitvault-apply.js.map +1 -1
- package/sdk/dist/node/gitvault-handoff.d.ts +22 -22
- package/sdk/dist/node/gitvault-handoff.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-handoff.js +45 -45
- package/sdk/dist/node/gitvault-handoff.js.map +1 -1
- package/sdk/dist/node/gitvault-prewarm.js +7 -7
- package/sdk/dist/node/gitvault-prewarm.js.map +1 -1
- package/sdk/dist/node/gitvault-restore.d.ts +1 -1
- package/sdk/dist/node/gitvault-restore.js +1 -1
- package/sdk/dist/node/index.d.ts +16 -16
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +15 -15
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/manifest-export.js +2 -2
- package/sdk/dist/node/manifest-export.js.map +1 -1
- package/sdk/dist/node/org-adopt.d.ts +49 -0
- package/sdk/dist/node/org-adopt.d.ts.map +1 -0
- package/sdk/dist/node/org-adopt.js +77 -0
- package/sdk/dist/node/org-adopt.js.map +1 -0
- package/sdk/dist/node/paid-fetch.d.ts +7 -7
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +54 -54
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/preflight.d.ts +1 -1
- package/sdk/dist/node/preflight.d.ts.map +1 -1
- package/sdk/dist/node/preflight.js +1 -1
- package/sdk/dist/node/preflight.js.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -1
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/node/source-scan.d.ts +1 -1
- package/sdk/dist/node/source-scan.js +2 -2
- package/sdk/dist/node/source-scan.js.map +1 -1
- package/sdk/dist/scoped.d.ts +11 -11
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +5 -5
- package/sdk/dist/scoped.js.map +1 -1
- package/core-dist/operator-session.js +0 -154
- package/lib/allowance.mjs +0 -355
- package/lib/cloud.mjs +0 -256
- package/lib/core.mjs +0 -123
- package/lib/operator-proofs.mjs +0 -22
- package/lib/operator.mjs +0 -771
- package/sdk/core-dist/operator-session.js +0 -154
- package/sdk/dist/namespaces/allowance.d.ts +0 -79
- package/sdk/dist/namespaces/allowance.d.ts.map +0 -1
- package/sdk/dist/namespaces/allowance.js +0 -149
- package/sdk/dist/namespaces/allowance.js.map +0 -1
- package/sdk/dist/namespaces/operator-session.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator-session.js.map +0 -1
- package/sdk/dist/namespaces/operator.d.ts +0 -359
- package/sdk/dist/namespaces/operator.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator.js +0 -272
- package/sdk/dist/namespaces/operator.js.map +0 -1
- package/sdk/dist/node/bearer-claim-key.d.ts.map +0 -1
- package/sdk/dist/node/bearer-claim-key.js.map +0 -1
- package/sdk/dist/node/operator-claim.d.ts +0 -49
- package/sdk/dist/node/operator-claim.d.ts.map +0 -1
- package/sdk/dist/node/operator-claim.js +0 -77
- package/sdk/dist/node/operator-claim.js.map +0 -1
package/lib/{org.mjs → orgs.mjs}
RENAMED
|
@@ -24,46 +24,45 @@ import {
|
|
|
24
24
|
|
|
25
25
|
const ROLE_LIST = "owner | admin | developer | billing | viewer";
|
|
26
26
|
|
|
27
|
-
const HELP = `run402
|
|
27
|
+
const HELP = `run402 orgs — organizations: create, label, membership, invites
|
|
28
28
|
|
|
29
29
|
Usage:
|
|
30
|
-
run402
|
|
31
|
-
run402
|
|
32
|
-
run402
|
|
33
|
-
run402
|
|
34
|
-
run402
|
|
35
|
-
run402
|
|
36
|
-
run402 org
|
|
37
|
-
run402
|
|
38
|
-
run402
|
|
39
|
-
run402
|
|
40
|
-
run402 org
|
|
41
|
-
run402
|
|
42
|
-
run402
|
|
43
|
-
run402
|
|
44
|
-
run402
|
|
45
|
-
run402
|
|
46
|
-
run402
|
|
47
|
-
run402
|
|
48
|
-
run402
|
|
49
|
-
run402
|
|
50
|
-
run402
|
|
51
|
-
run402 org invite rm [<org_id>] --principal <principal_id>
|
|
30
|
+
run402 orgs create [--name <label>]
|
|
31
|
+
run402 orgs list
|
|
32
|
+
run402 orgs get [<org_id>]
|
|
33
|
+
run402 orgs rename [<org_id>] --name <display_name> (or: --clear to remove the label)
|
|
34
|
+
run402 orgs payout-wallet [<org_id>] <wallet_address> (or: --clear to remove the explicit default)
|
|
35
|
+
run402 orgs slug <slug> [--org <org_id>]
|
|
36
|
+
run402 orgs adopt [--org <org_id>] [--name <label>]
|
|
37
|
+
run402 orgs use <org_id>
|
|
38
|
+
run402 orgs current
|
|
39
|
+
run402 orgs clear
|
|
40
|
+
run402 orgs bind [--org <org_id>] [--room <key>]
|
|
41
|
+
run402 orgs unbind
|
|
42
|
+
run402 orgs audit [<org_id>] [--limit N] [--after <cursor>] [--before <cursor>]
|
|
43
|
+
run402 orgs members list [<org_id>]
|
|
44
|
+
run402 orgs members add [<org_id>] <wallet_address> [--role <role>]
|
|
45
|
+
run402 orgs members role [<org_id>] --principal <principal_id> --role <role>
|
|
46
|
+
run402 orgs members rm [<org_id>] --principal <principal_id>
|
|
47
|
+
run402 orgs members revoke-key [<org_id>] --principal <principal_id> [--reason <why>] (owner + step-up; revokes the member's gitvault encryption key — its next gitvault operation enrolls afresh)
|
|
48
|
+
run402 orgs invite list [<org_id>]
|
|
49
|
+
run402 orgs invite create [<org_id>] --email <email> [--role <role>] [--ttl-hours N]
|
|
50
|
+
run402 orgs invite rm [<org_id>] --principal <principal_id>
|
|
52
51
|
|
|
53
52
|
<org_id> is optional everywhere: a leading UUID positional addresses that org;
|
|
54
53
|
omit it and the org comes from --org, then RUN402_ORG, then the .run402.json
|
|
55
|
-
binding, then 'run402
|
|
56
|
-
other with nothing to look up: run402
|
|
54
|
+
binding, then 'run402 orgs use'. Inside a bound checkout two agents add each
|
|
55
|
+
other with nothing to look up: run402 orgs members add <wallet_address> --role developer.
|
|
57
56
|
A developer-or-above add REFUSES (GITVAULT_WRITER_NOT_ADMITTED) unless this session's key is an admitted writer on every vault of the org, so the new member can push at once; a current writer admits your key with run402 repos access sync.
|
|
58
|
-
The second attribute may also be passed positionally (run402
|
|
57
|
+
The second attribute may also be passed positionally (run402 orgs members add <wallet_address>).
|
|
59
58
|
|
|
60
59
|
Subcommands:
|
|
61
60
|
create Create an empty org on the prototype tier (you become owner)
|
|
62
|
-
list
|
|
61
|
+
list Your orgs: role, tier, lifecycle, quotas, allowance, advisories
|
|
63
62
|
get Read one org (label + tier/lease + your role)
|
|
64
63
|
rename Set or clear an org's display label (owner-only)
|
|
65
64
|
slug Claim or rename the org's globally-unique, address-form slug
|
|
66
|
-
(owner-only). A genesis
|
|
65
|
+
(owner-only). A genesis set spends a one-time fee; a
|
|
67
66
|
rename releases the old slug into a ~90-day cooldown.
|
|
68
67
|
use Select the current org for this wallet profile
|
|
69
68
|
current Report the resolved current org and where it came from
|
|
@@ -71,8 +70,7 @@ Subcommands:
|
|
|
71
70
|
bind Write this checkout's org (+room) into .run402.json — commit it
|
|
72
71
|
unbind Remove the org/room keys from .run402.json
|
|
73
72
|
payout-wallet Set or clear the tenant route payout wallet (admin+)
|
|
74
|
-
|
|
75
|
-
member Manage members (list, add, role, rm) — mutations require owner
|
|
73
|
+
members Manage members (list, add, role, rm) — mutations require owner
|
|
76
74
|
invite Manage email invites (list, create, rm) — mutations require owner
|
|
77
75
|
audit Control-plane audit trail for an org (admin+)
|
|
78
76
|
|
|
@@ -84,25 +82,25 @@ Notes:
|
|
|
84
82
|
- JSON in, JSON out.
|
|
85
83
|
|
|
86
84
|
Examples:
|
|
87
|
-
run402
|
|
88
|
-
run402
|
|
89
|
-
run402
|
|
90
|
-
run402
|
|
91
|
-
run402
|
|
92
|
-
run402
|
|
93
|
-
run402
|
|
94
|
-
run402
|
|
95
|
-
run402
|
|
96
|
-
run402
|
|
97
|
-
run402
|
|
98
|
-
run402
|
|
85
|
+
run402 orgs create --name "Kychee"
|
|
86
|
+
run402 orgs list
|
|
87
|
+
run402 orgs get # the current org (binding / orgs use)
|
|
88
|
+
run402 orgs get 8f14e45f-ceea-4b7a-9d3c-0b2a6e6f1c2d
|
|
89
|
+
run402 orgs rename --name "New Name"
|
|
90
|
+
run402 orgs rename --clear
|
|
91
|
+
run402 orgs payout-wallet 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
|
92
|
+
run402 orgs payout-wallet --clear
|
|
93
|
+
run402 orgs members add 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --role admin
|
|
94
|
+
run402 orgs members add 8f14e45f-ceea-4b7a-9d3c-0b2a6e6f1c2d 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --role admin
|
|
95
|
+
run402 orgs invite create dev@example.com --role developer
|
|
96
|
+
run402 orgs audit --limit 50
|
|
99
97
|
`;
|
|
100
98
|
|
|
101
99
|
const SUB_HELP = {
|
|
102
|
-
create: `run402
|
|
100
|
+
create: `run402 orgs create — create an empty org (prototype tier; you become owner)
|
|
103
101
|
|
|
104
102
|
Usage:
|
|
105
|
-
run402
|
|
103
|
+
run402 orgs create [--name <label>]
|
|
106
104
|
|
|
107
105
|
The label is an optional free-text name (non-unique, not an id). Omit for an
|
|
108
106
|
unlabeled org. There is no tier input at create; the response reports the
|
|
@@ -110,42 +108,51 @@ created org's prototype tier plus lease_started_at / lease_expires_at. Paid
|
|
|
110
108
|
tiers are a separate flow. Step-up gated for control-plane sessions; the
|
|
111
109
|
free-org cap may apply.
|
|
112
110
|
`,
|
|
113
|
-
list: `run402
|
|
111
|
+
list: `run402 orgs list — your orgs, with the account overview
|
|
114
112
|
|
|
115
113
|
Usage:
|
|
116
|
-
run402
|
|
114
|
+
run402 orgs list
|
|
115
|
+
|
|
116
|
+
Lists every org you are a member of (GET /orgs/v1) and joins each row with
|
|
117
|
+
the account overview (GET /agent/v1/me/overview): tier, lifecycle state,
|
|
118
|
+
lease, quotas, allowance. The output also carries the overview's wallets,
|
|
119
|
+
rollup, and advisories, plus scope and session (the sign-in session's grade,
|
|
120
|
+
or null when a wallet reads). Both reads use the CLI's credential: the active
|
|
121
|
+
wallet when there is one, else the sign-in session from 'run402 login'. When the overview
|
|
122
|
+
read is refused (a grant key, for one), the memberships still print and
|
|
123
|
+
'overview' is null.
|
|
117
124
|
`,
|
|
118
|
-
get: `run402
|
|
125
|
+
get: `run402 orgs get — read one org (label + tier/lease + your role)
|
|
119
126
|
|
|
120
127
|
Usage:
|
|
121
|
-
run402
|
|
128
|
+
run402 orgs get [<org_id>]
|
|
122
129
|
|
|
123
130
|
Any active member may read. A non-member (including a guessed id) gets the same
|
|
124
131
|
non-revealing 403.
|
|
125
132
|
`,
|
|
126
|
-
rename: `run402
|
|
133
|
+
rename: `run402 orgs rename — set or clear an org's display label (owner-only)
|
|
127
134
|
|
|
128
135
|
Usage:
|
|
129
|
-
run402
|
|
130
|
-
run402
|
|
136
|
+
run402 orgs rename [<org_id>] --name <display_name>
|
|
137
|
+
run402 orgs rename [<org_id>] --clear
|
|
131
138
|
|
|
132
139
|
Legacy (still supported):
|
|
133
|
-
run402
|
|
140
|
+
run402 orgs rename [<org_id>] <display_name>
|
|
134
141
|
|
|
135
142
|
Owner-only + step-up gated. Pass --clear (or an empty display_name) to remove
|
|
136
143
|
the label. Output includes the updated tier and lease timestamps.
|
|
137
144
|
`,
|
|
138
|
-
slug: `run402
|
|
145
|
+
slug: `run402 orgs slug — set or rename the org's address-form slug
|
|
139
146
|
|
|
140
147
|
Usage:
|
|
141
|
-
run402
|
|
148
|
+
run402 orgs slug <slug> [--org <org_id>] [--idempotency-key <key>]
|
|
142
149
|
|
|
143
|
-
The slug is a globally-unique,
|
|
150
|
+
The slug is a globally-unique, address-form handle for the org
|
|
144
151
|
(repo-first-onramp design D6) — the <org-slug> half of a named repo address
|
|
145
152
|
run402::<org-slug>/<name>. Grammar: lowercase [a-z0-9-], no leading/trailing/
|
|
146
153
|
double hyphen, max 39 chars. Owner-only.
|
|
147
154
|
|
|
148
|
-
A genesis
|
|
155
|
+
A genesis set (the org had no prior slug) spends a one-time fee off
|
|
149
156
|
the org's balance. A rename is free but releases the OLD slug into a ~90-day
|
|
150
157
|
cooldown: it stops resolving, with a typed SLUG_RELEASED refusal naming the
|
|
151
158
|
new slug as successor — there is no redirect, so update every remote and
|
|
@@ -155,14 +162,14 @@ This is a paid, side-effecting mutation and requires Idempotency-Key; the SDK
|
|
|
155
162
|
generates one automatically unless --idempotency-key is passed, so a retried
|
|
156
163
|
call after a dropped response can never double-bill.
|
|
157
164
|
`,
|
|
158
|
-
"payout-wallet": `run402
|
|
165
|
+
"payout-wallet": `run402 orgs payout-wallet — set or clear the tenant route payout wallet
|
|
159
166
|
|
|
160
167
|
Usage:
|
|
161
|
-
run402
|
|
162
|
-
run402
|
|
168
|
+
run402 orgs payout-wallet [<org_id>] <wallet_address>
|
|
169
|
+
run402 orgs payout-wallet [<org_id>] --clear
|
|
163
170
|
|
|
164
171
|
Legacy (still supported):
|
|
165
|
-
run402
|
|
172
|
+
run402 orgs payout-wallet [<org_id>] <wallet_address>
|
|
166
173
|
|
|
167
174
|
Admin/owner-only + step-up gated. The wallet must already be active and linked
|
|
168
175
|
to the same org. This wallet receives x402 settlement for function web routes
|
|
@@ -172,50 +179,39 @@ explicit default; a single active org wallet may still resolve automatically.
|
|
|
172
179
|
The JSON response includes recovery.status, active_wallet_count, and
|
|
173
180
|
next_actions for PAYOUT_WALLET_REQUIRED / PAYOUT_WALLET_AMBIGUOUS setup.
|
|
174
181
|
`,
|
|
175
|
-
|
|
182
|
+
members: `run402 orgs members — manage org members
|
|
176
183
|
|
|
177
184
|
Usage:
|
|
178
|
-
run402
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
authenticator_id, and every org membership (org_id, display_name, role, status). REMOTE identity;
|
|
184
|
-
for local wallet/profile state use 'run402 status'.
|
|
185
|
-
`,
|
|
186
|
-
member: `run402 org member — manage org members
|
|
187
|
-
|
|
188
|
-
Usage:
|
|
189
|
-
run402 org member list [<org_id>]
|
|
190
|
-
run402 org member add [<org_id>] <wallet_address> [--role <role>]
|
|
191
|
-
run402 org member role [<org_id>] --principal <principal_id> --role <role>
|
|
192
|
-
run402 org member rm [<org_id>] --principal <principal_id>
|
|
193
|
-
run402 org member revoke-key [<org_id>] --principal <principal_id> [--reason <why>] (owner + step-up; revokes the member's gitvault encryption key — its next gitvault operation enrolls afresh)
|
|
185
|
+
run402 orgs members list [<org_id>]
|
|
186
|
+
run402 orgs members add [<org_id>] <wallet_address> [--role <role>]
|
|
187
|
+
run402 orgs members role [<org_id>] --principal <principal_id> --role <role>
|
|
188
|
+
run402 orgs members rm [<org_id>] --principal <principal_id>
|
|
189
|
+
run402 orgs members revoke-key [<org_id>] --principal <principal_id> [--reason <why>] (owner + step-up; revokes the member's gitvault encryption key — its next gitvault operation enrolls afresh)
|
|
194
190
|
|
|
195
191
|
Roles: ${ROLE_LIST} (add defaults to developer). Mutations require an active owner.
|
|
196
192
|
Demoting/removing the org's only active owner fails with 409 LAST_OWNER.
|
|
197
193
|
`,
|
|
198
|
-
invite: `run402
|
|
194
|
+
invite: `run402 orgs invite — manage email invites
|
|
199
195
|
|
|
200
196
|
Usage:
|
|
201
|
-
run402
|
|
202
|
-
run402
|
|
203
|
-
run402
|
|
197
|
+
run402 orgs invite list [<org_id>]
|
|
198
|
+
run402 orgs invite create [<org_id>] --email <email> [--role <role>] [--ttl-hours N]
|
|
199
|
+
run402 orgs invite rm [<org_id>] --principal <principal_id>
|
|
204
200
|
|
|
205
201
|
<org_id> is optional everywhere: a leading UUID positional addresses that org;
|
|
206
202
|
omit it and the org comes from --org, then RUN402_ORG, then the .run402.json
|
|
207
|
-
binding, then 'run402
|
|
208
|
-
other with nothing to look up: run402
|
|
203
|
+
binding, then 'run402 orgs use'. Inside a bound checkout two agents add each
|
|
204
|
+
other with nothing to look up: run402 orgs members add <wallet_address> --role developer.
|
|
209
205
|
A developer-or-above add REFUSES (GITVAULT_WRITER_NOT_ADMITTED) unless this session's key is an admitted writer on every vault of the org, so the new member can push at once; a current writer admits your key with run402 repos access sync.
|
|
210
|
-
The second attribute may also be passed positionally (run402
|
|
206
|
+
The second attribute may also be passed positionally (run402 orgs members add <wallet_address>).
|
|
211
207
|
|
|
212
208
|
An invite is claimed at the recipient's first login. Mutations require an active owner
|
|
213
209
|
(plus step-up when driven by a control-plane session).
|
|
214
210
|
`,
|
|
215
|
-
audit: `run402
|
|
211
|
+
audit: `run402 orgs audit — control-plane audit trail
|
|
216
212
|
|
|
217
213
|
Usage:
|
|
218
|
-
run402
|
|
214
|
+
run402 orgs audit [<org_id>] [--limit N] [--after <cursor>] [--before <cursor>]
|
|
219
215
|
|
|
220
216
|
Requires an admin+ membership on the org. Newest-first. Page forward with --after
|
|
221
217
|
(next_cursor from a prior page); --before is the legacy cursor. Returns
|
|
@@ -223,12 +219,12 @@ Requires an admin+ membership on the org. Newest-first. Page forward with --afte
|
|
|
223
219
|
`,
|
|
224
220
|
};
|
|
225
221
|
|
|
226
|
-
// ── Top-level: create / list / get / rename /
|
|
222
|
+
// ── Top-level: create / list / get / rename / audit ────────────────────
|
|
227
223
|
|
|
228
224
|
|
|
229
225
|
/**
|
|
230
226
|
* gitvault-multi-writer (rev 47) task 6.3 / design D3 — decided 2026-09-03
|
|
231
|
-
* (Tal): `
|
|
227
|
+
* (Tal): `orgs members add` REFUSES a writer-eligible add (developer or
|
|
232
228
|
* above) when this session's own key is not an admitted writer on EVERY
|
|
233
229
|
* vault of the org, because a developer who cannot push is not the member
|
|
234
230
|
* the caller meant, and a half-usable membership is exactly the silent
|
|
@@ -270,7 +266,7 @@ async function assertCallerCanAdmitWritersEverywhere(sdk, orgId, effectiveRole)
|
|
|
270
266
|
}
|
|
271
267
|
|
|
272
268
|
/**
|
|
273
|
-
* `
|
|
269
|
+
* `orgs members rm`'s inline epoch rotation (gitvault-multi-writer D6, the
|
|
274
270
|
* kygit-handoff member-removal decision): for every vault of the org where
|
|
275
271
|
* this session's key is an admitted writer, drive
|
|
276
272
|
* `rotateEpochForKeyRevocation(principalId)` — the one self-contained
|
|
@@ -317,7 +313,7 @@ async function create(args) {
|
|
|
317
313
|
const a = normalizeArgv(args);
|
|
318
314
|
const valueFlags = ["--name"];
|
|
319
315
|
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
320
|
-
requirePositionalCount(a, valueFlags, { min: 0, max: 0, command: "run402
|
|
316
|
+
requirePositionalCount(a, valueFlags, { min: 0, max: 0, command: "run402 orgs create [--name <label>]" });
|
|
321
317
|
const name = flagValue(a, "--name");
|
|
322
318
|
try {
|
|
323
319
|
console.log(JSON.stringify(await getSdk().orgs.create({ displayName: name ?? undefined }), null, 2));
|
|
@@ -329,36 +325,36 @@ async function create(args) {
|
|
|
329
325
|
async function list(args) {
|
|
330
326
|
const a = normalizeArgv(args);
|
|
331
327
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
332
|
-
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402
|
|
328
|
+
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402 orgs list" });
|
|
329
|
+
const sdk = getSdk();
|
|
330
|
+
let orgs;
|
|
333
331
|
try {
|
|
334
|
-
|
|
332
|
+
orgs = await sdk.orgs.list();
|
|
335
333
|
} catch (err) {
|
|
336
|
-
reportSdkError(err);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
async function whoami(args) {
|
|
341
|
-
const a = normalizeArgv(args);
|
|
342
|
-
assertKnownFlags(a, ["--help", "-h", "--set-name"], ["--set-name"]);
|
|
343
|
-
requirePositionalCount(positionalArgs(a, ["--set-name"]), ["--set-name"], { min: 0, max: 0, command: "run402 org whoami" });
|
|
344
|
-
const setName = flagValue(a, "--set-name");
|
|
345
|
-
if (setName !== null && setName.trim() === "") {
|
|
346
|
-
fail({
|
|
347
|
-
code: "BAD_USAGE",
|
|
348
|
-
message: "--set-name must not be empty.",
|
|
349
|
-
details: { field: "--set-name" },
|
|
350
|
-
hint: "Pass a 1-64 character display name.",
|
|
351
|
-
});
|
|
334
|
+
return reportSdkError(err);
|
|
352
335
|
}
|
|
336
|
+
// The account overview is the richer read, made with the same credential as
|
|
337
|
+
// the membership list; a caller the overview does not accept (a grant key)
|
|
338
|
+
// still gets its memberships.
|
|
339
|
+
let overview = null;
|
|
353
340
|
try {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const me = setName !== null ? await getSdk().orgs.setDisplayName(setName.trim()) : await getSdk().orgs.whoami();
|
|
358
|
-
console.log(JSON.stringify(me, null, 2));
|
|
359
|
-
} catch (err) {
|
|
360
|
-
reportSdkError(err);
|
|
341
|
+
overview = await sdk.me.overview();
|
|
342
|
+
} catch {
|
|
343
|
+
overview = null;
|
|
361
344
|
}
|
|
345
|
+
const byId = new Map((overview?.organizations ?? []).map((o) => [o.id, o]));
|
|
346
|
+
console.log(JSON.stringify({
|
|
347
|
+
orgs: orgs.map((m) => (byId.has(m.org_id) ? { ...m, overview: byId.get(m.org_id) } : m)),
|
|
348
|
+
...(overview
|
|
349
|
+
? {
|
|
350
|
+
scope: overview.scope ?? null,
|
|
351
|
+
session: overview.session ?? null,
|
|
352
|
+
rollup: overview.rollup ?? null,
|
|
353
|
+
wallets: overview.wallets ?? [],
|
|
354
|
+
advisories: overview.advisories ?? [],
|
|
355
|
+
}
|
|
356
|
+
: { overview: null }),
|
|
357
|
+
}, null, 2));
|
|
362
358
|
}
|
|
363
359
|
|
|
364
360
|
// ── Current organization (add-cli-current-org) ─────────────────────────────────
|
|
@@ -372,7 +368,7 @@ async function use(args) {
|
|
|
372
368
|
const a = normalizeArgv(args);
|
|
373
369
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
374
370
|
requirePositionalCount(a, [], {
|
|
375
|
-
min: 1, max: 1, command: "run402
|
|
371
|
+
min: 1, max: 1, command: "run402 orgs use <org_id>", missing: "<org_id>",
|
|
376
372
|
});
|
|
377
373
|
const orgId = positionalArgs(a, [])[0];
|
|
378
374
|
setSelectedOrgId(orgId);
|
|
@@ -382,7 +378,7 @@ async function use(args) {
|
|
|
382
378
|
async function clear(args) {
|
|
383
379
|
const a = normalizeArgv(args);
|
|
384
380
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
385
|
-
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402
|
|
381
|
+
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402 orgs clear" });
|
|
386
382
|
const previous = getSelectedOrgId();
|
|
387
383
|
clearSelectedOrgId();
|
|
388
384
|
console.log(JSON.stringify({ org_id: null, selected: false, previous_org_id: previous ?? null }, null, 2));
|
|
@@ -415,7 +411,7 @@ async function bind(args) {
|
|
|
415
411
|
const a = normalizeArgv(args);
|
|
416
412
|
const valueFlags = ["--org", "--room"];
|
|
417
413
|
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
418
|
-
requirePositionalCount(a, valueFlags, { min: 0, max: 0, command: "run402
|
|
414
|
+
requirePositionalCount(a, valueFlags, { min: 0, max: 0, command: "run402 orgs bind [--org <org_id>] [--room <key>]" });
|
|
419
415
|
|
|
420
416
|
let orgId = flagValue(a, "--org");
|
|
421
417
|
let picked = "flag";
|
|
@@ -432,7 +428,7 @@ async function bind(args) {
|
|
|
432
428
|
fail({
|
|
433
429
|
code: "NO_ORGS",
|
|
434
430
|
message: "This wallet is a member of no organization yet.",
|
|
435
|
-
hint: "Run 'run402 init' to provision one, or ask an owner to add you with 'run402
|
|
431
|
+
hint: "Run 'run402 init' to provision one, or ask an owner to add you with 'run402 orgs members add'.",
|
|
436
432
|
next_actions: [nextAction("initialize_wallet", { command: "run402 init", why: "Provision this wallet's organization, then retry." })],
|
|
437
433
|
});
|
|
438
434
|
}
|
|
@@ -440,9 +436,9 @@ async function bind(args) {
|
|
|
440
436
|
fail({
|
|
441
437
|
code: "AMBIGUOUS_ORG",
|
|
442
438
|
message: `This wallet belongs to ${rows.length} organizations — name the one to bind.`,
|
|
443
|
-
hint: "run402
|
|
439
|
+
hint: "run402 orgs bind --org <org_id>",
|
|
444
440
|
details: { orgs: rows.map((o) => ({ org_id: o.org_id, display_name: o.display_name ?? null, role: o.role ?? null })) },
|
|
445
|
-
next_actions: [nextAction("edit_request", { command: "run402
|
|
441
|
+
next_actions: [nextAction("edit_request", { command: "run402 orgs bind --org <org_id>", why: "Name which organization this checkout coordinates in." })],
|
|
446
442
|
});
|
|
447
443
|
}
|
|
448
444
|
orgId = rows[0].org_id;
|
|
@@ -451,7 +447,7 @@ async function bind(args) {
|
|
|
451
447
|
|
|
452
448
|
const room = flagValue(a, "--room") ?? roomKeyFromDir(process.cwd());
|
|
453
449
|
const { contents, file } = updateBindingFile(process.cwd(), {
|
|
454
|
-
org: requireOrgIdShape(orgId, picked === "flag" ? "--org" : "
|
|
450
|
+
org: requireOrgIdShape(orgId, picked === "flag" ? "--org" : "orgs list"),
|
|
455
451
|
...(room ? { room } : {}),
|
|
456
452
|
});
|
|
457
453
|
console.log(JSON.stringify({
|
|
@@ -470,7 +466,7 @@ async function bind(args) {
|
|
|
470
466
|
async function unbind(args) {
|
|
471
467
|
const a = normalizeArgv(args);
|
|
472
468
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
473
|
-
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402
|
|
469
|
+
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402 orgs unbind" });
|
|
474
470
|
const previous = readBindingFile(process.cwd());
|
|
475
471
|
const { contents, removed } = updateBindingFile(process.cwd(), { org: null, room: null });
|
|
476
472
|
console.log(JSON.stringify({
|
|
@@ -484,13 +480,13 @@ async function unbind(args) {
|
|
|
484
480
|
async function current(args) {
|
|
485
481
|
const a = normalizeArgv(args);
|
|
486
482
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
487
|
-
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402
|
|
483
|
+
requirePositionalCount(a, [], { min: 0, max: 0, command: "run402 orgs current" });
|
|
488
484
|
try {
|
|
489
|
-
// `cmd: "
|
|
485
|
+
// `cmd: "orgs"` exempts this from the ambiguity error on purpose: the
|
|
490
486
|
// command that reports the selection must stay usable while it is ambiguous.
|
|
491
487
|
// `optional` keeps an empty selection an explicit null state rather than a
|
|
492
488
|
// failure — reporting is not acting.
|
|
493
|
-
const resolved = await resolveOrg([], { cmd: "
|
|
489
|
+
const resolved = await resolveOrg([], { cmd: "orgs", optional: true });
|
|
494
490
|
console.log(JSON.stringify({
|
|
495
491
|
...orgProvenance(resolved),
|
|
496
492
|
selected_org_id: getSelectedOrgId() ?? null,
|
|
@@ -503,8 +499,8 @@ async function current(args) {
|
|
|
503
499
|
async function get(args) {
|
|
504
500
|
const a = normalizeArgv(args);
|
|
505
501
|
assertKnownFlags(a, ["--org", "--help", "-h"], ["--org"]);
|
|
506
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "
|
|
507
|
-
requireRest(pos, { max: 0, command: "run402
|
|
502
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "orgs" });
|
|
503
|
+
requireRest(pos, { max: 0, command: "run402 orgs get [<org_id>]" });
|
|
508
504
|
try {
|
|
509
505
|
console.log(JSON.stringify(await getSdk().org(org).get(), null, 2));
|
|
510
506
|
} catch (err) {
|
|
@@ -518,11 +514,11 @@ async function rename(args) {
|
|
|
518
514
|
const clear = a.includes("--clear");
|
|
519
515
|
const nameFlag = flagValue(a, "--name");
|
|
520
516
|
const single = clear || nameFlag !== null;
|
|
521
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--name"], { cmd: "
|
|
517
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--name"], { cmd: "orgs" });
|
|
522
518
|
requireRest(pos, {
|
|
523
519
|
min: single ? 0 : 1,
|
|
524
520
|
max: single ? 0 : 1,
|
|
525
|
-
command: "run402
|
|
521
|
+
command: "run402 orgs rename [<org_id>] --name <display_name>",
|
|
526
522
|
missing: "Missing <display_name> (use --name, or pass --clear).",
|
|
527
523
|
});
|
|
528
524
|
const displayName = clear ? null : (nameFlag ?? pos[0]);
|
|
@@ -539,11 +535,11 @@ async function payoutWallet(args) {
|
|
|
539
535
|
const clear = a.includes("--clear");
|
|
540
536
|
const walletFlag = flagValue(a, "--address");
|
|
541
537
|
const single = clear || walletFlag !== null;
|
|
542
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--address"], { cmd: "
|
|
538
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--address"], { cmd: "orgs" });
|
|
543
539
|
requireRest(pos, {
|
|
544
540
|
min: single ? 0 : 1,
|
|
545
541
|
max: single ? 0 : 1,
|
|
546
|
-
command: "run402
|
|
542
|
+
command: "run402 orgs payout-wallet [<org_id>] --address <wallet_address>",
|
|
547
543
|
missing: "Missing <wallet_address> (use --address, or pass --clear).",
|
|
548
544
|
});
|
|
549
545
|
const walletAddress = clear ? null : (walletFlag ?? pos[0]);
|
|
@@ -555,13 +551,65 @@ async function payoutWallet(args) {
|
|
|
555
551
|
}
|
|
556
552
|
|
|
557
553
|
/**
|
|
558
|
-
* `run402
|
|
559
|
-
* Owner-only, and a genesis
|
|
554
|
+
* `run402 orgs slug <slug>` — set or rename the org's address-form slug.
|
|
555
|
+
* Owner-only, and a genesis set spends a one-time fee — this is a
|
|
560
556
|
* PAID, side-effecting mutation, so it
|
|
561
557
|
* requires `Idempotency-Key`; the SDK generates one client-side when
|
|
562
558
|
* `--idempotency-key` is omitted, so a retried call after a dropped response
|
|
563
559
|
* can never double-bill.
|
|
564
560
|
*/
|
|
561
|
+
/**
|
|
562
|
+
* `run402 orgs adopt` — become the owner of the org your wallet's agent
|
|
563
|
+
* created (an ownership transfer on org memberships; the wallet stays on the
|
|
564
|
+
* agent, which is downgraded to developer). Dual proof: the write-capable
|
|
565
|
+
* sign-in session + a fresh signature from the active wallet over a server
|
|
566
|
+
* nonce. The Node convenience runs the whole dance (read session → challenge
|
|
567
|
+
* → sign → submit). Step-up failures and the multi-org `select_org`
|
|
568
|
+
* round-trip are surfaced here, not thrown at the user.
|
|
569
|
+
*/
|
|
570
|
+
async function adopt(args) {
|
|
571
|
+
const a = normalizeArgv(args);
|
|
572
|
+
const valueFlags = ["--org", "--name"];
|
|
573
|
+
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
574
|
+
requirePositionalCount(a, valueFlags, { min: 0, max: 0, command: "run402 orgs adopt [--org <org_id>] [--name <label>]" });
|
|
575
|
+
const orgId = flagValue(a, "--org");
|
|
576
|
+
const name = flagValue(a, "--name");
|
|
577
|
+
try {
|
|
578
|
+
const { adoptOrg } = await import("#sdk/node");
|
|
579
|
+
const result = await adoptOrg(getSdk(), {
|
|
580
|
+
orgId: orgId ?? undefined,
|
|
581
|
+
displayName: name ?? undefined,
|
|
582
|
+
});
|
|
583
|
+
// CLI output contract (cli-output-shape): no top-level `status` envelope.
|
|
584
|
+
// The gateway's discriminator becomes an explicit `adopted` boolean.
|
|
585
|
+
if (result && result.status === "select_org") {
|
|
586
|
+
console.log(JSON.stringify({
|
|
587
|
+
adopted: false,
|
|
588
|
+
selectable_orgs: result.selectable_orgs,
|
|
589
|
+
hint: "Your wallet's agent owns more than one org. Re-run with --org <org_id> to adopt one.",
|
|
590
|
+
}, null, 2));
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
console.log(JSON.stringify({
|
|
594
|
+
adopted: true,
|
|
595
|
+
org_id: result.org_id,
|
|
596
|
+
display_name: result.display_name,
|
|
597
|
+
role: result.role,
|
|
598
|
+
already_owned: result.already_owned ?? false,
|
|
599
|
+
}, null, 2));
|
|
600
|
+
} catch (err) {
|
|
601
|
+
const { isStepUpRequired } = await import("#sdk/node");
|
|
602
|
+
if (isStepUpRequired(err)) {
|
|
603
|
+
return fail({
|
|
604
|
+
code: "STEP_UP_REQUIRED",
|
|
605
|
+
message: "Adopting an org needs a fresh passkey step-up.",
|
|
606
|
+
hint: "Run 'run402 login' (a fresh passkey sign-in), then re-run 'run402 orgs adopt'.",
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
reportSdkError(err);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
565
613
|
async function slug(args) {
|
|
566
614
|
const a = normalizeArgv(args);
|
|
567
615
|
const valueFlags = ["--org", "--idempotency-key"];
|
|
@@ -569,23 +617,23 @@ async function slug(args) {
|
|
|
569
617
|
const [newSlug] = requirePositionalCount(a, valueFlags, {
|
|
570
618
|
min: 1,
|
|
571
619
|
max: 1,
|
|
572
|
-
command: "run402
|
|
620
|
+
command: "run402 orgs slug <slug> [--org <org_id>]",
|
|
573
621
|
missing: "Missing <slug>.",
|
|
574
622
|
});
|
|
575
|
-
const org = await resolveOrg(a, { cmd: "
|
|
623
|
+
const org = await resolveOrg(a, { cmd: "orgs" });
|
|
576
624
|
if (!org) {
|
|
577
625
|
fail({
|
|
578
626
|
code: "ORG_UNRESOLVED",
|
|
579
|
-
message: "Could not resolve which organization to
|
|
580
|
-
hint: "Pass --org <org_id>, or select one first with `run402
|
|
627
|
+
message: "Could not resolve which organization to set this slug for.",
|
|
628
|
+
hint: "Pass --org <org_id>, or select one first with `run402 orgs use <org_id>`.",
|
|
581
629
|
});
|
|
582
630
|
}
|
|
583
631
|
const idempotencyKey = flagValue(a, "--idempotency-key");
|
|
584
632
|
try {
|
|
585
|
-
const result = await getSdk().org(org.orgId).
|
|
633
|
+
const result = await getSdk().org(org.orgId).setSlug(newSlug, idempotencyKey != null ? { idempotencyKey } : {});
|
|
586
634
|
console.log(JSON.stringify(result, null, 2));
|
|
587
635
|
if (result.created) {
|
|
588
|
-
console.error(`slug "${result.slug}"
|
|
636
|
+
console.error(`slug "${result.slug}" set for ${org.orgId} — a one-time fee was debited from the org's balance.`);
|
|
589
637
|
} else if (result.previous_slug && result.previous_slug !== result.slug) {
|
|
590
638
|
console.error(
|
|
591
639
|
`org ${org.orgId} renamed from "${result.previous_slug}" to "${result.slug}" — no fee. ` +
|
|
@@ -603,8 +651,8 @@ async function audit(args) {
|
|
|
603
651
|
const a = normalizeArgv(args);
|
|
604
652
|
const valueFlags = ["--org", "--limit", "--after", "--before"];
|
|
605
653
|
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
606
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, valueFlags, { cmd: "
|
|
607
|
-
requireRest(pos, { max: 0, command: "run402
|
|
654
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, valueFlags, { cmd: "orgs" });
|
|
655
|
+
requireRest(pos, { max: 0, command: "run402 orgs audit [<org_id>]" });
|
|
608
656
|
const limitFlag = flagValue(a, "--limit");
|
|
609
657
|
const after = flagValue(a, "--after");
|
|
610
658
|
const before = flagValue(a, "--before");
|
|
@@ -627,19 +675,19 @@ async function runMember(args) {
|
|
|
627
675
|
const memberAction = args[0];
|
|
628
676
|
const rest = args.slice(1);
|
|
629
677
|
if (!memberAction || memberAction === "--help" || memberAction === "-h") {
|
|
630
|
-
console.log(SUB_HELP.
|
|
678
|
+
console.log(SUB_HELP.members);
|
|
631
679
|
process.exit(memberAction ? 0 : 1);
|
|
632
680
|
}
|
|
633
681
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
634
|
-
console.log(SUB_HELP.
|
|
682
|
+
console.log(SUB_HELP.members);
|
|
635
683
|
process.exit(0);
|
|
636
684
|
}
|
|
637
685
|
|
|
638
686
|
if (memberAction === "list") {
|
|
639
687
|
const a = normalizeArgv(rest);
|
|
640
688
|
assertKnownFlags(a, ["--org", "--help", "-h"], ["--org"]);
|
|
641
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "
|
|
642
|
-
requireRest(pos, { max: 0, command: "run402
|
|
689
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "orgs" });
|
|
690
|
+
requireRest(pos, { max: 0, command: "run402 orgs members list [<org_id>]" });
|
|
643
691
|
try {
|
|
644
692
|
console.log(JSON.stringify({ members: await getSdk().org(org).members.list() }, null, 2));
|
|
645
693
|
} catch (err) {
|
|
@@ -654,9 +702,9 @@ async function runMember(args) {
|
|
|
654
702
|
const role = flagValue(a, "--role");
|
|
655
703
|
const walletFlag = flagValue(a, "--address");
|
|
656
704
|
const count = walletFlag ? 0 : 1;
|
|
657
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--role", "--address"], { cmd: "
|
|
705
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--role", "--address"], { cmd: "orgs" });
|
|
658
706
|
requireRest(pos, {
|
|
659
|
-
min: count, max: count, command: "run402
|
|
707
|
+
min: count, max: count, command: "run402 orgs members add [<org_id>] <wallet_address> [--role <role>]",
|
|
660
708
|
missing: "Missing <wallet_address> (positional, or --address).",
|
|
661
709
|
});
|
|
662
710
|
const wallet = walletFlag ?? pos[0];
|
|
@@ -673,7 +721,7 @@ async function runMember(args) {
|
|
|
673
721
|
// this org's vaults now have a pending writer candidate (D3: there is
|
|
674
722
|
// no server-side writer admission — the client holds the keys) via a
|
|
675
723
|
// `sync_writers` next_action carrying `vault_ids[]`. Run the ACTUAL
|
|
676
|
-
// reconcile against each one now, so a single `
|
|
724
|
+
// reconcile against each one now, so a single `orgs members add` finishes
|
|
677
725
|
// the whole job when the caller can. `reconcile()` is ALREADY a
|
|
678
726
|
// fast, network-free no-op per vault when this session's own key
|
|
679
727
|
// isn't a writer there (task 5.7's own `eligible` gate). For a
|
|
@@ -721,9 +769,9 @@ async function runMember(args) {
|
|
|
721
769
|
const principalFlag = flagValue(a, "--principal");
|
|
722
770
|
const reason = flagValue(a, "--reason");
|
|
723
771
|
const count = principalFlag ? 0 : 1;
|
|
724
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal", "--reason"], { cmd: "
|
|
772
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal", "--reason"], { cmd: "orgs" });
|
|
725
773
|
requireRest(pos, {
|
|
726
|
-
min: count, max: count, command: "run402
|
|
774
|
+
min: count, max: count, command: "run402 orgs members revoke-key [<org_id>] --principal <principal_id> [--reason <why>]",
|
|
727
775
|
missing: "Missing <principal_id> (--principal).",
|
|
728
776
|
});
|
|
729
777
|
const principalId = principalFlag ?? pos[0];
|
|
@@ -741,9 +789,9 @@ async function runMember(args) {
|
|
|
741
789
|
const principalFlag = flagValue(a, "--principal");
|
|
742
790
|
const roleFlag = flagValue(a, "--role");
|
|
743
791
|
const count = 2 - (principalFlag ? 1 : 0) - (roleFlag ? 1 : 0);
|
|
744
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal", "--role"], { cmd: "
|
|
792
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal", "--role"], { cmd: "orgs" });
|
|
745
793
|
requireRest(pos, {
|
|
746
|
-
min: count, max: count, command: "run402
|
|
794
|
+
min: count, max: count, command: "run402 orgs members role [<org_id>] --principal <principal_id> --role <role>",
|
|
747
795
|
missing: "Missing <principal_id> (--principal) and/or <role> (--role).",
|
|
748
796
|
});
|
|
749
797
|
const principalId = principalFlag ?? pos[0];
|
|
@@ -761,9 +809,9 @@ async function runMember(args) {
|
|
|
761
809
|
assertKnownFlags(a, ["--org", "--principal", "--help", "-h"], ["--org", "--principal"]);
|
|
762
810
|
const principalFlag = flagValue(a, "--principal");
|
|
763
811
|
const count = principalFlag ? 0 : 1;
|
|
764
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal"], { cmd: "
|
|
812
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal"], { cmd: "orgs" });
|
|
765
813
|
requireRest(pos, {
|
|
766
|
-
min: count, max: count, command: "run402
|
|
814
|
+
min: count, max: count, command: "run402 orgs members rm [<org_id>] --principal <principal_id>",
|
|
767
815
|
missing: "Missing <principal_id> (use --principal).",
|
|
768
816
|
});
|
|
769
817
|
const principalId = principalFlag ?? pos[0];
|
|
@@ -792,7 +840,7 @@ async function runMember(args) {
|
|
|
792
840
|
return;
|
|
793
841
|
}
|
|
794
842
|
|
|
795
|
-
fail({ code: "BAD_USAGE", message: `Unknown '
|
|
843
|
+
fail({ code: "BAD_USAGE", message: `Unknown 'orgs members' action: ${memberAction}. Try list | add | role | rm.` });
|
|
796
844
|
}
|
|
797
845
|
|
|
798
846
|
// ── Invite group ─────────────────────────────────────────────────────────────────
|
|
@@ -812,8 +860,8 @@ async function runInvite(args) {
|
|
|
812
860
|
if (inviteAction === "list") {
|
|
813
861
|
const a = normalizeArgv(rest);
|
|
814
862
|
assertKnownFlags(a, ["--org", "--help", "-h"], ["--org"]);
|
|
815
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "
|
|
816
|
-
requireRest(pos, { max: 0, command: "run402
|
|
863
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org"], { cmd: "orgs" });
|
|
864
|
+
requireRest(pos, { max: 0, command: "run402 orgs invite list [<org_id>]" });
|
|
817
865
|
try {
|
|
818
866
|
console.log(JSON.stringify({ invites: await getSdk().org(org).invites.list() }, null, 2));
|
|
819
867
|
} catch (err) {
|
|
@@ -830,9 +878,9 @@ async function runInvite(args) {
|
|
|
830
878
|
const ttlFlag = flagValue(a, "--ttl-hours");
|
|
831
879
|
const emailFlag = flagValue(a, "--email");
|
|
832
880
|
const count = emailFlag ? 0 : 1;
|
|
833
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, valueFlags, { cmd: "
|
|
881
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, valueFlags, { cmd: "orgs" });
|
|
834
882
|
requireRest(pos, {
|
|
835
|
-
min: count, max: count, command: "run402
|
|
883
|
+
min: count, max: count, command: "run402 orgs invite create [<org_id>] --email <email> [--role <role>]",
|
|
836
884
|
missing: "Missing <email> (use --email).",
|
|
837
885
|
});
|
|
838
886
|
const email = emailFlag ?? pos[0];
|
|
@@ -851,9 +899,9 @@ async function runInvite(args) {
|
|
|
851
899
|
assertKnownFlags(a, ["--org", "--principal", "--help", "-h"], ["--org", "--principal"]);
|
|
852
900
|
const principalFlag = flagValue(a, "--principal");
|
|
853
901
|
const count = principalFlag ? 0 : 1;
|
|
854
|
-
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal"], { cmd: "
|
|
902
|
+
const { orgId: org, rest: pos } = await takeOrgPositional(a, ["--org", "--principal"], { cmd: "orgs" });
|
|
855
903
|
requireRest(pos, {
|
|
856
|
-
min: count, max: count, command: "run402
|
|
904
|
+
min: count, max: count, command: "run402 orgs invite rm [<org_id>] --principal <principal_id>",
|
|
857
905
|
missing: "Missing <principal_id> (use --principal).",
|
|
858
906
|
});
|
|
859
907
|
const principalId = principalFlag ?? pos[0];
|
|
@@ -865,7 +913,7 @@ async function runInvite(args) {
|
|
|
865
913
|
return;
|
|
866
914
|
}
|
|
867
915
|
|
|
868
|
-
fail({ code: "BAD_USAGE", message: `Unknown '
|
|
916
|
+
fail({ code: "BAD_USAGE", message: `Unknown 'orgs invite' action: ${inviteAction}. Try list | create | rm.` });
|
|
869
917
|
}
|
|
870
918
|
|
|
871
919
|
export async function run(sub, args) {
|
|
@@ -875,11 +923,11 @@ export async function run(sub, args) {
|
|
|
875
923
|
}
|
|
876
924
|
// Nested groups use `if (sub === ...)` (not `case`) so the sync test extracts
|
|
877
925
|
// their leaf actions via the dedicated memberAction/inviteAction parsers.
|
|
878
|
-
if (sub === "
|
|
926
|
+
if (sub === "members") {
|
|
879
927
|
await runMember(args ?? []);
|
|
880
928
|
return;
|
|
881
929
|
}
|
|
882
|
-
if (sub === "invite"
|
|
930
|
+
if (sub === "invite") {
|
|
883
931
|
await runInvite(args ?? []);
|
|
884
932
|
return;
|
|
885
933
|
}
|
|
@@ -894,7 +942,7 @@ export async function run(sub, args) {
|
|
|
894
942
|
case "rename": await rename(args); break;
|
|
895
943
|
case "payout-wallet": await payoutWallet(args); break;
|
|
896
944
|
case "slug": await slug(args); break;
|
|
897
|
-
case "
|
|
945
|
+
case "adopt": await adopt(args); break;
|
|
898
946
|
case "use": await use(args); break;
|
|
899
947
|
case "current": await current(args); break;
|
|
900
948
|
case "clear": await clear(args); break;
|
|
@@ -902,6 +950,6 @@ export async function run(sub, args) {
|
|
|
902
950
|
case "unbind": await unbind(args); break;
|
|
903
951
|
case "audit": await audit(args); break;
|
|
904
952
|
default:
|
|
905
|
-
failUnknownSubcommand("
|
|
953
|
+
failUnknownSubcommand("orgs", sub);
|
|
906
954
|
}
|
|
907
955
|
}
|