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,366 @@
1
+ # Quickstart: Cloud Login Implementation
2
+
3
+ **Feature**: Cloud Login Command | **Generated**: 2025-10-11 | **Phase**: 1
4
+
5
+ ## Overview
6
+
7
+ Quick implementation guide for the `hsh cloud login` feature, providing step-by-step development instructions and validation checkpoints.
8
+
9
+ ## Prerequisites
10
+
11
+ - TypeScript 5.0+ development environment
12
+ - Existing hsh CLI project structure
13
+ - Access to cloud instances with SSH keys
14
+ - yarn package manager
15
+
16
+ ## Implementation Steps
17
+
18
+ ### Step 1: Update Type Definitions
19
+
20
+ **File**: `src/types/index.ts`
21
+
22
+ Add new TypeScript interfaces for cloud configuration:
23
+
24
+ ```typescript
25
+ // Add to existing types
26
+ export interface CloudConfig {
27
+ ip: string;
28
+ privateKeyFile: string;
29
+ }
30
+
31
+ export interface ServiceConfig {
32
+ dev: CloudConfig;
33
+ staging: CloudConfig;
34
+ prod: CloudConfig;
35
+ }
36
+
37
+ export interface YirenConfig {
38
+ [serviceName: string]: ServiceConfig;
39
+ }
40
+
41
+ export interface HshConfig {
42
+ repos: {
43
+ [groupName: string]: {
44
+ [repoName: string]: string;
45
+ };
46
+ };
47
+ yiren: YirenConfig;
48
+ }
49
+
50
+ export type Environment = 'dev' | 'staging' | 'prod';
51
+ ```
52
+
53
+ **Validation**: TypeScript compilation succeeds with no type errors.
54
+
55
+ ### Step 2: Update Configuration Utility
56
+
57
+ **File**: `src/util.ts`
58
+
59
+ Update the configuration reading function to support new structure:
60
+
61
+ ```typescript
62
+ import { HshConfig } from './types/index.js';
63
+
64
+ export async function readConfig(): Promise<HshConfig> {
65
+ const configPath = path.join(os.homedir(), '.hsh', 'config.json');
66
+
67
+ if (!existsSync(configPath)) {
68
+ throw new Error(`Configuration file not found: ${configPath}`);
69
+ }
70
+
71
+ const configContent = await readFile(configPath, 'utf-8');
72
+ const config = JSON.parse(configContent);
73
+
74
+ // Auto-migrate legacy configuration
75
+ if (!config.repos && !config.yiren) {
76
+ return {
77
+ repos: config,
78
+ yiren: {},
79
+ };
80
+ }
81
+
82
+ return config as HshConfig;
83
+ }
84
+ ```
85
+
86
+ **Validation**: Configuration reading works with both old and new formats.
87
+
88
+ ### Step 3: Create Cloud Command Module
89
+
90
+ **File**: `src/commands/cloud.ts`
91
+
92
+ Implement the cloud login functionality:
93
+
94
+ ```typescript
95
+ import { $ } from 'zx';
96
+ import chalk from 'chalk';
97
+ import inquirer from 'inquirer';
98
+ import { readConfig } from '../util.js';
99
+ import { Environment, CloudConfig } from '../types/index.js';
100
+
101
+ export async function cloudLogin(env?: Environment, service?: string) {
102
+ try {
103
+ const config = await readConfig();
104
+
105
+ // Interactive prompts for missing parameters
106
+ if (!service) {
107
+ const availableServices = Object.keys(config.yiren);
108
+ if (availableServices.length === 0) {
109
+ console.error(chalk.red('❌ No cloud services configured'));
110
+ return;
111
+ }
112
+
113
+ const { selectedService } = await inquirer.prompt([
114
+ {
115
+ type: 'list',
116
+ name: 'selectedService',
117
+ message: 'Select service:',
118
+ choices: availableServices,
119
+ },
120
+ ]);
121
+ service = selectedService;
122
+ }
123
+
124
+ if (!env) {
125
+ const { selectedEnv } = await inquirer.prompt([
126
+ {
127
+ type: 'list',
128
+ name: 'selectedEnv',
129
+ message: 'Select environment:',
130
+ choices: ['dev', 'staging', 'prod'],
131
+ },
132
+ ]);
133
+ env = selectedEnv;
134
+ }
135
+
136
+ // Validate configuration exists
137
+ const serviceConfig = config.yiren[service];
138
+ if (!serviceConfig) {
139
+ console.error(chalk.red(`❌ Service '${service}' not found in configuration`));
140
+ return;
141
+ }
142
+
143
+ const cloudConfig = serviceConfig[env];
144
+ if (!cloudConfig) {
145
+ console.error(chalk.red(`❌ Environment '${env}' not configured for service '${service}'`));
146
+ return;
147
+ }
148
+
149
+ // Validate private key file
150
+ await validatePrivateKey(cloudConfig.privateKeyFile);
151
+
152
+ // Execute SSH connection
153
+ console.log(chalk.blue(`🔗 Connecting to ${service} (${env}): ${cloudConfig.ip}`));
154
+ await $`ssh -i ${cloudConfig.privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${cloudConfig.ip}`;
155
+ } catch (error) {
156
+ handleSSHError(error);
157
+ process.exit(1);
158
+ }
159
+ }
160
+
161
+ async function validatePrivateKey(privateKeyFile: string): Promise<void> {
162
+ // Implementation from research.md
163
+ // Check file existence and permissions
164
+ }
165
+
166
+ function handleSSHError(error: any): void {
167
+ // Implementation from research.md
168
+ // Provide user-friendly error messages
169
+ }
170
+ ```
171
+
172
+ **Validation**: SSH connections work with valid configuration.
173
+
174
+ ### Step 4: Update Main CLI Entry
175
+
176
+ **File**: `src/hsh.ts`
177
+
178
+ Add the cloud command structure to the CLI:
179
+
180
+ ```typescript
181
+ import { cloudLogin } from './commands/cloud.js';
182
+
183
+ // Add after existing commands
184
+ const cloudCommand = program
185
+ .command('cloud')
186
+ .description('Cloud infrastructure management commands');
187
+
188
+ // Add login subcommand
189
+ cloudCommand
190
+ .command('login')
191
+ .description('SSH into cloud instances')
192
+ .option('--env <environment>', 'Environment: dev, staging, or prod')
193
+ .option('--service <service>', 'Service name (e.g., todo-mini, wuhan-mall)')
194
+ .action(async (options) => {
195
+ await cloudLogin(options.env, options.service);
196
+ });
197
+
198
+ // Future subcommands can be added like:
199
+ // cloudCommand
200
+ // .command('scp')
201
+ // .description('Copy files to/from cloud instances')
202
+ // .action(async (options) => { ... });
203
+ ```
204
+
205
+ **Validation**: Command appears in `hsh --help` output with proper subcommand structure.
206
+
207
+ ### Step 5: Update IDE Commands for New Config
208
+
209
+ **File**: `src/commands/ide.ts`
210
+
211
+ Update existing IDE commands to use `config.repos`:
212
+
213
+ ```typescript
214
+ // Update existing functions to use config.repos instead of direct config access
215
+ export async function openCursor() {
216
+ const config = await readConfig();
217
+ const projects = config.repos; // Updated from direct config access
218
+ // Rest of implementation unchanged
219
+ }
220
+
221
+ export async function openSurf() {
222
+ const config = await readConfig();
223
+ const projects = config.repos; // Updated from direct config access
224
+ // Rest of implementation unchanged
225
+ }
226
+ ```
227
+
228
+ **Validation**: Existing `cursor` and `surf` commands continue to work.
229
+
230
+ ## Configuration Setup
231
+
232
+ ### Sample Configuration File
233
+
234
+ Create or update `~/.ai/config.json`:
235
+
236
+ ```json
237
+ {
238
+ "repos": {
239
+ "personal": {
240
+ "hsh-tool": "/Users/username/projects/hsh"
241
+ },
242
+ "work": {
243
+ "api-service": "/Users/username/work/api-service"
244
+ }
245
+ },
246
+ "yiren": {
247
+ "todo-mini": {
248
+ "dev": {
249
+ "ip": "192.168.1.10",
250
+ "privateKeyFile": "/Users/username/.ssh/todo-mini-dev.pem"
251
+ },
252
+ "staging": {
253
+ "ip": "192.168.1.20",
254
+ "privateKeyFile": "/Users/username/.ssh/todo-mini-staging.pem"
255
+ },
256
+ "prod": {
257
+ "ip": "192.168.1.30",
258
+ "privateKeyFile": "/Users/username/.ssh/todo-mini-prod.pem"
259
+ }
260
+ },
261
+ "wuhan-mall": {
262
+ "dev": {
263
+ "ip": "192.168.2.10",
264
+ "privateKeyFile": "/Users/username/.ssh/wuhan-mall-dev.pem"
265
+ },
266
+ "staging": {
267
+ "ip": "192.168.2.20",
268
+ "privateKeyFile": "/Users/username/.ssh/wuhan-mall-staging.pem"
269
+ },
270
+ "prod": {
271
+ "ip": "192.168.2.30",
272
+ "privateKeyFile": "/Users/username/.ssh/wuhan-mall-prod.pem"
273
+ }
274
+ }
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### SSH Key Setup
280
+
281
+ Ensure SSH private key files have correct permissions:
282
+
283
+ ```bash
284
+ chmod 600 /path/to/private-key-file.pem
285
+ ```
286
+
287
+ ## Testing
288
+
289
+ ### Manual Testing Checklist
290
+
291
+ - [ ] `hsh cloud --help` shows available subcommands
292
+ - [ ] `hsh cloud login --help` shows login-specific options
293
+ - [ ] `hsh cloud login --env dev --service todo-mini` connects successfully
294
+ - [ ] `hsh cloud login` prompts for missing parameters
295
+ - [ ] Invalid service name shows helpful error message
296
+ - [ ] Invalid environment shows helpful error message
297
+ - [ ] Missing private key file shows helpful error message
298
+ - [ ] Wrong private key permissions shows warning with fix command
299
+ - [ ] Existing `hsh cursor` command still works with new config structure
300
+ - [ ] Existing `hsh surf` command still works with new config structure
301
+ - [ ] Legacy configuration automatically migrates to new structure
302
+
303
+ ### Error Scenarios
304
+
305
+ Test error handling for:
306
+
307
+ - Configuration file not found
308
+ - Invalid JSON in configuration
309
+ - Network connectivity issues
310
+ - SSH authentication failures
311
+ - Missing private key files
312
+
313
+ ## Build and Deploy
314
+
315
+ ```bash
316
+ # Build TypeScript
317
+ yarn build
318
+
319
+ # Install globally for testing
320
+ yarn build:install
321
+
322
+ # Test commands
323
+ hsh cloud --help
324
+ hsh cloud login --help
325
+ hsh cloud login --env dev --service todo-mini
326
+ ```
327
+
328
+ ## Success Criteria
329
+
330
+ ✅ **Functional Requirements**:
331
+
332
+ - Cloud login command executes SSH connections
333
+ - Configuration structure supports both repos and cloud configs
334
+ - Backward compatibility maintained for existing commands
335
+
336
+ ✅ **Technical Requirements**:
337
+
338
+ - TypeScript strict mode compliance
339
+ - zx library usage for shell commands
340
+ - inquirer prompts for user interaction
341
+ - Chalk colored output for feedback
342
+
343
+ ✅ **Quality Requirements**:
344
+
345
+ - Comprehensive error handling
346
+ - Input validation and helpful messages
347
+ - Security best practices for SSH keys
348
+ - Performance targets met (<2 seconds command execution)
349
+
350
+ ## Next Steps
351
+
352
+ After implementation:
353
+
354
+ 1. Run comprehensive testing with various configuration scenarios
355
+ 2. Update documentation for new command usage
356
+ 3. Consider adding bash completion for service and environment names
357
+ 4. Plan additional cloud management features (status, logs, etc.)
358
+
359
+ ## Troubleshooting
360
+
361
+ Common issues and solutions:
362
+
363
+ - **TypeScript errors**: Ensure all imports use `.js` extensions
364
+ - **Configuration not found**: Check file path and permissions
365
+ - **SSH connection fails**: Verify network connectivity and key permissions
366
+ - **Command not found**: Rebuild and reinstall globally with `yarn build:install`
@@ -0,0 +1,290 @@
1
+ # Research: Cloud Login Implementation
2
+
3
+ **Generated**: 2025-10-11 | **Phase**: 0 | **Feature**: Cloud Login Command
4
+
5
+ ## Overview
6
+
7
+ Research for implementing `hsh cloud login` command with SSH connections, configuration migration, and error handling best practices.
8
+
9
+ ## 1. SSH Connection Management with zx
10
+
11
+ ### Decision: Use zx with proper SSH execution patterns
12
+
13
+ **Context**: Need to execute SSH commands using zx library following project constitution.
14
+
15
+ **Research Findings**:
16
+
17
+ - zx provides `$` template literal syntax for shell commands
18
+ - SSH connections require handling of interactive sessions and proper error handling
19
+ - Best practice: Use `$` with proper argument escaping and timeout handling
20
+
21
+ **Implementation Pattern**:
22
+
23
+ ```typescript
24
+ import { $ } from 'zx';
25
+
26
+ // SSH execution with zx
27
+ await $`ssh -i ${privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${ip}`;
28
+ ```
29
+
30
+ **Rationale**: zx provides consistent cross-platform shell execution with TypeScript integration. The `-o ConnectTimeout=10` prevents hanging connections, and `-o StrictHostKeyChecking=no` avoids interactive prompts.
31
+
32
+ **Alternatives Considered**:
33
+
34
+ - Direct `child_process.spawn()`: Rejected due to constitution requirement for zx usage
35
+ - SSH libraries (ssh2): Rejected to avoid additional dependencies and complexity
36
+
37
+ ## 2. Configuration File Migration Strategy
38
+
39
+ ### Decision: Backward-compatible configuration reader with automatic migration
40
+
41
+ **Context**: Need to support both old flat structure and new nested structure for IDE commands.
42
+
43
+ **Research Findings**:
44
+
45
+ - Configuration migration should be transparent to users
46
+ - Support both structures during transition period
47
+ - Provide clear migration path and warnings
48
+
49
+ **Implementation Strategy**:
50
+
51
+ ```typescript
52
+ interface LegacyConfig {
53
+ [category: string]: {
54
+ [project: string]: string;
55
+ };
56
+ }
57
+
58
+ interface NewConfig {
59
+ repos: {
60
+ [category: string]: {
61
+ [project: string]: string;
62
+ };
63
+ };
64
+ yiren: {
65
+ [service: string]: {
66
+ [env: string]: {
67
+ ip: string;
68
+ privateKeyFile: string;
69
+ };
70
+ };
71
+ };
72
+ }
73
+
74
+ function migrateConfig(config: any): NewConfig {
75
+ // Detect old format and migrate automatically
76
+ if (!config.repos && !config.yiren) {
77
+ return {
78
+ repos: config,
79
+ yiren: {},
80
+ };
81
+ }
82
+ return config as NewConfig;
83
+ }
84
+ ```
85
+
86
+ **Rationale**: Automatic migration maintains backward compatibility while enabling new features. Users don't need to manually update configurations.
87
+
88
+ **Alternatives Considered**:
89
+
90
+ - Breaking change requiring manual migration: Rejected to avoid user friction
91
+ - Supporting both formats permanently: Rejected due to complexity maintenance
92
+
93
+ ## 3. Error Handling Patterns for SSH Connections
94
+
95
+ ### Decision: Comprehensive error handling with user-friendly messages
96
+
97
+ **Context**: SSH connections can fail for various reasons (network, authentication, host unreachable).
98
+
99
+ **Research Findings**:
100
+
101
+ - SSH failures should provide actionable error messages
102
+ - Common failure modes: connection timeout, authentication failure, host unreachable
103
+ - Use chalk for colored error output following project patterns
104
+
105
+ **Error Handling Strategy**:
106
+
107
+ ```typescript
108
+ import chalk from 'chalk';
109
+
110
+ async function executeSSH(ip: string, privateKeyFile: string) {
111
+ try {
112
+ await $`ssh -i ${privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${ip}`;
113
+ } catch (error) {
114
+ if (error.message.includes('Connection timed out')) {
115
+ console.error(chalk.red('❌ Connection timeout - check network connectivity and IP address'));
116
+ } else if (error.message.includes('Permission denied')) {
117
+ console.error(
118
+ chalk.red('❌ Authentication failed - check private key file permissions and path')
119
+ );
120
+ } else if (error.message.includes('No route to host')) {
121
+ console.error(chalk.red('❌ Host unreachable - verify IP address and network access'));
122
+ } else {
123
+ console.error(chalk.red(`❌ SSH connection failed: ${error.message}`));
124
+ }
125
+ process.exit(1);
126
+ }
127
+ }
128
+ ```
129
+
130
+ **Rationale**: Specific error messages help users diagnose and fix connection issues quickly. Using chalk for colored output follows project conventions.
131
+
132
+ **Alternatives Considered**:
133
+
134
+ - Generic error messages: Rejected as unhelpful for debugging
135
+ - Silent failures: Rejected as users need feedback on connection status
136
+
137
+ ## 4. Command Parameter Validation
138
+
139
+ ### Decision: Use inquirer for interactive prompts with validation
140
+
141
+ **Context**: Need to validate environment and service parameters, provide user guidance.
142
+
143
+ **Research Findings**:
144
+
145
+ - inquirer provides excellent autocomplete and validation capabilities
146
+ - Should offer interactive selection when parameters are missing
147
+ - Validate against available options in configuration
148
+
149
+ **Implementation Pattern**:
150
+
151
+ ```typescript
152
+ import inquirer from 'inquirer';
153
+
154
+ async function promptForMissingParams(config: NewConfig, env?: string, service?: string) {
155
+ const questions = [];
156
+
157
+ if (!service) {
158
+ questions.push({
159
+ type: 'list',
160
+ name: 'service',
161
+ message: 'Select service:',
162
+ choices: Object.keys(config.yiren),
163
+ validate: (input: string) => Object.keys(config.yiren).includes(input),
164
+ });
165
+ }
166
+
167
+ if (!env) {
168
+ questions.push({
169
+ type: 'list',
170
+ name: 'env',
171
+ message: 'Select environment:',
172
+ choices: ['dev', 'staging', 'prod'],
173
+ validate: (input: string) => ['dev', 'staging', 'prod'].includes(input),
174
+ });
175
+ }
176
+
177
+ return await inquirer.prompt(questions);
178
+ }
179
+ ```
180
+
181
+ **Rationale**: Interactive prompts reduce user errors and provide guidance. Validation ensures only valid options are accepted.
182
+
183
+ **Alternatives Considered**:
184
+
185
+ - Command-line flags only: Rejected as less user-friendly for discovery
186
+ - No validation: Rejected as it leads to runtime errors
187
+
188
+ ## 5. Private Key File Security
189
+
190
+ ### Decision: Validate private key file permissions and existence
191
+
192
+ **Context**: SSH private keys must have correct permissions and exist for security.
193
+
194
+ **Research Findings**:
195
+
196
+ - SSH requires private key files to have 600 permissions (readable by owner only)
197
+ - Files should exist and be readable before attempting SSH connection
198
+ - Provide clear guidance on fixing permission issues
199
+
200
+ **Security Validation**:
201
+
202
+ ```typescript
203
+ import { access, stat } from 'fs/promises';
204
+ import { constants } from 'fs';
205
+
206
+ async function validatePrivateKey(privateKeyFile: string): Promise<void> {
207
+ try {
208
+ // Check if file exists
209
+ await access(privateKeyFile, constants.F_OK);
210
+
211
+ // Check permissions
212
+ const stats = await stat(privateKeyFile);
213
+ const permissions = stats.mode & parseInt('777', 8);
214
+
215
+ if (permissions !== parseInt('600', 8)) {
216
+ console.warn(
217
+ chalk.yellow(
218
+ `⚠️ Private key file permissions should be 600. Run: chmod 600 ${privateKeyFile}`
219
+ )
220
+ );
221
+ }
222
+ } catch (error) {
223
+ throw new Error(`Private key file not found or not accessible: ${privateKeyFile}`);
224
+ }
225
+ }
226
+ ```
227
+
228
+ **Rationale**: Proactive validation prevents common SSH authentication failures and provides actionable guidance.
229
+
230
+ **Alternatives Considered**:
231
+
232
+ - No permission checking: Rejected as it leads to confusing SSH failures
233
+ - Automatic permission fixing: Rejected as it modifies user files without permission
234
+
235
+ ## 6. TypeScript Type Definitions
236
+
237
+ ### Decision: Comprehensive type definitions for configuration and parameters
238
+
239
+ **Context**: Project requires strict TypeScript typing following constitution.
240
+
241
+ **Type Definitions**:
242
+
243
+ ```typescript
244
+ export interface CloudConfig {
245
+ ip: string;
246
+ privateKeyFile: string;
247
+ }
248
+
249
+ export interface ServiceConfig {
250
+ dev: CloudConfig;
251
+ staging: CloudConfig;
252
+ prod: CloudConfig;
253
+ }
254
+
255
+ export interface YirenConfig {
256
+ [serviceName: string]: ServiceConfig;
257
+ }
258
+
259
+ export interface HshConfig {
260
+ repos: {
261
+ [groupName: string]: {
262
+ [repoName: string]: string;
263
+ };
264
+ };
265
+ yiren: YirenConfig;
266
+ }
267
+
268
+ export type Environment = 'dev' | 'staging' | 'prod';
269
+ export type ServiceName = string;
270
+ ```
271
+
272
+ **Rationale**: Strong typing prevents runtime errors and enables better IDE support and refactoring capabilities.
273
+
274
+ **Alternatives Considered**:
275
+
276
+ - Loose typing with any: Rejected due to constitution requirements
277
+ - Inline types: Rejected for maintainability and reusability
278
+
279
+ ## Implementation Roadmap
280
+
281
+ 1. **Configuration Management**: Update util.ts with new config structure support
282
+ 2. **Type Definitions**: Add new types to types/index.ts
283
+ 3. **Cloud Command Module**: Create src/commands/cloud.ts with SSH functionality
284
+ 4. **CLI Integration**: Update src/hsh.ts to register cloud commands
285
+ 5. **IDE Command Updates**: Modify src/commands/ide.ts for new config structure
286
+ 6. **Testing**: Manual testing with various configuration scenarios
287
+
288
+ ## Conclusion
289
+
290
+ All technical questions have been resolved with specific implementation patterns. The approach maintains backward compatibility, follows project constitution requirements, and provides excellent user experience through proper error handling and validation.