run402 1.39.0 → 1.40.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/lib/agent.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import { API, allowanceAuthHeaders } from "./config.mjs";
1
+ import { allowanceAuthHeaders } from "./config.mjs";
2
+ import { getSdk } from "./sdk.mjs";
3
+ import { reportSdkError } from "./sdk-errors.mjs";
2
4
 
3
5
  const HELP = `run402 agent — Manage agent identity
4
6
 
@@ -23,20 +25,19 @@ async function contact(args) {
23
25
  if (args[i] === "--webhook" && args[i + 1]) webhook = args[++i];
24
26
  }
25
27
  if (!name) { console.error(JSON.stringify({ status: "error", message: "Missing --name <name>" })); process.exit(1); }
26
- const authHeaders = allowanceAuthHeaders("/agent/v1/contact");
27
-
28
- const body = { name };
29
- if (email) body.email = email;
30
- if (webhook) body.webhook = webhook;
31
-
32
- const res = await fetch(`${API}/agent/v1/contact`, {
33
- method: "POST",
34
- headers: { "Content-Type": "application/json", ...authHeaders },
35
- body: JSON.stringify(body),
36
- });
37
- const data = await res.json();
38
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
39
- console.log(JSON.stringify(data, null, 2));
28
+ // Preserve the aggressive early exit when no allowance is configured.
29
+ allowanceAuthHeaders("/agent/v1/contact");
30
+
31
+ try {
32
+ const data = await getSdk().admin.setAgentContact({
33
+ name,
34
+ email: email ?? undefined,
35
+ webhook: webhook ?? undefined,
36
+ });
37
+ console.log(JSON.stringify(data, null, 2));
38
+ } catch (err) {
39
+ reportSdkError(err);
40
+ }
40
41
  }
41
42
 
42
43
  export async function run(sub, args) {
package/lib/ai.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import { findProject, resolveProjectId, API } from "./config.mjs";
1
+ import { resolveProjectId } from "./config.mjs";
2
+ import { getSdk } from "./sdk.mjs";
3
+ import { reportSdkError } from "./sdk-errors.mjs";
2
4
 
3
5
  const HELP = `run402 ai — AI translation and moderation tools
4
6
 
@@ -68,7 +70,6 @@ async function translate(args) {
68
70
  }
69
71
 
70
72
  const projectId = resolveProjectId(projectOpt || positional[0]);
71
- const p = findProject(projectId);
72
73
  text = positional[1] || null;
73
74
 
74
75
  const to = parseFlag(args, "--to");
@@ -78,19 +79,12 @@ async function translate(args) {
78
79
  if (!text) { console.error(JSON.stringify({ status: "error", message: "Text required. Usage: run402 ai translate <project_id> <text> --to <lang>" })); process.exit(1); }
79
80
  if (!to) { console.error(JSON.stringify({ status: "error", message: "--to <lang> is required" })); process.exit(1); }
80
81
 
81
- const body = { text, to };
82
- if (from) body.from = from;
83
- if (context) body.context = context;
84
-
85
- const res = await fetch(`${API}/ai/v1/translate`, {
86
- method: "POST",
87
- headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
88
- body: JSON.stringify(body),
89
- });
90
- const data = await res.json();
91
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
92
-
93
- console.log(JSON.stringify({ status: "ok", text: data.text, from: data.from, to: data.to }));
82
+ try {
83
+ const data = await getSdk().ai.translate(projectId, { text, to, from: from ?? undefined, context: context ?? undefined });
84
+ console.log(JSON.stringify({ status: "ok", text: data.text, from: data.from, to: data.to }));
85
+ } catch (err) {
86
+ reportSdkError(err);
87
+ }
94
88
  }
95
89
 
