@agentuity/cli 0.0.108 → 0.0.110
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/build-report.d.ts +201 -0
- package/dist/build-report.d.ts.map +1 -0
- package/dist/build-report.js +335 -0
- package/dist/build-report.js.map +1 -0
- package/dist/cmd/build/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +9 -3
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +44 -1
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/typecheck.d.ts +7 -1
- package/dist/cmd/build/typecheck.d.ts.map +1 -1
- package/dist/cmd/build/typecheck.js +11 -1
- package/dist/cmd/build/typecheck.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +2 -1
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +2 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +2 -4
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +56 -18
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +3 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +14 -1
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.d.ts +3 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite-bundler.js +14 -5
- package/dist/cmd/build/vite-bundler.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +86 -9
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +0 -1
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +109 -15
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/project/auth/generate.d.ts +5 -0
- package/dist/cmd/project/auth/generate.d.ts.map +1 -0
- package/dist/cmd/project/auth/generate.js +102 -0
- package/dist/cmd/project/auth/generate.js.map +1 -0
- package/dist/cmd/project/auth/index.d.ts +2 -0
- package/dist/cmd/project/auth/index.d.ts.map +1 -0
- package/dist/cmd/project/auth/index.js +21 -0
- package/dist/cmd/project/auth/index.js.map +1 -0
- package/dist/cmd/project/auth/init.d.ts +2 -0
- package/dist/cmd/project/auth/init.d.ts.map +1 -0
- package/dist/cmd/project/auth/init.js +220 -0
- package/dist/cmd/project/auth/init.js.map +1 -0
- package/dist/cmd/project/auth/shared.d.ts +88 -0
- package/dist/cmd/project/auth/shared.d.ts.map +1 -0
- package/dist/cmd/project/auth/shared.js +435 -0
- package/dist/cmd/project/auth/shared.js.map +1 -0
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +9 -1
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +106 -0
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/types.d.ts +1 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/package.json +5 -4
- package/src/build-report.ts +457 -0
- package/src/cmd/build/entry-generator.ts +9 -3
- package/src/cmd/build/index.ts +51 -1
- package/src/cmd/build/typecheck.ts +19 -1
- package/src/cmd/build/vite/index.ts +4 -1
- package/src/cmd/build/vite/metadata-generator.ts +4 -6
- package/src/cmd/build/vite/registry-generator.ts +58 -19
- package/src/cmd/build/vite/vite-builder.ts +18 -1
- package/src/cmd/build/vite-bundler.ts +17 -4
- package/src/cmd/cloud/deploy.ts +105 -11
- package/src/cmd/cloud/deployment/show.ts +0 -1
- package/src/cmd/dev/index.ts +115 -14
- package/src/cmd/project/auth/generate.ts +116 -0
- package/src/cmd/project/auth/index.ts +21 -0
- package/src/cmd/project/auth/init.ts +263 -0
- package/src/cmd/project/auth/shared.ts +534 -0
- package/src/cmd/project/index.ts +9 -1
- package/src/cmd/project/template-flow.ts +125 -0
- package/src/types.ts +1 -2
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for Agentuity Auth setup
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { listResources, createResources, dbQuery } from '@agentuity/server';
|
|
6
|
+
import * as tui from '../../../tui';
|
|
7
|
+
import { getCatalystAPIClient } from '../../../config';
|
|
8
|
+
import enquirer from 'enquirer';
|
|
9
|
+
/**
|
|
10
|
+
* Select an existing database or create a new one
|
|
11
|
+
*/
|
|
12
|
+
export async function selectOrCreateDatabase(options) {
|
|
13
|
+
const { logger, auth, orgId, region, existingUrl } = options;
|
|
14
|
+
const catalystClient = getCatalystAPIClient(logger, auth, region);
|
|
15
|
+
const resources = await tui.spinner({
|
|
16
|
+
message: `Fetching databases for ${orgId} in ${region}`,
|
|
17
|
+
clearOnSuccess: true,
|
|
18
|
+
callback: async () => listResources(catalystClient, orgId, region),
|
|
19
|
+
});
|
|
20
|
+
const databases = resources.db;
|
|
21
|
+
// Extract existing database name from URL if provided
|
|
22
|
+
let existingDbName;
|
|
23
|
+
if (existingUrl) {
|
|
24
|
+
const urlMatch = existingUrl.match(/\/([^/?]+)(\?|$)/);
|
|
25
|
+
if (urlMatch) {
|
|
26
|
+
existingDbName = urlMatch[1];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const choices = [];
|
|
30
|
+
// Add "use existing" option first if we have an existing URL
|
|
31
|
+
if (existingUrl && existingDbName) {
|
|
32
|
+
choices.push({
|
|
33
|
+
name: '__existing__',
|
|
34
|
+
message: `${tui.tuiColors.success('✓')} Use existing (found in .env): ${existingDbName}`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Add create new option
|
|
38
|
+
choices.push({ name: '__create__', message: tui.bold('+ Create new database') });
|
|
39
|
+
// Add other databases
|
|
40
|
+
choices.push(...databases
|
|
41
|
+
.filter((db) => db.name !== existingDbName) // Don't duplicate existing
|
|
42
|
+
.map((db) => ({
|
|
43
|
+
name: db.name,
|
|
44
|
+
message: db.name,
|
|
45
|
+
})));
|
|
46
|
+
const response = await enquirer.prompt({
|
|
47
|
+
type: 'select',
|
|
48
|
+
name: 'database',
|
|
49
|
+
message: 'Select a database for auth:',
|
|
50
|
+
choices,
|
|
51
|
+
});
|
|
52
|
+
// Handle "use existing" selection
|
|
53
|
+
if (response.database === '__existing__' && existingUrl && existingDbName) {
|
|
54
|
+
return { name: existingDbName, url: existingUrl };
|
|
55
|
+
}
|
|
56
|
+
if (response.database === '__create__') {
|
|
57
|
+
const created = await tui.spinner({
|
|
58
|
+
message: `Creating database in ${region}`,
|
|
59
|
+
clearOnSuccess: true,
|
|
60
|
+
callback: async () => createResources(catalystClient, orgId, region, [{ type: 'db' }]),
|
|
61
|
+
});
|
|
62
|
+
if (created.length === 0) {
|
|
63
|
+
tui.fatal('Failed to create database');
|
|
64
|
+
}
|
|
65
|
+
const newDb = created[0];
|
|
66
|
+
tui.success(`Created database: ${tui.bold(newDb.name)}`);
|
|
67
|
+
const updatedResources = await listResources(catalystClient, orgId, region);
|
|
68
|
+
const dbInfo = updatedResources.db.find((d) => d.name === newDb.name);
|
|
69
|
+
if (!dbInfo?.url) {
|
|
70
|
+
tui.fatal('Failed to retrieve database connection URL');
|
|
71
|
+
}
|
|
72
|
+
return { name: newDb.name, url: dbInfo.url };
|
|
73
|
+
}
|
|
74
|
+
const selectedDb = databases.find((d) => d.name === response.database);
|
|
75
|
+
if (!selectedDb?.url) {
|
|
76
|
+
tui.fatal('Failed to retrieve database connection URL');
|
|
77
|
+
}
|
|
78
|
+
return { name: selectedDb.name, url: selectedDb.url };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Required auth dependencies
|
|
82
|
+
*/
|
|
83
|
+
export const AUTH_DEPENDENCIES = {
|
|
84
|
+
'@agentuity/auth': 'latest',
|
|
85
|
+
'better-auth': '^1.4.9',
|
|
86
|
+
'drizzle-orm': '^0.44.0',
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Check and install auth dependencies
|
|
90
|
+
*/
|
|
91
|
+
export async function ensureAuthDependencies(options) {
|
|
92
|
+
const { projectDir } = options;
|
|
93
|
+
const fs = await import('fs');
|
|
94
|
+
const path = await import('path');
|
|
95
|
+
const packageJsonPath = path.join(projectDir, 'package.json');
|
|
96
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
97
|
+
tui.fatal('No package.json found in project directory');
|
|
98
|
+
}
|
|
99
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
100
|
+
const deps = packageJson.dependencies || {};
|
|
101
|
+
const missingDeps = [];
|
|
102
|
+
for (const [dep, version] of Object.entries(AUTH_DEPENDENCIES)) {
|
|
103
|
+
if (!deps[dep]) {
|
|
104
|
+
missingDeps.push(`${dep}@${version}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (missingDeps.length === 0) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
tui.info(`Installing auth dependencies: ${missingDeps.join(', ')}`);
|
|
111
|
+
const proc = Bun.spawn(['bun', 'install', ...missingDeps], {
|
|
112
|
+
cwd: projectDir,
|
|
113
|
+
stdout: 'inherit',
|
|
114
|
+
stderr: 'inherit',
|
|
115
|
+
});
|
|
116
|
+
const exitCode = await proc.exited;
|
|
117
|
+
if (exitCode !== 0) {
|
|
118
|
+
throw new Error(`bun install failed with code ${exitCode}`);
|
|
119
|
+
}
|
|
120
|
+
tui.success('Dependencies installed');
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get the directory for generated SQL files.
|
|
125
|
+
* Uses src/generated/ if it exists, otherwise falls back to project root.
|
|
126
|
+
*/
|
|
127
|
+
export async function getGeneratedSqlDir(projectDir) {
|
|
128
|
+
const generatedDir = path.join(projectDir, 'src', 'generated');
|
|
129
|
+
if (await Bun.file(path.join(generatedDir, 'registry.ts')).exists()) {
|
|
130
|
+
return generatedDir;
|
|
131
|
+
}
|
|
132
|
+
return projectDir;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Detect existing ORM setup in project.
|
|
136
|
+
* TODO: This is probably not 100% accurate. Drizzle config could be in all sorts of places in a repo.
|
|
137
|
+
*/
|
|
138
|
+
export async function detectOrmSetup(projectDir) {
|
|
139
|
+
const drizzleConfigTs = path.join(projectDir, 'drizzle.config.ts');
|
|
140
|
+
const drizzleConfigJs = path.join(projectDir, 'drizzle.config.js');
|
|
141
|
+
const prismaSchema = path.join(projectDir, 'prisma', 'schema.prisma');
|
|
142
|
+
if ((await Bun.file(drizzleConfigTs).exists()) || (await Bun.file(drizzleConfigJs).exists())) {
|
|
143
|
+
return 'drizzle';
|
|
144
|
+
}
|
|
145
|
+
if (await Bun.file(prismaSchema).exists()) {
|
|
146
|
+
return 'prisma';
|
|
147
|
+
}
|
|
148
|
+
return 'none';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Generate auth schema SQL using drizzle-kit export.
|
|
152
|
+
*
|
|
153
|
+
* This generates SQL DDL statements from the @agentuity/auth Drizzle schema
|
|
154
|
+
* without needing a database connection.
|
|
155
|
+
*
|
|
156
|
+
* @param projectDir - Project directory (must have @agentuity/auth installed)
|
|
157
|
+
* @returns SQL DDL statements for auth tables
|
|
158
|
+
*/
|
|
159
|
+
export async function generateAuthSchemaSql(projectDir) {
|
|
160
|
+
const schemaPath = path.join(projectDir, 'node_modules/@agentuity/auth/src/schema.ts');
|
|
161
|
+
if (!(await Bun.file(schemaPath).exists())) {
|
|
162
|
+
throw new Error(`@agentuity/auth schema not found at ${schemaPath}. Ensure @agentuity/auth is installed.`);
|
|
163
|
+
}
|
|
164
|
+
const proc = Bun.spawn(['bunx', 'drizzle-kit', 'export', '--dialect=postgresql', `--schema=${schemaPath}`], {
|
|
165
|
+
cwd: projectDir,
|
|
166
|
+
stdout: 'pipe',
|
|
167
|
+
stderr: 'pipe',
|
|
168
|
+
});
|
|
169
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
170
|
+
new Response(proc.stdout).text(),
|
|
171
|
+
new Response(proc.stderr).text(),
|
|
172
|
+
proc.exited,
|
|
173
|
+
]);
|
|
174
|
+
if (exitCode !== 0) {
|
|
175
|
+
const errorMsg = stderr
|
|
176
|
+
.split('\n')
|
|
177
|
+
.filter((line) => !line.includes('Please install'))
|
|
178
|
+
.join('\n')
|
|
179
|
+
.trim();
|
|
180
|
+
throw new Error(`drizzle-kit export failed with code ${exitCode}: ${errorMsg}`);
|
|
181
|
+
}
|
|
182
|
+
return makeIdempotent(stdout);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Transform drizzle-kit SQL output to be idempotent.
|
|
186
|
+
*
|
|
187
|
+
* - Converts CREATE TABLE to CREATE TABLE IF NOT EXISTS
|
|
188
|
+
* - Converts CREATE INDEX to CREATE INDEX IF NOT EXISTS
|
|
189
|
+
* - Wraps ALTER TABLE ADD CONSTRAINT in DO blocks to handle existing constraints
|
|
190
|
+
*/
|
|
191
|
+
function makeIdempotent(sql) {
|
|
192
|
+
const lines = sql.split('\n');
|
|
193
|
+
const result = [];
|
|
194
|
+
for (const line of lines) {
|
|
195
|
+
const trimmed = line.trim();
|
|
196
|
+
if (trimmed.startsWith('CREATE TABLE ') && !trimmed.includes('IF NOT EXISTS')) {
|
|
197
|
+
result.push(line.replace('CREATE TABLE ', 'CREATE TABLE IF NOT EXISTS '));
|
|
198
|
+
}
|
|
199
|
+
else if (trimmed.startsWith('CREATE INDEX ') && !trimmed.includes('IF NOT EXISTS')) {
|
|
200
|
+
result.push(line.replace('CREATE INDEX ', 'CREATE INDEX IF NOT EXISTS '));
|
|
201
|
+
}
|
|
202
|
+
else if (trimmed.startsWith('ALTER TABLE ') && trimmed.includes('ADD CONSTRAINT')) {
|
|
203
|
+
const constraintMatch = trimmed.match(/ADD CONSTRAINT "([^"]+)"/);
|
|
204
|
+
if (constraintMatch) {
|
|
205
|
+
result.push(`DO $$ BEGIN ${trimmed} EXCEPTION WHEN duplicate_object THEN NULL; END $$;`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
result.push(line);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
result.push(line);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return result.join('\n');
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Split SQL into individual statements for sequential execution
|
|
219
|
+
* The dbQuery API only supports single statements
|
|
220
|
+
*/
|
|
221
|
+
export function splitSqlStatements(sql) {
|
|
222
|
+
// Split on semicolons, but be careful about edge cases
|
|
223
|
+
const statements = [];
|
|
224
|
+
let current = '';
|
|
225
|
+
for (const line of sql.split('\n')) {
|
|
226
|
+
const trimmed = line.trim();
|
|
227
|
+
// Skip empty lines and comments
|
|
228
|
+
if (!trimmed || trimmed.startsWith('--')) {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
current += line + '\n';
|
|
232
|
+
// If line ends with semicolon, it's end of statement
|
|
233
|
+
if (trimmed.endsWith(';')) {
|
|
234
|
+
const stmt = current.trim();
|
|
235
|
+
if (stmt && stmt !== ';') {
|
|
236
|
+
statements.push(stmt);
|
|
237
|
+
}
|
|
238
|
+
current = '';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Handle any remaining content
|
|
242
|
+
if (current.trim()) {
|
|
243
|
+
statements.push(current.trim());
|
|
244
|
+
}
|
|
245
|
+
return statements;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Run auth migrations against a database.
|
|
249
|
+
*
|
|
250
|
+
* @param options.sql - SQL to execute (from generateAuthSchemaSql or custom)
|
|
251
|
+
*/
|
|
252
|
+
export async function runAuthMigrations(options) {
|
|
253
|
+
const { logger, auth, orgId, region, databaseName, sql } = options;
|
|
254
|
+
const catalystClient = getCatalystAPIClient(logger, auth, region);
|
|
255
|
+
const statements = splitSqlStatements(sql);
|
|
256
|
+
await tui.spinner({
|
|
257
|
+
message: `Creating auth tables in database "${databaseName}" (${statements.length} SQL statements)`,
|
|
258
|
+
clearOnSuccess: true,
|
|
259
|
+
callback: async () => {
|
|
260
|
+
for (const statement of statements) {
|
|
261
|
+
await dbQuery(catalystClient, {
|
|
262
|
+
database: databaseName,
|
|
263
|
+
query: statement,
|
|
264
|
+
orgId,
|
|
265
|
+
region,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
tui.success(`Auth tables created in ${tui.bold(databaseName)}`);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Generate the auth.ts file content
|
|
274
|
+
*/
|
|
275
|
+
export function generateAuthFileContent() {
|
|
276
|
+
return `/**
|
|
277
|
+
* Agentuity Auth configuration.
|
|
278
|
+
*
|
|
279
|
+
* This is the single source of truth for authentication in this project.
|
|
280
|
+
* All auth tables are stored in your Postgres database.
|
|
281
|
+
*/
|
|
282
|
+
|
|
283
|
+
import {
|
|
284
|
+
createAuth,
|
|
285
|
+
createSessionMiddleware,
|
|
286
|
+
createApiKeyMiddleware,
|
|
287
|
+
} from '@agentuity/auth';
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Database URL for authentication.
|
|
291
|
+
*
|
|
292
|
+
* Set via DATABASE_URL environment variable.
|
|
293
|
+
* Get yours from: \`agentuity cloud database list --region use --json\`
|
|
294
|
+
*/
|
|
295
|
+
const DATABASE_URL = process.env.DATABASE_URL;
|
|
296
|
+
|
|
297
|
+
if (!DATABASE_URL) {
|
|
298
|
+
throw new Error('DATABASE_URL environment variable is required for authentication');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Agentuity Auth instance with sensible defaults.
|
|
303
|
+
*
|
|
304
|
+
* Defaults:
|
|
305
|
+
* - basePath: '/api/auth'
|
|
306
|
+
* - emailAndPassword: { enabled: true }
|
|
307
|
+
* - Uses AGENTUITY_AUTH_SECRET env var for signing
|
|
308
|
+
*
|
|
309
|
+
* Default plugins included:
|
|
310
|
+
* - organization (multi-tenancy)
|
|
311
|
+
* - jwt (token signing)
|
|
312
|
+
* - bearer (API auth)
|
|
313
|
+
* - apiKey (programmatic access)
|
|
314
|
+
*/
|
|
315
|
+
export const auth = createAuth({
|
|
316
|
+
// Simplest setup: just provide the connection string
|
|
317
|
+
// We create pg pool + Drizzle internally with joins enabled
|
|
318
|
+
connectionString: DATABASE_URL,
|
|
319
|
+
// All options below have sensible defaults and can be omitted:
|
|
320
|
+
// secret: process.env.AGENTUITY_AUTH_SECRET, // auto-resolved from env
|
|
321
|
+
// basePath: '/api/auth', // default
|
|
322
|
+
// emailAndPassword: { enabled: true }, // default
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Session middleware - validates cookies/bearer tokens.
|
|
327
|
+
* Use for routes that require authentication.
|
|
328
|
+
*/
|
|
329
|
+
export const authMiddleware = createSessionMiddleware(auth);
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Optional auth middleware - allows anonymous access.
|
|
333
|
+
* Sets ctx.auth = null for unauthenticated requests.
|
|
334
|
+
*/
|
|
335
|
+
export const optionalAuthMiddleware = createSessionMiddleware(auth, { optional: true });
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* API key middleware for programmatic access.
|
|
339
|
+
* Use for webhook endpoints or external integrations.
|
|
340
|
+
*/
|
|
341
|
+
export const apiKeyMiddleware = createApiKeyMiddleware(auth);
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Optional API key middleware - continues without auth if no API key present.
|
|
345
|
+
*/
|
|
346
|
+
export const optionalApiKeyMiddleware = createApiKeyMiddleware(auth, { optional: true });
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Type export for end-to-end type safety.
|
|
350
|
+
*/
|
|
351
|
+
export type Auth = typeof auth;
|
|
352
|
+
`;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Print integration examples to the console
|
|
356
|
+
*/
|
|
357
|
+
export function printIntegrationExamples() {
|
|
358
|
+
tui.newline();
|
|
359
|
+
tui.info(tui.bold('Next Steps - Add these to your project:'));
|
|
360
|
+
tui.newline();
|
|
361
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
362
|
+
console.log(tui.bold(' 1. Set up your API routes (e.g., src/api/index.ts):'));
|
|
363
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
364
|
+
console.log(`
|
|
365
|
+
import { createRouter } from '@agentuity/runtime';
|
|
366
|
+
import { mountAuthRoutes } from '@agentuity/auth';
|
|
367
|
+
import { auth, authMiddleware } from '../auth';
|
|
368
|
+
|
|
369
|
+
const api = createRouter();
|
|
370
|
+
|
|
371
|
+
// Mount auth routes (sign-in, sign-up, sign-out, session, etc.)
|
|
372
|
+
// Must match the basePath configured in createAuth (default: /api/auth)
|
|
373
|
+
api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth));
|
|
374
|
+
|
|
375
|
+
// Protect your API routes with auth middleware
|
|
376
|
+
api.use('/api/*', authMiddleware);
|
|
377
|
+
|
|
378
|
+
api.get('/api/me', async (c) => {
|
|
379
|
+
const user = await c.var.auth.getUser();
|
|
380
|
+
return c.json({ id: user.id, email: user.email });
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
export default api;
|
|
384
|
+
`);
|
|
385
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
386
|
+
console.log(tui.bold(' 2. Wrap your React app with AuthProvider:'));
|
|
387
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
388
|
+
console.log(`
|
|
389
|
+
import { AgentuityProvider } from '@agentuity/react';
|
|
390
|
+
import { createAuthClient } from '@agentuity/auth/react';
|
|
391
|
+
import { AuthProvider } from '@agentuity/auth';
|
|
392
|
+
|
|
393
|
+
const authClient = createAuthClient();
|
|
394
|
+
|
|
395
|
+
function App() {
|
|
396
|
+
return (
|
|
397
|
+
<AgentuityProvider>
|
|
398
|
+
<AuthProvider authClient={authClient}>
|
|
399
|
+
{/* your app */}
|
|
400
|
+
</AuthProvider>
|
|
401
|
+
</AgentuityProvider>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
`);
|
|
405
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
406
|
+
console.log(tui.bold(' 3. Access auth in agents via ctx.auth:'));
|
|
407
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
408
|
+
console.log(`
|
|
409
|
+
import { createAgent } from '@agentuity/runtime';
|
|
410
|
+
|
|
411
|
+
export default createAgent('my-agent', {
|
|
412
|
+
schema: { input: s.object({ name: s.string() }), output: s.string() },
|
|
413
|
+
handler: async (ctx, input) => {
|
|
414
|
+
// ctx.auth is available when using auth middleware
|
|
415
|
+
if (ctx.auth) {
|
|
416
|
+
const user = await ctx.auth.getUser();
|
|
417
|
+
return \`Hello, \${user.email}!\`;
|
|
418
|
+
}
|
|
419
|
+
return 'Hello, anonymous!';
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
`);
|
|
423
|
+
tui.newline();
|
|
424
|
+
console.log(tui.muted('━'.repeat(60)));
|
|
425
|
+
tui.info('Checklist:');
|
|
426
|
+
console.log(` ${tui.tuiColors.success('✓')} DATABASE_URL configured`);
|
|
427
|
+
console.log(` ${tui.tuiColors.success('✓')} AGENTUITY_AUTH_SECRET configured`);
|
|
428
|
+
console.log(` ${tui.tuiColors.success('✓')} Auth tables migrated`);
|
|
429
|
+
console.log(` ${tui.tuiColors.success('✓')} Dependencies installed`);
|
|
430
|
+
console.log(` ${tui.muted('○')} Wire Hono middleware`);
|
|
431
|
+
console.log(` ${tui.muted('○')} Add auth routes (mountAuthRoutes at /api/auth/*)`);
|
|
432
|
+
console.log(` ${tui.muted('○')} Wrap app with AuthProvider`);
|
|
433
|
+
tui.newline();
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/cmd/project/auth/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/index.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO,mCAgBlB,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { createProjectSubcommand } from './create';
|
|
|
3
3
|
import { listSubcommand } from './list';
|
|
4
4
|
import { deleteSubcommand } from './delete';
|
|
5
5
|
import { showSubcommand } from './show';
|
|
6
|
+
import { authCommand } from './auth';
|
|
6
7
|
import { getCommand } from '../../command-prefix';
|
|
7
8
|
export const command = createCommand({
|
|
8
9
|
name: 'project',
|
|
@@ -11,7 +12,14 @@ export const command = createCommand({
|
|
|
11
12
|
examples: [
|
|
12
13
|
{ command: getCommand('project create my-agent'), description: 'Create a new project' },
|
|
13
14
|
{ command: getCommand('project list'), description: 'List all projects' },
|
|
15
|
+
{ command: getCommand('project auth init'), description: 'Set up Agentuity Auth' },
|
|
16
|
+
],
|
|
17
|
+
subcommands: [
|
|
18
|
+
createProjectSubcommand,
|
|
19
|
+
listSubcommand,
|
|
20
|
+
deleteSubcommand,
|
|
21
|
+
showSubcommand,
|
|
22
|
+
authCommand,
|
|
14
23
|
],
|
|
15
|
-
subcommands: [createProjectSubcommand, listSubcommand, deleteSubcommand, showSubcommand],
|
|
16
24
|
});
|
|
17
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cmd/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACpC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,0BAA0B;IACvC,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IAC/B,QAAQ,EAAE;QACT,EAAE,OAAO,EAAE,UAAU,CAAC,yBAAyB,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE;QACvF,EAAE,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cmd/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACpC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,0BAA0B;IACvC,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IAC/B,QAAQ,EAAE;QACT,EAAE,OAAO,EAAE,UAAU,CAAC,yBAAyB,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE;QACvF,EAAE,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE;QACzE,EAAE,OAAO,EAAE,UAAU,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE;KAClF;IACD,WAAW,EAAE;QACZ,uBAAuB;QACvB,cAAc;QACd,gBAAgB;QAChB,cAAc;QACd,WAAW;KACX;CACD,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-flow.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/template-flow.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"template-flow.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/template-flow.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAmB3C,UAAU,iBAAiB;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkiB7E"}
|
|
@@ -12,6 +12,7 @@ import { ErrorCode } from '../../errors';
|
|
|
12
12
|
import { createProjectConfig } from '../../config';
|
|
13
13
|
import { findExistingEnvFile, readEnvFile, filterAgentuitySdkKeys, splitEnvAndSecrets, addResourceEnvVars, } from '../../env-util';
|
|
14
14
|
import { promptForDNS } from '../../domain';
|
|
15
|
+
import { ensureAuthDependencies, runAuthMigrations, generateAuthFileContent, printIntegrationExamples, generateAuthSchemaSql, } from './auth/shared';
|
|
15
16
|
export async function runCreateFlow(options) {
|
|
16
17
|
const { projectName: initialProjectName, dir: targetDir, template: initialTemplate, templateDir, templateBranch, skipPrompts, logger, auth, config, orgId: selectedOrgId, region, apiClient, domains, } = options;
|
|
17
18
|
// Fetch available templates
|
|
@@ -278,6 +279,92 @@ export async function runCreateFlow(options) {
|
|
|
278
279
|
}
|
|
279
280
|
}
|
|
280
281
|
}
|
|
282
|
+
// Auth setup - either from template or user choice
|
|
283
|
+
const templateHasAuth = selectedTemplate.id === 'agentuity-auth';
|
|
284
|
+
let authEnabled = templateHasAuth; // Auth templates have auth enabled by default
|
|
285
|
+
let authDatabaseName;
|
|
286
|
+
let authDatabaseUrl;
|
|
287
|
+
// For non-auth templates, ask if they want to enable auth
|
|
288
|
+
if (auth && catalystClient && orgId && region && !skipPrompts && !templateHasAuth) {
|
|
289
|
+
const enableAuth = await prompt.select({
|
|
290
|
+
message: 'Enable Agentuity Authentication?',
|
|
291
|
+
options: [
|
|
292
|
+
{ value: 'no', label: "No, I'll add auth later" },
|
|
293
|
+
{ value: 'yes', label: 'Yes, set up Agentuity Auth' },
|
|
294
|
+
],
|
|
295
|
+
});
|
|
296
|
+
if (enableAuth === 'yes') {
|
|
297
|
+
authEnabled = true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Set up database and secret for any auth-enabled project
|
|
301
|
+
if (authEnabled && auth && catalystClient && orgId && region && !skipPrompts) {
|
|
302
|
+
// If a database was already selected/created above, use it for auth
|
|
303
|
+
if (resourceEnvVars.DATABASE_URL) {
|
|
304
|
+
authDatabaseUrl = resourceEnvVars.DATABASE_URL;
|
|
305
|
+
// Extract database name from URL using proper URL parsing
|
|
306
|
+
try {
|
|
307
|
+
const dbUrl = new URL(authDatabaseUrl);
|
|
308
|
+
const dbName = dbUrl.pathname.replace(/^\/+/, ''); // Remove leading slashes
|
|
309
|
+
// Validate: non-empty and contains only safe characters
|
|
310
|
+
if (dbName && /^[A-Za-z0-9_-]+$/.test(dbName)) {
|
|
311
|
+
authDatabaseName = dbName;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// Invalid URL format, authDatabaseName stays undefined
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// No database selected yet, create one for auth
|
|
320
|
+
const created = await tui.spinner({
|
|
321
|
+
message: 'Provisioning database for auth',
|
|
322
|
+
clearOnSuccess: true,
|
|
323
|
+
callback: async () => {
|
|
324
|
+
return createResources(catalystClient, orgId, region, [{ type: 'db' }]);
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
authDatabaseName = created[0].name;
|
|
328
|
+
// Get env vars from created resource
|
|
329
|
+
if (created[0]?.env) {
|
|
330
|
+
authDatabaseUrl = created[0].env.DATABASE_URL;
|
|
331
|
+
// Also add to resourceEnvVars if not already set
|
|
332
|
+
if (!resourceEnvVars.DATABASE_URL) {
|
|
333
|
+
Object.assign(resourceEnvVars, created[0].env);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Install auth dependencies (skip for agentuity-auth template which has them)
|
|
338
|
+
if (!templateHasAuth) {
|
|
339
|
+
await ensureAuthDependencies({ projectDir: dest, logger });
|
|
340
|
+
// Generate auth.ts
|
|
341
|
+
const authFilePath = resolve(dest, 'src', 'auth.ts');
|
|
342
|
+
if (!existsSync(authFilePath)) {
|
|
343
|
+
const srcDir = resolve(dest, 'src');
|
|
344
|
+
if (!existsSync(srcDir)) {
|
|
345
|
+
await Bun.write(resolve(srcDir, '.gitkeep'), '');
|
|
346
|
+
}
|
|
347
|
+
await Bun.write(authFilePath, generateAuthFileContent());
|
|
348
|
+
tui.success('Created src/auth.ts');
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Run migrations
|
|
352
|
+
if (authDatabaseName) {
|
|
353
|
+
const sql = await tui.spinner({
|
|
354
|
+
message: 'Preparing auth database schema...',
|
|
355
|
+
clearOnSuccess: true,
|
|
356
|
+
callback: () => generateAuthSchemaSql(dest),
|
|
357
|
+
});
|
|
358
|
+
await runAuthMigrations({
|
|
359
|
+
logger,
|
|
360
|
+
auth,
|
|
361
|
+
orgId,
|
|
362
|
+
region,
|
|
363
|
+
databaseName: authDatabaseName,
|
|
364
|
+
sql,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
281
368
|
let projectId;
|
|
282
369
|
if (auth && apiClient && orgId) {
|
|
283
370
|
const cloudRegion = region ?? process.env.AGENTUITY_REGION ?? 'usc';
|
|
@@ -312,9 +399,24 @@ export async function runCreateFlow(options) {
|
|
|
312
399
|
});
|
|
313
400
|
},
|
|
314
401
|
});
|
|
402
|
+
// Add auth secret to resourceEnvVars if auth is enabled
|
|
403
|
+
if (authEnabled && !resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
404
|
+
const devSecret = `dev-${crypto.randomUUID()}`;
|
|
405
|
+
resourceEnvVars.AGENTUITY_AUTH_SECRET = devSecret;
|
|
406
|
+
}
|
|
315
407
|
// Write resource environment variables to .env
|
|
316
408
|
if (Object.keys(resourceEnvVars).length > 0) {
|
|
317
409
|
await addResourceEnvVars(dest, resourceEnvVars);
|
|
410
|
+
// Show user feedback for auth-related env vars
|
|
411
|
+
if (authEnabled) {
|
|
412
|
+
if (resourceEnvVars.DATABASE_URL) {
|
|
413
|
+
tui.success('DATABASE_URL added to .env');
|
|
414
|
+
}
|
|
415
|
+
if (resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
416
|
+
tui.success('AGENTUITY_AUTH_SECRET added to .env');
|
|
417
|
+
tui.info(`Generate one with: ${tui.muted('npx @better-auth/cli secret')} or ${tui.muted('openssl rand -hex 32')}`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
318
420
|
}
|
|
319
421
|
// After registration, push any existing env/secrets from .env
|
|
320
422
|
if (projectId) {
|
|
@@ -373,6 +475,10 @@ export async function runCreateFlow(options) {
|
|
|
373
475
|
await promptForDNS(projectId, _domains, config);
|
|
374
476
|
}
|
|
375
477
|
}
|
|
478
|
+
// Print auth integration examples if auth was enabled (skip for auth template - already set up)
|
|
479
|
+
if (authEnabled && !templateHasAuth) {
|
|
480
|
+
printIntegrationExamples();
|
|
481
|
+
}
|
|
376
482
|
}
|
|
377
483
|
/**
|
|
378
484
|
* Sanitize a project name to create a safe directory/package name
|