Agent skill
project-config
[Utilities] Scan workspace and update docs/project-config.json to match current project structure
Install this agent skill to your Project
npx add-skill https://github.com/duc01226/EasyPlatform/tree/main/.claude/skills/project-config
SKILL.md
[IMPORTANT] Use
TaskCreateto break ALL work into small tasks BEFORE starting — including tasks for each file read. This prevents context loss from long files. For simple tasks, AI MUST ask user whether to skip.
Quick Summary
Goal: Scan the project workspace and update docs/project-config.json with accurate values reflecting the current directory structure, services, apps, and framework patterns.
Workflow:
- Read -- Load current
docs/project-config.json(or skeleton if just created) - Scan -- Discover backend services, frontend apps, design system docs, SCSS patterns, component prefixes
- Update -- Write updated config preserving the existing schema structure
- Verify -- Validate the updated config is valid JSON and all paths/regexes are correct
Key Rules:
- Preserves existing schema structure — only updates values, never removes sections
- Path regexes use
[\\/]for cross-platform path separator matching - Non-destructive: creates backup before overwriting if file exists
- Idempotent: safe to run multiple times
- Schema enforcement: validated by
.claude/hooks/lib/project-config-schema.cjs
Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).
⛔ Schema Protection Rules (CRITICAL)
The config structure is enforced by a schema validator. DO NOT:
- DO NOT rename, remove, or restructure any top-level section
- DO NOT change the type of any field (e.g., array→object, string→number)
- DO NOT rename keys within nested objects (e.g.,
serviceMap→services) - DO NOT populate deprecated v1 sections (
backendServices,frontendApps,scss,componentFinder,sharedNamespace) for NEW projects - DO NOT remove v1 data from EXISTING projects — it remains valid until explicitly migrated
You MAY:
- Add entries to existing maps/arrays
- Update values within existing entries
- Add optional fields defined in the schema (e.g.,
quickTips,examples) - Populate v2 sections (
modules[],contextGroups[],styling,componentSystem) for any project
Schema Structure (v2)
docs/project-config.json
├── schemaVersion (number, optional — 1 or 2)
├── project (object, optional)
│ ├── name, description, languages[], packageManagers[], monorepoTool
├── modules[] (array, optional — universal module registry)
│ └── { name, kind, pathRegex, description, tags[], meta{} }
├── contextGroups[] (array, optional — hook injection config)
│ └── { name, pathRegexes[], fileExtensions[], guideDoc, patternsDoc, stylingDoc, designSystemDoc, rules[] }
├── styling (object, optional — replaces scss)
│ ├── technology, guideDoc, appMap{}, patterns[]
├── designSystem (object, required)
│ ├── docsPath, modernUiNote, appMappings[]
├── componentSystem (object, optional — replaces componentFinder)
│ ├── type, selectorPrefixes[], filePattern, layerClassification{}
├── framework (object, required)
│ ├── name, backendPatternsDoc, frontendPatternsDoc, codeReviewDoc, integrationTestDoc, searchPatternKeywords[]
├── testing (object, optional)
│ ├── frameworks[], filePatterns{}, commands{}, coverageTool, guideDoc
├── databases (object, optional, freeform)
├── messaging (object, optional)
│ ├── broker, patterns[], consumerConvention
├── api (object, optional)
│ ├── style, docsFormat, docsPath, authPattern
├── infrastructure (object, optional)
│ ├── containerization, orchestration, cicd{ tool, configPath }
├── custom (object, optional, freeform)
│
│ ── DEPRECATED v1 sections (still validated if present) ──
├── backendServices (object, DEPRECATED — use modules[] kind=backend-service)
├── frontendApps (object, DEPRECATED — use modules[] kind=frontend-app)
├── scss (object, DEPRECATED — use styling)
├── componentFinder (object, DEPRECATED — use componentSystem)
└── sharedNamespace (string, DEPRECATED)
Run
node .claude/hooks/lib/project-config-schema.cjs --describefor exact field names and types.
Phase 0: Validate Current Config (MANDATORY)
Before any changes, validate the existing config:
node -e "
const { validateConfig, formatResult } = require('./.claude/hooks/lib/project-config-schema.cjs');
const config = JSON.parse(require('fs').readFileSync('docs/project-config.json', 'utf-8'));
console.log(formatResult(validateConfig(config)));
"
If validation fails, note the errors — the scan should fix them.
Phase 0b: Ensure CLAUDE.md Exists
Check if CLAUDE.md exists at the project root. If missing, create a skeleton with essential sections so the AI has project instructions from the start.
test -f CLAUDE.md && echo "EXISTS" || echo "MISSING"
If MISSING — create skeleton CLAUDE.md:
The skeleton should contain:
- Project name and description (from
docs/project-config.jsonif available) - Key file locations section (empty, to be filled by the user or
/scan-*skills) - Development commands section (empty placeholders)
- Naming conventions section
- A note directing users to run
/claude-md-initafter scan skills complete for full generation
NOTE: The
session-init-docs.cjshook also creates this skeleton automatically on session start. This phase is a safety net for cases where the hook didn't run or was skipped. The full CLAUDE.md generation via/claude-md-initruns as the last task in Phase 5, after all scan skills populate reference docs.
If EXISTS — skip. Do not overwrite an existing CLAUDE.md.
Phase 0c: Read Exact Schema Shapes (MANDATORY for new projects)
Before generating ANY config values, read the exact schema field shapes:
node .claude/hooks/lib/project-config-schema.cjs --describe
This outputs every section with exact field names, types, and required/optional markers. Use these field names verbatim — do NOT guess or abbreviate. Common AI mistakes to avoid:
designSystem.appMappings[].name(NOTapp)designSystem.appMappings[].pathRegexes(NOTpathRegexsingular)designSystem.appMappings[].docFile(NOTdesignDocordoc)referenceDocs[].filename(NOTnameorfile)styling.patterns[].scssExamples(NOTexamples)
Phase 1: Read Current Config
Read docs/project-config.json
Note the existing structure and any sections already populated with real values (not skeleton placeholders).
Phase 2: Discover Project Structure
Run these scans in parallel where possible. For new projects, populate v2 sections. For existing projects with v1 data, populate v2 alongside v1.
2a. Modules (v2 — replaces backendServices + frontendApps)
Discover all project modules (services, apps, libraries):
# Backend services: find directories with .csproj files
find src/ -name "*.csproj" -maxdepth 4 | head -30
# Repository interfaces (for meta.repository)
grep -r "interface I.*RootRepository" src/ --include="*.cs" -l
# Frontend apps: find app directories
ls -d src/*/apps/*/ 2>/dev/null || ls -d src/*/ 2>/dev/null
ls -d src/*/libs/*/ 2>/dev/null || ls -d libs/*/ 2>/dev/null
# Detect framework (Angular, React, etc.)
find src/ -name "angular.json" -o -name "nx.json" | head -10
Build modules[]:
Each module entry: { name, kind, pathRegex, description, tags[], meta{} }
kind:"backend-service","frontend-app","library","framework"tags:["modern"],["legacy"],["microservice", "mongodb"], etc.meta: service-specific data —{ repository, port, generation }
2b. Context Groups (v2 — hook injection config)
Build context groups from detected language/framework patterns:
# Detect backend service paths
find src/ -path "*/Services/*" -name "*.cs" | head -5
# Detect frontend paths
find src/ -path "*/{frontend}/*" -name "*.ts" | head -5
find src/ -path "*/Web/*" -name "*.ts" | head -5
Build contextGroups[]:
Each group: { name, pathRegexes[], fileExtensions[], guideDoc, patternsDoc, stylingDoc, designSystemDoc, rules[] }
rules[]: Critical coding rules for this context (consumed by hooks — NO hardcoded fallbacks)stylingDoc: Path to SCSS/CSS styling guide doc (optional, used by frontend-context hook)designSystemDoc: Path to design system overview doc (optional, used by frontend-context hook)
2c. Design System
ls docs/project-reference/design-system/ 2>/dev/null
find docs/ -name "*DesignSystem*" -o -name "*design-system*" 2>/dev/null | head -10
Build designSystem (unchanged from v1)
2d. Styling (v2 — replaces scss)
grep -r "@use " src/ --include="*.scss" -l | head -5
grep -r "@import " src/ --include="*.scss" -l | head -5
Build styling:
styling.technology—"scss","css","tailwind", etc.styling.appMap{}— app → SCSS path regexstyling.patterns[]— each item hasname,pathRegexes[],description,scssExamples[]
2e. Component System (v2 — replaces componentFinder)
grep -r "selector:" src/ --include="*.ts" | grep -oP "selector:\s*'([a-z]+-)" | sort -u | head -10
Build componentSystem:
componentSystem.selectorPrefixes[]componentSystem.layerClassification{}
2f. Infrastructure & Testing
# Detect test frameworks
find src/ -name "*.Test.cs" -o -name "*.spec.ts" | head -5
# Detect databases from connection strings
grep -r "ConnectionString\|MongoClient\|SqlConnection" src/ --include="*.json" -l | head -5
# Detect message broker
grep -r "RabbitMQ\|MassTransit\|Azure.Messaging" src/ --include="*.cs" -l | head -5
Build: testing, databases, messaging, api, infrastructure
2g. Framework & Shared
find src/ -name "*.csproj" -exec grep -l "PackageReference" {} \; | head -5
Build: framework.name, framework.searchPatternKeywords[]
2h. E2E Testing Infrastructure
Discover E2E testing setup — framework, paths, configurations:
# Detect E2E framework from package.json or .csproj
grep -l "playwright\|cypress\|selenium\|webdriver\|puppeteer" package.json */package.json 2>/dev/null
grep -r "Selenium.WebDriver\|Microsoft.Playwright" **/*.csproj 2>/dev/null | head -5
# Find E2E config files
ls playwright.config.* cypress.config.* wdio.conf.* protractor.conf.* 2>/dev/null
find . -path "*/e2e/*" -name "*.config.*" 2>/dev/null | head -5[:search]
# Find E2E test directories
ls -d testing/e2e/ tests/e2e/ e2e/ cypress/ playwright/ 2>/dev/null
find . -name "*.spec.ts" -path "*e2e*" 2>/dev/null | head -10
find . -name "*Tests.cs" -path "*E2E*" 2>/dev/null | head -10
# Find page objects
find . -name "*-page.ts" -o -name "*Page.cs" 2>/dev/null | head -10
# Find fixtures
find . -name "*fixture*" -path "*e2e*" 2>/dev/null | head -10
Build e2eTesting:
{
"e2eTesting": {
"framework": "playwright|cypress|selenium|webdriver",
"language": "typescript|csharp",
"configFile": "testing/e2e/tests/playwright.config.ts",
"testsPath": "testing/e2e/tests/specs/",
"pageObjectsPath": "testing/e2e/tests/page-objects/",
"fixturesPath": "testing/e2e/tests/fixtures/",
"guideDoc": "docs/project-reference/e2e-test-reference.md",
"testSpecsDocs": ["docs/test-specs/", "docs/business-features/**/detailed-features/*.md"],
"searchPatterns": ["test\\(['\"]TC-", "\\.spec\\.ts$", "\\[Trait"],
"runCommands": {
"all": "npm run e2e",
"headed": "npm run e2e:headed",
"ui": "npm run e2e:ui"
},
"tcCodeFormat": "TC-{MODULE}-E2E-{NNN}",
"bestPractices": [],
"entryPoints": []
}
}
Populate from discovered values:
framework: Detect from config files or package.jsontestsPath,pageObjectsPath,fixturesPath: Detect from directory structureconfigFile: Path to framework configtcCodeFormat: Detect pattern from existing tests (grep for TC- codes)entryPoints: List framework config + key fixture files
2i. Graph Connectors (auto-detect frontend→backend API mapping)
If the project has BOTH frontend AND backend modules (detected in Phase 2a), auto-populate graphConnectors to enable API endpoint detection:
Detection logic (AI decision):
-
Frontend framework detection:
@angular/corein any package.json →"angular"reactin any package.json →"react"vuein any package.json →"vue"- None detected →
"generic"
-
Backend framework detection:
.csprojwithMicrosoft.AspNetCore→"dotnet"@springbootorspring-boot-starter-webin pom.xml/build.gradle →"spring"expressin any package.json →"express"fastapiin any requirements.txt/pyproject.toml →"fastapi"- None detected →
"generic"
-
Path detection:
- Frontend paths: use module paths from
modules[]wherekind=frontend-app - Backend paths: use module paths from
modules[]wherekind=backend-service, filter to controller/route directories
- Frontend paths: use module paths from
-
Route prefix: Common prefixes:
"api"for .NET/Spring,""for Express/FastAPI. AI determines based on codebase evidence.
Build graphConnectors:
{
"graphConnectors": {
"apiEndpoints": {
"enabled": true,
"frontend": {
"framework": "<detected>",
"paths": ["<from modules[]>"],
"customPatterns": []
},
"backend": {
"framework": "<detected>",
"paths": ["<from modules[]>"],
"routePrefix": "<detected>",
"customPatterns": []
}
}
}
}
Rules:
- Only populate if both frontend AND backend are detected (skip for backend-only or frontend-only projects)
- Set
enabled: trueby default when both sides detected - Use AI judgment for ambiguous cases — if unsure, set
"generic"framework - Supported frameworks:
angular,react,vue,dotnet,spring,express,fastapi,generic
2j. Implicit Connections (auto-detect loosely coupled patterns)
If the project has backend services with event-driven or message bus patterns, auto-populate graphConnectors.implicitConnections[].
Detection heuristics (AI decision):
- If
.csfiles withEntityEventApplicationHandler<found inUseCaseEvents/dirs → suggestentity-definition-to-event-handlers+repo-crud-to-event-handlersrules - If
.csfiles withEntityEventBusMessageProducer<found inProducers/dirs → suggestentity-event-producersrule - If
.csfiles withEntityEventBusMessageConsumer<orPlatformApplicationMessageBusConsumer<found inConsumers/dirs → suggestbus-message-producers-to-consumers+free-format-message-consumersrules - If
.csfiles withCommandEventApplicationHandler<found → suggestcommand-event-handlersrule - If files contain
new \w+BusMessageorSendAsync.*BusMessageoutside ofProducers/dirs → suggestfree-format-bus-message-send-to-consumersrule (captures free-format messages sent directly via bus producer service, not via typed producer classes) - If files contain
FreeFormatMessages/directories with bus message class definitions → suggestfree-format-bus-message-class-to-consumersrule - For non-.NET projects: AI uses judgment to detect event/message patterns and propose custom rules (e.g., Redux actions, signal handlers, pub/sub patterns)
Rules:
- Only populate
implicitConnections[]when patterns are detected; omit if none found - Each rule must have
pathsscoped to relevant directories (not repo root) - Set
matchBy: "key-equals"by default; use"key-contains"only for fuzzy message name matching - MANDATORY: Present detected rules to user via
AskUserQuestionbefore writing — let user confirm or adjust patterns - After writing rules, run
python .claude/scripts/code_graph connect-implicit --jsonto verify edges are created - Report: "Created N implicit connection rules, detected M edges"
Merge Strategy
- If
modules[]is empty but v1 sections exist — leave v1 data, skipmodules[]generation (let hooks use v1 fallback) - If scanning fresh — populate
modules[]andcontextGroups[], skip deprecated v1 sections - Only overwrite a field if scan found concrete values — keep existing values for empty scan results
Phase 3: Write Updated Config
- Read the current file again (in case of concurrent changes)
- Merge discovered values into the existing structure
- Write
docs/project-config.jsonwithJSON.stringify(config, null, 2) - Preserve any existing values that scanning couldn't improve (e.g., manually curated quickTips)
Merge strategy: Only overwrite a field if the scan found concrete values. Keep existing values for fields where scan returned empty.
Phase 4: Verify (MANDATORY)
- Schema validation — Run the validator to ensure structure is intact:
bash
node -e " const { validateConfig, formatResult } = require('./.claude/hooks/lib/project-config-schema.cjs'); const config = JSON.parse(require('fs').readFileSync('docs/project-config.json', 'utf-8')); const result = validateConfig(config); console.log(formatResult(result)); process.exit(result.valid ? 0 : 1); " - If validation fails — fix the errors before proceeding. Never commit an invalid config.
- Spot-check 2-3 service paths to confirm they match actual directories
- Run hook tests:
node .claude/hooks/tests/test-all-hooks.cjs
Phase 5: Plan Reference Doc Population (MANDATORY)
After project-config is verified, AI MANDATORY IMPORTANT MUST create TaskCreate items to populate all reference docs via /scan-* skills. Each scan skill reads docs/project-config.json for project-specific paths — so this phase depends on Phases 1-4 completing first.
Canonical mapping (from SCAN_SKILL_MAP in .claude/hooks/session-init-docs.cjs):
| Reference Doc | Scan Skill Command |
|---|---|
project-structure-reference.md |
/scan-project-structure |
backend-patterns-reference.md |
/scan-backend-patterns |
design-system/ + scss-styling-guide.md + frontend-patterns-reference.md |
/scan-ui-system |
integration-test-reference.md |
/scan-integration-tests |
feature-docs-reference.md |
/scan-feature-docs |
code-review-rules.md |
/scan-code-review-rules |
e2e-test-reference.md |
/scan-e2e-tests |
domain-entities-reference.md |
/scan-domain-entities |
Instructions:
- Create one
TaskCreateper scan skill above (8 tasks total) - Each task subject:
"Run /scan-{name} to populate docs/{filename}" - Each task description:
"Invoke /scan-{name} skill to scan codebase and populate docs/{filename} with real project patterns." - Tasks should be
pending— execute sequentially after project-config phase completes /scan-project-structureshould run first (other scans may reference its output)- LAST TASK: After ALL scan skills complete, create a final task:
"Run /claude-md-init to generate CLAUDE.md from config + scan results". This must run last because it reads populated reference docs to build the documentation index and lookup guide.
E2E Investigation Guidance
When investigating or fixing E2E test failures, AI MUST:
-
Update
e2eTestingsection indocs/project-config.jsonwith any discovered patterns:- New run commands found
- Missing entry points identified
- Best practices learned from debugging
-
Update
docs/project-reference/e2e-test-reference.mdwith learnings:- Common failure patterns and fixes
- Setup gotchas (auth, fixtures, seed data)
- Environment-specific configurations
- Selector strategy tips for the project
-
Check TC code traceability — ensure all E2E tests have proper:
- TC code in test name:
TC-{MODULE}-E2E-{NNN} - Tags/traits linking to test specs
- Comments linking to feature docs
- TC code in test name:
Example update workflow:
# After fixing an E2E auth issue
# 1. Update project-config.json e2eTesting.bestPractices
# 2. Update docs/project-reference/e2e-test-reference.md "Common Issues" section
# 3. Add TC code to any tests that were missing them
Output
Report what changed:
- Sections updated vs unchanged
- New services/apps discovered
- Any path mismatches or warnings
- Reference doc scan tasks created (list all 10)
Post-Completion Tasks (MANDATORY)
After project-config scan completes, MUST create these follow-up tasks:
-
TaskCreate: "Run /graph-build to build code knowledge graph" — The knowledge graph uses project-config.json for API connector patterns and implicit connection rules. Building the graph after config ensures frontend↔backend API edges and MESSAGE_BUS edges are created correctly.
-
TaskCreate: "Run /docs-init or /scan-all to populate reference docs" — Reference docs (backend-patterns, frontend-patterns, etc.) depend on accurate project-config.json. Run scans after config is populated.
-
TaskCreate: "Verify graph edges: run
python .claude/scripts/code_graph status --json" — Confirm graph built successfully with API_ENDPOINT and MESSAGE_BUS edges.
Why graph-build after project-config? The graph auto-connect feature reads
graphConnectorsfrom project-config.json to match frontend HTTP calls with backend routes. Without populated config, auto-detection is used as fallback — but explicit config produces more accurate matches (custom patterns, scoped paths).
Closing Reminders
- MUST break work into small todo tasks using
TaskCreateBEFORE starting - MUST search codebase for 3+ similar patterns before creating new code
- MUST cite
file:lineevidence for every claim (confidence >80% to act) - MUST add a final review todo task to verify work quality
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
fix-parallel
[Implementation] Analyze & fix issues with parallel fullstack-developer agents
ask
[Utilities] Answer technical and architectural questions.
claude-code
[Utilities] Claude Code CLI setup, configuration, troubleshooting, and feature guidance. Triggers on claude code setup, hook not firing, MCP connection, context limit, skill creation, slash command setup.
workflow-deployment
[Workflow] Trigger Deployment & Infrastructure workflow — CI/CD pipelines, Docker, Kubernetes setup and deployment.
workflow-idea-to-pbi
[Workflow] Trigger Idea to PBI workflow — po/ba workflow: capture idea, refine to pbi, create stories, prioritize.
easy-claude-help
[Utilities] Configuration guide for the easy-claude framework — explain settings, guide users through configuring .ck.json.
Didn't find tool you were looking for?