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.
- package/.claude/commands/speckit.analyze.md +184 -0
- package/.claude/commands/speckit.checklist.md +294 -0
- package/.claude/commands/speckit.clarify.md +177 -0
- package/.claude/commands/speckit.constitution.md +78 -0
- package/.claude/commands/speckit.implement.md +121 -0
- package/.claude/commands/speckit.plan.md +81 -0
- package/.claude/commands/speckit.specify.md +204 -0
- package/.claude/commands/speckit.tasks.md +108 -0
- package/.claude/settings.local.json +23 -0
- package/.prettierignore +5 -0
- package/.prettierrc.json +10 -0
- package/.specify/memory/constitution.md +72 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +113 -0
- package/.specify/scripts/bash/create-new-feature.sh +97 -0
- package/.specify/scripts/bash/setup-plan.sh +60 -0
- package/.specify/scripts/bash/update-agent-context.sh +738 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/plan-template.md +111 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +250 -0
- package/CLAUDE.md +199 -0
- package/PRD.md +268 -0
- package/README.md +171 -0
- package/dist/ai-summon.d.ts +2 -0
- package/dist/ai-summon.js +73 -0
- package/dist/commands/ide/index.d.ts +3 -0
- package/dist/commands/ide/index.js +253 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +55 -0
- package/dist/commands/url.d.ts +4 -0
- package/dist/commands/url.js +223 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.js +1 -0
- package/dist/util.d.ts +16 -0
- package/dist/util.js +109 -0
- package/eslint.config.js +47 -0
- package/package.json +47 -0
- package/specs/001-cloud-login-feature/contracts/cloud-command.ts +82 -0
- package/specs/001-cloud-login-feature/contracts/config-service.ts +170 -0
- package/specs/001-cloud-login-feature/data-model.md +269 -0
- package/specs/001-cloud-login-feature/plan.md +91 -0
- package/specs/001-cloud-login-feature/quickstart.md +366 -0
- package/specs/001-cloud-login-feature/research.md +290 -0
- package/specs/001-cloud-login-feature/spec.md +195 -0
- package/specs/001-cloud-login-feature/tasks.md +235 -0
- package/specs/001-cloud-scp-command/contracts/cloud-scp-api.ts +402 -0
- package/specs/001-cloud-scp-command/data-model.md +424 -0
- package/specs/001-cloud-scp-command/plan.md +124 -0
- package/specs/001-cloud-scp-command/quickstart.md +536 -0
- package/specs/001-cloud-scp-command/research.md +345 -0
- package/specs/001-cloud-scp-command/spec.md +248 -0
- package/specs/001-cloud-scp-command/tasks.md +434 -0
- package/src/ai-summon.ts +88 -0
- package/src/commands/ide/index.ts +322 -0
- package/src/commands/init.ts +64 -0
- package/src/commands/url.ts +262 -0
- package/src/types/index.ts +49 -0
- package/src/util.ts +146 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
# Quickstart: Cloud SCP Command
|
|
2
|
+
|
|
3
|
+
**Feature**: 001-cloud-scp-command
|
|
4
|
+
**Date**: 2025-10-11
|
|
5
|
+
**Audience**: Developers implementing or using the `hsh cloud scp` command
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This quickstart guide provides step-by-step instructions for implementing and using the `hsh cloud scp` command. The command enables secure file and directory copying to cloud instances using the same configuration as `hsh cloud login`.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
### For Implementation
|
|
16
|
+
|
|
17
|
+
- Node.js 16+ installed
|
|
18
|
+
- TypeScript 5.0+ compiler
|
|
19
|
+
- Yarn package manager
|
|
20
|
+
- Familiarity with Commander.js, zx, and inquirer libraries
|
|
21
|
+
- Access to the hsh project repository
|
|
22
|
+
|
|
23
|
+
### For Usage
|
|
24
|
+
|
|
25
|
+
- `hsh` CLI tool installed globally (`yarn build:install`)
|
|
26
|
+
- Cloud configuration set up in `~/.ai/config.json`
|
|
27
|
+
- SSH private key files with proper permissions (600)
|
|
28
|
+
- SSH client installed (part of standard OS installation)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Configuration Setup
|
|
33
|
+
|
|
34
|
+
### Step 1: Configure Cloud Services
|
|
35
|
+
|
|
36
|
+
Create or update `~/.ai/config.json` with your cloud services:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"yiren": {
|
|
41
|
+
"my-service": {
|
|
42
|
+
"dev": {
|
|
43
|
+
"ip": "192.168.1.10",
|
|
44
|
+
"privateKeyFile": "/path/to/dev-key.pem"
|
|
45
|
+
},
|
|
46
|
+
"staging": {
|
|
47
|
+
"ip": "192.168.1.20",
|
|
48
|
+
"privateKeyFile": "/path/to/staging-key.pem"
|
|
49
|
+
},
|
|
50
|
+
"prod": {
|
|
51
|
+
"ip": "192.168.1.30",
|
|
52
|
+
"privateKeyFile": "/path/to/prod-key.pem"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Note**: This configuration is shared with `hsh cloud login`. No additional setup needed if cloud login already configured.
|
|
60
|
+
|
|
61
|
+
### Step 2: Verify Private Key Permissions
|
|
62
|
+
|
|
63
|
+
Ensure your SSH private key files have correct permissions:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
chmod 600 /path/to/dev-key.pem
|
|
67
|
+
chmod 600 /path/to/staging-key.pem
|
|
68
|
+
chmod 600 /path/to/prod-key.pem
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The command will warn you if permissions are incorrect but will still attempt the connection.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Basic Usage
|
|
76
|
+
|
|
77
|
+
### Copy a Single File
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# With explicit service and environment
|
|
81
|
+
hsh cloud scp ./config.json /etc/app/config.json --env dev --service my-service
|
|
82
|
+
|
|
83
|
+
# Interactive mode (prompts for service and environment)
|
|
84
|
+
hsh cloud scp ./config.json /etc/app/config.json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Expected Output**:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
π Connecting to my-service (dev): 192.168.1.10
|
|
91
|
+
β
Successfully copied to my-service (dev): /etc/app/config.json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Copy a Directory
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Directory copy REQUIRES -r flag
|
|
98
|
+
hsh cloud scp -r ./dist /var/www/html --env staging --service my-service
|
|
99
|
+
|
|
100
|
+
# Interactive mode with recursive flag
|
|
101
|
+
hsh cloud scp -r ./build /opt/app/
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Expected Output**:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
π Connecting to my-service (staging): 192.168.1.20
|
|
108
|
+
β
Successfully copied to my-service (staging): /var/www/html
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Production Deployment (with Safety Confirmation)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
hsh cloud scp -r ./dist /var/www/html --env prod --service my-service
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Expected Prompt**:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
? β οΈ You are about to copy files to PRODUCTION (my-service). Continue? (y/N)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**If confirmed (y)**:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
π Connecting to my-service (prod): 192.168.1.30
|
|
127
|
+
β
Successfully copied to my-service (prod): /var/www/html
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**If cancelled (N)**:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
βΈοΈ Production operation cancelled.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Common Use Cases
|
|
139
|
+
|
|
140
|
+
### 1. Deploy Configuration File
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Update application config on staging
|
|
144
|
+
hsh cloud scp ./app.config.json /etc/myapp/config.json --env staging --service myapp
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 2. Deploy Built Application
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Deploy production build to web server
|
|
151
|
+
hsh cloud scp -r ./dist /var/www/html --env prod --service myapp
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 3. Upload Deployment Scripts
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Copy deployment script to server
|
|
158
|
+
hsh cloud scp ./scripts/deploy.sh /root/scripts/deploy.sh --env dev --service myapp
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 4. Batch File Upload
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Upload multiple config files
|
|
165
|
+
hsh cloud scp ./configs/nginx.conf /etc/nginx/sites-available/myapp --env dev --service myapp
|
|
166
|
+
hsh cloud scp ./configs/systemd.service /etc/systemd/system/myapp.service --env dev --service myapp
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 5. Interactive Workflow (No Flags)
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Let the CLI guide you through service and environment selection
|
|
173
|
+
hsh cloud scp -r ./dist /var/www/html
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Interactive Prompts**:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
? Select service: (Use arrow keys)
|
|
180
|
+
β― todo-mini
|
|
181
|
+
wuhan-mall
|
|
182
|
+
my-service
|
|
183
|
+
|
|
184
|
+
? Select environment: (Use arrow keys)
|
|
185
|
+
β― dev
|
|
186
|
+
staging
|
|
187
|
+
prod
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Error Handling
|
|
193
|
+
|
|
194
|
+
### Error: Local Path Not Found
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
hsh cloud scp ./nonexistent.txt /tmp/
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Output**:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
β Local path not found: ./nonexistent.txt
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Solution**: Verify the local path exists and is typed correctly.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### Error: Directory Without -r Flag
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
hsh cloud scp ./dist /var/www/html --env dev --service myapp
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Output**:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
β Cannot copy directory without -r flag
|
|
220
|
+
Hint: Use -r flag for recursive directory copy
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Solution**: Add `-r` flag for directory copies:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
hsh cloud scp -r ./dist /var/www/html --env dev --service myapp
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### Error: Service Not Configured
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
hsh cloud scp ./file.txt /tmp/ --service unknown-service
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Output**:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
β Service 'unknown-service' not found in configuration
|
|
241
|
+
Available services: my-service, todo-mini, wuhan-mall
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Solution**: Use one of the available services or add the service to `~/.ai/config.json`.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Error: Environment Not Configured
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
hsh cloud scp ./file.txt /tmp/ --env dev --service my-service
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Output**:
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
β Environment 'dev' not configured for service 'my-service'
|
|
258
|
+
Available environments for my-service: staging, prod
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Solution**: Add the missing environment to `~/.ai/config.json` or use an available environment.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Error: Connection Timeout
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
hsh cloud scp ./file.txt /tmp/ --env dev --service myapp
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Output**:
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
π Connecting to myapp (dev): 192.168.1.10
|
|
275
|
+
β Connection timeout - check network connectivity and IP address
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Solution**:
|
|
279
|
+
|
|
280
|
+
- Verify the IP address in configuration is correct
|
|
281
|
+
- Check network connectivity to the server
|
|
282
|
+
- Ensure the server is running and accessible
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### Error: Authentication Failed
|
|
287
|
+
|
|
288
|
+
**Output**:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
β Authentication failed - check private key file permissions and path
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Solution**:
|
|
295
|
+
|
|
296
|
+
- Verify private key file path in configuration
|
|
297
|
+
- Check private key file permissions: `chmod 600 /path/to/key.pem`
|
|
298
|
+
- Ensure the key matches the server's authorized_keys
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Implementation Guide
|
|
303
|
+
|
|
304
|
+
### Step 1: Add Types to types/index.ts
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// Add SCP-specific types
|
|
308
|
+
export interface ScpOptions {
|
|
309
|
+
env?: Environment;
|
|
310
|
+
service?: string;
|
|
311
|
+
recursive?: boolean;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export interface PathValidationResult {
|
|
315
|
+
exists: boolean;
|
|
316
|
+
isDirectory: boolean;
|
|
317
|
+
isFile: boolean;
|
|
318
|
+
path: string;
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Step 2: Implement cloudScp Function in src/commands/cloud.ts
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { stat } from 'fs/promises';
|
|
326
|
+
|
|
327
|
+
// Path validation helper
|
|
328
|
+
async function validateLocalPath(path: string): Promise<PathValidationResult> {
|
|
329
|
+
try {
|
|
330
|
+
const stats = await stat(path);
|
|
331
|
+
return {
|
|
332
|
+
exists: true,
|
|
333
|
+
isDirectory: stats.isDirectory(),
|
|
334
|
+
isFile: stats.isFile(),
|
|
335
|
+
path: path,
|
|
336
|
+
};
|
|
337
|
+
} catch (error: any) {
|
|
338
|
+
if (error.code === 'ENOENT') {
|
|
339
|
+
return {
|
|
340
|
+
exists: false,
|
|
341
|
+
isDirectory: false,
|
|
342
|
+
isFile: false,
|
|
343
|
+
path: path,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Main SCP function
|
|
351
|
+
export async function cloudScp(
|
|
352
|
+
localPath: string,
|
|
353
|
+
remotePath: string,
|
|
354
|
+
options: ScpOptions
|
|
355
|
+
): Promise<void> {
|
|
356
|
+
try {
|
|
357
|
+
// 1. Validate local path
|
|
358
|
+
const pathInfo = await validateLocalPath(localPath);
|
|
359
|
+
|
|
360
|
+
if (!pathInfo.exists) {
|
|
361
|
+
console.error(chalk.red(`β Local path not found: ${localPath}`));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// 2. Check recursive flag for directories
|
|
366
|
+
if (pathInfo.isDirectory && !options.recursive) {
|
|
367
|
+
console.error(chalk.red('β Cannot copy directory without -r flag'));
|
|
368
|
+
console.log(chalk.yellow('Hint: Use -r flag for recursive directory copy'));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// 3. Read configuration
|
|
373
|
+
const config = readConfig();
|
|
374
|
+
|
|
375
|
+
// 4. Service selection (interactive if not provided)
|
|
376
|
+
const service = options.service || (await promptForService(Object.keys(config.yiren)));
|
|
377
|
+
|
|
378
|
+
// 5. Environment selection (interactive if not provided)
|
|
379
|
+
const serviceConfig = config.yiren[service];
|
|
380
|
+
const env =
|
|
381
|
+
options.env || (await promptForEnvironment(Object.keys(serviceConfig) as Environment[]));
|
|
382
|
+
|
|
383
|
+
// 6. Get cloud configuration
|
|
384
|
+
const cloudConfig = serviceConfig[env];
|
|
385
|
+
|
|
386
|
+
// 7. Validate private key
|
|
387
|
+
await validatePrivateKey(cloudConfig.privateKeyFile);
|
|
388
|
+
|
|
389
|
+
// 8. Production confirmation
|
|
390
|
+
if (env === 'prod') {
|
|
391
|
+
const { confirmProduction } = await inquirer.prompt([
|
|
392
|
+
{
|
|
393
|
+
type: 'confirm',
|
|
394
|
+
name: 'confirmProduction',
|
|
395
|
+
message: chalk.red(
|
|
396
|
+
`β οΈ You are about to copy files to PRODUCTION (${service}). Continue?`
|
|
397
|
+
),
|
|
398
|
+
default: false,
|
|
399
|
+
},
|
|
400
|
+
]);
|
|
401
|
+
|
|
402
|
+
if (!confirmProduction) {
|
|
403
|
+
console.log(chalk.yellow('βΈοΈ Production operation cancelled.'));
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// 9. Execute SCP
|
|
409
|
+
console.log(chalk.blue(`π Connecting to ${service} (${env}): ${cloudConfig.ip}`));
|
|
410
|
+
|
|
411
|
+
const flags = pathInfo.isDirectory ? '-r' : '';
|
|
412
|
+
await $`scp -i ${cloudConfig.privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no scp ${flags} ${localPath} root@${cloudConfig.ip}:${remotePath}`;
|
|
413
|
+
|
|
414
|
+
console.log(chalk.green(`β
Successfully copied to ${service} (${env}): ${remotePath}`));
|
|
415
|
+
} catch (error) {
|
|
416
|
+
handleSSHError(error);
|
|
417
|
+
process.exit(1);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Step 3: Register Command in src/hsh.ts
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
// Add import
|
|
426
|
+
import { cloudLogin, cloudScp } from './commands/cloud.js';
|
|
427
|
+
|
|
428
|
+
// Add SCP subcommand to existing cloud command
|
|
429
|
+
cloudCommand
|
|
430
|
+
.command('scp')
|
|
431
|
+
.description('Copy files to cloud instances')
|
|
432
|
+
.option('-r, --recursive', 'Copy directories recursively')
|
|
433
|
+
.option('--env <environment>', 'Environment: dev, staging, or prod')
|
|
434
|
+
.option('--service <service>', 'Service name')
|
|
435
|
+
.argument('<local-path>', 'Local file or directory path')
|
|
436
|
+
.argument('<remote-path>', 'Remote destination path')
|
|
437
|
+
.action(async (localPath: string, remotePath: string, options: ScpOptions) => {
|
|
438
|
+
await cloudScp(localPath, remotePath, options);
|
|
439
|
+
});
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Step 4: Build and Test
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# Compile TypeScript
|
|
446
|
+
yarn build
|
|
447
|
+
|
|
448
|
+
# Install globally for testing
|
|
449
|
+
yarn build:install
|
|
450
|
+
|
|
451
|
+
# Test with a simple file
|
|
452
|
+
hsh cloud scp ./package.json /tmp/test.json --env dev --service myapp
|
|
453
|
+
|
|
454
|
+
# Test with a directory
|
|
455
|
+
hsh cloud scp -r ./dist /tmp/dist-test --env dev --service myapp
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Testing Checklist
|
|
461
|
+
|
|
462
|
+
- [ ] File copy with explicit --env and --service flags
|
|
463
|
+
- [ ] Directory copy with -r flag
|
|
464
|
+
- [ ] Interactive service selection (no --service flag)
|
|
465
|
+
- [ ] Interactive environment selection (no --env flag)
|
|
466
|
+
- [ ] Production confirmation prompt
|
|
467
|
+
- [ ] Production cancellation
|
|
468
|
+
- [ ] Error handling for missing local path
|
|
469
|
+
- [ ] Error handling for directory without -r flag
|
|
470
|
+
- [ ] Error handling for invalid service
|
|
471
|
+
- [ ] Error handling for invalid environment
|
|
472
|
+
- [ ] Error handling for connection timeout
|
|
473
|
+
- [ ] Error handling for authentication failure
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## Troubleshooting
|
|
478
|
+
|
|
479
|
+
### Command Not Found
|
|
480
|
+
|
|
481
|
+
**Problem**: `hsh: command not found` or `hsh cloud scp: command not found`
|
|
482
|
+
|
|
483
|
+
**Solution**:
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
cd /path/to/hsh
|
|
487
|
+
yarn build:install
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### TypeScript Compilation Errors
|
|
491
|
+
|
|
492
|
+
**Problem**: Type errors during build
|
|
493
|
+
|
|
494
|
+
**Solution**:
|
|
495
|
+
|
|
496
|
+
- Ensure all types are imported from `types/index.ts`
|
|
497
|
+
- Verify strict mode compliance
|
|
498
|
+
- Check that all function signatures match the API contract
|
|
499
|
+
|
|
500
|
+
### Permission Warnings
|
|
501
|
+
|
|
502
|
+
**Problem**: Warning about private key file permissions
|
|
503
|
+
|
|
504
|
+
**Solution**:
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
chmod 600 /path/to/private-key.pem
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Next Steps
|
|
513
|
+
|
|
514
|
+
After implementing the cloud scp command:
|
|
515
|
+
|
|
516
|
+
1. **Test thoroughly** across all environments (dev, staging, prod)
|
|
517
|
+
2. **Update documentation** if additional use cases are discovered
|
|
518
|
+
3. **Consider enhancements**:
|
|
519
|
+
- Add progress indication for large file transfers
|
|
520
|
+
- Support bidirectional copy (download from remote)
|
|
521
|
+
- Add dry-run mode to preview operations
|
|
522
|
+
- Support custom SSH ports via configuration
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## Summary
|
|
527
|
+
|
|
528
|
+
The `hsh cloud scp` command provides a streamlined way to copy files and directories to cloud instances:
|
|
529
|
+
|
|
530
|
+
β
Reuses existing cloud configuration
|
|
531
|
+
β
Interactive service/environment selection
|
|
532
|
+
β
Production safety confirmations
|
|
533
|
+
β
Clear error messages with actionable guidance
|
|
534
|
+
β
Follows project TypeScript and CLI conventions
|
|
535
|
+
|
|
536
|
+
For questions or issues, refer to the full specification in `spec.md` or the implementation contracts in `contracts/cloud-scp-api.ts`.
|