96
90
  async function moderate(args) {
@@ -105,20 +99,16 @@ async function moderate(args) {
105
99
  }
106
100
 
107
101
  const projectId = resolveProjectId(projectOpt || positional[0]);
108
- const p = findProject(projectId);
109
102
  text = positional[1] || null;
110
103
 
111
104
  if (!text) { console.error(JSON.stringify({ status: "error", message: "Text required. Usage: run402 ai moderate <project_id> <text>" })); process.exit(1); }
112
105
 
113
- const res = await fetch(`${API}/ai/v1/moderate`, {
114
- method: "POST",
115
- headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
116
- body: JSON.stringify({ text }),
117
- });
118
- const data = await res.json();
119
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
120
-
121
- console.log(JSON.stringify({ status: "ok", flagged: data.flagged, categories: data.categories, category_scores: data.category_scores }));
106
+ try {
107
+ const data = await getSdk().ai.moderate(projectId, text);
108
+ console.log(JSON.stringify({ status: "ok", flagged: data.flagged, categories: data.categories, category_scores: data.category_scores }));
109
+ } catch (err) {
110
+ reportSdkError(err);
111
+ }
122
112
  }
123
113
 
124
114
  async function usage(args) {
@@ -132,15 +122,13 @@ async function usage(args) {
132
122
  }
133
123
 
134
124
  const projectId = resolveProjectId(projectOpt || positional[0]);
135
- const p = findProject(projectId);
136
-
137
- const res = await fetch(`${API}/ai/v1/usage`, {
138
- headers: { "Authorization": `Bearer ${p.service_key}` },
139
- });
140
- const data = await res.json();
141
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
142
125
 
143
- console.log(JSON.stringify({ status: "ok", ...data }));
126
+ try {
127
+ const data = await getSdk().ai.usage(projectId);
128
+ console.log(JSON.stringify({ status: "ok", ...data }));
129
+ } catch (err) {
130
+ reportSdkError(err);
131
+ }
144
132
  }
145
133
 
146
134
  export async function run(sub, args) {
package/lib/allowance.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import { readAllowance, saveAllowance, ALLOWANCE_FILE, API } from "./config.mjs";
2
+ import { getSdk } from "./sdk.mjs";
3
+ import { reportSdkError } from "./sdk-errors.mjs";
2
4
 
3
5
  const HELP = `run402 allowance — Manage your agent allowance
4
6
 
@@ -76,24 +78,43 @@ async function loadDeps() {
76
78
  }
77
79
 
78
80
  async function status() {
79
- const w = readAllowance();
80
- if (!w) {
81
- console.log(JSON.stringify({ status: "no_wallet", message: "No agent allowance found. Run: run402 allowance create" }));
82
- return;
81
+ try {
82
+ const data = await getSdk().allowance.status();
83
+ if (!data.configured) {
84
+ console.log(JSON.stringify({ status: "no_wallet", message: "No agent allowance found. Run: run402 allowance create" }));
85
+ return;
86
+ }
87
+ // Preserve CLI's rail field (SDK doesn't surface it; read from local allowance).
88
+ const w = readAllowance();
89
+ console.log(JSON.stringify({
90
+ status: "ok",
91
+ address: data.address,
92
+ created: data.created,
93
+ funded: data.funded || false,
94
+ rail: w?.rail || "x402",
95
+ path: data.path ?? ALLOWANCE_FILE,
96
+ }));
97
+ } catch (err) {
98
+ reportSdkError(err);
83
99
  }
84
- console.log(JSON.stringify({ status: "ok", address: w.address, created: w.created, funded: w.funded || false, rail: w.rail || "x402", path: ALLOWANCE_FILE }));
85
100
  }
86
101
 
87
102
  async function create() {
88
- if (readAllowance()) {
89
- console.log(JSON.stringify({ status: "error", message: "Agent allowance already exists. Use 'status' to check it." }));
90
- process.exit(1);
103
+ try {
104
+ const result = await getSdk().allowance.create();
105
+ console.log(JSON.stringify({
106
+ status: "ok",
107
+ address: result.address,
108
+ message: `Agent allowance created. Stored locally at ${result.path ?? ALLOWANCE_FILE}`,
109
+ }));
110
+ } catch (err) {
111
+ const msg = (err instanceof Error) ? err.message : String(err);
112
+ if (/already exists/i.test(msg)) {
113
+ console.log(JSON.stringify({ status: "error", message: "Agent allowance already exists. Use 'status' to check it." }));
114
+ process.exit(1);
115
+ }
116
+ reportSdkError(err);
91
117
  }
92
- const { generatePrivateKey, privateKeyToAccount } = await loadDeps();
93
- const privateKey = generatePrivateKey();
94
- const account = privateKeyToAccount(privateKey);
95
- saveAllowance({ address: account.address, privateKey, created: new Date().toISOString(), funded: false });
96
- console.log(JSON.stringify({ status: "ok", address: account.address, message: `Agent allowance created. Stored locally at ${ALLOWANCE_FILE}` }));
97
118
  }
98
119
 
99
120
  async function fund() {
@@ -199,9 +220,13 @@ async function balance() {
199
220
  }
200
221
 
201
222
  async function exportAddr() {
202
- const w = readAllowance();
203
- if (!w) { console.log(JSON.stringify({ status: "error", message: "No agent allowance." })); process.exit(1); }
204
- console.log(w.address);
223
+ try {
224
+ const address = await getSdk().allowance.export();
225
+ console.log(address);
226
+ } catch {
227
+ console.log(JSON.stringify({ status: "error", message: "No agent allowance." }));
228
+ process.exit(1);
229
+ }
205
230
  }
206
231
 
207
232
  async function checkout(args) {
package/lib/apps.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import { findProject, API, allowanceAuthHeaders, saveProject } from "./config.mjs";
1
+ import { allowanceAuthHeaders, saveProject } from "./config.mjs";
2
+ import { getSdk } from "./sdk.mjs";
3
+ import { reportSdkError } from "./sdk-errors.mjs";
2
4
 
3
5
  const HELP = `run402 apps — Browse and manage the app marketplace
4
6
 
@@ -101,16 +103,16 @@ Examples:
101
103
  };
