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,434 @@
1
+ # Tasks: Cloud SCP Command
2
+
3
+ **Feature ID**: 001-cloud-scp-command
4
+ **Branch**: `001-cloud-scp-command`
5
+ **Input**: Design documents from `/specs/001-cloud-scp-command/`
6
+ **Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/
7
+
8
+ **Tests**: Manual CLI testing (no automated test suite requested in spec)
9
+
10
+ **Organization**: Tasks grouped by user story for independent implementation and testing
11
+
12
+ ## Format: `[ID] [P?] [Story] Description`
13
+
14
+ - **[P]**: Can run in parallel (different files, no dependencies)
15
+ - **[Story]**: Which user story this task belongs to (US1, US2, US3)
16
+ - Include exact file paths in descriptions
17
+
18
+ ---
19
+
20
+ ## Phase 1: Setup (Shared Infrastructure)
21
+
22
+ **Purpose**: Minimal setup - most infrastructure already exists from cloud login feature
23
+
24
+ - [x] T001 Verify TypeScript 5.0+ configuration in tsconfig.json (strict mode enabled)
25
+ - [x] T002 [P] Verify existing dependencies (commander, inquirer, zx, chalk, fs/promises)
26
+ - [x] T003 [P] Review existing cloud.ts helper functions (validatePrivateKey, promptForService, promptForEnvironment, handleSSHError)
27
+
28
+ **Notes**: This is an extension of existing infrastructure. Setup tasks are verification only since the project already exists.
29
+
30
+ ---
31
+
32
+ ## Phase 2: Foundational (Blocking Prerequisites)
33
+
34
+ **Purpose**: Core types and infrastructure needed by ALL user stories
35
+
36
+ **⚠️ CRITICAL**: No user story work can begin until this phase is complete
37
+
38
+ - [x] T004 [P] Add ScpOptions interface to src/types/index.ts (env, service, recursive fields)
39
+ - [x] T005 [P] Add PathValidationResult interface to src/types/index.ts (exists, isDirectory, isFile, path fields)
40
+ - [x] T006 [P] Export ScpOptions and PathValidationResult from src/types/index.ts
41
+
42
+ **Checkpoint**: Foundation ready - user story implementation can now begin
43
+
44
+ ---
45
+
46
+ ## Phase 3: User Story 1 - Quick File Deploy (Priority: P1) 🎯 MVP
47
+
48
+ **Goal**: Enable developers to quickly copy a single file to a remote server with interactive prompts
49
+
50
+ **Independent Test**:
51
+
52
+ ```bash
53
+ # Create a test file
54
+ echo "test content" > /tmp/test-file.txt
55
+
56
+ # Test command (interactive - will prompt for service/env)
57
+ hsh cloud scp /tmp/test-file.txt /tmp/remote-test.txt
58
+
59
+ # Verify success message appears
60
+ # Expected: ✅ Successfully copied to [service] ([env]): /tmp/remote-test.txt
61
+ ```
62
+
63
+ ### Implementation for User Story 1
64
+
65
+ - [x] T007 [US1] Implement validateLocalPath() function in src/commands/cloud.ts
66
+ - Import { stat } from 'fs/promises'
67
+ - Check if path exists using stat()
68
+ - Return PathValidationResult with exists, isDirectory, isFile, path
69
+ - Handle ENOENT error (file not found) separately from permission errors
70
+ - Throw on permission denied or other fs errors
71
+
72
+ - [x] T008 [US1] Implement cloudScp() main function in src/commands/cloud.ts (depends on T007)
73
+ - Accept localPath, remotePath, options parameters with ScpOptions type
74
+ - Call validateLocalPath() for local path validation
75
+ - Handle case when path doesn't exist: log error and return early
76
+ - Read configuration using existing readConfig() from util.ts
77
+ - Handle case when no services configured: log error and return
78
+ - Use existing promptForService() if options.service not provided
79
+ - Validate service exists in config, log available services if not found
80
+ - Use existing promptForEnvironment() if options.env not provided
81
+ - Validate environment exists for service, log available environments if not found
82
+ - Get cloudConfig from config.yiren[service][env]
83
+ - Call existing validatePrivateKey() with cloudConfig.privateKeyFile
84
+ - Construct SCP command using zx $ template literal
85
+ - Pattern: `scp -i ${privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no scp ${localPath} root@${ip}:${remotePath}`
86
+ - Wrap SCP execution in try-catch, use existing handleSSHError() on failure
87
+ - Log success message with chalk.green on completion
88
+
89
+ - [x] T009 [US1] Export cloudScp function from src/commands/cloud.ts
90
+ - Add cloudScp to existing export list
91
+
92
+ - [x] T010 [US1] Import cloudScp in src/hsh.ts
93
+ - Add cloudScp to import statement from './commands/cloud.js'
94
+
95
+ - [x] T011 [US1] Register cloud scp subcommand in src/hsh.ts (depends on T010)
96
+ - Add after existing cloud login subcommand registration
97
+ - Use cloudCommand.command('scp')
98
+ - Add .description('Copy files to cloud instances')
99
+ - Add .option('--env <environment>', 'Environment: dev, staging, or prod')
100
+ - Add .option('--service <service>', 'Service name')
101
+ - Add .argument('<local-path>', 'Local file or directory path')
102
+ - Add .argument('<remote-path>', 'Remote destination path')
103
+ - Add .action() handler that calls cloudScp(localPath, remotePath, options)
104
+
105
+ - [x] T012 [US1] Build and test file copy functionality
106
+ - Run: yarn build
107
+ - Run: yarn build:install
108
+ - Test with actual file: hsh cloud scp /tmp/test.txt /tmp/remote-test.txt
109
+ - Verify interactive prompts work for service and environment selection
110
+ - Verify file copy succeeds with success message
111
+
112
+ **Checkpoint**: User Story 1 complete - file copying works with interactive prompts
113
+
114
+ ---
115
+
116
+ ## Phase 4: User Story 2 - Directory Upload (Priority: P2)
117
+
118
+ **Goal**: Enable developers to upload entire directories with recursive flag validation
119
+
120
+ **Independent Test**:
121
+
122
+ ```bash
123
+ # Create a test directory with files
124
+ mkdir -p /tmp/test-dir
125
+ echo "file1" > /tmp/test-dir/file1.txt
126
+ echo "file2" > /tmp/test-dir/file2.txt
127
+
128
+ # Test without -r flag (should fail with clear message)
129
+ hsh cloud scp /tmp/test-dir /tmp/remote-dir
130
+
131
+ # Expected: ❌ Cannot copy directory without -r flag
132
+ # Expected: Hint: Use -r flag for recursive directory copy
133
+
134
+ # Test with -r flag (should succeed)
135
+ hsh cloud scp -r /tmp/test-dir /tmp/remote-dir --env dev --service my-service
136
+
137
+ # Verify success message appears
138
+ ```
139
+
140
+ ### Implementation for User Story 2
141
+
142
+ - [ ] T013 [US2] Add -r/--recursive option to cloud scp command in src/hsh.ts
143
+ - Add before .argument() calls
144
+ - Use .option('-r, --recursive', 'Copy directories recursively')
145
+
146
+ - [ ] T014 [US2] Add directory detection logic to cloudScp() in src/commands/cloud.ts
147
+ - After validateLocalPath() call, check if pathInfo.isDirectory is true
148
+ - If isDirectory && !options.recursive, log error and return early
149
+ - Error message: chalk.red('❌ Cannot copy directory without -r flag')
150
+ - Hint message: chalk.yellow('Hint: Use -r flag for recursive directory copy')
151
+
152
+ - [ ] T015 [US2] Update SCP command construction for recursive flag in src/commands/cloud.ts
153
+ - Before SCP execution, check if pathInfo.isDirectory
154
+ - If directory, construct flags variable with '-r', otherwise empty string
155
+ - Update SCP command: `scp -i ${privateKeyFile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no scp ${flags} ${localPath} root@${ip}:${remotePath}`
156
+ - Ensure flags variable is properly spaced or empty
157
+
158
+ - [ ] T016 [US2] Build and test directory copy functionality
159
+ - Run: yarn build
160
+ - Run: yarn build:install
161
+ - Test directory without -r flag: verify error message with hint
162
+ - Test directory with -r flag: verify successful recursive copy
163
+ - Test that file copy still works (regression test for US1)
164
+
165
+ **Checkpoint**: User Stories 1 AND 2 complete - both file and directory copying work
166
+
167
+ ---
168
+
169
+ ## Phase 5: User Story 3 - Interactive Service Selection (Priority: P3)
170
+
171
+ **Goal**: Polish interactive experience - ensure prompts work consistently with cloud login
172
+
173
+ **Independent Test**:
174
+
175
+ ```bash
176
+ # Test interactive service selection (no --service flag)
177
+ hsh cloud scp /tmp/test.txt /tmp/remote.txt
178
+
179
+ # Expected: Prompt "Select service:" with list of available services
180
+ # User selects service from list
181
+ # Expected: Prompt "Select environment:" with list of available environments for that service
182
+ # User selects environment from list
183
+ # Expected: ✅ Successfully copied to [service] ([env]): /tmp/remote.txt
184
+ ```
185
+
186
+ ### Implementation for User Story 3
187
+
188
+ **Note**: Interactive prompts already implemented in US1 (T008). This phase focuses on production safety.
189
+
190
+ - [x] T017 [US3] Add production confirmation prompt to cloudScp() in src/commands/cloud.ts
191
+ - After getting cloudConfig, before validatePrivateKey()
192
+ - Check if env === 'prod'
193
+ - If production, use inquirer.prompt() with type: 'confirm'
194
+ - Message: chalk.red(`⚠️ You are about to copy files to PRODUCTION (${service}). Continue?`)
195
+ - Default: false
196
+ - If confirmProduction is false, log chalk.yellow('⏸️ Production operation cancelled.') and return
197
+ - If confirmed, continue with execution
198
+
199
+ - [x] T018 [US3] Build and test production confirmation
200
+ - Run: yarn build
201
+ - Run: yarn build:install
202
+ - Test with --env prod: verify production warning appears
203
+ - Test declining production: verify cancellation message
204
+ - Test accepting production: verify copy proceeds
205
+ - Test dev/staging: verify no prompt appears (regression test)
206
+
207
+ **Checkpoint**: All user stories complete - interactive prompts and production safety work
208
+
209
+ ---
210
+
211
+ ## Phase 6: Polish & Cross-Cutting Concerns
212
+
213
+ **Purpose**: Final improvements and validation
214
+
215
+ - [x] T019 [P] Code review: Verify all types are properly exported from src/types/index.ts
216
+ - [x] T020 [P] Code review: Verify consistent error handling with chalk colors
217
+ - [x] T021 [P] Code review: Verify all async functions use await with proper error handling
218
+ - [x] T022 [P] Verify TypeScript compilation with strict mode: yarn build
219
+ - [x] T023 Test all user stories end-to-end following quickstart.md validation scenarios
220
+ - File copy with explicit --env and --service flags
221
+ - Directory copy with -r flag
222
+ - Interactive service selection (no --service flag)
223
+ - Interactive environment selection (no --env flag)
224
+ - Production confirmation prompt and cancellation
225
+ - Error handling for missing local path
226
+ - Error handling for directory without -r flag
227
+ - Error handling for invalid service
228
+ - Error handling for invalid environment
229
+
230
+ - [x] T024 Final verification: Install globally and test from different directory
231
+ - Run: yarn build:install
232
+ - Navigate to different directory: cd ~/
233
+ - Test command: hsh cloud scp [test scenarios from T023]
234
+ - Verify all functionality works from any directory
235
+
236
+ ---
237
+
238
+ ## Dependencies & Execution Order
239
+
240
+ ### Phase Dependencies
241
+
242
+ - **Setup (Phase 1)**: No dependencies - verification only
243
+ - **Foundational (Phase 2)**: Depends on Setup - adds required types to src/types/index.ts
244
+ - **User Story 1 (Phase 3)**: Depends on Foundational - implements basic file copy with interactive prompts
245
+ - **User Story 2 (Phase 4)**: Depends on US1 complete - adds directory copy functionality
246
+ - **User Story 3 (Phase 5)**: Depends on US1 complete - adds production safety (can run in parallel with US2)
247
+ - **Polish (Phase 6)**: Depends on all user stories complete
248
+
249
+ ### User Story Dependencies
250
+
251
+ - **User Story 1 (P1)**: Foundation → Basic file copy → Interactive prompts → SCP execution
252
+ - BLOCKS: US2, US3 (they extend US1 functionality)
253
+
254
+ - **User Story 2 (P2)**: US1 → Directory detection → -r flag validation → Recursive copy
255
+ - Can run in parallel with US3 (different features)
256
+
257
+ - **User Story 3 (P3)**: US1 → Production detection → Confirmation prompt → Safe execution
258
+ - Can run in parallel with US2 (different features)
259
+
260
+ ### Within Each User Story
261
+
262
+ **User Story 1** (T007-T012):
263
+
264
+ - T007 (validateLocalPath) must complete first - foundational helper
265
+ - T008 (cloudScp main function) depends on T007
266
+ - T009 (export) depends on T008
267
+ - T010 (import) can run in parallel with T009 [P]
268
+ - T011 (register command) depends on T010
269
+ - T012 (build and test) depends on T011
270
+
271
+ **User Story 2** (T013-T016):
272
+
273
+ - T013 (add -r option) and T014 (directory detection) can run in parallel [P]
274
+ - T015 (update SCP command) depends on T014
275
+ - T016 (build and test) depends on T013, T014, T015
276
+
277
+ **User Story 3** (T017-T018):
278
+
279
+ - T017 (production confirmation) is single task
280
+ - T018 (build and test) depends on T017
281
+
282
+ ### Parallel Opportunities
283
+
284
+ **Phase 1 (Setup)**:
285
+
286
+ - T002 and T003 can run in parallel [P]
287
+
288
+ **Phase 2 (Foundational)**:
289
+
290
+ - T004, T005, T006 can all run in parallel [P] - different interfaces in same file
291
+
292
+ **Phase 3 (US1)**:
293
+
294
+ - T009 and T010 can run in parallel [P] - different files
295
+
296
+ **Phase 4 (US2)**:
297
+
298
+ - T013 and T014 can run in parallel [P] - different parts of implementation
299
+
300
+ **Phase 5 (US3)**:
301
+
302
+ - Can run in parallel with Phase 4 (US2) if two developers available
303
+
304
+ **Phase 6 (Polish)**:
305
+
306
+ - T019, T020, T021, T022 can all run in parallel [P] - different review areas
307
+
308
+ ---
309
+
310
+ ## Parallel Example: User Story 1
311
+
312
+ ```bash
313
+ # After Foundational phase completes:
314
+
315
+ # Launch T009 and T010 in parallel (different files):
316
+ Task A: "Export cloudScp function from src/commands/cloud.ts"
317
+ Task B: "Import cloudScp in src/hsh.ts"
318
+
319
+ # After both complete, continue with T011:
320
+ Task: "Register cloud scp subcommand in src/hsh.ts"
321
+ ```
322
+
323
+ ## Parallel Example: User Story 2 and 3
324
+
325
+ ```bash
326
+ # After US1 completes, with 2 developers:
327
+
328
+ # Developer A works on US2:
329
+ Task: "Add -r/--recursive option to cloud scp command"
330
+ Task: "Add directory detection logic to cloudScp()"
331
+ Task: "Update SCP command construction for recursive flag"
332
+
333
+ # Developer B works on US3 (in parallel):
334
+ Task: "Add production confirmation prompt to cloudScp()"
335
+ Task: "Build and test production confirmation"
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Implementation Strategy
341
+
342
+ ### MVP First (User Story 1 Only)
343
+
344
+ 1. ✅ Complete Phase 1: Setup (verify existing infrastructure)
345
+ 2. ✅ Complete Phase 2: Foundational (add SCP-specific types)
346
+ 3. ✅ Complete Phase 3: User Story 1 (basic file copy with interactive prompts)
347
+ 4. **STOP and VALIDATE**: Test file copying independently
348
+ 5. Ready for basic usage!
349
+
350
+ **MVP Deliverable**: Developers can copy single files to cloud instances using interactive service/environment selection
351
+
352
+ ### Incremental Delivery
353
+
354
+ 1. Foundation → US1 → **MVP Release** (basic file copy)
355
+ 2. US1 → US2 → **Enhanced Release** (add directory support)
356
+ 3. US2 → US3 → **Production Ready** (add production safety)
357
+ 4. US3 → Polish → **Final Release** (complete feature)
358
+
359
+ Each increment adds value without breaking previous functionality.
360
+
361
+ ### Parallel Team Strategy
362
+
363
+ With 2 developers:
364
+
365
+ 1. **Together**: Complete Setup + Foundational (quick - mostly verification)
366
+ 2. **Together**: Complete User Story 1 (foundation for both US2 and US3)
367
+ 3. **Split**:
368
+ - Developer A: User Story 2 (directory support)
369
+ - Developer B: User Story 3 (production safety)
370
+ 4. **Together**: Polish & validation
371
+
372
+ ---
373
+
374
+ ## Notes
375
+
376
+ ### Task Conventions
377
+
378
+ - [P] tasks = different files, no dependencies - can run in parallel
379
+ - [Story] label maps task to specific user story (US1, US2, US3)
380
+ - Each user story should be independently completable and testable
381
+ - Manual CLI testing approach (no automated test suite)
382
+
383
+ ### File Modifications Summary
384
+
385
+ - **src/types/index.ts**: Add ScpOptions, PathValidationResult interfaces
386
+ - **src/commands/cloud.ts**: Add validateLocalPath(), cloudScp() functions
387
+ - **src/hsh.ts**: Add cloud scp subcommand registration
388
+
389
+ ### Function Reuse
390
+
391
+ - ✅ validatePrivateKey() - from cloud.ts
392
+ - ✅ promptForService() - from cloud.ts
393
+ - ✅ promptForEnvironment() - from cloud.ts
394
+ - ✅ handleSSHError() - from cloud.ts
395
+ - ✅ readConfig() - from util.ts
396
+
397
+ ### Error Handling Layers
398
+
399
+ 1. Path validation (validateLocalPath)
400
+ 2. Configuration validation (service/environment existence)
401
+ 3. Recursive flag validation (directory requires -r)
402
+ 4. Production confirmation (explicit user consent)
403
+ 5. SSH/SCP execution errors (handleSSHError)
404
+
405
+ ### Testing Strategy
406
+
407
+ - Manual CLI testing following quickstart.md scenarios
408
+ - Test each user story independently before moving to next
409
+ - Regression test previous stories when adding new functionality
410
+ - End-to-end testing from different directories after global install
411
+
412
+ ---
413
+
414
+ ## Total Task Count: 24 tasks
415
+
416
+ **By Phase**:
417
+
418
+ - Phase 1 (Setup): 3 tasks
419
+ - Phase 2 (Foundational): 3 tasks
420
+ - Phase 3 (US1 - MVP): 6 tasks
421
+ - Phase 4 (US2): 4 tasks
422
+ - Phase 5 (US3): 2 tasks
423
+ - Phase 6 (Polish): 6 tasks
424
+
425
+ **By User Story**:
426
+
427
+ - User Story 1 (Quick File Deploy): 6 tasks
428
+ - User Story 2 (Directory Upload): 4 tasks
429
+ - User Story 3 (Interactive Service Selection / Production Safety): 2 tasks
430
+ - Infrastructure & Polish: 12 tasks
431
+
432
+ **Parallel Opportunities**: 11 tasks marked [P] can potentially run in parallel
433
+
434
+ **Suggested MVP Scope**: Phase 1 + Phase 2 + Phase 3 (12 tasks) = Basic file copy functionality
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { getPackageJson } from './util.js';
4
+ import { openIDE, refreshIdeReposCache } from './commands/ide/index.js';
5
+ import { addUrl, openUrlGroup, removeUrl, searchAndOpenUrl } from './commands/url.js';
6
+ import { initConfig } from './commands/init.js';
7
+
8
+ const packageJson = getPackageJson();
9
+
10
+ const program = new Command();
11
+
12
+ program.usage('<command> [options]');
13
+ program.version(packageJson.version);
14
+
15
+ program
16
+ .command('init')
17
+ .description('initialize ~/.ai/config.json (prompts for workingDirectory)')
18
+ .option('-w, --working-directory <path>', 'set workingDirectory without prompting')
19
+ .option('-f, --force', 'overwrite existing config without confirmation')
20
+ .action(async (options: { workingDirectory?: string; force?: boolean }) => {
21
+ await initConfig({ workingDirectory: options.workingDirectory, force: options.force });
22
+ });
23
+
24
+ const cursor = program.command('cursor').description('open project in Cursor');
25
+ cursor
26
+ .argument('[search]', 'optional search keyword for fuzzy search')
27
+ .action(async (search?: string) => {
28
+ await openIDE('cursor', search);
29
+ });
30
+ cursor
31
+ .command('refresh')
32
+ .description('refresh cached auto-discovered repositories (workingDirectory mode)')
33
+ .action(async () => {
34
+ await refreshIdeReposCache();
35
+ });
36
+
37
+ const claude = program.command('claude').description('open project in Claude');
38
+ claude
39
+ .argument('[search]', 'optional search keyword for fuzzy search')
40
+ .action(async (search?: string) => {
41
+ await openIDE('claude', search);
42
+ });
43
+ claude
44
+ .command('refresh')
45
+ .description('refresh cached auto-discovered repositories (workingDirectory mode)')
46
+ .action(async () => {
47
+ await refreshIdeReposCache();
48
+ });
49
+
50
+ // URL management commands
51
+ const urlCommand = program.command('url').description('URL bookmark management');
52
+
53
+ urlCommand
54
+ .command('add')
55
+ .description('Add a new URL bookmark')
56
+ .argument('<name>', 'Name of the URL bookmark')
57
+ .argument('<url>', 'URL to bookmark')
58
+ .action(async (name: string, url: string) => {
59
+ await addUrl(name, url);
60
+ });
61
+
62
+ urlCommand
63
+ .command('remove')
64
+ .description('Remove a URL bookmark')
65
+ .argument(
66
+ '[name]',
67
+ 'Name of the URL bookmark to remove (optional, will enter search mode if not provided)'
68
+ )
69
+ .action(async (name?: string) => {
70
+ await removeUrl(name);
71
+ });
72
+
73
+ urlCommand
74
+ .command('search')
75
+ .description('Search and open a URL bookmark in Chrome')
76
+ .option('--suppress', 'Auto-dismiss popups by simulating Enter key after 1s')
77
+ .action(async (options: { suppress?: boolean }) => {
78
+ await searchAndOpenUrl(options.suppress);
79
+ });
80
+
81
+ urlCommand
82
+ .command('group')
83
+ .description('Select and open a URL group in a new Chrome window')
84
+ .action(async () => {
85
+ await openUrlGroup();
86
+ });
87
+
88
+ program.parse();