cc-devflow 1.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.
- package/.claude/CLAUDE.md +83 -0
- package/.claude/agents/architecture-designer.md +443 -0
- package/.claude/agents/bug-analyzer.md +382 -0
- package/.claude/agents/checklist-agent.md +175 -0
- package/.claude/agents/clarify-analyst.md +50 -0
- package/.claude/agents/code-reviewer.md +71 -0
- package/.claude/agents/codex-analyzer.md +39 -0
- package/.claude/agents/compatibility-checker.md +580 -0
- package/.claude/agents/consistency-checker.md +532 -0
- package/.claude/agents/impact-analyzer.md +441 -0
- package/.claude/agents/planner.md +230 -0
- package/.claude/agents/prd-writer.md +320 -0
- package/.claude/agents/project-guidelines-generator.md +1329 -0
- package/.claude/agents/qa-tester.md +313 -0
- package/.claude/agents/release-manager.md +295 -0
- package/.claude/agents/security-reviewer.md +314 -0
- package/.claude/agents/style-guide-generator.md +458 -0
- package/.claude/agents/tech-architect.md +516 -0
- package/.claude/agents/ui-designer.md +485 -0
- package/.claude/commands/code-review-high.md +58 -0
- package/.claude/commands/core-architecture.md +429 -0
- package/.claude/commands/core-guidelines.md +486 -0
- package/.claude/commands/core-roadmap.md +439 -0
- package/.claude/commands/core-style.md +293 -0
- package/.claude/commands/flow-archive.md +245 -0
- package/.claude/commands/flow-checklist.md +260 -0
- package/.claude/commands/flow-clarify.md +136 -0
- package/.claude/commands/flow-constitution.md +82 -0
- package/.claude/commands/flow-dev.md +134 -0
- package/.claude/commands/flow-epic.md +150 -0
- package/.claude/commands/flow-fix.md +104 -0
- package/.claude/commands/flow-ideate.md +214 -0
- package/.claude/commands/flow-init.md +313 -0
- package/.claude/commands/flow-new.md +394 -0
- package/.claude/commands/flow-prd.md +131 -0
- package/.claude/commands/flow-qa.md +93 -0
- package/.claude/commands/flow-release.md +92 -0
- package/.claude/commands/flow-restart.md +98 -0
- package/.claude/commands/flow-status.md +64 -0
- package/.claude/commands/flow-tech.md +142 -0
- package/.claude/commands/flow-ui.md +189 -0
- package/.claude/commands/flow-update.md +111 -0
- package/.claude/commands/flow-upgrade.md +115 -0
- package/.claude/commands/flow-verify.md +96 -0
- package/.claude/commands/problem-analyzer.md +60 -0
- package/.claude/config/quality-rules.yml +161 -0
- package/.claude/docs/SPEC_KIT_CONSTITUTION_ANALYSIS.md +426 -0
- package/.claude/docs/design/consistency-conflict-detection-algorithms.md +658 -0
- package/.claude/docs/design/intent-driven-input-design.md +380 -0
- package/.claude/docs/design/prd-version-management-design.md +437 -0
- package/.claude/docs/guides/INIT_TROUBLESHOOTING.md +117 -0
- package/.claude/docs/guides/NEW_TROUBLESHOOTING.md +151 -0
- package/.claude/docs/guides/ROADMAP_TROUBLESHOOTING.md +188 -0
- package/.claude/docs/guides/TASK_COMPLETION_MARKING.md +338 -0
- package/.claude/docs/templates/ARCHITECTURE_TEMPLATE.md +633 -0
- package/.claude/docs/templates/BACKLOG_TEMPLATE.md +261 -0
- package/.claude/docs/templates/CHECKLIST_TEMPLATE.md +52 -0
- package/.claude/docs/templates/CLARIFICATION_REPORT_TEMPLATE.md +206 -0
- package/.claude/docs/templates/CODE_REVIEW_TEMPLATE.md +71 -0
- package/.claude/docs/templates/EPIC_TEMPLATE.md +805 -0
- package/.claude/docs/templates/INIT_FLOW_TEMPLATE.md +213 -0
- package/.claude/docs/templates/INTENT_CLARIFICATION_TEMPLATE.md +57 -0
- package/.claude/docs/templates/NEW_ORCHESTRATION_TEMPLATE.md +148 -0
- package/.claude/docs/templates/PRD_TEMPLATE.md +562 -0
- package/.claude/docs/templates/RESEARCH_TEMPLATE.md +276 -0
- package/.claude/docs/templates/REVIEW-HIGH.md +57 -0
- package/.claude/docs/templates/ROADMAP_DIALOGUE_TEMPLATE.md +198 -0
- package/.claude/docs/templates/ROADMAP_TEMPLATE.md +310 -0
- package/.claude/docs/templates/STYLE_TEMPLATE.md +1266 -0
- package/.claude/docs/templates/TASKS_TEMPLATE.md +523 -0
- package/.claude/docs/templates/TECH_DESIGN_TEMPLATE.md +1019 -0
- package/.claude/docs/templates/UI_PROTOTYPE_TEMPLATE.md +1436 -0
- package/.claude/guides/agent-guides/agent-coordination-guide.md +459 -0
- package/.claude/guides/project-guidelines-system.md +463 -0
- package/.claude/guides/technical-guides/datetime-handling-guide.md +563 -0
- package/.claude/guides/technical-guides/git-github-guide.md +642 -0
- package/.claude/guides/technical-guides/test-execution-guide.md +618 -0
- package/.claude/guides/workflow-guides/bug-fix-orchestrator.md +217 -0
- package/.claude/guides/workflow-guides/flow-orchestrator.md +282 -0
- package/.claude/hooks/checklist-gate.js +397 -0
- package/.claude/hooks/error-handling-reminder.sh +12 -0
- package/.claude/hooks/error-handling-reminder.ts +459 -0
- package/.claude/hooks/post-tool-use-tracker.sh +280 -0
- package/.claude/hooks/pre-tool-use-guardrail.sh +36 -0
- package/.claude/hooks/pre-tool-use-guardrail.ts +342 -0
- package/.claude/hooks/skill-activation-prompt.sh +36 -0
- package/.claude/hooks/skill-activation-prompt.ts +214 -0
- package/.claude/hooks/state/skills-used-test-guard.json +3 -0
- package/.claude/rules/devflow-conventions.md +305 -0
- package/.claude/rules/project-constitution.md +748 -0
- package/.claude/schemas/constitution.schema.json +43 -0
- package/.claude/scripts/analyze-upgrade-impact.sh +200 -0
- package/.claude/scripts/archive-requirement.sh +351 -0
- package/.claude/scripts/calculate-checklist-completion.sh +243 -0
- package/.claude/scripts/calculate-quarter.sh +206 -0
- package/.claude/scripts/check-dependencies.sh +409 -0
- package/.claude/scripts/check-prerequisites.sh +232 -0
- package/.claude/scripts/check-task-status.sh +264 -0
- package/.claude/scripts/checklist-errors.sh +131 -0
- package/.claude/scripts/common.sh +570 -0
- package/.claude/scripts/consolidate-research.sh +182 -0
- package/.claude/scripts/create-requirement.sh +426 -0
- package/.claude/scripts/export-contracts.sh +117 -0
- package/.claude/scripts/extract-data-model.sh +78 -0
- package/.claude/scripts/generate-clarification-questions.sh +377 -0
- package/.claude/scripts/generate-clarification-report.sh +463 -0
- package/.claude/scripts/generate-quickstart.sh +146 -0
- package/.claude/scripts/generate-research-tasks.sh +157 -0
- package/.claude/scripts/generate-status-report.sh +523 -0
- package/.claude/scripts/generate-tech-analysis.sh +46 -0
- package/.claude/scripts/locate-requirement-in-roadmap.sh +233 -0
- package/.claude/scripts/manage-constitution.sh +602 -0
- package/.claude/scripts/mark-task-complete.sh +198 -0
- package/.claude/scripts/populate-research-tasks.sh +259 -0
- package/.claude/scripts/recover-workflow.sh +460 -0
- package/.claude/scripts/run-clarify-scan.sh +601 -0
- package/.claude/scripts/run-high-review.sh +62 -0
- package/.claude/scripts/run-problem-analysis.sh +68 -0
- package/.claude/scripts/setup-epic.sh +173 -0
- package/.claude/scripts/sync-roadmap-progress.sh +300 -0
- package/.claude/scripts/sync-task-marks.sh +199 -0
- package/.claude/scripts/test-clarify-scan.sh +515 -0
- package/.claude/scripts/update-agent-context.sh +806 -0
- package/.claude/scripts/validate-constitution.sh +567 -0
- package/.claude/scripts/validate-hooks.sh +487 -0
- package/.claude/scripts/validate-research.sh +332 -0
- package/.claude/scripts/validate-scope-boundary.sh +493 -0
- package/.claude/scripts/verify-setup.sh +37 -0
- package/.claude/settings.json +76 -0
- package/.claude/skills/_reference-implementations/README.md +96 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/SKILL.md +302 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/architecture-overview.md +451 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/async-and-errors.md +307 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/complete-examples.md +638 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/configuration.md +275 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/database-patterns.md +224 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/middleware-guide.md +213 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/routing-and-controllers.md +756 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/sentry-and-monitoring.md +336 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/services-and-repositories.md +789 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/testing-guide.md +235 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/validation-patterns.md +754 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/SKILL.md +399 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/common-patterns.md +331 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/complete-examples.md +872 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/component-patterns.md +502 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/data-fetching.md +767 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/file-organization.md +502 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/loading-and-error-states.md +501 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/performance.md +406 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/routing-guide.md +364 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/styling-guide.md +428 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/typescript-standards.md +418 -0
- package/.claude/skills/cc-devflow-orchestrator/SKILL.md +229 -0
- package/.claude/skills/constitution-guardian/SKILL.md +306 -0
- package/.claude/skills/devflow-constitution-quick-ref/SKILL.md +374 -0
- package/.claude/skills/devflow-file-standards/SKILL.md +353 -0
- package/.claude/skills/devflow-tdd-enforcer/SKILL.md +192 -0
- package/.claude/skills/skill-developer/ADVANCED.md +197 -0
- package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +306 -0
- package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +152 -0
- package/.claude/skills/skill-developer/SKILL.md +426 -0
- package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +315 -0
- package/.claude/skills/skill-developer/TRIGGER_TYPES.md +305 -0
- package/.claude/skills/skill-developer/TROUBLESHOOTING.md +514 -0
- package/.claude/skills/skill-rules.json +213 -0
- package/.claude/tests/README.md +300 -0
- package/.claude/tests/TODO.md +69 -0
- package/.claude/tests/__pycache__/test_analyze_upgrade_impact.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_consolidate_research.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_export_contracts.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_extract_data_model.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_generate_quickstart.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_generate_research_tasks.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/constitution/run_all_constitution_tests.sh +111 -0
- package/.claude/tests/constitution/test_agent_assignment.sh +207 -0
- package/.claude/tests/constitution/test_article_coverage.sh +201 -0
- package/.claude/tests/constitution/test_template_completeness.sh +150 -0
- package/.claude/tests/constitution/test_version_consistency.sh +120 -0
- package/.claude/tests/fixtures/spec_delta_full.md +16 -0
- package/.claude/tests/fixtures/tasks_progress_sample.md +5 -0
- package/.claude/tests/run-all-tests.sh +229 -0
- package/.claude/tests/scripts/run.sh +30 -0
- package/.claude/tests/scripts/test-framework.sh +128 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh +511 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak +504 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak2 +505 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak3 +506 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak4 +507 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak5 +508 -0
- package/.claude/tests/scripts/test_check_task_status.sh +499 -0
- package/.claude/tests/scripts/test_common.sh +244 -0
- package/.claude/tests/scripts/test_generate_status_report.sh +71 -0
- package/.claude/tests/scripts/test_mark_task_complete.sh +441 -0
- package/.claude/tests/scripts/test_mark_task_complete.sh.backup +410 -0
- package/.claude/tests/scripts/test_recover_workflow.sh +304 -0
- package/.claude/tests/scripts/test_setup_epic.sh +437 -0
- package/.claude/tests/scripts/test_sync_task_marks.sh +196 -0
- package/.claude/tests/scripts/test_validate_constitution.sh +74 -0
- package/.claude/tests/scripts/test_validate_research.sh +462 -0
- package/.claude/tests/slugify.bats +82 -0
- package/.claude/tests/test-framework.sh +732 -0
- package/.claude/tests/test_analyze_upgrade_impact.py +34 -0
- package/.claude/tests/test_consolidate_research.py +48 -0
- package/.claude/tests/test_export_contracts.py +43 -0
- package/.claude/tests/test_extract_data_model.py +33 -0
- package/.claude/tests/test_generate_quickstart.py +50 -0
- package/.claude/tests/test_generate_research_tasks.py +52 -0
- package/.claude/tsc-cache/6e64f818-6398-49ca-8623-581a9af85c44/edited-files.log +1 -0
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +1 -0
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/edited-files.log +1 -0
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +1 -0
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/edited-files.log +1 -0
- package/CHANGELOG.md +507 -0
- package/LICENSE +21 -0
- package/README.md +534 -0
- package/README.zh-CN.md +530 -0
- package/bin/adapt.js +240 -0
- package/bin/cc-devflow-cli.js +185 -0
- package/bin/cc-devflow.js +78 -0
- package/config/adapters.yml +5 -0
- package/config/schema/adapters.schema.json +44 -0
- package/docs/CLAUDE.md +26 -0
- package/docs/commands/README.md +61 -0
- package/docs/commands/README.zh-CN.md +55 -0
- package/docs/commands/core-roadmap.md +106 -0
- package/docs/commands/core-roadmap.zh-CN.md +102 -0
- package/docs/commands/core-style.md +405 -0
- package/docs/commands/core-style.zh-CN.md +405 -0
- package/docs/commands/flow-init.md +134 -0
- package/docs/commands/flow-init.zh-CN.md +163 -0
- package/docs/commands/flow-new.md +274 -0
- package/docs/commands/flow-new.zh-CN.md +270 -0
- package/docs/guides/getting-started.md +204 -0
- package/docs/guides/getting-started.zh-CN.md +152 -0
- package/lib/adapters/adapter-interface.js +57 -0
- package/lib/adapters/claude-adapter.js +74 -0
- package/lib/adapters/codex-adapter.js +40 -0
- package/lib/adapters/config-validator.js +68 -0
- package/lib/adapters/logger.js +42 -0
- package/lib/adapters/registry.js +153 -0
- package/lib/compiler/CLAUDE.md +92 -0
- package/lib/compiler/__tests__/drift.test.js +215 -0
- package/lib/compiler/__tests__/errors.test.js +184 -0
- package/lib/compiler/__tests__/incremental.test.js +174 -0
- package/lib/compiler/__tests__/integration.test.js +174 -0
- package/lib/compiler/__tests__/manifest.test.js +233 -0
- package/lib/compiler/__tests__/parser.test.js +456 -0
- package/lib/compiler/__tests__/schemas.test.js +301 -0
- package/lib/compiler/__tests__/skills-registry.test.js +125 -0
- package/lib/compiler/__tests__/transformer.test.js +286 -0
- package/lib/compiler/emitters/antigravity-emitter.js +171 -0
- package/lib/compiler/emitters/base-emitter.js +73 -0
- package/lib/compiler/emitters/codex-emitter.js +52 -0
- package/lib/compiler/emitters/cursor-emitter.js +31 -0
- package/lib/compiler/emitters/index.js +50 -0
- package/lib/compiler/emitters/qwen-emitter.js +39 -0
- package/lib/compiler/errors.js +119 -0
- package/lib/compiler/index.js +256 -0
- package/lib/compiler/manifest.js +242 -0
- package/lib/compiler/parser.js +258 -0
- package/lib/compiler/platforms.js +113 -0
- package/lib/compiler/resource-copier.js +320 -0
- package/lib/compiler/rules-emitters/__tests__/antigravity-rules-emitter.test.js +191 -0
- package/lib/compiler/rules-emitters/__tests__/codex-rules-emitter.test.js +109 -0
- package/lib/compiler/rules-emitters/__tests__/cursor-rules-emitter.test.js +123 -0
- package/lib/compiler/rules-emitters/__tests__/qwen-rules-emitter.test.js +123 -0
- package/lib/compiler/rules-emitters/antigravity-rules-emitter.js +253 -0
- package/lib/compiler/rules-emitters/base-rules-emitter.js +83 -0
- package/lib/compiler/rules-emitters/codex-rules-emitter.js +116 -0
- package/lib/compiler/rules-emitters/cursor-rules-emitter.js +98 -0
- package/lib/compiler/rules-emitters/index.js +71 -0
- package/lib/compiler/rules-emitters/qwen-rules-emitter.js +70 -0
- package/lib/compiler/schemas.js +144 -0
- package/lib/compiler/skills-registry.js +225 -0
- package/lib/compiler/transformer.js +236 -0
- package/package.json +50 -0
|
@@ -0,0 +1,806 @@
|
|
|
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, Roo Code, CodeBuddy CLI, Amp, 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-agent|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
|
+
# Load shared helpers and derive repo metadata (avoid spec-kit context)
|
|
54
|
+
source "$SCRIPT_DIR/common.sh"
|
|
55
|
+
|
|
56
|
+
REPO_ROOT="$(get_repo_root)"
|
|
57
|
+
HAS_GIT="false"
|
|
58
|
+
if has_git; then
|
|
59
|
+
HAS_GIT="true"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
CURRENT_BRANCH="${DEVFLOW_BRANCH:-}"
|
|
63
|
+
if [[ -z "$CURRENT_BRANCH" && "$HAS_GIT" == "true" ]]; then
|
|
64
|
+
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || "")
|
|
65
|
+
fi
|
|
66
|
+
if [[ -z "$CURRENT_BRANCH" ]]; then
|
|
67
|
+
CURRENT_BRANCH="unknown-branch"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
NEW_PLAN="${DEVFLOW_CONTEXT_SOURCE:-${DEVFLOW_PLAN_PATH:-}}"
|
|
71
|
+
if [[ -z "$NEW_PLAN" && -f "$REPO_ROOT/devflow/ROADMAP.md" ]]; then
|
|
72
|
+
NEW_PLAN="$REPO_ROOT/devflow/ROADMAP.md"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
AGENT_TYPE="${1:-}"
|
|
76
|
+
AGENT_CONTEXT_TEMPLATE="${DEVFLOW_AGENT_CONTEXT_TEMPLATE:-}"
|
|
77
|
+
|
|
78
|
+
# Agent-specific file paths
|
|
79
|
+
CLAUDE_FILE="$REPO_ROOT/CLAUDE.md"
|
|
80
|
+
GEMINI_FILE="$REPO_ROOT/GEMINI.md"
|
|
81
|
+
COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md"
|
|
82
|
+
CURSOR_FILE="$REPO_ROOT/.cursor/rules/specify-rules.mdc"
|
|
83
|
+
QWEN_FILE="$REPO_ROOT/QWEN.md"
|
|
84
|
+
AGENTS_FILE="$REPO_ROOT/AGENTS.md"
|
|
85
|
+
WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
|
|
86
|
+
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
|
|
87
|
+
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
|
|
88
|
+
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
|
|
89
|
+
CODEBUDDY_FILE="$REPO_ROOT/CODEBUDDY.md"
|
|
90
|
+
AMP_FILE="$REPO_ROOT/AGENTS.md"
|
|
91
|
+
Q_FILE="$REPO_ROOT/AGENTS.md"
|
|
92
|
+
|
|
93
|
+
# Global variables for parsed plan data
|
|
94
|
+
NEW_LANG=""
|
|
95
|
+
NEW_FRAMEWORK=""
|
|
96
|
+
NEW_DB=""
|
|
97
|
+
NEW_PROJECT_TYPE=""
|
|
98
|
+
|
|
99
|
+
#==============================================================================
|
|
100
|
+
# Utility Functions
|
|
101
|
+
#==============================================================================
|
|
102
|
+
|
|
103
|
+
log_info() {
|
|
104
|
+
echo "INFO: $1"
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
log_success() {
|
|
108
|
+
echo "✓ $1"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
log_error() {
|
|
112
|
+
echo "ERROR: $1" >&2
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
log_warning() {
|
|
116
|
+
echo "WARNING: $1" >&2
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Cleanup function for temporary files
|
|
120
|
+
cleanup() {
|
|
121
|
+
local exit_code=$?
|
|
122
|
+
rm -f /tmp/agent_update_*_$$
|
|
123
|
+
rm -f /tmp/manual_additions_$$
|
|
124
|
+
exit $exit_code
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Set up cleanup trap
|
|
128
|
+
trap cleanup EXIT INT TERM
|
|
129
|
+
|
|
130
|
+
#==============================================================================
|
|
131
|
+
# Validation Functions
|
|
132
|
+
#==============================================================================
|
|
133
|
+
|
|
134
|
+
validate_environment() {
|
|
135
|
+
if [[ "$CURRENT_BRANCH" == "unknown-branch" ]]; then
|
|
136
|
+
log_warning "Unable to resolve current branch; context may lack feature-specific metadata."
|
|
137
|
+
if [[ "$HAS_GIT" == "false" ]]; then
|
|
138
|
+
log_info "Running outside git; set DEVFLOW_BRANCH to provide a stable branch name."
|
|
139
|
+
fi
|
|
140
|
+
else
|
|
141
|
+
log_info "Detected branch: $CURRENT_BRANCH"
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
if [[ -n "$NEW_PLAN" ]]; then
|
|
145
|
+
if [[ ! -f "$NEW_PLAN" ]]; then
|
|
146
|
+
log_warning "Plan file not found at $NEW_PLAN; context update will skip plan metadata."
|
|
147
|
+
fi
|
|
148
|
+
else
|
|
149
|
+
log_info "No plan source configured; plan-based metadata extraction disabled."
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
if [[ -n "$AGENT_CONTEXT_TEMPLATE" && ! -f "$AGENT_CONTEXT_TEMPLATE" ]]; then
|
|
153
|
+
log_warning "Custom agent context template '$AGENT_CONTEXT_TEMPLATE' was not found. Using embedded template."
|
|
154
|
+
fi
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#==============================================================================
|
|
158
|
+
# Plan Parsing Functions
|
|
159
|
+
#==============================================================================
|
|
160
|
+
|
|
161
|
+
extract_plan_field() {
|
|
162
|
+
local field_pattern="$1"
|
|
163
|
+
local plan_file="$2"
|
|
164
|
+
|
|
165
|
+
grep "^\*\*${field_pattern}\*\*: " "$plan_file" 2>/dev/null | \
|
|
166
|
+
head -1 | \
|
|
167
|
+
sed "s|^\*\*${field_pattern}\*\*: ||" | \
|
|
168
|
+
sed 's/^[ \t]*//;s/[ \t]*$//' | \
|
|
169
|
+
grep -v "NEEDS CLARIFICATION" | \
|
|
170
|
+
grep -v "^N/A$" || echo ""
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
parse_plan_data() {
|
|
174
|
+
local plan_file="$1"
|
|
175
|
+
|
|
176
|
+
if [[ -z "$plan_file" ]]; then
|
|
177
|
+
log_info "Skipping plan parsing (no plan source)."
|
|
178
|
+
return 0
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
if [[ ! -f "$plan_file" ]]; then
|
|
182
|
+
log_warning "Plan file not available: $plan_file. Skipping metadata extraction."
|
|
183
|
+
return 0
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
if [[ ! -r "$plan_file" ]]; then
|
|
187
|
+
log_warning "Plan file is not readable: $plan_file. Skipping metadata extraction."
|
|
188
|
+
return 0
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
log_info "Parsing plan data from $plan_file"
|
|
192
|
+
|
|
193
|
+
NEW_LANG=$(extract_plan_field "Language/Version" "$plan_file")
|
|
194
|
+
NEW_FRAMEWORK=$(extract_plan_field "Primary Dependencies" "$plan_file")
|
|
195
|
+
NEW_DB=$(extract_plan_field "Storage" "$plan_file")
|
|
196
|
+
NEW_PROJECT_TYPE=$(extract_plan_field "Project Type" "$plan_file")
|
|
197
|
+
|
|
198
|
+
# Log what we found
|
|
199
|
+
if [[ -n "$NEW_LANG" ]]; then
|
|
200
|
+
log_info "Found language: $NEW_LANG"
|
|
201
|
+
else
|
|
202
|
+
log_warning "No language information found in plan"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
if [[ -n "$NEW_FRAMEWORK" ]]; then
|
|
206
|
+
log_info "Found framework: $NEW_FRAMEWORK"
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
|
|
210
|
+
log_info "Found database: $NEW_DB"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
if [[ -n "$NEW_PROJECT_TYPE" ]]; then
|
|
214
|
+
log_info "Found project type: $NEW_PROJECT_TYPE"
|
|
215
|
+
fi
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
format_technology_stack() {
|
|
219
|
+
local lang="$1"
|
|
220
|
+
local framework="$2"
|
|
221
|
+
local parts=()
|
|
222
|
+
|
|
223
|
+
# Add non-empty parts
|
|
224
|
+
[[ -n "$lang" && "$lang" != "NEEDS CLARIFICATION" ]] && parts+=("$lang")
|
|
225
|
+
[[ -n "$framework" && "$framework" != "NEEDS CLARIFICATION" && "$framework" != "N/A" ]] && parts+=("$framework")
|
|
226
|
+
|
|
227
|
+
# Join with proper formatting
|
|
228
|
+
if [[ ${#parts[@]} -eq 0 ]]; then
|
|
229
|
+
echo ""
|
|
230
|
+
elif [[ ${#parts[@]} -eq 1 ]]; then
|
|
231
|
+
echo "${parts[0]}"
|
|
232
|
+
else
|
|
233
|
+
# Join multiple parts with " + "
|
|
234
|
+
local result="${parts[0]}"
|
|
235
|
+
for ((i=1; i<${#parts[@]}; i++)); do
|
|
236
|
+
result="$result + ${parts[i]}"
|
|
237
|
+
done
|
|
238
|
+
echo "$result"
|
|
239
|
+
fi
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#==============================================================================
|
|
243
|
+
# Template and Content Generation Functions
|
|
244
|
+
#==============================================================================
|
|
245
|
+
|
|
246
|
+
get_project_structure() {
|
|
247
|
+
local project_type="$1"
|
|
248
|
+
|
|
249
|
+
if [[ "$project_type" == *"web"* ]]; then
|
|
250
|
+
echo "backend/\\nfrontend/\\ntests/"
|
|
251
|
+
else
|
|
252
|
+
echo "src/\\ntests/"
|
|
253
|
+
fi
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
get_commands_for_language() {
|
|
257
|
+
local lang="$1"
|
|
258
|
+
|
|
259
|
+
case "$lang" in
|
|
260
|
+
*"Python"*)
|
|
261
|
+
echo "cd src && pytest && ruff check ."
|
|
262
|
+
;;
|
|
263
|
+
*"Rust"*)
|
|
264
|
+
echo "cargo test && cargo clippy"
|
|
265
|
+
;;
|
|
266
|
+
*"JavaScript"*|*"TypeScript"*)
|
|
267
|
+
echo "npm test \\&\\& npm run lint"
|
|
268
|
+
;;
|
|
269
|
+
*)
|
|
270
|
+
echo "# Add commands for $lang"
|
|
271
|
+
;;
|
|
272
|
+
esac
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
get_language_conventions() {
|
|
276
|
+
local lang="$1"
|
|
277
|
+
echo "$lang: Follow standard conventions"
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
create_new_agent_file() {
|
|
281
|
+
local target_file="$1"
|
|
282
|
+
local temp_file="$2"
|
|
283
|
+
local project_name="$3"
|
|
284
|
+
local current_date="$4"
|
|
285
|
+
|
|
286
|
+
local template_source="$AGENT_CONTEXT_TEMPLATE"
|
|
287
|
+
|
|
288
|
+
if [[ -n "$template_source" ]] && [[ -f "$template_source" ]]; then
|
|
289
|
+
log_info "Creating new agent context file from custom template..."
|
|
290
|
+
if ! cp "$template_source" "$temp_file"; then
|
|
291
|
+
log_error "Failed to copy custom template: $template_source"
|
|
292
|
+
return 1
|
|
293
|
+
fi
|
|
294
|
+
else
|
|
295
|
+
if [[ -n "$template_source" ]]; then
|
|
296
|
+
log_warning "Custom template '$template_source' is unavailable. Falling back to embedded template."
|
|
297
|
+
else
|
|
298
|
+
log_info "Creating new agent context file from embedded template."
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
cat <<'EOF' > "$temp_file"
|
|
302
|
+
# [PROJECT NAME] Agent Context
|
|
303
|
+
|
|
304
|
+
**Last updated**: [DATE]
|
|
305
|
+
|
|
306
|
+
## Active Technologies
|
|
307
|
+
[EXTRACTED FROM ALL PLAN.MD FILES]
|
|
308
|
+
|
|
309
|
+
## Expected Project Structure
|
|
310
|
+
[ACTUAL STRUCTURE FROM PLANS]
|
|
311
|
+
|
|
312
|
+
## Command Access Notes
|
|
313
|
+
[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]
|
|
314
|
+
|
|
315
|
+
## Language Guidance
|
|
316
|
+
[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]
|
|
317
|
+
|
|
318
|
+
## Recent Feature Highlights
|
|
319
|
+
[LAST 3 FEATURES AND WHAT THEY ADDED]
|
|
320
|
+
|
|
321
|
+
*Generated by cc-devflow adapter compiler for automated agent contexts.*
|
|
322
|
+
EOF
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
# Replace template placeholders
|
|
326
|
+
local project_structure
|
|
327
|
+
project_structure=$(get_project_structure "$NEW_PROJECT_TYPE")
|
|
328
|
+
|
|
329
|
+
local commands
|
|
330
|
+
commands=$(get_commands_for_language "$NEW_LANG")
|
|
331
|
+
|
|
332
|
+
local language_conventions
|
|
333
|
+
language_conventions=$(get_language_conventions "$NEW_LANG")
|
|
334
|
+
|
|
335
|
+
# Perform substitutions with error checking using safer approach
|
|
336
|
+
# Escape special characters for sed by using a different delimiter or escaping
|
|
337
|
+
local escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
|
|
338
|
+
local escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
|
|
339
|
+
local escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')
|
|
340
|
+
|
|
341
|
+
# Build technology stack and recent change strings conditionally
|
|
342
|
+
local tech_stack
|
|
343
|
+
if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
|
|
344
|
+
tech_stack="- $escaped_lang + $escaped_framework ($escaped_branch)"
|
|
345
|
+
elif [[ -n "$escaped_lang" ]]; then
|
|
346
|
+
tech_stack="- $escaped_lang ($escaped_branch)"
|
|
347
|
+
elif [[ -n "$escaped_framework" ]]; then
|
|
348
|
+
tech_stack="- $escaped_framework ($escaped_branch)"
|
|
349
|
+
else
|
|
350
|
+
tech_stack="- ($escaped_branch)"
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
local recent_change
|
|
354
|
+
if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
|
|
355
|
+
recent_change="- $escaped_branch: Added $escaped_lang + $escaped_framework"
|
|
356
|
+
elif [[ -n "$escaped_lang" ]]; then
|
|
357
|
+
recent_change="- $escaped_branch: Added $escaped_lang"
|
|
358
|
+
elif [[ -n "$escaped_framework" ]]; then
|
|
359
|
+
recent_change="- $escaped_branch: Added $escaped_framework"
|
|
360
|
+
else
|
|
361
|
+
recent_change="- $escaped_branch: Added"
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
local substitutions=(
|
|
365
|
+
"s|\[PROJECT NAME\]|$project_name|"
|
|
366
|
+
"s|\[DATE\]|$current_date|"
|
|
367
|
+
"s|\[EXTRACTED FROM ALL PLAN.MD FILES\]|$tech_stack|"
|
|
368
|
+
"s|\[ACTUAL STRUCTURE FROM PLANS\]|$project_structure|g"
|
|
369
|
+
"s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$commands|"
|
|
370
|
+
"s|\[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE\]|$language_conventions|"
|
|
371
|
+
"s|\[LAST 3 FEATURES AND WHAT THEY ADDED\]|$recent_change|"
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
for substitution in "${substitutions[@]}"; do
|
|
375
|
+
if ! sed -i.bak -e "$substitution" "$temp_file"; then
|
|
376
|
+
log_error "Failed to perform substitution: $substitution"
|
|
377
|
+
rm -f "$temp_file" "$temp_file.bak"
|
|
378
|
+
return 1
|
|
379
|
+
fi
|
|
380
|
+
done
|
|
381
|
+
|
|
382
|
+
# Convert \n sequences to actual newlines
|
|
383
|
+
newline=$(printf '\n')
|
|
384
|
+
sed -i.bak2 "s/\\\\n/${newline}/g" "$temp_file"
|
|
385
|
+
|
|
386
|
+
# Clean up backup files
|
|
387
|
+
rm -f "$temp_file.bak" "$temp_file.bak2"
|
|
388
|
+
|
|
389
|
+
return 0
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
update_existing_agent_file() {
|
|
396
|
+
local target_file="$1"
|
|
397
|
+
local current_date="$2"
|
|
398
|
+
|
|
399
|
+
log_info "Updating existing agent context file..."
|
|
400
|
+
|
|
401
|
+
# Use a single temporary file for atomic update
|
|
402
|
+
local temp_file
|
|
403
|
+
temp_file=$(mktemp) || {
|
|
404
|
+
log_error "Failed to create temporary file"
|
|
405
|
+
return 1
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
# Process the file in one pass
|
|
409
|
+
local tech_stack=$(format_technology_stack "$NEW_LANG" "$NEW_FRAMEWORK")
|
|
410
|
+
local new_tech_entries=()
|
|
411
|
+
local new_change_entry=""
|
|
412
|
+
|
|
413
|
+
# Prepare new technology entries
|
|
414
|
+
if [[ -n "$tech_stack" ]] && ! grep -q "$tech_stack" "$target_file"; then
|
|
415
|
+
new_tech_entries+=("- $tech_stack ($CURRENT_BRANCH)")
|
|
416
|
+
fi
|
|
417
|
+
|
|
418
|
+
if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]] && ! grep -q "$NEW_DB" "$target_file"; then
|
|
419
|
+
new_tech_entries+=("- $NEW_DB ($CURRENT_BRANCH)")
|
|
420
|
+
fi
|
|
421
|
+
|
|
422
|
+
# Prepare new change entry
|
|
423
|
+
if [[ -n "$tech_stack" ]]; then
|
|
424
|
+
new_change_entry="- $CURRENT_BRANCH: Added $tech_stack"
|
|
425
|
+
elif [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]]; then
|
|
426
|
+
new_change_entry="- $CURRENT_BRANCH: Added $NEW_DB"
|
|
427
|
+
fi
|
|
428
|
+
|
|
429
|
+
# Check if sections exist in the file
|
|
430
|
+
local has_active_technologies=0
|
|
431
|
+
local has_recent_changes=0
|
|
432
|
+
|
|
433
|
+
if grep -q "^## Active Technologies" "$target_file" 2>/dev/null; then
|
|
434
|
+
has_active_technologies=1
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
if grep -q "^## Recent Changes" "$target_file" 2>/dev/null; then
|
|
438
|
+
has_recent_changes=1
|
|
439
|
+
fi
|
|
440
|
+
|
|
441
|
+
# Process file line by line
|
|
442
|
+
local in_tech_section=false
|
|
443
|
+
local in_changes_section=false
|
|
444
|
+
local tech_entries_added=false
|
|
445
|
+
local changes_entries_added=false
|
|
446
|
+
local existing_changes_count=0
|
|
447
|
+
local file_ended=false
|
|
448
|
+
|
|
449
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
450
|
+
# Handle Active Technologies section
|
|
451
|
+
if [[ "$line" == "## Active Technologies" ]]; then
|
|
452
|
+
echo "$line" >> "$temp_file"
|
|
453
|
+
in_tech_section=true
|
|
454
|
+
continue
|
|
455
|
+
elif [[ $in_tech_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
|
|
456
|
+
# Add new tech entries before closing the section
|
|
457
|
+
if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
|
|
458
|
+
printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
|
|
459
|
+
tech_entries_added=true
|
|
460
|
+
fi
|
|
461
|
+
echo "$line" >> "$temp_file"
|
|
462
|
+
in_tech_section=false
|
|
463
|
+
continue
|
|
464
|
+
elif [[ $in_tech_section == true ]] && [[ -z "$line" ]]; then
|
|
465
|
+
# Add new tech entries before empty line in tech section
|
|
466
|
+
if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
|
|
467
|
+
printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
|
|
468
|
+
tech_entries_added=true
|
|
469
|
+
fi
|
|
470
|
+
echo "$line" >> "$temp_file"
|
|
471
|
+
continue
|
|
472
|
+
fi
|
|
473
|
+
|
|
474
|
+
# Handle Recent Changes section
|
|
475
|
+
if [[ "$line" == "## Recent Changes" ]]; then
|
|
476
|
+
echo "$line" >> "$temp_file"
|
|
477
|
+
# Add new change entry right after the heading
|
|
478
|
+
if [[ -n "$new_change_entry" ]]; then
|
|
479
|
+
echo "$new_change_entry" >> "$temp_file"
|
|
480
|
+
fi
|
|
481
|
+
in_changes_section=true
|
|
482
|
+
changes_entries_added=true
|
|
483
|
+
continue
|
|
484
|
+
elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
|
|
485
|
+
echo "$line" >> "$temp_file"
|
|
486
|
+
in_changes_section=false
|
|
487
|
+
continue
|
|
488
|
+
elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
|
|
489
|
+
# Keep only first 2 existing changes
|
|
490
|
+
if [[ $existing_changes_count -lt 2 ]]; then
|
|
491
|
+
echo "$line" >> "$temp_file"
|
|
492
|
+
((existing_changes_count++))
|
|
493
|
+
fi
|
|
494
|
+
continue
|
|
495
|
+
fi
|
|
496
|
+
|
|
497
|
+
# Update timestamp
|
|
498
|
+
if [[ "$line" =~ \*\*Last\ updated\*\*:.*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then
|
|
499
|
+
echo "$line" | sed "s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/$current_date/" >> "$temp_file"
|
|
500
|
+
else
|
|
501
|
+
echo "$line" >> "$temp_file"
|
|
502
|
+
fi
|
|
503
|
+
done < "$target_file"
|
|
504
|
+
|
|
505
|
+
# Post-loop check: if we're still in the Active Technologies section and haven't added new entries
|
|
506
|
+
if [[ $in_tech_section == true ]] && [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
|
|
507
|
+
printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
|
|
508
|
+
tech_entries_added=true
|
|
509
|
+
fi
|
|
510
|
+
|
|
511
|
+
# If sections don't exist, add them at the end of the file
|
|
512
|
+
if [[ $has_active_technologies -eq 0 ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
|
|
513
|
+
echo "" >> "$temp_file"
|
|
514
|
+
echo "## Active Technologies" >> "$temp_file"
|
|
515
|
+
printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
|
|
516
|
+
tech_entries_added=true
|
|
517
|
+
fi
|
|
518
|
+
|
|
519
|
+
if [[ $has_recent_changes -eq 0 ]] && [[ -n "$new_change_entry" ]]; then
|
|
520
|
+
echo "" >> "$temp_file"
|
|
521
|
+
echo "## Recent Changes" >> "$temp_file"
|
|
522
|
+
echo "$new_change_entry" >> "$temp_file"
|
|
523
|
+
changes_entries_added=true
|
|
524
|
+
fi
|
|
525
|
+
|
|
526
|
+
# Move temp file to target atomically
|
|
527
|
+
if ! mv "$temp_file" "$target_file"; then
|
|
528
|
+
log_error "Failed to update target file"
|
|
529
|
+
rm -f "$temp_file"
|
|
530
|
+
return 1
|
|
531
|
+
fi
|
|
532
|
+
|
|
533
|
+
return 0
|
|
534
|
+
}
|
|
535
|
+
#==============================================================================
|
|
536
|
+
# Main Agent File Update Function
|
|
537
|
+
#==============================================================================
|
|
538
|
+
|
|
539
|
+
update_agent_file() {
|
|
540
|
+
local target_file="$1"
|
|
541
|
+
local agent_name="$2"
|
|
542
|
+
|
|
543
|
+
if [[ -z "$target_file" ]] || [[ -z "$agent_name" ]]; then
|
|
544
|
+
log_error "update_agent_file requires target_file and agent_name parameters"
|
|
545
|
+
return 1
|
|
546
|
+
fi
|
|
547
|
+
|
|
548
|
+
log_info "Updating $agent_name context file: $target_file"
|
|
549
|
+
|
|
550
|
+
local project_name
|
|
551
|
+
project_name=$(basename "$REPO_ROOT")
|
|
552
|
+
local current_date
|
|
553
|
+
current_date=$(date +%Y-%m-%d)
|
|
554
|
+
|
|
555
|
+
# Create directory if it doesn't exist
|
|
556
|
+
local target_dir
|
|
557
|
+
target_dir=$(dirname "$target_file")
|
|
558
|
+
if [[ ! -d "$target_dir" ]]; then
|
|
559
|
+
if ! mkdir -p "$target_dir"; then
|
|
560
|
+
log_error "Failed to create directory: $target_dir"
|
|
561
|
+
return 1
|
|
562
|
+
fi
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
if [[ ! -f "$target_file" ]]; then
|
|
566
|
+
# Create new file from template
|
|
567
|
+
local temp_file
|
|
568
|
+
temp_file=$(mktemp) || {
|
|
569
|
+
log_error "Failed to create temporary file"
|
|
570
|
+
return 1
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if create_new_agent_file "$target_file" "$temp_file" "$project_name" "$current_date"; then
|
|
574
|
+
if mv "$temp_file" "$target_file"; then
|
|
575
|
+
log_success "Created new $agent_name context file"
|
|
576
|
+
else
|
|
577
|
+
log_error "Failed to move temporary file to $target_file"
|
|
578
|
+
rm -f "$temp_file"
|
|
579
|
+
return 1
|
|
580
|
+
fi
|
|
581
|
+
else
|
|
582
|
+
log_error "Failed to create new agent file"
|
|
583
|
+
rm -f "$temp_file"
|
|
584
|
+
return 1
|
|
585
|
+
fi
|
|
586
|
+
else
|
|
587
|
+
# Update existing file
|
|
588
|
+
if [[ ! -r "$target_file" ]]; then
|
|
589
|
+
log_error "Cannot read existing file: $target_file"
|
|
590
|
+
return 1
|
|
591
|
+
fi
|
|
592
|
+
|
|
593
|
+
if [[ ! -w "$target_file" ]]; then
|
|
594
|
+
log_error "Cannot write to existing file: $target_file"
|
|
595
|
+
return 1
|
|
596
|
+
fi
|
|
597
|
+
|
|
598
|
+
if update_existing_agent_file "$target_file" "$current_date"; then
|
|
599
|
+
log_success "Updated existing $agent_name context file"
|
|
600
|
+
else
|
|
601
|
+
log_error "Failed to update existing agent file"
|
|
602
|
+
return 1
|
|
603
|
+
fi
|
|
604
|
+
fi
|
|
605
|
+
|
|
606
|
+
return 0
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
#==============================================================================
|
|
610
|
+
# Agent Selection and Processing
|
|
611
|
+
#==============================================================================
|
|
612
|
+
|
|
613
|
+
update_specific_agent() {
|
|
614
|
+
local agent_type="$1"
|
|
615
|
+
|
|
616
|
+
case "$agent_type" in
|
|
617
|
+
claude)
|
|
618
|
+
update_agent_file "$CLAUDE_FILE" "Claude Code"
|
|
619
|
+
;;
|
|
620
|
+
gemini)
|
|
621
|
+
update_agent_file "$GEMINI_FILE" "Gemini CLI"
|
|
622
|
+
;;
|
|
623
|
+
copilot)
|
|
624
|
+
update_agent_file "$COPILOT_FILE" "GitHub Copilot"
|
|
625
|
+
;;
|
|
626
|
+
cursor-agent)
|
|
627
|
+
update_agent_file "$CURSOR_FILE" "Cursor IDE"
|
|
628
|
+
;;
|
|
629
|
+
qwen)
|
|
630
|
+
update_agent_file "$QWEN_FILE" "Qwen Code"
|
|
631
|
+
;;
|
|
632
|
+
opencode)
|
|
633
|
+
update_agent_file "$AGENTS_FILE" "opencode"
|
|
634
|
+
;;
|
|
635
|
+
codex)
|
|
636
|
+
update_agent_file "$AGENTS_FILE" "Codex CLI"
|
|
637
|
+
;;
|
|
638
|
+
windsurf)
|
|
639
|
+
update_agent_file "$WINDSURF_FILE" "Windsurf"
|
|
640
|
+
;;
|
|
641
|
+
kilocode)
|
|
642
|
+
update_agent_file "$KILOCODE_FILE" "Kilo Code"
|
|
643
|
+
;;
|
|
644
|
+
auggie)
|
|
645
|
+
update_agent_file "$AUGGIE_FILE" "Auggie CLI"
|
|
646
|
+
;;
|
|
647
|
+
roo)
|
|
648
|
+
update_agent_file "$ROO_FILE" "Roo Code"
|
|
649
|
+
;;
|
|
650
|
+
codebuddy)
|
|
651
|
+
update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI"
|
|
652
|
+
;;
|
|
653
|
+
amp)
|
|
654
|
+
update_agent_file "$AMP_FILE" "Amp"
|
|
655
|
+
;;
|
|
656
|
+
q)
|
|
657
|
+
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
|
|
658
|
+
;;
|
|
659
|
+
*)
|
|
660
|
+
log_error "Unknown agent type '$agent_type'"
|
|
661
|
+
log_error "Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|roo|amp|q"
|
|
662
|
+
exit 1
|
|
663
|
+
;;
|
|
664
|
+
esac
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
update_all_existing_agents() {
|
|
668
|
+
local found_agent=false
|
|
669
|
+
|
|
670
|
+
# Check each possible agent file and update if it exists
|
|
671
|
+
if [[ -f "$CLAUDE_FILE" ]]; then
|
|
672
|
+
update_agent_file "$CLAUDE_FILE" "Claude Code"
|
|
673
|
+
found_agent=true
|
|
674
|
+
fi
|
|
675
|
+
|
|
676
|
+
if [[ -f "$GEMINI_FILE" ]]; then
|
|
677
|
+
update_agent_file "$GEMINI_FILE" "Gemini CLI"
|
|
678
|
+
found_agent=true
|
|
679
|
+
fi
|
|
680
|
+
|
|
681
|
+
if [[ -f "$COPILOT_FILE" ]]; then
|
|
682
|
+
update_agent_file "$COPILOT_FILE" "GitHub Copilot"
|
|
683
|
+
found_agent=true
|
|
684
|
+
fi
|
|
685
|
+
|
|
686
|
+
if [[ -f "$CURSOR_FILE" ]]; then
|
|
687
|
+
update_agent_file "$CURSOR_FILE" "Cursor IDE"
|
|
688
|
+
found_agent=true
|
|
689
|
+
fi
|
|
690
|
+
|
|
691
|
+
if [[ -f "$QWEN_FILE" ]]; then
|
|
692
|
+
update_agent_file "$QWEN_FILE" "Qwen Code"
|
|
693
|
+
found_agent=true
|
|
694
|
+
fi
|
|
695
|
+
|
|
696
|
+
if [[ -f "$AGENTS_FILE" ]]; then
|
|
697
|
+
update_agent_file "$AGENTS_FILE" "Codex/opencode"
|
|
698
|
+
found_agent=true
|
|
699
|
+
fi
|
|
700
|
+
|
|
701
|
+
if [[ -f "$WINDSURF_FILE" ]]; then
|
|
702
|
+
update_agent_file "$WINDSURF_FILE" "Windsurf"
|
|
703
|
+
found_agent=true
|
|
704
|
+
fi
|
|
705
|
+
|
|
706
|
+
if [[ -f "$KILOCODE_FILE" ]]; then
|
|
707
|
+
update_agent_file "$KILOCODE_FILE" "Kilo Code"
|
|
708
|
+
found_agent=true
|
|
709
|
+
fi
|
|
710
|
+
|
|
711
|
+
if [[ -f "$AUGGIE_FILE" ]]; then
|
|
712
|
+
update_agent_file "$AUGGIE_FILE" "Auggie CLI"
|
|
713
|
+
found_agent=true
|
|
714
|
+
fi
|
|
715
|
+
|
|
716
|
+
if [[ -f "$ROO_FILE" ]]; then
|
|
717
|
+
update_agent_file "$ROO_FILE" "Roo Code"
|
|
718
|
+
found_agent=true
|
|
719
|
+
fi
|
|
720
|
+
|
|
721
|
+
if [[ -f "$CODEBUDDY_FILE" ]]; then
|
|
722
|
+
update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI"
|
|
723
|
+
found_agent=true
|
|
724
|
+
fi
|
|
725
|
+
|
|
726
|
+
if [[ -f "$Q_FILE" ]]; then
|
|
727
|
+
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
|
|
728
|
+
found_agent=true
|
|
729
|
+
fi
|
|
730
|
+
|
|
731
|
+
# If no agent files exist, create a default Claude file
|
|
732
|
+
if [[ "$found_agent" == false ]]; then
|
|
733
|
+
log_info "No existing agent files found, creating default Claude file..."
|
|
734
|
+
update_agent_file "$CLAUDE_FILE" "Claude Code"
|
|
735
|
+
fi
|
|
736
|
+
}
|
|
737
|
+
print_summary() {
|
|
738
|
+
echo
|
|
739
|
+
log_info "Summary of changes:"
|
|
740
|
+
|
|
741
|
+
if [[ -n "$NEW_LANG" ]]; then
|
|
742
|
+
echo " - Added language: $NEW_LANG"
|
|
743
|
+
fi
|
|
744
|
+
|
|
745
|
+
if [[ -n "$NEW_FRAMEWORK" ]]; then
|
|
746
|
+
echo " - Added framework: $NEW_FRAMEWORK"
|
|
747
|
+
fi
|
|
748
|
+
|
|
749
|
+
if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
|
|
750
|
+
echo " - Added database: $NEW_DB"
|
|
751
|
+
fi
|
|
752
|
+
|
|
753
|
+
echo
|
|
754
|
+
|
|
755
|
+
log_info "Usage: $0 [claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|codebuddy|q]"
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
#==============================================================================
|
|
759
|
+
# Main Execution
|
|
760
|
+
#==============================================================================
|
|
761
|
+
|
|
762
|
+
main() {
|
|
763
|
+
# Validate environment before proceeding
|
|
764
|
+
validate_environment
|
|
765
|
+
|
|
766
|
+
log_info "=== Updating agent context files for feature $CURRENT_BRANCH ==="
|
|
767
|
+
|
|
768
|
+
# Parse the plan file to extract project information
|
|
769
|
+
if ! parse_plan_data "$NEW_PLAN"; then
|
|
770
|
+
log_error "Failed to parse plan data"
|
|
771
|
+
exit 1
|
|
772
|
+
fi
|
|
773
|
+
|
|
774
|
+
# Process based on agent type argument
|
|
775
|
+
local success=true
|
|
776
|
+
|
|
777
|
+
if [[ -z "$AGENT_TYPE" ]]; then
|
|
778
|
+
# No specific agent provided - update all existing agent files
|
|
779
|
+
log_info "No agent specified, updating all existing agent files..."
|
|
780
|
+
if ! update_all_existing_agents; then
|
|
781
|
+
success=false
|
|
782
|
+
fi
|
|
783
|
+
else
|
|
784
|
+
# Specific agent provided - update only that agent
|
|
785
|
+
log_info "Updating specific agent: $AGENT_TYPE"
|
|
786
|
+
if ! update_specific_agent "$AGENT_TYPE"; then
|
|
787
|
+
success=false
|
|
788
|
+
fi
|
|
789
|
+
fi
|
|
790
|
+
|
|
791
|
+
# Print summary
|
|
792
|
+
print_summary
|
|
793
|
+
|
|
794
|
+
if [[ "$success" == true ]]; then
|
|
795
|
+
log_success "Agent context update completed successfully"
|
|
796
|
+
exit 0
|
|
797
|
+
else
|
|
798
|
+
log_error "Agent context update completed with errors"
|
|
799
|
+
exit 1
|
|
800
|
+
fi
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
# Execute main function if script is run directly
|
|
804
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
805
|
+
main "$@"
|
|
806
|
+
fi
|