@agentuity/cli 1.0.13 → 1.0.15

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 (135) hide show
  1. package/bin/cli.ts +8 -0
  2. package/dist/agent-detection.js +2 -2
  3. package/dist/agent-detection.js.map +1 -1
  4. package/dist/banner.js +2 -2
  5. package/dist/banner.js.map +1 -1
  6. package/dist/bun-path.d.ts.map +1 -1
  7. package/dist/bun-path.js +2 -1
  8. package/dist/bun-path.js.map +1 -1
  9. package/dist/cmd/build/ast.d.ts.map +1 -1
  10. package/dist/cmd/build/ast.js +87 -14
  11. package/dist/cmd/build/ast.js.map +1 -1
  12. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
  13. package/dist/cmd/build/vite/agent-discovery.js +3 -2
  14. package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
  15. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  16. package/dist/cmd/build/vite/metadata-generator.js +2 -1
  17. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  18. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  19. package/dist/cmd/build/vite/registry-generator.js +9 -7
  20. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  21. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  22. package/dist/cmd/build/vite/route-discovery.js +3 -2
  23. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  24. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  25. package/dist/cmd/cloud/deploy.js +19 -21
  26. package/dist/cmd/cloud/deploy.js.map +1 -1
  27. package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
  28. package/dist/cmd/cloud/env/delete.js +3 -26
  29. package/dist/cmd/cloud/env/delete.js.map +1 -1
  30. package/dist/cmd/cloud/env/import.d.ts.map +1 -1
  31. package/dist/cmd/cloud/env/import.js +3 -16
  32. package/dist/cmd/cloud/env/import.js.map +1 -1
  33. package/dist/cmd/cloud/env/set.d.ts.map +1 -1
  34. package/dist/cmd/cloud/env/set.js +3 -19
  35. package/dist/cmd/cloud/env/set.js.map +1 -1
  36. package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
  37. package/dist/cmd/cloud/sandbox/cp.js +2 -1
  38. package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
  39. package/dist/cmd/git/account/add.d.ts +6 -8
  40. package/dist/cmd/git/account/add.d.ts.map +1 -1
  41. package/dist/cmd/git/account/add.js +37 -151
  42. package/dist/cmd/git/account/add.js.map +1 -1
  43. package/dist/cmd/git/account/index.d.ts +0 -1
  44. package/dist/cmd/git/account/index.d.ts.map +1 -1
  45. package/dist/cmd/git/account/index.js +3 -4
  46. package/dist/cmd/git/account/index.js.map +1 -1
  47. package/dist/cmd/git/account/list.d.ts.map +1 -1
  48. package/dist/cmd/git/account/list.js +35 -67
  49. package/dist/cmd/git/account/list.js.map +1 -1
  50. package/dist/cmd/git/account/remove.d.ts.map +1 -1
  51. package/dist/cmd/git/account/remove.js +42 -84
  52. package/dist/cmd/git/account/remove.js.map +1 -1
  53. package/dist/cmd/git/api.d.ts +19 -23
  54. package/dist/cmd/git/api.d.ts.map +1 -1
  55. package/dist/cmd/git/api.js +38 -56
  56. package/dist/cmd/git/api.js.map +1 -1
  57. package/dist/cmd/git/identity/connect.d.ts +15 -0
  58. package/dist/cmd/git/identity/connect.d.ts.map +1 -0
  59. package/dist/cmd/git/identity/connect.js +135 -0
  60. package/dist/cmd/git/identity/connect.js.map +1 -0
  61. package/dist/cmd/git/identity/disconnect.d.ts +2 -0
  62. package/dist/cmd/git/identity/disconnect.d.ts.map +1 -0
  63. package/dist/cmd/git/identity/disconnect.js +83 -0
  64. package/dist/cmd/git/identity/disconnect.js.map +1 -0
  65. package/dist/cmd/git/identity/index.d.ts +2 -0
  66. package/dist/cmd/git/identity/index.d.ts.map +1 -0
  67. package/dist/cmd/git/identity/index.js +10 -0
  68. package/dist/cmd/git/identity/index.js.map +1 -0
  69. package/dist/cmd/git/identity/status.d.ts +2 -0
  70. package/dist/cmd/git/identity/status.d.ts.map +1 -0
  71. package/dist/cmd/git/identity/status.js +77 -0
  72. package/dist/cmd/git/identity/status.js.map +1 -0
  73. package/dist/cmd/git/index.d.ts +0 -1
  74. package/dist/cmd/git/index.d.ts.map +1 -1
  75. package/dist/cmd/git/index.js +3 -2
  76. package/dist/cmd/git/index.js.map +1 -1
  77. package/dist/cmd/git/link.d.ts +2 -3
  78. package/dist/cmd/git/link.d.ts.map +1 -1
  79. package/dist/cmd/git/link.js +22 -28
  80. package/dist/cmd/git/link.js.map +1 -1
  81. package/dist/cmd/git/list.d.ts.map +1 -1
  82. package/dist/cmd/git/list.js +42 -55
  83. package/dist/cmd/git/list.js.map +1 -1
  84. package/dist/cmd/git/status.d.ts.map +1 -1
  85. package/dist/cmd/git/status.js +51 -38
  86. package/dist/cmd/git/status.js.map +1 -1
  87. package/dist/cmd/upgrade/npm-availability.d.ts +6 -7
  88. package/dist/cmd/upgrade/npm-availability.d.ts.map +1 -1
  89. package/dist/cmd/upgrade/npm-availability.js +9 -18
  90. package/dist/cmd/upgrade/npm-availability.js.map +1 -1
  91. package/dist/config.d.ts.map +1 -1
  92. package/dist/config.js +14 -4
  93. package/dist/config.js.map +1 -1
  94. package/dist/utils/detectSubagent.d.ts.map +1 -1
  95. package/dist/utils/detectSubagent.js +3 -0
  96. package/dist/utils/detectSubagent.js.map +1 -1
  97. package/dist/utils/normalize-path.d.ts +11 -0
  98. package/dist/utils/normalize-path.d.ts.map +1 -0
  99. package/dist/utils/normalize-path.js +13 -0
  100. package/dist/utils/normalize-path.js.map +1 -0
  101. package/dist/utils/zip.d.ts.map +1 -1
  102. package/dist/utils/zip.js +2 -1
  103. package/dist/utils/zip.js.map +1 -1
  104. package/package.json +6 -6
  105. package/src/agent-detection.ts +2 -2
  106. package/src/banner.ts +2 -2
  107. package/src/bun-path.ts +2 -1
  108. package/src/cmd/build/ast.ts +96 -15
  109. package/src/cmd/build/vite/agent-discovery.ts +3 -2
  110. package/src/cmd/build/vite/metadata-generator.ts +2 -1
  111. package/src/cmd/build/vite/registry-generator.ts +9 -7
  112. package/src/cmd/build/vite/route-discovery.ts +3 -2
  113. package/src/cmd/cloud/deploy.ts +54 -61
  114. package/src/cmd/cloud/env/delete.ts +3 -34
  115. package/src/cmd/cloud/env/import.ts +2 -18
  116. package/src/cmd/cloud/env/set.ts +2 -21
  117. package/src/cmd/cloud/sandbox/cp.ts +2 -1
  118. package/src/cmd/git/account/add.ts +51 -190
  119. package/src/cmd/git/account/index.ts +3 -5
  120. package/src/cmd/git/account/list.ts +51 -82
  121. package/src/cmd/git/account/remove.ts +45 -95
  122. package/src/cmd/git/api.ts +49 -111
  123. package/src/cmd/git/identity/connect.ts +178 -0
  124. package/src/cmd/git/identity/disconnect.ts +103 -0
  125. package/src/cmd/git/identity/index.ts +10 -0
  126. package/src/cmd/git/identity/status.ts +96 -0
  127. package/src/cmd/git/index.ts +3 -3
  128. package/src/cmd/git/link.ts +32 -35
  129. package/src/cmd/git/list.ts +48 -59
  130. package/src/cmd/git/status.ts +55 -40
  131. package/src/cmd/upgrade/npm-availability.ts +14 -23
  132. package/src/config.ts +14 -5
  133. package/src/utils/detectSubagent.ts +5 -0
  134. package/src/utils/normalize-path.ts +12 -0
  135. package/src/utils/zip.ts +2 -1
