auth 1.5.5 → 1.5.6
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/dist/index.mjs +645 -100
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,39 +1,584 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
+
import { exec, execSync, spawn } from "node:child_process";
|
|
3
4
|
import * as fs$2 from "node:fs";
|
|
4
5
|
import fs, { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
|
-
import
|
|
6
|
+
import * as os$1 from "node:os";
|
|
7
|
+
import os from "node:os";
|
|
6
8
|
import * as path$1 from "node:path";
|
|
7
9
|
import path, { join } from "node:path";
|
|
8
|
-
import { createTelemetry, getTelemetryAuthConfig } from "@better-auth/telemetry";
|
|
9
|
-
import { getAdapter } from "better-auth/db/adapter";
|
|
10
10
|
import chalk from "chalk";
|
|
11
11
|
import prompts from "prompts";
|
|
12
12
|
import yoctoSpinner from "yocto-spinner";
|
|
13
|
-
import
|
|
13
|
+
import fs$1 from "node:fs/promises";
|
|
14
|
+
import { createTelemetry, getTelemetryAuthConfig } from "@better-auth/telemetry";
|
|
15
|
+
import { getAdapter } from "better-auth/db/adapter";
|
|
16
|
+
import * as z from "zod";
|
|
14
17
|
import { initGetFieldName, initGetModelName } from "better-auth/adapters";
|
|
15
18
|
import { getAuthTables } from "better-auth/db";
|
|
16
19
|
import prettier, { format } from "prettier";
|
|
17
20
|
import { getMigrations } from "better-auth/db/migration";
|
|
18
21
|
import { capitalizeFirstLetter } from "@better-auth/core/utils/string";
|
|
19
22
|
import { produceSchema } from "@mrleebo/prisma-ast";
|
|
20
|
-
import { exec, execSync, spawn } from "node:child_process";
|
|
21
23
|
import Crypto from "node:crypto";
|
|
22
24
|
import babelPresetReact from "@babel/preset-react";
|
|
23
25
|
import babelPresetTypeScript from "@babel/preset-typescript";
|
|
24
26
|
import { BetterAuthError } from "@better-auth/core/error";
|
|
25
27
|
import { loadConfig } from "c12";
|
|
26
28
|
import { getTsconfig, parseTsconfig } from "get-tsconfig";
|
|
27
|
-
import * as os$1 from "node:os";
|
|
28
|
-
import os from "node:os";
|
|
29
29
|
import open from "open";
|
|
30
|
-
import z from "zod";
|
|
31
30
|
import { env } from "@better-auth/core/env";
|
|
32
31
|
import { log } from "@clack/prompts";
|
|
33
32
|
import { base64 } from "@better-auth/utils/base64";
|
|
34
33
|
import * as semver from "semver";
|
|
35
34
|
import "dotenv/config";
|
|
36
35
|
|
|
36
|
+
//#region src/commands/ai.ts
|
|
37
|
+
const PROTOCOL_URL = "https://agent-auth-protocol.com";
|
|
38
|
+
const AGENT_CLI_PKG = "@auth/agent-cli";
|
|
39
|
+
const AGENT_PLUGIN_PKG = "@better-auth/agent-auth";
|
|
40
|
+
const DEFAULT_REGISTRY = "https://agent-auth.directory";
|
|
41
|
+
const SKILLS_REPO = "better-auth/agent-auth";
|
|
42
|
+
function cancelled() {
|
|
43
|
+
console.log(chalk.yellow("\n✋ Setup cancelled."));
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
function check(value) {
|
|
47
|
+
if (value === void 0 || value === null) cancelled();
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
async function aiAction() {
|
|
51
|
+
console.log("\n" + [
|
|
52
|
+
` ██ ████`,
|
|
53
|
+
` ████ ██ ${chalk.bold("Agent Auth")} ${chalk.dim("Setup")}`,
|
|
54
|
+
` ██ ████ ${chalk.gray("AI agent authentication & capability-based authorization.")}`
|
|
55
|
+
].join("\n"));
|
|
56
|
+
console.log();
|
|
57
|
+
const { setup } = await prompts({
|
|
58
|
+
type: "select",
|
|
59
|
+
name: "setup",
|
|
60
|
+
message: "What would you like to do?",
|
|
61
|
+
choices: [{
|
|
62
|
+
title: "Integrate Agent Auth client",
|
|
63
|
+
value: "client",
|
|
64
|
+
description: "MCP server, CLI, or SDK for your agents"
|
|
65
|
+
}, {
|
|
66
|
+
title: "Create an Agent Auth server",
|
|
67
|
+
value: "server",
|
|
68
|
+
description: "expose capabilities from your service to AI agents"
|
|
69
|
+
}]
|
|
70
|
+
});
|
|
71
|
+
check(setup);
|
|
72
|
+
if (setup === "client") await setupClient();
|
|
73
|
+
else await setupServerSelection();
|
|
74
|
+
}
|
|
75
|
+
async function setupClient() {
|
|
76
|
+
const { method } = await prompts({
|
|
77
|
+
type: "select",
|
|
78
|
+
name: "method",
|
|
79
|
+
message: "How do you want to integrate?",
|
|
80
|
+
choices: [{
|
|
81
|
+
title: "MCP Server",
|
|
82
|
+
value: "mcp",
|
|
83
|
+
description: "for AI tools — Claude, Cursor, Windsurf, etc."
|
|
84
|
+
}, {
|
|
85
|
+
title: "CLI",
|
|
86
|
+
value: "cli",
|
|
87
|
+
description: "command-line tool for agent workflows"
|
|
88
|
+
}]
|
|
89
|
+
});
|
|
90
|
+
check(method);
|
|
91
|
+
if (method === "mcp") await setupMcp();
|
|
92
|
+
else await setupCli();
|
|
93
|
+
}
|
|
94
|
+
async function setupServerSelection() {
|
|
95
|
+
const { implementation } = await prompts({
|
|
96
|
+
type: "select",
|
|
97
|
+
name: "implementation",
|
|
98
|
+
message: "Choose an implementation",
|
|
99
|
+
choices: [{
|
|
100
|
+
title: "Better Auth + Agent Auth",
|
|
101
|
+
value: "better-auth",
|
|
102
|
+
description: "TypeScript"
|
|
103
|
+
}]
|
|
104
|
+
});
|
|
105
|
+
check(implementation);
|
|
106
|
+
await setupServer();
|
|
107
|
+
}
|
|
108
|
+
async function setupMcp() {
|
|
109
|
+
const { tool } = await prompts({
|
|
110
|
+
type: "select",
|
|
111
|
+
name: "tool",
|
|
112
|
+
message: "Which AI tool?",
|
|
113
|
+
choices: [
|
|
114
|
+
{
|
|
115
|
+
title: "Cursor",
|
|
116
|
+
value: "cursor"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
title: "Claude Code",
|
|
120
|
+
value: "claude-code"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
title: "Claude Desktop",
|
|
124
|
+
value: "claude-desktop"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
title: "Windsurf",
|
|
128
|
+
value: "windsurf"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
title: "VS Code / Copilot",
|
|
132
|
+
value: "vscode"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
title: "Open Code",
|
|
136
|
+
value: "opencode"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
title: "Other",
|
|
140
|
+
value: "other"
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
check(tool);
|
|
145
|
+
let scope = "global";
|
|
146
|
+
if (tool === "cursor" || tool === "vscode") {
|
|
147
|
+
const { s } = await prompts({
|
|
148
|
+
type: "select",
|
|
149
|
+
name: "s",
|
|
150
|
+
message: "Where should it be configured?",
|
|
151
|
+
choices: [{
|
|
152
|
+
title: "This project",
|
|
153
|
+
value: "project",
|
|
154
|
+
description: tool === "cursor" ? ".cursor/mcp.json" : ".vscode/mcp.json"
|
|
155
|
+
}, {
|
|
156
|
+
title: "Global (all projects)",
|
|
157
|
+
value: "global",
|
|
158
|
+
description: tool === "cursor" ? "~/.cursor/mcp.json" : "user settings"
|
|
159
|
+
}]
|
|
160
|
+
});
|
|
161
|
+
check(s);
|
|
162
|
+
scope = s;
|
|
163
|
+
}
|
|
164
|
+
const { registryUrl } = await prompts({
|
|
165
|
+
type: "text",
|
|
166
|
+
name: "registryUrl",
|
|
167
|
+
message: "Registry URL",
|
|
168
|
+
initial: DEFAULT_REGISTRY
|
|
169
|
+
});
|
|
170
|
+
const mcpArgs = buildMcpArgs(registryUrl?.trim() || DEFAULT_REGISTRY);
|
|
171
|
+
if (tool === "claude-code") await setupClaudeCode(mcpArgs);
|
|
172
|
+
else if (tool === "opencode") await setupOpenCode(mcpArgs);
|
|
173
|
+
else if (tool === "other") showJsonConfig({
|
|
174
|
+
command: "npx",
|
|
175
|
+
args: mcpArgs
|
|
176
|
+
});
|
|
177
|
+
else await writeMcpConfigInteractive(tool, scope, mcpArgs);
|
|
178
|
+
await offerSkillInstall("agent-auth-mcp");
|
|
179
|
+
showNextSteps([`${chalk.cyan("Docs")} ${PROTOCOL_URL}/docs/integrate-client`, `${chalk.cyan("GitHub")} https://github.com/better-auth/agent-auth`]);
|
|
180
|
+
console.log(chalk.green("\n✔ ") + chalk.bold("Done! ") + "Restart your AI tool to connect.\n");
|
|
181
|
+
}
|
|
182
|
+
async function setupClaudeCode(args) {
|
|
183
|
+
const { scope } = await prompts({
|
|
184
|
+
type: "select",
|
|
185
|
+
name: "scope",
|
|
186
|
+
message: "Where should it be configured?",
|
|
187
|
+
choices: [{
|
|
188
|
+
title: "This project",
|
|
189
|
+
value: "project",
|
|
190
|
+
description: "--scope project"
|
|
191
|
+
}, {
|
|
192
|
+
title: "Global (all projects)",
|
|
193
|
+
value: "user",
|
|
194
|
+
description: "--scope user"
|
|
195
|
+
}]
|
|
196
|
+
});
|
|
197
|
+
check(scope);
|
|
198
|
+
const cmd = [
|
|
199
|
+
"claude",
|
|
200
|
+
"mcp",
|
|
201
|
+
"add",
|
|
202
|
+
"agent-auth",
|
|
203
|
+
"--scope",
|
|
204
|
+
scope,
|
|
205
|
+
"--",
|
|
206
|
+
"npx",
|
|
207
|
+
...args
|
|
208
|
+
].join(" ");
|
|
209
|
+
console.log(chalk.bold.white("\nRun this command:"));
|
|
210
|
+
console.log(chalk.cyan(` ${cmd}\n`));
|
|
211
|
+
const { run } = await prompts({
|
|
212
|
+
type: "confirm",
|
|
213
|
+
name: "run",
|
|
214
|
+
message: "Run it now?",
|
|
215
|
+
initial: true
|
|
216
|
+
});
|
|
217
|
+
if (run) {
|
|
218
|
+
const s = yoctoSpinner({
|
|
219
|
+
text: "Adding MCP server to Claude Code…",
|
|
220
|
+
color: "white"
|
|
221
|
+
});
|
|
222
|
+
s.start();
|
|
223
|
+
try {
|
|
224
|
+
execSync(cmd, { stdio: "pipe" });
|
|
225
|
+
s.success("Added to Claude Code.");
|
|
226
|
+
} catch {
|
|
227
|
+
s.stop();
|
|
228
|
+
console.log(chalk.yellow("⚠ Could not run the command automatically."));
|
|
229
|
+
console.log(chalk.gray(" Run the command above manually."));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async function setupOpenCode(args) {
|
|
234
|
+
const configPath = path$1.join(process.cwd(), "opencode.json");
|
|
235
|
+
const display = "opencode.json";
|
|
236
|
+
const openCodeEntry = {
|
|
237
|
+
type: "stdio",
|
|
238
|
+
command: "npx",
|
|
239
|
+
args,
|
|
240
|
+
enabled: true
|
|
241
|
+
};
|
|
242
|
+
const { write } = await prompts({
|
|
243
|
+
type: "confirm",
|
|
244
|
+
name: "write",
|
|
245
|
+
message: `Write config to ${chalk.cyan(display)}?`,
|
|
246
|
+
initial: true
|
|
247
|
+
});
|
|
248
|
+
if (write) {
|
|
249
|
+
writeOpenCodeConfig(configPath, openCodeEntry);
|
|
250
|
+
console.log(chalk.green(`\n✓ Written to ${display}`));
|
|
251
|
+
} else {
|
|
252
|
+
const json = JSON.stringify({
|
|
253
|
+
$schema: "https://opencode.ai/config.json",
|
|
254
|
+
mcp: { "agent-auth": openCodeEntry }
|
|
255
|
+
}, null, 2);
|
|
256
|
+
console.log(chalk.bold.white("\nAdd to your opencode.json:\n"));
|
|
257
|
+
console.log(json.split("\n").map((line) => chalk.cyan(` ${line}`)).join("\n"));
|
|
258
|
+
console.log();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function writeOpenCodeConfig(configPath, entry) {
|
|
262
|
+
let config = {};
|
|
263
|
+
if (fs$2.existsSync(configPath)) try {
|
|
264
|
+
config = JSON.parse(fs$2.readFileSync(configPath, "utf-8"));
|
|
265
|
+
} catch {}
|
|
266
|
+
const mcp = config.mcp ?? {};
|
|
267
|
+
mcp["agent-auth"] = entry;
|
|
268
|
+
config.$schema = "https://opencode.ai/config.json";
|
|
269
|
+
config.mcp = mcp;
|
|
270
|
+
fs$2.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
271
|
+
}
|
|
272
|
+
async function writeMcpConfigInteractive(tool, scope, args) {
|
|
273
|
+
const entry = {
|
|
274
|
+
command: "npx",
|
|
275
|
+
args
|
|
276
|
+
};
|
|
277
|
+
const configPath = getMcpConfigPath(tool, scope);
|
|
278
|
+
if (!configPath) {
|
|
279
|
+
showJsonConfig(entry);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const display = displayPath(configPath, scope);
|
|
283
|
+
const { write } = await prompts({
|
|
284
|
+
type: "confirm",
|
|
285
|
+
name: "write",
|
|
286
|
+
message: `Write config to ${chalk.cyan(display)}?`,
|
|
287
|
+
initial: true
|
|
288
|
+
});
|
|
289
|
+
if (write) {
|
|
290
|
+
writeMcpConfig(configPath, entry);
|
|
291
|
+
console.log(chalk.green(`\n✓ Written to ${display}`));
|
|
292
|
+
} else showJsonConfig(entry);
|
|
293
|
+
}
|
|
294
|
+
async function setupCli() {
|
|
295
|
+
const { installCli } = await prompts({
|
|
296
|
+
type: "confirm",
|
|
297
|
+
name: "installCli",
|
|
298
|
+
message: `Install ${chalk.cyan(AGENT_CLI_PKG)} globally?`,
|
|
299
|
+
initial: true
|
|
300
|
+
});
|
|
301
|
+
if (installCli) {
|
|
302
|
+
const s = yoctoSpinner({
|
|
303
|
+
text: `Installing ${AGENT_CLI_PKG}…`,
|
|
304
|
+
color: "white"
|
|
305
|
+
});
|
|
306
|
+
s.start();
|
|
307
|
+
try {
|
|
308
|
+
execSync(`npm install -g ${AGENT_CLI_PKG}`, { stdio: "pipe" });
|
|
309
|
+
s.success(`${AGENT_CLI_PKG} installed globally.`);
|
|
310
|
+
} catch {
|
|
311
|
+
s.stop();
|
|
312
|
+
console.log(chalk.yellow("⚠ Could not install automatically. Run manually:"));
|
|
313
|
+
console.log(chalk.cyan(` npm install -g ${AGENT_CLI_PKG}\n`));
|
|
314
|
+
}
|
|
315
|
+
} else console.log(chalk.dim(`\n To install later: npm install -g ${AGENT_CLI_PKG}\n`));
|
|
316
|
+
await offerSkillInstall("agent-auth-cli");
|
|
317
|
+
console.log(chalk.bold.white("\nUsage:"));
|
|
318
|
+
console.log(chalk.gray(" # Discover a provider"));
|
|
319
|
+
console.log(chalk.cyan(" auth-agent discover https://api.example.com"));
|
|
320
|
+
console.log(chalk.gray("\n # Search the registry for providers"));
|
|
321
|
+
console.log(chalk.cyan(` auth-agent search "send email"`));
|
|
322
|
+
console.log(chalk.gray("\n # Connect an agent with capabilities"));
|
|
323
|
+
console.log(chalk.cyan(" auth-agent connect --provider <url> --capabilities <cap1> <cap2>"));
|
|
324
|
+
console.log(chalk.gray("\n # Execute a capability"));
|
|
325
|
+
console.log(chalk.cyan(` auth-agent execute <agent-id> <capability> --args '{"key":"value"}'`));
|
|
326
|
+
console.log(chalk.gray("\n # Run as MCP server"));
|
|
327
|
+
console.log(chalk.cyan(` auth-agent mcp`));
|
|
328
|
+
showNextSteps([`${chalk.cyan("Docs")} ${PROTOCOL_URL}/docs/integrate-client`, `${chalk.cyan("GitHub")} https://github.com/better-auth/agent-auth`]);
|
|
329
|
+
console.log(chalk.green("\n✔ ") + chalk.bold("Ready. ") + "Run auth-agent --help to see all commands.\n");
|
|
330
|
+
}
|
|
331
|
+
async function setupServer() {
|
|
332
|
+
const { source } = await prompts({
|
|
333
|
+
type: "select",
|
|
334
|
+
name: "source",
|
|
335
|
+
message: "How do you want to define capabilities?",
|
|
336
|
+
choices: [
|
|
337
|
+
{
|
|
338
|
+
title: "Default",
|
|
339
|
+
value: "manual",
|
|
340
|
+
description: "define capabilities in code"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
title: "From an OpenAPI spec",
|
|
344
|
+
value: "openapi",
|
|
345
|
+
description: "derive capabilities from an OpenAPI document"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
title: "From an MCP server",
|
|
349
|
+
value: "mcp",
|
|
350
|
+
description: "proxy an existing MCP server's tools"
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
});
|
|
354
|
+
check(source);
|
|
355
|
+
const { name } = await prompts({
|
|
356
|
+
type: "text",
|
|
357
|
+
name: "name",
|
|
358
|
+
message: "What's your service called?",
|
|
359
|
+
validate: (v) => v?.trim() ? true : "Name is required."
|
|
360
|
+
});
|
|
361
|
+
check(name);
|
|
362
|
+
const { description } = await prompts({
|
|
363
|
+
type: "text",
|
|
364
|
+
name: "description",
|
|
365
|
+
message: `Short description ${chalk.dim("(press Enter to skip)")}`
|
|
366
|
+
});
|
|
367
|
+
const desc = description?.trim() || void 0;
|
|
368
|
+
let sourceUrl;
|
|
369
|
+
if (source === "openapi") {
|
|
370
|
+
const { url } = await prompts({
|
|
371
|
+
type: "text",
|
|
372
|
+
name: "url",
|
|
373
|
+
message: `OpenAPI spec URL ${chalk.dim("(e.g. https://api.example.com/openapi.json)")}`,
|
|
374
|
+
validate: (v) => v?.trim() ? true : "URL is required."
|
|
375
|
+
});
|
|
376
|
+
check(url);
|
|
377
|
+
sourceUrl = url.trim();
|
|
378
|
+
} else if (source === "mcp") {
|
|
379
|
+
const { url } = await prompts({
|
|
380
|
+
type: "text",
|
|
381
|
+
name: "url",
|
|
382
|
+
message: `MCP server URL ${chalk.dim("(e.g. https://api.example.com/mcp)")}`,
|
|
383
|
+
validate: (v) => v?.trim() ? true : "URL is required."
|
|
384
|
+
});
|
|
385
|
+
check(url);
|
|
386
|
+
sourceUrl = url.trim();
|
|
387
|
+
}
|
|
388
|
+
const code = generateServerCode(name.trim(), desc, source, sourceUrl);
|
|
389
|
+
const { write } = await prompts({
|
|
390
|
+
type: "confirm",
|
|
391
|
+
name: "write",
|
|
392
|
+
message: "Generate an auth config file?",
|
|
393
|
+
initial: true
|
|
394
|
+
});
|
|
395
|
+
if (write) {
|
|
396
|
+
const { filePath } = await prompts({
|
|
397
|
+
type: "text",
|
|
398
|
+
name: "filePath",
|
|
399
|
+
message: "File path",
|
|
400
|
+
initial: "lib/auth.ts"
|
|
401
|
+
});
|
|
402
|
+
const target = filePath?.trim() || "lib/auth.ts";
|
|
403
|
+
if (fs$2.existsSync(target)) {
|
|
404
|
+
const { overwrite } = await prompts({
|
|
405
|
+
type: "confirm",
|
|
406
|
+
name: "overwrite",
|
|
407
|
+
message: `${chalk.yellow(target)} already exists. Overwrite?`,
|
|
408
|
+
initial: false
|
|
409
|
+
});
|
|
410
|
+
if (!overwrite) {
|
|
411
|
+
showCodeBlock(code, "auth config");
|
|
412
|
+
showServerOutro();
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const dir = path$1.dirname(target);
|
|
417
|
+
if (dir && dir !== "." && !fs$2.existsSync(dir)) fs$2.mkdirSync(dir, { recursive: true });
|
|
418
|
+
fs$2.writeFileSync(target, code);
|
|
419
|
+
console.log(chalk.green(`\n✓ Created ${target}`));
|
|
420
|
+
} else showCodeBlock(code, "auth config");
|
|
421
|
+
showServerOutro();
|
|
422
|
+
}
|
|
423
|
+
function generateServerCode(name, description, source, sourceUrl) {
|
|
424
|
+
const descLine = description ? `\n\t\t\tproviderDescription: ${JSON.stringify(description)},` : "";
|
|
425
|
+
if (source === "openapi" && sourceUrl) return `import { betterAuth } from "better-auth";
|
|
426
|
+
import { agentAuth } from "${AGENT_PLUGIN_PKG}";
|
|
427
|
+
import { createFromOpenAPI } from "${AGENT_PLUGIN_PKG}/openapi";
|
|
428
|
+
|
|
429
|
+
const spec = await fetch(${JSON.stringify(sourceUrl)}).then(r => r.json());
|
|
430
|
+
|
|
431
|
+
const openapi = createFromOpenAPI(spec, {
|
|
432
|
+
\tbaseUrl: ${JSON.stringify(sourceUrl.replace(/\/openapi\.json$|\/openapi\.yaml$|\/swagger\.json$|\/docs\/openapi$/, ""))},
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
export const auth = betterAuth({
|
|
436
|
+
\tplugins: [
|
|
437
|
+
\t\tagentAuth({
|
|
438
|
+
\t\t\tproviderName: ${JSON.stringify(name)},${descLine}
|
|
439
|
+
\t\t\t...openapi,
|
|
440
|
+
\t\t}),
|
|
441
|
+
\t],
|
|
442
|
+
});
|
|
443
|
+
`;
|
|
444
|
+
if (source === "mcp" && sourceUrl) return `import { betterAuth } from "better-auth";
|
|
445
|
+
import { agentAuth } from "${AGENT_PLUGIN_PKG}";
|
|
446
|
+
|
|
447
|
+
export const auth = betterAuth({
|
|
448
|
+
\tplugins: [
|
|
449
|
+
\t\tagentAuth({
|
|
450
|
+
\t\t\tproviderName: ${JSON.stringify(name)},${descLine}
|
|
451
|
+
\t\t\tmcpServer: ${JSON.stringify(sourceUrl)},
|
|
452
|
+
\t\t}),
|
|
453
|
+
\t],
|
|
454
|
+
});
|
|
455
|
+
`;
|
|
456
|
+
return `import { betterAuth } from "better-auth";
|
|
457
|
+
import { agentAuth } from "${AGENT_PLUGIN_PKG}";
|
|
458
|
+
|
|
459
|
+
export const auth = betterAuth({
|
|
460
|
+
\tplugins: [
|
|
461
|
+
\t\tagentAuth({
|
|
462
|
+
\t\t\tproviderName: ${JSON.stringify(name)},${descLine}
|
|
463
|
+
\t\t\tcapabilities: [
|
|
464
|
+
\t\t\t\t{
|
|
465
|
+
\t\t\t\t\tname: "example",
|
|
466
|
+
\t\t\t\t\tdescription: "An example capability — replace with your own",
|
|
467
|
+
\t\t\t\t\tinput: {
|
|
468
|
+
\t\t\t\t\t\ttype: "object",
|
|
469
|
+
\t\t\t\t\t\tproperties: {
|
|
470
|
+
\t\t\t\t\t\t\tmessage: { type: "string", description: "Input message" },
|
|
471
|
+
\t\t\t\t\t\t},
|
|
472
|
+
\t\t\t\t\t},
|
|
473
|
+
\t\t\t\t},
|
|
474
|
+
\t\t\t],
|
|
475
|
+
\t\t\tasync onExecute({ capability, arguments: args }) {
|
|
476
|
+
\t\t\t\tswitch (capability) {
|
|
477
|
+
\t\t\t\t\tcase "example":
|
|
478
|
+
\t\t\t\t\t\treturn { message: \`Hello from \${(args as Record<string, string>).message}\` };
|
|
479
|
+
\t\t\t\t\tdefault:
|
|
480
|
+
\t\t\t\t\t\tthrow new Error(\`Unknown capability: \${capability}\`);
|
|
481
|
+
\t\t\t\t}
|
|
482
|
+
\t\t\t},
|
|
483
|
+
\t\t}),
|
|
484
|
+
\t],
|
|
485
|
+
});
|
|
486
|
+
`;
|
|
487
|
+
}
|
|
488
|
+
function showServerOutro() {
|
|
489
|
+
console.log(chalk.bold.white("\nNext steps:\n"));
|
|
490
|
+
console.log(chalk.white(" 1. Install dependencies:"));
|
|
491
|
+
console.log(chalk.cyan(` npm install better-auth ${AGENT_PLUGIN_PKG}\n`));
|
|
492
|
+
console.log(chalk.white(" 2. Configure your database:"));
|
|
493
|
+
console.log(chalk.gray(" Better Auth needs a database to store agents, hosts, and grants."));
|
|
494
|
+
console.log(chalk.cyan(" https://www.better-auth.com/docs/concepts/database\n"));
|
|
495
|
+
console.log(chalk.white(" 3. Run database migrations:"));
|
|
496
|
+
console.log(chalk.cyan(" npx auth migrate\n"));
|
|
497
|
+
console.log(chalk.white(" 4. Expose the discovery endpoint at your app root:"));
|
|
498
|
+
console.log(chalk.gray(" GET /.well-known/agent-configuration"));
|
|
499
|
+
console.log(chalk.gray(" → return auth.api.getAgentConfiguration({ headers })\n"));
|
|
500
|
+
console.log(` ${chalk.cyan("Docs")} ${PROTOCOL_URL}/docs/build-server`);
|
|
501
|
+
console.log(` ${chalk.cyan("GitHub")} https://github.com/better-auth/agent-auth`);
|
|
502
|
+
console.log(chalk.green("\n✔ ") + chalk.bold("Server scaffolded. ") + "Follow the steps above to finish setup.\n");
|
|
503
|
+
}
|
|
504
|
+
async function offerSkillInstall(skillName) {
|
|
505
|
+
const { installSkill } = await prompts({
|
|
506
|
+
type: "confirm",
|
|
507
|
+
name: "installSkill",
|
|
508
|
+
message: `Install the ${chalk.cyan(skillName)} skill for your coding agents?`,
|
|
509
|
+
initial: true
|
|
510
|
+
});
|
|
511
|
+
if (!installSkill) return;
|
|
512
|
+
const cmd = `npx -y skills add ${SKILLS_REPO} --skill ${skillName}`;
|
|
513
|
+
const s = yoctoSpinner({
|
|
514
|
+
text: `Installing ${skillName} skill…`,
|
|
515
|
+
color: "white"
|
|
516
|
+
});
|
|
517
|
+
s.start();
|
|
518
|
+
try {
|
|
519
|
+
execSync(cmd, { stdio: "pipe" });
|
|
520
|
+
s.success(`${skillName} skill installed.`);
|
|
521
|
+
} catch {
|
|
522
|
+
s.stop();
|
|
523
|
+
console.log(chalk.yellow("⚠ Could not install automatically. Run manually:"));
|
|
524
|
+
console.log(chalk.cyan(` ${cmd}\n`));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function buildMcpArgs(registry) {
|
|
528
|
+
const args = [
|
|
529
|
+
"-y",
|
|
530
|
+
AGENT_CLI_PKG,
|
|
531
|
+
"mcp"
|
|
532
|
+
];
|
|
533
|
+
if (registry && registry !== DEFAULT_REGISTRY) args.push("--registry-url", registry);
|
|
534
|
+
return args;
|
|
535
|
+
}
|
|
536
|
+
function getMcpConfigPath(tool, scope) {
|
|
537
|
+
const home = os$1.homedir();
|
|
538
|
+
switch (tool) {
|
|
539
|
+
case "cursor": return scope === "global" ? path$1.join(home, ".cursor", "mcp.json") : path$1.join(process.cwd(), ".cursor", "mcp.json");
|
|
540
|
+
case "claude-desktop":
|
|
541
|
+
if (process.platform === "win32") return path$1.join(process.env.APPDATA || home, "Claude", "claude_desktop_config.json");
|
|
542
|
+
if (process.platform === "darwin") return path$1.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
543
|
+
return path$1.join(home, ".config", "Claude", "claude_desktop_config.json");
|
|
544
|
+
case "windsurf": return path$1.join(home, ".codeium", "windsurf", "mcp_config.json");
|
|
545
|
+
case "vscode": return scope === "global" ? null : path$1.join(process.cwd(), ".vscode", "mcp.json");
|
|
546
|
+
default: return null;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function writeMcpConfig(configPath, entry) {
|
|
550
|
+
let config = {};
|
|
551
|
+
if (fs$2.existsSync(configPath)) try {
|
|
552
|
+
config = JSON.parse(fs$2.readFileSync(configPath, "utf-8"));
|
|
553
|
+
} catch {}
|
|
554
|
+
const servers = config.mcpServers ?? {};
|
|
555
|
+
servers["agent-auth"] = entry;
|
|
556
|
+
config.mcpServers = servers;
|
|
557
|
+
const dir = path$1.dirname(configPath);
|
|
558
|
+
if (!fs$2.existsSync(dir)) fs$2.mkdirSync(dir, { recursive: true });
|
|
559
|
+
fs$2.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
560
|
+
}
|
|
561
|
+
function displayPath(filePath, scope) {
|
|
562
|
+
if (scope === "project") return path$1.relative(process.cwd(), filePath) || filePath;
|
|
563
|
+
return filePath.replace(os$1.homedir(), "~");
|
|
564
|
+
}
|
|
565
|
+
function showJsonConfig(entry) {
|
|
566
|
+
const json = JSON.stringify({ mcpServers: { "agent-auth": entry } }, null, 2);
|
|
567
|
+
console.log(chalk.bold.white("\nAdd to your MCP configuration:\n"));
|
|
568
|
+
console.log(json.split("\n").map((line) => chalk.cyan(` ${line}`)).join("\n"));
|
|
569
|
+
console.log();
|
|
570
|
+
}
|
|
571
|
+
function showCodeBlock(code, title) {
|
|
572
|
+
console.log(chalk.bold.white(`\n${title}:\n`));
|
|
573
|
+
console.log(code.split("\n").map((line) => chalk.dim(` ${line}`)).join("\n"));
|
|
574
|
+
}
|
|
575
|
+
function showNextSteps(lines) {
|
|
576
|
+
console.log(chalk.bold.white("\nLearn more:\n"));
|
|
577
|
+
for (const line of lines) console.log(` ${line}`);
|
|
578
|
+
}
|
|
579
|
+
const ai = new Command("ai").description("Interactive setup for Agent Auth — AI agent authentication").action(aiAction);
|
|
580
|
+
|
|
581
|
+
//#endregion
|
|
37
582
|
//#region src/generators/drizzle.ts
|
|
38
583
|
function convertToSnakeCase(str, camelCase) {
|
|
39
584
|
if (camelCase) return str;
|
|
@@ -1143,14 +1688,14 @@ function createMockAdapter$1(adapterId, dialect) {
|
|
|
1143
1688
|
};
|
|
1144
1689
|
}
|
|
1145
1690
|
async function generateAction(opts) {
|
|
1146
|
-
const options = z
|
|
1147
|
-
cwd: z
|
|
1148
|
-
config: z
|
|
1149
|
-
output: z
|
|
1150
|
-
adapter: z
|
|
1151
|
-
dialect: z
|
|
1152
|
-
y: z
|
|
1153
|
-
yes: z
|
|
1691
|
+
const options = z.object({
|
|
1692
|
+
cwd: z.string(),
|
|
1693
|
+
config: z.string().optional(),
|
|
1694
|
+
output: z.string().optional(),
|
|
1695
|
+
adapter: z.string().optional(),
|
|
1696
|
+
dialect: z.string().optional(),
|
|
1697
|
+
y: z.boolean().optional(),
|
|
1698
|
+
yes: z.boolean().optional()
|
|
1154
1699
|
}).parse(opts);
|
|
1155
1700
|
const cwd = path.resolve(options.cwd);
|
|
1156
1701
|
if (!existsSync(cwd)) {
|
|
@@ -2426,7 +2971,7 @@ const tempPluginsConfig = {
|
|
|
2426
2971
|
argument: {
|
|
2427
2972
|
index: 0,
|
|
2428
2973
|
isProperty: "issuer",
|
|
2429
|
-
schema: z
|
|
2974
|
+
schema: z.coerce.string().optional()
|
|
2430
2975
|
}
|
|
2431
2976
|
},
|
|
2432
2977
|
{
|
|
@@ -2438,7 +2983,7 @@ const tempPluginsConfig = {
|
|
|
2438
2983
|
argument: {
|
|
2439
2984
|
index: 0,
|
|
2440
2985
|
isProperty: "skipVerificationOnEnable",
|
|
2441
|
-
schema: z
|
|
2986
|
+
schema: z.coerce.boolean().optional()
|
|
2442
2987
|
}
|
|
2443
2988
|
},
|
|
2444
2989
|
{
|
|
@@ -2455,7 +3000,7 @@ const tempPluginsConfig = {
|
|
|
2455
3000
|
argument: {
|
|
2456
3001
|
index: 0,
|
|
2457
3002
|
isProperty: "digits",
|
|
2458
|
-
schema: z
|
|
3003
|
+
schema: z.coerce.number().positive().optional()
|
|
2459
3004
|
}
|
|
2460
3005
|
}, {
|
|
2461
3006
|
flag: "totp-otp-period",
|
|
@@ -2466,7 +3011,7 @@ const tempPluginsConfig = {
|
|
|
2466
3011
|
argument: {
|
|
2467
3012
|
index: 0,
|
|
2468
3013
|
isProperty: "period",
|
|
2469
|
-
schema: z
|
|
3014
|
+
schema: z.coerce.number().positive().optional()
|
|
2470
3015
|
}
|
|
2471
3016
|
}],
|
|
2472
3017
|
argument: {
|
|
@@ -2488,7 +3033,7 @@ const tempPluginsConfig = {
|
|
|
2488
3033
|
argument: {
|
|
2489
3034
|
index: 0,
|
|
2490
3035
|
isProperty: "period",
|
|
2491
|
-
schema: z
|
|
3036
|
+
schema: z.coerce.number().positive().optional()
|
|
2492
3037
|
}
|
|
2493
3038
|
}, {
|
|
2494
3039
|
flag: "otp-store-otp",
|
|
@@ -2513,7 +3058,7 @@ const tempPluginsConfig = {
|
|
|
2513
3058
|
argument: {
|
|
2514
3059
|
index: 0,
|
|
2515
3060
|
isProperty: "storeOTP",
|
|
2516
|
-
schema: z
|
|
3061
|
+
schema: z.enum([
|
|
2517
3062
|
"plain",
|
|
2518
3063
|
"encrypted",
|
|
2519
3064
|
"hashed"
|
|
@@ -2538,7 +3083,7 @@ const tempPluginsConfig = {
|
|
|
2538
3083
|
argument: {
|
|
2539
3084
|
index: 0,
|
|
2540
3085
|
isProperty: "amount",
|
|
2541
|
-
schema: z
|
|
3086
|
+
schema: z.coerce.number().positive().optional()
|
|
2542
3087
|
}
|
|
2543
3088
|
}, {
|
|
2544
3089
|
flag: "backup-code-length",
|
|
@@ -2549,7 +3094,7 @@ const tempPluginsConfig = {
|
|
|
2549
3094
|
argument: {
|
|
2550
3095
|
index: 0,
|
|
2551
3096
|
isProperty: "length",
|
|
2552
|
-
schema: z
|
|
3097
|
+
schema: z.coerce.number().positive().optional()
|
|
2553
3098
|
}
|
|
2554
3099
|
}],
|
|
2555
3100
|
argument: {
|
|
@@ -2574,7 +3119,7 @@ const tempPluginsConfig = {
|
|
|
2574
3119
|
argument: {
|
|
2575
3120
|
index: 0,
|
|
2576
3121
|
isProperty: "twoFactorTable",
|
|
2577
|
-
schema: z
|
|
3122
|
+
schema: z.coerce.string().optional()
|
|
2578
3123
|
}
|
|
2579
3124
|
}]
|
|
2580
3125
|
}
|
|
@@ -2608,7 +3153,7 @@ const tempPluginsConfig = {
|
|
|
2608
3153
|
argument: {
|
|
2609
3154
|
index: 0,
|
|
2610
3155
|
isProperty: "maxUsernameLength",
|
|
2611
|
-
schema: z
|
|
3156
|
+
schema: z.coerce.number().min(0).positive().optional()
|
|
2612
3157
|
}
|
|
2613
3158
|
},
|
|
2614
3159
|
{
|
|
@@ -2620,7 +3165,7 @@ const tempPluginsConfig = {
|
|
|
2620
3165
|
argument: {
|
|
2621
3166
|
index: 0,
|
|
2622
3167
|
isProperty: "minUsernameLength",
|
|
2623
|
-
schema: z
|
|
3168
|
+
schema: z.coerce.number().min(0).positive().optional()
|
|
2624
3169
|
}
|
|
2625
3170
|
},
|
|
2626
3171
|
{
|
|
@@ -2643,7 +3188,7 @@ const tempPluginsConfig = {
|
|
|
2643
3188
|
argument: {
|
|
2644
3189
|
index: 0,
|
|
2645
3190
|
isProperty: "username",
|
|
2646
|
-
schema: z
|
|
3191
|
+
schema: z.enum(["pre-normalization", "post-normalization"]).optional()
|
|
2647
3192
|
}
|
|
2648
3193
|
}, {
|
|
2649
3194
|
flag: "username-validation-order-display-username",
|
|
@@ -2661,7 +3206,7 @@ const tempPluginsConfig = {
|
|
|
2661
3206
|
argument: {
|
|
2662
3207
|
index: 0,
|
|
2663
3208
|
isProperty: "displayUsername",
|
|
2664
|
-
schema: z
|
|
3209
|
+
schema: z.enum(["pre-normalization", "post-normalization"]).optional()
|
|
2665
3210
|
}
|
|
2666
3211
|
}],
|
|
2667
3212
|
argument: {
|
|
@@ -2700,7 +3245,7 @@ const tempPluginsConfig = {
|
|
|
2700
3245
|
argument: {
|
|
2701
3246
|
index: 0,
|
|
2702
3247
|
isProperty: "expiresIn",
|
|
2703
|
-
schema: z
|
|
3248
|
+
schema: z.coerce.number().optional()
|
|
2704
3249
|
}
|
|
2705
3250
|
},
|
|
2706
3251
|
{
|
|
@@ -2715,7 +3260,7 @@ const tempPluginsConfig = {
|
|
|
2715
3260
|
argument: {
|
|
2716
3261
|
index: 0,
|
|
2717
3262
|
isProperty: "sendMagicLink",
|
|
2718
|
-
schema: z
|
|
3263
|
+
schema: z.coerce.string()
|
|
2719
3264
|
}
|
|
2720
3265
|
},
|
|
2721
3266
|
{
|
|
@@ -2732,7 +3277,7 @@ const tempPluginsConfig = {
|
|
|
2732
3277
|
argument: {
|
|
2733
3278
|
index: 0,
|
|
2734
3279
|
isProperty: "window",
|
|
2735
|
-
schema: z
|
|
3280
|
+
schema: z.coerce.number().optional()
|
|
2736
3281
|
}
|
|
2737
3282
|
}, {
|
|
2738
3283
|
flag: "magic-link-rate-limit-max",
|
|
@@ -2744,7 +3289,7 @@ const tempPluginsConfig = {
|
|
|
2744
3289
|
argument: {
|
|
2745
3290
|
index: 0,
|
|
2746
3291
|
isProperty: "max",
|
|
2747
|
-
schema: z
|
|
3292
|
+
schema: z.coerce.number().optional()
|
|
2748
3293
|
}
|
|
2749
3294
|
}],
|
|
2750
3295
|
argument: {
|
|
@@ -2768,7 +3313,7 @@ const tempPluginsConfig = {
|
|
|
2768
3313
|
argument: {
|
|
2769
3314
|
index: 0,
|
|
2770
3315
|
isProperty: "storeToken",
|
|
2771
|
-
schema: z
|
|
3316
|
+
schema: z.enum(["plain", "hashed"]).optional()
|
|
2772
3317
|
}
|
|
2773
3318
|
}
|
|
2774
3319
|
]
|
|
@@ -2804,7 +3349,7 @@ const tempPluginsConfig = {
|
|
|
2804
3349
|
argument: {
|
|
2805
3350
|
index: 0,
|
|
2806
3351
|
isProperty: "sendVerificationOTP",
|
|
2807
|
-
schema: z
|
|
3352
|
+
schema: z.coerce.string()
|
|
2808
3353
|
}
|
|
2809
3354
|
},
|
|
2810
3355
|
{
|
|
@@ -2817,7 +3362,7 @@ const tempPluginsConfig = {
|
|
|
2817
3362
|
argument: {
|
|
2818
3363
|
index: 0,
|
|
2819
3364
|
isProperty: "otpLength",
|
|
2820
|
-
schema: z
|
|
3365
|
+
schema: z.coerce.number().optional()
|
|
2821
3366
|
}
|
|
2822
3367
|
},
|
|
2823
3368
|
{
|
|
@@ -2830,7 +3375,7 @@ const tempPluginsConfig = {
|
|
|
2830
3375
|
argument: {
|
|
2831
3376
|
index: 0,
|
|
2832
3377
|
isProperty: "expiresIn",
|
|
2833
|
-
schema: z
|
|
3378
|
+
schema: z.coerce.number().optional()
|
|
2834
3379
|
}
|
|
2835
3380
|
},
|
|
2836
3381
|
{
|
|
@@ -2843,7 +3388,7 @@ const tempPluginsConfig = {
|
|
|
2843
3388
|
argument: {
|
|
2844
3389
|
index: 0,
|
|
2845
3390
|
isProperty: "sendVerificationOnSignUp",
|
|
2846
|
-
schema: z
|
|
3391
|
+
schema: z.coerce.boolean().optional()
|
|
2847
3392
|
}
|
|
2848
3393
|
},
|
|
2849
3394
|
{
|
|
@@ -2856,7 +3401,7 @@ const tempPluginsConfig = {
|
|
|
2856
3401
|
argument: {
|
|
2857
3402
|
index: 0,
|
|
2858
3403
|
isProperty: "disableSignUp",
|
|
2859
|
-
schema: z
|
|
3404
|
+
schema: z.coerce.boolean().optional()
|
|
2860
3405
|
}
|
|
2861
3406
|
},
|
|
2862
3407
|
{
|
|
@@ -2869,7 +3414,7 @@ const tempPluginsConfig = {
|
|
|
2869
3414
|
argument: {
|
|
2870
3415
|
index: 0,
|
|
2871
3416
|
isProperty: "allowedAttempts",
|
|
2872
|
-
schema: z
|
|
3417
|
+
schema: z.coerce.number().optional()
|
|
2873
3418
|
}
|
|
2874
3419
|
},
|
|
2875
3420
|
{
|
|
@@ -2895,7 +3440,7 @@ const tempPluginsConfig = {
|
|
|
2895
3440
|
argument: {
|
|
2896
3441
|
index: 0,
|
|
2897
3442
|
isProperty: "storeOTP",
|
|
2898
|
-
schema: z
|
|
3443
|
+
schema: z.enum([
|
|
2899
3444
|
"plain",
|
|
2900
3445
|
"encrypted",
|
|
2901
3446
|
"hashed"
|
|
@@ -2912,7 +3457,7 @@ const tempPluginsConfig = {
|
|
|
2912
3457
|
argument: {
|
|
2913
3458
|
index: 0,
|
|
2914
3459
|
isProperty: "overrideDefaultEmailVerification",
|
|
2915
|
-
schema: z
|
|
3460
|
+
schema: z.coerce.boolean().optional()
|
|
2916
3461
|
}
|
|
2917
3462
|
}
|
|
2918
3463
|
]
|
|
@@ -3039,7 +3584,7 @@ const tempPluginsConfig = {
|
|
|
3039
3584
|
argument: {
|
|
3040
3585
|
index: 0,
|
|
3041
3586
|
isProperty: "defaultRole",
|
|
3042
|
-
schema: z
|
|
3587
|
+
schema: z.coerce.string().optional()
|
|
3043
3588
|
}
|
|
3044
3589
|
}, {
|
|
3045
3590
|
flag: "admin-roles",
|
|
@@ -3050,7 +3595,7 @@ const tempPluginsConfig = {
|
|
|
3050
3595
|
argument: {
|
|
3051
3596
|
index: 0,
|
|
3052
3597
|
isProperty: "adminRoles",
|
|
3053
|
-
schema: z
|
|
3598
|
+
schema: z.array(z.string()).optional()
|
|
3054
3599
|
}
|
|
3055
3600
|
}]
|
|
3056
3601
|
},
|
|
@@ -3082,7 +3627,7 @@ const tempPluginsConfig = {
|
|
|
3082
3627
|
argument: {
|
|
3083
3628
|
index: 0,
|
|
3084
3629
|
isProperty: "apiKeyHeaders",
|
|
3085
|
-
schema: z
|
|
3630
|
+
schema: z.coerce.string().optional()
|
|
3086
3631
|
}
|
|
3087
3632
|
},
|
|
3088
3633
|
{
|
|
@@ -3095,7 +3640,7 @@ const tempPluginsConfig = {
|
|
|
3095
3640
|
argument: {
|
|
3096
3641
|
index: 0,
|
|
3097
3642
|
isProperty: "defaultKeyLength",
|
|
3098
|
-
schema: z
|
|
3643
|
+
schema: z.coerce.number().positive().optional()
|
|
3099
3644
|
}
|
|
3100
3645
|
},
|
|
3101
3646
|
{
|
|
@@ -3107,7 +3652,7 @@ const tempPluginsConfig = {
|
|
|
3107
3652
|
argument: {
|
|
3108
3653
|
index: 0,
|
|
3109
3654
|
isProperty: "disableKeyHashing",
|
|
3110
|
-
schema: z
|
|
3655
|
+
schema: z.coerce.boolean().optional()
|
|
3111
3656
|
}
|
|
3112
3657
|
},
|
|
3113
3658
|
{
|
|
@@ -3119,7 +3664,7 @@ const tempPluginsConfig = {
|
|
|
3119
3664
|
argument: {
|
|
3120
3665
|
index: 0,
|
|
3121
3666
|
isProperty: "enableMetadata",
|
|
3122
|
-
schema: z
|
|
3667
|
+
schema: z.coerce.boolean().optional()
|
|
3123
3668
|
}
|
|
3124
3669
|
},
|
|
3125
3670
|
{
|
|
@@ -3131,7 +3676,7 @@ const tempPluginsConfig = {
|
|
|
3131
3676
|
argument: {
|
|
3132
3677
|
index: 0,
|
|
3133
3678
|
isProperty: "enableSessionForAPIKeys",
|
|
3134
|
-
schema: z
|
|
3679
|
+
schema: z.coerce.boolean().optional()
|
|
3135
3680
|
}
|
|
3136
3681
|
}
|
|
3137
3682
|
]
|
|
@@ -3163,7 +3708,7 @@ const tempPluginsConfig = {
|
|
|
3163
3708
|
argument: {
|
|
3164
3709
|
index: 0,
|
|
3165
3710
|
isProperty: "requireSignature",
|
|
3166
|
-
schema: z
|
|
3711
|
+
schema: z.coerce.boolean().optional()
|
|
3167
3712
|
}
|
|
3168
3713
|
}]
|
|
3169
3714
|
},
|
|
@@ -3204,7 +3749,7 @@ const tempPluginsConfig = {
|
|
|
3204
3749
|
argument: {
|
|
3205
3750
|
index: 0,
|
|
3206
3751
|
isProperty: "provider",
|
|
3207
|
-
schema: z
|
|
3752
|
+
schema: z.enum([
|
|
3208
3753
|
"google-recaptcha",
|
|
3209
3754
|
"cloudflare-turnstile",
|
|
3210
3755
|
"hcaptcha",
|
|
@@ -3219,7 +3764,7 @@ const tempPluginsConfig = {
|
|
|
3219
3764
|
argument: {
|
|
3220
3765
|
index: 0,
|
|
3221
3766
|
isProperty: "secretKey",
|
|
3222
|
-
schema: z
|
|
3767
|
+
schema: z.coerce.string()
|
|
3223
3768
|
}
|
|
3224
3769
|
},
|
|
3225
3770
|
{
|
|
@@ -3230,7 +3775,7 @@ const tempPluginsConfig = {
|
|
|
3230
3775
|
argument: {
|
|
3231
3776
|
index: 0,
|
|
3232
3777
|
isProperty: "siteKey",
|
|
3233
|
-
schema: z
|
|
3778
|
+
schema: z.coerce.string().optional()
|
|
3234
3779
|
}
|
|
3235
3780
|
},
|
|
3236
3781
|
{
|
|
@@ -3243,7 +3788,7 @@ const tempPluginsConfig = {
|
|
|
3243
3788
|
argument: {
|
|
3244
3789
|
index: 0,
|
|
3245
3790
|
isProperty: "minScore",
|
|
3246
|
-
schema: z
|
|
3791
|
+
schema: z.coerce.number().min(0).max(1).optional()
|
|
3247
3792
|
}
|
|
3248
3793
|
}
|
|
3249
3794
|
]
|
|
@@ -3268,7 +3813,7 @@ const tempPluginsConfig = {
|
|
|
3268
3813
|
argument: {
|
|
3269
3814
|
index: 0,
|
|
3270
3815
|
isProperty: "shouldMutateListDeviceSessionsEndpoint",
|
|
3271
|
-
schema: z
|
|
3816
|
+
schema: z.coerce.boolean().optional()
|
|
3272
3817
|
}
|
|
3273
3818
|
}]
|
|
3274
3819
|
},
|
|
@@ -3300,7 +3845,7 @@ const tempPluginsConfig = {
|
|
|
3300
3845
|
argument: {
|
|
3301
3846
|
index: 0,
|
|
3302
3847
|
isProperty: "expiresIn",
|
|
3303
|
-
schema: z
|
|
3848
|
+
schema: z.coerce.string().optional()
|
|
3304
3849
|
}
|
|
3305
3850
|
},
|
|
3306
3851
|
{
|
|
@@ -3312,7 +3857,7 @@ const tempPluginsConfig = {
|
|
|
3312
3857
|
argument: {
|
|
3313
3858
|
index: 0,
|
|
3314
3859
|
isProperty: "interval",
|
|
3315
|
-
schema: z
|
|
3860
|
+
schema: z.coerce.string().optional()
|
|
3316
3861
|
}
|
|
3317
3862
|
},
|
|
3318
3863
|
{
|
|
@@ -3325,7 +3870,7 @@ const tempPluginsConfig = {
|
|
|
3325
3870
|
argument: {
|
|
3326
3871
|
index: 0,
|
|
3327
3872
|
isProperty: "deviceCodeLength",
|
|
3328
|
-
schema: z
|
|
3873
|
+
schema: z.coerce.number().positive().optional()
|
|
3329
3874
|
}
|
|
3330
3875
|
},
|
|
3331
3876
|
{
|
|
@@ -3338,7 +3883,7 @@ const tempPluginsConfig = {
|
|
|
3338
3883
|
argument: {
|
|
3339
3884
|
index: 0,
|
|
3340
3885
|
isProperty: "userCodeLength",
|
|
3341
|
-
schema: z
|
|
3886
|
+
schema: z.coerce.number().positive().optional()
|
|
3342
3887
|
}
|
|
3343
3888
|
}
|
|
3344
3889
|
]
|
|
@@ -3369,7 +3914,7 @@ const tempPluginsConfig = {
|
|
|
3369
3914
|
argument: {
|
|
3370
3915
|
index: 0,
|
|
3371
3916
|
isProperty: "customPasswordCompromisedMessage",
|
|
3372
|
-
schema: z
|
|
3917
|
+
schema: z.coerce.string().optional()
|
|
3373
3918
|
}
|
|
3374
3919
|
}]
|
|
3375
3920
|
},
|
|
@@ -3393,7 +3938,7 @@ const tempPluginsConfig = {
|
|
|
3393
3938
|
argument: {
|
|
3394
3939
|
index: 0,
|
|
3395
3940
|
isProperty: "disableSettingJwtHeader",
|
|
3396
|
-
schema: z
|
|
3941
|
+
schema: z.coerce.boolean().optional()
|
|
3397
3942
|
}
|
|
3398
3943
|
}]
|
|
3399
3944
|
},
|
|
@@ -3425,7 +3970,7 @@ const tempPluginsConfig = {
|
|
|
3425
3970
|
argument: {
|
|
3426
3971
|
index: 0,
|
|
3427
3972
|
isProperty: "cookieName",
|
|
3428
|
-
schema: z
|
|
3973
|
+
schema: z.coerce.string().optional()
|
|
3429
3974
|
}
|
|
3430
3975
|
},
|
|
3431
3976
|
{
|
|
@@ -3438,7 +3983,7 @@ const tempPluginsConfig = {
|
|
|
3438
3983
|
argument: {
|
|
3439
3984
|
index: 0,
|
|
3440
3985
|
isProperty: "maxAge",
|
|
3441
|
-
schema: z
|
|
3986
|
+
schema: z.coerce.number().positive().optional()
|
|
3442
3987
|
}
|
|
3443
3988
|
},
|
|
3444
3989
|
{
|
|
@@ -3450,7 +3995,7 @@ const tempPluginsConfig = {
|
|
|
3450
3995
|
argument: {
|
|
3451
3996
|
index: 0,
|
|
3452
3997
|
isProperty: "storeInDatabase",
|
|
3453
|
-
schema: z
|
|
3998
|
+
schema: z.coerce.boolean().optional()
|
|
3454
3999
|
}
|
|
3455
4000
|
}
|
|
3456
4001
|
]
|
|
@@ -3480,7 +4025,7 @@ const tempPluginsConfig = {
|
|
|
3480
4025
|
argument: {
|
|
3481
4026
|
index: 0,
|
|
3482
4027
|
isProperty: "loginPage",
|
|
3483
|
-
schema: z
|
|
4028
|
+
schema: z.coerce.string()
|
|
3484
4029
|
}
|
|
3485
4030
|
}, {
|
|
3486
4031
|
flag: "mcp-resource",
|
|
@@ -3490,7 +4035,7 @@ const tempPluginsConfig = {
|
|
|
3490
4035
|
argument: {
|
|
3491
4036
|
index: 0,
|
|
3492
4037
|
isProperty: "resource",
|
|
3493
|
-
schema: z
|
|
4038
|
+
schema: z.coerce.string().optional()
|
|
3494
4039
|
}
|
|
3495
4040
|
}]
|
|
3496
4041
|
},
|
|
@@ -3515,7 +4060,7 @@ const tempPluginsConfig = {
|
|
|
3515
4060
|
argument: {
|
|
3516
4061
|
index: 0,
|
|
3517
4062
|
isProperty: "maximumSessions",
|
|
3518
|
-
schema: z
|
|
4063
|
+
schema: z.coerce.number().positive().optional()
|
|
3519
4064
|
}
|
|
3520
4065
|
}]
|
|
3521
4066
|
},
|
|
@@ -3545,7 +4090,7 @@ const tempPluginsConfig = {
|
|
|
3545
4090
|
argument: {
|
|
3546
4091
|
index: 0,
|
|
3547
4092
|
isProperty: "currentURL",
|
|
3548
|
-
schema: z
|
|
4093
|
+
schema: z.coerce.string().optional()
|
|
3549
4094
|
}
|
|
3550
4095
|
}, {
|
|
3551
4096
|
flag: "oauth-proxy-production-url",
|
|
@@ -3555,7 +4100,7 @@ const tempPluginsConfig = {
|
|
|
3555
4100
|
argument: {
|
|
3556
4101
|
index: 0,
|
|
3557
4102
|
isProperty: "productionURL",
|
|
3558
|
-
schema: z
|
|
4103
|
+
schema: z.coerce.string().optional()
|
|
3559
4104
|
}
|
|
3560
4105
|
}]
|
|
3561
4106
|
},
|
|
@@ -3579,7 +4124,7 @@ const tempPluginsConfig = {
|
|
|
3579
4124
|
argument: {
|
|
3580
4125
|
index: 0,
|
|
3581
4126
|
isProperty: "disableSignup",
|
|
3582
|
-
schema: z
|
|
4127
|
+
schema: z.coerce.boolean().optional()
|
|
3583
4128
|
}
|
|
3584
4129
|
}, {
|
|
3585
4130
|
flag: "one-tap-client-id",
|
|
@@ -3589,7 +4134,7 @@ const tempPluginsConfig = {
|
|
|
3589
4134
|
argument: {
|
|
3590
4135
|
index: 0,
|
|
3591
4136
|
isProperty: "clientId",
|
|
3592
|
-
schema: z
|
|
4137
|
+
schema: z.coerce.string().optional()
|
|
3593
4138
|
}
|
|
3594
4139
|
}]
|
|
3595
4140
|
},
|
|
@@ -3622,7 +4167,7 @@ const tempPluginsConfig = {
|
|
|
3622
4167
|
argument: {
|
|
3623
4168
|
index: 0,
|
|
3624
4169
|
isProperty: "expiresIn",
|
|
3625
|
-
schema: z
|
|
4170
|
+
schema: z.coerce.number().positive().optional()
|
|
3626
4171
|
}
|
|
3627
4172
|
},
|
|
3628
4173
|
{
|
|
@@ -3634,7 +4179,7 @@ const tempPluginsConfig = {
|
|
|
3634
4179
|
argument: {
|
|
3635
4180
|
index: 0,
|
|
3636
4181
|
isProperty: "disableClientRequest",
|
|
3637
|
-
schema: z
|
|
4182
|
+
schema: z.coerce.boolean().optional()
|
|
3638
4183
|
}
|
|
3639
4184
|
},
|
|
3640
4185
|
{
|
|
@@ -3653,7 +4198,7 @@ const tempPluginsConfig = {
|
|
|
3653
4198
|
argument: {
|
|
3654
4199
|
index: 0,
|
|
3655
4200
|
isProperty: "storeToken",
|
|
3656
|
-
schema: z
|
|
4201
|
+
schema: z.enum(["plain", "hashed"]).optional()
|
|
3657
4202
|
}
|
|
3658
4203
|
}
|
|
3659
4204
|
]
|
|
@@ -3686,7 +4231,7 @@ const tempPluginsConfig = {
|
|
|
3686
4231
|
argument: {
|
|
3687
4232
|
index: 0,
|
|
3688
4233
|
isProperty: "path",
|
|
3689
|
-
schema: z
|
|
4234
|
+
schema: z.coerce.string().optional()
|
|
3690
4235
|
}
|
|
3691
4236
|
},
|
|
3692
4237
|
{
|
|
@@ -3698,7 +4243,7 @@ const tempPluginsConfig = {
|
|
|
3698
4243
|
argument: {
|
|
3699
4244
|
index: 0,
|
|
3700
4245
|
isProperty: "disableDefaultReference",
|
|
3701
|
-
schema: z
|
|
4246
|
+
schema: z.coerce.boolean().optional()
|
|
3702
4247
|
}
|
|
3703
4248
|
},
|
|
3704
4249
|
{
|
|
@@ -3760,7 +4305,7 @@ const tempPluginsConfig = {
|
|
|
3760
4305
|
argument: {
|
|
3761
4306
|
index: 0,
|
|
3762
4307
|
isProperty: "theme",
|
|
3763
|
-
schema: z
|
|
4308
|
+
schema: z.enum([
|
|
3764
4309
|
"alternate",
|
|
3765
4310
|
"default",
|
|
3766
4311
|
"moon",
|
|
@@ -3799,7 +4344,7 @@ const tempPluginsConfig = {
|
|
|
3799
4344
|
argument: {
|
|
3800
4345
|
index: 0,
|
|
3801
4346
|
isProperty: "allowUserToCreateOrganization",
|
|
3802
|
-
schema: z
|
|
4347
|
+
schema: z.coerce.boolean().optional()
|
|
3803
4348
|
}
|
|
3804
4349
|
},
|
|
3805
4350
|
{
|
|
@@ -3811,7 +4356,7 @@ const tempPluginsConfig = {
|
|
|
3811
4356
|
argument: {
|
|
3812
4357
|
index: 0,
|
|
3813
4358
|
isProperty: "creatorRole",
|
|
3814
|
-
schema: z
|
|
4359
|
+
schema: z.coerce.string().optional()
|
|
3815
4360
|
}
|
|
3816
4361
|
},
|
|
3817
4362
|
{
|
|
@@ -3824,7 +4369,7 @@ const tempPluginsConfig = {
|
|
|
3824
4369
|
argument: {
|
|
3825
4370
|
index: 0,
|
|
3826
4371
|
isProperty: "membershipLimit",
|
|
3827
|
-
schema: z
|
|
4372
|
+
schema: z.coerce.number().positive().optional()
|
|
3828
4373
|
}
|
|
3829
4374
|
}
|
|
3830
4375
|
]
|
|
@@ -3855,7 +4400,7 @@ const tempPluginsConfig = {
|
|
|
3855
4400
|
argument: {
|
|
3856
4401
|
index: 0,
|
|
3857
4402
|
isProperty: "domain",
|
|
3858
|
-
schema: z
|
|
4403
|
+
schema: z.coerce.string()
|
|
3859
4404
|
}
|
|
3860
4405
|
},
|
|
3861
4406
|
{
|
|
@@ -3866,7 +4411,7 @@ const tempPluginsConfig = {
|
|
|
3866
4411
|
argument: {
|
|
3867
4412
|
index: 0,
|
|
3868
4413
|
isProperty: "emailDomainName",
|
|
3869
|
-
schema: z
|
|
4414
|
+
schema: z.coerce.string().optional()
|
|
3870
4415
|
}
|
|
3871
4416
|
},
|
|
3872
4417
|
{
|
|
@@ -3878,7 +4423,7 @@ const tempPluginsConfig = {
|
|
|
3878
4423
|
argument: {
|
|
3879
4424
|
index: 0,
|
|
3880
4425
|
isProperty: "anonymous",
|
|
3881
|
-
schema: z
|
|
4426
|
+
schema: z.coerce.boolean().optional()
|
|
3882
4427
|
}
|
|
3883
4428
|
}
|
|
3884
4429
|
]
|
|
@@ -3933,7 +4478,7 @@ const tempPluginsConfig = {
|
|
|
3933
4478
|
argument: {
|
|
3934
4479
|
index: 0,
|
|
3935
4480
|
isProperty: "defaultOverrideUserInfo",
|
|
3936
|
-
schema: z
|
|
4481
|
+
schema: z.coerce.boolean().optional()
|
|
3937
4482
|
}
|
|
3938
4483
|
},
|
|
3939
4484
|
{
|
|
@@ -3946,7 +4491,7 @@ const tempPluginsConfig = {
|
|
|
3946
4491
|
argument: {
|
|
3947
4492
|
index: 0,
|
|
3948
4493
|
isProperty: "disableImplicitSignUp",
|
|
3949
|
-
schema: z
|
|
4494
|
+
schema: z.coerce.boolean().optional()
|
|
3950
4495
|
}
|
|
3951
4496
|
},
|
|
3952
4497
|
{
|
|
@@ -3960,7 +4505,7 @@ const tempPluginsConfig = {
|
|
|
3960
4505
|
argument: {
|
|
3961
4506
|
index: 0,
|
|
3962
4507
|
isProperty: "providersLimit",
|
|
3963
|
-
schema: z
|
|
4508
|
+
schema: z.coerce.number().int().positive().optional()
|
|
3964
4509
|
}
|
|
3965
4510
|
},
|
|
3966
4511
|
{
|
|
@@ -3973,7 +4518,7 @@ const tempPluginsConfig = {
|
|
|
3973
4518
|
argument: {
|
|
3974
4519
|
index: 0,
|
|
3975
4520
|
isProperty: "trustEmailVerified",
|
|
3976
|
-
schema: z
|
|
4521
|
+
schema: z.coerce.boolean().optional()
|
|
3977
4522
|
}
|
|
3978
4523
|
},
|
|
3979
4524
|
{
|
|
@@ -3984,7 +4529,7 @@ const tempPluginsConfig = {
|
|
|
3984
4529
|
argument: {
|
|
3985
4530
|
index: 0,
|
|
3986
4531
|
isProperty: "domainVerification",
|
|
3987
|
-
schema: z
|
|
4532
|
+
schema: z.object({ enabled: z.coerce.boolean().optional() }).optional()
|
|
3988
4533
|
},
|
|
3989
4534
|
isNestedObject: [{
|
|
3990
4535
|
flag: "sso-domain-verification-enabled",
|
|
@@ -3996,7 +4541,7 @@ const tempPluginsConfig = {
|
|
|
3996
4541
|
argument: {
|
|
3997
4542
|
index: 0,
|
|
3998
4543
|
isProperty: "enabled",
|
|
3999
|
-
schema: z
|
|
4544
|
+
schema: z.coerce.boolean().optional()
|
|
4000
4545
|
}
|
|
4001
4546
|
}]
|
|
4002
4547
|
}
|
|
@@ -4017,7 +4562,7 @@ const tempPluginsConfig = {
|
|
|
4017
4562
|
argument: {
|
|
4018
4563
|
index: 0,
|
|
4019
4564
|
isProperty: "domainVerification",
|
|
4020
|
-
schema: z
|
|
4565
|
+
schema: z.object({ enabled: z.coerce.boolean().optional() }).optional()
|
|
4021
4566
|
},
|
|
4022
4567
|
isNestedObject: [{
|
|
4023
4568
|
flag: "sso-client-domain-verification-enabled",
|
|
@@ -4029,7 +4574,7 @@ const tempPluginsConfig = {
|
|
|
4029
4574
|
argument: {
|
|
4030
4575
|
index: 0,
|
|
4031
4576
|
isProperty: "enabled",
|
|
4032
|
-
schema: z
|
|
4577
|
+
schema: z.coerce.boolean().optional()
|
|
4033
4578
|
}
|
|
4034
4579
|
}]
|
|
4035
4580
|
}]
|
|
@@ -6245,11 +6790,11 @@ const mcp = new Command("mcp").description("Add Better Auth MCP server to MCP Cl
|
|
|
6245
6790
|
//#region src/commands/migrate.ts
|
|
6246
6791
|
/** @internal */
|
|
6247
6792
|
async function migrateAction(opts) {
|
|
6248
|
-
const options = z
|
|
6249
|
-
cwd: z
|
|
6250
|
-
config: z
|
|
6251
|
-
y: z
|
|
6252
|
-
yes: z
|
|
6793
|
+
const options = z.object({
|
|
6794
|
+
cwd: z.string(),
|
|
6795
|
+
config: z.string().optional(),
|
|
6796
|
+
y: z.boolean().optional(),
|
|
6797
|
+
yes: z.boolean().optional()
|
|
6253
6798
|
}).parse(opts);
|
|
6254
6799
|
const cwd = path.resolve(options.cwd);
|
|
6255
6800
|
if (!existsSync(cwd)) {
|
|
@@ -6401,9 +6946,9 @@ function isBetterAuthPackage(name) {
|
|
|
6401
6946
|
return name === "better-auth" || name.startsWith("@better-auth/");
|
|
6402
6947
|
}
|
|
6403
6948
|
async function upgradeAction(opts) {
|
|
6404
|
-
const options = z
|
|
6405
|
-
cwd: z
|
|
6406
|
-
yes: z
|
|
6949
|
+
const options = z.object({
|
|
6950
|
+
cwd: z.string(),
|
|
6951
|
+
yes: z.boolean().optional()
|
|
6407
6952
|
}).parse(opts);
|
|
6408
6953
|
const cwd = path.resolve(options.cwd);
|
|
6409
6954
|
if (!existsSync(cwd)) {
|
|
@@ -6512,7 +7057,7 @@ async function main() {
|
|
|
6512
7057
|
packageInfo = await getPackageInfo();
|
|
6513
7058
|
cliVersion = packageInfo.version || "1.1.2";
|
|
6514
7059
|
} catch {}
|
|
6515
|
-
program.addCommand(init).addCommand(migrate).addCommand(generate).addCommand(generateSecret).addCommand(info).addCommand(login).addCommand(logout).addCommand(mcp).addCommand(upgrade).version(cliVersion).description("Better Auth CLI").action(() => program.help());
|
|
7060
|
+
program.addCommand(ai).addCommand(init).addCommand(migrate).addCommand(generate).addCommand(generateSecret).addCommand(info).addCommand(login).addCommand(logout).addCommand(mcp).addCommand(upgrade).version(cliVersion).description("Better Auth CLI").action(() => program.help());
|
|
6516
7061
|
program.parse();
|
|
6517
7062
|
}
|
|
6518
7063
|
main().catch((error) => {
|