@agentuity/cli 1.0.5 → 1.0.7

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.
@@ -98,17 +98,19 @@ export async function generateEntryFile(options) {
98
98
  ${routeImportsAndMounts.join('\n')}
99
99
  `
100
100
  : '';
101
- // Workbench API routes mounting (if configured)
102
- // hasWorkbenchConfig is build-time (from agentuity.config.ts)
103
- // hasWorkbench combines config + runtime dev mode check
101
+ // Workbench API routes mounting
102
+ // Always mounted - these routes are needed for the cloud workbench to communicate with deployed agents
103
+ // Auth is handled by middleware inside the router (signature verification in production, no auth in development)
104
+ // The hasWorkbenchConfig flag only controls whether the local workbench UI is served
104
105
  const workbenchApiMount = `
106
+ // Mount workbench API routes (/_agentuity/workbench/*)
107
+ // Always available for cloud workbench communication
108
+ // Auth is handled inside the router (signature verification in production)
109
+ const workbenchRouter = createWorkbenchRouter();
110
+ app.route('/', workbenchRouter);
111
+
112
+ // hasWorkbenchConfig controls whether the local workbench UI is served (dev mode only)
105
113
  const hasWorkbenchConfig = ${hasWorkbenchConfig};
106
- const hasWorkbench = isDevelopment() && hasWorkbenchConfig;
107
- if (hasWorkbench) {
108
- // Mount workbench API routes (/_agentuity/workbench/*)
109
- const workbenchRouter = createWorkbenchRouter();
110
- app.route('/', workbenchRouter);
111
- }
112
114
  `;
113
115
  // Asset proxy routes - Always generated, but only active at runtime when:
114
116
  // - NODE_ENV !== 'production' (isDevelopment())
@@ -333,7 +335,7 @@ ${analyticsEnabled
333
335
  // 404 for unmatched API/system routes
334
336
  app.all('/_agentuity/*', (c: Context) => c.notFound());
335
337
  app.all('/api/*', (c: Context) => c.notFound());
336
- if (!hasWorkbench) {
338
+ if (!(hasWorkbenchConfig && isDevelopment())) {
337
339
  app.all('/workbench/*', (c: Context) => c.notFound());
338
340
  }
339
341
 
@@ -379,7 +381,7 @@ ${analyticsEnabled
379
381
  // 404 for unmatched API/system routes (IMPORTANT: comes before SPA fallback)
380
382
  app.all('/_agentuity/*', (c: Context) => c.notFound());
381
383
  app.all('/api/*', (c: Context) => c.notFound());
382
- if (!hasWorkbench) {
384
+ if (!(hasWorkbenchConfig && isDevelopment())) {
383
385
  app.all('/workbench/*', (c: Context) => c.notFound());
384
386
  }
385
387
 
@@ -395,25 +397,22 @@ ${analyticsEnabled
395
397
  }
396
398
  `;
397
399
  }
398
- // Workbench routes (if enabled) - runtime mode detection
400
+ // Workbench UI routes (development only)
401
+ // The workbench UI is only served in development mode; the API routes are always available
399
402
  const workbenchRoute = workbench?.route ?? '/workbench';
400
403
  const workbenchRoutes = `
401
- if (hasWorkbench) {
402
- // Development mode: Let Vite serve source files with HMR
403
- if (isDevelopment()) {
404
- const workbenchSrcDir = import.meta.dir + '/workbench-src';
405
- const workbenchIndexPath = import.meta.dir + '/workbench-src/index.html';
406
- app.get('${workbenchRoute}', async (c: Context) => {
407
- const html = await Bun.file(workbenchIndexPath).text();
408
- // Rewrite script/css paths to use Vite's @fs protocol
409
- const withVite = html
410
- .replace('src="./main.tsx"', \`src="/@fs\${workbenchSrcDir}/main.tsx"\`)
411
- .replace('href="./styles.css"', \`href="/@fs\${workbenchSrcDir}/styles.css"\`);
412
- return c.html(withVite);
413
- });
414
- } else {
415
- // Production mode disables the workbench assets
416
- }
404
+ // Workbench UI is only available in development mode (API routes are always available)
405
+ if (hasWorkbenchConfig && isDevelopment()) {
406
+ const workbenchSrcDir = import.meta.dir + '/workbench-src';
407
+ const workbenchIndexPath = import.meta.dir + '/workbench-src/index.html';
408
+ app.get('${workbenchRoute}', async (c: Context) => {
409
+ const html = await Bun.file(workbenchIndexPath).text();
410
+ // Rewrite script/css paths to use Vite's @fs protocol
411
+ const withVite = html
412
+ .replace('src="./main.tsx"', \`src="/@fs\${workbenchSrcDir}/main.tsx"\`)
413
+ .replace('href="./styles.css"', \`href="/@fs\${workbenchSrcDir}/styles.css"\`);
414
+ return c.html(withVite);
415
+ });
417
416
  }
418
417
  `;
