context-engineer 1.1.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.
- package/README.md +88 -0
- package/bin/cli.mjs +91 -0
- package/lib/copy.mjs +102 -0
- package/lib/init.mjs +166 -0
- package/lib/prompts.mjs +144 -0
- package/lib/update.mjs +198 -0
- package/package.json +35 -0
- package/templates/checksums.json +68 -0
- package/templates/claude/.claude/rules/context-maintenance.md +38 -0
- package/templates/claude/.claude/rules/experience-capture.md +46 -0
- package/templates/claude/.claude/settings.project.json +22 -0
- package/templates/claude/.claude/skills/bootstrap/SKILL.md +223 -0
- package/templates/claude/.claude/skills/dev/SKILL.md +119 -0
- package/templates/claude/.claude/skills/dev-capture/SKILL.md +111 -0
- package/templates/claude/.claude/skills/dev-commit/SKILL.md +90 -0
- package/templates/claude/.claude/skills/dev-decompose/SKILL.md +113 -0
- package/templates/claude/.claude/skills/dev-deps/SKILL.md +108 -0
- package/templates/claude/.claude/skills/dev-execute/SKILL.md +196 -0
- package/templates/claude/.claude/skills/dev-prd/SKILL.md +100 -0
- package/templates/claude/.claude/skills/dev-quality/SKILL.md +109 -0
- package/templates/claude/.claude/skills/dev-requirements/SKILL.md +75 -0
- package/templates/claude/.claude/skills/review-context/SKILL.md +120 -0
- package/templates/claude/.claude/skills/sync/SKILL.md +107 -0
- package/templates/claude/.claude/skills/update-context/SKILL.md +105 -0
- package/templates/claude/.claude/workflow/agents/implementer.md +65 -0
- package/templates/claude/.claude/workflow/agents/reviewer.md +96 -0
- package/templates/claude/.claude/workflow/agents/team-config.md +97 -0
- package/templates/claude/.claude/workflow/agents/tester.md +98 -0
- package/templates/claude/.claude/workflow/interfaces/phase-contract.md +157 -0
- package/templates/claude/CLAUDE.md +50 -0
- package/templates/core/.context/_meta/concepts.md +9 -0
- package/templates/core/.context/_meta/drift-report.md +16 -0
- package/templates/core/.context/_meta/last-sync.json +6 -0
- package/templates/core/.context/_meta/schema.md +242 -0
- package/templates/core/.context/architecture/api-surface.md +52 -0
- package/templates/core/.context/architecture/class-index.md +49 -0
- package/templates/core/.context/architecture/data-flow.md +103 -0
- package/templates/core/.context/architecture/data-model.md +35 -0
- package/templates/core/.context/architecture/decisions/001-template.md +35 -0
- package/templates/core/.context/architecture/dependencies.md +35 -0
- package/templates/core/.context/architecture/infrastructure.md +42 -0
- package/templates/core/.context/architecture/module-graph.md +68 -0
- package/templates/core/.context/architecture/overview.md +87 -0
- package/templates/core/.context/business/domain-model.md +43 -0
- package/templates/core/.context/business/glossary.md +23 -0
- package/templates/core/.context/business/overview.md +29 -0
- package/templates/core/.context/business/workflows.md +61 -0
- package/templates/core/.context/constitution.md +84 -0
- package/templates/core/.context/conventions/code-style.md +47 -0
- package/templates/core/.context/conventions/error-handling.md +50 -0
- package/templates/core/.context/conventions/git.md +46 -0
- package/templates/core/.context/conventions/patterns.md +41 -0
- package/templates/core/.context/conventions/testing.md +49 -0
- package/templates/core/.context/experience/debugging.md +21 -0
- package/templates/core/.context/experience/incidents.md +26 -0
- package/templates/core/.context/experience/lessons.md +23 -0
- package/templates/core/.context/experience/performance.md +29 -0
- package/templates/core/.context/index.md +93 -0
- package/templates/core/.context/progress/backlog.md +23 -0
- package/templates/core/.context/progress/status.md +30 -0
- package/templates/core/.context/workflow/artifacts/.gitkeep +0 -0
- package/templates/core/.context/workflow/config.md +35 -0
- package/templates/core/AGENTS.md +53 -0
- package/templates/core/scripts/compact-experience.sh +83 -0
- package/templates/core/scripts/detect-drift.sh +388 -0
- package/templates/core/scripts/extract-structure.sh +757 -0
- package/templates/core/scripts/sync-context.sh +510 -0
- package/templates/cursor/.cursor/rules/always.mdc +18 -0
- package/templates/cursor/.cursor/rules/backend.mdc +16 -0
- package/templates/cursor/.cursor/rules/database.mdc +16 -0
- package/templates/cursor/.cursor/rules/frontend.mdc +13 -0
- package/templates/cursor/.cursorrules +23 -0
- package/templates/github/.github/copilot-instructions.md +15 -0
- package/templates/github/.github/workflows/context-drift.yml +73 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# sync-context.sh — Regenerate auto-generated context files from source code
|
|
4
|
+
#
|
|
5
|
+
# Usage: bash scripts/sync-context.sh [--all | --data-model | --api-surface | --dependencies]
|
|
6
|
+
#
|
|
7
|
+
# This script analyzes source code and regenerates the auto-generated context files.
|
|
8
|
+
# It supports multiple tech stacks and auto-detects the project type.
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
CONTEXT_DIR=".context"
|
|
13
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
14
|
+
|
|
15
|
+
# ============================================================
|
|
16
|
+
# Tech Stack Detection
|
|
17
|
+
# ============================================================
|
|
18
|
+
|
|
19
|
+
detect_tech_stack() {
|
|
20
|
+
local stacks=()
|
|
21
|
+
|
|
22
|
+
[ -f "package.json" ] && stacks+=("nodejs")
|
|
23
|
+
[ -f "tsconfig.json" ] && stacks+=("typescript")
|
|
24
|
+
ls ./*.csproj >/dev/null 2>&1 && stacks+=("dotnet")
|
|
25
|
+
ls ./*.sln >/dev/null 2>&1 && stacks+=("dotnet")
|
|
26
|
+
[ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || [ -f "setup.py" ] && stacks+=("python")
|
|
27
|
+
[ -f "go.mod" ] && stacks+=("go")
|
|
28
|
+
[ -f "Cargo.toml" ] && stacks+=("rust")
|
|
29
|
+
[ -f "pom.xml" ] || [ -f "build.gradle" ] && stacks+=("java")
|
|
30
|
+
|
|
31
|
+
if [ ${#stacks[@]} -eq 0 ]; then
|
|
32
|
+
echo "unknown"
|
|
33
|
+
else
|
|
34
|
+
echo "${stacks[*]}"
|
|
35
|
+
fi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# ============================================================
|
|
39
|
+
# Dependencies Sync
|
|
40
|
+
# ============================================================
|
|
41
|
+
|
|
42
|
+
sync_dependencies() {
|
|
43
|
+
echo "Syncing dependencies..."
|
|
44
|
+
local output="$CONTEXT_DIR/architecture/dependencies.md"
|
|
45
|
+
local sources=()
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
echo "<!-- AUTO-GENERATED: Do not edit manually. Run scripts/sync-context.sh to regenerate. -->"
|
|
49
|
+
echo "<!-- generated-from: package manifests -->"
|
|
50
|
+
echo "<!-- generated-at: $TIMESTAMP -->"
|
|
51
|
+
echo ""
|
|
52
|
+
echo "# Dependencies"
|
|
53
|
+
echo ""
|
|
54
|
+
echo "## Summary"
|
|
55
|
+
echo ""
|
|
56
|
+
|
|
57
|
+
# Node.js / TypeScript
|
|
58
|
+
if [ -f "package.json" ]; then
|
|
59
|
+
sources+=("package.json")
|
|
60
|
+
echo "### Node.js Dependencies"
|
|
61
|
+
echo ""
|
|
62
|
+
echo "#### Runtime"
|
|
63
|
+
echo ""
|
|
64
|
+
echo '| Package | Version |'
|
|
65
|
+
echo '|---------|---------|'
|
|
66
|
+
# Extract dependencies from package.json
|
|
67
|
+
if command -v node >/dev/null 2>&1; then
|
|
68
|
+
node -e "
|
|
69
|
+
const pkg = require('./package.json');
|
|
70
|
+
const deps = pkg.dependencies || {};
|
|
71
|
+
Object.entries(deps).forEach(([k,v]) => console.log('| ' + k + ' | ' + v + ' |'));
|
|
72
|
+
" 2>/dev/null || echo "| (unable to parse) | — |"
|
|
73
|
+
else
|
|
74
|
+
echo "| (node not available to parse) | — |"
|
|
75
|
+
fi
|
|
76
|
+
echo ""
|
|
77
|
+
echo "#### Development"
|
|
78
|
+
echo ""
|
|
79
|
+
echo '| Package | Version |'
|
|
80
|
+
echo '|---------|---------|'
|
|
81
|
+
if command -v node >/dev/null 2>&1; then
|
|
82
|
+
node -e "
|
|
83
|
+
const pkg = require('./package.json');
|
|
84
|
+
const deps = pkg.devDependencies || {};
|
|
85
|
+
Object.entries(deps).forEach(([k,v]) => console.log('| ' + k + ' | ' + v + ' |'));
|
|
86
|
+
" 2>/dev/null || echo "| (unable to parse) | — |"
|
|
87
|
+
else
|
|
88
|
+
echo "| (node not available to parse) | — |"
|
|
89
|
+
fi
|
|
90
|
+
echo ""
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Python
|
|
94
|
+
if [ -f "requirements.txt" ]; then
|
|
95
|
+
sources+=("requirements.txt")
|
|
96
|
+
echo "### Python Dependencies"
|
|
97
|
+
echo ""
|
|
98
|
+
echo '| Package | Version |'
|
|
99
|
+
echo '|---------|---------|'
|
|
100
|
+
while IFS= read -r line; do
|
|
101
|
+
# Skip comments and empty lines
|
|
102
|
+
[[ "$line" =~ ^#.*$ ]] && continue
|
|
103
|
+
[[ -z "$line" ]] && continue
|
|
104
|
+
# Parse package==version or package>=version
|
|
105
|
+
local pkg ver
|
|
106
|
+
pkg=$(echo "$line" | sed 's/[>=<~!].*//')
|
|
107
|
+
ver=$(echo "$line" | grep -oP '(?<=[>=<~!]=).*' || echo "any")
|
|
108
|
+
echo "| $pkg | $ver |"
|
|
109
|
+
done < "requirements.txt"
|
|
110
|
+
echo ""
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# .NET
|
|
114
|
+
for csproj in ./*.csproj; do
|
|
115
|
+
[ -f "$csproj" ] || continue
|
|
116
|
+
sources+=("$csproj")
|
|
117
|
+
echo "### .NET Dependencies ($csproj)"
|
|
118
|
+
echo ""
|
|
119
|
+
echo '| Package | Version |'
|
|
120
|
+
echo '|---------|---------|'
|
|
121
|
+
grep -oP 'Include="([^"]+)".*Version="([^"]+)"' "$csproj" | \
|
|
122
|
+
sed 's/Include="\([^"]*\)".*Version="\([^"]*\)"/| \1 | \2 |/' 2>/dev/null || echo "| (unable to parse) | — |"
|
|
123
|
+
echo ""
|
|
124
|
+
done
|
|
125
|
+
|
|
126
|
+
# Go
|
|
127
|
+
if [ -f "go.mod" ]; then
|
|
128
|
+
sources+=("go.mod")
|
|
129
|
+
echo "### Go Dependencies"
|
|
130
|
+
echo ""
|
|
131
|
+
echo '| Module | Version |'
|
|
132
|
+
echo '|--------|---------|'
|
|
133
|
+
grep -E '^\t' "go.mod" 2>/dev/null | \
|
|
134
|
+
awk '{print "| " $1 " | " $2 " |"}' || echo "| (unable to parse) | — |"
|
|
135
|
+
echo ""
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
echo "## External Services"
|
|
139
|
+
echo ""
|
|
140
|
+
echo "| Service | Purpose | Environment Variable |"
|
|
141
|
+
echo "|---------|---------|---------------------|"
|
|
142
|
+
echo "| [Add external services manually] | — | — |"
|
|
143
|
+
|
|
144
|
+
} > "$output"
|
|
145
|
+
|
|
146
|
+
echo " → $output (sources: ${sources[*]:-none})"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# ============================================================
|
|
150
|
+
# Data Model Sync
|
|
151
|
+
# ============================================================
|
|
152
|
+
|
|
153
|
+
sync_data_model() {
|
|
154
|
+
echo "Syncing data model..."
|
|
155
|
+
local output="$CONTEXT_DIR/architecture/data-model.md"
|
|
156
|
+
local found_models=false
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
echo "<!-- AUTO-GENERATED: Do not edit manually. Run scripts/sync-context.sh to regenerate. -->"
|
|
160
|
+
echo "<!-- generated-from: ORM models and schema files -->"
|
|
161
|
+
echo "<!-- generated-at: $TIMESTAMP -->"
|
|
162
|
+
echo ""
|
|
163
|
+
echo "# Data Model"
|
|
164
|
+
echo ""
|
|
165
|
+
|
|
166
|
+
# C# / EF Core entities
|
|
167
|
+
local entity_files
|
|
168
|
+
entity_files=$(find . \( -path "*/Entities/*" -o -path "*/entities/*" -o -path "*/Models/*" -o -path "*/models/*" \) -name "*.cs" -not -path "./.git/*" -not -path "*/bin/*" -not -path "*/obj/*" 2>/dev/null || true)
|
|
169
|
+
if [ -n "$entity_files" ]; then
|
|
170
|
+
found_models=true
|
|
171
|
+
echo "## Entities"
|
|
172
|
+
echo ""
|
|
173
|
+
echo "| Entity | File |"
|
|
174
|
+
echo "|--------|------|"
|
|
175
|
+
echo "$entity_files" | while IFS= read -r file; do
|
|
176
|
+
[ -z "$file" ] && continue
|
|
177
|
+
grep -oP '(?:class|record)\s+([A-Z][a-zA-Z0-9_]+)' "$file" 2>/dev/null | sed 's/\(class\|record\)\s*//' | while read -r name; do
|
|
178
|
+
echo "| $name | $file |"
|
|
179
|
+
done
|
|
180
|
+
done
|
|
181
|
+
echo ""
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
# Python models (Django / SQLAlchemy)
|
|
185
|
+
local py_model_files
|
|
186
|
+
py_model_files=$(find . -name "models.py" -not -path "./.git/*" -not -path "*/node_modules/*" -not -path "*/.venv/*" 2>/dev/null || true)
|
|
187
|
+
if [ -n "$py_model_files" ]; then
|
|
188
|
+
found_models=true
|
|
189
|
+
echo "## Python Models"
|
|
190
|
+
echo ""
|
|
191
|
+
echo "| Model | File |"
|
|
192
|
+
echo "|-------|------|"
|
|
193
|
+
echo "$py_model_files" | while IFS= read -r file; do
|
|
194
|
+
[ -z "$file" ] && continue
|
|
195
|
+
grep -oP 'class\s+([A-Z][a-zA-Z0-9_]+)' "$file" 2>/dev/null | sed 's/class\s*//' | while read -r name; do
|
|
196
|
+
echo "| $name | $file |"
|
|
197
|
+
done
|
|
198
|
+
done
|
|
199
|
+
echo ""
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# Prisma schema
|
|
203
|
+
if [ -f "prisma/schema.prisma" ]; then
|
|
204
|
+
found_models=true
|
|
205
|
+
echo "## Prisma Models"
|
|
206
|
+
echo ""
|
|
207
|
+
echo "| Model | Source |"
|
|
208
|
+
echo "|-------|--------|"
|
|
209
|
+
grep -oP 'model\s+([A-Z][a-zA-Z0-9_]+)' prisma/schema.prisma 2>/dev/null | sed 's/model\s*//' | while read -r name; do
|
|
210
|
+
echo "| $name | prisma/schema.prisma |"
|
|
211
|
+
done
|
|
212
|
+
echo ""
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# TypeScript entities (TypeORM / Sequelize / MikroORM)
|
|
216
|
+
local ts_entity_files
|
|
217
|
+
ts_entity_files=$(find . \( -name "*.entity.ts" -o -name "*.model.ts" \) -not -path "*/node_modules/*" -not -path "./.git/*" 2>/dev/null || true)
|
|
218
|
+
if [ -n "$ts_entity_files" ]; then
|
|
219
|
+
found_models=true
|
|
220
|
+
echo "## TypeScript Entities"
|
|
221
|
+
echo ""
|
|
222
|
+
echo "| Entity | File |"
|
|
223
|
+
echo "|--------|------|"
|
|
224
|
+
echo "$ts_entity_files" | while IFS= read -r file; do
|
|
225
|
+
[ -z "$file" ] && continue
|
|
226
|
+
grep -oP '(?:class|interface)\s+([A-Z][a-zA-Z0-9_]+)' "$file" 2>/dev/null | sed 's/\(class\|interface\)\s*//' | head -1 | while read -r name; do
|
|
227
|
+
[ -n "$name" ] && echo "| $name | $file |"
|
|
228
|
+
done
|
|
229
|
+
done
|
|
230
|
+
echo ""
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
# Go structs in model directories
|
|
234
|
+
local go_model_files
|
|
235
|
+
go_model_files=$(find . \( -path "*/model/*" -o -path "*/models/*" -o -path "*/entity/*" \) -name "*.go" -not -name "*_test.go" -not -path "./.git/*" 2>/dev/null || true)
|
|
236
|
+
if [ -n "$go_model_files" ]; then
|
|
237
|
+
found_models=true
|
|
238
|
+
echo "## Go Models"
|
|
239
|
+
echo ""
|
|
240
|
+
echo "| Struct | File |"
|
|
241
|
+
echo "|--------|------|"
|
|
242
|
+
echo "$go_model_files" | while IFS= read -r file; do
|
|
243
|
+
[ -z "$file" ] && continue
|
|
244
|
+
grep -oP 'type\s+([A-Z][a-zA-Z0-9_]+)\s+struct' "$file" 2>/dev/null | sed 's/type\s*//;s/\s*struct//' | while read -r name; do
|
|
245
|
+
echo "| $name | $file |"
|
|
246
|
+
done
|
|
247
|
+
done
|
|
248
|
+
echo ""
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# Java entities
|
|
252
|
+
local java_entity_files
|
|
253
|
+
java_entity_files=$(find . -name "*.java" -not -path "./.git/*" -not -path "*/build/*" -not -path "*/target/*" 2>/dev/null | xargs grep -l '@Entity\|@Table\|@Document' 2>/dev/null || true)
|
|
254
|
+
if [ -n "$java_entity_files" ]; then
|
|
255
|
+
found_models=true
|
|
256
|
+
echo "## Java Entities"
|
|
257
|
+
echo ""
|
|
258
|
+
echo "| Entity | File |"
|
|
259
|
+
echo "|--------|------|"
|
|
260
|
+
echo "$java_entity_files" | while IFS= read -r file; do
|
|
261
|
+
[ -z "$file" ] && continue
|
|
262
|
+
grep -oP 'class\s+([A-Z][a-zA-Z0-9_]+)' "$file" 2>/dev/null | sed 's/class\s*//' | head -1 | while read -r name; do
|
|
263
|
+
[ -n "$name" ] && echo "| $name | $file |"
|
|
264
|
+
done
|
|
265
|
+
done
|
|
266
|
+
echo ""
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
if [ "$found_models" = false ]; then
|
|
270
|
+
echo "No ORM models, migration files, or schema definitions detected."
|
|
271
|
+
echo ""
|
|
272
|
+
echo "If this project uses a database, populate this file manually or run"
|
|
273
|
+
echo "\`/bootstrap-context\` for AI-assisted analysis."
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
} > "$output"
|
|
277
|
+
|
|
278
|
+
echo " → $output"
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
# ============================================================
|
|
282
|
+
# API Surface Sync
|
|
283
|
+
# ============================================================
|
|
284
|
+
|
|
285
|
+
sync_api_surface() {
|
|
286
|
+
echo "Syncing API surface..."
|
|
287
|
+
local output="$CONTEXT_DIR/architecture/api-surface.md"
|
|
288
|
+
local found_routes=false
|
|
289
|
+
|
|
290
|
+
{
|
|
291
|
+
echo "<!-- AUTO-GENERATED: Do not edit manually. Run scripts/sync-context.sh to regenerate. -->"
|
|
292
|
+
echo "<!-- generated-from: route and controller definitions -->"
|
|
293
|
+
echo "<!-- generated-at: $TIMESTAMP -->"
|
|
294
|
+
echo ""
|
|
295
|
+
echo "# API Surface"
|
|
296
|
+
echo ""
|
|
297
|
+
|
|
298
|
+
# Express.js / NestJS / Node.js routes
|
|
299
|
+
local node_route_files
|
|
300
|
+
node_route_files=$(find . \( -name "*.routes.ts" -o -name "*.router.ts" -o -name "*.controller.ts" -o -name "*.routes.js" -o -name "*.router.js" \) -not -path "*/node_modules/*" -not -path "./.git/*" 2>/dev/null || true)
|
|
301
|
+
if [ -n "$node_route_files" ]; then
|
|
302
|
+
found_routes=true
|
|
303
|
+
echo "## Node.js Endpoints"
|
|
304
|
+
echo ""
|
|
305
|
+
echo "| Method | Path | File |"
|
|
306
|
+
echo "|--------|------|------|"
|
|
307
|
+
echo "$node_route_files" | while IFS= read -r file; do
|
|
308
|
+
[ -z "$file" ] && continue
|
|
309
|
+
grep -oP "(?:get|post|put|delete|patch|Get|Post|Put|Delete|Patch)\s*\(\s*['\"]([^'\"]+)" "$file" 2>/dev/null | \
|
|
310
|
+
sed "s/\s*(\s*['\"]/ /; s/['\"]//g" | while read -r method path; do
|
|
311
|
+
[ -n "$method" ] && [ -n "$path" ] && echo "| ${method^^} | $path | $file |"
|
|
312
|
+
done
|
|
313
|
+
done
|
|
314
|
+
echo ""
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
# ASP.NET Core controllers
|
|
318
|
+
local cs_controllers
|
|
319
|
+
cs_controllers=$(find . -name "*Controller.cs" -not -path "./.git/*" -not -path "*/bin/*" -not -path "*/obj/*" 2>/dev/null || true)
|
|
320
|
+
if [ -n "$cs_controllers" ]; then
|
|
321
|
+
found_routes=true
|
|
322
|
+
echo "## ASP.NET Endpoints"
|
|
323
|
+
echo ""
|
|
324
|
+
echo "| Controller | Route Prefix | File |"
|
|
325
|
+
echo "|------------|-------------|------|"
|
|
326
|
+
echo "$cs_controllers" | while IFS= read -r file; do
|
|
327
|
+
[ -z "$file" ] && continue
|
|
328
|
+
local controller
|
|
329
|
+
controller=$(grep -oP 'class\s+([A-Z][a-zA-Z0-9_]+Controller)' "$file" 2>/dev/null | sed 's/class\s*//' | head -1)
|
|
330
|
+
local route
|
|
331
|
+
route=$(grep -oP '\[Route\("([^"]+)"\)\]' "$file" 2>/dev/null | head -1 | grep -oP '"[^"]+"' | tr -d '"')
|
|
332
|
+
[ -n "$controller" ] && echo "| $controller | ${route:-/} | $file |"
|
|
333
|
+
done
|
|
334
|
+
echo ""
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
# Python Flask / FastAPI / Django routes
|
|
338
|
+
local py_route_files
|
|
339
|
+
py_route_files=$(find . \( -name "views.py" -o -name "urls.py" -o -name "routes.py" \) -not -path "./.git/*" -not -path "*/node_modules/*" -not -path "*/.venv/*" 2>/dev/null || true)
|
|
340
|
+
if [ -n "$py_route_files" ]; then
|
|
341
|
+
found_routes=true
|
|
342
|
+
echo "## Python Endpoints"
|
|
343
|
+
echo ""
|
|
344
|
+
echo "| Path | File |"
|
|
345
|
+
echo "|------|------|"
|
|
346
|
+
echo "$py_route_files" | while IFS= read -r file; do
|
|
347
|
+
[ -z "$file" ] && continue
|
|
348
|
+
grep -oP "(?:path|url|route)\s*\(\s*['\"]([^'\"]+)" "$file" 2>/dev/null | \
|
|
349
|
+
grep -oP "['\"][^'\"]+['\"]" | tr -d "'\"" | while read -r path; do
|
|
350
|
+
[ -n "$path" ] && echo "| $path | $file |"
|
|
351
|
+
done
|
|
352
|
+
done
|
|
353
|
+
echo ""
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
# Go routes (gin / echo / chi / net/http)
|
|
357
|
+
local go_route_files
|
|
358
|
+
go_route_files=$(find . -name "*.go" -not -name "*_test.go" -not -path "./.git/*" -not -path "*/vendor/*" 2>/dev/null | xargs grep -l '\.GET\|\.POST\|\.PUT\|\.DELETE\|\.HandleFunc\|\.Handle(' 2>/dev/null || true)
|
|
359
|
+
if [ -n "$go_route_files" ]; then
|
|
360
|
+
found_routes=true
|
|
361
|
+
echo "## Go Endpoints"
|
|
362
|
+
echo ""
|
|
363
|
+
echo "| Path | File |"
|
|
364
|
+
echo "|------|------|"
|
|
365
|
+
echo "$go_route_files" | while IFS= read -r file; do
|
|
366
|
+
[ -z "$file" ] && continue
|
|
367
|
+
grep -oP '(?:GET|POST|PUT|DELETE|Handle|HandleFunc)\s*\(\s*"([^"]+)"' "$file" 2>/dev/null | \
|
|
368
|
+
grep -oP '"[^"]+"' | tr -d '"' | while read -r path; do
|
|
369
|
+
[ -n "$path" ] && echo "| $path | $file |"
|
|
370
|
+
done
|
|
371
|
+
done
|
|
372
|
+
echo ""
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
# Java Spring Boot controllers
|
|
376
|
+
local java_controllers
|
|
377
|
+
java_controllers=$(find . -name "*.java" -not -path "./.git/*" -not -path "*/build/*" -not -path "*/target/*" 2>/dev/null | xargs grep -l '@RestController\|@Controller' 2>/dev/null || true)
|
|
378
|
+
if [ -n "$java_controllers" ]; then
|
|
379
|
+
found_routes=true
|
|
380
|
+
echo "## Java Endpoints"
|
|
381
|
+
echo ""
|
|
382
|
+
echo "| Controller | Mapping | File |"
|
|
383
|
+
echo "|------------|---------|------|"
|
|
384
|
+
echo "$java_controllers" | while IFS= read -r file; do
|
|
385
|
+
[ -z "$file" ] && continue
|
|
386
|
+
local controller
|
|
387
|
+
controller=$(grep -oP 'class\s+([A-Z][a-zA-Z0-9_]+)' "$file" 2>/dev/null | sed 's/class\s*//' | head -1)
|
|
388
|
+
local mapping
|
|
389
|
+
mapping=$(grep -oP '@RequestMapping\s*\(\s*"([^"]+)"' "$file" 2>/dev/null | grep -oP '"[^"]+"' | tr -d '"' | head -1)
|
|
390
|
+
[ -n "$controller" ] && echo "| $controller | ${mapping:-/} | $file |"
|
|
391
|
+
done
|
|
392
|
+
echo ""
|
|
393
|
+
fi
|
|
394
|
+
|
|
395
|
+
if [ "$found_routes" = false ]; then
|
|
396
|
+
echo "No route definitions, controllers, or API endpoints detected."
|
|
397
|
+
echo ""
|
|
398
|
+
echo "If this project exposes an API, populate this file manually or run"
|
|
399
|
+
echo "\`/bootstrap-context\` for AI-assisted analysis."
|
|
400
|
+
fi
|
|
401
|
+
|
|
402
|
+
} > "$output"
|
|
403
|
+
|
|
404
|
+
echo " → $output"
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
# ============================================================
|
|
408
|
+
# Module Graph Sync (delegates to extract-structure.sh)
|
|
409
|
+
# ============================================================
|
|
410
|
+
|
|
411
|
+
sync_module_graph() {
|
|
412
|
+
echo "Syncing module graph..."
|
|
413
|
+
local script_dir
|
|
414
|
+
script_dir=$(dirname "$0")
|
|
415
|
+
|
|
416
|
+
if [ -f "$script_dir/extract-structure.sh" ]; then
|
|
417
|
+
bash "$script_dir/extract-structure.sh" --module-graph
|
|
418
|
+
else
|
|
419
|
+
echo " → extract-structure.sh not found. Skipping module graph sync."
|
|
420
|
+
fi
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
# ============================================================
|
|
424
|
+
# Class Index Sync (delegates to extract-structure.sh)
|
|
425
|
+
# ============================================================
|
|
426
|
+
|
|
427
|
+
sync_class_index() {
|
|
428
|
+
echo "Syncing class index..."
|
|
429
|
+
local script_dir
|
|
430
|
+
script_dir=$(dirname "$0")
|
|
431
|
+
|
|
432
|
+
if [ -f "$script_dir/extract-structure.sh" ]; then
|
|
433
|
+
bash "$script_dir/extract-structure.sh" --class-index
|
|
434
|
+
else
|
|
435
|
+
echo " → extract-structure.sh not found. Skipping class index sync."
|
|
436
|
+
fi
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
# ============================================================
|
|
440
|
+
# Update Metadata
|
|
441
|
+
# ============================================================
|
|
442
|
+
|
|
443
|
+
update_metadata() {
|
|
444
|
+
echo "Updating metadata..."
|
|
445
|
+
local sync_file="$CONTEXT_DIR/_meta/last-sync.json"
|
|
446
|
+
|
|
447
|
+
if command -v node >/dev/null 2>&1; then
|
|
448
|
+
node -e "
|
|
449
|
+
const fs = require('fs');
|
|
450
|
+
const data = JSON.parse(fs.readFileSync('$sync_file', 'utf8'));
|
|
451
|
+
data.lastFullSync = '$TIMESTAMP';
|
|
452
|
+
fs.writeFileSync('$sync_file', JSON.stringify(data, null, 2) + '\n');
|
|
453
|
+
" 2>/dev/null || echo " → Warning: Could not update last-sync.json (node error)"
|
|
454
|
+
else
|
|
455
|
+
echo " → Warning: node not available, skipping metadata update"
|
|
456
|
+
fi
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# ============================================================
|
|
460
|
+
# Main
|
|
461
|
+
# ============================================================
|
|
462
|
+
|
|
463
|
+
echo "========================================="
|
|
464
|
+
echo " Context Sync"
|
|
465
|
+
echo "========================================="
|
|
466
|
+
echo ""
|
|
467
|
+
|
|
468
|
+
TECH_STACK=$(detect_tech_stack)
|
|
469
|
+
echo "Detected tech stack: $TECH_STACK"
|
|
470
|
+
echo ""
|
|
471
|
+
|
|
472
|
+
TARGET="${1:---all}"
|
|
473
|
+
|
|
474
|
+
case "$TARGET" in
|
|
475
|
+
--all)
|
|
476
|
+
sync_dependencies
|
|
477
|
+
sync_data_model
|
|
478
|
+
sync_api_surface
|
|
479
|
+
sync_module_graph
|
|
480
|
+
sync_class_index
|
|
481
|
+
update_metadata
|
|
482
|
+
;;
|
|
483
|
+
--dependencies)
|
|
484
|
+
sync_dependencies
|
|
485
|
+
update_metadata
|
|
486
|
+
;;
|
|
487
|
+
--data-model)
|
|
488
|
+
sync_data_model
|
|
489
|
+
update_metadata
|
|
490
|
+
;;
|
|
491
|
+
--api-surface)
|
|
492
|
+
sync_api_surface
|
|
493
|
+
update_metadata
|
|
494
|
+
;;
|
|
495
|
+
--module-graph)
|
|
496
|
+
sync_module_graph
|
|
497
|
+
update_metadata
|
|
498
|
+
;;
|
|
499
|
+
--class-index)
|
|
500
|
+
sync_class_index
|
|
501
|
+
update_metadata
|
|
502
|
+
;;
|
|
503
|
+
*)
|
|
504
|
+
echo "Usage: bash scripts/sync-context.sh [--all | --data-model | --api-surface | --dependencies | --module-graph | --class-index]"
|
|
505
|
+
exit 1
|
|
506
|
+
;;
|
|
507
|
+
esac
|
|
508
|
+
|
|
509
|
+
echo ""
|
|
510
|
+
echo "Done. Run 'bash scripts/detect-drift.sh --report' to verify."
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Always-loaded context: constitution summary and loading protocol"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Context System
|
|
7
|
+
|
|
8
|
+
This project uses `.context/` for structured project knowledge.
|
|
9
|
+
|
|
10
|
+
## Loading Protocol
|
|
11
|
+
1. Read `.context/constitution.md` for the Context Loading Route Table
|
|
12
|
+
2. Load ONLY files relevant to your current task
|
|
13
|
+
3. See `.context/index.md` for full context directory
|
|
14
|
+
|
|
15
|
+
## Context Maintenance
|
|
16
|
+
- Update `.context/` files when you change architecture, data models, APIs, or conventions
|
|
17
|
+
- Record non-trivial bug fixes in `.context/experience/debugging.md`
|
|
18
|
+
- Auto-generated files (marked `<!-- AUTO-GENERATED -->`) must not be edited manually
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Backend development context loader"
|
|
3
|
+
globs: ["src/api/**", "src/services/**", "src/controllers/**", "src/routes/**", "server/**", "backend/**"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backend Context
|
|
7
|
+
|
|
8
|
+
When working on backend code, load these context files:
|
|
9
|
+
- `.context/architecture/api-surface.md` — API contracts and endpoints
|
|
10
|
+
- `.context/architecture/data-model.md` — Database schema and relationships
|
|
11
|
+
- `.context/conventions/patterns.md` — Design patterns used in this project
|
|
12
|
+
- `.context/conventions/code-style.md` — Naming and formatting conventions
|
|
13
|
+
- `.context/conventions/error-handling.md` — Error handling patterns
|
|
14
|
+
|
|
15
|
+
If modifying API endpoints, update `.context/architecture/api-surface.md`.
|
|
16
|
+
If modifying database models, update `.context/architecture/data-model.md`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Database and data model context loader"
|
|
3
|
+
globs: ["**/migrations/**", "**/models/**", "**/entities/**", "**/schema*", "prisma/**", "**/DbContext*"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database Context
|
|
7
|
+
|
|
8
|
+
When working on database-related code, load these context files:
|
|
9
|
+
- `.context/architecture/data-model.md` — Current schema and relationships
|
|
10
|
+
- `.context/conventions/patterns.md` — Data access patterns
|
|
11
|
+
- `.context/business/domain-model.md` — Business entity definitions
|
|
12
|
+
|
|
13
|
+
After making schema changes:
|
|
14
|
+
1. Update `.context/architecture/data-model.md`
|
|
15
|
+
2. Check if `.context/business/domain-model.md` needs updating
|
|
16
|
+
3. Run `scripts/sync-context.sh` to regenerate auto-generated files
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Frontend development context loader"
|
|
3
|
+
globs: ["src/components/**", "src/pages/**", "src/views/**", "src/hooks/**", "src/stores/**", "frontend/**", "client/**"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Frontend Context
|
|
7
|
+
|
|
8
|
+
When working on frontend code, load these context files:
|
|
9
|
+
- `.context/architecture/overview.md` — System architecture
|
|
10
|
+
- `.context/conventions/code-style.md` — Naming and formatting conventions
|
|
11
|
+
- `.context/conventions/patterns.md` — UI component patterns
|
|
12
|
+
|
|
13
|
+
If adding new pages or routes, check `.context/architecture/api-surface.md` for available API endpoints.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Cursor Rules
|
|
2
|
+
|
|
3
|
+
This project uses a structured context system at `.context/`.
|
|
4
|
+
|
|
5
|
+
## Context Loading Protocol
|
|
6
|
+
|
|
7
|
+
1. Read `.context/constitution.md` for non-negotiable principles and the Context Loading Route Table
|
|
8
|
+
2. Use the Route Table to load ONLY the context files relevant to your current task
|
|
9
|
+
3. Read `.context/index.md` for a full directory of available context
|
|
10
|
+
|
|
11
|
+
## Context Maintenance
|
|
12
|
+
|
|
13
|
+
When you modify code that affects architecture, data models, API surfaces, or conventions, update the corresponding `.context/` file in the same commit.
|
|
14
|
+
|
|
15
|
+
When you fix a non-trivial bug, record it in `.context/experience/debugging.md`.
|
|
16
|
+
|
|
17
|
+
## Key Commands
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Build: [BUILD_COMMAND]
|
|
21
|
+
# Test: [TEST_COMMAND]
|
|
22
|
+
# Drift check: bash scripts/detect-drift.sh
|
|
23
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# GitHub Copilot Instructions
|
|
2
|
+
|
|
3
|
+
This project uses a structured context system at `.context/`.
|
|
4
|
+
|
|
5
|
+
## Context Loading
|
|
6
|
+
|
|
7
|
+
1. Read `.context/constitution.md` for non-negotiable principles and the Context Loading Route Table
|
|
8
|
+
2. Use the Route Table to determine which context files are relevant to your current task
|
|
9
|
+
3. See `.context/index.md` for a full directory of all available context
|
|
10
|
+
|
|
11
|
+
## Key Rules
|
|
12
|
+
|
|
13
|
+
- When modifying architecture, data models, or APIs, update corresponding `.context/` files
|
|
14
|
+
- When fixing bugs, record the issue and resolution in `.context/experience/debugging.md`
|
|
15
|
+
- Files marked `<!-- AUTO-GENERATED -->` should not be edited manually
|