@jaguilar87/gaia-ops 1.0.0

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