Skip to content

Commit aa2cc1b

Browse files
authored
feat: remove plan command, add --plan flag and ResourceGraph toggle to deploy (#74)
* fix: remove plan command, add --plan flag to deploy * feat: add toggleable ResourceGraph view to deploy (Ctrl+G) * make ctrl+r description better
1 parent c7ac704 commit aa2cc1b

File tree

20 files changed

+97
-744
lines changed

20 files changed

+97
-744
lines changed

integ-tests/help.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const COMMANDS = [
77
'dev',
88
'invoke',
99
'destroy',
10-
'plan',
1110
'status',
1211
'validate',
1312
'add',

src/cli/cli.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { registerEdit } from './commands/edit';
88
import { registerInvoke } from './commands/invoke';
99
import { registerOutline } from './commands/outline';
1010
import { registerPackage } from './commands/package';
11-
import { registerPlan } from './commands/plan';
1211
import { registerRemove } from './commands/remove';
1312
import { registerStatus } from './commands/status';
1413
import { registerStopSession } from './commands/stop-session';
@@ -112,7 +111,6 @@ export function registerCommands(program: Command) {
112111
registerInvoke(program);
113112
registerOutline(program);
114113
registerPackage(program);
115-
registerPlan(program);
116114
registerRemove(program);
117115
registerStatus(program);
118116
registerStopSession(program);

src/cli/commands/deploy/actions.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface ValidatedDeployOptions {
1919
target: string;
2020
autoConfirm?: boolean;
2121
verbose?: boolean;
22+
plan?: boolean;
2223
onProgress?: (step: string, status: 'start' | 'success' | 'error') => void;
2324
onResourceEvent?: (message: string) => void;
2425
}
@@ -125,6 +126,19 @@ export async function handleDeploy(options: ValidatedDeployOptions): Promise<Dep
125126
}
126127
endStep('success');
127128

129+
// Plan mode: stop after synth and checks, don't deploy
130+
if (options.plan) {
131+
logger.finalize(true);
132+
await toolkitWrapper.dispose();
133+
toolkitWrapper = null;
134+
return {
135+
success: true,
136+
targetName: target.name,
137+
stackName,
138+
logPath: logger.getRelativeLogPath(),
139+
};
140+
}
141+
128142
// Set up identity providers if needed
129143
let identityKmsKeyArn: string | undefined;
130144
if (hasOwnedIdentityApiProviders(context.projectSpec)) {

src/cli/commands/deploy/command.tsx

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ async function handleDeployCLI(options: DeployOptions): Promise<void> {
7272
target: options.target!,
7373
autoConfirm: options.yes,
7474
verbose: options.verbose,
75+
plan: options.plan,
7576
onProgress,
7677
onResourceEvent,
7778
});
@@ -84,22 +85,28 @@ async function handleDeployCLI(options: DeployOptions): Promise<void> {
8485
if (options.json) {
8586
console.log(JSON.stringify(result));
8687
} else if (result.success) {
87-
console.log(`\n✓ Deployed to '${result.targetName}' (stack: ${result.stackName})`);
88+
if (options.plan) {
89+
console.log(`\n✓ Plan complete for '${result.targetName}' (stack: ${result.stackName})`);
90+
console.log('\nRun `agentcore deploy` to deploy.');
91+
} else {
92+
console.log(`\n✓ Deployed to '${result.targetName}' (stack: ${result.stackName})`);
93+
94+
// Show stack outputs in non-JSON mode
95+
if (result.outputs && Object.keys(result.outputs).length > 0) {
96+
console.log('\nOutputs:');
97+
for (const [key, value] of Object.entries(result.outputs)) {
98+
console.log(` ${key}: ${value}`);
99+
}
100+
}
88101

89-
// Show stack outputs in non-JSON mode
90-
if (result.outputs && Object.keys(result.outputs).length > 0) {
91-
console.log('\nOutputs:');
92-
for (const [key, value] of Object.entries(result.outputs)) {
93-
console.log(` ${key}: ${value}`);
102+
if (result.nextSteps && result.nextSteps.length > 0) {
103+
console.log(`Next: ${result.nextSteps.join(' | ')}`);
94104
}
95105
}
96106

97107
if (result.logPath) {
98108
console.log(`\nLog: ${result.logPath}`);
99109
}
100-
if (result.nextSteps && result.nextSteps.length > 0) {
101-
console.log(`Next: ${result.nextSteps.join(' | ')}`);
102-
}
103110
} else {
104111
console.error(result.error);
105112
if (result.logPath) {
@@ -120,23 +127,26 @@ export const registerDeploy = (program: Command) => {
120127
.option('--progress', 'Show deployment progress in real-time')
121128
.option('-v, --verbose', 'Show resource-level deployment events')
122129
.option('--json', 'Output as JSON')
123-
.action(async (cliOptions: { target?: string; yes?: boolean; progress?: boolean; json?: boolean }) => {
124-
try {
125-
requireProject();
126-
if (cliOptions.json || cliOptions.target || cliOptions.progress) {
127-
// Default to "default" target in CLI mode
128-
const options = { ...cliOptions, target: cliOptions.target ?? 'default' };
129-
await handleDeployCLI(options as DeployOptions);
130-
} else {
131-
handleDeployTUI({ autoConfirm: cliOptions.yes });
132-
}
133-
} catch (error) {
134-
if (cliOptions.json) {
135-
console.log(JSON.stringify({ success: false, error: getErrorMessage(error) }));
136-
} else {
137-
render(<Text color="red">Error: {getErrorMessage(error)}</Text>);
130+
.option('--plan', 'Preview deployment without deploying (dry-run)')
131+
.action(
132+
async (cliOptions: { target?: string; yes?: boolean; progress?: boolean; json?: boolean; plan?: boolean }) => {
133+
try {
134+
requireProject();
135+
if (cliOptions.json || cliOptions.target || cliOptions.progress || cliOptions.plan) {
136+
// Default to "default" target in CLI mode
137+
const options = { ...cliOptions, target: cliOptions.target ?? 'default' };
138+
await handleDeployCLI(options as DeployOptions);
139+
} else {
140+
handleDeployTUI({ autoConfirm: cliOptions.yes });
141+
}
142+
} catch (error) {
143+
if (cliOptions.json) {
144+
console.log(JSON.stringify({ success: false, error: getErrorMessage(error) }));
145+
} else {
146+
render(<Text color="red">Error: {getErrorMessage(error)}</Text>);
147+
}
148+
process.exit(1);
138149
}
139-
process.exit(1);
140150
}
141-
});
151+
);
142152
};

src/cli/commands/deploy/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export interface DeployOptions {
44
progress?: boolean;
55
verbose?: boolean;
66
json?: boolean;
7+
plan?: boolean;
78
}
89

910
export interface DeployResult {

src/cli/commands/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export { registerCreate } from './create';
88
export { registerInvoke } from './invoke';
99
export { registerOutline } from './outline';
1010
export { registerPackage } from './package';
11-
export { registerPlan } from './plan';
1211
export { registerRemove } from './remove';
1312
export { registerStatus } from './status';
1413
export { registerStopSession } from './stop-session';

src/cli/commands/plan/__tests__/plan.test.ts

Lines changed: 0 additions & 120 deletions
This file was deleted.

src/cli/commands/plan/actions.ts

Lines changed: 0 additions & 111 deletions
This file was deleted.

0 commit comments

Comments
 (0)