@@ -1,22 +1,28 @@
1
- import { createSubcommand } from '../../types';
2
- import * as tui from '../../tui';
1
+ import { z } from 'zod';
3
2
  import { getCommand } from '../../command-prefix';
4
3
  import { ErrorCode } from '../../errors';
5
- import { getProjectGithubStatus, getGithubIntegrationStatus } from './api';
6
- import { z } from 'zod';
4
+ import * as tui from '../../tui';
5
+ import { createSubcommand } from '../../types';
6
+ import { getGithubIntegrationStatus, getProjectGithubStatus } from './api';
7
7
 
8
8
  const StatusResponseSchema = z.object({
9
- orgId: z.string().describe('Organization ID'),
10
- connected: z.boolean().describe('Whether GitHub is connected to the org'),
11
- integrations: z
9
+ connected: z.boolean().describe('Whether GitHub is connected'),
10
+ identity: z
11
+ .object({
12
+ githubUsername: z.string(),
13
+ githubEmail: z.string().optional(),
14
+ })
15
+ .nullable()
16
+ .describe('Connected GitHub identity'),
17
+ installations: z
12
18
  .array(
13
19
  z.object({
14
- id: z.string(),
15
- githubAccountName: z.string(),
16
- githubAccountType: z.enum(['user', 'org']),
20
+ installationId: z.string(),
21
+ accountName: z.string(),
22
+ accountType: z.enum(['User', 'Organization']),
17
23
  })
18
24
  )
19
- .describe('Connected GitHub accounts'),
25
+ .describe('GitHub App installations'),
20
26
  projectId: z.string().describe('Project ID'),
21
27
  linked: z.boolean().describe('Whether the project is linked to a repo'),
22
28
  repoFullName: z.string().optional().describe('Full repository name'),
@@ -50,11 +56,11 @@ export const statusSubcommand = createSubcommand({
50
56
  const { logger, apiClient, project, options } = ctx;
51
57
 
52
58
  try {
53
- // Get org-level GitHub status
54
- const orgStatus = await tui.spinner({
59
+ // Get user-level GitHub status
60
+ const githubStatus = await tui.spinner({
55
61
  message: 'Checking GitHub connection...',
56
62
  clearOnSuccess: true,
57
- callback: () => getGithubIntegrationStatus(apiClient, project.orgId),
63
+ callback: () => getGithubIntegrationStatus(apiClient),
58
64
  });
59
65
 
60
66
  // Get project-level link status
@@ -65,12 +71,17 @@ export const statusSubcommand = createSubcommand({
65
71
  });
66
72
 
67
73
  const result = {
68
- orgId: project.orgId,
69
- connected: orgStatus.connected,
70
- integrations: orgStatus.integrations.map((i) => ({
71
- id: i.id,
72
- githubAccountName: i.githubAccountName,
73
- githubAccountType: i.githubAccountType,
74
+ connected: githubStatus.connected,
75
+ identity: githubStatus.identity
76
+ ? {
77
+ githubUsername: githubStatus.identity.githubUsername,
78
+ githubEmail: githubStatus.identity.githubEmail,
79
+ }
80
+ : null,
81
+ installations: githubStatus.installations.map((i) => ({
82
+ installationId: i.installationId,
83
+ accountName: i.accountName,
84
+ accountType: i.accountType,
74
85
  })),
75
86
  projectId: project.projectId,
76
87
  linked: projectStatus.linked,
@@ -86,47 +97,51 @@ export const statusSubcommand = createSubcommand({
86
97
  }
87
98
 
88
99
  tui.newline();
89
- console.log(tui.bold('GitHub Status'));
100
+ tui.output(tui.bold('GitHub Status'));
90
101
  tui.newline();
91
102
 
92
- // Organization status
93
- console.log(`${tui.bold('Organization:')} ${project.orgId}`);
94
- if (orgStatus.connected && orgStatus.integrations.length > 0) {
95
- console.log(
96
- ` ${tui.colorSuccess('✓')} ${orgStatus.integrations.length} GitHub account${orgStatus.integrations.length > 1 ? 's' : ''} connected`
103
+ // GitHub identity status
104
+ if (githubStatus.connected && githubStatus.identity) {
105
+ tui.output(
106
+ `${tui.bold('GitHub:')} ${tui.colorSuccess('✓')} Connected as ${tui.bold(githubStatus.identity.githubUsername)}`
97
107
  );
98
- for (const integration of orgStatus.integrations) {
99
- const typeLabel = integration.githubAccountType === 'org' ? 'org' : 'user';
100
- console.log(` - ${integration.githubAccountName} ${tui.muted(`(${typeLabel})`)}`);
108
+ if (githubStatus.installations.length > 0) {
109
+ tui.output(
110
+ ` ${githubStatus.installations.length} installation${githubStatus.installations.length > 1 ? 's' : ''}`
111
+ );
112
+ for (const installation of githubStatus.installations) {
113
+ const typeLabel = installation.accountType === 'Organization' ? 'org' : 'user';
114
+ tui.output(` - ${installation.accountName} ${tui.muted(`(${typeLabel})`)}`);
115
+ }
101
116
  }
102
117
  } else {
103
- console.log(` ${tui.colorError('✗')} No GitHub accounts connected`);
104
- console.log(
105
- tui.muted(` Run ${tui.bold('agentuity git account add')} to connect one`)
118
+ tui.output(`${tui.bold('GitHub:')} ${tui.colorError('✗')} No GitHub account connected`);
119
+ tui.output(
120
+ tui.muted(` Run ${tui.bold('agentuity git identity connect')} to connect one`)
106
121
  );
107
122
  }
108
123
 
109
124
  tui.newline();
110
125
 
111
126
  // Project status
112
- console.log(`${tui.bold('Project:')} ${project.projectId}`);
127
+ tui.output(`${tui.bold('Project:')} ${project.projectId}`);
113
128
  if (projectStatus.linked) {
114
- console.log(
129
+ tui.output(
115
130
  ` ${tui.colorSuccess('✓')} Linked to ${tui.bold(projectStatus.repoFullName ?? '<unknown repository>')}`
116
131
  );
117
- console.log(` Branch: ${projectStatus.branch}`);
132
+ tui.output(` Branch: ${projectStatus.branch}`);
118
133
  if (projectStatus.directory) {
119
- console.log(` Directory: ${projectStatus.directory}`);
134
+ tui.output(` Directory: ${projectStatus.directory}`);
120
135
  }
121
- console.log(
136
+ tui.output(
122
137
  ` Auto-deploy: ${projectStatus.autoDeploy ? tui.colorSuccess('enabled') : tui.muted('disabled')}`
123
138
  );
124
- console.log(
139
+ tui.output(
125
140
  ` Preview deploys: ${projectStatus.previewDeploy ? tui.colorSuccess('enabled') : tui.muted('disabled')}`
126
141
  );
127
142
  } else {
128
- console.log(` ${tui.muted('○')} Not linked to a repository`);
129
- console.log(tui.muted(` Run ${tui.bold('agentuity git link')} to link one`));
143
+ tui.output(` ${tui.muted('○')} Not linked to a repository`);
144
+ tui.output(tui.muted(` Run ${tui.bold('agentuity git link')} to link one`));
130
145
  }
131
146
 
132
147
  tui.newline();
@@ -1,15 +1,10 @@
1
1
  /**
2
2
  * npm registry availability checking utilities.
3
- * Used to verify a version is available via bun's resolver before attempting upgrade.
3
+ * Used to verify a version is available on npm before attempting upgrade.
4
4
  */
5
5
 
6
- import { tmpdir } from 'node:os';
7
-
8
6
  const PACKAGE_SPEC = '@agentuity/cli';
9
7
 
10
- /** Default timeout for `bun info` subprocess calls (10 seconds) */
11
- const BUN_INFO_TIMEOUT_MS = 10_000;
12
-
13
8
  /** Default timeout for install (`bun add -g`) subprocess calls (30 seconds) */
14
9
  const INSTALL_TIMEOUT_MS = 30_000;
15
10
 
@@ -89,28 +84,24 @@ async function withTimeout<T>(
89
84
  }
90
85
 
91
86
  /**
92
- * Check if a specific version of @agentuity/cli is resolvable by bun.
93
- * Uses `bun info` to verify bun's own resolver/CDN can see the version,
94
- * which avoids the race where npm registry returns 200 but bun's CDN
95
- * has not yet propagated the version.
87
+ * Check if a specific version of @agentuity/cli is available on the npm registry.
96
88
  *
97
89
  * @param version - Version to check (with or without 'v' prefix)
98
90
  * @returns true if version is available, false otherwise
99
91
  */
100
- export async function isVersionAvailableOnNpm(version: string): Promise<boolean> {
92
+ export async function isVersionAvailableOnNpm(
93
+ version: string,
94
+ options?: { timeoutMs?: number }
95
+ ): Promise<boolean> {
101
96
  const normalizedVersion = version.replace(/^v/, '');
97
+ const timeoutMs = options?.timeoutMs ?? 10_000;
102
98
  try {
103
- const result = await spawnWithTimeout(
104
- ['bun', 'info', `${PACKAGE_SPEC}@${normalizedVersion}`, '--json'],
105
- { cwd: tmpdir(), timeout: BUN_INFO_TIMEOUT_MS }
99
+ const response = await fetch(
100
+ `https://registry.npmjs.org/${PACKAGE_SPEC}/${normalizedVersion}`,
101
+ { signal: AbortSignal.timeout(timeoutMs) }
106
102
  );
107
- if (result.exitCode !== 0) {
108
- return false;
109
- }
110
- const info = JSON.parse(result.stdout.toString());
111
- if (info.error) {
112
- return false;
113
- }
103
+ if (!response.ok) return false;
104
+ const info = (await response.json()) as { version?: string };
114
105
  return info.version === normalizedVersion;
115
106
  } catch {
116
107
  return false;
@@ -118,14 +109,14 @@ export async function isVersionAvailableOnNpm(version: string): Promise<boolean>
118
109
  }
119
110
 
120
111
  /**
121
- * Quick check if a version is available via bun's resolver.
112
+ * Quick check if a version is available on npm.
122
113
  * Used for implicit version checks (auto-upgrade flow).
123
114
  *
124
115
  * @param version - Version to check (with or without 'v' prefix)
125
116
  * @returns true if version is available, false if unavailable or error
126
117
  */
127
118
  export async function isVersionAvailableOnNpmQuick(version: string): Promise<boolean> {
128
- return isVersionAvailableOnNpm(version);
119
+ return isVersionAvailableOnNpm(version, { timeoutMs: 1_000 });
129
120
  }
130
121
 
131
122
  export interface WaitForNpmOptions {
package/src/config.ts CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  deleteAuthFromKeychain,
20
20
  } from './keychain';
21
21
  import { clearProfileCache } from './cache';
22
+ import { readEnvFile, writeEnvFile } from './env-util';
22
23
 
23
24
  export const defaultProfileName = 'production';
24
25
 
@@ -634,12 +635,20 @@ export async function createProjectConfig(dir: string, config: InitialProjectCon
634
635
  };
635
636
  await Bun.write(configPath, JSON.stringify(configData, null, 2) + '\n');
636
637
 
637
- // generate the .env file with initial secret
638
+ // generate or update the .env file with SDK key
638
639
  const envPath = join(dir, '.env');
639
- const comment =
640
- '# AGENTUITY_SDK_KEY is a sensitive value and should not be committed to version control.';
641
- const content = `${comment}\nAGENTUITY_SDK_KEY=${sdkKey}\n`;
642
- await Bun.write(envPath, content);
640
+ const envFile = Bun.file(envPath);
641
+ if (await envFile.exists()) {
642
+ // Preserve existing .env content, just update SDK key
643
+ const existing = await readEnvFile(envPath);
644
+ existing.AGENTUITY_SDK_KEY = sdkKey;
645
+ await writeEnvFile(envPath, existing, { preserveExisting: false });
646
+ } else {
647
+ const comment =
648
+ '# AGENTUITY_SDK_KEY is a sensitive value and should not be committed to version control.';
649
+ const content = `${comment}\nAGENTUITY_SDK_KEY=${sdkKey}\n`;
650
+ await Bun.write(envPath, content);
651
+ }
643
652
  await chmod(envPath, 0o600);
644
653
 
645
654
  // generate the vscode settings (only if they don't already exist)
@@ -1,3 +1,5 @@
1
+ import { toForwardSlash } from './normalize-path';
2
+
1
3
  /**
2
4
  * Detects if a file path represents a subagent based on path structure.
3
5
  *
@@ -19,6 +21,9 @@ export function detectSubagent(
19
21
  normalizedPath = normalizedPath.replace(srcDir, '');
20
22
  }
21
23
 
24
+ // Normalize path separators for cross-platform compatibility
25
+ normalizedPath = toForwardSlash(normalizedPath);
26
+
22
27
  // Strip leading './' and split into parts, filtering out empty segments
23
28
  const pathParts = normalizedPath.replace(/^\.\//, '').split('/').filter(Boolean);
24
29
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Normalize path separators to forward slashes for cross-platform compatibility.
3
+ *
4
+ * On Windows, Node.js path functions (relative, resolve, join) return backslashes.
5
+ * JavaScript import paths, zip entry names, and remote file paths must use forward slashes.
6
+ *
7
+ * @param p - The path to normalize
8
+ * @returns The path with all backslashes replaced by forward slashes
9
+ */
10
+ export function toForwardSlash(p: string): string {
11
+ return p.replace(/\\/g, '/');
12
+ }
package/src/utils/zip.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { relative } from 'node:path';
2
2
  import { Glob } from 'bun';
3
3
  import AdmZip from 'adm-zip';
4
+ import { toForwardSlash } from './normalize-path';
4
5
 
5
6
  interface Options {
6
7
  progress?: (val: number) => void;
@@ -15,7 +16,7 @@ export async function zipDir(dir: string, outdir: string, options?: Options) {
15
16
  const total = files.length;
16
17
  let count = 0;
17
18
  for (const file of files) {
18
- const rel = relative(dir, file);
19
+ const rel = toForwardSlash(relative(dir, file));
19
20
  let skip = false;
20
21
  if (options?.filter) {
21
22
  if (!options.filter(file, rel)) {