419
418
  // Server startup (same for dev and prod - Bun.serve with native WebSocket)
@@ -600,7 +599,8 @@ app.use('*', createBaseMiddleware({
600
599
  meter: otel.meter,
601
600
  }));
602
601
 
603
- app.use('/_agentuity/workbench/*', createCorsMiddleware());
602
+ // Note: Workbench routes use their own CORS middleware (defined in createWorkbenchRouter)
603
+ // which includes signature headers for production authentication
604
604
  app.use('/api/*', createCorsMiddleware());
605
605
 
606
606
  // Critical: otelMiddleware creates session/thread/waitUntilHandler
@@ -1 +1 @@
1
- {"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../../../src/cmd/build/entry-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../../../src/cmd/build/entry-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface EnvDiffEntry {
2
+ key: string;
3
+ /** The value from the "source" side (the side being pushed/pulled from) */
4
+ sourceValue: string;
5
+ /** The value from the "target" side (the side being overwritten), undefined if new */
6
+ targetValue?: string;
7
+ /** Whether the source side stores this as a secret */
8
+ sourceIsSecret: boolean;
9
+ /** Whether the target side stores this as a secret (undefined if new, i.e. no target) */
10
+ targetIsSecret?: boolean;
11
+ }
12
+ export interface EnvDiff {
13
+ newEntries: EnvDiffEntry[];
14
+ changedEntries: EnvDiffEntry[];
15
+ unchangedEntries: EnvDiffEntry[];
16
+ }
17
+ /**
18
+ * Compute diff between source and target env/secrets.
19
+ * "Source" is where values come from; "target" is what will be overwritten.
20
+ *
21
+ * For push: source=local, target=remote
22
+ * For pull: source=cloud, target=local
23
+ */
24
+ export declare function computeEnvDiff(sourceEnv: Record<string, string>, sourceSecrets: Record<string, string>, targetEnv: Record<string, string>, targetSecrets: Record<string, string>): EnvDiff;
25
+ export interface DisplayEnvDiffOptions {
26
+ /** Label for the operation, shown in header. E.g. "push" or "pull" */
27
+ direction: 'push' | 'pull';
28
+ }
29
+ /**
30
+ * Display a diff view of env changes.
31
+ * In TTY mode, shows a rich color-coded diff.
32
+ * In non-TTY mode, shows simple text summary.
33
+ */
34
+ export declare function displayEnvDiff(diff: EnvDiff, options: DisplayEnvDiffOptions): void;
35
+ //# sourceMappingURL=env-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-diff.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/env-diff.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,cAAc,EAAE,OAAO,CAAC;IACxB,yFAAyF;IACzF,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,OAAO;IACvB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,gBAAgB,EAAE,YAAY,EAAE,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CA4ET;AAMD,MAAM,WAAW,qBAAqB;IACrC,sEAAsE;IACtE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAsDlF"}
@@ -0,0 +1,145 @@
1
+ import * as tui from '../../../tui';
2
+ import { maskSecret } from '../../../env-util';
3
+ /**
4
+ * Compute diff between source and target env/secrets.
5
+ * "Source" is where values come from; "target" is what will be overwritten.
6
+ *
7
+ * For push: source=local, target=remote
8
+ * For pull: source=cloud, target=local
9
+ */
10
+ export function computeEnvDiff(sourceEnv, sourceSecrets, targetEnv, targetSecrets) {
11
+ const newEntries = [];
12
+ const changedEntries = [];
13
+ const unchangedEntries = [];
14
+ // Check env vars
15
+ for (const key of Object.keys(sourceEnv)) {
16
+ const sourceValue = sourceEnv[key];
17
+ if (key in targetEnv) {
18
+ if (sourceValue === targetEnv[key]) {
19
+ unchangedEntries.push({
20
+ key,
21
+ sourceValue,
22
+ targetValue: targetEnv[key],
23
+ sourceIsSecret: false,
24
+ targetIsSecret: false,
25
+ });
26
+ }
27
+ else {
28
+ changedEntries.push({
29
+ key,
30
+ sourceValue,
31
+ targetValue: targetEnv[key],
32
+ sourceIsSecret: false,
33
+ targetIsSecret: false,
34
+ });
35
+ }
36
+ }
37
+ else if (key in targetSecrets) {
38
+ // Key exists but as a different type - treat as changed
39
+ changedEntries.push({
40
+ key,
41
+ sourceValue,
42
+ targetValue: targetSecrets[key],
43
+ sourceIsSecret: false,
44
+ targetIsSecret: true,
45
+ });
46
+ }
47
+ else {
48
+ newEntries.push({ key, sourceValue, sourceIsSecret: false });
49
+ }
50
+ }
51
+ // Check secrets
52
+ for (const key of Object.keys(sourceSecrets)) {
53
+ const sourceValue = sourceSecrets[key];
54
+ if (key in targetSecrets) {
55
+ if (sourceValue === targetSecrets[key]) {
56
+ unchangedEntries.push({
57
+ key,
58
+ sourceValue,
59
+ targetValue: targetSecrets[key],
60
+ sourceIsSecret: true,
61
+ targetIsSecret: true,
62
+ });
63
+ }
64
+ else {
65
+ changedEntries.push({
66
+ key,
67
+ sourceValue,
68
+ targetValue: targetSecrets[key],
69
+ sourceIsSecret: true,
70
+ targetIsSecret: true,
71
+ });
72
+ }
73
+ }
74
+ else if (key in targetEnv) {
75
+ // Key exists but as a different type - treat as changed
76
+ changedEntries.push({
77
+ key,
78
+ sourceValue,
79
+ targetValue: targetEnv[key],
80
+ sourceIsSecret: true,
81
+ targetIsSecret: false,
82
+ });
83
+ }
84
+ else {
85
+ newEntries.push({ key, sourceValue, sourceIsSecret: true });
86
+ }
87
+ }
88
+ return { newEntries, changedEntries, unchangedEntries };
89
+ }
90
+ function displayValue(value, isSecret) {
91
+ return isSecret ? maskSecret(value) : value;
92
+ }
93
+ /**
94
+ * Display a diff view of env changes.
95
+ * In TTY mode, shows a rich color-coded diff.
96
+ * In non-TTY mode, shows simple text summary.
97
+ */
98
+ export function displayEnvDiff(diff, options) {
99
+ const { direction } = options;
100
+ // Non-TTY: simple summary
101
+ if (!tui.isTTYLike()) {
102
+ if (diff.newEntries.length > 0) {
103
+ tui.info(`New variables: ${diff.newEntries.length} (${diff.newEntries.map((e) => e.key).join(', ')})`);
104
+ }
105
+ if (diff.changedEntries.length > 0) {
106
+ const verb = direction === 'push' ? 'overwritten remotely' : 'overwritten locally';
107
+ tui.warning(`Variables that will be ${verb}: ${diff.changedEntries.length} (${diff.changedEntries.map((e) => e.key).join(', ')})`);
108
+ }
109
+ if (diff.unchangedEntries.length > 0) {
110
+ tui.info(`Unchanged variables: ${diff.unchangedEntries.length}`);
111
+ }
112
+ return;
113
+ }
114
+ // TTY: rich diff view
115
+ tui.newline();
116
+ tui.info('Environment variable changes:');
117
+ tui.newline();
118
+ // Sort all entries by key for consistent display
119
+ const allEntries = [
120
+ ...diff.newEntries.map((e) => ({ ...e, status: 'new' })),
121
+ ...diff.changedEntries.map((e) => ({ ...e, status: 'changed' })),
122
+ ...diff.unchangedEntries.map((e) => ({ ...e, status: 'unchanged' })),
123
+ ].sort((a, b) => a.key.localeCompare(b.key));
124
+ for (const entry of allEntries) {
125
+ const typeLabel = entry.sourceIsSecret ? 'secret' : 'env';
126
+ const val = displayValue(entry.sourceValue, entry.sourceIsSecret);
127
+ if (entry.status === 'new') {
128
+ const line = ` ${tui.colorSuccess('+')} ${tui.bold(entry.key)}=${val} ${tui.colorMuted(`(new, ${typeLabel})`)}`;
129
+ process.stderr.write(line + '\n');
130
+ }
131
+ else if (entry.status === 'changed') {
132
+ const oldVal = displayValue(entry.targetValue, entry.targetIsSecret ?? false);
133
+ // For push: show "remote_old → local_new" (replacing remote with local)
134
+ // For pull: show "local_old → cloud_new" (replacing local with cloud)
135
+ const line = ` ${tui.colorWarning('~')} ${tui.bold(entry.key)}=${oldVal} → ${val} ${tui.colorMuted(`(changed, ${typeLabel})`)}`;
136
+ process.stderr.write(line + '\n');
137
+ }
138
+ else {
139
+ const line = ` ${tui.colorMuted(`= ${entry.key}=${val} (unchanged, ${typeLabel})`)}`;
140
+ process.stderr.write(line + '\n');
141
+ }
142
+ }
143
+ tui.newline();
144
+ }
145
+ //# sourceMappingURL=env-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-diff.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/env-diff.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/pull.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc,yCAwHzB,CAAC"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/pull.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,cAAc,yCAyKzB,CAAC"}
@@ -2,12 +2,16 @@ import { z } from 'zod';
2
2
  import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { projectGet, orgEnvGet } from '@agentuity/server';
