@agentuity/cli 0.1.12 → 0.1.14

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.
Files changed (140) hide show
  1. package/dist/auth.d.ts +1 -1
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +6 -2
  4. package/dist/auth.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +44 -91
  7. package/dist/cli.js.map +1 -1
  8. package/dist/cmd/auth/index.d.ts.map +1 -1
  9. package/dist/cmd/auth/index.js +3 -0
  10. package/dist/cmd/auth/index.js.map +1 -1
  11. package/dist/cmd/auth/org/index.d.ts +2 -0
  12. package/dist/cmd/auth/org/index.d.ts.map +1 -0
  13. package/dist/cmd/auth/org/index.js +121 -0
  14. package/dist/cmd/auth/org/index.js.map +1 -0
  15. package/dist/cmd/build/vite/beacon-plugin.d.ts +19 -0
  16. package/dist/cmd/build/vite/beacon-plugin.d.ts.map +1 -0
  17. package/dist/cmd/build/vite/beacon-plugin.js +137 -0
  18. package/dist/cmd/build/vite/beacon-plugin.js.map +1 -0
  19. package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
  20. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  21. package/dist/cmd/build/vite/vite-builder.js +12 -2
  22. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  23. package/dist/cmd/build/webanalytics-generator.js +25 -9
  24. package/dist/cmd/build/webanalytics-generator.js.map +1 -1
  25. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  26. package/dist/cmd/cloud/db/get.js +7 -0
  27. package/dist/cmd/cloud/db/get.js.map +1 -1
  28. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  29. package/dist/cmd/cloud/db/list.js +19 -6
  30. package/dist/cmd/cloud/db/list.js.map +1 -1
  31. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  32. package/dist/cmd/cloud/deploy.js +24 -1
  33. package/dist/cmd/cloud/deploy.js.map +1 -1
  34. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
  35. package/dist/cmd/cloud/deployment/show.js +5 -0
  36. package/dist/cmd/cloud/deployment/show.js.map +1 -1
  37. package/dist/cmd/cloud/index.d.ts.map +1 -1
  38. package/dist/cmd/cloud/index.js +3 -0
  39. package/dist/cmd/cloud/index.js.map +1 -1
  40. package/dist/cmd/cloud/region/index.d.ts +2 -0
  41. package/dist/cmd/cloud/region/index.d.ts.map +1 -0
  42. package/dist/cmd/cloud/region/index.js +136 -0
  43. package/dist/cmd/cloud/region/index.js.map +1 -0
  44. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
  45. package/dist/cmd/cloud/sandbox/snapshot/build.js +35 -5
  46. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  47. package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
  48. package/dist/cmd/cloud/scp/download.js +4 -2
  49. package/dist/cmd/cloud/scp/download.js.map +1 -1
  50. package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
  51. package/dist/cmd/cloud/scp/upload.js +4 -2
  52. package/dist/cmd/cloud/scp/upload.js.map +1 -1
  53. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  54. package/dist/cmd/cloud/ssh.js +3 -1
  55. package/dist/cmd/cloud/ssh.js.map +1 -1
  56. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  57. package/dist/cmd/cloud/storage/get.js +12 -5
  58. package/dist/cmd/cloud/storage/get.js.map +1 -1
  59. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  60. package/dist/cmd/cloud/storage/list.js +10 -0
  61. package/dist/cmd/cloud/storage/list.js.map +1 -1
  62. package/dist/cmd/dev/index.d.ts.map +1 -1
  63. package/dist/cmd/dev/index.js +62 -5
  64. package/dist/cmd/dev/index.js.map +1 -1
  65. package/dist/cmd/help/index.d.ts.map +1 -1
  66. package/dist/cmd/help/index.js +8 -18
  67. package/dist/cmd/help/index.js.map +1 -1
  68. package/dist/cmd/project/create.d.ts.map +1 -1
  69. package/dist/cmd/project/create.js +10 -7
  70. package/dist/cmd/project/create.js.map +1 -1
  71. package/dist/cmd/project/import.d.ts +2 -0
  72. package/dist/cmd/project/import.d.ts.map +1 -0
  73. package/dist/cmd/project/import.js +88 -0
  74. package/dist/cmd/project/import.js.map +1 -0
  75. package/dist/cmd/project/index.d.ts.map +1 -1
  76. package/dist/cmd/project/index.js +3 -0
  77. package/dist/cmd/project/index.js.map +1 -1
  78. package/dist/cmd/project/reconcile.d.ts +67 -0
  79. package/dist/cmd/project/reconcile.d.ts.map +1 -0
  80. package/dist/cmd/project/reconcile.js +458 -0
  81. package/dist/cmd/project/reconcile.js.map +1 -0
  82. package/dist/cmd/project/template-flow.d.ts +11 -1
  83. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  84. package/dist/cmd/project/template-flow.js +25 -7
  85. package/dist/cmd/project/template-flow.js.map +1 -1
  86. package/dist/config.d.ts +8 -3
  87. package/dist/config.d.ts.map +1 -1
  88. package/dist/config.js +50 -21
  89. package/dist/config.js.map +1 -1
  90. package/dist/legacy-check.d.ts.map +1 -1
  91. package/dist/legacy-check.js +8 -0
  92. package/dist/legacy-check.js.map +1 -1
  93. package/dist/program-ref.d.ts +4 -0
  94. package/dist/program-ref.d.ts.map +1 -0
  95. package/dist/program-ref.js +8 -0
  96. package/dist/program-ref.js.map +1 -0
  97. package/dist/regions.d.ts +8 -0
  98. package/dist/regions.d.ts.map +1 -0
  99. package/dist/regions.js +77 -0
  100. package/dist/regions.js.map +1 -0
  101. package/dist/tui.d.ts.map +1 -1
  102. package/dist/tui.js +5 -4
  103. package/dist/tui.js.map +1 -1
  104. package/dist/types.d.ts +1 -0
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/types.js +1 -0
  107. package/dist/types.js.map +1 -1
  108. package/package.json +6 -6
  109. package/src/auth.ts +8 -8
  110. package/src/cli.ts +52 -108
  111. package/src/cmd/auth/index.ts +3 -0
  112. package/src/cmd/auth/org/index.ts +142 -0
  113. package/src/cmd/build/vite/beacon-plugin.ts +162 -0
  114. package/src/cmd/build/vite/vite-builder.ts +15 -2
  115. package/src/cmd/build/webanalytics-generator.ts +25 -9
  116. package/src/cmd/cloud/db/get.ts +7 -0
  117. package/src/cmd/cloud/db/list.ts +20 -6
  118. package/src/cmd/cloud/deploy.ts +32 -1
  119. package/src/cmd/cloud/deployment/show.ts +5 -0
  120. package/src/cmd/cloud/index.ts +3 -0
  121. package/src/cmd/cloud/region/index.ts +157 -0
  122. package/src/cmd/cloud/sandbox/snapshot/build.ts +42 -5
  123. package/src/cmd/cloud/scp/download.ts +6 -2
  124. package/src/cmd/cloud/scp/upload.ts +6 -2
  125. package/src/cmd/cloud/ssh.ts +5 -1
  126. package/src/cmd/cloud/storage/get.ts +12 -5
  127. package/src/cmd/cloud/storage/list.ts +11 -0
  128. package/src/cmd/dev/index.ts +62 -5
  129. package/src/cmd/help/index.ts +8 -22
  130. package/src/cmd/project/create.ts +10 -7
  131. package/src/cmd/project/import.ts +98 -0
  132. package/src/cmd/project/index.ts +3 -0
  133. package/src/cmd/project/reconcile.ts +606 -0
  134. package/src/cmd/project/template-flow.ts +37 -7
  135. package/src/config.ts +58 -22
  136. package/src/legacy-check.ts +10 -0
  137. package/src/program-ref.ts +11 -0
  138. package/src/regions.ts +95 -0
  139. package/src/tui.ts +6 -4
  140. package/src/types.ts +1 -0
