run402 4.93.1 → 4.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -41
- package/cli.mjs +34 -29
- 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 +1 -1
- package/lib/admin.mjs +1 -1
- package/lib/agent.mjs +20 -18
- package/lib/approve.mjs +81 -0
- package/lib/apps.mjs +3 -3
- package/lib/assets.mjs +2 -2
- package/lib/billing.mjs +6 -6
- package/lib/buzz-doctor.mjs +1 -1
- package/lib/buzz-notifications.mjs +1 -1
- package/lib/buzz.mjs +1 -1
- package/lib/buzz.test.mjs +1 -1
- package/lib/ci.mjs +4 -4
- package/lib/cold-start.mjs +21 -21
- package/lib/command-manifest.mjs +20 -34
- package/lib/config.mjs +24 -24
- package/lib/contacts.mjs +13 -13
- package/lib/contracts.mjs +1 -1
- package/lib/credentials.mjs +2 -2
- package/lib/daemon-path.mjs +1 -1
- package/lib/delegates.mjs +1 -1
- package/lib/deliveries.mjs +4 -4
- package/lib/deploy-rehearse-discovery.test.mjs +7 -7
- package/lib/deploy-v2.mjs +232 -184
- package/lib/deploy.mjs +21 -53
- package/lib/doctor-source-scan.mjs +1 -1
- package/lib/doctor.mjs +57 -57
- package/lib/escalations.mjs +1 -1
- package/lib/feedback.mjs +10 -10
- package/lib/gitvault-daemon.mjs +1 -1
- package/lib/image.mjs +3 -3
- package/lib/init.mjs +66 -66
- package/lib/lightning-wallet.mjs +28 -28
- package/lib/login.mjs +207 -0
- package/lib/logout.mjs +53 -0
- package/lib/next-actions.mjs +15 -15
- package/lib/org.mjs +100 -13
- package/lib/pay.mjs +1 -1
- package/lib/projects.mjs +26 -29
- package/lib/redeem.mjs +7 -8
- package/lib/remote-helper-session.mjs +12 -12
- package/lib/repos.mjs +62 -62
- package/lib/rooms.mjs +103 -67
- package/lib/sdk-errors.mjs +9 -4
- package/lib/sdk.mjs +3 -3
- package/lib/service.mjs +5 -5
- package/lib/session-proofs.mjs +21 -0
- package/lib/sign-in.mjs +296 -0
- package/lib/sites.mjs +8 -8
- package/lib/stats.mjs +2 -2
- package/lib/status.mjs +25 -25
- package/lib/subdomains.mjs +19 -19
- package/lib/subscriptions.mjs +8 -8
- package/lib/tier.mjs +29 -22
- package/lib/transfer.mjs +58 -85
- package/lib/up.mjs +7 -7
- package/lib/wallet-context.mjs +3 -3
- package/lib/wallet-context.test.mjs +3 -3
- package/lib/wallets.mjs +196 -31
- package/lib/webhook-secret.mjs +6 -6
- package/lib/whoami.mjs +75 -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 +1 -1
- package/sdk/dist/actions.d.ts.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 +19 -19
- package/sdk/dist/credentials.d.ts.map +1 -1
- package/sdk/dist/credentials.js +1 -1
- package/sdk/dist/errors.d.ts +24 -26
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +34 -37
- 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 +29 -16
- 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 +51 -120
- 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 +1 -1
- package/sdk/dist/namespaces/ai.js +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/credentials.types.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.js +5 -5
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +4 -4
- 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 +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +24 -24
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +109 -109
- 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 +43 -20
- 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 +74 -71
- 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 +36 -36
- package/sdk/dist/node/actions-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 +17 -16
- package/sdk/dist/node/credentials.d.ts.map +1 -1
- package/sdk/dist/node/credentials.js +28 -27
- package/sdk/dist/node/credentials.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-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/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/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 +3 -3
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +2 -2
- package/sdk/dist/scoped.js.map +1 -1
- package/core-dist/operator-session.js +0 -154
- package/lib/allowance.mjs +0 -355
- 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/buzz.test.mjs
CHANGED
|
@@ -84,7 +84,7 @@ describe("run402 buzz CLI", () => {
|
|
|
84
84
|
return {
|
|
85
85
|
buzz_human_adoption_offer_id: `buzzhao_${"1".repeat(32)}`,
|
|
86
86
|
status: "available",
|
|
87
|
-
|
|
87
|
+
offer_url: `https://console.run402.com/buzz/adoptions/buzzhao_${"1".repeat(32)}`,
|
|
88
88
|
};
|
|
89
89
|
},
|
|
90
90
|
},
|
package/lib/ci.mjs
CHANGED
|
@@ -34,7 +34,7 @@ Subcommands:
|
|
|
34
34
|
`;
|
|
35
35
|
|
|
36
36
|
const SUB_HELP = {
|
|
37
|
-
link: `run402 ci link github — Link GitHub Actions OIDC for deploy
|
|
37
|
+
link: `run402 ci link github — Link GitHub Actions OIDC for run402 deploy
|
|
38
38
|
|
|
39
39
|
Usage:
|
|
40
40
|
run402 ci link github [--project <id>] [--manifest <path>] [--repo <owner/repo>] [--branch <name> | --environment <name>] [--repository-id <id>] [--workflow <path>] [--expires-at <iso>] [--route-scope <pattern> ...] [--force]
|
|
@@ -245,7 +245,7 @@ ${environmentLine} steps:
|
|
|
245
245
|
- name: Deploy to run402
|
|
246
246
|
# Redirect stdin from /dev/null: a CI runner's stdin is a FIFO/file that
|
|
247
247
|
# older run402 CLIs counted as a second manifest source alongside --manifest.
|
|
248
|
-
run: npx --yes run402@${RUN402_VERSION} deploy
|
|
248
|
+
run: npx --yes run402@${RUN402_VERSION} deploy --manifest ${shellQuote(manifest)} --project ${shellQuote(projectId)} < /dev/null
|
|
249
249
|
`;
|
|
250
250
|
}
|
|
251
251
|
|
|
@@ -328,8 +328,8 @@ async function linkGithub(args) {
|
|
|
328
328
|
signedDelegation = signCiDelegation(values, { apiBase: API });
|
|
329
329
|
} catch (err) {
|
|
330
330
|
fail({
|
|
331
|
-
code: "
|
|
332
|
-
message: err?.message || "No local
|
|
331
|
+
code: "NO_WALLET",
|
|
332
|
+
message: err?.message || "No local wallet configured.",
|
|
333
333
|
hint: "Run: run402 init",
|
|
334
334
|
});
|
|
335
335
|
}
|
package/lib/cold-start.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `cold-start.mjs` — the minimal x402/Base-Sepolia cold-start chain
|
|
3
|
-
* (kygit-handoff design D5):
|
|
3
|
+
* (kygit-handoff design D5): wallet → faucet → one x402 prototype
|
|
4
4
|
* payment. `repos create` (and so `kygit create`) folds this in when it is
|
|
5
5
|
* refused `NO_ACTIVE_TIER`, so `kygit create` on a genuinely fresh machine
|
|
6
6
|
* ends with a vault, no human signup, no cloud dashboard.
|
|
7
7
|
*
|
|
8
|
-
* This is the SAME shape `run402 init` already walks (
|
|
8
|
+
* This is the SAME shape `run402 init` already walks (create the wallet →
|
|
9
9
|
* balance check → faucet → tier), factored down to the x402/Base-Sepolia
|
|
10
10
|
* default rail only (MPP/Tempo is `init`'s own separate concern — an agent
|
|
11
11
|
* hitting NO_ACTIVE_TIER mid-`repos create` gets the default rail, not a
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* create` needs when it discovers there is no tier and nothing else has
|
|
16
16
|
* set one up yet.
|
|
17
17
|
*
|
|
18
|
-
* add-room-invite design D9 splits the funded-wallet half (
|
|
18
|
+
* add-room-invite design D9 splits the funded-wallet half (wallet →
|
|
19
19
|
* faucet-if-empty → brief settlement poll) out as {@link ensureFundedWallet}
|
|
20
20
|
* — `rooms join <key>` needs exactly that half, with NO tier purchase and NO
|
|
21
21
|
* project creation (the claim itself is the one x402 payment that funds the
|
|
@@ -23,42 +23,42 @@
|
|
|
23
23
|
* `ensureFundedWallet` followed by the tier step — so every EXISTING caller
|
|
24
24
|
* (`repos create`/`resume`/`join`) is unchanged.
|
|
25
25
|
*/
|
|
26
|
-
import {
|
|
26
|
+
import { readWallet, saveWallet } from "./config.mjs";
|
|
27
27
|
import { getSdk } from "./sdk.mjs";
|
|
28
28
|
|
|
29
29
|
const USDC_ABI = [{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }];
|
|
30
30
|
const USDC_SEPOLIA = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Wallet → faucet-if-empty → brief settlement poll. NO tier purchase, no
|
|
34
34
|
* project creation — the caller decides what (if anything) to pay for next.
|
|
35
35
|
*
|
|
36
36
|
* @param {(line: string) => void} announce Called once per step, so the
|
|
37
37
|
* caller can print each one it took (client-surface spec: "announcing
|
|
38
38
|
* each step").
|
|
39
|
-
* @returns {Promise<{
|
|
39
|
+
* @returns {Promise<{wallet_created: boolean, faucet_requested: boolean, address: string}>}
|
|
40
40
|
*/
|
|
41
41
|
export async function ensureFundedWallet(announce = () => {}) {
|
|
42
|
-
const out = {
|
|
42
|
+
const out = { wallet_created: false, faucet_requested: false, address: "" };
|
|
43
43
|
|
|
44
|
-
let
|
|
45
|
-
if (!
|
|
44
|
+
let localWallet = readWallet();
|
|
45
|
+
if (!localWallet) {
|
|
46
46
|
const { generatePrivateKey, privateKeyToAccount } = await import("viem/accounts");
|
|
47
47
|
const privateKey = generatePrivateKey();
|
|
48
48
|
const account = privateKeyToAccount(privateKey);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
out.
|
|
52
|
-
announce(`
|
|
49
|
+
localWallet = { address: account.address, privateKey, created: new Date().toISOString(), funded: false, rail: "x402" };
|
|
50
|
+
saveWallet(localWallet);
|
|
51
|
+
out.wallet_created = true;
|
|
52
|
+
announce(`wallet created: ${localWallet.address}`);
|
|
53
53
|
}
|
|
54
|
-
out.address =
|
|
54
|
+
out.address = localWallet.address;
|
|
55
55
|
|
|
56
56
|
const { createPublicClient, http } = await import("viem");
|
|
57
57
|
const { baseSepolia } = await import("viem/chains");
|
|
58
58
|
const client = createPublicClient({ chain: baseSepolia, transport: http() });
|
|
59
59
|
let balance = 0;
|
|
60
60
|
try {
|
|
61
|
-
balance = Number(await client.readContract({ address: USDC_SEPOLIA, abi: USDC_ABI, functionName: "balanceOf", args: [
|
|
61
|
+
balance = Number(await client.readContract({ address: USDC_SEPOLIA, abi: USDC_ABI, functionName: "balanceOf", args: [localWallet.address] }));
|
|
62
62
|
} catch {
|
|
63
63
|
/* an RPC hiccup here is not fatal — the payment below will surface a real failure if the balance really is zero */
|
|
64
64
|
}
|
|
@@ -67,19 +67,19 @@ export async function ensureFundedWallet(announce = () => {}) {
|
|
|
67
67
|
// The faucet is throttled (0.25 USDC / 24h): a throttle refusal is
|
|
68
68
|
// surfaced with its wait and NEVER retried silently (client-surface
|
|
69
69
|
// spec) — this call is not wrapped in a swallowing catch.
|
|
70
|
-
await getSdk().
|
|
70
|
+
await getSdk().wallets.faucet(localWallet.address);
|
|
71
71
|
out.faucet_requested = true;
|
|
72
72
|
announce("faucet requested — waiting briefly for on-chain confirmation");
|
|
73
73
|
for (let i = 0; i < 30; i++) {
|
|
74
74
|
await new Promise((r) => setTimeout(r, 1000));
|
|
75
75
|
try {
|
|
76
|
-
balance = Number(await client.readContract({ address: USDC_SEPOLIA, abi: USDC_ABI, functionName: "balanceOf", args: [
|
|
76
|
+
balance = Number(await client.readContract({ address: USDC_SEPOLIA, abi: USDC_ABI, functionName: "balanceOf", args: [localWallet.address] }));
|
|
77
77
|
if (balance > 0) break;
|
|
78
78
|
} catch {
|
|
79
79
|
/* keep polling */
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
saveWallet({ ...localWallet, funded: true, lastFaucet: new Date().toISOString() });
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
return out;
|
|
@@ -91,13 +91,13 @@ export async function ensureFundedWallet(announce = () => {}) {
|
|
|
91
91
|
* no edits.
|
|
92
92
|
*
|
|
93
93
|
* @param {(line: string) => void} announce Called once per step.
|
|
94
|
-
* @returns {Promise<{
|
|
94
|
+
* @returns {Promise<{wallet_created: boolean, faucet_requested: boolean, tier: object|null}>}
|
|
95
95
|
*/
|
|
96
96
|
export async function foldColdStartChain(announce = () => {}) {
|
|
97
97
|
const funded = await ensureFundedWallet(announce);
|
|
98
98
|
|
|
99
|
-
announce("
|
|
99
|
+
announce("setting the prototype tier (one x402 testnet payment; the free tier, no lease)");
|
|
100
100
|
const tier = await getSdk().tier.set("prototype");
|
|
101
101
|
announce(`prototype tier active${tier?.status === "already_active" ? " (already active)" : ""}`);
|
|
102
|
-
return {
|
|
102
|
+
return { wallet_created: funded.wallet_created, faucet_requested: funded.faucet_requested, tier };
|
|
103
103
|
}
|
package/lib/command-manifest.mjs
CHANGED
|
@@ -107,6 +107,8 @@ export const COMMAND_MANIFEST = [
|
|
|
107
107
|
{ path: ["wallets", "unbind"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
108
108
|
{ path: ["wallets", "import"], positionals: [p("name")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["gate-import-wallet", "--key", "__FIXTURE_FILE__"] },
|
|
109
109
|
{ path: ["wallets", "rm"], positionals: [p("name")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["no-such-wallet", "--yes"] },
|
|
110
|
+
{ path: ["wallets", "fund"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], skipBehavioral: "polls on-chain funding with sleeps" },
|
|
111
|
+
{ path: ["wallets", "balance"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
110
112
|
{ path: ["wallets", "lightning"], positionals: [p("action", { required: false })], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["status"] },
|
|
111
113
|
|
|
112
114
|
// ── credentials (gateway project credentials) ────────────────────────────
|
|
@@ -124,14 +126,6 @@ export const COMMAND_MANIFEST = [
|
|
|
124
126
|
{ path: ["credentials", "project-keys", "export"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--reveal"] },
|
|
125
127
|
{ path: ["credentials", "project-keys", "remove"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [] },
|
|
126
128
|
|
|
127
|
-
// ── allowance ────────────────────────────────────────────────────────────
|
|
128
|
-
{ path: ["allowance", "status"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
129
|
-
{ path: ["allowance", "create"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], skipBehavioral: "creates a real local wallet key outside the gate's scratch profile" },
|
|
130
|
-
{ path: ["allowance", "fund"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], skipBehavioral: "polls on-chain funding with sleeps" },
|
|
131
|
-
{ path: ["allowance", "balance"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
132
|
-
{ path: ["allowance", "export"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
133
|
-
{ path: ["allowance", "checkout"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["--amount", "5000000"] },
|
|
134
|
-
{ path: ["allowance", "history"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
135
129
|
|
|
136
130
|
// ── tier ─────────────────────────────────────────────────────────────────
|
|
137
131
|
{ path: ["tier", "status"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
@@ -186,18 +180,21 @@ export const COMMAND_MANIFEST = [
|
|
|
186
180
|
{ path: ["core", "projects", "import"], positionals: [p("archive_path")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["__FIXTURE_FILE__", "--name", "gate-import"] },
|
|
187
181
|
|
|
188
182
|
// ── deploy (unified deploy v2) ───────────────────────────────────────────
|
|
189
|
-
|
|
183
|
+
// Bare `run402 deploy` IS the deploy (a verb); the family's subcommands
|
|
184
|
+
// follow. Dispatched flat through deploy.mjs so the gate exercises the
|
|
185
|
+
// same argv decision a person's shell does.
|
|
186
|
+
{ path: ["deploy"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--spec", "{}", "--check"], runStyle: "flat" },
|
|
190
187
|
{ path: ["deploy", "rehearse"], positionals: [p("plan_id", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["plan_gate1"], runStyle: "deployV2" },
|
|
191
188
|
{ path: ["deploy", "promote"], positionals: [p("release_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["rel_gate1"], runStyle: "deployV2" },
|
|
192
189
|
{ path: ["deploy", "resume"], positionals: [p("operation_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["op_gate1"], runStyle: "deployV2" },
|
|
190
|
+
{ path: ["deploy", "status"], positionals: [p("operation_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["op_gate1"], runStyle: "deployV2" },
|
|
193
191
|
{ path: ["deploy", "list"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "deployV2" },
|
|
194
192
|
{ path: ["deploy", "events"], positionals: [p("operation_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["op_gate1"], runStyle: "deployV2" },
|
|
195
193
|
{ path: ["deploy", "verify"], positionals: [p("operation_id", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["op_gate1"], runStyle: "deployV2" },
|
|
196
|
-
{ path: ["deploy", "
|
|
197
|
-
{ path: ["deploy", "
|
|
198
|
-
{ path: ["deploy", "
|
|
199
|
-
{ path: ["deploy", "
|
|
200
|
-
{ path: ["deploy", "resolve"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--url", "https://example.com/"], runStyle: "deployV2" },
|
|
194
|
+
{ path: ["deploy", "releases", "get"], positionals: [p("release_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["rel_gate1"], runStyle: "deployV2" },
|
|
195
|
+
{ path: ["deploy", "releases", "active"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "deployV2" },
|
|
196
|
+
{ path: ["deploy", "releases", "diff"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--from", "empty", "--to", "active"], runStyle: "deployV2" },
|
|
197
|
+
{ path: ["deploy", "resolve"], positionals: [p("url", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["https://example.com/"], runStyle: "deployV2" },
|
|
201
198
|
|
|
202
199
|
// ── ci ───────────────────────────────────────────────────────────────────
|
|
203
200
|
{ path: ["ci", "link"], positionals: [p("provider")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["github"] },
|
|
@@ -210,7 +207,6 @@ export const COMMAND_MANIFEST = [
|
|
|
210
207
|
{ path: ["transfer", "preview"], positionals: [p("transfer_id")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["tr_gate1"] },
|
|
211
208
|
{ path: ["transfer", "list"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
212
209
|
{ path: ["transfer", "accept"], positionals: [p("transfer_id")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["tr_gate1"] },
|
|
213
|
-
{ path: ["transfer", "claim"], positionals: [p("transfer_id")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["tr_gate1"] },
|
|
214
210
|
{ path: ["transfer", "cancel"], positionals: [p("transfer_id")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["tr_gate1"] },
|
|
215
211
|
|
|
216
212
|
// ── org ──────────────────────────────────────────────────────────────────
|
|
@@ -266,9 +262,11 @@ export const COMMAND_MANIFEST = [
|
|
|
266
262
|
// add-room-invite design D9: `rooms join` is one verb, two forms — no
|
|
267
263
|
// positional registers a presence (the behaviorally-tested path, unchanged
|
|
268
264
|
// by the optional positional below since minimalArgs stays empty); a
|
|
269
|
-
// `kri1_…` positional
|
|
265
|
+
// `kri1_…` positional redeems the key first (a real x402 payment + an
|
|
270
266
|
// org-membership mutation), so that form is never behaviorally exercised
|
|
271
267
|
// here — the same reasoning `repos join`'s own row states.
|
|
268
|
+
{ path: ["rooms", "list"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub" },
|
|
269
|
+
{ path: ["rooms", "get"], positionals: [p("room_key")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["run402-dev"], runStyle: "sub" },
|
|
272
270
|
{ path: ["rooms", "join"], positionals: [p("key", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub" },
|
|
273
271
|
{ path: ["rooms", "invite"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "mints a single-use bearer key from a live room, registering the inviter's presence and posting a real room message — never run against the gate's own checkout" },
|
|
274
272
|
{ path: ["rooms", "leave"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub" },
|
|
@@ -375,7 +373,7 @@ export const COMMAND_MANIFEST = [
|
|
|
375
373
|
{ path: ["sites", "deploy-dir"], positionals: [p("dir")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["__SCRATCH_DIR__"] },
|
|
376
374
|
|
|
377
375
|
// ── subdomains ───────────────────────────────────────────────────────────
|
|
378
|
-
{ path: ["subdomains", "
|
|
376
|
+
{ path: ["subdomains", "add"], positionals: [p("name")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["gate-sub"] },
|
|
379
377
|
{ path: ["subdomains", "list"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [] },
|
|
380
378
|
{ path: ["subdomains", "delete"], positionals: [p("name")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["gate-sub", "--confirm"] },
|
|
381
379
|
|
|
@@ -427,18 +425,16 @@ export const COMMAND_MANIFEST = [
|
|
|
427
425
|
{ path: ["email", "webhooks", "deliveries"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [] },
|
|
428
426
|
{ path: ["email", "webhooks", "redrive"], positionals: [p("delivery_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["dlv_gate1"] },
|
|
429
427
|
|
|
430
|
-
// ── message / agent /
|
|
428
|
+
// ── message / agent / sign-in ────────────────────────────────────────────
|
|
431
429
|
{ path: ["feedback", "send"], positionals: [p("words", { variadic: true })], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["hello", "from", "the", "gate"] },
|
|
432
430
|
{ path: ["agent", "contact"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["--name", "gate-agent"] },
|
|
433
431
|
{ path: ["agent", "status"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
434
432
|
{ path: ["agent", "verify-email"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
435
433
|
{ path: ["agent", "passkey"], positionals: [p("action")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["enroll"] },
|
|
436
|
-
{ path: ["
|
|
437
|
-
{ path: ["
|
|
438
|
-
{ path: ["
|
|
439
|
-
{ path: ["
|
|
440
|
-
{ path: ["operator", "claim-wallet-org"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [] },
|
|
441
|
-
{ path: ["operator", "approve"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["--action", "org.project.create", "--org", "org_gate1", "--no-open"] },
|
|
434
|
+
{ path: ["login"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], runStyle: "flat", skipBehavioral: "opens a browser / loopback listener" },
|
|
435
|
+
{ path: ["logout"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], runStyle: "flat" },
|
|
436
|
+
{ path: ["whoami"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: [], runStyle: "flat", skipBehavioral: "requires live principal authentication" },
|
|
437
|
+
{ path: ["approve"], positionals: [], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["--action", "org.project.create", "--org", "org_gate1", "--no-open"], runStyle: "flat" },
|
|
442
438
|
|
|
443
439
|
// ── auth ─────────────────────────────────────────────────────────────────
|
|
444
440
|
{ path: ["auth", "magic-link"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--email", "gate@example.com", "--redirect", "https://example.com/cb"] },
|
|
@@ -497,7 +493,6 @@ export const COMMAND_MANIFEST = [
|
|
|
497
493
|
// Families deliberately absent from the manifest, consumed by the gate's
|
|
498
494
|
// completeness check against cli.mjs's dispatch switch.
|
|
499
495
|
export const SKIPPED_FAMILIES = {
|
|
500
|
-
"apply": "pure alias for `deploy apply` (covered by the deploy family)",
|
|
501
496
|
"dev": "interactive wrapper that spawns `astro dev`",
|
|
502
497
|
// RESERVED, not dispatched: every `run402 message …` fails with
|
|
503
498
|
// COMMAND_REMOVED pointing at `feedback send` / `messages send` /
|
|
@@ -538,15 +533,6 @@ export const SKIPPED_FAMILIES = {
|
|
|
538
533
|
export const RESERVED_SUBCOMMANDS = {
|
|
539
534
|
"source-access:export": "moved to `repos recovery-bundle` — the artifact `repos recover --bundle` consumes belongs to the repos family",
|
|
540
535
|
"source-access:status": "moved to `repos access` — your own wrapper custody rides its member_custody block; the org advisory is `doctor --only recovery_posture`",
|
|
541
|
-
"rooms:who": "renamed to `rooms join` — an interrogative must not name a write",
|
|
542
|
-
"rooms:send": "moved to `messages send` — the verb acts on a message",
|
|
543
|
-
// The routes and SDK methods for room list/get exist (agent-room-lifecycle);
|
|
544
|
-
// only these two SPELLINGS are held back, because they were freed from
|
|
545
|
-
// meaning "list/get MESSAGES" and a reused spelling changes meaning without
|
|
546
|
-
// ever failing. One major, then they may name the room.
|
|
547
|
-
"rooms:list": "moved to `messages list` — the verb acts on a message",
|
|
548
|
-
"rooms:get": "moved to `messages get` — the verb acts on a message",
|
|
549
|
-
"rooms:ack": "moved to `messages ack` — the verb acts on a message",
|
|
550
536
|
"escalations:contacts": "merged into `contacts` — the ladder and Telegram channels are one question",
|
|
551
537
|
// Every `gitvault <verb>` spelling. Nine
|
|
552
538
|
// answer COMMAND_MOVED naming their `repos` successor; `push` and
|
package/lib/config.mjs
CHANGED
|
@@ -12,22 +12,22 @@ import {
|
|
|
12
12
|
getLegacyProjectsPath,
|
|
13
13
|
getProfileStatePath,
|
|
14
14
|
getProjectCredentialsPath,
|
|
15
|
-
|
|
15
|
+
getWalletPath,
|
|
16
16
|
configureApiBase,
|
|
17
17
|
isCoreApiTarget,
|
|
18
18
|
readApiTargetConfig,
|
|
19
19
|
} from "../core-dist/config.js";
|
|
20
|
-
import {
|
|
20
|
+
import { readWallet as coreReadWallet, saveWallet as coreSaveWallet } from "../core-dist/wallet.js";
|
|
21
21
|
import { loadKeyStore, getProject, saveProject, updateProject, removeProject, saveKeyStore, getActiveProjectId, setActiveProjectId } from "../core-dist/keystore.js";
|
|
22
|
-
import {
|
|
22
|
+
import { getWalletAuthHeaders as coreGetWalletAuthHeaders } from "../core-dist/wallet-auth.js";
|
|
23
23
|
import { fail } from "./sdk-errors.mjs";
|
|
24
24
|
import { initializeWalletAction, selectProjectAction } from "./next-actions.mjs";
|
|
25
25
|
|
|
26
26
|
// Wallet-dependent paths are exposed as getters (preferred — they always
|
|
27
27
|
// reflect the active profile, even if some future code path imports this module
|
|
28
|
-
// before wallet resolution). Production code (init/doctor/
|
|
28
|
+
// before wallet resolution). Production code (init/doctor/wallet) uses these.
|
|
29
29
|
export function configDir() { return getConfigDir(); }
|
|
30
|
-
export function
|
|
30
|
+
export function walletFile() { return getWalletPath(); }
|
|
31
31
|
export function projectCredentialsFile() { return getProjectCredentialsPath(); }
|
|
32
32
|
export function profileStateFile() { return getProfileStatePath(); }
|
|
33
33
|
export function legacyProjectsFile() { return getLegacyProjectsPath(); }
|
|
@@ -45,7 +45,7 @@ export function activeProfile() { return getActiveProfile(); }
|
|
|
45
45
|
// module, and tests set RUN402_CONFIG_DIR before importing. New code should
|
|
46
46
|
// prefer the getters above.
|
|
47
47
|
export const CONFIG_DIR = getConfigDir();
|
|
48
|
-
export const
|
|
48
|
+
export const WALLET_FILE = getWalletPath();
|
|
49
49
|
export const PROJECTS_FILE = getProjectCredentialsPath();
|
|
50
50
|
export const PROJECT_CREDENTIALS_FILE = getProjectCredentialsPath();
|
|
51
51
|
export const PROFILE_STATE_FILE = getProfileStatePath();
|
|
@@ -54,40 +54,40 @@ export const PROFILE_STATE_FILE = getProfileStatePath();
|
|
|
54
54
|
export const API = getApiBase();
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Wraps core's `
|
|
57
|
+
* Wraps core's `readWallet()` and converts the malformed-shape throw
|
|
58
58
|
* into the canonical CLI failure envelope. Without this guard, every
|
|
59
|
-
* CLI subcommand that touches the
|
|
60
|
-
* source paths the moment a user has a malformed `
|
|
59
|
+
* CLI subcommand that touches the wallet leaks a Node stack trace and
|
|
60
|
+
* source paths the moment a user has a malformed `wallet.json`.
|
|
61
61
|
*
|
|
62
62
|
* The unparseable-JSON case still returns `null` (matching the historical
|
|
63
|
-
* "
|
|
64
|
-
* error with `code:
|
|
63
|
+
* "no_wallet" UX); only valid-JSON-but-wrong-shape becomes a structured
|
|
64
|
+
* error with `code: BAD_WALLET_FILE`.
|
|
65
65
|
*/
|
|
66
|
-
export function
|
|
66
|
+
export function readWallet() {
|
|
67
67
|
try {
|
|
68
|
-
return
|
|
68
|
+
return coreReadWallet();
|
|
69
69
|
} catch (err) {
|
|
70
70
|
fail({
|
|
71
|
-
code: "
|
|
72
|
-
message: err?.message ?? "
|
|
73
|
-
hint: "Back up ~/.config/run402/
|
|
74
|
-
details: { path:
|
|
71
|
+
code: "BAD_WALLET_FILE",
|
|
72
|
+
message: err?.message ?? "wallet.json is malformed",
|
|
73
|
+
hint: "Back up ~/.config/run402/wallet.json and run 'run402 init' to recreate it.",
|
|
74
|
+
details: { path: walletFile() },
|
|
75
75
|
next_actions: [initializeWalletAction()],
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export function
|
|
81
|
-
|
|
80
|
+
export function saveWallet(data) {
|
|
81
|
+
coreSaveWallet(data);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
export function
|
|
85
|
-
const headers =
|
|
84
|
+
export function walletAuthHeaders(path) {
|
|
85
|
+
const headers = coreGetWalletAuthHeaders(path);
|
|
86
86
|
if (!headers) {
|
|
87
87
|
fail({
|
|
88
|
-
code: "
|
|
89
|
-
message: "No
|
|
90
|
-
hint: "Run: run402
|
|
88
|
+
code: "NO_WALLET",
|
|
89
|
+
message: "No local wallet found.",
|
|
90
|
+
hint: "Run: run402 init",
|
|
91
91
|
next_actions: [initializeWalletAction()],
|
|
92
92
|
});
|
|
93
93
|
}
|
package/lib/contacts.mjs
CHANGED
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
* `--kind` flag nobody could answer without looking it up.
|
|
19
19
|
*
|
|
20
20
|
* HTTP paths are unchanged (`/agent/v1/notifications/channels*`,
|
|
21
|
-
* `/orgs/v1/:org_id/escalation-contacts*`); the
|
|
21
|
+
* `/orgs/v1/:org_id/escalation-contacts*`); the SIWX auth headers below
|
|
22
22
|
* are PATH-scoped and must keep naming the real routes.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
24
|
+
import { walletAuthHeaders } from "./config.mjs";
|
|
25
|
+
import { sessionProofs } from "./session-proofs.mjs";
|
|
26
26
|
import { getSdk } from "./sdk.mjs";
|
|
27
27
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
28
28
|
import {
|
|
@@ -59,7 +59,7 @@ Two kinds, one question:
|
|
|
59
59
|
Every row carries \`kind\`. \`rm\` takes either kind's id and works out which.
|
|
60
60
|
|
|
61
61
|
Notes:
|
|
62
|
-
- Adding an address with no verified
|
|
62
|
+
- Adding an address with no verified contact email is ACCEPTED with a
|
|
63
63
|
reachability warning — you must be able to configure the chain before the
|
|
64
64
|
humans are bound.
|
|
65
65
|
- What actually landed is \`run402 deliveries\`.
|
|
@@ -69,7 +69,7 @@ async function preferences(args) {
|
|
|
69
69
|
const parsedArgs = normalizeArgv(args);
|
|
70
70
|
assertKnownFlags(parsedArgs, ["--help", "-h"]);
|
|
71
71
|
const positionals = positionalArgs(parsedArgs);
|
|
72
|
-
|
|
72
|
+
walletAuthHeaders("/agent/v1/notifications/preferences");
|
|
73
73
|
|
|
74
74
|
if (positionals.length === 0) {
|
|
75
75
|
// GET preferences
|
|
@@ -104,7 +104,7 @@ async function preferences(args) {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
try {
|
|
107
|
-
const data = await getSdk().admin.setNotificationPreferences(patch,
|
|
107
|
+
const data = await getSdk().admin.setNotificationPreferences(patch, sessionProofs("/agent/v1/notifications/preferences"));
|
|
108
108
|
console.log(JSON.stringify(data, null, 2));
|
|
109
109
|
} catch (err) {
|
|
110
110
|
reportSdkError(err);
|
|
@@ -185,7 +185,7 @@ async function channelsConnect(args) {
|
|
|
185
185
|
fail({ code: "BAD_USAGE", message: `Unexpected argument for notifications channels connect: ${positionals[1]}` });
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
const proofs =
|
|
188
|
+
const proofs = sessionProofs("/agent/v1/notifications/channels/telegram");
|
|
189
189
|
let pending;
|
|
190
190
|
try {
|
|
191
191
|
pending = await getSdk().admin.channels.connectTelegram(label ? { label } : {}, proofs);
|
|
@@ -215,7 +215,7 @@ async function channelsConnect(args) {
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
async function channelsList() {
|
|
218
|
-
|
|
218
|
+
walletAuthHeaders("/agent/v1/notifications/channels");
|
|
219
219
|
try {
|
|
220
220
|
console.log(JSON.stringify(await getSdk().admin.channels.list(), null, 2));
|
|
221
221
|
} catch (err) {
|
|
@@ -232,9 +232,9 @@ async function channelsRevoke(args) {
|
|
|
232
232
|
command: "run402 notifications channels revoke <binding_id>",
|
|
233
233
|
missing: "Missing <binding_id>.",
|
|
234
234
|
});
|
|
235
|
-
|
|
235
|
+
walletAuthHeaders("/agent/v1/notifications/channels/telegram");
|
|
236
236
|
try {
|
|
237
|
-
console.log(JSON.stringify(await getSdk().admin.channels.revokeTelegram(bindingId,
|
|
237
|
+
console.log(JSON.stringify(await getSdk().admin.channels.revokeTelegram(bindingId, sessionProofs("/agent/v1/notifications/channels/telegram")), null, 2));
|
|
238
238
|
} catch (err) {
|
|
239
239
|
reportSdkError(err);
|
|
240
240
|
}
|
|
@@ -280,7 +280,7 @@ async function test(args) {
|
|
|
280
280
|
const source = flagValue(parsedArgs, "--source");
|
|
281
281
|
if (source !== null) assertAllowedValue(source, ["app", "platform"], "--source");
|
|
282
282
|
const eventType = flagValue(parsedArgs, "--type");
|
|
283
|
-
|
|
283
|
+
walletAuthHeaders("/agent/v1/notifications/test");
|
|
284
284
|
const opts = {};
|
|
285
285
|
if (source) opts.source = source;
|
|
286
286
|
if (eventType) opts.eventType = eventType;
|
|
@@ -319,7 +319,7 @@ async function listContacts(args) {
|
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
try {
|
|
322
|
-
|
|
322
|
+
walletAuthHeaders("/agent/v1/notifications/channels");
|
|
323
323
|
const res = await sdk.admin.channels.list();
|
|
324
324
|
for (const ch of res.telegram ?? []) {
|
|
325
325
|
rows.push({ kind: "telegram", id: ch.binding_id ?? ch.id, ...ch });
|
|
@@ -354,7 +354,7 @@ async function removeContact(args) {
|
|
|
354
354
|
return;
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
|
-
|
|
357
|
+
walletAuthHeaders("/agent/v1/notifications/channels");
|
|
358
358
|
const chans = await sdk.admin.channels.list();
|
|
359
359
|
const chan = (chans.telegram ?? []).find((c) => (c.binding_id ?? c.id) === id);
|
|
360
360
|
if (chan) {
|
package/lib/contracts.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
const HELP = `run402 contracts — KMS-backed Ethereum signers for smart-contract calls
|
|
15
15
|
|
|
16
16
|
Pricing: $0.04/day per signer ($1.20/month) plus $0.000005 per contract call.
|
|
17
|
-
Signer creation requires $1.20
|
|
17
|
+
Signer creation requires $1.20 of allowance (30 days of rent).
|
|
18
18
|
Non-custodial: see https://run402.com/humans/terms.html#non-custodial-kms-wallets
|
|
19
19
|
|
|
20
20
|
Usage:
|
package/lib/credentials.mjs
CHANGED
|
@@ -48,7 +48,7 @@ Notes:
|
|
|
48
48
|
- 'issue', 'rotate' and 'revoke' need owner membership on the project's org
|
|
49
49
|
plus a fresh step-up, so a scoped agent credential can never escalate
|
|
50
50
|
itself into a permanent root. Authenticate with a wallet (SIWX) or a
|
|
51
|
-
|
|
51
|
+
sign-in session ('run402 login').
|
|
52
52
|
- 'token' is the exception: a delegate can mint one with no human present.
|
|
53
53
|
- Secrets are returned EXACTLY ONCE and are never recoverable. Full JSON goes
|
|
54
54
|
to stdout so you can pipe it; the warnings go to stderr.
|
|
@@ -126,7 +126,7 @@ anon/service keys, or "rotatable" once it holds credentials it can revoke
|
|
|
126
126
|
individually.
|
|
127
127
|
|
|
128
128
|
There is deliberately NO deadline: retirement is gated on conditions (every
|
|
129
|
-
tenant migrated, 30 consecutive days of zero legacy-key use, explicit
|
|
129
|
+
tenant migrated, 30 consecutive days of zero legacy-key use, explicit staff
|
|
130
130
|
approval), not a date. Read retirement.gated_on rather than planning against a
|
|
131
131
|
date the platform has not committed to.
|
|
132
132
|
`,
|
package/lib/daemon-path.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* builtins (pinned by the import-graph gate test), so it must stay tiny.
|
|
5
5
|
*
|
|
6
6
|
* The socket lives INSIDE the client configuration directory — the same
|
|
7
|
-
* 0700 trust boundary that already holds the
|
|
7
|
+
* 0700 trust boundary that already holds the wallet private key and the
|
|
8
8
|
* gitvault keystore — and its path is keyed by CLI version, so a CLI
|
|
9
9
|
* upgrade resolves a NEW path: the new client never reaches the old daemon,
|
|
10
10
|
* which idles out on its own. Windows uses a named pipe whose name carries
|
package/lib/delegates.mjs
CHANGED
|
@@ -32,7 +32,7 @@ Notes:
|
|
|
32
32
|
- A delegate can never be an owner, and is revocable and expiring.
|
|
33
33
|
- The token is shown ONCE and is not recoverable. Store it immediately;
|
|
34
34
|
if you lose it, 'rotate' issues a new one.
|
|
35
|
-
- Use it with: RUN402_DELEGATE_TOKEN=<token> run402 deploy
|
|
35
|
+
- Use it with: RUN402_DELEGATE_TOKEN=<token> run402 deploy ...
|
|
36
36
|
- JSON in, JSON out.
|
|
37
37
|
|
|
38
38
|
Why this exists:
|
package/lib/deliveries.mjs
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* produces them, which is now `contacts` and `subscriptions`.
|
|
8
8
|
*
|
|
9
9
|
* HTTP paths are unchanged (`/agent/v1/notifications*`) — this is client
|
|
10
|
-
* vocabulary, and the
|
|
10
|
+
* vocabulary, and the SIWX auth headers below are PATH-scoped, so they
|
|
11
11
|
* must keep naming the real route. Renaming them would ship broken auth
|
|
12
12
|
* against a live path, which is exactly how the `feedback` rename nearly went
|
|
13
13
|
* wrong.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import { walletAuthHeaders } from "./config.mjs";
|
|
16
16
|
import { getSdk } from "./sdk.mjs";
|
|
17
17
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
18
18
|
import {
|
|
@@ -47,7 +47,7 @@ async function list(args) {
|
|
|
47
47
|
if (extra.length > 0) {
|
|
48
48
|
fail({ code: "BAD_USAGE", message: `Unexpected argument for notifications list: ${extra[0]}` });
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
walletAuthHeaders("/agent/v1/notifications");
|
|
51
51
|
const opts = {};
|
|
52
52
|
const type = flagValue(parsedArgs, "--type");
|
|
53
53
|
const since = flagValue(parsedArgs, "--since");
|
|
@@ -72,7 +72,7 @@ async function get(args) {
|
|
|
72
72
|
if (positionals.length !== 1) {
|
|
73
73
|
fail({ code: "BAD_USAGE", message: "Usage: run402 notifications get <id>" });
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
walletAuthHeaders("/agent/v1/notifications");
|
|
76
76
|
try {
|
|
77
77
|
const data = await getSdk().admin.getNotification(positionals[0]);
|
|
78
78
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3,21 +3,21 @@ import assert from "node:assert/strict";
|
|
|
3
3
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
|
-
import {
|
|
6
|
+
import { discoverDeployManifest } from "./deploy-v2.mjs";
|
|
7
7
|
|
|
8
|
-
describe("deploy rehearse — manifest discovery (the way up does it)", () => {
|
|
8
|
+
describe("deploy / deploy rehearse — manifest discovery (the way up does it)", () => {
|
|
9
9
|
it("prefers run402.json, then run402.deploy.json, then app.json, then executable configs", () => {
|
|
10
10
|
const dir = mkdtempSync(join(tmpdir(), "run402-rehearse-discover-"));
|
|
11
11
|
try {
|
|
12
|
-
assert.equal(
|
|
12
|
+
assert.equal(discoverDeployManifest(dir), null);
|
|
13
13
|
writeFileSync(join(dir, "run402.deploy.ts"), "export default {}");
|
|
14
|
-
assert.equal(
|
|
14
|
+
assert.equal(discoverDeployManifest(dir), join(dir, "run402.deploy.ts"));
|
|
15
15
|
writeFileSync(join(dir, "app.json"), "{}");
|
|
16
|
-
assert.equal(
|
|
16
|
+
assert.equal(discoverDeployManifest(dir), join(dir, "app.json"));
|
|
17
17
|
writeFileSync(join(dir, "run402.deploy.json"), "{}");
|
|
18
|
-
assert.equal(
|
|
18
|
+
assert.equal(discoverDeployManifest(dir), join(dir, "run402.deploy.json"));
|
|
19
19
|
writeFileSync(join(dir, "run402.json"), "{}");
|
|
20
|
-
assert.equal(
|
|
20
|
+
assert.equal(discoverDeployManifest(dir), join(dir, "run402.json"));
|
|
21
21
|
} finally {
|
|
22
22
|
rmSync(dir, { recursive: true, force: true });
|
|
23
23
|
}
|