ai-summon 0.0.1

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 (61) hide show
  1. package/.claude/commands/speckit.analyze.md +184 -0
  2. package/.claude/commands/speckit.checklist.md +294 -0
  3. package/.claude/commands/speckit.clarify.md +177 -0
  4. package/.claude/commands/speckit.constitution.md +78 -0
  5. package/.claude/commands/speckit.implement.md +121 -0
  6. package/.claude/commands/speckit.plan.md +81 -0
  7. package/.claude/commands/speckit.specify.md +204 -0
  8. package/.claude/commands/speckit.tasks.md +108 -0
  9. package/.claude/settings.local.json +23 -0
  10. package/.prettierignore +5 -0
  11. package/.prettierrc.json +10 -0
  12. package/.specify/memory/constitution.md +72 -0
  13. package/.specify/scripts/bash/check-prerequisites.sh +166 -0
  14. package/.specify/scripts/bash/common.sh +113 -0
  15. package/.specify/scripts/bash/create-new-feature.sh +97 -0
  16. package/.specify/scripts/bash/setup-plan.sh +60 -0
  17. package/.specify/scripts/bash/update-agent-context.sh +738 -0
  18. package/.specify/templates/agent-file-template.md +28 -0
  19. package/.specify/templates/checklist-template.md +40 -0
  20. package/.specify/templates/plan-template.md +111 -0
  21. package/.specify/templates/spec-template.md +115 -0
  22. package/.specify/templates/tasks-template.md +250 -0
  23. package/CLAUDE.md +199 -0
  24. package/PRD.md +268 -0
  25. package/README.md +171 -0
  26. package/dist/ai-summon.d.ts +2 -0
  27. package/dist/ai-summon.js +73 -0
  28. package/dist/commands/ide/index.d.ts +3 -0
  29. package/dist/commands/ide/index.js +253 -0
  30. package/dist/commands/init.d.ts +4 -0
  31. package/dist/commands/init.js +55 -0
  32. package/dist/commands/url.d.ts +4 -0
  33. package/dist/commands/url.js +223 -0
  34. package/dist/types/index.d.ts +40 -0
  35. package/dist/types/index.js +1 -0
  36. package/dist/util.d.ts +16 -0
  37. package/dist/util.js +109 -0
  38. package/eslint.config.js +47 -0
  39. package/package.json +47 -0
  40. package/specs/001-cloud-login-feature/contracts/cloud-command.ts +82 -0
  41. package/specs/001-cloud-login-feature/contracts/config-service.ts +170 -0
  42. package/specs/001-cloud-login-feature/data-model.md +269 -0
  43. package/specs/001-cloud-login-feature/plan.md +91 -0
  44. package/specs/001-cloud-login-feature/quickstart.md +366 -0
  45. package/specs/001-cloud-login-feature/research.md +290 -0
  46. package/specs/001-cloud-login-feature/spec.md +195 -0
  47. package/specs/001-cloud-login-feature/tasks.md +235 -0
  48. package/specs/001-cloud-scp-command/contracts/cloud-scp-api.ts +402 -0
  49. package/specs/001-cloud-scp-command/data-model.md +424 -0
  50. package/specs/001-cloud-scp-command/plan.md +124 -0
  51. package/specs/001-cloud-scp-command/quickstart.md +536 -0
  52. package/specs/001-cloud-scp-command/research.md +345 -0
  53. package/specs/001-cloud-scp-command/spec.md +248 -0
  54. package/specs/001-cloud-scp-command/tasks.md +434 -0
  55. package/src/ai-summon.ts +88 -0
  56. package/src/commands/ide/index.ts +322 -0
  57. package/src/commands/init.ts +64 -0
  58. package/src/commands/url.ts +262 -0
  59. package/src/types/index.ts +49 -0
  60. package/src/util.ts +146 -0
  61. package/tsconfig.json +21 -0
