@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.
- package/bin/cli.ts +8 -0
- package/dist/agent-detection.js +2 -2
- package/dist/agent-detection.js.map +1 -1
- package/dist/banner.js +2 -2
- package/dist/banner.js.map +1 -1
- package/dist/bun-path.d.ts.map +1 -1
- package/dist/bun-path.js +2 -1
- package/dist/bun-path.js.map +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +87 -14
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.js +3 -2
- package/dist/cmd/build/vite/agent-discovery.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 -1
- 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 +9 -7
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +3 -2
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +19 -21
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/env/delete.js +3 -26
- package/dist/cmd/cloud/env/delete.js.map +1 -1
- package/dist/cmd/cloud/env/import.d.ts.map +1 -1
- package/dist/cmd/cloud/env/import.js +3 -16
- package/dist/cmd/cloud/env/import.js.map +1 -1
- package/dist/cmd/cloud/env/set.d.ts.map +1 -1
- package/dist/cmd/cloud/env/set.js +3 -19
- package/dist/cmd/cloud/env/set.js.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.js +2 -1
- package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
- package/dist/cmd/git/account/add.d.ts +6 -8
- package/dist/cmd/git/account/add.d.ts.map +1 -1
- package/dist/cmd/git/account/add.js +37 -151
- package/dist/cmd/git/account/add.js.map +1 -1
- package/dist/cmd/git/account/index.d.ts +0 -1
- package/dist/cmd/git/account/index.d.ts.map +1 -1
- package/dist/cmd/git/account/index.js +3 -4
- package/dist/cmd/git/account/index.js.map +1 -1
- package/dist/cmd/git/account/list.d.ts.map +1 -1
- package/dist/cmd/git/account/list.js +35 -67
- package/dist/cmd/git/account/list.js.map +1 -1
- package/dist/cmd/git/account/remove.d.ts.map +1 -1
- package/dist/cmd/git/account/remove.js +42 -84
- package/dist/cmd/git/account/remove.js.map +1 -1
- package/dist/cmd/git/api.d.ts +19 -23
- package/dist/cmd/git/api.d.ts.map +1 -1
- package/dist/cmd/git/api.js +38 -56
- package/dist/cmd/git/api.js.map +1 -1
- package/dist/cmd/git/identity/connect.d.ts +15 -0
- package/dist/cmd/git/identity/connect.d.ts.map +1 -0
- package/dist/cmd/git/identity/connect.js +135 -0
- package/dist/cmd/git/identity/connect.js.map +1 -0
- package/dist/cmd/git/identity/disconnect.d.ts +2 -0
- package/dist/cmd/git/identity/disconnect.d.ts.map +1 -0
- package/dist/cmd/git/identity/disconnect.js +83 -0
- package/dist/cmd/git/identity/disconnect.js.map +1 -0
- package/dist/cmd/git/identity/index.d.ts +2 -0
- package/dist/cmd/git/identity/index.d.ts.map +1 -0
- package/dist/cmd/git/identity/index.js +10 -0
- package/dist/cmd/git/identity/index.js.map +1 -0
- package/dist/cmd/git/identity/status.d.ts +2 -0
- package/dist/cmd/git/identity/status.d.ts.map +1 -0
- package/dist/cmd/git/identity/status.js +77 -0
- package/dist/cmd/git/identity/status.js.map +1 -0
- package/dist/cmd/git/index.d.ts +0 -1
- package/dist/cmd/git/index.d.ts.map +1 -1
- package/dist/cmd/git/index.js +3 -2
- package/dist/cmd/git/index.js.map +1 -1
- package/dist/cmd/git/link.d.ts +2 -3
- package/dist/cmd/git/link.d.ts.map +1 -1
- package/dist/cmd/git/link.js +22 -28
- package/dist/cmd/git/link.js.map +1 -1
- package/dist/cmd/git/list.d.ts.map +1 -1
- package/dist/cmd/git/list.js +42 -55
- package/dist/cmd/git/list.js.map +1 -1
- package/dist/cmd/git/status.d.ts.map +1 -1
- package/dist/cmd/git/status.js +51 -38
- package/dist/cmd/git/status.js.map +1 -1
- package/dist/cmd/upgrade/npm-availability.d.ts +6 -7
- package/dist/cmd/upgrade/npm-availability.d.ts.map +1 -1
- package/dist/cmd/upgrade/npm-availability.js +9 -18
- package/dist/cmd/upgrade/npm-availability.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -4
- package/dist/config.js.map +1 -1
- package/dist/utils/detectSubagent.d.ts.map +1 -1
- package/dist/utils/detectSubagent.js +3 -0
- package/dist/utils/detectSubagent.js.map +1 -1
- package/dist/utils/normalize-path.d.ts +11 -0
- package/dist/utils/normalize-path.d.ts.map +1 -0
- package/dist/utils/normalize-path.js +13 -0
- package/dist/utils/normalize-path.js.map +1 -0
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js +2 -1
- package/dist/utils/zip.js.map +1 -1
- package/package.json +6 -6
- package/src/agent-detection.ts +2 -2
- package/src/banner.ts +2 -2
- package/src/bun-path.ts +2 -1
- package/src/cmd/build/ast.ts +96 -15
- package/src/cmd/build/vite/agent-discovery.ts +3 -2
- package/src/cmd/build/vite/metadata-generator.ts +2 -1
- package/src/cmd/build/vite/registry-generator.ts +9 -7
- package/src/cmd/build/vite/route-discovery.ts +3 -2
- package/src/cmd/cloud/deploy.ts +54 -61
- package/src/cmd/cloud/env/delete.ts +3 -34
- package/src/cmd/cloud/env/import.ts +2 -18
- package/src/cmd/cloud/env/set.ts +2 -21
- package/src/cmd/cloud/sandbox/cp.ts +2 -1
- package/src/cmd/git/account/add.ts +51 -190
- package/src/cmd/git/account/index.ts +3 -5
- package/src/cmd/git/account/list.ts +51 -82
- package/src/cmd/git/account/remove.ts +45 -95
- package/src/cmd/git/api.ts +49 -111
- package/src/cmd/git/identity/connect.ts +178 -0
- package/src/cmd/git/identity/disconnect.ts +103 -0
- package/src/cmd/git/identity/index.ts +10 -0
- package/src/cmd/git/identity/status.ts +96 -0
- package/src/cmd/git/index.ts +3 -3
- package/src/cmd/git/link.ts +32 -35
- package/src/cmd/git/list.ts +48 -59
- package/src/cmd/git/status.ts +55 -40
- package/src/cmd/upgrade/npm-availability.ts +14 -23
- package/src/config.ts +14 -5
- package/src/utils/detectSubagent.ts +5 -0
- package/src/utils/normalize-path.ts +12 -0
- package/src/utils/zip.ts +2 -1
package/src/cmd/build/ast.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { LogLevel } from '../../types';
|
|
|
11
11
|
import { existsSync, mkdirSync, statSync } from 'node:fs';
|
|
12
12
|
import JSON5 from 'json5';
|
|
13
13
|
import { formatSchemaCode } from './format-schema';
|
|
14
|
+
import { toForwardSlash } from '../../utils/normalize-path';
|
|
14
15
|
import {
|
|
15
16
|
computeApiMountPath,
|
|
16
17
|
joinMountAndRoute,
|
|
@@ -488,7 +489,7 @@ export async function parseEvalMetadata(
|
|
|
488
489
|
ecmaVersion: 'latest',
|
|
489
490
|
sourceType: 'module',
|
|
490
491
|
});
|
|
491
|
-
const rel = relative(rootDir, filename);
|
|
492
|
+
const rel = toForwardSlash(relative(rootDir, filename));
|
|
492
493
|
const version = hash(contents);
|
|
493
494
|
const evals: Array<{
|
|
494
495
|
filename: string;
|
|
@@ -706,7 +707,7 @@ export async function parseAgentMetadata(
|
|
|
706
707
|
sourceType: 'module',
|
|
707
708
|
});
|
|
708
709
|
let exportName: string | undefined;
|
|
709
|
-
const rel = relative(rootDir, filename);
|
|
710
|
+
const rel = toForwardSlash(relative(rootDir, filename));
|
|
710
711
|
let name: string | undefined; // Will be set from createAgent identifier
|
|
711
712
|
const version = hash(contents);
|
|
712
713
|
const id = getAgentId(projectId, deploymentId, rel, version);
|
|
@@ -910,7 +911,7 @@ export async function parseAgentMetadata(
|
|
|
910
911
|
| 'error';
|
|
911
912
|
const logger = createLogger(logLevel);
|
|
912
913
|
const agentDir = dirname(filename);
|
|
913
|
-
const evalsPath =
|
|
914
|
+
const evalsPath = join(agentDir, 'eval.ts');
|
|
914
915
|
logger.trace(`Checking for evals file at ${evalsPath}`);
|
|
915
916
|
const evalsFile = Bun.file(evalsPath);
|
|
916
917
|
if (await evalsFile.exists()) {
|
|
@@ -1049,7 +1050,7 @@ function validateSchemaExports(
|
|
|
1049
1050
|
}
|
|
1050
1051
|
|
|
1051
1052
|
/**
|
|
1052
|
-
*
|
|
1053
|
+
* Information extracted from validator middleware in route handler arguments.
|
|
1053
1054
|
*/
|
|
1054
1055
|
interface ValidatorInfo {
|
|
1055
1056
|
hasValidator: boolean;
|
|
@@ -1059,9 +1060,66 @@ interface ValidatorInfo {
|
|
|
1059
1060
|
stream?: boolean;
|
|
1060
1061
|
}
|
|
1061
1062
|
|
|
1063
|
+
/**
|
|
1064
|
+
* Scan route handler arguments for validator middleware and extract schema information.
|
|
1065
|
+
*
|
|
1066
|
+
* Accumulates schema info across ALL validator arguments in the route handler,
|
|
1067
|
+
* supporting common patterns like combining param + JSON body validation:
|
|
1068
|
+
*
|
|
1069
|
+
* ```ts
|
|
1070
|
+
* router.patch('/:id',
|
|
1071
|
+
* zValidator('param', paramSchema), // detected, no schema extracted (non-json)
|
|
1072
|
+
* zValidator('json', bodySchema), // detected, inputSchemaVariable = 'bodySchema'
|
|
1073
|
+
* async (c) => { ... }
|
|
1074
|
+
* );
|
|
1075
|
+
* ```
|
|
1076
|
+
*
|
|
1077
|
+
* **Schema merge strategy — first match wins:**
|
|
1078
|
+
* When multiple validators provide the same schema field (e.g., two `inputSchemaVariable`
|
|
1079
|
+
* providers), the first one encountered is kept. This is intentional because:
|
|
1080
|
+
*
|
|
1081
|
+
* 1. Primary validators (e.g., `validator({ input, output })`, `agent.validator()`) are
|
|
1082
|
+
* conventionally listed before supplementary validators (param, query, header, cookie).
|
|
1083
|
+
* 2. For `zValidator`, only `'json'` targets extract schemas — other targets (param, query,
|
|
1084
|
+
* header, cookie) return no schema variables, so ordering rarely matters in practice.
|
|
1085
|
+
* 3. Duplicate json validators on the same route is uncommon; when it occurs, a warning
|
|
1086
|
+
* is logged to help developers catch unintentional conflicts.
|
|
1087
|
+
*
|
|
1088
|
+
* Supported validator patterns:
|
|
1089
|
+
* - `validator({ input, output, stream })` — Agentuity object-style
|
|
1090
|
+
* - `validator('json', callback)` — Hono callback-style
|
|
1091
|
+
* - `zValidator('json', schema)` — Zod validator (only 'json' target extracts schemas)
|
|
1092
|
+
* - `agent.validator()` / `agent.validator({ input, output })` — Agent validators
|
|
1093
|
+
*
|
|
1094
|
+
* @param args - The arguments array from a route handler call expression (e.g., `router.post(path, ...args)`)
|
|
1095
|
+
* @returns Accumulated validator info with merged schemas from all validators found
|
|
1096
|
+
*/
|
|
1062
1097
|
function hasValidatorCall(args: unknown[]): ValidatorInfo {
|
|
1063
1098
|
if (!args || args.length === 0) return { hasValidator: false };
|
|
1064
1099
|
|
|
1100
|
+
const result: ValidatorInfo = { hasValidator: false };
|
|
1101
|
+
|
|
1102
|
+
// Helper: merge a schema field using first-match-wins strategy, warn on conflict.
|
|
1103
|
+
// When a field is already set and a different value is encountered, the first value
|
|
1104
|
+
// is kept and a warning is emitted to help developers catch unintentional duplicates.
|
|
1105
|
+
const mergeField = <K extends 'inputSchemaVariable' | 'outputSchemaVariable'>(
|
|
1106
|
+
field: K,
|
|
1107
|
+
value: string | undefined
|
|
1108
|
+
) => {
|
|
1109
|
+
if (!value) return;
|
|
1110
|
+
if (result[field] && result[field] !== value) {
|
|
1111
|
+
const label = field === 'inputSchemaVariable' ? 'inputSchema' : 'outputSchema';
|
|
1112
|
+
logger.warn(
|
|
1113
|
+
'Multiple validators provide %s: using "%s", ignoring "%s"',
|
|
1114
|
+
label,
|
|
1115
|
+
result[field],
|
|
1116
|
+
value
|
|
1117
|
+
);
|
|
1118
|
+
} else if (!result[field]) {
|
|
1119
|
+
result[field] = value;
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1065
1123
|
for (const arg of args) {
|
|
1066
1124
|
if (!arg || typeof arg !== 'object') continue;
|
|
1067
1125
|
const node = arg as ASTNode;
|
|
@@ -1070,28 +1128,38 @@ function hasValidatorCall(args: unknown[]): ValidatorInfo {
|
|
|
1070
1128
|
if (node.type === 'CallExpression') {
|
|
1071
1129
|
const callExpr = node as ASTCallExpression;
|
|
1072
1130
|
|
|
1073
|
-
// Check for standalone validator({ input, output })
|
|
1131
|
+
// Check for standalone validator({ input, output }) or Hono validator('json', callback)
|
|
1074
1132
|
if (callExpr.callee.type === 'Identifier') {
|
|
1075
1133
|
const identifier = callExpr.callee as ASTNodeIdentifier;
|
|
1076
1134
|
if (identifier.name === 'validator') {
|
|
1077
1135
|
// Try to extract schema variables from validator({ input, output, stream })
|
|
1078
1136
|
const schemas = extractValidatorSchemas(callExpr);
|
|
1079
|
-
//
|
|
1137
|
+
// If we found schemas from object-style validator, merge them
|
|
1080
1138
|
if (
|
|
1081
1139
|
schemas.inputSchemaVariable ||
|
|
1082
1140
|
schemas.outputSchemaVariable ||
|
|
1083
1141
|
schemas.stream !== undefined
|
|
1084
1142
|
) {
|
|
1085
|
-
|
|
1143
|
+
result.hasValidator = true;
|
|
1144
|
+
mergeField('inputSchemaVariable', schemas.inputSchemaVariable);
|
|
1145
|
+
mergeField('outputSchemaVariable', schemas.outputSchemaVariable);
|
|
1146
|
+
if (schemas.stream !== undefined && result.stream === undefined) {
|
|
1147
|
+
result.stream = schemas.stream;
|
|
1148
|
+
}
|
|
1149
|
+
continue;
|
|
1086
1150
|
}
|
|
1087
1151
|
// Try Hono validator('json', callback) pattern
|
|
1088
1152
|
const honoSchemas = extractHonoValidatorSchema(callExpr);
|
|
1089
|
-
|
|
1153
|
+
result.hasValidator = true;
|
|
1154
|
+
mergeField('inputSchemaVariable', honoSchemas.inputSchemaVariable);
|
|
1155
|
+
continue;
|
|
1090
1156
|
}
|
|
1091
1157
|
// Check for zValidator('json', schema)
|
|
1092
1158
|
if (identifier.name === 'zValidator') {
|
|
1093
1159
|
const schemas = extractZValidatorSchema(callExpr);
|
|
1094
|
-
|
|
1160
|
+
result.hasValidator = true;
|
|
1161
|
+
mergeField('inputSchemaVariable', schemas.inputSchemaVariable);
|
|
1162
|
+
continue;
|
|
1095
1163
|
}
|
|
1096
1164
|
}
|
|
1097
1165
|
|
|
@@ -1106,13 +1174,22 @@ function hasValidatorCall(args: unknown[]): ValidatorInfo {
|
|
|
1106
1174
|
: undefined;
|
|
1107
1175
|
// Also check for schema overrides: agent.validator({ input, output })
|
|
1108
1176
|
const schemas = extractValidatorSchemas(callExpr);
|
|
1109
|
-
|
|
1177
|
+
result.hasValidator = true;
|
|
1178
|
+
if (agentVariable && !result.agentVariable) {
|
|
1179
|
+
result.agentVariable = agentVariable;
|
|
1180
|
+
}
|
|
1181
|
+
mergeField('inputSchemaVariable', schemas.inputSchemaVariable);
|
|
1182
|
+
mergeField('outputSchemaVariable', schemas.outputSchemaVariable);
|
|
1183
|
+
if (schemas.stream !== undefined && result.stream === undefined) {
|
|
1184
|
+
result.stream = schemas.stream;
|
|
1185
|
+
}
|
|
1186
|
+
continue;
|
|
1110
1187
|
}
|
|
1111
1188
|
}
|
|
1112
1189
|
}
|
|
1113
1190
|
}
|
|
1114
1191
|
|
|
1115
|
-
return
|
|
1192
|
+
return result;
|
|
1116
1193
|
}
|
|
1117
1194
|
|
|
1118
1195
|
/**
|
|
@@ -1599,7 +1676,7 @@ export async function parseRoute(
|
|
|
1599
1676
|
});
|
|
1600
1677
|
}
|
|
1601
1678
|
|
|
1602
|
-
const rel = relative(rootDir, filename);
|
|
1679
|
+
const rel = toForwardSlash(relative(rootDir, filename));
|
|
1603
1680
|
|
|
1604
1681
|
// Compute the API mount path using the shared helper
|
|
1605
1682
|
// This ensures consistency between route type generation (here) and runtime mounting (entry-generator.ts)
|
|
@@ -1651,8 +1728,12 @@ export async function parseRoute(
|
|
|
1651
1728
|
SUPPORTED_HTTP_METHODS.includes(m.toLowerCase() as SupportedHttpMethod);
|
|
1652
1729
|
|
|
1653
1730
|
switch (method) {
|
|
1654
|
-
case 'use':
|
|
1655
|
-
|
|
1731
|
+
case 'use':
|
|
1732
|
+
case 'onError':
|
|
1733
|
+
case 'notFound':
|
|
1734
|
+
case 'basePath':
|
|
1735
|
+
case 'mount': {
|
|
1736
|
+
// Skip Hono middleware, lifecycle handlers, and configuration methods - they don't represent API routes
|
|
1656
1737
|
continue;
|
|
1657
1738
|
}
|
|
1658
1739
|
case 'route': {
|
|
@@ -2703,7 +2784,7 @@ export async function generateLifecycleTypes(
|
|
|
2703
2784
|
// local dev (symlinked to packages/) and CI (actual node_modules)
|
|
2704
2785
|
if (existsSync(runtimePkgPath)) {
|
|
2705
2786
|
// Calculate relative path from src/generated/ to node_modules package
|
|
2706
|
-
const relPath = relative(outDir, runtimePkgPath);
|
|
2787
|
+
const relPath = toForwardSlash(relative(outDir, runtimePkgPath));
|
|
2707
2788
|
runtimeImportPath = relPath;
|
|
2708
2789
|
logger.debug(`Using relative path to runtime package: ${relPath}`);
|
|
2709
2790
|
} else {
|
|
@@ -11,6 +11,7 @@ import { dirname, join, relative } from 'node:path';
|
|
|
11
11
|
import { existsSync } from 'node:fs';
|
|
12
12
|
import type { Logger } from '../../../types';
|
|
13
13
|
import { formatSchemaCode } from '../format-schema';
|
|
14
|
+
import { toForwardSlash } from '../../../utils/normalize-path';
|
|
14
15
|
|
|
15
16
|
interface ASTNode {
|
|
16
17
|
type: string;
|
|
@@ -728,7 +729,7 @@ export async function discoverAgents(
|
|
|
728
729
|
|
|
729
730
|
// Use 'src/' prefix for consistency with bun bundler and registry imports
|
|
730
731
|
const rootDir = join(srcDir, '..');
|
|
731
|
-
const relativeFilename = relative(rootDir, filePath);
|
|
732
|
+
const relativeFilename = toForwardSlash(relative(rootDir, filePath));
|
|
732
733
|
const agentMetadata = extractAgentMetadata(
|
|
733
734
|
contents,
|
|
734
735
|
relativeFilename,
|
|
@@ -763,7 +764,7 @@ export async function discoverAgents(
|
|
|
763
764
|
// 2. Check for evals in separate eval.ts file in same directory
|
|
764
765
|
const agentDir = dirname(filePath);
|
|
765
766
|
const evalsPath = join(agentDir, 'eval.ts');
|
|
766
|
-
const relativeEvalsPath = relative(rootDir, evalsPath);
|
|
767
|
+
const relativeEvalsPath = toForwardSlash(relative(rootDir, evalsPath));
|
|
767
768
|
const evalsInSeparateFile = await extractEvalMetadata(
|
|
768
769
|
evalsPath,
|
|
769
770
|
relativeEvalsPath,
|
|
@@ -11,6 +11,7 @@ import type { z } from 'zod';
|
|
|
11
11
|
import type { AgentMetadata } from './agent-discovery';
|
|
12
12
|
import type { RouteMetadata } from './route-discovery';
|
|
13
13
|
import type { Logger, DeployOptions } from '../../../types';
|
|
14
|
+
import { toForwardSlash } from '../../../utils/normalize-path';
|
|
14
15
|
import { getVersion } from '../../../version';
|
|
15
16
|
import { getGitInfo, buildGitTags } from '../../../utils/git';
|
|
16
17
|
|
|
@@ -174,7 +175,7 @@ export interface MetadataGeneratorOptions {
|
|
|
174
175
|
*/
|
|
175
176
|
function normalizeImportKey(path: string): string {
|
|
176
177
|
// Strip leading './' or 'src/' or '@'
|
|
177
|
-
let p = path.replace(/^src\//, '');
|
|
178
|
+
let p = toForwardSlash(path).replace(/^src\//, '');
|
|
178
179
|
if (p.startsWith('./')) p = p.slice(2);
|
|
179
180
|
if (p.startsWith('@')) p = p.slice(1);
|
|
180
181
|
|
|
@@ -9,6 +9,7 @@ import { writeFileSync, mkdirSync, existsSync, unlinkSync, readFileSync } from '
|
|
|
9
9
|
import { stat } from 'node:fs/promises';
|
|
10
10
|
import { StructuredError } from '@agentuity/core';
|
|
11
11
|
import { toCamelCase, toPascalCase } from '../../../utils/string';
|
|
12
|
+
import { toForwardSlash } from '../../../utils/normalize-path';
|
|
12
13
|
import type { AgentMetadata } from './agent-discovery';
|
|
13
14
|
import type { RouteInfo } from './route-discovery';
|
|
14
15
|
|
|
@@ -27,7 +28,7 @@ function rebaseImportPath(routeFilename: string, schemaImportPath: string, srcDi
|
|
|
27
28
|
|
|
28
29
|
// Normalize route filename to get its directory relative to srcDir
|
|
29
30
|
let routeDir: string;
|
|
30
|
-
const cleanFilename = routeFilename
|
|
31
|
+
const cleanFilename = toForwardSlash(routeFilename);
|
|
31
32
|
if (cleanFilename.startsWith('./')) {
|
|
32
33
|
routeDir = dirname(join(srcDir, cleanFilename.substring(2)));
|
|
33
34
|
} else if (cleanFilename.startsWith('src/')) {
|
|
@@ -41,7 +42,7 @@ function rebaseImportPath(routeFilename: string, schemaImportPath: string, srcDi
|
|
|
41
42
|
|
|
42
43
|
// Calculate the relative path from src/generated/ to the resolved schema path
|
|
43
44
|
const generatedDir = join(srcDir, 'generated');
|
|
44
|
-
let rebasedPath = relative(generatedDir, resolvedSchemaPath)
|
|
45
|
+
let rebasedPath = toForwardSlash(relative(generatedDir, resolvedSchemaPath));
|
|
45
46
|
|
|
46
47
|
// Ensure it starts with './' or '../'
|
|
47
48
|
if (!rebasedPath.startsWith('.') && !rebasedPath.startsWith('/')) {
|
|
@@ -136,7 +137,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
136
137
|
if (evalMeta.filename === agent.filename) continue;
|
|
137
138
|
|
|
138
139
|
// Build the relative path for the eval file
|
|
139
|
-
let evalRelativePath = evalMeta.filename;
|
|
140
|
+
let evalRelativePath = toForwardSlash(evalMeta.filename);
|
|
140
141
|
if (evalRelativePath.startsWith('./agent/')) {
|
|
141
142
|
evalRelativePath = evalRelativePath
|
|
142
143
|
.replace(/^\.\/agent\//, '../agent/')
|
|
@@ -165,7 +166,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
165
166
|
.map(({ name, filename }) => {
|
|
166
167
|
const camelName = toCamelCase(name);
|
|
167
168
|
// Handle both './agent/...' and 'src/agent/...' formats
|
|
168
|
-
let relativePath = filename;
|
|
169
|
+
let relativePath = toForwardSlash(filename);
|
|
169
170
|
if (relativePath.startsWith('./agent/')) {
|
|
170
171
|
// ./agent/foo.ts -> ../agent/foo.js (use .js extension for TypeScript)
|
|
171
172
|
relativePath = relativePath
|
|
@@ -716,7 +717,8 @@ export async function generateRouteRegistry(
|
|
|
716
717
|
resolvedPath = `../api/${finalPath}`;
|
|
717
718
|
} else if (resolvedPath.startsWith('./') || resolvedPath.startsWith('../')) {
|
|
718
719
|
// Resolve relative import from route file's directory
|
|
719
|
-
const
|
|
720
|
+
const normalizedFilename = toForwardSlash(route.filename);
|
|
721
|
+
const routeDir = normalizedFilename.substring(0, normalizedFilename.lastIndexOf('/'));
|
|
720
722
|
// Join and normalize the path
|
|
721
723
|
const joined = `${routeDir}/${resolvedPath}`;
|
|
722
724
|
// Normalize by resolving .. and . segments
|
|
@@ -784,7 +786,7 @@ export async function generateRouteRegistry(
|
|
|
784
786
|
: (route.inputSchemaImportedName ?? route.inputSchemaVariable);
|
|
785
787
|
} else {
|
|
786
788
|
// Schema is locally defined - import from the route file
|
|
787
|
-
const filename = route.filename
|
|
789
|
+
const filename = toForwardSlash(route.filename);
|
|
788
790
|
const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
|
|
789
791
|
const withoutLeadingDot = withoutSrc.startsWith('./')
|
|
790
792
|
? withoutSrc.substring(2)
|
|
@@ -819,7 +821,7 @@ export async function generateRouteRegistry(
|
|
|
819
821
|
: (route.outputSchemaImportedName ?? route.outputSchemaVariable);
|
|
820
822
|
} else {
|
|
821
823
|
// Schema is locally defined - import from the route file
|
|
822
|
-
const filename = route.filename
|
|
824
|
+
const filename = toForwardSlash(route.filename);
|
|
823
825
|
const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
|
|
824
826
|
const withoutLeadingDot = withoutSrc.startsWith('./')
|
|
825
827
|
? withoutSrc.substring(2)
|
|
@@ -9,6 +9,7 @@ import { join, relative } from 'node:path';
|
|
|
9
9
|
import { existsSync } from 'node:fs';
|
|
10
10
|
import type { Logger } from '../../../types';
|
|
11
11
|
import { parseRoute } from '../ast';
|
|
12
|
+
import { toForwardSlash } from '../../../utils/normalize-path';
|
|
12
13
|
|
|
13
14
|
export interface RouteMetadata {
|
|
14
15
|
id: string;
|
|
@@ -105,7 +106,7 @@ export async function discoverRoutes(
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
const rootDir = join(srcDir, '..');
|
|
108
|
-
const relativeFilename = './' + relative(srcDir, filePath);
|
|
109
|
+
const relativeFilename = './' + toForwardSlash(relative(srcDir, filePath));
|
|
109
110
|
|
|
110
111
|
try {
|
|
111
112
|
const parsedRoutes = await parseRoute(
|
|
@@ -183,7 +184,7 @@ export async function discoverRoutes(
|
|
|
183
184
|
const rootDir = join(srcDir, '..');
|
|
184
185
|
const subrouterRelPaths = new Set<string>();
|
|
185
186
|
for (const absPath of mountedSubrouters) {
|
|
186
|
-
subrouterRelPaths.add(relative(rootDir, absPath));
|
|
187
|
+
subrouterRelPaths.add(toForwardSlash(relative(rootDir, absPath)));
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
// Remove routes whose filename matches a sub-router file
|
package/src/cmd/cloud/deploy.ts
CHANGED
|
@@ -1,68 +1,69 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { join, resolve } from 'node:path';
|
|
3
1
|
import { createPublicKey } from 'node:crypto';
|
|
4
2
|
import { createReadStream, createWriteStream, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
5
3
|
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
6
5
|
import { StructuredError } from '@agentuity/core';
|
|
7
|
-
import { createSubcommand, DeployOptionsSchema } from '../../types';
|
|
8
|
-
import { getUserAgent } from '../../api';
|
|
9
|
-
import * as tui from '../../tui';
|
|
10
|
-
import {
|
|
11
|
-
saveProjectDir,
|
|
12
|
-
getDefaultConfigDir,
|
|
13
|
-
loadProjectSDKKey,
|
|
14
|
-
updateProjectConfig,
|
|
15
|
-
getGlobalCatalystAPIClient,
|
|
16
|
-
} from '../../config';
|
|
17
|
-
import { getProjectGithubStatus } from '../git/api';
|
|
18
|
-
import { runGitLink } from '../git/link';
|
|
19
6
|
import {
|
|
20
|
-
runSteps,
|
|
21
|
-
stepSuccess,
|
|
22
|
-
stepSkipped,
|
|
23
|
-
stepError,
|
|
24
|
-
pauseStepUI,
|
|
25
|
-
StepInterruptError,
|
|
26
|
-
type Step,
|
|
27
|
-
type StepContext,
|
|
28
|
-
} from '../../steps';
|
|
29
|
-
import { viteBundle } from '../build/vite-bundler';
|
|
30
|
-
import { loadBuildMetadata, getStreamURL } from '../../config';
|
|
31
|
-
import {
|
|
32
|
-
projectEnvUpdate,
|
|
33
|
-
projectDeploymentCreate,
|
|
34
|
-
projectDeploymentUpdate,
|
|
35
|
-
projectDeploymentComplete,
|
|
36
|
-
projectDeploymentStatus,
|
|
37
|
-
projectDeploymentMalwareCheck,
|
|
38
|
-
validateResources,
|
|
39
|
-
projectGet,
|
|
40
|
-
projectUpdateRegion,
|
|
41
|
-
type Deployment,
|
|
42
7
|
type BuildMetadata,
|
|
43
|
-
type
|
|
8
|
+
type Deployment,
|
|
44
9
|
type DeploymentComplete,
|
|
10
|
+
type DeploymentInstructions,
|
|
45
11
|
type DeploymentStatusResult,
|
|
46
|
-
type MalwareCheckResult,
|
|
47
12
|
getAppBaseURL,
|
|
13
|
+
type MalwareCheckResult,
|
|
14
|
+
projectDeploymentComplete,
|
|
15
|
+
projectDeploymentCreate,
|
|
16
|
+
projectDeploymentMalwareCheck,
|
|
17
|
+
projectDeploymentStatus,
|
|
18
|
+
projectDeploymentUpdate,
|
|
19
|
+
projectEnvUpdate,
|
|
20
|
+
projectGet,
|
|
21
|
+
projectUpdateRegion,
|
|
22
|
+
validateResources,
|
|
48
23
|
} from '@agentuity/server';
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
import { getUserAgent } from '../../api';
|
|
26
|
+
import { BuildReportCollector, clearGlobalCollector, setGlobalCollector } from '../../build-report';
|
|
27
|
+
import { getCachedProject, setCachedProject } from '../../cache';
|
|
28
|
+
import { getCommand } from '../../command-prefix';
|
|
49
29
|
import {
|
|
30
|
+
getDefaultConfigDir,
|
|
31
|
+
getGlobalCatalystAPIClient,
|
|
32
|
+
getStreamURL,
|
|
33
|
+
loadBuildMetadata,
|
|
34
|
+
loadProjectSDKKey,
|
|
35
|
+
saveProjectDir,
|
|
36
|
+
updateProjectConfig,
|
|
37
|
+
} from '../../config';
|
|
38
|
+
import { encryptFIPSKEMDEMStream } from '../../crypto/box';
|
|
39
|
+
import * as domain from '../../domain';
|
|
40
|
+
import {
|
|
41
|
+
filterAgentuitySdkKeys,
|
|
50
42
|
findExistingEnvFile,
|
|
51
43
|
readEnvFile,
|
|
52
|
-
filterAgentuitySdkKeys,
|
|
53
44
|
splitEnvAndSecrets,
|
|
54
45
|
} from '../../env-util';
|
|
55
|
-
import { zipDir } from '../../utils/zip';
|
|
56
|
-
import { encryptFIPSKEMDEMStream } from '../../crypto/box';
|
|
57
|
-
import { getCommand } from '../../command-prefix';
|
|
58
|
-
import * as domain from '../../domain';
|
|
59
46
|
import { ErrorCode, getExitCode } from '../../errors';
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
import {
|
|
48
|
+
pauseStepUI,
|
|
49
|
+
runSteps,
|
|
50
|
+
type Step,
|
|
51
|
+
type StepContext,
|
|
52
|
+
StepInterruptError,
|
|
53
|
+
stepError,
|
|
54
|
+
stepSkipped,
|
|
55
|
+
stepSuccess,
|
|
56
|
+
} from '../../steps';
|
|
57
|
+
import * as tui from '../../tui';
|
|
58
|
+
import { createSubcommand, DeployOptionsSchema } from '../../types';
|
|
63
59
|
import { validateAptDependencies } from '../../utils/apt-validator';
|
|
64
60
|
import { extractDependencies } from '../../utils/deps';
|
|
65
|
-
import {
|
|
61
|
+
import { zipDir } from '../../utils/zip';
|
|
62
|
+
import { typecheck } from '../build/typecheck';
|
|
63
|
+
import { viteBundle } from '../build/vite-bundler';
|
|
64
|
+
import { getProjectGithubStatus } from '../git/api';
|
|
65
|
+
import { runGitLink } from '../git/link';
|
|
66
|
+
import { runForkedDeploy } from './deploy-fork';
|
|
66
67
|
|
|
67
68
|
const DeploymentCancelledError = StructuredError(
|
|
68
69
|
'DeploymentCancelled',
|
|
@@ -501,7 +502,6 @@ export const deploySubcommand = createSubcommand({
|
|
|
501
502
|
const result = await runGitLink({
|
|
502
503
|
apiClient,
|
|
503
504
|
projectId: project.projectId,
|
|
504
|
-
orgId: project.orgId,
|
|
505
505
|
logger,
|
|
506
506
|
skipAlreadyLinkedCheck: true,
|
|
507
507
|
config,
|
|
@@ -515,7 +515,8 @@ export const deploySubcommand = createSubcommand({
|
|
|
515
515
|
tui.info('Push a commit to trigger your first deployment.');
|
|
516
516
|
tui.newline();
|
|
517
517
|
throw new DeploymentCancelledError();
|
|
518
|
-
}
|
|
518
|
+
}
|
|
519
|
+
if (result.linked) {
|
|
519
520
|
// Linked but auto-deploy disabled, continue with manual deploy
|
|
520
521
|
tui.newline();
|
|
521
522
|
tui.info('GitHub repository linked. Continuing with deployment...');
|
|
@@ -623,9 +624,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
623
624
|
|
|
624
625
|
if (typeResult.success) {
|
|
625
626
|
capturedOutput.push(
|
|
626
|
-
tui.muted(
|
|
627
|
-
`✓ Typechecked in ${Math.floor(Date.now() - started).toFixed(0)}ms`
|
|
628
|
-
)
|
|
627
|
+
tui.muted(`✓ Typechecked in ${Date.now() - started}ms`)
|
|
629
628
|
);
|
|
630
629
|
} else {
|
|
631
630
|
// Errors already added to collector by typecheck()
|
|
@@ -1174,9 +1173,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
1174
1173
|
|
|
1175
1174
|
const lines = [`${ex}`, ''];
|
|
1176
1175
|
lines.push(
|
|
1177
|
-
`${tui.ICONS.arrow} ${
|
|
1178
|
-
tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)
|
|
1179
|
-
}`
|
|
1176
|
+
`${tui.ICONS.arrow} ${tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)}`
|
|
1180
1177
|
);
|
|
1181
1178
|
tui.banner(tui.colorError(`Deployment: ${deployment.id} Failed`), lines.join('\n'), {
|
|
1182
1179
|
centerTitle: false,
|
|
@@ -1209,15 +1206,11 @@ export const deploySubcommand = createSubcommand({
|
|
|
1209
1206
|
}`
|
|
1210
1207
|
);
|
|
1211
1208
|
lines.push(
|
|
1212
|
-
`${tui.ICONS.arrow} ${
|
|
1213
|
-
tui.bold(tui.padRight('Project:', 12)) + tui.link(latestUrl)
|
|
1214
|
-
}`
|
|
1209
|
+
`${tui.ICONS.arrow} ${tui.bold(tui.padRight('Project:', 12)) + tui.link(latestUrl)}`
|
|
1215
1210
|
);
|
|
1216
1211
|
}
|
|
1217
1212
|
lines.push(
|
|
1218
|
-
`${tui.ICONS.arrow} ${
|
|
1219
|
-
tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)
|
|
1220
|
-
}`
|
|
1213
|
+
`${tui.ICONS.arrow} ${tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)}`
|
|
1221
1214
|
);
|
|
1222
1215
|
tui.banner(`Deployment: ${tui.colorPrimary(deployment.id)}`, lines.join('\n'), {
|
|
1223
1216
|
centerTitle: false,
|
|
@@ -2,12 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createSubcommand } from '../../../types';
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
4
|
import { projectEnvDelete, projectGet, orgEnvDelete, orgEnvGet } from '@agentuity/server';
|
|
5
|
-
import {
|
|
6
|
-
findExistingEnvFile,
|
|
7
|
-
readEnvFile,
|
|
8
|
-
writeEnvFile,
|
|
9
|
-
isReservedAgentuityKey,
|
|
10
|
-
} from '../../../env-util';
|
|
5
|
+
import { isReservedAgentuityKey } from '../../../env-util';
|
|
11
6
|
import { getCommand } from '../../../command-prefix';
|
|
12
7
|
import { ErrorCode } from '../../../errors';
|
|
13
8
|
import { resolveOrgId, isOrgScope } from './org-util';
|
|
@@ -15,10 +10,6 @@ import { resolveOrgId, isOrgScope } from './org-util';
|
|
|
15
10
|
const EnvDeleteResponseSchema = z.object({
|
|
16
11
|
success: z.boolean().describe('Whether the operation succeeded'),
|
|
17
12
|
keys: z.array(z.string()).describe('Variable keys that were deleted'),
|
|
18
|
-
path: z
|
|
19
|
-
.string()
|
|
20
|
-
.optional()
|
|
21
|
-
.describe('Local file path where variables were removed (project scope only)'),
|
|
22
13
|
secrets: z.array(z.string()).describe('Keys that were secrets'),
|
|
23
14
|
env: z.array(z.string()).describe('Keys that were environment variables'),
|
|
24
15
|
scope: z.enum(['project', 'org']).describe('The scope from which the variables were deleted'),
|
|
@@ -61,7 +52,7 @@ export const deleteSubcommand = createSubcommand({
|
|
|
61
52
|
},
|
|
62
53
|
|
|
63
54
|
async handler(ctx) {
|
|
64
|
-
const { args, project,
|
|
55
|
+
const { args, project, apiClient, config, opts } = ctx;
|
|
65
56
|
const useOrgScope = isOrgScope(opts?.org);
|
|
66
57
|
const keys = args.key;
|
|
67
58
|
|
|
@@ -174,38 +165,16 @@ export const deleteSubcommand = createSubcommand({
|
|
|
174
165
|
});
|
|
175
166
|
});
|
|
176
167
|
|
|
177
|
-
// Update local .env file only if we have a project directory and an existing .env file
|
|
178
|
-
let envFilePath: string | undefined;
|
|
179
|
-
if (projectDir) {
|
|
180
|
-
envFilePath = await findExistingEnvFile(projectDir);
|
|
181
|
-
if (envFilePath) {
|
|
182
|
-
const currentEnv = await readEnvFile(envFilePath);
|
|
183
|
-
const originalKeyCount = Object.keys(currentEnv).length;
|
|
184
|
-
for (const key of [...secretKeys, ...envKeys]) {
|
|
185
|
-
delete currentEnv[key];
|
|
186
|
-
}
|
|
187
|
-
// Only write if we actually removed keys (avoid creating empty file)
|
|
188
|
-
const keysRemoved = originalKeyCount > Object.keys(currentEnv).length;
|
|
189
|
-
if (keysRemoved) {
|
|
190
|
-
await writeEnvFile(envFilePath, currentEnv, { preserveExisting: false });
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
168
|
const deletedKeys = [...secretKeys, ...envKeys];
|
|
196
169
|
if (notFoundKeys.length > 0) {
|
|
197
170
|
tui.warning(`Variables not found (skipped): ${notFoundKeys.join(', ')}`);
|
|
198
171
|
}
|
|
199
172
|
|
|
200
|
-
|
|
201
|
-
tui.success(
|
|
202
|
-
`Deleted ${deletedKeys.length} variable(s): ${deletedKeys.join(', ')}${locationMsg}`
|
|
203
|
-
);
|
|
173
|
+
tui.success(`Deleted ${deletedKeys.length} variable(s): ${deletedKeys.join(', ')}`);
|
|
204
174
|
|
|
205
175
|
return {
|
|
206
176
|
success: true,
|
|
207
177
|
keys: deletedKeys,
|
|
208
|
-
path: envFilePath,
|
|
209
178
|
secrets: secretKeys,
|
|
210
179
|
env: envKeys,
|
|
211
180
|
scope: 'project' as const,
|
|
@@ -3,9 +3,7 @@ import { createSubcommand } from '../../../types';
|
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
4
|
import { projectEnvUpdate, orgEnvUpdate } from '@agentuity/server';
|
|
5
5
|
import {
|
|
6
|
-
findExistingEnvFile,
|
|
7
6
|
readEnvFile,
|
|
8
|
-
writeEnvFile,
|
|
9
7
|
filterAgentuitySdkKeys,
|
|
10
8
|
splitEnvAndSecrets,
|
|
11
9
|
validateNoPublicSecrets,
|
|
@@ -19,17 +17,13 @@ const EnvImportResponseSchema = z.object({
|
|
|
19
17
|
envCount: z.number().describe('Number of env vars imported'),
|
|
20
18
|
secretCount: z.number().describe('Number of secrets imported'),
|
|
21
19
|
skipped: z.number().describe('Number of items skipped'),
|
|
22
|
-
path: z
|
|
23
|
-
.string()
|
|
24
|
-
.optional()
|
|
25
|
-
.describe('Local file path where variables were saved (project scope only)'),
|
|
26
20
|
file: z.string().describe('Source file path'),
|
|
27
21
|
scope: z.enum(['project', 'org']).describe('The scope where variables were imported'),
|
|
28
22
|
});
|
|
29
23
|
|
|
30
24
|
export const importSubcommand = createSubcommand({
|
|
31
25
|
name: 'import',
|
|
32
|
-
description: 'Import environment variables and secrets from a file to cloud
|
|
26
|
+
description: 'Import environment variables and secrets from a file to cloud',
|
|
33
27
|
tags: ['mutating', 'creates-resource', 'slow', 'api-intensive', 'requires-auth'],
|
|
34
28
|
examples: [
|
|
35
29
|
{
|
|
@@ -62,7 +56,7 @@ export const importSubcommand = createSubcommand({
|
|
|
62
56
|
},
|
|
63
57
|
|
|
64
58
|
async handler(ctx) {
|
|
65
|
-
const { args, apiClient, project,
|
|
59
|
+
const { args, apiClient, project, config, opts } = ctx;
|
|
66
60
|
const useOrgScope = isOrgScope(opts?.org);
|
|
67
61
|
|
|
68
62
|
// Require project context if not using org scope
|
|
@@ -161,15 +155,6 @@ export const importSubcommand = createSubcommand({
|
|
|
161
155
|
});
|
|
162
156
|
});
|
|
163
157
|
|
|
164
|
-
// Merge with local .env file only if we have a project directory
|
|
165
|
-
let localEnvPath: string | undefined;
|
|
166
|
-
if (projectDir) {
|
|
167
|
-
localEnvPath = await findExistingEnvFile(projectDir);
|
|
168
|
-
// writeEnvFile preserves existing keys by default, so just write the filtered vars
|
|
169
|
-
// This will merge with existing .env content, preserving AGENTUITY_SDK_KEY and other keys
|
|
170
|
-
await writeEnvFile(localEnvPath, filteredVars);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
158
|
tui.success(
|
|
174
159
|
`Imported ${totalCount} variable${totalCount !== 1 ? 's' : ''} from ${args.file} (${envCount} env, ${secretCount} secret${secretCount !== 1 ? 's' : ''})`
|
|
175
160
|
);
|
|
@@ -180,7 +165,6 @@ export const importSubcommand = createSubcommand({
|
|
|
180
165
|
envCount,
|
|
181
166
|
secretCount,
|
|
182
167
|
skipped: Object.keys(importedVars).length - totalCount,
|
|
183
|
-
path: localEnvPath,
|
|
184
168
|
file: args.file,
|
|
185
169
|
scope: 'project' as const,
|
|
186
170
|
};
|