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,424 @@
1
+ # Data Model: Cloud SCP Command
2
+
3
+ **Feature**: 001-cloud-scp-command
4
+ **Date**: 2025-10-11
5
+
6
+ ## Overview
7
+
8
+ This document defines the data structures, types, and state management for the `hsh cloud scp` command. Since this feature extends the existing cloud infrastructure, it primarily reuses existing types and adds minimal new structures.
9
+
10
+ ## Type Definitions
11
+
12
+ ### Existing Types (Reused from types/index.ts)
13
+
14
+ ```typescript
15
+ // Environment type - already defined in cloud login
16
+ export type Environment = 'dev' | 'staging' | 'prod';
17
+
18
+ // Cloud configuration interface - already defined
19
+ export interface CloudConfig {
20
+ ip: string;
21
+ privateKeyFile: string;
22
+ }
23
+
24
+ // Service configuration - already defined
25
+ export interface ServiceConfig {
26
+ [key: string]: CloudConfig;
27
+ }
28
+
29
+ // Full configuration structure - already defined
30
+ export interface Config {
31
+ repos?: {
32
+ [category: string]: {
33
+ [project: string]: string;
34
+ };
35
+ };
36
+ yiren: {
37
+ [service: string]: {
38
+ dev?: CloudConfig;
39
+ staging?: CloudConfig;
40
+ prod?: CloudConfig;
41
+ };
42
+ };
43
+ }
44
+ ```
45
+
46
+ ### New Types (SCP-Specific)
47
+
48
+ ```typescript
49
+ // SCP command options interface
50
+ export interface ScpOptions {
51
+ env?: Environment;
52
+ service?: string;
53
+ recursive?: boolean;
54
+ }
55
+
56
+ // Path validation result
57
+ export interface PathValidationResult {
58
+ exists: boolean;
59
+ isDirectory: boolean;
60
+ isFile: boolean;
61
+ path: string;
62
+ }
63
+
64
+ // SCP operation metadata (for logging/debugging)
65
+ export interface ScpOperation {
66
+ localPath: string;
67
+ remotePath: string;
68
+ service: string;
69
+ environment: Environment;
70
+ isDirectory: boolean;
71
+ timestamp: Date;
72
+ }
73
+ ```
74
+
75
+ ## Entities
76
+
77
+ ### Entity 1: SCP Command Parameters
78
+
79
+ **Purpose**: Encapsulates all parameters required to execute an SCP operation
80
+
81
+ **Fields**:
82
+
83
+ - `localPath: string` - Source file or directory path on local filesystem
84
+ - `remotePath: string` - Destination path on remote server
85
+ - `options: ScpOptions` - Command options including environment, service, and recursive flag
86
+
87
+ **Validation Rules**:
88
+
89
+ - `localPath`: Must exist on local filesystem (validated before execution)
90
+ - `remotePath`: Must be non-empty string (format validation delegated to SSH/SCP)
91
+ - `options.recursive`: Required if localPath is a directory
92
+ - `options.env`: Must be one of 'dev' | 'staging' | 'prod' (if provided)
93
+ - `options.service`: Must exist in configuration (if provided)
94
+
95
+ **Usage**:
96
+
97
+ ```typescript
98
+ interface ScpCommandParams {
99
+ localPath: string;
100
+ remotePath: string;
101
+ options: ScpOptions;
102
+ }
103
+ ```
104
+
105
+ ### Entity 2: Path Validation State
106
+
107
+ **Purpose**: Represents the result of local path validation
108
+
109
+ **Fields**:
110
+
111
+ - `exists: boolean` - Whether the path exists on filesystem
112
+ - `isDirectory: boolean` - Whether the path is a directory
113
+ - `isFile: boolean` - Whether the path is a regular file
114
+ - `path: string` - The validated path (resolved/absolute)
115
+
116
+ **State Transitions**:
117
+
118
+ 1. **Initial**: Path provided by user → validation pending
119
+ 2. **Validated**: Path checked via fs.stat() → exists/type determined
120
+ 3. **Error**: Path doesn't exist or permission denied → error state
121
+
122
+ **Validation Flow**:
123
+
124
+ ```typescript
125
+ async function validatePath(path: string): Promise<PathValidationResult> {
126
+ try {
127
+ const stats = await stat(path);
128
+ return {
129
+ exists: true,
130
+ isDirectory: stats.isDirectory(),
131
+ isFile: stats.isFile(),
132
+ path: path,
133
+ };
134
+ } catch (error) {
135
+ if (error.code === 'ENOENT') {
136
+ return {
137
+ exists: false,
138
+ isDirectory: false,
139
+ isFile: false,
140
+ path: path,
141
+ };
142
+ }
143
+ throw error; // Permission errors, etc.
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### Entity 3: SCP Execution Context
149
+
150
+ **Purpose**: Complete context required to execute SCP command
151
+
152
+ **Fields**:
153
+
154
+ - `service: string` - Selected service name
155
+ - `environment: Environment` - Selected environment
156
+ - `cloudConfig: CloudConfig` - IP and private key from configuration
157
+ - `localPath: string` - Validated local source path
158
+ - `remotePath: string` - Remote destination path
159
+ - `isRecursive: boolean` - Whether to use -r flag
160
+
161
+ **Derivation**:
162
+
163
+ ```typescript
164
+ interface ScpExecutionContext {
165
+ service: string;
166
+ environment: Environment;
167
+ cloudConfig: CloudConfig;
168
+ localPath: string;
169
+ remotePath: string;
170
+ isRecursive: boolean;
171
+ }
172
+
173
+ // Derived from user input + configuration + validation
174
+ function buildExecutionContext(
175
+ params: ScpCommandParams,
176
+ config: Config,
177
+ pathInfo: PathValidationResult
178
+ ): ScpExecutionContext {
179
+ return {
180
+ service: params.options.service || await promptForService(...),
181
+ environment: params.options.env || await promptForEnvironment(...),
182
+ cloudConfig: config.yiren[service][environment],
183
+ localPath: pathInfo.path,
184
+ remotePath: params.remotePath,
185
+ isRecursive: pathInfo.isDirectory
186
+ };
187
+ }
188
+ ```
189
+
190
+ ## Configuration Data Model
191
+
192
+ ### Configuration File Structure
193
+
194
+ The SCP command uses the existing `~/.ai/config.json` structure:
195
+
196
+ ```json
197
+ {
198
+ "yiren": {
199
+ "service-name": {
200
+ "dev": {
201
+ "ip": "192.168.1.10",
202
+ "privateKeyFile": "/path/to/dev-key.pem"
203
+ },
204
+ "staging": {
205
+ "ip": "192.168.1.20",
206
+ "privateKeyFile": "/path/to/staging-key.pem"
207
+ },
208
+ "prod": {
209
+ "ip": "192.168.1.30",
210
+ "privateKeyFile": "/path/to/prod-key.pem"
211
+ }
212
+ }
213
+ }
214
+ }
215
+ ```
216
+
217
+ **No Schema Changes Required**: SCP command fully reuses cloud login configuration
218
+
219
+ ## Data Flow
220
+
221
+ ### 1. Command Input → Validation
222
+
223
+ ```
224
+ User Input:
225
+ hsh cloud scp -r ./dist /var/www/html --env prod --service my-app
226
+
227
+
228
+
229
+ Parse Parameters:
230
+ localPath: "./dist"
231
+ remotePath: "/var/www/html"
232
+ options: { env: "prod", service: "my-app", recursive: true }
233
+
234
+
235
+
236
+ Validate Local Path:
237
+ await stat("./dist")
238
+ → { exists: true, isDirectory: true, isFile: false }
239
+
240
+
241
+
242
+ Validate Recursive Flag:
243
+ isDirectory: true
244
+ recursive: true
245
+ → ✅ Valid
246
+ ```
247
+
248
+ ### 2. Configuration Resolution
249
+
250
+ ```
251
+ Configuration Lookup:
252
+ config.yiren["my-app"]["prod"]
253
+
254
+
255
+
256
+ Extract CloudConfig:
257
+ {
258
+ ip: "192.168.1.30",
259
+ privateKeyFile: "/path/to/prod-key.pem"
260
+ }
261
+
262
+
263
+
264
+ Validate Private Key:
265
+ await validatePrivateKey("/path/to/prod-key.pem")
266
+ → Check existence, permissions
267
+ ```
268
+
269
+ ### 3. Interactive Prompts (if options missing)
270
+
271
+ ```
272
+ If options.service === undefined:
273
+ services = Object.keys(config.yiren)
274
+ selectedService = await promptForService(services)
275
+
276
+ If options.env === undefined:
277
+ environments = Object.keys(config.yiren[service])
278
+ selectedEnv = await promptForEnvironment(environments)
279
+ ```
280
+
281
+ ### 4. Execution Context → SCP Command
282
+
283
+ ```
284
+ Build Context:
285
+ {
286
+ service: "my-app",
287
+ environment: "prod",
288
+ cloudConfig: { ip: "...", privateKeyFile: "..." },
289
+ localPath: "./dist",
290
+ remotePath: "/var/www/html",
291
+ isRecursive: true
292
+ }
293
+
294
+
295
+
296
+ Construct SCP Command:
297
+ scp -i /path/to/prod-key.pem scp -r ./dist root@192.168.1.30:/var/www/html
298
+
299
+
300
+
301
+ Execute via zx:
302
+ await $`scp -i ${privateKey} scp ${flags} ${localPath} root@${ip}:${remotePath}`
303
+ ```
304
+
305
+ ## Error States
306
+
307
+ ### Path Validation Errors
308
+
309
+ ```typescript
310
+ // Error State 1: Path doesn't exist
311
+ {
312
+ exists: false,
313
+ isDirectory: false,
314
+ isFile: false,
315
+ path: "./nonexistent"
316
+ }
317
+ → Error: "❌ Local path not found: ./nonexistent"
318
+
319
+ // Error State 2: Directory without -r flag
320
+ {
321
+ exists: true,
322
+ isDirectory: true,
323
+ isFile: false,
324
+ path: "./dist"
325
+ }
326
+ + options.recursive: false
327
+ → Error: "❌ Cannot copy directory without -r flag"
328
+
329
+ // Error State 3: Permission denied
330
+ throw { code: 'EACCES', path: './restricted' }
331
+ → Error: "❌ Permission denied: ./restricted"
332
+ ```
333
+
334
+ ### Configuration Errors
335
+
336
+ ```typescript
337
+ // Error State 4: Service not found
338
+ config.yiren["unknown-service"]
339
+ → undefined
340
+ → Error: "❌ Service 'unknown-service' not found in configuration"
341
+
342
+ // Error State 5: Environment not configured
343
+ config.yiren["my-app"]["unknown-env"]
344
+ → undefined
345
+ → Error: "❌ Environment 'unknown-env' not configured for service 'my-app'"
346
+
347
+ // Error State 6: No services configured
348
+ config.yiren
349
+ → {} (empty)
350
+ → Error: "❌ No cloud services configured in yiren section"
351
+ ```
352
+
353
+ ### SSH/SCP Errors
354
+
355
+ ```typescript
356
+ // Error State 7: Connection timeout
357
+ → Handled by handleSSHError()
358
+ → "❌ Connection timeout - check network connectivity and IP address"
359
+
360
+ // Error State 8: Authentication failure
361
+ → Handled by handleSSHError()
362
+ → "❌ Authentication failed - check private key file permissions and path"
363
+
364
+ // Error State 9: Host unreachable
365
+ → Handled by handleSSHError()
366
+ → "❌ Host unreachable - verify IP address and network access"
367
+ ```
368
+
369
+ ## State Management
370
+
371
+ This feature is stateless - all state is ephemeral and exists only during command execution:
372
+
373
+ 1. **Input State**: Command-line arguments and options (ephemeral)
374
+ 2. **Configuration State**: Read from `~/.ai/config.json` (persistent, read-only)
375
+ 3. **Validation State**: Path validation results (ephemeral, derived)
376
+ 4. **Execution State**: SCP execution context (ephemeral, derived)
377
+
378
+ **No Persistent State**: No databases, no session storage, no state files
379
+
380
+ ## Type Safety Guarantees
381
+
382
+ ### TypeScript Strict Mode Enforcement
383
+
384
+ ```typescript
385
+ // All functions have explicit return types
386
+ async function cloudScp(localPath: string, remotePath: string, options: ScpOptions): Promise<void>;
387
+
388
+ // All parameters are typed
389
+ async function validateLocalPath(path: string): Promise<PathValidationResult>;
390
+
391
+ // Error handling preserves types
392
+ try {
393
+ await cloudScp(localPath, remotePath, options);
394
+ } catch (error: any) {
395
+ handleSSHError(error);
396
+ }
397
+ ```
398
+
399
+ ### Interface Validation
400
+
401
+ ```typescript
402
+ // Configuration structure is validated at runtime
403
+ function isCloudConfig(obj: any): obj is CloudConfig {
404
+ return obj && typeof obj.ip === 'string' && typeof obj.privateKeyFile === 'string';
405
+ }
406
+
407
+ // Environment validation
408
+ function isEnvironment(value: any): value is Environment {
409
+ return value === 'dev' || value === 'staging' || value === 'prod';
410
+ }
411
+ ```
412
+
413
+ ## Summary
414
+
415
+ The data model for `hsh cloud scp` is intentionally minimal:
416
+
417
+ - **Reuses 100%** of existing cloud login types (`Environment`, `CloudConfig`, `ServiceConfig`, `Config`)
418
+ - **Adds 3 new types** for SCP-specific needs (`ScpOptions`, `PathValidationResult`, `ScpOperation`)
419
+ - **No schema changes** to configuration file structure
420
+ - **Stateless design** with ephemeral state during execution
421
+ - **Type-safe** with strict TypeScript enforcement
422
+ - **Validated** at each stage: path → configuration → execution
423
+
424
+ This aligns with the constitution's TypeScript-First principle and the modular architecture requirement by maintaining clear separation between types, validation, and execution logic.
@@ -0,0 +1,124 @@
1
+ # Implementation Plan: Cloud SCP Command
2
+
3
+ **Branch**: `001-cloud-scp-command` | **Date**: 2025-10-11 | **Spec**: [spec.md](./spec.md)
4
+ **Input**: Feature specification from `/specs/001-cloud-scp-command/spec.md`
5
+
6
+ **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
7
+
8
+ ## Summary
9
+
10
+ Add `hsh cloud scp` command to enable secure file/directory copying to cloud instances. The command extends existing cloud infrastructure management by reusing the same configuration structure and helper functions from `cloud login`. It will support interactive service/environment selection, automatic file vs directory detection, and production safety confirmations.
11
+
12
+ ## Technical Context
13
+
14
+ **Language/Version**: TypeScript 5.0+ with ES2020 target and ESNext modules
15
+ **Primary Dependencies**:
16
+
17
+ - commander (CLI framework for command/option parsing)
18
+ - inquirer (interactive prompts with validation)
19
+ - zx (shell command execution)
20
+ - chalk (terminal colors for user feedback)
21
+ - fs/promises (file system operations for path validation)
22
+
23
+ **Storage**: Configuration from `~/.ai/config.json` (existing yiren section)
24
+ **Testing**: Manual CLI testing (consistent with project patterns)
25
+ **Target Platform**: Node.js CLI (global installation via yarn)
26
+ **Project Type**: Single TypeScript CLI project
27
+ **Performance Goals**: Command initialization <2s (excluding actual file transfer time)
28
+ **Constraints**:
29
+
30
+ - Reuse existing cloud.ts helper functions (validatePrivateKey, promptForService, promptForEnvironment, handleSSHError)
31
+ - Maintain backward compatibility with cloud login configuration
32
+ - Follow SCP standard conventions for flags and argument order
33
+
34
+ **Scale/Scope**:
35
+
36
+ - Single new subcommand addition to existing cloud command group
37
+ - Reuses 4 existing helper functions from cloud.ts
38
+ - Adds 1 new function (cloudScp) to src/commands/cloud.ts
39
+ - Updates hsh.ts with new subcommand definition (~10 lines)
40
+
41
+ ## Constitution Check
42
+
43
+ _GATE: Must pass before Phase 0 research. Re-check after Phase 1 design._
44
+
45
+ ✅ **TypeScript-First**: All code written in TypeScript with strict mode, fully typed
46
+
47
+ - New cloudScp function will be fully typed with CloudConfig, Environment interfaces
48
+ - Path validation uses typed fs/promises API
49
+ - All parameters and return types explicitly defined
50
+
51
+ ✅ **Shell Integration**: Uses zx library for all shell operations with async/await
52
+
53
+ - SCP command execution via `$` template literals from zx
54
+ - All shell operations are async/await with proper error handling
55
+ - No direct child_process usage
56
+
57
+ ✅ **Interactive CLI**: Uses inquirer prompts with validation and chalk/ora for feedback
58
+
59
+ - Reuses promptForService and promptForEnvironment from cloud.ts
60
+ - Chalk for colored success/error messages
61
+ - Input validation before SCP execution
62
+
63
+ ✅ **Modular Architecture**: Commands organized by domain in separate modules
64
+
65
+ - cloudScp function added to src/commands/cloud.ts (cloud domain)
66
+ - Command registration in hsh.ts delegates to cloud module
67
+ - Follows existing cloud login pattern
68
+
69
+ ✅ **Yarn Package Management**: Uses Yarn with standard script patterns
70
+
71
+ - No new dependencies required
72
+ - Follows existing build, dev, start patterns
73
+ - Global installation via existing bin configuration
74
+
75
+ ## Project Structure
76
+
77
+ ### Documentation (this feature)
78
+
79
+ ```
80
+ specs/001-cloud-scp-command/
81
+ ├── spec.md # Feature specification
82
+ ├── plan.md # This file (/speckit.plan command output)
83
+ ├── research.md # Phase 0 output (/speckit.plan command)
84
+ ├── data-model.md # Phase 1 output (/speckit.plan command)
85
+ ├── quickstart.md # Phase 1 output (/speckit.plan command)
86
+ ├── contracts/ # Phase 1 output (/speckit.plan command)
87
+ └── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
88
+ ```
89
+
90
+ ### Source Code (repository root)
91
+
92
+ ```
93
+ src/
94
+ ├── commands/
95
+ │ ├── cloud.ts # MODIFIED: Add cloudScp function and SCP-related helpers
96
+ │ ├── git.ts # Unchanged
97
+ │ ├── mono.ts # Unchanged
98
+ │ └── ide.ts # Unchanged
99
+ ├── types/
100
+ │ └── index.ts # May add SCP-specific types if needed
101
+ ├── util.ts # Unchanged
102
+ └── hsh.ts # MODIFIED: Add cloud scp subcommand registration
103
+
104
+ dist/ # Compiled TypeScript output
105
+ └── [mirrors src structure]
106
+ ```
107
+
108
+ **Structure Decision**: TypeScript CLI Project (existing structure)
109
+
110
+ - **Modified Files**:
111
+ - `src/commands/cloud.ts`: Add cloudScp function with path validation and SCP execution
112
+ - `src/hsh.ts`: Register new `cloud scp` subcommand with options/arguments
113
+ - **Unchanged Files**: git.ts, mono.ts, ide.ts, util.ts remain unchanged
114
+ - **No New Files**: All functionality fits within existing cloud.ts module
115
+ - **Type Reuse**: Uses existing CloudConfig, Environment types from types/index.ts
116
+
117
+ ## Complexity Tracking
118
+
119
+ _Fill ONLY if Constitution Check has violations that must be justified_
120
+
121
+ | Violation | Why Needed | Simpler Alternative Rejected Because |
122
+ | -------------------------- | ------------------ | ------------------------------------ |
123
+ | [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
124
+ | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |