@agentuity/cli 0.0.85 → 0.0.87
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/bin/cli.ts +9 -0
- package/dist/bun-path.d.ts +9 -0
- package/dist/bun-path.d.ts.map +1 -0
- package/dist/bun-path.js +24 -0
- package/dist/bun-path.js.map +1 -0
- package/dist/cmd/ai/index.d.ts.map +1 -1
- package/dist/cmd/ai/index.js +1 -0
- package/dist/cmd/ai/index.js.map +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +5 -0
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/bundler.d.ts +1 -1
- package/dist/cmd/build/bundler.d.ts.map +1 -1
- package/dist/cmd/build/bundler.js +99 -81
- package/dist/cmd/build/bundler.js.map +1 -1
- package/dist/cmd/build/patch/_util.js +6 -6
- package/dist/cmd/build/patch/_util.js.map +1 -1
- package/dist/cmd/build/patch/llm.js +1 -1
- package/dist/cmd/build/patch/llm.js.map +1 -1
- package/dist/cmd/build/plugin.d.ts.map +1 -1
- package/dist/cmd/build/plugin.js +21 -14
- package/dist/cmd/build/plugin.js.map +1 -1
- package/dist/cmd/build/route-discovery.d.ts +8 -4
- package/dist/cmd/build/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/route-discovery.js +10 -5
- package/dist/cmd/build/route-discovery.js.map +1 -1
- package/dist/cmd/cloud/scp/download.js +3 -3
- package/dist/cmd/cloud/scp/download.js.map +1 -1
- package/dist/cmd/cloud/scp/upload.js +3 -3
- package/dist/cmd/cloud/scp/upload.js.map +1 -1
- package/dist/cmd/cloud/ssh.js +3 -3
- package/dist/cmd/cloud/ssh.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +11 -1
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +7 -0
- package/dist/cmd/index.js.map +1 -1
- package/dist/cmd/profile/create.d.ts.map +1 -1
- package/dist/cmd/profile/create.js +1 -0
- package/dist/cmd/profile/create.js.map +1 -1
- package/dist/cmd/project/download.d.ts.map +1 -1
- package/dist/cmd/project/download.js +5 -15
- package/dist/cmd/project/download.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts +20 -0
- package/dist/cmd/upgrade/index.d.ts.map +1 -0
- package/dist/cmd/upgrade/index.js +307 -0
- package/dist/cmd/upgrade/index.js.map +1 -0
- package/dist/cmd/version/index.d.ts.map +1 -1
- package/dist/cmd/version/index.js +1 -0
- package/dist/cmd/version/index.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -94
- package/dist/config.js.map +1 -1
- package/dist/download.d.ts.map +1 -1
- package/dist/download.js +1 -6
- package/dist/download.js.map +1 -1
- package/dist/git-helper.d.ts +22 -0
- package/dist/git-helper.d.ts.map +1 -0
- package/dist/git-helper.js +71 -0
- package/dist/git-helper.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +16 -0
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/dependency-checker.d.ts +20 -0
- package/dist/utils/dependency-checker.d.ts.map +1 -0
- package/dist/utils/dependency-checker.js +161 -0
- package/dist/utils/dependency-checker.js.map +1 -0
- package/dist/version-check.d.ts +13 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +177 -0
- package/dist/version-check.js.map +1 -0
- package/package.json +3 -3
- package/src/bun-path.ts +26 -0
- package/src/cmd/ai/index.ts +1 -0
- package/src/cmd/build/ast.ts +7 -0
- package/src/cmd/build/bundler.ts +115 -94
- package/src/cmd/build/patch/_util.ts +6 -6
- package/src/cmd/build/patch/llm.ts +1 -1
- package/src/cmd/build/plugin.ts +23 -16
- package/src/cmd/build/route-discovery.ts +10 -5
- package/src/cmd/cloud/scp/download.ts +3 -3
- package/src/cmd/cloud/scp/upload.ts +3 -3
- package/src/cmd/cloud/ssh.ts +3 -3
- package/src/cmd/dev/index.ts +17 -1
- package/src/cmd/index.ts +8 -0
- package/src/cmd/profile/create.ts +1 -0
- package/src/cmd/project/download.ts +6 -14
- package/src/cmd/upgrade/index.ts +365 -0
- package/src/cmd/version/index.ts +1 -0
- package/src/config.ts +12 -121
- package/src/download.ts +1 -7
- package/src/git-helper.ts +74 -0
- package/src/index.ts +2 -0
- package/src/tui.ts +19 -0
- package/src/types.ts +7 -0
- package/src/utils/dependency-checker.ts +207 -0
- package/src/version-check.ts +234 -0
package/src/cmd/build/bundler.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { Logger } from '../../types';
|
|
|
14
14
|
import { generateWorkbenchMainTsx, generateWorkbenchIndexHtml } from './workbench';
|
|
15
15
|
import { analyzeWorkbench, type WorkbenchAnalysis } from './ast';
|
|
16
16
|
import { type DeployOptions } from '../../schemas/deploy';
|
|
17
|
+
import { checkAndUpgradeDependencies } from '../../utils/dependency-checker';
|
|
17
18
|
|
|
18
19
|
const minBunVersion = '>=1.3.3';
|
|
19
20
|
|
|
@@ -102,7 +103,6 @@ export async function bundle({
|
|
|
102
103
|
dev = false,
|
|
103
104
|
rootDir,
|
|
104
105
|
project,
|
|
105
|
-
port,
|
|
106
106
|
outDir: customOutDir,
|
|
107
107
|
tag,
|
|
108
108
|
logsUrl,
|
|
@@ -131,6 +131,14 @@ export async function bundle({
|
|
|
131
131
|
const versionOutput = await checkBunVersion();
|
|
132
132
|
output.push(...versionOutput);
|
|
133
133
|
|
|
134
|
+
// Check and upgrade @agentuity/* dependencies if needed
|
|
135
|
+
const upgradeResult = await checkAndUpgradeDependencies(rootDir, logger);
|
|
136
|
+
if (upgradeResult.failed.length > 0 && process.stdin.isTTY) {
|
|
137
|
+
throw new BuildFailedError({
|
|
138
|
+
message: `Failed to upgrade dependencies: ${upgradeResult.failed.join(', ')}`,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
134
142
|
const outDir = customOutDir ?? join(rootDir, '.agentuity');
|
|
135
143
|
const srcDir = join(rootDir, 'src');
|
|
136
144
|
|
|
@@ -377,6 +385,26 @@ export async function bundle({
|
|
|
377
385
|
}
|
|
378
386
|
}
|
|
379
387
|
|
|
388
|
+
// must always set for the template always
|
|
389
|
+
define['process.env.AGENTUITY_PUBLIC_WORKBENCH_PATH'] = JSON.stringify('');
|
|
390
|
+
|
|
391
|
+
// Analyze workbench config early to set environment variables for web build
|
|
392
|
+
if (existsSync(appFile)) {
|
|
393
|
+
if (!workbench) {
|
|
394
|
+
const appContent = await Bun.file(appFile).text();
|
|
395
|
+
workbench = analyzeWorkbench(appContent);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (workbench.hasWorkbench) {
|
|
399
|
+
// Create workbench config with proper defaults
|
|
400
|
+
const defaultConfig = { route: '/workbench', headers: {} };
|
|
401
|
+
const config = { ...defaultConfig, ...workbench.config };
|
|
402
|
+
|
|
403
|
+
// Add to define so process.env.AGENTUITY_PUBLIC_WORKBENCH_PATH gets replaced at build time
|
|
404
|
+
define['process.env.AGENTUITY_PUBLIC_WORKBENCH_PATH'] = JSON.stringify(config.route);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
380
408
|
// web folder is optional
|
|
381
409
|
const webDir = join(srcDir, 'web');
|
|
382
410
|
if (existsSync(webDir)) {
|
|
@@ -468,106 +496,99 @@ export async function bundle({
|
|
|
468
496
|
}
|
|
469
497
|
|
|
470
498
|
// Bundle workbench app if detected via setupWorkbench
|
|
471
|
-
if (existsSync(appFile)) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
naming: {
|
|
506
|
-
entry: '[dir]/[name].[ext]',
|
|
507
|
-
chunk: 'workbench/chunk/[name]-[hash].[ext]',
|
|
508
|
-
asset: 'workbench/asset/[name]-[hash].[ext]',
|
|
509
|
-
},
|
|
510
|
-
};
|
|
499
|
+
if (existsSync(appFile) && workbench && workbench.hasWorkbench) {
|
|
500
|
+
// Create workbench config with proper defaults
|
|
501
|
+
const defaultConfig = { route: '/workbench', headers: {} };
|
|
502
|
+
const config = { ...defaultConfig, ...workbench.config };
|
|
503
|
+
try {
|
|
504
|
+
// Generate workbench files on the fly instead of using files from package
|
|
505
|
+
const tempWorkbenchDir = join(outDir, 'temp-workbench');
|
|
506
|
+
mkdirSync(tempWorkbenchDir, { recursive: true });
|
|
507
|
+
|
|
508
|
+
// Generate files using templates
|
|
509
|
+
await Bun.write(join(tempWorkbenchDir, 'main.tsx'), generateWorkbenchMainTsx(config));
|
|
510
|
+
const workbenchIndexFile = join(tempWorkbenchDir, 'index.html');
|
|
511
|
+
await Bun.write(workbenchIndexFile, generateWorkbenchIndexHtml());
|
|
512
|
+
|
|
513
|
+
// Bundle workbench using generated files
|
|
514
|
+
// Disable splitting to avoid CommonJS/ESM module resolution conflicts
|
|
515
|
+
const workbenchBuildConfig: Bun.BuildConfig = {
|
|
516
|
+
entrypoints: [workbenchIndexFile],
|
|
517
|
+
outdir: join(outDir, 'workbench'),
|
|
518
|
+
sourcemap: dev ? 'inline' : 'linked',
|
|
519
|
+
target: 'browser',
|
|
520
|
+
format: 'esm',
|
|
521
|
+
banner: `// Generated file. DO NOT EDIT`,
|
|
522
|
+
minify: !dev,
|
|
523
|
+
drop: isProd ? ['debugger'] : undefined,
|
|
524
|
+
splitting: false,
|
|
525
|
+
packages: 'bundle',
|
|
526
|
+
conditions: ['browser', 'import', 'default'],
|
|
527
|
+
naming: {
|
|
528
|
+
entry: '[dir]/[name].[ext]',
|
|
529
|
+
chunk: 'workbench/chunk/[name]-[hash].[ext]',
|
|
530
|
+
asset: 'workbench/asset/[name]-[hash].[ext]',
|
|
531
|
+
},
|
|
532
|
+
};
|
|
511
533
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
}
|
|
528
|
-
// Clean up temp directory even on failure
|
|
529
|
-
rmSync(tempWorkbenchDir, { recursive: true, force: true });
|
|
530
|
-
logger.fatal('Workbench bundling failed');
|
|
534
|
+
const workbenchResult = await Bun.build(workbenchBuildConfig);
|
|
535
|
+
if (workbenchResult.success) {
|
|
536
|
+
logger.debug('Workbench bundled successfully');
|
|
537
|
+
// Clean up temp directory
|
|
538
|
+
rmSync(tempWorkbenchDir, { recursive: true, force: true });
|
|
539
|
+
} else {
|
|
540
|
+
logger.error('Workbench bundling failed. Logs:', workbenchResult.logs);
|
|
541
|
+
if (workbenchResult.logs.length === 0) {
|
|
542
|
+
logger.error('No build logs available. Checking generated files...');
|
|
543
|
+
logger.error('Temp dir exists:', await Bun.file(tempWorkbenchDir).exists());
|
|
544
|
+
logger.error('Index file exists:', await Bun.file(workbenchIndexFile).exists());
|
|
545
|
+
logger.error(
|
|
546
|
+
'Main.tsx exists:',
|
|
547
|
+
await Bun.file(join(tempWorkbenchDir, 'main.tsx')).exists()
|
|
548
|
+
);
|
|
531
549
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
+
// Clean up temp directory even on failure
|
|
551
|
+
rmSync(tempWorkbenchDir, { recursive: true, force: true });
|
|
552
|
+
logger.fatal('Workbench bundling failed');
|
|
553
|
+
}
|
|
554
|
+
} catch (error) {
|
|
555
|
+
logger.error('Failed to bundle workbench:', error);
|
|
556
|
+
// Collect all error messages
|
|
557
|
+
const errorMessages: string[] = [];
|
|
558
|
+
if (error instanceof AggregateError && Array.isArray(error.errors)) {
|
|
559
|
+
for (const err of error.errors) {
|
|
560
|
+
// Extract useful info from Bun's ResolveMessage errors
|
|
561
|
+
if (err && typeof err === 'object') {
|
|
562
|
+
const errObj = err as Record<string, unknown>;
|
|
563
|
+
if (typeof errObj.message === 'string') {
|
|
564
|
+
errorMessages.push(` ${errObj.message}`);
|
|
565
|
+
}
|
|
566
|
+
const position = errObj.position as Record<string, unknown> | undefined;
|
|
567
|
+
if (position?.file && position?.line && position?.column) {
|
|
568
|
+
errorMessages.push(
|
|
569
|
+
` at ${position.file}:${position.line}:${position.column}`
|
|
570
|
+
);
|
|
550
571
|
}
|
|
551
572
|
}
|
|
552
573
|
}
|
|
574
|
+
}
|
|
553
575
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// Don't continue if workbench bundling fails
|
|
569
|
-
logger.fatal(errorMessages.join('\n'));
|
|
576
|
+
// Show different tips based on whether we're in a monorepo or published package
|
|
577
|
+
const isMonorepo = await Bun.file(join(rootDir, '../../packages')).exists();
|
|
578
|
+
if (isMonorepo) {
|
|
579
|
+
errorMessages.push(
|
|
580
|
+
'\nTip: Make sure all @agentuity/* packages are built by',
|
|
581
|
+
'running "bun run build" from the monorepo root.'
|
|
582
|
+
);
|
|
583
|
+
} else {
|
|
584
|
+
errorMessages.push(
|
|
585
|
+
'\nTip: If you see module resolution errors, try running',
|
|
586
|
+
'"bun install" to ensure all dependencies are installed.'
|
|
587
|
+
);
|
|
570
588
|
}
|
|
589
|
+
|
|
590
|
+
// Don't continue if workbench bundling fails
|
|
591
|
+
logger.fatal(errorMessages.join('\n'));
|
|
571
592
|
}
|
|
572
593
|
}
|
|
573
594
|
|
|
@@ -44,13 +44,13 @@ export function generateGatewayEnvGuard(
|
|
|
44
44
|
provider: string
|
|
45
45
|
): string {
|
|
46
46
|
return `{
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
process.env.${apikey} =
|
|
51
|
-
process.env.${apibase} =
|
|
47
|
+
const _agentuity_sdk_key = process.env.AGENTUITY_SDK_KEY;
|
|
48
|
+
const _agentuity_url = process.env.AGENTUITY_AIGATEWAY_URL || process.env.AGENTUITY_TRANSPORT_URL || (_agentuity_sdk_key ? 'https://agentuity.ai' : '');
|
|
49
|
+
if (_agentuity_url && _agentuity_sdk_key) {
|
|
50
|
+
process.env.${apikey} = _agentuity_sdk_key;
|
|
51
|
+
process.env.${apibase} = _agentuity_url + '/gateway/${provider}';
|
|
52
52
|
console.debug('Enabled Agentuity AI Gateway for ${provider}');
|
|
53
|
-
} else {
|
|
53
|
+
} else if (!process.env.${apikey}) {
|
|
54
54
|
${generateEnvWarning(apikey)}
|
|
55
55
|
}
|
|
56
56
|
}
|
package/src/cmd/build/plugin.ts
CHANGED
|
@@ -375,6 +375,8 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
375
375
|
index += html;
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
|
+
// make paths absolute
|
|
379
|
+
index = index.replaceAll('./web/', '/web/');
|
|
378
380
|
const webstatic = serveStatic({ root: import.meta.dir + '/web' });
|
|
379
381
|
// In dev mode, serve from source; in prod, serve from build output
|
|
380
382
|
const publicRoot = ${isDevMode} ? ${JSON.stringify(join(srcDir, 'web', 'public'))} : import.meta.dir + '/web/public';
|
|
@@ -389,16 +391,8 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
389
391
|
if (path.includes('..') || path.includes('%2e%2e')) {
|
|
390
392
|
return c.notFound();
|
|
391
393
|
}
|
|
392
|
-
//
|
|
393
|
-
|
|
394
|
-
try {
|
|
395
|
-
// serveStatic calls next() internally if file not found
|
|
396
|
-
return await publicstatic(c, next);
|
|
397
|
-
} catch (err) {
|
|
398
|
-
return next();
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return next();
|
|
394
|
+
// serve default for any path not explicitly matched
|
|
395
|
+
return c.html(index);
|
|
402
396
|
});
|
|
403
397
|
})();`);
|
|
404
398
|
}
|
|
@@ -495,6 +489,14 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
495
489
|
}
|
|
496
490
|
|
|
497
491
|
for (const apiFile of apiFiles) {
|
|
492
|
+
// Quick check: skip files that don't contain createRouter or Hono
|
|
493
|
+
// This avoids expensive AST parsing for utility files
|
|
494
|
+
const fileContent = await Bun.file(apiFile).text();
|
|
495
|
+
if (!fileContent.includes('createRouter') && !fileContent.includes('new Hono')) {
|
|
496
|
+
logger.trace(`Skipping ${apiFile}: no createRouter or Hono found`);
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
|
|
498
500
|
try {
|
|
499
501
|
const routes = await parseRoute(rootDir, apiFile, projectId, deploymentId);
|
|
500
502
|
|
|
@@ -574,12 +576,17 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
574
576
|
});
|
|
575
577
|
}
|
|
576
578
|
} catch (error) {
|
|
577
|
-
// Skip files that don't have
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
579
|
+
// Skip files that don't have proper router setup despite containing createRouter/Hono
|
|
580
|
+
// (e.g., files that import but don't use them, or have syntax errors)
|
|
581
|
+
if (error instanceof Error) {
|
|
582
|
+
if (
|
|
583
|
+
error.message.includes('could not find default export') ||
|
|
584
|
+
error.message.includes('could not find an proper createRouter')
|
|
585
|
+
) {
|
|
586
|
+
logger.trace(`Skipping ${apiFile}: ${error.message}`);
|
|
587
|
+
} else {
|
|
588
|
+
throw error;
|
|
589
|
+
}
|
|
583
590
|
} else {
|
|
584
591
|
throw error;
|
|
585
592
|
}
|
|
@@ -19,17 +19,21 @@ export interface DiscoveredRouteFile {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Recursively discover all TypeScript
|
|
22
|
+
* Recursively discover all TypeScript files in an API directory.
|
|
23
|
+
* Any .ts file CAN be a route if it exports a router, but not all files MUST be routes.
|
|
24
|
+
* Files without router exports (utility files, types, helpers) are discovered but gracefully skipped during processing.
|
|
25
|
+
*
|
|
23
26
|
* Supports nested structures like:
|
|
24
|
-
* - src/api/index.ts (root API router)
|
|
27
|
+
* - src/api/index.ts (root API router - handled separately)
|
|
25
28
|
* - src/api/auth/route.ts -> mounted at /api/auth
|
|
29
|
+
* - src/api/auth/login.ts -> mounted at /api/auth
|
|
26
30
|
* - src/api/v1/users/route.ts -> mounted at /api/v1/users
|
|
27
|
-
* - src/api/
|
|
31
|
+
* - src/api/auth/helpers.ts -> discovered but skipped if no router export
|
|
28
32
|
*
|
|
29
33
|
* @param apiDir - Absolute path to the src/api directory
|
|
30
34
|
* @param currentDir - Current directory being scanned (used for recursion)
|
|
31
35
|
* @param results - Accumulated results (used for recursion)
|
|
32
|
-
* @returns Array of discovered
|
|
36
|
+
* @returns Array of discovered TypeScript files with mount information
|
|
33
37
|
*/
|
|
34
38
|
export function discoverRouteFiles(
|
|
35
39
|
apiDir: string,
|
|
@@ -63,8 +67,9 @@ export function discoverRouteFiles(
|
|
|
63
67
|
|
|
64
68
|
// For subdirectory files, determine mount path
|
|
65
69
|
// src/api/auth/route.ts -> /api/auth
|
|
70
|
+
// src/api/auth/login.ts -> /api/auth
|
|
66
71
|
// src/api/v1/users/route.ts -> /api/v1/users
|
|
67
|
-
// src/api/admin/
|
|
72
|
+
// src/api/admin/helpers.ts -> /api/admin (discovered but may be skipped during processing)
|
|
68
73
|
const pathParts = relativePath.split('/');
|
|
69
74
|
pathParts.pop(); // Remove filename
|
|
70
75
|
|
|
@@ -36,7 +36,7 @@ export const downloadCommand = createSubcommand({
|
|
|
36
36
|
description: 'Download multiple files',
|
|
37
37
|
},
|
|
38
38
|
],
|
|
39
|
-
requires: { apiClient: true, auth: true },
|
|
39
|
+
requires: { apiClient: true, auth: true, region: true },
|
|
40
40
|
optional: { project: true },
|
|
41
41
|
prerequisites: ['cloud deploy'],
|
|
42
42
|
schema: {
|
|
@@ -51,7 +51,7 @@ export const downloadCommand = createSubcommand({
|
|
|
51
51
|
},
|
|
52
52
|
|
|
53
53
|
async handler(ctx) {
|
|
54
|
-
const { apiClient, args, opts, project, projectDir, config } = ctx;
|
|
54
|
+
const { apiClient, args, opts, project, projectDir, config, region } = ctx;
|
|
55
55
|
|
|
56
56
|
let identifier = opts?.identifier ?? project?.projectId;
|
|
57
57
|
|
|
@@ -59,7 +59,7 @@ export const downloadCommand = createSubcommand({
|
|
|
59
59
|
identifier = await tui.showProjectList(apiClient, true);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
const hostname = getIONHost(config);
|
|
62
|
+
const hostname = getIONHost(config, region);
|
|
63
63
|
const destination = args.destination ?? projectDir;
|
|
64
64
|
|
|
65
65
|
try {
|
|
@@ -39,7 +39,7 @@ export const uploadCommand = createSubcommand({
|
|
|
39
39
|
description: 'Upload multiple files',
|
|
40
40
|
},
|
|
41
41
|
],
|
|
42
|
-
requires: { apiClient: true, auth: true },
|
|
42
|
+
requires: { apiClient: true, auth: true, region: true },
|
|
43
43
|
schema: {
|
|
44
44
|
args,
|
|
45
45
|
options,
|
|
@@ -54,7 +54,7 @@ export const uploadCommand = createSubcommand({
|
|
|
54
54
|
prerequisites: ['cloud deploy'],
|
|
55
55
|
|
|
56
56
|
async handler(ctx) {
|
|
57
|
-
const { apiClient, args, opts, project, projectDir, config } = ctx;
|
|
57
|
+
const { apiClient, args, opts, project, projectDir, config, region } = ctx;
|
|
58
58
|
|
|
59
59
|
let identifier = opts?.identifier ?? project?.projectId;
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ export const uploadCommand = createSubcommand({
|
|
|
62
62
|
identifier = await tui.showProjectList(apiClient, true);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const hostname = getIONHost(config);
|
|
65
|
+
const hostname = getIONHost(config, region);
|
|
66
66
|
const destination = args.destination ?? '.';
|
|
67
67
|
|
|
68
68
|
try {
|
package/src/cmd/cloud/ssh.ts
CHANGED
|
@@ -35,13 +35,13 @@ export const sshSubcommand = createSubcommand({
|
|
|
35
35
|
},
|
|
36
36
|
],
|
|
37
37
|
toplevel: true,
|
|
38
|
-
requires: { auth: true, apiClient: true },
|
|
38
|
+
requires: { auth: true, apiClient: true, region: true },
|
|
39
39
|
optional: { project: true },
|
|
40
40
|
prerequisites: ['cloud deploy'],
|
|
41
41
|
schema: { args, options },
|
|
42
42
|
|
|
43
43
|
async handler(ctx) {
|
|
44
|
-
const { apiClient, project, projectDir, args, config, opts } = ctx;
|
|
44
|
+
const { apiClient, project, projectDir, args, config, opts, region } = ctx;
|
|
45
45
|
|
|
46
46
|
let projectId = project?.projectId;
|
|
47
47
|
let identifier = args?.identifier;
|
|
@@ -56,7 +56,7 @@ export const sshSubcommand = createSubcommand({
|
|
|
56
56
|
projectId = await tui.showProjectList(apiClient, true);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const hostname = getIONHost(config);
|
|
59
|
+
const hostname = getIONHost(config, region);
|
|
60
60
|
|
|
61
61
|
const cmd = ['ssh', `${identifier ?? projectId}@${hostname}`, command].filter(
|
|
62
62
|
Boolean
|
package/src/cmd/dev/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { type Config, createCommand } from '../../types';
|
|
|
16
16
|
import * as tui from '../../tui';
|
|
17
17
|
import { createAgentTemplates, createAPITemplates } from './templates';
|
|
18
18
|
import { generateEndpoint, type DevmodeResponse } from './api';
|
|
19
|
-
import { APIClient, getAPIBaseURL, getGravityDevModeURL } from '../../api';
|
|
19
|
+
import { APIClient, getAppBaseURL, getAPIBaseURL, getGravityDevModeURL } from '../../api';
|
|
20
20
|
import { download } from './download';
|
|
21
21
|
import { createDevmodeSyncService } from './sync';
|
|
22
22
|
import { getDevmodeDeploymentId } from '../build/ast';
|
|
@@ -105,6 +105,7 @@ export const command = createCommand({
|
|
|
105
105
|
let devmode: DevmodeResponse | undefined;
|
|
106
106
|
let gravityBin: string | undefined;
|
|
107
107
|
let gravityURL: string | undefined;
|
|
108
|
+
let appURL: string | undefined;
|
|
108
109
|
|
|
109
110
|
if (auth && project && opts.public) {
|
|
110
111
|
// Generate devmode endpoint only when using --public
|
|
@@ -123,6 +124,7 @@ export const command = createCommand({
|
|
|
123
124
|
config = _config;
|
|
124
125
|
devmode = endpoint;
|
|
125
126
|
gravityURL = getGravityDevModeURL(project.region, config);
|
|
127
|
+
appURL = `${getAppBaseURL(config)}/r/${project.projectId}`;
|
|
126
128
|
logger.trace('gravity url: %s', gravityURL);
|
|
127
129
|
}
|
|
128
130
|
|
|
@@ -179,6 +181,9 @@ export const command = createCommand({
|
|
|
179
181
|
? tui.link(`http://127.0.0.1:${opts.port}${workbench.config?.route ?? '/workbench'}`)
|
|
180
182
|
: tui.warn('Disabled')) +
|
|
181
183
|
'\n' +
|
|
184
|
+
tui.muted(tui.padRight('Dashboard:', padding)) +
|
|
185
|
+
(appURL ? tui.link(appURL) : tui.warn('Disabled')) +
|
|
186
|
+
'\n' +
|
|
182
187
|
(canDoInput
|
|
183
188
|
? '\n' + tui.muted('Press ') + tui.bold('h') + tui.muted(' for keyboard shortcuts')
|
|
184
189
|
: '');
|
|
@@ -933,6 +938,17 @@ export const command = createCommand({
|
|
|
933
938
|
return;
|
|
934
939
|
}
|
|
935
940
|
|
|
941
|
+
// Ignore .git folder
|
|
942
|
+
if (changedFile && (changedFile === '.git' || changedFile.startsWith('.git/'))) {
|
|
943
|
+
logger.trace(
|
|
944
|
+
'File change ignored (.git folder): %s (event: %s, file: %s)',
|
|
945
|
+
watchDir,
|
|
946
|
+
eventType,
|
|
947
|
+
changedFile
|
|
948
|
+
);
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
|
|
936
952
|
// Ignore changes in .agentuity directory (build output)
|
|
937
953
|
// Check both relative path and normalized absolute path
|
|
938
954
|
const isInAgentuityDir =
|
package/src/cmd/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CommandDefinition } from '../types';
|
|
2
|
+
import { isRunningFromExecutable } from './upgrade';
|
|
2
3
|
|
|
3
4
|
// Use dynamic imports for bundler compatibility while maintaining lazy loading
|
|
4
5
|
export async function discoverCommands(): Promise<CommandDefinition[]> {
|
|
@@ -12,12 +13,19 @@ export async function discoverCommands(): Promise<CommandDefinition[]> {
|
|
|
12
13
|
import('./profile').then((m) => m.command),
|
|
13
14
|
import('./project').then((m) => m.command),
|
|
14
15
|
import('./repl').then((m) => m.command),
|
|
16
|
+
import('./upgrade').then((m) => m.command),
|
|
15
17
|
import('./version').then((m) => m.command),
|
|
16
18
|
]);
|
|
17
19
|
|
|
18
20
|
const commands: CommandDefinition[] = [];
|
|
21
|
+
const isExecutable = isRunningFromExecutable();
|
|
19
22
|
|
|
20
23
|
for (const cmd of commandModules) {
|
|
24
|
+
// Skip commands that require running from an executable when not in one
|
|
25
|
+
if (cmd.executable && !isExecutable) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
commands.push(cmd);
|
|
22
30
|
|
|
23
31
|
// Auto-create hidden top-level aliases for subcommands with toplevel: true
|
|
@@ -73,6 +73,7 @@ export const createCommand = createSubcommand({
|
|
|
73
73
|
if (name === 'local') {
|
|
74
74
|
// if we're creating a local profile, go ahead and fill it out for the dev to make it easier to get started
|
|
75
75
|
const localConfig = (await loadConfig(filename)) as Config;
|
|
76
|
+
localConfig.name = name;
|
|
76
77
|
localConfig.overrides = {
|
|
77
78
|
api_url: 'https://api.agentuity.io',
|
|
78
79
|
app_url: 'https://app.agentuity.io',
|
|
@@ -228,21 +228,13 @@ export async function setupProject(options: SetupOptions): Promise<void> {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
// Initialize git repository if git is available
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
// Check for real git (not macOS stub that triggers Xcode CLT popup)
|
|
232
|
+
const { isGitAvailable, getDefaultBranch } = await import('../../git-helper');
|
|
233
|
+
const gitAvailable = await isGitAvailable();
|
|
234
|
+
|
|
235
|
+
if (gitAvailable) {
|
|
233
236
|
// Get default branch from git config, fallback to 'main'
|
|
234
|
-
|
|
235
|
-
try {
|
|
236
|
-
const result = Bun.spawnSync(['git', 'config', '--global', 'init.defaultBranch']);
|
|
237
|
-
if (result.exitCode === 0) {
|
|
238
|
-
const branch = result.stdout.toString().trim();
|
|
239
|
-
if (branch) {
|
|
240
|
-
defaultBranch = branch;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
} catch {
|
|
244
|
-
// Ignore errors, use fallback
|
|
245
|
-
}
|
|
237
|
+
const defaultBranch = (await getDefaultBranch()) || 'main';
|
|
246
238
|
|
|
247
239
|
// Git is available, initialize repository
|
|
248
240
|
await tui.runCommand({
|