5
- import { findExistingEnvFile, readEnvFile, writeEnvFile, mergeEnvVars } from '../../../env-util';
5
+ import { findExistingEnvFile, readEnvFile, writeEnvFile, mergeEnvVars, splitEnvAndSecrets, filterAgentuitySdkKeys, } from '../../../env-util';
6
6
  import { getCommand } from '../../../command-prefix';
7
7
  import { resolveOrgId, isOrgScope } from './org-util';
8
+ import { computeEnvDiff, displayEnvDiff } from './env-diff';
8
9
  const EnvPullResponseSchema = z.object({
9
10
  success: z.boolean().describe('Whether pull succeeded'),
10
11
  pulled: z.number().describe('Number of items pulled'),
12
+ newCount: z.number().describe('Number of new variables added locally'),
13
+ changedCount: z.number().describe('Number of local variables overwritten'),
14
+ unchangedCount: z.number().describe('Number of unchanged variables'),
11
15
  path: z.string().describe('Local file path where variables were saved'),
12
16
  force: z.boolean().describe('Whether force mode was used'),
13
17
  scope: z.enum(['project', 'org']).describe('The scope from which variables were pulled'),
@@ -38,11 +42,13 @@ export const pullSubcommand = createSubcommand({
38
42
  async handler(ctx) {
39
43
  const { opts, apiClient, project, projectDir, config } = ctx;
40
44
  const useOrgScope = isOrgScope(opts?.org);
45
+ const forceMode = opts?.force ?? false;
41
46
  // Require project context for local file operations
42
47
  if (!projectDir) {
43
48
  tui.fatal('Project context required. Run from a project directory.');
44
49
  }
45
- let cloudEnv;
50
+ let cloudEnvVars = {};
51
+ let cloudSecretVars = {};
46
52
  let scope;
47
53
  let cloudApiKey;
48
54
  if (useOrgScope) {
@@ -51,7 +57,8 @@ export const pullSubcommand = createSubcommand({
51
57
  const orgData = await tui.spinner('Pulling environment variables from organization', () => {
52
58
  return orgEnvGet(apiClient, { id: orgId, mask: false });
53
59
  });
54
- cloudEnv = { ...orgData.env, ...orgData.secrets };
60
+ cloudEnvVars = orgData.env || {};
61
+ cloudSecretVars = orgData.secrets || {};
55
62
  scope = 'org';
56
63
  cloudApiKey = undefined; // Orgs don't have api_key
57
64
  }
@@ -63,7 +70,8 @@ export const pullSubcommand = createSubcommand({
63
70
  const projectData = await tui.spinner('Pulling environment variables from cloud', () => {
64
71
  return projectGet(apiClient, { id: project.projectId, mask: false });
65
72
  });
66
- cloudEnv = { ...projectData.env, ...projectData.secrets };
73
+ cloudEnvVars = projectData.env || {};
74
+ cloudSecretVars = projectData.secrets || {};
67
75
  scope = 'project';
68
76
  cloudApiKey = projectData.api_key;
69
77
  }
@@ -72,9 +80,36 @@ export const pullSubcommand = createSubcommand({
72
80
  const localEnv = await readEnvFile(targetEnvPath);
73
81
  // Preserve local AGENTUITY_SDK_KEY
74
82
  const localSdkKey = localEnv.AGENTUITY_SDK_KEY;
83
+ // Split local env for diff comparison (excluding AGENTUITY_ reserved keys)
84
+ const localForDiff = { ...localEnv };
85
+ delete localForDiff.AGENTUITY_SDK_KEY;
86
+ const filteredLocal = filterAgentuitySdkKeys(localForDiff);
87
+ const { env: localEnvVars, secrets: localSecretVars } = splitEnvAndSecrets(filteredLocal);
88
+ // Compute diff: cloud (source) → local (target)
89
+ const diff = computeEnvDiff(cloudEnvVars, cloudSecretVars, localEnvVars, localSecretVars);
90
+ // Display diff
91
+ displayEnvDiff(diff, { direction: 'pull' });
92
+ // If force mode and there are changes, prompt for confirmation
93
+ if (forceMode && diff.changedEntries.length > 0) {
94
+ const confirmed = await tui.confirm(`${diff.changedEntries.length} local variable${diff.changedEntries.length !== 1 ? 's' : ''} will be overwritten. Continue?`, true);
95
+ if (!confirmed) {
96
+ tui.info('Pull cancelled');
97
+ return {
98
+ success: false,
99
+ pulled: 0,
100
+ newCount: 0,
101
+ changedCount: 0,
102
+ unchangedCount: 0,
103
+ path: targetEnvPath,
104
+ force: forceMode,
105
+ scope,
106
+ };
107
+ }
108
+ }
75
109
  // Merge: cloud values override local if force=true, otherwise keep local
110
+ const cloudEnv = { ...cloudEnvVars, ...cloudSecretVars };
76
111
  let mergedEnv;
77
- if (opts?.force) {
112
+ if (forceMode) {
78
113
  // Cloud values take priority
79
114
  mergedEnv = mergeEnvVars(localEnv, cloudEnv);
80
115
  }
@@ -102,12 +137,21 @@ export const pullSubcommand = createSubcommand({
102
137
  }
103
138
  const count = Object.keys(cloudEnv).length;
104
139
  const scopeLabel = useOrgScope ? 'organization' : 'project';
105
- tui.success(`Pulled ${count} environment variable${count !== 1 ? 's' : ''} from ${scopeLabel} to ${targetEnvPath}`);
140
+ // Update success message with diff counts
141
+ if (forceMode) {
142
+ tui.success(`Pulled ${count} variable${count !== 1 ? 's' : ''} from ${scopeLabel} (${diff.newEntries.length} new, ${diff.changedEntries.length} updated, ${diff.unchangedEntries.length} unchanged)`);
143
+ }
144
+ else {
145
+ tui.success(`Pulled ${count} variable${count !== 1 ? 's' : ''} from ${scopeLabel} (${diff.newEntries.length} new, ${diff.changedEntries.length} skipped, ${diff.unchangedEntries.length} unchanged)`);
146
+ }
106
147
  return {
107
148
  success: true,
108
149
  pulled: count,
150
+ newCount: diff.newEntries.length,
151
+ changedCount: forceMode ? diff.changedEntries.length : 0,
152
+ unchangedCount: diff.unchangedEntries.length,
109
153
  path: targetEnvPath,
110
- force: opts?.force ?? false,
154
+ force: forceMode,
111
155
  scope,
112
156
  };
113
157
  },
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACvD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IACvE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IAC1D,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;CACxF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;IAC9C,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,0DAA0D;IACvE,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IAC/B,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE;QACT,EAAE,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE;QACrE,EAAE,OAAO,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE;QAC7F,EAAE,OAAO,EAAE,UAAU,CAAC,gBAAgB,CAAC,EAAE,WAAW,EAAE,wBAAwB,EAAE;KAChF;IACD,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;IACzC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;IAC3B,aAAa,EAAE,CAAC,cAAc,CAAC;IAC/B,MAAM,EAAE;QACP,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;YACjB,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACtF,GAAG,EAAE,CAAC;iBACJ,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;iBAChC,QAAQ,EAAE;iBACV,QAAQ,CAAC,0DAA0D,CAAC;SACtE,CAAC;QACF,QAAQ,EAAE,qBAAqB;KAC/B;IAED,KAAK,CAAC,OAAO,CAAC,GAAG;QAChB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAC7D,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAE1C,oDAAoD;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,GAAG,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,QAAgC,CAAC;QACrC,IAAI,KAAwB,CAAC;QAC7B,IAAI,WAA+B,CAAC;QAEpC,IAAI,WAAW,EAAE,CAAC;YACjB,qBAAqB;YACrB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAK,CAAC,GAAI,CAAC,CAAC;YAEhE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAChC,iDAAiD,EACjD,GAAG,EAAE;gBACJ,OAAO,SAAS,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzD,CAAC,CACD,CAAC;YAEF,QAAQ,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YAClD,KAAK,GAAG,KAAK,CAAC;YACd,WAAW,GAAG,SAAS,CAAC,CAAC,0BAA0B;QACpD,CAAC;aAAM,CAAC;YACP,gBAAgB;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,GAAG,CAAC,KAAK,CACR,6FAA6F,CAC7F,CAAC;YACH,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBACtF,OAAO,UAAU,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,QAAQ,GAAG,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;YAC1D,KAAK,GAAG,SAAS,CAAC;YAClB,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC;QACnC,CAAC;QAED,6BAA6B;QAC7B,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC;QAElD,mCAAmC;QACnC,MAAM,WAAW,GAAG,QAAQ,CAAC,iBAAiB,CAAC;QAE/C,yEAAyE;QACzE,IAAI,SAAiC,CAAC;QACtC,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YACjB,6BAA6B;YAC7B,SAAS,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACP,4DAA4D;YAC5D,SAAS,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;QAED,oFAAoF;QACpF,MAAM,aAAa,GAAG,WAAW,IAAI,WAAW,CAAC;QACjD,IAAI,aAAa,EAAE,CAAC;YACnB,SAAS,CAAC,iBAAiB,GAAG,aAAa,CAAC;QAC7C,CAAC;QAED,mGAAmG;QACnG,MAAM,YAAY,CAAC,aAAa,EAAE,SAAS,EAAE;YAC5C,gBAAgB,EAAE,KAAK;YACvB,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;gBACnB,IAAI,GAAG,KAAK,mBAAmB,EAAE,CAAC;oBACjC,OAAO,wFAAwF,CAAC;gBACjG,CAAC;gBACD,OAAO,IAAI,CAAC;YACb,CAAC;SACD,CAAC,CAAC;QAEH,IAAI,WAAW,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,8BAA8B,aAAa,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC3C,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,GAAG,CAAC,OAAO,CACV,UAAU,KAAK,wBAAwB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,UAAU,OAAO,aAAa,EAAE,CACtG,CAAC;QAEF,OAAO;YACN,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK;YAC3B,KAAK;SACL,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/pull.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/push.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,cAAc,yCAkIzB,CAAC"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/env/push.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,cAAc,yCAsNzB,CAAC"}
@@ -1,17 +1,22 @@
1
1
  import { z } from 'zod';
2
2
  import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
- import { projectEnvUpdate, orgEnvUpdate } from '@agentuity/server';
4
+ import { projectEnvUpdate, orgEnvUpdate, projectGet, orgEnvGet } from '@agentuity/server';
5
5
  import { findExistingEnvFile, readEnvFile, filterAgentuitySdkKeys, splitEnvAndSecrets, validateNoPublicSecrets, } from '../../../env-util';
6
6
  import { getCommand } from '../../../command-prefix';
7
7
  import { resolveOrgId, isOrgScope } from './org-util';
8
+ import { computeEnvDiff, displayEnvDiff } from './env-diff';
8
9
  const EnvPushResponseSchema = z.object({
9
10
  success: z.boolean().describe('Whether push succeeded'),
10
11
  pushed: z.number().describe('Number of items pushed'),
11
12
  envCount: z.number().describe('Number of env vars pushed'),
12
13
  secretCount: z.number().describe('Number of secrets pushed'),
14
+ newCount: z.number().describe('Number of new variables added'),
15
+ changedCount: z.number().describe('Number of existing variables overwritten'),
16
+ unchangedCount: z.number().describe('Number of unchanged variables'),
13
17
  source: z.string().describe('Source file path'),
14
18
  scope: z.enum(['project', 'org']).describe('The scope where variables were pushed'),
19
+ force: z.boolean().describe('Whether force mode was used'),
15
20
  });
16
21
  export const pushSubcommand = createSubcommand({
17
22
  name: 'push',
@@ -31,6 +36,7 @@ export const pushSubcommand = createSubcommand({
31
36
  .union([z.boolean(), z.string()])
32
37
  .optional()
33
38
  .describe('push to organization level (use --org for default org)'),
39
+ force: z.boolean().default(false).describe('overwrite remote values without confirmation'),
34
40
  }),
35
41
  response: EnvPushResponseSchema,
36
42
  },
@@ -46,6 +52,7 @@ export const pushSubcommand = createSubcommand({
46
52
  const localEnv = await readEnvFile(envFilePath);
47
53
  // Filter out reserved AGENTUITY_ prefixed keys
48
54
  const filteredEnv = filterAgentuitySdkKeys(localEnv);
55
+ const forceMode = opts?.force ?? false;
49
56
  if (Object.keys(filteredEnv).length === 0) {
50
57
  tui.warning('No variables to push');
51
58
  return {
@@ -53,8 +60,12 @@ export const pushSubcommand = createSubcommand({
53
60
  pushed: 0,
54
61
  envCount: 0,
55
62
  secretCount: 0,
63
+ newCount: 0,
64
+ changedCount: 0,
65
+ unchangedCount: 0,
56
66
  source: envFilePath,
57
67
  scope: useOrgScope ? 'org' : 'project',
68
+ force: forceMode,
58
69
  };
59
70
  }
60
71
  // Split into env and secrets based on key naming conventions
@@ -74,6 +85,31 @@ export const pushSubcommand = createSubcommand({
74
85
  if (useOrgScope) {
75
86
  // Organization scope
76
87
  const orgId = await resolveOrgId(apiClient, config, opts.org);
88
+ // Fetch remote state to compute diff
89
+ const orgData = await tui.spinner('Fetching remote variables', () => {
90
+ return orgEnvGet(apiClient, { id: orgId, mask: false });
91
+ });
92
+ const diff = computeEnvDiff(env, secrets, orgData.env || {}, orgData.secrets || {});
93
+ displayEnvDiff(diff, { direction: 'push' });
94
+ // Prompt for confirmation if there are changes to existing variables
95
+ if (diff.changedEntries.length > 0 && !forceMode) {
96
+ const confirmed = await tui.confirm(`${diff.changedEntries.length} existing variable${diff.changedEntries.length !== 1 ? 's' : ''} will be overwritten. Continue?`, true);
97
+ if (!confirmed) {
98
+ tui.info('Push cancelled');
99
+ return {
100
+ success: false,
101
+ pushed: 0,
102
+ envCount: 0,
103
+ secretCount: 0,
104
+ newCount: 0,
105
+ changedCount: 0,
106
+ unchangedCount: 0,
107
+ source: envFilePath,
108
+ scope: 'org',
109
+ force: forceMode,
110
+ };
111
+ }
112
+ }
77
113
  await tui.spinner('Pushing variables to organization', () => {
78
114
  return orgEnvUpdate(apiClient, {
79
115
  id: orgId,
@@ -84,21 +120,50 @@ export const pushSubcommand = createSubcommand({
84
120
  const envCount = Object.keys(env).length;
85
121
  const secretCount = Object.keys(secrets).length;
86
122
  const totalCount = envCount + secretCount;
87
- tui.success(`Pushed ${totalCount} variable${totalCount !== 1 ? 's' : ''} to organization (${envCount} env, ${secretCount} secret${secretCount !== 1 ? 's' : ''})`);
123
+ tui.success(`Pushed ${totalCount} variable${totalCount !== 1 ? 's' : ''} to organization (${diff.newEntries.length} new, ${diff.changedEntries.length} updated, ${diff.unchangedEntries.length} unchanged)`);
88
124
  return {
89
125
  success: true,
90
126
  pushed: totalCount,
91
127
  envCount,
92
128
  secretCount,
129
+ newCount: diff.newEntries.length,
130
+ changedCount: diff.changedEntries.length,
131
+ unchangedCount: diff.unchangedEntries.length,
93
132
  source: envFilePath,
94
133
  scope: 'org',
134
+ force: forceMode,
95
135
  };
96
136
  }
97
137
  else {
98
- // Project scope (existing behavior)
138
+ // Project scope
99
139
  if (!project) {
100
140
  tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
101
141
  }
142
+ // Fetch remote state to compute diff
143
+ const projectData = await tui.spinner('Fetching remote variables', () => {
144
+ return projectGet(apiClient, { id: project.projectId, mask: false });
145
+ });
146
+ const diff = computeEnvDiff(env, secrets, projectData.env || {}, projectData.secrets || {});
147
+ displayEnvDiff(diff, { direction: 'push' });
148
+ // Prompt for confirmation if there are changes to existing variables
149
+ if (diff.changedEntries.length > 0 && !forceMode) {
150
+ const confirmed = await tui.confirm(`${diff.changedEntries.length} existing variable${diff.changedEntries.length !== 1 ? 's' : ''} will be overwritten. Continue?`, true);
151
+ if (!confirmed) {
152
+ tui.info('Push cancelled');
153
+ return {
154
+ success: false,
155
+ pushed: 0,
156
+ envCount: 0,
157
+ secretCount: 0,
158
+ newCount: 0,
159
+ changedCount: 0,
160
+ unchangedCount: 0,
161
+ source: envFilePath,
162
+ scope: 'project',
163
+ force: forceMode,
164
+ };
165
+ }
166
+ }
102
167
  await tui.spinner('Pushing variables to cloud', () => {
103
168
  return projectEnvUpdate(apiClient, {
104
169
  id: project.projectId,
@@ -109,14 +174,18 @@ export const pushSubcommand = createSubcommand({
109
174
  const envCount = Object.keys(env).length;
110
175
  const secretCount = Object.keys(secrets).length;
111
176
  const totalCount = envCount + secretCount;
112
- tui.success(`Pushed ${totalCount} variable${totalCount !== 1 ? 's' : ''} to cloud (${envCount} env, ${secretCount} secret${secretCount !== 1 ? 's' : ''})`);
177
+ tui.success(`Pushed ${totalCount} variable${totalCount !== 1 ? 's' : ''} to cloud (${diff.newEntries.length} new, ${diff.changedEntries.length} updated, ${diff.unchangedEntries.length} unchanged)`);
113
178
  return {
114
179
  success: true,
115
180
  pushed: totalCount,
116
181
  envCount,
117
182
  secretCount,
183
+ newCount: diff.newEntries.length,
184
+ changedCount: diff.changedEntries.length,
185
+ unchangedCount: diff.unchangedEntries.length,
118
186
  source: envFilePath,
119
187
  scope: 'project',
188
+ force: forceMode,
120
189
  };
121
190
  }
122
191
  },