@agentuity/cli 0.1.25 → 0.1.27

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 (36) hide show
  1. package/bin/cli.ts +14 -4
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +6 -3
  4. package/dist/auth.js.map +1 -1
  5. package/dist/cmd/auth/login.d.ts.map +1 -1
  6. package/dist/cmd/auth/login.js +2 -1
  7. package/dist/cmd/auth/login.js.map +1 -1
  8. package/dist/cmd/build/ast.d.ts.map +1 -1
  9. package/dist/cmd/build/ast.js +14 -26
  10. package/dist/cmd/build/ast.js.map +1 -1
  11. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  12. package/dist/cmd/build/entry-generator.js +7 -13
  13. package/dist/cmd/build/entry-generator.js.map +1 -1
  14. package/dist/cmd/build/vite/api-mount-path.d.ts +61 -0
  15. package/dist/cmd/build/vite/api-mount-path.d.ts.map +1 -0
  16. package/dist/cmd/build/vite/api-mount-path.js +83 -0
  17. package/dist/cmd/build/vite/api-mount-path.js.map +1 -0
  18. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  19. package/dist/cmd/cloud/deploy.js +4 -2
  20. package/dist/cmd/cloud/deploy.js.map +1 -1
  21. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
  22. package/dist/cmd/cloud/sandbox/snapshot/build.js +11 -1
  23. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  24. package/dist/version-check.d.ts +2 -2
  25. package/dist/version-check.d.ts.map +1 -1
  26. package/dist/version-check.js +18 -3
  27. package/dist/version-check.js.map +1 -1
  28. package/package.json +6 -6
  29. package/src/auth.ts +6 -3
  30. package/src/cmd/auth/login.ts +2 -1
  31. package/src/cmd/build/ast.ts +18 -27
  32. package/src/cmd/build/entry-generator.ts +8 -14
  33. package/src/cmd/build/vite/api-mount-path.ts +87 -0
  34. package/src/cmd/cloud/deploy.ts +4 -1
  35. package/src/cmd/cloud/sandbox/snapshot/build.ts +13 -1
  36. package/src/version-check.ts +22 -2
@@ -4,10 +4,12 @@ import * as tui from './tui';
4
4
  import { saveConfig } from './config';
5
5
  import { $ } from 'bun';
6
6
  const ONE_HOUR_MS = 60 * 60 * 1000;
7
+ // Tags that indicate a command should skip the upgrade prompt
8
+ const SKIP_UPGRADE_TAGS = ['read-only', 'fast'];
7
9
  /**
8
10
  * Check if we should skip the version check based on environment and config
9
11
  */