package/src/config.ts CHANGED
@@ -359,6 +359,29 @@ export async function saveOrgId(orgId: string): Promise<void> {
359
359
  await saveConfig(config);
360
360
  }
361
361
 
362
+ export async function clearOrgId(): Promise<void> {
363
+ const config = await getOrInitConfig();
364
+ if (config.preferences) {
365
+ delete (config.preferences as Record<string, unknown>).orgId;
366
+ await saveConfig(config);
367
+ }
368
+ }
369
+
370
+ export async function saveRegion(region: string): Promise<void> {
371
+ const config = await getOrInitConfig();
372
+ config.preferences = config.preferences || {};
373
+ (config.preferences as Record<string, unknown>).region = region;
374
+ await saveConfig(config);
375
+ }
376
+
377
+ export async function clearRegion(): Promise<void> {
378
+ const config = await getOrInitConfig();
379
+ if (config.preferences) {
380
+ delete (config.preferences as Record<string, unknown>).region;
381
+ await saveConfig(config);
382
+ }
383
+ }
384
+
362
385
  export async function getAuth(): Promise<AuthData | null> {
363
386
  const config = await loadConfig();
364
387
  const profileName = config?.name || defaultProfileName;
@@ -590,26 +613,29 @@ export async function createProjectConfig(dir: string, config: InitialProjectCon
590
613
  await Bun.write(envPath, content);
591
614
  await chmod(envPath, 0o600);
592
615
 
593
- // generate the vscode settings
616
+ // generate the vscode settings (only if they don't already exist)
594
617
  const vscodeDir = join(dir, '.vscode');
595
- mkdirSync(vscodeDir);
596
-
597
- const settings = {
598
- 'search.exclude': {
599
- '**/.git/**': true,
600
- '**/node_modules/**': true,
601
- '**/bun.lock': true,
602
- '**/.agentuity/**': true,
603
- },
604
- 'json.schemas': [
605
- {
606
- fileMatch: ['agentuity.json'],
607
- url: 'https://agentuity.dev/schema/cli/v1/agentuity.json',
618
+ const settingsPath = join(vscodeDir, 'settings.json');
619
+ if (!(await Bun.file(settingsPath).exists())) {
620
+ mkdirSync(vscodeDir, { recursive: true });
621
+
622
+ const settings = {
623
+ 'search.exclude': {
624
+ '**/.git/**': true,
625
+ '**/node_modules/**': true,
626
+ '**/bun.lock': true,
627
+ '**/.agentuity/**': true,
608
628
  },
609
- ],
610
- };
629
+ 'json.schemas': [
630
+ {
631
+ fileMatch: ['agentuity.json'],
632
+ url: 'https://agentuity.dev/schema/cli/v1/agentuity.json',
633
+ },
634
+ ],
635
+ };
611
636
 
612
- await Bun.write(join(vscodeDir, 'settings.json'), JSON.stringify(settings, null, 2));
637
+ await Bun.write(settingsPath, JSON.stringify(settings, null, 2));
638
+ }
613
639
  }
614
640
 
615
641
  export async function updateProjectConfig(
@@ -721,13 +747,18 @@ interface RegionsCacheData {
721
747
  /**
722
748
  * Get the default region using priority ordering:
723
749
  * 1. AGENTUITY_REGION environment variable
724
- * 2. First entry in region-{profile}.json (nearest region, sorted by distance)
725
- * 3. 'local' for local profile, 'usc' otherwise
750
+ * 2. 'local' for local profile
751
+ * 3. Saved region preference (config.preferences.region)
752
+ * 4. First entry in region-{profile}.json (nearest region, sorted by distance)
753
+ * 5. 'usc' fallback
726
754
  *
727
755
  * Used for API calls that can hit any Catalyst instance (global database operations).
728
756
  * Note: This is NOT called when --region flag is provided (handled at command level).
729
757
  */
730
- export async function getDefaultRegion(profileName = 'production'): Promise<string> {
758
+ export async function getDefaultRegion(
759
+ profileName = 'production',
760
+ config?: Config | null
761
+ ): Promise<string> {
731
762
  // 1. Check environment variable first
732
763
  if (process.env.AGENTUITY_REGION) {
733
764
  return process.env.AGENTUITY_REGION;
@@ -738,7 +769,12 @@ export async function getDefaultRegion(profileName = 'production'): Promise<stri
738
769
  return 'local';
739
770
  }
740
771
 
741
- // 3. Check cached regions file (sorted by distance)
772
+ // 3. Check saved region preference
773
+ if (config?.preferences?.region) {
774
+ return config.preferences.region;
775
+ }
776
+
777
+ // 4. Check cached regions file (sorted by distance)
742
778
  try {
743
779
  const cachePath = join(getDefaultConfigDir(), `regions-${profileName}.json`);
744
780
  const file = Bun.file(cachePath);
@@ -752,7 +788,7 @@ export async function getDefaultRegion(profileName = 'production'): Promise<stri
752
788
  // Fall through to default
753
789
  }
754
790
 
755
- // 4. Final fallback
791
+ // 5. Final fallback
756
792
  return 'usc';
757
793
  }
758
794
 
@@ -23,6 +23,11 @@ export async function checkLegacyCLI(): Promise<void> {
23
23
  join(homeDir, '.local/bin/agentuity'), // XDG user bin
24
24
  ];
25
25
 
26
+ // Exclude the currently running executable from the legacy check
27
+ // This prevents the new CLI from detecting itself as legacy when installed
28
+ // in standard system locations like /usr/local/bin
29
+ const currentExecutable = process.execPath;
30
+
26
31
  const foundInstalls: LegacyInstall[] = [];
27
32
 
28
33
  // Check if Homebrew manages the agentuity package
@@ -40,6 +45,11 @@ export async function checkLegacyCLI(): Promise<void> {
40
45
 
41
46
  // Check file system locations
42
47
  for (const location of legacyLocations) {
48
+ // Skip if this is the currently running executable
49
+ if (location === currentExecutable) {
50
+ continue;
51
+ }
52
+
43
53
  const file = Bun.file(location);
44
54
  if (await file.exists()) {
45
55
  try {
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+
3
+ let programRef: Command | null = null;
4
+
5
+ export function setProgram(program: Command): void {
6
+ programRef = program;
7
+ }
8
+
9
+ export function getProgram(): Command | null {
10
+ return programRef;
11
+ }
package/src/regions.ts ADDED
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Region caching utilities for avoiding repeated API calls
3
+ */
4
+ import { join } from 'node:path';
5
+ import { mkdir, unlink } from 'node:fs/promises';
6
+ import type { Logger } from '@agentuity/core';
7
+ import { listRegions, type RegionList } from '@agentuity/server';
8
+ import { getDefaultConfigDir } from './config';
9
+ import type { APIClient } from './api';
10
+
11
+ const REGIONS_CACHE_MAX_AGE_MS = 5 * 24 * 60 * 60 * 1000; // 5 days
12
+ const LEGACY_REGIONS_CACHE_FILE = 'regions.json';
13
+
14
+ function getRegionsCacheFile(profileName: string): string {
15
+ return `regions-${profileName}.json`;
16
+ }
17
+
18
+ async function removeLegacyRegionsCache(logger: Logger): Promise<void> {
19
+ try {
20
+ const legacyPath = join(getDefaultConfigDir(), LEGACY_REGIONS_CACHE_FILE);
21
+ const file = Bun.file(legacyPath);
22
+ if (await file.exists()) {
23
+ await unlink(legacyPath);
24
+ logger.trace('removed legacy regions cache file');
25
+ }
26
+ } catch {
27
+ // Ignore errors when removing legacy file
28
+ }
29
+ }
30
+
31
+ interface RegionsCacheData {
32
+ timestamp: number;
33
+ regions: RegionList;
34
+ }
35
+
36
+ async function getCachedRegions(profileName: string, logger: Logger): Promise<RegionList | null> {
37
+ try {
38
+ // Clean up legacy single-file cache from older versions
39
+ await removeLegacyRegionsCache(logger);
40
+
41
+ const cachePath = join(getDefaultConfigDir(), getRegionsCacheFile(profileName));
42
+ const file = Bun.file(cachePath);
43
+ if (!(await file.exists())) {
44
+ return null;
45
+ }
46
+ const data: RegionsCacheData = await file.json();
47
+ const age = Date.now() - data.timestamp;
48
+ if (age > REGIONS_CACHE_MAX_AGE_MS) {
49
+ logger.trace('regions cache expired for profile %s (age: %dms)', profileName, age);
50
+ return null;
51
+ }
52
+ logger.trace('using cached regions for profile %s (age: %dms)', profileName, age);
53
+ return data.regions;
54
+ } catch (error) {
55
+ logger.trace('failed to read regions cache for profile %s: %s', profileName, error);
56
+ return null;
57
+ }
58
+ }
59
+
60
+ async function saveRegionsCache(
61
+ profileName: string,
62
+ regions: RegionList,
63
+ logger: Logger
64
+ ): Promise<void> {
65
+ try {
66
+ const cacheDir = getDefaultConfigDir();
67
+ await mkdir(cacheDir, { recursive: true });
68
+ const cachePath = join(cacheDir, getRegionsCacheFile(profileName));
69
+ const data: RegionsCacheData = {
70
+ timestamp: Date.now(),
71
+ regions,
72
+ };
73
+ await Bun.write(cachePath, JSON.stringify(data));
74
+ logger.trace('saved regions cache for profile %s', profileName);
75
+ } catch (error) {
76
+ logger.trace('failed to save regions cache for profile %s: %s', profileName, error);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Fetch regions from API with caching
82
+ */
83
+ export async function fetchRegionsWithCache(
84
+ profileName: string,
85
+ apiClient: APIClient,
86
+ logger: Logger
87
+ ): Promise<RegionList> {
88
+ const cached = await getCachedRegions(profileName, logger);
89
+ if (cached) {
90
+ return cached;
91
+ }
92
+ const regions = await listRegions(apiClient);
93
+ await saveRegionsCache(profileName, regions, logger);
94
+ return regions;
95
+ }
package/src/tui.ts CHANGED
@@ -348,6 +348,11 @@ export function link(url: string, title?: string, color = getColor('link')): str
348
348
  * Check if terminal supports OSC 8 hyperlinks
349
349
  */
350
350
  export function supportsHyperlinks(): boolean {
351
+ // No hyperlink support without a TTY
352
+ if (!process.stdout.isTTY) {
353
+ return false;
354
+ }
355
+
351
356
  const term = process.env.TERM || '';
352
357
  const termProgram = process.env.TERM_PROGRAM || '';
353
358
  const wtSession = process.env.WT_SESSION || '';
@@ -360,7 +365,6 @@ export function supportsHyperlinks(): boolean {
360
365
  termProgram.includes('Apple_Terminal') ||
361
366
  termProgram.includes('Hyper') ||
362
367
  term.includes('xterm-kitty') ||
363
- term.includes('xterm-256color') ||
364
368
  wtSession !== '' // Windows Terminal
365
369
  );
366
370
  }
@@ -816,9 +820,7 @@ export function showLoggedOutMessage(appBaseUrl: string, hasProfile = false): vo
816
820
  const RESET = '\x1b[0m';
817
821
 
818
822
  const signupTitle = hasProfile ? 'Login' : 'Sign up / Login';
819
- const signupURL = hasProfile
820
- ? `${appBaseUrl}/sign-in`
821
- : `${appBaseUrl}/sign-up`;
823
+ const signupURL = hasProfile ? `${appBaseUrl}/sign-in` : `${appBaseUrl}/sign-up`;
822
824
  const showInline = supportsHyperlinks();
823
825
  const signupLink = showInline
824
826
  ? link(signupURL, signupTitle)
package/src/types.ts CHANGED
@@ -50,6 +50,7 @@ export const ConfigSchema = zod.object({
50
50
  last_legacy_warning: zod.number().optional().describe('Last legacy CLI warning timestamp'),
51
51
  signup_banner_shown: zod.boolean().optional().describe('If the signup banner was shown'),
52
52
  orgId: zod.string().optional().describe('Default organization ID'),
53
+ region: zod.string().optional().describe('Default cloud region'),
53
54
  project_dir: zod.string().optional().describe('Last used project directory'),
54
55
  })
55
56
  .optional()