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,738 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Update agent context files with information from plan.md
4
+ #
5
+ # This script maintains AI agent context files by parsing feature specifications
6
+ # and updating agent-specific configuration files with project information.
7
+ #
8
+ # MAIN FUNCTIONS:
9
+ # 1. Environment Validation
10
+ # - Verifies git repository structure and branch information
11
+ # - Checks for required plan.md files and templates
12
+ # - Validates file permissions and accessibility
13
+ #
14
+ # 2. Plan Data Extraction
15
+ # - Parses plan.md files to extract project metadata
16
+ # - Identifies language/version, frameworks, databases, and project types
17
+ # - Handles missing or incomplete specification data gracefully
18
+ #
19
+ # 3. Agent File Management
20
+ # - Creates new agent context files from templates when needed
21
+ # - Updates existing agent files with new project information
22
+ # - Preserves manual additions and custom configurations
23
+ # - Supports multiple AI agent formats and directory structures
24
+ #
25
+ # 4. Content Generation
26
+ # - Generates language-specific build/test commands
27
+ # - Creates appropriate project directory structures
28
+ # - Updates technology stacks and recent changes sections
29
+ # - Maintains consistent formatting and timestamps
30
+ #
31
+ # 5. Multi-Agent Support
32
+ # - Handles agent-specific file paths and naming conventions
33
+ # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Kilo Code, Auggie CLI, or Amazon Q Developer CLI
34
+ # - Can update single agents or all existing agent files
35
+ # - Creates default Claude file if no agent files exist
36
+ #
37
+ # Usage: ./update-agent-context.sh [agent_type]
38
+ # Agent types: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|q
39
+ # Leave empty to update all existing agent files
40
+
41
+ set -e
42
+
43
+ # Enable strict error handling
44
+ set -u
45
+ set -o pipefail
46
+
47
+ #==============================================================================
48
+ # Configuration and Global Variables
49
+ #==============================================================================
50
+
51
+ # Get script directory and load common functions
52
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
53
+ source "$SCRIPT_DIR/common.sh"
54
+
55
+ # Get all paths and variables from common functions
56
+ eval $(get_feature_paths)
57
+
58
+ NEW_PLAN="$IMPL_PLAN" # Alias for compatibility with existing code
59
+ AGENT_TYPE="${1:-}"
60
+
61
+ # Agent-specific file paths
62
+ CLAUDE_FILE="$REPO_ROOT/CLAUDE.md"
63
+ GEMINI_FILE="$REPO_ROOT/GEMINI.md"
64
+ COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md"
65
+ CURSOR_FILE="$REPO_ROOT/.cursor/rules/specify-rules.mdc"
66
+ QWEN_FILE="$REPO_ROOT/QWEN.md"
67
+ AGENTS_FILE="$REPO_ROOT/AGENTS.md"
68
+ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
69
+ KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
70
+ AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
71
+ ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
72
+ CODEBUDDY_FILE="$REPO_ROOT/.codebuddy/rules/specify-rules.md"
73
+ Q_FILE="$REPO_ROOT/AGENTS.md"
74
+
75
+ # Template file
76
+ TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
77
+
78
+ # Global variables for parsed plan data
79
+ NEW_LANG=""
80
+ NEW_FRAMEWORK=""
81
+ NEW_DB=""
82
+ NEW_PROJECT_TYPE=""
83
+
84
+ #==============================================================================
85
+ # Utility Functions
86
+ #==============================================================================
87
+
88
+ log_info() {
89
+ echo "INFO: $1"
90
+ }
91
+
92
+ log_success() {
93
+ echo "✓ $1"
94
+ }
95
+
96
+ log_error() {
97
+ echo "ERROR: $1" >&2
98
+ }
99
+
100
+ log_warning() {
101
+ echo "WARNING: $1" >&2
102
+ }
103
+
104
+ # Cleanup function for temporary files
105
+ cleanup() {
106
+ local exit_code=$?
107
+ rm -f /tmp/agent_update_*_$$
108
+ rm -f /tmp/manual_additions_$$
109
+ exit $exit_code
110
+ }
111
+
112
+ # Set up cleanup trap
113
+ trap cleanup EXIT INT TERM
114
+
115
+ #==============================================================================
116
+ # Validation Functions
117
+ #==============================================================================
118
+
119
+ validate_environment() {
120
+ # Check if we have a current branch/feature (git or non-git)
121
+ if [[ -z "$CURRENT_BRANCH" ]]; then
122
+ log_error "Unable to determine current feature"
123
+ if [[ "$HAS_GIT" == "true" ]]; then
124
+ log_info "Make sure you're on a feature branch"
125
+ else
126
+ log_info "Set SPECIFY_FEATURE environment variable or create a feature first"
127
+ fi
128
+ exit 1
129
+ fi
130
+
131
+ # Check if plan.md exists
132
+ if [[ ! -f "$NEW_PLAN" ]]; then
133
+ log_error "No plan.md found at $NEW_PLAN"
134
+ log_info "Make sure you're working on a feature with a corresponding spec directory"
135
+ if [[ "$HAS_GIT" != "true" ]]; then
136
+ log_info "Use: export SPECIFY_FEATURE=your-feature-name or create a new feature first"
137
+ fi
138
+ exit 1
139
+ fi
140
+
141
+ # Check if template exists (needed for new files)
142
+ if [[ ! -f "$TEMPLATE_FILE" ]]; then
143
+ log_warning "Template file not found at $TEMPLATE_FILE"
144
+ log_warning "Creating new agent files will fail"
145
+ fi
146
+ }
147
+
148
+ #==============================================================================
149
+ # Plan Parsing Functions
150
+ #==============================================================================
151
+
152
+ extract_plan_field() {
153
+ local field_pattern="$1"
154
+ local plan_file="$2"
155
+
156
+ grep "^\*\*${field_pattern}\*\*: " "$plan_file" 2>/dev/null | \
157
+ head -1 | \
158
+ sed "s|^\*\*${field_pattern}\*\*: ||" | \
159
+ sed 's/^[ \t]*//;s/[ \t]*$//' | \
160
+ grep -v "NEEDS CLARIFICATION" | \
161
+ grep -v "^N/A$" || echo ""
162
+ }
163
+
164
+ parse_plan_data() {
165
+ local plan_file="$1"
166
+
167
+ if [[ ! -f "$plan_file" ]]; then
168
+ log_error "Plan file not found: $plan_file"
169
+ return 1
170
+ fi
171
+
172
+ if [[ ! -r "$plan_file" ]]; then
173
+ log_error "Plan file is not readable: $plan_file"
174
+ return 1
175
+ fi
176
+
177
+ log_info "Parsing plan data from $plan_file"
178
+
179
+ NEW_LANG=$(extract_plan_field "Language/Version" "$plan_file")
180
+ NEW_FRAMEWORK=$(extract_plan_field "Primary Dependencies" "$plan_file")
181
+ NEW_DB=$(extract_plan_field "Storage" "$plan_file")
182
+ NEW_PROJECT_TYPE=$(extract_plan_field "Project Type" "$plan_file")
183
+
184
+ # Log what we found
185
+ if [[ -n "$NEW_LANG" ]]; then
186
+ log_info "Found language: $NEW_LANG"
187
+ else
188
+ log_warning "No language information found in plan"
189
+ fi
190
+
191
+ if [[ -n "$NEW_FRAMEWORK" ]]; then
192
+ log_info "Found framework: $NEW_FRAMEWORK"
193
+ fi
194
+
195
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
196
+ log_info "Found database: $NEW_DB"
197
+ fi
198
+
199
+ if [[ -n "$NEW_PROJECT_TYPE" ]]; then
200
+ log_info "Found project type: $NEW_PROJECT_TYPE"
201
+ fi
202
+ }
203
+
204
+ format_technology_stack() {
205
+ local lang="$1"
206
+ local framework="$2"
207
+ local parts=()
208
+
209
+ # Add non-empty parts
210
+ [[ -n "$lang" && "$lang" != "NEEDS CLARIFICATION" ]] && parts+=("$lang")
211
+ [[ -n "$framework" && "$framework" != "NEEDS CLARIFICATION" && "$framework" != "N/A" ]] && parts+=("$framework")
212
+
213
+ # Join with proper formatting
214
+ if [[ ${#parts[@]} -eq 0 ]]; then
215
+ echo ""
216
+ elif [[ ${#parts[@]} -eq 1 ]]; then
217
+ echo "${parts[0]}"
218
+ else
219
+ # Join multiple parts with " + "
220
+ local result="${parts[0]}"
221
+ for ((i=1; i<${#parts[@]}; i++)); do
222
+ result="$result + ${parts[i]}"
223
+ done
224
+ echo "$result"
225
+ fi
226
+ }
227
+
228
+ #==============================================================================
229
+ # Template and Content Generation Functions
230
+ #==============================================================================
231
+
232
+ get_project_structure() {
233
+ local project_type="$1"
234
+
235
+ if [[ "$project_type" == *"web"* ]]; then
236
+ echo "backend/\\nfrontend/\\ntests/"
237
+ else
238
+ echo "src/\\ntests/"
239
+ fi
240
+ }
241
+
242
+ get_commands_for_language() {
243
+ local lang="$1"
244
+
245
+ case "$lang" in
246
+ *"Python"*)
247
+ echo "cd src && pytest && ruff check ."
248
+ ;;
249
+ *"Rust"*)
250
+ echo "cargo test && cargo clippy"
251
+ ;;
252
+ *"JavaScript"*|*"TypeScript"*)
253
+ echo "npm test && npm run lint"
254
+ ;;
255
+ *)
256
+ echo "# Add commands for $lang"
257
+ ;;
258
+ esac
259
+ }
260
+
261
+ get_language_conventions() {
262
+ local lang="$1"
263
+ echo "$lang: Follow standard conventions"
264
+ }
265
+
266
+ create_new_agent_file() {
267
+ local target_file="$1"
268
+ local temp_file="$2"
269
+ local project_name="$3"
270
+ local current_date="$4"
271
+
272
+ if [[ ! -f "$TEMPLATE_FILE" ]]; then
273
+ log_error "Template not found at $TEMPLATE_FILE"
274
+ return 1
275
+ fi
276
+
277
+ if [[ ! -r "$TEMPLATE_FILE" ]]; then
278
+ log_error "Template file is not readable: $TEMPLATE_FILE"
279
+ return 1
280
+ fi
281
+
282
+ log_info "Creating new agent context file from template..."
283
+
284
+ if ! cp "$TEMPLATE_FILE" "$temp_file"; then
285
+ log_error "Failed to copy template file"
286
+ return 1
287
+ fi
288
+
289
+ # Replace template placeholders
290
+ local project_structure
291
+ project_structure=$(get_project_structure "$NEW_PROJECT_TYPE")
292
+
293
+ local commands
294
+ commands=$(get_commands_for_language "$NEW_LANG")
295
+
296
+ local language_conventions
297
+ language_conventions=$(get_language_conventions "$NEW_LANG")
298
+
299
+ # Perform substitutions with error checking using safer approach
300
+ # Escape special characters for sed by using a different delimiter or escaping
301
+ local escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
302
+ local escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
303
+ local escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')
304
+
305
+ # Build technology stack and recent change strings conditionally
306
+ local tech_stack
307
+ if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
308
+ tech_stack="- $escaped_lang + $escaped_framework ($escaped_branch)"
309
+ elif [[ -n "$escaped_lang" ]]; then
310
+ tech_stack="- $escaped_lang ($escaped_branch)"
311
+ elif [[ -n "$escaped_framework" ]]; then
312
+ tech_stack="- $escaped_framework ($escaped_branch)"
313
+ else
314
+ tech_stack="- ($escaped_branch)"
315
+ fi
316
+
317
+ local recent_change
318
+ if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
319
+ recent_change="- $escaped_branch: Added $escaped_lang + $escaped_framework"
320
+ elif [[ -n "$escaped_lang" ]]; then
321
+ recent_change="- $escaped_branch: Added $escaped_lang"
322
+ elif [[ -n "$escaped_framework" ]]; then
323
+ recent_change="- $escaped_branch: Added $escaped_framework"
324
+ else
325
+ recent_change="- $escaped_branch: Added"
326
+ fi
327
+
328
+ local substitutions=(
329
+ "s|\[PROJECT NAME\]|$project_name|"
330
+ "s|\[DATE\]|$current_date|"
331
+ "s|\[EXTRACTED FROM ALL PLAN.MD FILES\]|$tech_stack|"
332
+ "s|\[ACTUAL STRUCTURE FROM PLANS\]|$project_structure|g"
333
+ "s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$commands|"
334
+ "s|\[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE\]|$language_conventions|"
335
+ "s|\[LAST 3 FEATURES AND WHAT THEY ADDED\]|$recent_change|"
336
+ )
337
+
338
+ for substitution in "${substitutions[@]}"; do
339
+ if ! sed -i.bak -e "$substitution" "$temp_file"; then
340
+ log_error "Failed to perform substitution: $substitution"
341
+ rm -f "$temp_file" "$temp_file.bak"
342
+ return 1
343
+ fi
344
+ done
345
+
346
+ # Convert \n sequences to actual newlines
347
+ newline=$(printf '\n')
348
+ sed -i.bak2 "s/\\\\n/${newline}/g" "$temp_file"
349
+
350
+ # Clean up backup files
351
+ rm -f "$temp_file.bak" "$temp_file.bak2"
352
+
353
+ return 0
354
+ }
355
+
356
+
357
+
358
+
359
+ update_existing_agent_file() {
360
+ local target_file="$1"
361
+ local current_date="$2"
362
+
363
+ log_info "Updating existing agent context file..."
364
+
365
+ # Use a single temporary file for atomic update
366
+ local temp_file
367
+ temp_file=$(mktemp) || {
368
+ log_error "Failed to create temporary file"
369
+ return 1
370
+ }
371
+
372
+ # Process the file in one pass
373
+ local tech_stack=$(format_technology_stack "$NEW_LANG" "$NEW_FRAMEWORK")
374
+ local new_tech_entries=()
375
+ local new_change_entry=""
376
+
377
+ # Prepare new technology entries
378
+ if [[ -n "$tech_stack" ]] && ! grep -q "$tech_stack" "$target_file"; then
379
+ new_tech_entries+=("- $tech_stack ($CURRENT_BRANCH)")
380
+ fi
381
+
382
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]] && ! grep -q "$NEW_DB" "$target_file"; then
383
+ new_tech_entries+=("- $NEW_DB ($CURRENT_BRANCH)")
384
+ fi
385
+
386
+ # Prepare new change entry
387
+ if [[ -n "$tech_stack" ]]; then
388
+ new_change_entry="- $CURRENT_BRANCH: Added $tech_stack"
389
+ elif [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]]; then
390
+ new_change_entry="- $CURRENT_BRANCH: Added $NEW_DB"
391
+ fi
392
+
393
+ # Process file line by line
394
+ local in_tech_section=false
395
+ local in_changes_section=false
396
+ local tech_entries_added=false
397
+ local changes_entries_added=false
398
+ local existing_changes_count=0
399
+
400
+ while IFS= read -r line || [[ -n "$line" ]]; do
401
+ # Handle Active Technologies section
402
+ if [[ "$line" == "## Active Technologies" ]]; then
403
+ echo "$line" >> "$temp_file"
404
+ in_tech_section=true
405
+ continue
406
+ elif [[ $in_tech_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
407
+ # Add new tech entries before closing the section
408
+ if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
409
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
410
+ tech_entries_added=true
411
+ fi
412
+ echo "$line" >> "$temp_file"
413
+ in_tech_section=false
414
+ continue
415
+ elif [[ $in_tech_section == true ]] && [[ -z "$line" ]]; then
416
+ # Add new tech entries before empty line in tech section
417
+ if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
418
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
419
+ tech_entries_added=true
420
+ fi
421
+ echo "$line" >> "$temp_file"
422
+ continue
423
+ fi
424
+
425
+ # Handle Recent Changes section
426
+ if [[ "$line" == "## Recent Changes" ]]; then
427
+ echo "$line" >> "$temp_file"
428
+ # Add new change entry right after the heading
429
+ if [[ -n "$new_change_entry" ]]; then
430
+ echo "$new_change_entry" >> "$temp_file"
431
+ fi
432
+ in_changes_section=true
433
+ changes_entries_added=true
434
+ continue
435
+ elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
436
+ echo "$line" >> "$temp_file"
437
+ in_changes_section=false
438
+ continue
439
+ elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
440
+ # Keep only first 2 existing changes
441
+ if [[ $existing_changes_count -lt 2 ]]; then
442
+ echo "$line" >> "$temp_file"
443
+ ((existing_changes_count++))
444
+ fi
445
+ continue
446
+ fi
447
+
448
+ # Update timestamp
449
+ if [[ "$line" =~ \*\*Last\ updated\*\*:.*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then
450
+ echo "$line" | sed "s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/$current_date/" >> "$temp_file"
451
+ else
452
+ echo "$line" >> "$temp_file"
453
+ fi
454
+ done < "$target_file"
455
+
456
+ # Post-loop check: if we're still in the Active Technologies section and haven't added new entries
457
+ if [[ $in_tech_section == true ]] && [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
458
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
459
+ fi
460
+
461
+ # Move temp file to target atomically
462
+ if ! mv "$temp_file" "$target_file"; then
463
+ log_error "Failed to update target file"
464
+ rm -f "$temp_file"
465
+ return 1
466
+ fi
467
+
468
+ return 0
469
+ }
470
+ #==============================================================================
471
+ # Main Agent File Update Function
472
+ #==============================================================================
473
+
474
+ update_agent_file() {
475
+ local target_file="$1"
476
+ local agent_name="$2"
477
+
478
+ if [[ -z "$target_file" ]] || [[ -z "$agent_name" ]]; then
479
+ log_error "update_agent_file requires target_file and agent_name parameters"
480
+ return 1
481
+ fi
482
+
483
+ log_info "Updating $agent_name context file: $target_file"
484
+
485
+ local project_name
486
+ project_name=$(basename "$REPO_ROOT")
487
+ local current_date
488
+ current_date=$(date +%Y-%m-%d)
489
+
490
+ # Create directory if it doesn't exist
491
+ local target_dir
492
+ target_dir=$(dirname "$target_file")
493
+ if [[ ! -d "$target_dir" ]]; then
494
+ if ! mkdir -p "$target_dir"; then
495
+ log_error "Failed to create directory: $target_dir"
496
+ return 1
497
+ fi
498
+ fi
499
+
500
+ if [[ ! -f "$target_file" ]]; then
501
+ # Create new file from template
502
+ local temp_file
503
+ temp_file=$(mktemp) || {
504
+ log_error "Failed to create temporary file"
505
+ return 1
506
+ }
507
+
508
+ if create_new_agent_file "$target_file" "$temp_file" "$project_name" "$current_date"; then
509
+ if mv "$temp_file" "$target_file"; then
510
+ log_success "Created new $agent_name context file"
511
+ else
512
+ log_error "Failed to move temporary file to $target_file"
513
+ rm -f "$temp_file"
514
+ return 1
515
+ fi
516
+ else
517
+ log_error "Failed to create new agent file"
518
+ rm -f "$temp_file"
519
+ return 1
520
+ fi
521
+ else
522
+ # Update existing file
523
+ if [[ ! -r "$target_file" ]]; then
524
+ log_error "Cannot read existing file: $target_file"
525
+ return 1
526
+ fi
527
+
528
+ if [[ ! -w "$target_file" ]]; then
529
+ log_error "Cannot write to existing file: $target_file"
530
+ return 1
531
+ fi
532
+
533
+ if update_existing_agent_file "$target_file" "$current_date"; then
534
+ log_success "Updated existing $agent_name context file"
535
+ else
536
+ log_error "Failed to update existing agent file"
537
+ return 1
538
+ fi
539
+ fi
540
+
541
+ return 0
542
+ }
543
+
544
+ #==============================================================================
545
+ # Agent Selection and Processing
546
+ #==============================================================================
547
+
548
+ update_specific_agent() {
549
+ local agent_type="$1"
550
+
551
+ case "$agent_type" in
552
+ claude)
553
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
554
+ ;;
555
+ gemini)
556
+ update_agent_file "$GEMINI_FILE" "Gemini CLI"
557
+ ;;
558
+ copilot)
559
+ update_agent_file "$COPILOT_FILE" "GitHub Copilot"
560
+ ;;
561
+ cursor)
562
+ update_agent_file "$CURSOR_FILE" "Cursor IDE"
563
+ ;;
564
+ qwen)
565
+ update_agent_file "$QWEN_FILE" "Qwen Code"
566
+ ;;
567
+ opencode)
568
+ update_agent_file "$AGENTS_FILE" "opencode"
569
+ ;;
570
+ codex)
571
+ update_agent_file "$AGENTS_FILE" "Codex CLI"
572
+ ;;
573
+ windsurf)
574
+ update_agent_file "$WINDSURF_FILE" "Windsurf"
575
+ ;;
576
+ kilocode)
577
+ update_agent_file "$KILOCODE_FILE" "Kilo Code"
578
+ ;;
579
+ auggie)
580
+ update_agent_file "$AUGGIE_FILE" "Auggie CLI"
581
+ ;;
582
+ roo)
583
+ update_agent_file "$ROO_FILE" "Roo Code"
584
+ ;;
585
+ codebuddy)
586
+ update_agent_file "$CODEBUDDY_FILE" "CodeBuddy"
587
+ ;;
588
+ q)
589
+ update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
590
+ ;;
591
+ *)
592
+ log_error "Unknown agent type '$agent_type'"
593
+ log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q"
594
+ exit 1
595
+ ;;
596
+ esac
597
+ }
598
+
599
+ update_all_existing_agents() {
600
+ local found_agent=false
601
+
602
+ # Check each possible agent file and update if it exists
603
+ if [[ -f "$CLAUDE_FILE" ]]; then
604
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
605
+ found_agent=true
606
+ fi
607
+
608
+ if [[ -f "$GEMINI_FILE" ]]; then
609
+ update_agent_file "$GEMINI_FILE" "Gemini CLI"
610
+ found_agent=true
611
+ fi
612
+
613
+ if [[ -f "$COPILOT_FILE" ]]; then
614
+ update_agent_file "$COPILOT_FILE" "GitHub Copilot"
615
+ found_agent=true
616
+ fi
617
+
618
+ if [[ -f "$CURSOR_FILE" ]]; then
619
+ update_agent_file "$CURSOR_FILE" "Cursor IDE"
620
+ found_agent=true
621
+ fi
622
+
623
+ if [[ -f "$QWEN_FILE" ]]; then
624
+ update_agent_file "$QWEN_FILE" "Qwen Code"
625
+ found_agent=true
626
+ fi
627
+
628
+ if [[ -f "$AGENTS_FILE" ]]; then
629
+ update_agent_file "$AGENTS_FILE" "Codex/opencode"
630
+ found_agent=true
631
+ fi
632
+
633
+ if [[ -f "$WINDSURF_FILE" ]]; then
634
+ update_agent_file "$WINDSURF_FILE" "Windsurf"
635
+ found_agent=true
636
+ fi
637
+
638
+ if [[ -f "$KILOCODE_FILE" ]]; then
639
+ update_agent_file "$KILOCODE_FILE" "Kilo Code"
640
+ found_agent=true
641
+ fi
642
+
643
+ if [[ -f "$AUGGIE_FILE" ]]; then
644
+ update_agent_file "$AUGGIE_FILE" "Auggie CLI"
645
+ found_agent=true
646
+ fi
647
+
648
+ if [[ -f "$ROO_FILE" ]]; then
649
+ update_agent_file "$ROO_FILE" "Roo Code"
650
+ found_agent=true
651
+ fi
652
+
653
+ if [[ -f "$CODEBUDDY_FILE" ]]; then
654
+ update_agent_file "$CODEBUDDY_FILE" "CodeBuddy"
655
+ found_agent=true
656
+ fi
657
+
658
+ if [[ -f "$Q_FILE" ]]; then
659
+ update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
660
+ found_agent=true
661
+ fi
662
+
663
+ # If no agent files exist, create a default Claude file
664
+ if [[ "$found_agent" == false ]]; then
665
+ log_info "No existing agent files found, creating default Claude file..."
666
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
667
+ fi
668
+ }
669
+ print_summary() {
670
+ echo
671
+ log_info "Summary of changes:"
672
+
673
+ if [[ -n "$NEW_LANG" ]]; then
674
+ echo " - Added language: $NEW_LANG"
675
+ fi
676
+
677
+ if [[ -n "$NEW_FRAMEWORK" ]]; then
678
+ echo " - Added framework: $NEW_FRAMEWORK"
679
+ fi
680
+
681
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
682
+ echo " - Added database: $NEW_DB"
683
+ fi
684
+
685
+ echo
686
+
687
+ log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|codebuddy|q]"
688
+ }
689
+
690
+ #==============================================================================
691
+ # Main Execution
692
+ #==============================================================================
693
+
694
+ main() {
695
+ # Validate environment before proceeding
696
+ validate_environment
697
+
698
+ log_info "=== Updating agent context files for feature $CURRENT_BRANCH ==="
699
+
700
+ # Parse the plan file to extract project information
701
+ if ! parse_plan_data "$NEW_PLAN"; then
702
+ log_error "Failed to parse plan data"
703
+ exit 1
704
+ fi
705
+
706
+ # Process based on agent type argument
707
+ local success=true
708
+
709
+ if [[ -z "$AGENT_TYPE" ]]; then
710
+ # No specific agent provided - update all existing agent files
711
+ log_info "No agent specified, updating all existing agent files..."
712
+ if ! update_all_existing_agents; then
713
+ success=false
714
+ fi
715
+ else
716
+ # Specific agent provided - update only that agent
717
+ log_info "Updating specific agent: $AGENT_TYPE"
718
+ if ! update_specific_agent "$AGENT_TYPE"; then
719
+ success=false
720
+ fi
721
+ fi
722
+
723
+ # Print summary
724
+ print_summary
725
+
726
+ if [[ "$success" == true ]]; then
727
+ log_success "Agent context update completed successfully"
728
+ exit 0
729
+ else
730
+ log_error "Agent context update completed with errors"
731
+ exit 1
732
+ fi
733
+ }
734
+
735
+ # Execute main function if script is run directly
736
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
737
+ main "$@"
738
+ fi