10
- function shouldSkipCheck(config, options, commandDef, args) {
12
+ function shouldSkipCheck(config, options, commandDef, subcommandDef, args) {
11
13
  // Skip if running via bun/bunx (not installed executable)
12
14
  if (!isRunningFromExecutable()) {
13
15
  return true;
@@ -42,6 +44,19 @@ function shouldSkipCheck(config, options, commandDef, args) {
42
44
  if (commandDef && commandDef.skipUpgradeCheck === true) {
43
45
  return true;
44
46
  }
47
+ // Skip if subcommand explicitly opts out of upgrade check
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ if (subcommandDef && subcommandDef.skipUpgradeCheck === true) {
50
+ return true;
51
+ }
52
+ // Skip if command or subcommand has tags indicating it's read-only or fast
53
+ // These commands shouldn't be interrupted with upgrade prompts
54
+ const commandTags = commandDef?.tags ?? [];
55
+ const subcommandTags = subcommandDef?.tags ?? [];
56
+ const allTags = [...commandTags, ...subcommandTags];
57
+ if (allTags.some((tag) => SKIP_UPGRADE_TAGS.includes(tag))) {
58
+ return true;
59
+ }
45
60
  // Skip for help commands
46
61
  const helpFlags = ['--help', '-h', 'help'];
47
62
  if (args.some((arg) => helpFlags.includes(arg))) {
@@ -140,9 +155,9 @@ async function performUpgrade(logger) {
140
155
  * Check for updates and optionally prompt to upgrade
141
156
  * Should be called early in the CLI initialization, before commands execute
142
157
  */
143
- export async function checkForUpdates(config, logger, options, commandDef, args) {
158
+ export async function checkForUpdates(config, logger, options, commandDef, subcommandDef, args) {
144
159
  // Determine if we should skip the check
145
- if (shouldSkipCheck(config, options, commandDef, args)) {
160
+ if (shouldSkipCheck(config, options, commandDef, subcommandDef, args)) {
146
161
  logger.trace('Skipping version check (disabled or not applicable)');
147
162
  return;
148
163
  }
@@ -1 +1 @@
1
- {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../src/version-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../src/version-check.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentuity/cli",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Agentuity employees and contributors",
6
6
  "type": "module",
@@ -40,9 +40,9 @@
40
40
  "prepublishOnly": "bun run clean && bun run build"
41
41
  },
42
42
  "dependencies": {
43
- "@agentuity/auth": "0.1.25",
44
- "@agentuity/core": "0.1.25",
45
- "@agentuity/server": "0.1.25",
43
+ "@agentuity/auth": "0.1.27",
44
+ "@agentuity/core": "0.1.27",
45
+ "@agentuity/server": "0.1.27",
46
46
  "@datasert/cronjs-parser": "^1.4.0",
47
47
  "@terascope/fetch-github-release": "^2.2.1",
48
48
  "@vitejs/plugin-react": "^5.1.2",
@@ -60,10 +60,10 @@
60
60
  "typescript": "^5.9.0",
61
61
  "vite": "^7.2.7",
62
62
  "zod": "^4.3.5",
63
- "@agentuity/frontend": "0.1.25"
63
+ "@agentuity/frontend": "0.1.27"
64
64
  },
65
65
  "devDependencies": {
66
- "@agentuity/test-utils": "0.1.25",
66
+ "@agentuity/test-utils": "0.1.27",
67
67
  "@types/adm-zip": "^0.5.7",
68
68
  "@types/bun": "latest",
69
69
  "@types/tar-fs": "^2.0.4",
package/src/auth.ts CHANGED
@@ -72,12 +72,13 @@ export async function requireAuth(ctx: CommandContext<undefined>): Promise<AuthD
72
72
  // Import and run login flow
73
73
  const { loginCommand } = await import('./cmd/auth/login');
74
74
 
75
- // Ensure apiClient is available for login handler
75
+ // Ensure apiClient and opts are available for login handler
76
76
  const loginCtx = ctx as unknown as Record<string, unknown>;
77
77
  if (!loginCtx.apiClient) {
78
78
  const apiUrl = getAPIBaseURL(ctx.config ?? null);
79
79
  loginCtx.apiClient = new APIClient(apiUrl, ctx.logger, ctx.config ?? null);
80
80
  }
81
+ loginCtx.opts ??= {};
81
82
 
82
83
  if (loginCommand.handler) {
83
84
  await loginCommand.handler(loginCtx as CommandContext);
@@ -165,12 +166,13 @@ export async function optionalAuth(
165
166
  // Import and run login flow
166
167
  const { loginCommand } = await import('./cmd/auth/login');
167
168
 
168
- // Ensure apiClient is available for login handler
169
+ // Ensure apiClient and opts are available for login handler
169
170
  const loginCtx1 = ctx as unknown as Record<string, unknown>;
170
171
  if (!loginCtx1.apiClient) {
171
172
  const apiUrl = getAPIBaseURL(ctx.config ?? null);
172
173
  loginCtx1.apiClient = new APIClient(apiUrl, ctx.logger, ctx.config ?? null);
173
174
  }
175
+ loginCtx1.opts ??= {};
174
176
 
175
177
  if (loginCommand.handler) {
176
178
  await loginCommand.handler(loginCtx1 as CommandContext);
@@ -207,12 +209,13 @@ export async function optionalAuth(
207
209
  // Import and run login flow
208
210
  const { loginCommand } = await import('./cmd/auth/login');
209
211
 
210
- // Ensure apiClient is available for login handler
212
+ // Ensure apiClient and opts are available for login handler
211
213
  const loginCtx2 = ctx as unknown as Record<string, unknown>;
212
214
  if (!loginCtx2.apiClient) {
213
215
  const apiUrl = getAPIBaseURL(ctx.config ?? null);
214
216
  loginCtx2.apiClient = new APIClient(apiUrl, ctx.logger, ctx.config ?? null);
215
217
  }
218
+ loginCtx2.opts ??= {};
216
219
 
217
220
  if (loginCommand.handler) {
218
221
  await loginCommand.handler(loginCtx2 as CommandContext);
@@ -25,7 +25,8 @@ export const loginCommand = createSubcommand({
25
25
  response: z.object({ success: z.boolean() }),
26
26
  },
27
27
  async handler(ctx) {
28
- const { logger, config, apiClient, opts, options } = ctx;
28
+ const { logger, config, apiClient, options } = ctx;
29
+ const opts = ctx.opts ?? {};
29
30
 
30
31
  if (opts.setupToken) {
31
32
  const url = getAPIBaseURL(config);
@@ -11,6 +11,11 @@ import type { LogLevel } from '../../types';
11
11
  import { existsSync, mkdirSync } from 'node:fs';
12
12
  import JSON5 from 'json5';
13
13
  import { formatSchemaCode } from './format-schema';
14
+ import {
15
+ computeApiMountPath,
16
+ joinMountAndRoute,
17
+ extractRelativeApiPath,
18
+ } from './vite/api-mount-path';
14
19
 
15
20
  const logger = createLogger((process.env.AGENTUITY_LOG_LEVEL || 'info') as LogLevel);
16
21
 
@@ -1492,26 +1497,18 @@ export async function parseRoute(
1492
1497
 
1493
1498
  const rel = relative(rootDir, filename);
1494
1499
 
1495
- // For src/api/index.ts, we don't want to add the folder name since it's the root API router
1496
- const isRootApi = filename.includes('src/api/index.ts');
1497
-
1498
- // For nested routes, use the full path from src/api/ instead of just the immediate parent
1499
- // e.g., src/api/v1/users/route.ts -> routeName = "v1/users"
1500
- // src/api/auth/route.ts -> routeName = "auth"
1501
- // src/api/test.ts -> routeName = "" (file directly in src/api/)
1502
- let routeName = '';
1503
- if (!isRootApi) {
1504
- const apiMatch = filename.match(/src\/api\/(.+?)\/[^/]+\.ts$/);
1505
- if (apiMatch) {
1506
- // File in subdirectory: src/api/auth/route.ts -> "auth"
1507
- routeName = apiMatch[1];
1508
- }
1509
- // For files directly in src/api/ (e.g., test.ts), routeName stays empty
1510
- // This prevents double /api prefix since these files often define full paths
1511
- }
1500
+ // Compute the API mount path using the shared helper
1501
+ // This ensures consistency between route type generation (here) and runtime mounting (entry-generator.ts)
1502
+ // Examples:
1503
+ // src/api/index.ts -> basePath = '/api'
1504
+ // src/api/sessions.ts -> basePath = '/api/sessions'
1505
+ // src/api/auth/route.ts -> basePath = '/api/auth'
1506
+ // src/api/users/profile/route.ts -> basePath = '/api/users/profile'
1507
+ const srcDir = join(rootDir, 'src');
1508
+ const relativeApiPath = extractRelativeApiPath(filename, srcDir);
1509
+ const basePath = computeApiMountPath(relativeApiPath);
1512
1510
 
1513
1511
  const routes: RouteDefinition = [];
1514
- const routePrefix = '/api';
1515
1512
 
1516
1513
  try {
1517
1514
  for (const body of ast.body) {
@@ -1593,9 +1590,7 @@ export async function parseRoute(
1593
1590
 
1594
1591
  // Create a route entry for each method
1595
1592
  for (const httpMethod of methods) {
1596
- const thepath = `${routePrefix}/${routeName}/${pathSuffix}`
1597
- .replaceAll(/\/{2,}/g, '/')
1598
- .replaceAll(/\/$/g, '');
1593
+ const thepath = joinMountAndRoute(basePath, pathSuffix);
1599
1594
  const id = generateRouteId(
1600
1595
  projectId,
1601
1596
  deploymentId,
@@ -1692,9 +1687,7 @@ export async function parseRoute(
1692
1687
 
1693
1688
  // Create a route entry for each supported method
1694
1689
  for (const httpMethod of SUPPORTED_HTTP_METHODS) {
1695
- const thepath = `${routePrefix}/${routeName}/${pathSuffix}`
1696
- .replaceAll(/\/{2,}/g, '/')
1697
- .replaceAll(/\/$/g, '');
1690
+ const thepath = joinMountAndRoute(basePath, pathSuffix);
1698
1691
  const id = generateRouteId(
1699
1692
  projectId,
1700
1693
  deploymentId,
@@ -1888,9 +1881,7 @@ export async function parseRoute(
1888
1881
  });
1889
1882
  }
1890
1883
  }
1891
- const thepath = `${routePrefix}/${routeName}/${suffix}`
1892
- .replaceAll(/\/{2,}/g, '/')
1893
- .replaceAll(/\/$/g, '');
1884
+ const thepath = joinMountAndRoute(basePath, suffix);
1894
1885
  const id = generateRouteId(
1895
1886
  projectId,
1896
1887
  deploymentId,
@@ -7,6 +7,7 @@ import { join } from 'node:path';
7
7
  import type { Logger, WorkbenchConfig, AnalyticsConfig } from '../../types';
8
8
  import { discoverRoutes } from './vite/route-discovery';
9
9
  import { generateWebAnalyticsFile } from './webanalytics-generator';
10
+ import { computeApiMountPath } from './vite/api-mount-path';
10
11
 
11
12
  interface GenerateEntryOptions {
12
13
  rootDir: string;
@@ -107,21 +108,14 @@ export async function generateEntryFile(options: GenerateEntryOptions): Promise<
107
108
  let routeIndex = 0;
108
109
 
109
110
  for (const routeFile of sortedRouteFiles) {
111
+ // Normalize path separators for cross-platform compatibility (Windows uses backslashes)
112
+ const normalizedRouteFile = routeFile.replace(/\\/g, '/');
110
113
  // Convert src/api/auth/route.ts -> auth/route
111
- const relativePath = routeFile.replace(/^src\/api\//, '').replace(/\.tsx?$/, '');
112
-
113
- // Determine the mount path
114
- // src/api/index.ts -> /api
115
- // src/api/auth/route.ts -> /api/auth
116
- // src/api/users/profile/route.ts -> /api/users/profile
117
- let mountPath = '/api';
118
- if (relativePath !== 'index') {
119
- // Remove 'route' or 'index' from the end
120
- const cleanPath = relativePath.replace(/\/(route|index)$/, '');
121
- if (cleanPath) {
122
- mountPath = `/api/${cleanPath}`;
123
- }
124
- }
114
+ const relativePath = normalizedRouteFile.replace(/^src\/api\//, '').replace(/\.tsx?$/, '');
115
+
116
+ // Determine the mount path using the shared helper
117
+ // This ensures consistency with route type generation in ast.ts
118
+ const mountPath = computeApiMountPath(relativePath);
125
119
 
126
120
  const importName = `router_${routeIndex++}`;
127
121
  routeImportsAndMounts.push(
@@ -0,0 +1,87 @@
1
+ /**
2
+ * API Mount Path Utilities
3
+ *
4
+ * Shared helpers for computing API route mount paths from file paths.
5
+ * Used by both entry-generator.ts (runtime mounting) and ast.ts (type generation)
6
+ * to ensure consistent path calculation.
7
+ */
8
+
9
+ /**
10
+ * Compute the API mount path from a route file's relative path.
11
+ * This is the path used in app.route(mountPath, router).
12
+ *
13
+ * The mount path is based on the DIRECTORY containing the file, not the filename.
14
+ * Files directly in src/api/ (regardless of their name) mount at /api.
15
+ * Files in subdirectories mount at /api/{subdirectory}.
16
+ *
17
+ * @param relativePath - Path relative to src/api/ without extension
18
+ * e.g., 'index', 'sessions', 'auth/route', 'users/profile/route'
19
+ * @returns Mount path like '/api', '/api/auth', '/api/users/profile'
20
+ *
21
+ * @example
22
+ * computeApiMountPath('index') // '/api' (file in src/api/)
23
+ * computeApiMountPath('sessions') // '/api' (file in src/api/)
24
+ * computeApiMountPath('route') // '/api' (file in src/api/)
25
+ * computeApiMountPath('auth/route') // '/api/auth' (file in src/api/auth/)
26
+ * computeApiMountPath('auth/index') // '/api/auth' (file in src/api/auth/)
27
+ * computeApiMountPath('users/profile/route') // '/api/users/profile' (file in src/api/users/profile/)
28
+ */
29
+ export function computeApiMountPath(relativePath: string): string {
30
+ // Extract the directory path (everything before the last /)
31
+ const lastSlashIndex = relativePath.lastIndexOf('/');
32
+ if (lastSlashIndex === -1) {
33
+ // File is directly in src/api/ (e.g., 'index', 'sessions', 'route')
34
+ return '/api';
35
+ }
36
+
37
+ // File is in a subdirectory (e.g., 'auth/route' -> 'auth')
38
+ const dirPath = relativePath.substring(0, lastSlashIndex);
39
+ return `/api/${dirPath}`;
40
+ }
41
+
42
+ /**
43
+ * Join a mount base path with a route's local path.
44
+ * Handles normalization of slashes and empty/root paths.
45
+ *
46
+ * @param base - The mount base path (e.g., '/api/sessions')
47
+ * @param route - The local route path (e.g., '/', '/users', ':id')
48
+ * @returns The combined full path
49
+ *
50
+ * @example
51
+ * joinMountAndRoute('/api/sessions', '/') // '/api/sessions'
52
+ * joinMountAndRoute('/api/sessions', '/users') // '/api/sessions/users'
53
+ * joinMountAndRoute('/api', '/health') // '/api/health'
54
+ * joinMountAndRoute('/api/users', ':id') // '/api/users/:id'
55
+ */
56
+ export function joinMountAndRoute(base: string, route: string): string {
57
+ if (!route || route === '/') {
58
+ return base;
59
+ }
60
+ const normalized = route.startsWith('/') ? route : `/${route}`;
61
+ return `${base}${normalized}`.replace(/\/{2,}/g, '/').replace(/\/$/, '');
62
+ }
63
+
64
+ import { join, relative } from 'node:path';
65
+
66
+ /**
67
+ * Extract the relative path from a full file path to src/api/.
68
+ * Normalizes path separators for cross-platform compatibility.
69
+ *
70
+ * @param filename - Full path to the route file
71
+ * @param srcDir - Path to the src directory
72
+ * @returns Path relative to src/api/ without extension
73
+ *
74
+ * @example
75
+ * // Given srcDir = '/project/src'
76
+ * extractRelativeApiPath('/project/src/api/sessions.ts', '/project/src')
77
+ * // Returns: 'sessions'
78
+ *
79
+ * extractRelativeApiPath('/project/src/api/auth/route.ts', '/project/src')
80
+ * // Returns: 'auth/route'
81
+ */
82
+ export function extractRelativeApiPath(filename: string, srcDir: string): string {
83
+ const apiDir = join(srcDir, 'api');
84
+ return relative(apiDir, filename)
85
+ .replace(/\\/g, '/') // Normalize Windows paths
86
+ .replace(/\.tsx?$/, ''); // Remove extension
87
+ }
@@ -13,6 +13,7 @@ import {
13
13
  getDefaultConfigDir,
14
14
  loadProjectSDKKey,
15
15
  updateProjectConfig,
16
+ getGlobalCatalystAPIClient,
16
17
  } from '../../config';
17
18
  import { getProjectGithubStatus } from '../git/api';
18
19
  import { runGitLink } from '../git/link';
@@ -341,8 +342,10 @@ export const deploySubcommand = createSubcommand({
341
342
  return null;
342
343
  }
343
344
  logger.debug('Checking %d packages for malware', packages.length);
345
+ // Use Catalyst client directly for malware check (security routes are on Catalyst)
346
+ const catalystClient = await getGlobalCatalystAPIClient(logger, auth, config?.name);
344
347
  const result = await projectDeploymentMalwareCheck(
345
- apiClient,
348
+ catalystClient,
346
349
  deployment!.id,
347
350
  packages
348
351
  );
@@ -165,7 +165,7 @@ function substituteVariables(
165
165
  }
166
166
 
167
167
  // Default patterns that are always excluded from snapshot builds
168
- const DEFAULT_EXCLUSIONS = ['.git/**', 'node_modules/**', '.agentuity/**', '.env*'];
168
+ const DEFAULT_EXCLUSIONS = ['.git', '.git/**', 'node_modules/**', '.agentuity/**', '.env*'];
169
169
 
170
170
  async function resolveFileGlobs(
171
171
  directory: string,
@@ -203,6 +203,8 @@ async function resolveFileGlobs(
203
203
  }
204
204
  }
205
205
 
206
+ // Expand exclusion patterns to include nested variants
207
+ const expandedExclusions: string[] = [];
206
208
  for (let pattern of exclusions) {
207
209
  // If pattern already contains glob wildcards, use it as-is
208
210
  // Otherwise, check if it refers to a directory and auto-append /** to exclude all contents
@@ -219,6 +221,16 @@ async function resolveFileGlobs(
219
221
  }
220
222
  }
221
223
 
224
+ expandedExclusions.push(pattern);
225
+
226
+ // Add **/ prefix variant to match nested occurrences (e.g., .agentuity/** -> **/.agentuity/**)
227
+ // Skip if pattern already starts with **/ or is just a wildcard pattern
228
+ if (!pattern.startsWith('**/')) {
229
+ expandedExclusions.push(`**/${pattern}`);
230
+ }
231
+ }
232
+
233
+ for (const pattern of expandedExclusions) {
222
234
  const glob = new Bun.Glob(pattern);
223
235
  for await (const file of glob.scan({ cwd: directory, dot: true })) {
224
236
  files.delete(file);
@@ -1,4 +1,4 @@
1
- import type { Config, Logger, CommandDefinition } from './types';
1
+ import type { Config, Logger, CommandDefinition, SubcommandDefinition } from './types';
2
2
  import { isRunningFromExecutable, fetchLatestVersion } from './cmd/upgrade';
3
3
  import { getVersion, getCompareUrl, getReleaseUrl, toTag } from './version';
4
4
  import * as tui from './tui';
@@ -7,6 +7,9 @@ import { $ } from 'bun';
7
7
 
8
8
  const ONE_HOUR_MS = 60 * 60 * 1000;
9
9
 
10
+ // Tags that indicate a command should skip the upgrade prompt
11
+ const SKIP_UPGRADE_TAGS = ['read-only', 'fast'];
12
+
10
13
  /**
11
14
  * Check if we should skip the version check based on environment and config
12
15
  */
@@ -20,6 +23,7 @@ function shouldSkipCheck(
20
23
  skipVersionCheck?: boolean;
21
24
  },
22
25
  commandDef: CommandDefinition | undefined,
26
+ subcommandDef: SubcommandDefinition | undefined,
23
27
  args: string[]
24
28
  ): boolean {
25
29
  // Skip if running via bun/bunx (not installed executable)
@@ -64,6 +68,21 @@ function shouldSkipCheck(
64
68
  return true;
65
69
  }
66
70
 
71
+ // Skip if subcommand explicitly opts out of upgrade check
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ if (subcommandDef && (subcommandDef as any).skipUpgradeCheck === true) {
74
+ return true;
75
+ }
76
+
77
+ // Skip if command or subcommand has tags indicating it's read-only or fast
78
+ // These commands shouldn't be interrupted with upgrade prompts
79
+ const commandTags = commandDef?.tags ?? [];
80
+ const subcommandTags = subcommandDef?.tags ?? [];
81
+ const allTags = [...commandTags, ...subcommandTags];
82
+ if (allTags.some((tag) => SKIP_UPGRADE_TAGS.includes(tag))) {
83
+ return true;
84
+ }
85
+
67
86
  // Skip for help commands
68
87
  const helpFlags = ['--help', '-h', 'help'];
69
88
  if (args.some((arg) => helpFlags.includes(arg))) {
@@ -187,10 +206,11 @@ export async function checkForUpdates(
187
206
  skipVersionCheck?: boolean;
188
207
  },
189
208
  commandDef: CommandDefinition | undefined,
209
+ subcommandDef: SubcommandDefinition | undefined,
190
210
  args: string[]
191
211
  ): Promise<void> {
192
212
  // Determine if we should skip the check
193
- if (shouldSkipCheck(config, options, commandDef, args)) {
213
+ if (shouldSkipCheck(config, options, commandDef, subcommandDef, args)) {
194
214
  logger.trace('Skipping version check (disabled or not applicable)');
195
215
  return;
196
216
  }