@@ -0,0 +1,345 @@
1
+ # Research: Cloud SCP Command
2
+
3
+ **Feature**: 001-cloud-scp-command
4
+ **Date**: 2025-10-11
5
+ **Status**: Complete
6
+
7
+ ## Research Overview
8
+
9
+ This document consolidates research findings for implementing the `hsh cloud scp` command. Since this feature extends existing cloud infrastructure functionality, research focuses on SCP best practices, path validation approaches, and integration patterns with the existing codebase.
10
+
11
+ ## Decision 1: SCP Command Pattern
12
+
13
+ ### Decision
14
+
15
+ Use `scp -i {privateKey} scp [flags] {source} {user}@{host}:{dest}` pattern for SCP execution.
16
+
17
+ ### Rationale
18
+
19
+ - **Consistency**: Matches the SSH approach used in `cloud login` command
20
+ - **Key Management**: Ensures proper private key authentication flow
21
+ - **Error Handling**: SSH error patterns can be handled by existing `handleSSHError` function
22
+ - **Platform Compatibility**: Works across all platforms supported by the SSH suite
23
+
24
+ ### Alternatives Considered
25
+
26
+ 1. **Direct SCP command**: `scp -i {privateKey} [flags] {source} {user}@{host}:{dest}`
27
+ - **Rejected**: While simpler, inconsistent with cloud login's SSH-first approach
28
+ - **Concern**: May have different error handling requirements
29
+
30
+ 2. **rsync over SSH**: `rsync -avz -e "scp -i {privateKey}" {source} {user}@{host}:{dest}`
31
+ - **Rejected**: Adds external dependency (rsync)
32
+ - **Overkill**: Feature doesn't require rsync's advanced sync capabilities
33
+ - **Complexity**: More flags and options to manage
34
+
35
+ ### Implementation Details
36
+
37
+ ```typescript
38
+ // For files
39
+ await $`scp -i ${privateKeyFile} scp ${localPath} root@${ip}:${remotePath}`;
40
+
41
+ // For directories (-r flag)
42
+ await $`scp -i ${privateKeyFile} scp -r ${localPath} root@${ip}:${remotePath}`;
43
+ ```
44
+
45
+ ## Decision 2: Path Validation Strategy
46
+
47
+ ### Decision
48
+
49
+ Use Node.js `fs/promises` API with `stat()` for comprehensive path validation before SCP execution.
50
+
51
+ ### Rationale
52
+
53
+ - **Early Failure**: Detect invalid paths before expensive SSH/SCP operations
54
+ - **Type Detection**: `stat()` provides file vs directory information
55
+ - **Permission Checking**: Can detect read permission issues early
56
+ - **Synchronous Path Check**: Validates source exists, preventing ambiguous SCP errors
57
+
58
+ ### Alternatives Considered
59
+
60
+ 1. **No validation, rely on SCP errors**
61
+ - **Rejected**: Poor user experience with cryptic SCP error messages
62
+ - **Delayed feedback**: Only fails after SSH connection established
63
+
64
+ 2. **Simple `access()` check only**
65
+ - **Rejected**: Doesn't provide file vs directory information
66
+ - **Missing context**: Can't auto-detect if `-r` flag is needed
67
+
68
+ ### Implementation Details
69
+
70
+ ```typescript
71
+ import { stat } from 'fs/promises';
72
+
73
+ async function validateLocalPath(path: string): Promise<{ exists: boolean; isDirectory: boolean }> {
74
+ try {
75
+ const stats = await stat(path);
76
+ return { exists: true, isDirectory: stats.isDirectory() };
77
+ } catch (error) {
78
+ if (error.code === 'ENOENT') {
79
+ return { exists: false, isDirectory: false };
80
+ }
81
+ throw error; // Permission or other errors
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Decision 3: Recursive Flag Handling
87
+
88
+ ### Decision
89
+
90
+ Require explicit `-r` flag for directory copies, error if missing.
91
+
92
+ ### Rationale
93
+
94
+ - **SCP Standard**: Follows standard SCP behavior and conventions
95
+ - **Explicit Intent**: Forces user to be explicit about recursive operations
96
+ - **Error Prevention**: Prevents accidental large directory transfers
97
+ - **User Education**: Clear error message teaches correct flag usage
98
+
99
+ ### Alternatives Considered
100
+
101
+ 1. **Auto-detect and add `-r` flag**
102
+ - **Rejected**: Too implicit, hides important flag from user
103
+ - **Learning barrier**: Users won't learn correct SCP usage
104
+
105
+ 2. **Prompt user when directory detected**
106
+ - **Rejected**: Adds friction to CLI workflow
107
+ - **Automation unfriendly**: Breaks non-interactive script usage
108
+
109
+ ### Implementation Details
110
+
111
+ ```typescript
112
+ // Validation logic
113
+ if (pathInfo.isDirectory && !options.recursive) {
114
+ console.error(chalk.red('❌ Cannot copy directory without -r flag'));
115
+ console.log(chalk.yellow('Hint: Use -r flag for recursive directory copy'));
116
+ process.exit(1);
117
+ }
118
+ ```
119
+
120
+ ## Decision 4: Function Reuse Strategy
121
+
122
+ ### Decision
123
+
124
+ Reuse existing cloud.ts helper functions for all shared functionality.
125
+
126
+ ### Functions to Reuse
127
+
128
+ 1. **validatePrivateKey()**: SSH key validation and permission checking
129
+ 2. **promptForService()**: Interactive service selection
130
+ 3. **promptForEnvironment()**: Interactive environment selection
131
+ 4. **handleSSHError()**: SSH/SCP error handling with user-friendly messages
132
+
133
+ ### Rationale
134
+
135
+ - **DRY Principle**: Eliminates code duplication
136
+ - **Consistency**: Same user experience across cloud commands
137
+ - **Maintainability**: Bug fixes benefit all cloud commands
138
+ - **Testing**: Shared functions already tested through cloud login
139
+
140
+ ### New Functions Required
141
+
142
+ 1. **validateLocalPath()**: Path existence and type checking (SCP-specific)
143
+ 2. **cloudScp()**: Main SCP command execution (new subcommand)
144
+
145
+ ### Implementation Pattern
146
+
147
+ ```typescript
148
+ export async function cloudScp(
149
+ localPath: string,
150
+ remotePath: string,
151
+ options: { env?: Environment; service?: string; recursive?: boolean }
152
+ ): Promise<void> {
153
+ // Reuse existing patterns from cloudLogin
154
+ const config = readConfig();
155
+
156
+ // Reuse: Service selection
157
+ const service = options.service || (await promptForService(Object.keys(config.yiren)));
158
+
159
+ // Reuse: Environment selection
160
+ const env = options.env || (await promptForEnvironment(Object.keys(config.yiren[service])));
161
+
162
+ // Reuse: Key validation
163
+ await validatePrivateKey(cloudConfig.privateKeyFile);
164
+
165
+ // New: Path validation
166
+ const pathInfo = await validateLocalPath(localPath);
167
+
168
+ // Reuse: Production confirmation (from cloudLogin pattern)
169
+ if (env === 'prod') {
170
+ // ... confirmation prompt logic
171
+ }
172
+
173
+ // New: SCP execution
174
+ await $`scp -i ${cloudConfig.privateKeyFile} scp ${flags} ${localPath} root@${cloudConfig.ip}:${remotePath}`;
175
+ }
176
+ ```
177
+
178
+ ## Decision 5: Production Safety Confirmation
179
+
180
+ ### Decision
181
+
182
+ Implement same production confirmation prompt as `cloud login`.
183
+
184
+ ### Rationale
185
+
186
+ - **Consistency**: Matches user expectations from cloud login
187
+ - **Safety**: Prevents accidental production file overwrites
188
+ - **Explicit Consent**: Requires active confirmation for prod operations
189
+ - **Audit Trail**: User explicitly acknowledges production access
190
+
191
+ ### Implementation Details
192
+
193
+ ```typescript
194
+ if (env === 'prod') {
195
+ const { confirmProduction } = await inquirer.prompt([
196
+ {
197
+ type: 'confirm',
198
+ name: 'confirmProduction',
199
+ message: chalk.red(`⚠️ You are about to copy files to PRODUCTION (${service}). Continue?`),
200
+ default: false,
201
+ },
202
+ ]);
203
+
204
+ if (!confirmProduction) {
205
+ console.log(chalk.yellow('⏸️ Production operation cancelled.'));
206
+ return;
207
+ }
208
+ }
209
+ ```
210
+
211
+ ## Decision 6: Error Handling Strategy
212
+
213
+ ### Decision
214
+
215
+ Layer error handling with specific messages for each failure point.
216
+
217
+ ### Error Categories
218
+
219
+ 1. **Path Errors**: Local file/directory not found, permission denied
220
+ 2. **Configuration Errors**: Service/environment not configured
221
+ 3. **Validation Errors**: Missing -r flag for directories
222
+ 4. **SSH/SCP Errors**: Connection failures, authentication failures
223
+
224
+ ### Error Handling Flow
225
+
226
+ ```typescript
227
+ try {
228
+ // Layer 1: Path validation
229
+ const pathInfo = await validateLocalPath(localPath);
230
+ if (!pathInfo.exists) {
231
+ console.error(chalk.red(`❌ Local path not found: ${localPath}`));
232
+ return;
233
+ }
234
+
235
+ // Layer 2: Recursive flag validation
236
+ if (pathInfo.isDirectory && !options.recursive) {
237
+ console.error(chalk.red('❌ Cannot copy directory without -r flag'));
238
+ console.log(chalk.yellow('Hint: Use -r flag for recursive directory copy'));
239
+ return;
240
+ }
241
+
242
+ // Layer 3: Configuration validation (reuse existing logic)
243
+ // ...
244
+
245
+ // Layer 4: SCP execution
246
+ await $`scp -i ${privateKey} scp ${flags} ${localPath} root@${ip}:${remotePath}`;
247
+ console.log(chalk.green(`✅ Successfully copied to ${service} (${env}): ${remotePath}`));
248
+ } catch (error) {
249
+ // Reuse handleSSHError for SSH/SCP connection errors
250
+ handleSSHError(error);
251
+ process.exit(1);
252
+ }
253
+ ```
254
+
255
+ ### Rationale
256
+
257
+ - **Clear Feedback**: Each error type has specific, actionable message
258
+ - **Early Failure**: Validation errors caught before SCP execution
259
+ - **Reuse Existing**: SSH errors handled by existing handleSSHError function
260
+ - **User Experience**: Helpful hints guide users to correct usage
261
+
262
+ ## Technology Best Practices
263
+
264
+ ### TypeScript Best Practices
265
+
266
+ - **Strict Mode**: All code follows strict TypeScript typing
267
+ - **Interface Reuse**: Use existing `CloudConfig`, `Environment` types
268
+ - **Async/Await**: All file system and shell operations use async/await
269
+ - **Error Types**: Properly type catch blocks and error handling
270
+
271
+ ### zx Library Usage
272
+
273
+ - **Template Literals**: Use `$` template literals for all shell commands
274
+ - **Variable Escaping**: zx automatically handles path escaping
275
+ - **Error Propagation**: zx throws on non-zero exit codes by default
276
+ - **Process Handling**: Proper async/await with shell operations
277
+
278
+ ### Commander.js Patterns
279
+
280
+ - **Option Definition**: Use `.option()` for flags with proper descriptions
281
+ - **Argument Definition**: Use `.argument()` for positional parameters
282
+ - **Action Handler**: Async action handlers for all commands
283
+ - **Delegation Pattern**: Main file defines interface, delegates to domain modules
284
+
285
+ ## Integration Patterns
286
+
287
+ ### Configuration Access
288
+
289
+ - Reuse `readConfig()` from util.ts
290
+ - Access `config.yiren` structure (established by cloud login)
291
+ - Validate service and environment existence before use
292
+
293
+ ### Interactive Prompts
294
+
295
+ - Reuse `promptForService()` and `promptForEnvironment()`
296
+ - Maintain consistent prompt styling with inquirer
297
+ - Provide helpful validation messages
298
+
299
+ ### Command Registration
300
+
301
+ ```typescript
302
+ // In hsh.ts - following existing cloud command pattern
303
+ cloudCommand
304
+ .command('scp')
305
+ .description('Copy files to cloud instances')
306
+ .option('-r, --recursive', 'Copy directories recursively')
307
+ .option('--env <environment>', 'Environment: dev, staging, or prod')
308
+ .option('--service <service>', 'Service name')
309
+ .argument('<local-path>', 'Local file or directory path')
310
+ .argument('<remote-path>', 'Remote destination path')
311
+ .action(async (localPath, remotePath, options) => {
312
+ await cloudScp(localPath, remotePath, options);
313
+ });
314
+ ```
315
+
316
+ ## Open Questions & Resolutions
317
+
318
+ ### Q1: Should we support SCP options like -P (port)?
319
+
320
+ **Resolution**: No, not in initial implementation. Current cloud config doesn't include custom SSH ports. Can add later if needed.
321
+
322
+ ### Q2: Should we validate remote path format?
323
+
324
+ **Resolution**: No, let SCP/SSH handle remote path validation. Remote filesystem structure varies, hard to validate without SSH connection.
325
+
326
+ ### Q3: Should we support bidirectional SCP (download from remote)?
327
+
328
+ **Resolution**: No, out of scope for this feature. Current requirement is upload only. Can be separate command later (e.g., `hsh cloud download`).
329
+
330
+ ### Q4: Should we show progress for large file transfers?
331
+
332
+ **Resolution**: Not in initial version. SCP provides basic progress output by default. Enhanced progress indication can be added in future iteration if needed.
333
+
334
+ ## Summary
335
+
336
+ This research establishes a clear implementation path for the `hsh cloud scp` command:
337
+
338
+ 1. **SCP via SSH wrapper** for consistency with cloud login
339
+ 2. **Node.js fs/promises** for path validation and type detection
340
+ 3. **Explicit -r flag** requirement following SCP standards
341
+ 4. **Maximum function reuse** from existing cloud.ts helpers
342
+ 5. **Production safety** with confirmation prompts
343
+ 6. **Layered error handling** with specific, actionable messages
344
+
345
+ All decisions align with the project's constitution (TypeScript-first, zx for shell, inquirer for prompts, modular architecture) and reuse existing patterns from the cloud login implementation.
@@ -0,0 +1,248 @@
1
+ # Feature Specification: Cloud SCP Command
2
+
3
+ **Feature ID**: 001-cloud-scp-command
4
+ **Created**: 2025-10-11
5
+ **Type**: CLI Enhancement
6
+ **Depends On**: 001-cloud-login-feature (cloud configuration structure)
7
+
8
+ ## Overview
9
+
10
+ Add a new `hsh cloud scp` command that enables users to securely copy files and directories to cloud instances using SCP. The command extends the existing cloud infrastructure management functionality by leveraging the same environment and service configuration used by `hsh cloud login`.
11
+
12
+ ## Functional Requirements
13
+
14
+ ### FR-1: Cloud SCP Command Structure
15
+
16
+ - **Main Command**: `hsh cloud` - Cloud infrastructure management (existing)
17
+ - **New Subcommand**: `hsh cloud scp [options] <local-path> <remote-path>`
18
+ - **Options**:
19
+ - `-r, --recursive`: Copy directories recursively (required for folders)
20
+ - `--env <environment>`: Environment selection (dev/staging/prod)
21
+ - `--service <service-name>`: Service name (todo-mini, wuhan-mall, etc.)
22
+ - **Parameters**:
23
+ - `<local-path>`: Local file or directory path to copy
24
+ - `<remote-path>`: Remote destination path on the target server
25
+ - **Behavior**: Execute SCP command to copy local files/directories to remote server
26
+
27
+ ### FR-2: Interactive Prompts
28
+
29
+ When `--env` or `--service` options are not provided, the command should:
30
+
31
+ - **Service Selection**: Prompt user to select from available services in configuration
32
+ - **Environment Selection**: Prompt user to select from available environments for the chosen service
33
+ - **Reuse Existing Patterns**: Use the same prompt functions from cloud login (`promptForService`, `promptForEnvironment`)
34
+
35
+ ### FR-3: Configuration Reuse
36
+
37
+ - **Configuration File**: `~/.ai/config.json` (same as cloud login)
38
+ - **Configuration Structure**: Uses existing `yiren` section from cloud login feature
39
+ ```json
40
+ {
41
+ "yiren": {
42
+ "[service-name]": {
43
+ "dev": {
44
+ "ip": "IP",
45
+ "privateKeyFile": "path/to/private-key-file"
46
+ },
47
+ "staging": { ... },
48
+ "prod": { ... }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### FR-4: SCP Command Execution
55
+
56
+ The command should construct and execute different SCP commands based on the input type:
57
+
58
+ **For Files**:
59
+
60
+ ```bash
61
+ scp -i /path/to/privateKey scp local-file-path root@IP:remote-folder-path
62
+ ```
63
+
64
+ **For Directories** (with `-r` flag):
65
+
66
+ ```bash
67
+ scp -i /path/to/privateKey scp -r local-folder-path root@IP:remote-folder-path
68
+ ```
69
+
70
+ **Command Resolution**:
71
+
72
+ - Private key: `config.yiren[service][env].privateKeyFile`
73
+ - IP address: `config.yiren[service][env].ip`
74
+ - User: Always `root` (consistent with cloud login)
75
+
76
+ ### FR-5: Path Validation
77
+
78
+ - **Local Path**: Validate that local path exists before attempting copy
79
+ - **Directory Detection**: Automatically detect if local path is a directory
80
+ - **Recursive Flag**: Require `-r` flag for directory copies
81
+ - **Error Messages**: Clear feedback for missing paths or incorrect flag usage
82
+
83
+ ## Technical Requirements
84
+
85
+ ### TR-1: Command Integration
86
+
87
+ - Add `scp` subcommand to existing `cloud` command group in `hsh.ts`
88
+ - Implement `cloudScp` function in `src/commands/cloud.ts`
89
+ - Follow Commander.js patterns for option and argument parsing
90
+ - Reuse existing cloud helper functions for configuration and validation
91
+
92
+ ### TR-2: File System Operations
93
+
94
+ - Use Node.js `fs/promises` API for path validation
95
+ - Detect file vs directory using `stat` or `lstat`
96
+ - Validate local path exists before SCP execution
97
+ - Provide clear error messages for invalid paths
98
+
99
+ ### TR-3: SCP Execution
100
+
101
+ - Use zx library for shell command execution (following constitution)
102
+ - Construct SCP command with proper flag handling (`-r` for directories)
103
+ - Include SSH options for key authentication and connection settings
104
+ - Handle SCP-specific errors and exit codes
105
+
106
+ ### TR-4: Error Handling
107
+
108
+ - **Path Errors**: Local path not found, permission issues
109
+ - **Configuration Errors**: Missing service/environment configuration
110
+ - **SCP Errors**: Connection failures, permission denied, file transfer issues
111
+ - **Flag Errors**: Missing `-r` flag for directory copy
112
+ - Reuse `handleSSHError` function for connection-related errors
113
+
114
+ ### TR-5: Production Safety
115
+
116
+ - Implement same production confirmation prompt as cloud login
117
+ - Warn users before copying to production environments
118
+ - Require explicit confirmation for production operations
119
+
120
+ ## User Stories
121
+
122
+ ### US-1: Quick File Deploy
123
+
124
+ **As a** developer
125
+ **I want to** quickly copy a local file to a remote server
126
+ **So that** I can deploy configuration changes without manual SCP commands
127
+
128
+ **Acceptance Criteria**:
129
+
130
+ - Command accepts local file path and remote destination
131
+ - Automatically detects it's a file and uses appropriate SCP command
132
+ - Prompts for service and environment if not provided
133
+ - Successfully copies file to remote server
134
+
135
+ **Example**:
136
+
137
+ ```bash
138
+ hsh cloud scp ./config.json /etc/myapp/config.json
139
+ # Prompts for service and environment, then copies file
140
+ ```
141
+
142
+ ### US-2: Directory Upload
143
+
144
+ **As a** developer
145
+ **I want to** upload an entire directory to a remote server
146
+ **So that** I can deploy multiple files in one command
147
+
148
+ **Acceptance Criteria**:
149
+
150
+ - Command requires `-r` flag for directory copy
151
+ - Recursively copies entire directory structure
152
+ - Provides clear error if `-r` flag is missing for directories
153
+
154
+ **Example**:
155
+
156
+ ```bash
157
+ hsh cloud scp -r ./dist /var/www/html --env prod --service wuhan-mall
158
+ ```
159
+
160
+ ### US-3: Interactive Service Selection
161
+
162
+ **As a** developer managing multiple services
163
+ **I want to** be prompted for service and environment if not specified
164
+ **So that** I can quickly select without remembering exact names
165
+
166
+ **Acceptance Criteria**:
167
+
168
+ - Displays available services when `--service` is omitted
169
+ - Displays available environments when `--env` is omitted
170
+ - Uses same interactive prompts as cloud login command
171
+
172
+ **Example**:
173
+
174
+ ```bash
175
+ hsh cloud scp ./app.js /opt/app/
176
+ # Interactive prompts guide service and environment selection
177
+ ```
178
+
179
+ ## Usage Examples
180
+
181
+ ### Basic File Copy
182
+
183
+ ```bash
184
+ hsh cloud scp ./config.json /etc/app/config.json --env dev --service todo-mini
185
+ ```
186
+
187
+ ### Directory Copy with Recursive Flag
188
+
189
+ ```bash
190
+ hsh cloud scp -r ./build /var/www/html --env staging --service wuhan-mall
191
+ ```
192
+
193
+ ### Interactive Mode (No Flags)
194
+
195
+ ```bash
196
+ hsh cloud scp ./deploy.sh /root/scripts/
197
+ # Prompts: Select service → Select environment → Executes SCP
198
+ ```
199
+
200
+ ### Production Copy with Confirmation
201
+
202
+ ```bash
203
+ hsh cloud scp -r ./dist /var/www/html --env prod --service todo-mini
204
+ # Shows production warning → Requires confirmation → Executes SCP
205
+ ```
206
+
207
+ ## Dependencies
208
+
209
+ - **Existing**: commander, zx, chalk, inquirer, fs/promises (already in project)
210
+ - **New**: None required
211
+ - **External**: SCP command (system dependency, part of SSH suite)
212
+ - **Internal**: Reuses cloud.ts helper functions and configuration structure
213
+
214
+ ## Success Criteria
215
+
216
+ 1. Command successfully copies files to specified environment and service
217
+ 2. Automatic detection of file vs directory with appropriate flag validation
218
+ 3. Interactive prompts work consistently with cloud login command
219
+ 4. Production confirmation prevents accidental deployments
220
+ 5. Clear error messages for all failure scenarios
221
+ 6. Follows project's TypeScript and CLI design principles
222
+ 7. Code reuses existing cloud infrastructure patterns
223
+
224
+ ## Non-Functional Requirements
225
+
226
+ - **Security**: SSH keys properly managed, not exposed in logs or error messages
227
+ - **Performance**: Command executes within 2 seconds (excluding actual file transfer time)
228
+ - **Usability**: Clear error messages, helpful validation, intuitive flag usage
229
+ - **Maintainability**: Code follows existing patterns, reuses helper functions, minimal duplication
230
+ - **Compatibility**: Works with existing cloud configuration without modifications
231
+
232
+ ## Design Decisions
233
+
234
+ ### Reuse Over Duplication
235
+
236
+ - Reuse `validatePrivateKey`, `promptForService`, `promptForEnvironment` from cloud login
237
+ - Reuse `handleSSHError` for consistent error handling
238
+ - Reuse configuration reading and validation patterns
239
+
240
+ ### SCP via SSH Wrapper
241
+
242
+ The command pattern `scp -i {key} scp ...` is used instead of direct `scp -i {key} ...` for consistency with cloud login's SSH approach and to ensure proper key authentication flow.
243
+
244
+ ### Flag Consistency
245
+
246
+ - `-r` flag follows standard SCP convention for recursive copy
247
+ - `--env` and `--service` flags match cloud login for consistency
248
+ - Position of local and remote paths follows standard SCP argument order