Skip to content

Commit c75211b

Browse files
MajorTalclaude
andcommitted
Add run402 projects info <id> command
Shows REST URL, anon_key, service_key, tier, active status, and expiry in one shot — no more piecing it together from projects.json. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 93f93da commit c75211b

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

cli/lib/projects.mjs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Subcommands:
99
quote Show pricing tiers
1010
provision [--tier <tier>] [--name <n>] Provision a new Postgres project (pays via x402)
1111
list List all your projects (IDs, tiers, URLs, expiry)
12+
info <id> Show project details: REST URL, keys, expiry
1213
sql <id> "<query>" Run a SQL query against a project's Postgres DB
1314
rest <id> <table> [params] Query a table via the REST API (PostgREST)
1415
usage <id> Show compute/storage usage for a project
@@ -21,6 +22,7 @@ Examples:
2122
run402 projects provision --tier prototype
2223
run402 projects provision --tier hobby --name my-app
2324
run402 projects list
25+
run402 projects info abc123
2426
run402 projects sql abc123 "SELECT * FROM users LIMIT 5"
2527
run402 projects rest abc123 users "limit=10&select=id,name"
2628
run402 projects usage abc123
@@ -89,6 +91,22 @@ async function list() {
8991
console.log(JSON.stringify(entries.map(([id, p]) => ({ project_id: id, tier: p.tier, site_url: p.site_url, lease_expires_at: p.lease_expires_at, deployed_at: p.deployed_at })), null, 2));
9092
}
9193

94+
async function info(projectId) {
95+
const p = findProject(projectId);
96+
const active = p.lease_expires_at ? new Date(p.lease_expires_at) > new Date() : null;
97+
console.log(JSON.stringify({
98+
project_id: projectId,
99+
tier: p.tier,
100+
active,
101+
lease_expires_at: p.lease_expires_at,
102+
rest_url: `${API}/rest/v1`,
103+
anon_key: p.anon_key,
104+
service_key: p.service_key,
105+
site_url: p.site_url || null,
106+
deployed_at: p.deployed_at || null,
107+
}, null, 2));
108+
}
109+
92110
async function sqlCmd(projectId, query) {
93111
const p = findProject(projectId);
94112
const res = await fetch(`${API}/projects/v1/admin/${projectId}/sql`, { method: "POST", headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "text/plain" }, body: query });
@@ -138,6 +156,7 @@ export async function run(sub, args) {
138156
case "quote": await quote(); break;
139157
case "provision": await provision(args); break;
140158
case "list": await list(); break;
159+
case "info": await info(args[0]); break;
141160
case "sql": await sqlCmd(args[0], args[1]); break;
142161
case "rest": await rest(args[0], args[1], args[2]); break;
143162
case "usage": await usage(args[0]); break;

sync.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const SURFACE: Capability[] = [
188188
// ── Billing ──────────────────────────────────────────────────────────────
189189
{ id: "check_balance", endpoint: "GET /billing/v1/accounts/:wallet", mcp: "check_balance", cli: "allowance:balance", openclaw: "allowance:balance" },
190190
{ id: "list_projects", endpoint: "GET /wallets/v1/:wallet/projects", mcp: "list_projects", cli: "projects:list", openclaw: "projects:list" },
191+
{ id: "project_info", endpoint: "(local)", mcp: null, cli: "projects:info", openclaw: "projects:info" },
191192

192193
// ── Image generation ─────────────────────────────────────────────────────
193194
{ id: "generate_image", endpoint: "POST /generate-image/v1", mcp: "generate_image", cli: "image:generate", openclaw: "image:generate" },

0 commit comments

Comments
 (0)