102
104
 
103
105
  async function browse(args) {
104
- let url = `${API}/apps/v1`;
105
106
  const tags = [];
106
107
  for (let i = 0; i < args.length; i++) {
107
108
  if (args[i] === "--tag" && args[i + 1]) tags.push(args[++i]);
108
109
  }
109
- if (tags.length > 0) url += "?" + tags.map(t => `tag=${encodeURIComponent(t)}`).join("&");
110
- const res = await fetch(url);
111
- const data = await res.json();
112
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
113
- console.log(JSON.stringify(data, null, 2));
110
+ try {
111
+ const data = await getSdk().apps.browse(tags.length > 0 ? tags : undefined);
112
+ console.log(JSON.stringify(data, null, 2));
113
+ } catch (err) {
114
+ reportSdkError(err);
115
+ }
114
116
  }
115
117
 
116
118
  async function fork(versionId, name, args) {
@@ -119,33 +121,34 @@ async function fork(versionId, name, args) {
119
121
  if (args[i] === "--tier" && args[i + 1]) opts.tier = args[++i];
120
122
  if (args[i] === "--subdomain" && args[i + 1]) opts.subdomain = args[++i];
121
123
  }
122
- const authHeaders = allowanceAuthHeaders("/fork/v1");
123
-
124
- const body = { version_id: versionId, name };
125
- if (opts.subdomain) body.subdomain = opts.subdomain;
126
-
127
- const res = await fetch(`${API}/fork/v1`, {
128
- method: "POST",
129
- headers: { "Content-Type": "application/json", ...authHeaders },
130
- body: JSON.stringify(body),
131
- });
132
- const data = await res.json();
133
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
134
-
135
- // Save project credentials locally
136
- if (data.project_id) {
137
- saveProject(data.project_id, {
138
- anon_key: data.anon_key, service_key: data.service_key,
139
- tier: data.tier, lease_expires_at: data.lease_expires_at,
140
- site_url: data.site_url || data.subdomain_url,
141
- deployed_at: new Date().toISOString(),
124
+ // Preserve the aggressive early exit when no allowance is configured.
125
+ allowanceAuthHeaders("/fork/v1");
126
+
127
+ try {
128
+ const data = await getSdk().apps.fork({
129
+ versionId,
130
+ name,
131
+ subdomain: opts.subdomain,
142
132
  });
133
+
134
+ // SDK persists via the Node provider's saveProject/setActiveProject; we
135
+ // mirror the old CLI behavior here (deployed_at + site_url surfaced from
136
+ // the fork response) with a follow-up updateProject for the extra fields.
137
+ if (data.project_id) {
138
+ saveProject(data.project_id, {
139
+ anon_key: data.anon_key,
140
+ service_key: data.service_key,
141
+ site_url: data.site_url || data.subdomain_url,
142
+ deployed_at: new Date().toISOString(),
143
+ });
144
+ }
145
+ console.log(JSON.stringify(data, null, 2));
146
+ } catch (err) {
147
+ reportSdkError(err);
143
148
  }
144
- console.log(JSON.stringify(data, null, 2));
145
149
  }
146
150
 
147
151
  async function publish(projectId, args) {
148
- const p = findProject(projectId);
149
152
  const opts = { description: undefined, tags: undefined, visibility: undefined, forkAllowed: undefined };
150
153
  for (let i = 0; i < args.length; i++) {
151
154
  if (args[i] === "--description" && args[i + 1]) opts.description = args[++i];
@@ -153,72 +156,61 @@ async function publish(projectId, args) {
153
156
  if (args[i] === "--visibility" && args[i + 1]) opts.visibility = args[++i];
154
157
  if (args[i] === "--fork-allowed") opts.forkAllowed = true;
155
158
  }
156
- const body = {};
157
- if (opts.description) body.description = opts.description;
158
- if (opts.tags) body.tags = opts.tags;
159
- if (opts.visibility) body.visibility = opts.visibility;
160
- if (opts.forkAllowed !== undefined) body.fork_allowed = opts.forkAllowed;
161
-
162
- const res = await fetch(`${API}/projects/v1/admin/${projectId}/publish`, {
163
- method: "POST",
164
- headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
165
- body: JSON.stringify(body),
166
- });
167
- const data = await res.json();
168
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
169
- console.log(JSON.stringify(data, null, 2));
159
+ try {
160
+ const data = await getSdk().apps.publish(projectId, {
161
+ description: opts.description,
162
+ tags: opts.tags,
163
+ visibility: opts.visibility,
164
+ fork_allowed: opts.forkAllowed,
165
+ });
166
+ console.log(JSON.stringify(data, null, 2));
167
+ } catch (err) {
168
+ reportSdkError(err);
169
+ }
170
170
  }
171
171
 
172
172
  async function versions(projectId) {
173
- const p = findProject(projectId);
174
- const res = await fetch(`${API}/projects/v1/admin/${projectId}/versions`, {
175
- headers: { "Authorization": `Bearer ${p.service_key}` },
176
- });
177
- const data = await res.json();
178
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
179
- console.log(JSON.stringify(data, null, 2));
173
+ try {
174
+ const data = await getSdk().apps.listVersions(projectId);
175
+ console.log(JSON.stringify(data, null, 2));
176
+ } catch (err) {
177
+ reportSdkError(err);
178
+ }
180
179
  }
181
180
 
182
181
  async function inspect(versionId) {
183
182
  if (!versionId) { console.error(JSON.stringify({ status: "error", message: "Missing version ID" })); process.exit(1); }
184
- const res = await fetch(`${API}/apps/v1/${versionId}`);
185
- const data = await res.json();
186
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
187
- console.log(JSON.stringify(data, null, 2));
183
+ try {
184
+ const data = await getSdk().apps.getApp(versionId);
185
+ console.log(JSON.stringify(data, null, 2));
186
+ } catch (err) {
187
+ reportSdkError(err);
188
+ }
188
189
  }
189
190
 
190
191
  async function update(projectId, versionId, args) {
191
- const p = findProject(projectId);
192
- const body = {};
192
+ const opts = {};
193
193
  for (let i = 0; i < args.length; i++) {
194
- if (args[i] === "--description" && args[i + 1]) body.description = args[++i];
195
- if (args[i] === "--tags" && args[i + 1]) body.tags = args[++i].split(",");
196
- if (args[i] === "--visibility" && args[i + 1]) body.visibility = args[++i];
197
- if (args[i] === "--fork-allowed") body.fork_allowed = true;
198
- if (args[i] === "--no-fork") body.fork_allowed = false;
194
+ if (args[i] === "--description" && args[i + 1]) opts.description = args[++i];
195
+ if (args[i] === "--tags" && args[i + 1]) opts.tags = args[++i].split(",");
196
+ if (args[i] === "--visibility" && args[i + 1]) opts.visibility = args[++i];
197
+ if (args[i] === "--fork-allowed") opts.fork_allowed = true;
198
+ if (args[i] === "--no-fork") opts.fork_allowed = false;
199
+ }
200
+ try {
201
+ await getSdk().apps.updateVersion(projectId, versionId, opts);
202
+ console.log(JSON.stringify({ status: "ok", project_id: projectId, version_id: versionId }));
203
+ } catch (err) {
204
+ reportSdkError(err);
199
205
  }
200
- const res = await fetch(`${API}/projects/v1/admin/${projectId}/versions/${versionId}`, {
201
- method: "PATCH",
202
- headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
203
- body: JSON.stringify(body),
204
- });
205
- const data = await res.json();
206
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
207
- console.log(JSON.stringify(data, null, 2));
208
206
  }
209
207
 
210
208
  async function deleteVersion(projectId, versionId) {
211
- const p = findProject(projectId);
212
- const res = await fetch(`${API}/projects/v1/admin/${projectId}/versions/${versionId}`, {
213
- method: "DELETE",
214
- headers: { "Authorization": `Bearer ${p.service_key}` },
215
- });
216
- if (res.status === 204 || res.ok) {
209
+ try {
210
+ await getSdk().apps.deleteVersion(projectId, versionId);
217
211
  console.log(JSON.stringify({ status: "ok", message: `Version ${versionId} deleted.` }));
218
- } else {
219
- const data = await res.json();
220
- console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
221
- process.exit(1);
212
+ } catch (err) {
213
+ reportSdkError(err);
222
214
  }
223
215
  }
224
216
 
package/lib/auth.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import { findProject, resolveProjectId, API } from "./config.mjs";
2
+ import { getSdk } from "./sdk.mjs";
3
+ import { reportSdkError } from "./sdk-errors.mjs";
2
4
 
3
5
  const HELP = `run402 auth — Manage project user authentication
4
6
 
@@ -118,50 +120,30 @@ async function magicLink(args) {
118
120
  const email = parseFlag(args, "--email");
119
121
  const redirect = parseFlag(args, "--redirect");
120
122
  const projectId = resolveProjectId(parseFlag(args, "--project"));
121
- const p = findProject(projectId);
122
123
 
123
124
  if (!email) { console.error(JSON.stringify({ status: "error", message: "Missing --email" })); process.exit(1); }
124
125
  if (!redirect) { console.error(JSON.stringify({ status: "error", message: "Missing --redirect <url>" })); process.exit(1); }
125
126
 
126
- const res = await fetch(`${API}/auth/v1/magic-link`, {
127
- method: "POST",
128
- headers: {
129
- "apikey": p.anon_key,
130
- "Authorization": `Bearer ${p.anon_key}`,
131
- "Content-Type": "application/json",
132
- },
133
- body: JSON.stringify({ email, redirect_url: redirect }),
134
- });
135
- const data = await res.json();
136
- if (!res.ok) {
137
- console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
138
- process.exit(1);
127
+ try {
128
+ await getSdk().auth.requestMagicLink(projectId, { email, redirectUrl: redirect });
129
+ console.log(JSON.stringify({ status: "ok", email, redirect_url: redirect }));
130
+ } catch (err) {
131
+ reportSdkError(err);
139
132
  }
140
- console.log(JSON.stringify({ status: "ok", ...data }));
141
133
  }
142
134
 
143
135
  async function verify(args) {
144
136
  const token = parseFlag(args, "--token");
145
137
  const projectId = resolveProjectId(parseFlag(args, "--project"));
146
- const p = findProject(projectId);
147
138
 
148
139
  if (!token) { console.error(JSON.stringify({ status: "error", message: "Missing --token" })); process.exit(1); }
149
140
 
150
- const res = await fetch(`${API}/auth/v1/token?grant_type=magic_link`, {
151
- method: "POST",
152
- headers: {
153
- "apikey": p.anon_key,
154
- "Authorization": `Bearer ${p.anon_key}`,
155
- "Content-Type": "application/json",
156
- },
157
- body: JSON.stringify({ token }),
158
- });
159
- const data = await res.json();
160
- if (!res.ok) {
161
- console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
162
- process.exit(1);
141
+ try {
142
+ const data = await getSdk().auth.verifyMagicLink(projectId, token);
143
+ console.log(JSON.stringify({ status: "ok", ...data }));
144
+ } catch (err) {
145
+ reportSdkError(err);
163
146
  }
164
- console.log(JSON.stringify({ status: "ok", ...data }));
165
147
  }
166
148
 
167
149
  async function setPassword(args) {
@@ -169,59 +151,38 @@ async function setPassword(args) {
169
151
  const newPassword = parseFlag(args, "--new");
170
152
  const currentPassword = parseFlag(args, "--current");
171
153
  const projectId = resolveProjectId(parseFlag(args, "--project"));
172
- const p = findProject(projectId);
173
154
 
174
155
  if (!accessToken) { console.error(JSON.stringify({ status: "error", message: "Missing --token <bearer_token>" })); process.exit(1); }
175
156
  if (!newPassword) { console.error(JSON.stringify({ status: "error", message: "Missing --new <password>" })); process.exit(1); }
176
157
 
177
- const body = { new_password: newPassword };
178
- if (currentPassword) body.current_password = currentPassword;
179
-
180
- // /auth/v1/* is gated by apikeyAuth middleware: the `apikey` header must be
181
- // the project's anon_key. `Authorization: Bearer <access_token>` stays as
182
- // the user's identity so the server knows whose password to change.
183
- const res = await fetch(`${API}/auth/v1/user/password`, {
184
- method: "PUT",
185
- headers: {
186
- "apikey": p.anon_key,
187
- "Authorization": `Bearer ${accessToken}`,
188
- "Content-Type": "application/json",
189
- },
190
- body: JSON.stringify(body),
191
- });
192
- const data = await res.json();
193
- if (!res.ok) {
194
- console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
195
- process.exit(1);
158
+ try {
159
+ await getSdk().auth.setUserPassword(projectId, {
160
+ accessToken,
161
+ newPassword,
162
+ currentPassword: currentPassword ?? undefined,
163
+ });
164
+ console.log(JSON.stringify({ status: "ok" }));
165
+ } catch (err) {
166
+ reportSdkError(err);
196
167
  }
197
- console.log(JSON.stringify({ status: "ok", ...data }));
198
168
  }
199
169
 
200
170
  async function settings(args) {
201
171
  const allowPasswordSet = parseFlag(args, "--allow-password-set");
202
172
  const projectId = resolveProjectId(parseFlag(args, "--project"));
203
- const p = findProject(projectId);
204
173
 
205
174
  if (allowPasswordSet === null) { console.error(JSON.stringify({ status: "error", message: "Missing --allow-password-set <true|false>" })); process.exit(1); }
206
175
 
207
- const res = await fetch(`${API}/auth/v1/settings`, {
208
- method: "PATCH",
209
- headers: {
210
- "apikey": p.anon_key,
211
- "Authorization": `Bearer ${p.service_key}`,
212
- "Content-Type": "application/json",
213
- },
214
- body: JSON.stringify({ allow_password_set: allowPasswordSet === "true" }),
215
- });
216
- const data = await res.json();
217
- if (!res.ok) {
218
- console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
219
- process.exit(1);
176
+ try {
177
+ await getSdk().auth.settings(projectId, { allow_password_set: allowPasswordSet === "true" });
178
+ console.log(JSON.stringify({ status: "ok", allow_password_set: allowPasswordSet === "true" }));
179
+ } catch (err) {
180
+ reportSdkError(err);
220
181
  }
221
- console.log(JSON.stringify({ status: "ok", ...data }));
222
182
  }
223
183
 
224
184
  async function providers(args) {
185
+ // `providers` isn't in the pilot SDK surface — keep the direct fetch.
225
186
  const projectId = resolveProjectId(parseFlag(args, "--project"));
226
187
  const p = findProject(projectId);
227
188