run402 1.12.3 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.mjs +7 -1
- package/lib/deploy.mjs +24 -15
- package/lib/init.mjs +18 -1
- package/lib/status.mjs +63 -0
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -20,6 +20,7 @@ Usage:
|
|
|
20
20
|
|
|
21
21
|
Commands:
|
|
22
22
|
init Set up allowance, funding, and check tier status
|
|
23
|
+
status Show full account state (allowance, balance, tier, projects)
|
|
23
24
|
allowance Manage your agent allowance (create, fund, balance, status)
|
|
24
25
|
tier Manage tier subscription (status, set)
|
|
25
26
|
projects Manage projects (provision, list, query, inspect, delete)
|
|
@@ -65,7 +66,12 @@ if (!cmd || cmd === '--help' || cmd === '-h') {
|
|
|
65
66
|
switch (cmd) {
|
|
66
67
|
case "init": {
|
|
67
68
|
const { run } = await import("./lib/init.mjs");
|
|
68
|
-
await run();
|
|
69
|
+
await run([sub, ...rest].filter(Boolean));
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "status": {
|
|
73
|
+
const { run } = await import("./lib/status.mjs");
|
|
74
|
+
await run([sub, ...rest].filter(Boolean));
|
|
69
75
|
break;
|
|
70
76
|
}
|
|
71
77
|
case "allowance": {
|
package/lib/deploy.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "fs";
|
|
2
|
-
import { API, allowanceAuthHeaders,
|
|
2
|
+
import { API, allowanceAuthHeaders, findProject } from "./config.mjs";
|
|
3
3
|
|
|
4
|
-
const HELP = `run402 deploy — Deploy
|
|
4
|
+
const HELP = `run402 deploy — Deploy to an existing project on Run402
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
7
|
run402 deploy [options]
|
|
@@ -9,11 +9,12 @@ Usage:
|
|
|
9
9
|
|
|
10
10
|
Options:
|
|
11
11
|
--manifest <file> Path to manifest JSON file (default: read from stdin)
|
|
12
|
+
--project <id> Project ID to deploy to (default: active project)
|
|
12
13
|
--help, -h Show this help message
|
|
13
14
|
|
|
14
15
|
Manifest format (JSON):
|
|
15
16
|
{
|
|
16
|
-
"
|
|
17
|
+
"project_id": "prj_...",
|
|
17
18
|
"migrations": "CREATE TABLE items (id serial PRIMARY KEY, title text NOT NULL, done boolean DEFAULT false)",
|
|
18
19
|
"rls": {
|
|
19
20
|
"template": "public_read_write",
|
|
@@ -28,7 +29,8 @@ Manifest format (JSON):
|
|
|
28
29
|
"subdomain": "my-app"
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
project_id is required (provision first with 'run402 provision').
|
|
33
|
+
All other fields are optional.
|
|
32
34
|
|
|
33
35
|
RLS templates:
|
|
34
36
|
user_owns_rows — users see only their rows (requires owner_column per table)
|
|
@@ -40,16 +42,18 @@ Manifest format (JSON):
|
|
|
40
42
|
|
|
41
43
|
Examples:
|
|
42
44
|
run402 deploy --manifest app.json
|
|
45
|
+
run402 deploy --manifest app.json --project prj_123_1
|
|
43
46
|
cat app.json | run402 deploy
|
|
44
47
|
|
|
45
48
|
Prerequisites:
|
|
46
49
|
- run402 init Set up allowance and funding
|
|
47
50
|
- run402 tier set prototype Subscribe to a tier
|
|
51
|
+
- run402 provision Provision a project first
|
|
48
52
|
|
|
49
53
|
Notes:
|
|
50
54
|
- Requires an active tier subscription (run402 tier set <tier>)
|
|
51
|
-
-
|
|
52
|
-
- Use 'run402 projects list' to see all
|
|
55
|
+
- Provision a project first with 'run402 provision', then deploy to it
|
|
56
|
+
- Use 'run402 projects list' to see all provisioned projects
|
|
53
57
|
`;
|
|
54
58
|
|
|
55
59
|
async function readStdin() {
|
|
@@ -59,25 +63,30 @@ async function readStdin() {
|
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
export async function run(args) {
|
|
62
|
-
const opts = { manifest: null };
|
|
66
|
+
const opts = { manifest: null, project: null };
|
|
63
67
|
for (let i = 0; i < args.length; i++) {
|
|
64
68
|
if (args[i] === "--help" || args[i] === "-h") { console.log(HELP); process.exit(0); }
|
|
65
69
|
if (args[i] === "--manifest" && args[i + 1]) opts.manifest = args[++i];
|
|
70
|
+
if (args[i] === "--project" && args[i + 1]) opts.project = args[++i];
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
const manifest = opts.manifest ? JSON.parse(readFileSync(opts.manifest, "utf-8")) : JSON.parse(await readStdin());
|
|
69
74
|
|
|
75
|
+
// --project flag overrides manifest's project_id
|
|
76
|
+
if (opts.project) manifest.project_id = opts.project;
|
|
77
|
+
|
|
78
|
+
// If no project_id in manifest, use active project
|
|
79
|
+
if (!manifest.project_id) {
|
|
80
|
+
const { id } = findProject(null);
|
|
81
|
+
manifest.project_id = id;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Remove legacy 'name' field if present
|
|
85
|
+
delete manifest.name;
|
|
86
|
+
|
|
70
87
|
const authHeaders = allowanceAuthHeaders("/deploy/v1");
|
|
71
88
|
const res = await fetch(`${API}/deploy/v1`, { method: "POST", headers: { "Content-Type": "application/json", ...authHeaders }, body: JSON.stringify(manifest) });
|
|
72
89
|
const result = await res.json();
|
|
73
90
|
if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...result })); process.exit(1); }
|
|
74
|
-
if (result.project_id) {
|
|
75
|
-
saveProject(result.project_id, {
|
|
76
|
-
anon_key: result.anon_key, service_key: result.service_key,
|
|
77
|
-
site_url: result.site_url || result.subdomain_url,
|
|
78
|
-
deployed_at: new Date().toISOString(),
|
|
79
|
-
});
|
|
80
|
-
setActiveProjectId(result.project_id);
|
|
81
|
-
}
|
|
82
91
|
console.log(JSON.stringify(result, null, 2));
|
|
83
92
|
}
|
package/lib/init.mjs
CHANGED
|
@@ -5,10 +5,27 @@ import { mkdirSync } from "fs";
|
|
|
5
5
|
const USDC_ABI = [{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }];
|
|
6
6
|
const USDC_SEPOLIA = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
|
|
7
7
|
|
|
8
|
+
const HELP = `run402 init — Set up allowance, funding, and check tier status
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
run402 init
|
|
12
|
+
|
|
13
|
+
Steps (idempotent — safe to re-run):
|
|
14
|
+
1. Creates config directory (~/.config/run402)
|
|
15
|
+
2. Creates agent allowance if none exists
|
|
16
|
+
3. Checks on-chain USDC balance; requests faucet if zero
|
|
17
|
+
4. Shows current tier subscription status
|
|
18
|
+
5. Lists local project count
|
|
19
|
+
6. Suggests next step (tier set or deploy)
|
|
20
|
+
|
|
21
|
+
Run this once to get started, or again to check your setup.
|
|
22
|
+
`;
|
|
23
|
+
|
|
8
24
|
function short(addr) { return addr.slice(0, 6) + "..." + addr.slice(-4); }
|
|
9
25
|
function line(label, value) { console.log(` ${label.padEnd(10)} ${value}`); }
|
|
10
26
|
|
|
11
|
-
export async function run() {
|
|
27
|
+
export async function run(args = []) {
|
|
28
|
+
if (args.includes("--help") || args.includes("-h")) { console.log(HELP); process.exit(0); }
|
|
12
29
|
console.log();
|
|
13
30
|
|
|
14
31
|
// 1. Config directory
|
package/lib/status.mjs
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readAllowance, loadKeyStore, getActiveProjectId, API } from "./config.mjs";
|
|
2
|
+
import { getAllowanceAuthHeaders } from "../core-dist/allowance-auth.js";
|
|
3
|
+
|
|
4
|
+
const HELP = `run402 status — Show full account state in one shot
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
run402 status
|
|
8
|
+
|
|
9
|
+
Displays:
|
|
10
|
+
- Allowance address and funding status
|
|
11
|
+
- Billing balance (available + held)
|
|
12
|
+
- Tier subscription (name, status, expiry)
|
|
13
|
+
- Projects (from server, with fallback to local keystore)
|
|
14
|
+
- Active project ID
|
|
15
|
+
|
|
16
|
+
Output is JSON. Requires an existing allowance (run 'run402 init' first).
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export async function run(args = []) {
|
|
20
|
+
if (args.includes("--help") || args.includes("-h")) { console.log(HELP); process.exit(0); }
|
|
21
|
+
const allowance = readAllowance();
|
|
22
|
+
if (!allowance) {
|
|
23
|
+
console.log(JSON.stringify({ status: "no_allowance", message: "No agent allowance found. Run: run402 init" }));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const wallet = allowance.address.toLowerCase();
|
|
28
|
+
const authHeaders = getAllowanceAuthHeaders("/tiers/v1/status");
|
|
29
|
+
|
|
30
|
+
// Parallel API calls: tier + billing balance + server-side projects
|
|
31
|
+
const [tierRes, balanceRes, projectsRes] = await Promise.all([
|
|
32
|
+
authHeaders
|
|
33
|
+
? fetch(`${API}/tiers/v1/status`, { headers: { ...authHeaders } }).catch(() => null)
|
|
34
|
+
: null,
|
|
35
|
+
fetch(`${API}/billing/v1/accounts/${wallet}`).catch(() => null),
|
|
36
|
+
fetch(`${API}/wallets/v1/${wallet}/projects`).catch(() => null),
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
const tier = tierRes?.ok ? await tierRes.json() : null;
|
|
40
|
+
const billing = balanceRes?.ok ? await balanceRes.json() : null;
|
|
41
|
+
const remote = projectsRes?.ok ? await projectsRes.json() : null;
|
|
42
|
+
|
|
43
|
+
// Local keystore
|
|
44
|
+
const store = loadKeyStore();
|
|
45
|
+
const activeId = getActiveProjectId();
|
|
46
|
+
|
|
47
|
+
const result = {
|
|
48
|
+
allowance: {
|
|
49
|
+
address: allowance.address,
|
|
50
|
+
funded: allowance.funded || false,
|
|
51
|
+
},
|
|
52
|
+
tier: tier && tier.tier
|
|
53
|
+
? { name: tier.tier, status: tier.status, expires: tier.lease_expires_at }
|
|
54
|
+
: null,
|
|
55
|
+
balance: billing && billing.exists
|
|
56
|
+
? { available_usd_micros: billing.available_usd_micros, held_usd_micros: billing.held_usd_micros }
|
|
57
|
+
: null,
|
|
58
|
+
projects: remote?.projects || Object.keys(store.projects).map(id => ({ id })),
|
|
59
|
+
active_project: activeId || null,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
console.log(JSON.stringify(result, null, 2));
|
|
63
|
+
}
|
package/package.json
CHANGED