all-for-claudecode 2.1.0 → 2.2.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.
@@ -0,0 +1,261 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # afc-consistency-check.sh — Cross-reference validation for project consistency
5
+ # Checks: config placeholders, agent names, hook scripts, test coverage
6
+ # Run as part of: npm run lint
7
+
8
+ # shellcheck disable=SC2329
9
+ cleanup() {
10
+ :
11
+ }
12
+ trap cleanup EXIT
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ PROJECT_DIR="${1:-$(cd "$SCRIPT_DIR/.." && pwd)}"
16
+ ERRORS=0
17
+ WARNINGS=0
18
+
19
+ # --- Helpers ---
20
+
21
+ fail() {
22
+ printf "[afc:consistency] FAIL: %s\n" "$1" >&2
23
+ ERRORS=$((ERRORS + 1))
24
+ }
25
+
26
+ warn() {
27
+ printf "[afc:consistency] WARN: %s\n" "$1" >&2
28
+ WARNINGS=$((WARNINGS + 1))
29
+ }
30
+
31
+ ok() {
32
+ printf "[afc:consistency] ✓ %s\n" "$1"
33
+ }
34
+
35
+ # --- Check 1: Config Placeholder Validation ---
36
+ # Verify all {config.*} references in commands/ and docs/ map to known config keys
37
+
38
+ check_config_placeholders() {
39
+ local template="$PROJECT_DIR/templates/afc.config.template.md"
40
+ if [ ! -f "$template" ]; then
41
+ warn "Config template not found: $template"
42
+ return
43
+ fi
44
+
45
+ # Extract valid config keys from template
46
+ # YAML keys: ci, gate, test
47
+ local yaml_keys
48
+ yaml_keys=$(grep -oE '^\s*[a-z_]+:' "$template" 2>/dev/null | sed 's/[[:space:]]*//;s/://' | sort -u || true)
49
+ # Section headers → lowercase with underscores: Architecture → architecture, Code Style → code_style, Project Context → project_context
50
+ local section_keys
51
+ section_keys=$(grep -oE '^## [A-Za-z ]+' "$template" 2>/dev/null \
52
+ | sed 's/^## //' \
53
+ | tr '[:upper:]' '[:lower:]' \
54
+ | sed 's/ /_/g' \
55
+ | sort -u || true)
56
+
57
+ local valid_keys
58
+ valid_keys=$(printf '%s\n%s\n' "$yaml_keys" "$section_keys" | sort -u)
59
+
60
+ # Extract all {config.*} references from commands and docs
61
+ local refs
62
+ refs=$(grep -rohE '\{config\.[a-z_]+\}' "$PROJECT_DIR/commands/" "$PROJECT_DIR/docs/" 2>/dev/null \
63
+ | sed 's/{config\.//;s/}//' \
64
+ | sort -u || true)
65
+
66
+ local count=0
67
+ local invalid=0
68
+ for ref in $refs; do
69
+ count=$((count + 1))
70
+ if ! printf '%s\n' "$valid_keys" | grep -qxF "$ref"; then
71
+ fail "{config.$ref} referenced but not defined in config template"
72
+ invalid=$((invalid + 1))
73
+ fi
74
+ done
75
+
76
+ if [ "$invalid" -eq 0 ]; then
77
+ ok "Config placeholders: $count references, all valid"
78
+ fi
79
+ }
80
+
81
+ # --- Check 2: Agent Name Consistency ---
82
+ # Verify subagent_type references in commands match agent definitions
83
+
84
+ check_agent_names() {
85
+ local agents_dir="$PROJECT_DIR/agents"
86
+ if [ ! -d "$agents_dir" ]; then
87
+ warn "Agents directory not found"
88
+ return
89
+ fi
90
+
91
+ # Extract agent names from agent files (name: field in frontmatter)
92
+ local defined_agents
93
+ defined_agents=$(grep -h '^name:' "$agents_dir"/*.md 2>/dev/null \
94
+ | sed 's/^name:[[:space:]]*//' \
95
+ | tr -d '"' \
96
+ | sort -u || true)
97
+
98
+ # Extract subagent_type references from commands (afc:agent-name pattern)
99
+ local referenced_agents
100
+ referenced_agents=$(grep -rohE 'subagent_type:[[:space:]]*"afc:[^"]*"' "$PROJECT_DIR/commands/" 2>/dev/null \
101
+ | sed 's/.*"afc://;s/"//' \
102
+ | sort -u || true)
103
+
104
+ local count=0
105
+ local invalid=0
106
+ for ref in $referenced_agents; do
107
+ count=$((count + 1))
108
+ if ! printf '%s\n' "$defined_agents" | grep -qxF "$ref"; then
109
+ fail "subagent_type 'afc:$ref' referenced but no agents/$ref.md found"
110
+ invalid=$((invalid + 1))
111
+ fi
112
+ done
113
+
114
+ # Check for unprefixed subagent_type that should have afc: prefix
115
+ local unprefixed
116
+ unprefixed=$(grep -rohE 'subagent_type:[[:space:]]*"afc-[^"]*"' "$PROJECT_DIR/commands/" 2>/dev/null \
117
+ | sed 's/.*subagent_type:[[:space:]]*"//;s/".*//' \
118
+ | sort -u || true)
119
+ for ref in $unprefixed; do
120
+ if printf '%s\n' "$defined_agents" | grep -qxF "$ref"; then
121
+ fail "subagent_type '$ref' should use 'afc:$ref' prefix (found in agents/)"
122
+ invalid=$((invalid + 1))
123
+ fi
124
+ done
125
+
126
+ if [ "$invalid" -eq 0 ]; then
127
+ ok "Agent names: $count references, all consistent"
128
+ fi
129
+ }
130
+
131
+ # --- Check 3: Hook Script Existence ---
132
+ # Verify all scripts referenced in hooks.json actually exist
133
+
134
+ check_hook_scripts() {
135
+ local hooks_file="$PROJECT_DIR/hooks/hooks.json"
136
+ if [ ! -f "$hooks_file" ]; then
137
+ warn "hooks.json not found"
138
+ return
139
+ fi
140
+
141
+ local scripts
142
+ scripts=$(grep -oE 'scripts/[^"]+\.sh' "$hooks_file" 2>/dev/null | sort -u || true)
143
+
144
+ local count=0
145
+ local missing=0
146
+ for script in $scripts; do
147
+ count=$((count + 1))
148
+ if [ ! -f "$PROJECT_DIR/$script" ]; then
149
+ fail "hooks.json references '$script' but file not found"
150
+ missing=$((missing + 1))
151
+ fi
152
+ done
153
+
154
+ if [ "$missing" -eq 0 ]; then
155
+ ok "Hook scripts: $count references, all exist"
156
+ fi
157
+ }
158
+
159
+ # --- Check 4: Test Coverage ---
160
+ # Verify each afc-*.sh script (except afc-state.sh library) has a spec file
161
+
162
+ check_test_coverage() {
163
+ local count=0
164
+ local missing=0
165
+ for script in "$PROJECT_DIR"/scripts/afc-*.sh; do
166
+ local scriptname
167
+ scriptname=$(basename "$script" .sh)
168
+ # Skip shared library and self (validation script)
169
+ if [ "$scriptname" = "afc-state" ] || [ "$scriptname" = "afc-consistency-check" ]; then
170
+ continue
171
+ fi
172
+ count=$((count + 1))
173
+ if [ ! -f "$PROJECT_DIR/spec/${scriptname}_spec.sh" ]; then
174
+ fail "scripts/$scriptname.sh has no spec/${scriptname}_spec.sh"
175
+ missing=$((missing + 1))
176
+ fi
177
+ done
178
+
179
+ if [ "$missing" -eq 0 ]; then
180
+ ok "Test coverage: $count scripts, all have specs"
181
+ fi
182
+ }
183
+
184
+ # --- Check 5: Version Sync ---
185
+ # Verify version numbers match across package.json, plugin.json, marketplace.json
186
+
187
+ check_version_sync() {
188
+ local pkg="$PROJECT_DIR/package.json"
189
+ local plugin="$PROJECT_DIR/.claude-plugin/plugin.json"
190
+ local market="$PROJECT_DIR/.claude-plugin/marketplace.json"
191
+
192
+ if [ ! -f "$pkg" ] || [ ! -f "$plugin" ] || [ ! -f "$market" ]; then
193
+ warn "One or more version files missing"
194
+ return
195
+ fi
196
+
197
+ local pkg_ver plugin_ver market_meta market_plugin
198
+ if command -v jq >/dev/null 2>&1; then
199
+ pkg_ver=$(jq -r '.version' "$pkg")
200
+ plugin_ver=$(jq -r '.version' "$plugin")
201
+ market_meta=$(jq -r '.metadata.version' "$market")
202
+ market_plugin=$(jq -r '.plugins[0].version' "$market")
203
+ else
204
+ pkg_ver=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$pkg" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
205
+ plugin_ver=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$plugin" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
206
+ market_meta=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$market" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
207
+ market_plugin=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$market" | sed -n '2p' | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
208
+ fi
209
+
210
+ if [ "$pkg_ver" = "$plugin_ver" ] && [ "$plugin_ver" = "$market_meta" ] && [ "$market_meta" = "$market_plugin" ]; then
211
+ ok "Version sync: $pkg_ver (all 4 match)"
212
+ else
213
+ fail "Version mismatch: package.json=$pkg_ver plugin.json=$plugin_ver marketplace.meta=$market_meta marketplace.plugin=$market_plugin"
214
+ fi
215
+ }
216
+
217
+ # --- Check 6: SSOT Phase Constants ---
218
+ # Verify SSOT phase list in afc-state.sh is not duplicated in other scripts
219
+
220
+ check_phase_ssot() {
221
+ # shellcheck source=afc-state.sh
222
+ . "$SCRIPT_DIR/afc-state.sh"
223
+
224
+ local dupes=0
225
+ # Look for hardcoded phase lists (pipe-separated patterns with 3+ known phases)
226
+ for script in "$PROJECT_DIR"/scripts/afc-*.sh; do
227
+ local scriptname
228
+ scriptname=$(basename "$script")
229
+ # Skip the SSOT source itself and this validation script
230
+ if [ "$scriptname" = "afc-state.sh" ] || [ "$scriptname" = "afc-consistency-check.sh" ]; then
231
+ continue
232
+ fi
233
+ # Check for hardcoded phase case patterns (spec|plan|...|clean style)
234
+ if grep -qE 'spec\|plan\|.*\|clean' "$script" 2>/dev/null; then
235
+ fail "$scriptname contains hardcoded phase list — use SSOT helpers from afc-state.sh"
236
+ dupes=$((dupes + 1))
237
+ fi
238
+ done
239
+
240
+ if [ "$dupes" -eq 0 ]; then
241
+ ok "Phase SSOT: no hardcoded phase lists found in scripts"
242
+ fi
243
+ }
244
+
245
+ # --- Run All Checks ---
246
+
247
+ printf "[afc:consistency] Running cross-reference validation...\n"
248
+
249
+ check_config_placeholders
250
+ check_agent_names
251
+ check_hook_scripts
252
+ check_test_coverage
253
+ check_version_sync
254
+ check_phase_ssot
255
+
256
+ printf "\n[afc:consistency] Done: %d errors, %d warnings\n" "$ERRORS" "$WARNINGS"
257
+
258
+ if [ "$ERRORS" -gt 0 ]; then
259
+ exit 1
260
+ fi
261
+ exit 0
@@ -59,7 +59,7 @@ if [ -f "$CONFIG_FILE" ]; then
59
59
  # Extract ci, gate, test values from YAML code block
60
60
  # Handles both quoted and unquoted: ci: "npm run lint" or ci: npm run lint
61
61
  for key in ci gate test; do
62
- val=$(grep -E "^${key}:" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/^[^:]*:[[:space:]]*//;s/^"//;s/"[[:space:]]*$//' || true)
62
+ val=$(grep -E "^\s*${key}:\s*\"[^\"]*\"" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/.*'"${key}"': *"\([^"]*\)".*/\1/' || true)
63
63
  if [ -n "$val" ] && [ "$val" != '""' ]; then
64
64
  DYNAMIC_WHITELIST="${DYNAMIC_WHITELIST:+${DYNAMIC_WHITELIST}|}${val}"
65
65
  # Generate PM-agnostic variants (npm → pnpm, yarn, bun)
@@ -97,6 +97,16 @@ if [ "$ALLOWED" = "false" ]; then
97
97
  esac
98
98
  fi
99
99
 
100
+ # Plugin's own scripts (auto-allow during pipeline execution)
101
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-}"
102
+ if [ "$ALLOWED" = "false" ] && [ -n "$PLUGIN_ROOT" ]; then
103
+ case "$COMMAND" in
104
+ "\"${PLUGIN_ROOT}/scripts/"*|"${PLUGIN_ROOT}/scripts/"*)
105
+ ALLOWED=true
106
+ ;;
107
+ esac
108
+ fi
109
+
100
110
  # Prefix matching (allow paths after shellcheck, prettier, chmod +x)
101
111
  if [ "$ALLOWED" = "false" ]; then
102
112
  case "$COMMAND" in
@@ -73,17 +73,14 @@ case "$COMMAND" in
73
73
 
74
74
  phase)
75
75
  PHASE="${2:?Phase name required}"
76
- case "$PHASE" in
77
- spec|plan|tasks|implement|review|clean|clarify|test-pre-gen|blast-radius|fast-path)
78
- afc_state_write "phase" "$PHASE"
79
- afc_state_invalidate_ci
80
- echo "Phase: $PHASE"
81
- ;;
82
- *)
83
- printf "[afc:pipeline] Invalid phase: %s\n → Valid phases: spec|plan|tasks|implement|review|clean|clarify|test-pre-gen|blast-radius\n" "$PHASE" >&2
84
- exit 1
85
- ;;
86
- esac
76
+ if afc_is_valid_phase "$PHASE"; then
77
+ afc_state_write "phase" "$PHASE"
78
+ afc_state_invalidate_ci
79
+ echo "Phase: $PHASE"
80
+ else
81
+ printf "[afc:pipeline] Invalid phase: %s\n → Valid phases: %s\n" "$PHASE" "$AFC_VALID_PHASES" >&2
82
+ exit 1
83
+ fi
87
84
  ;;
88
85
 
89
86
  ci-pass)
@@ -8,6 +8,26 @@
8
8
  _AFC_STATE_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.claude"
9
9
  _AFC_STATE_FILE="${_AFC_STATE_DIR}/.afc-state.json"
10
10
 
11
+ # --- Phase Constants (SSOT) ---
12
+ # All valid pipeline phases. Update HERE when adding a new phase.
13
+ AFC_VALID_PHASES="spec|plan|tasks|implement|review|clean|clarify|test-pre-gen|blast-radius|fast-path"
14
+ # Phases that do NOT require CI gate to pass (preparatory phases)
15
+ AFC_CI_EXEMPT_PHASES="spec|plan|tasks|clarify|test-pre-gen|blast-radius"
16
+
17
+ # Check if a phase name is valid
18
+ # Usage: afc_is_valid_phase <phase>
19
+ # Returns: 0 if valid, 1 if not
20
+ afc_is_valid_phase() {
21
+ printf '%s\n' "$AFC_VALID_PHASES" | tr '|' '\n' | grep -qxF "$1"
22
+ }
23
+
24
+ # Check if a phase is exempt from CI gate
25
+ # Usage: afc_is_ci_exempt <phase>
26
+ # Returns: 0 if exempt, 1 if CI required
27
+ afc_is_ci_exempt() {
28
+ printf '%s\n' "$AFC_CI_EXEMPT_PHASES" | tr '|' '\n' | grep -qxF "$1"
29
+ }
30
+
11
31
  # --- Public API ---
12
32
 
13
33
  # Check if pipeline is active (state file exists and has feature)
@@ -45,12 +45,10 @@ FEATURE="$(afc_state_read feature || echo '')"
45
45
  # Check current Phase
46
46
  CURRENT_PHASE="$(afc_state_read phase || echo '')"
47
47
 
48
- # Spec/Plan/Tasks Phase (1-3) do not require CI -> pass through
49
- case "${CURRENT_PHASE:-}" in
50
- spec|plan|tasks|clarify|test-pre-gen|blast-radius)
51
- exit 0
52
- ;;
53
- esac
48
+ # Preparatory phases do not require CI -> pass through
49
+ if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
50
+ exit 0
51
+ fi
54
52
 
55
53
  # Implement/Review/Clean Phase (4-6) require CI to pass
56
54
  CI_TIME="$(afc_state_read ciPassedAt 2>/dev/null || echo '')"
@@ -51,6 +51,13 @@ if [ -f "$CONFIG_FILE" ]; then
51
51
  if [ -n "$STYLE" ]; then
52
52
  CONTEXT="$CONTEXT | Code Style: $STYLE"
53
53
  fi
54
+
55
+ # Extract Project Context section (## Project Context to next ## or EOF)
56
+ # shellcheck disable=SC2001
57
+ PROJ_CTX=$(sed -n '/^## Project Context/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
58
+ if [ -n "$PROJ_CTX" ]; then
59
+ CONTEXT="$CONTEXT | Project Context: $PROJ_CTX"
60
+ fi
54
61
  fi
55
62
 
56
63
  # 5. Output as hookSpecificOutput JSON (required for SubagentStart context injection)
@@ -32,12 +32,10 @@ FEATURE="$(afc_state_read feature || echo '')"
32
32
  # Check current Phase
33
33
  CURRENT_PHASE="$(afc_state_read phase || echo '')"
34
34
 
35
- # Spec/Plan/Tasks Phase (1-3) do not require CI -> pass through
36
- case "${CURRENT_PHASE:-}" in
37
- spec|plan|tasks)
38
- exit 0
39
- ;;
40
- esac
35
+ # Preparatory phases do not require CI -> pass through
36
+ if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
37
+ exit 0
38
+ fi
41
39
 
42
40
  # Implement/Review/Clean Phase (4-6) require CI to pass
43
41
  CI_TIME="$(afc_state_read ciPassedAt 2>/dev/null || echo '')"
@@ -1,90 +1,26 @@
1
- # all-for-claudecode Configuration
1
+ # Project Configuration
2
2
 
3
- > This file defines project-specific settings for the afc command system.
4
- > All afc commands reference this file to determine project-specific behavior.
5
- > Modify each section to match your project.
3
+ > afc commands reference this file to determine project-specific behavior.
4
+ > CI Commands are parsed by scripts keep the YAML format intact.
5
+ > All other sections are free-form markdown — write whatever best describes your project.
6
6
 
7
7
  ## CI Commands
8
8
 
9
+ <!-- DO NOT change the format below. Scripts parse these keys. -->
9
10
  ```yaml
10
- ci: "npm run ci" # Full CI (lint + typecheck + build)
11
- typecheck: "npm run typecheck" # Typecheck only
12
- lint: "npm run lint" # Lint only
13
- lint_fix: "npm run lint:fix" # Auto-fix lint
14
- gate: "npm run typecheck && npm run lint" # Phase gate (run repeatedly during implement)
15
- test: "npm test" # Tests
11
+ ci: "npm run ci"
12
+ gate: "npm run typecheck && npm run lint"
13
+ test: "npm test"
16
14
  ```
17
15
 
18
16
  ## Architecture
19
17
 
20
- ```yaml
21
- style: "Layered" # e.g.: FSD, Clean Architecture, Modular Monolith, Layered
22
- layers: [] # List from top to bottom layer
23
- import_rule: "" # Import direction rule (e.g.: "upper → lower only")
24
- segments: [] # Sub-segments for each layer
25
- path_alias: "" # e.g.: "@/* → ./src/*"
26
- ```
27
-
28
- ## Framework
29
-
30
- ```yaml
31
- name: "" # e.g.: Next.js 14, Vite, CRA
32
- runtime: "" # e.g.: App Router, Pages Router
33
- client_directive: "" # e.g.: 'use client' (leave empty if not applicable)
34
- client_directive_rule: "" # Rule for applying client directives
35
- server_client_boundary: false # Whether a server/client boundary exists
36
- ```
18
+ (init analyzes your project and writes this section in free-form)
37
19
 
38
20
  ## Code Style
39
21
 
40
- ```yaml
41
- language: "TypeScript"
42
- strict_mode: true
43
- type_keyword: "type" # type vs interface
44
- import_type: true # Whether to use import type
45
- component_style: "PascalCase"
46
- props_position: "above component"
47
- handler_naming: "handle[Event]"
48
- boolean_naming: "is/has/can[State]"
49
- constant_naming: "UPPER_SNAKE_CASE"
50
- any_policy: "minimize"
51
- ```
52
-
53
- ## State Management
54
-
55
- ```yaml
56
- global_state: "" # e.g.: Zustand, Redux, Pinia
57
- server_state: "" # e.g.: React Query, SWR, Apollo
58
- local_state: "" # e.g.: Context API, useState
59
- store_location: "" # Store file location pattern
60
- query_location: "" # Query file location pattern
61
- ```
62
-
63
- ## Styling
64
-
65
- ```yaml
66
- framework: "" # e.g.: Tailwind CSS, styled-components, CSS Modules
67
- ```
68
-
69
- ## Testing
70
-
71
- ```yaml
72
- framework: "" # e.g.: Jest, Vitest, Playwright
73
- ```
74
-
75
- ## Project-Specific Risks
76
-
77
- > Project-specific risk patterns that must be checked in the Plan's RISK Critic
78
- > Modify to match your project.
79
-
80
- 1. (example) Import order violation
81
- 2. (example) Circular reference
82
- 3. (example) Type safety bypass (as any)
83
-
84
- ## Mini-Review Checklist
22
+ (init analyzes your project and writes this section in free-form)
85
23
 
86
- > Items to inspect for each file in the Mini-Review of the Implement Phase gate
24
+ ## Project Context
87
25
 
88
- 1. Architecture rule violations
89
- 2. Code style pattern compliance
90
- 3. Dead code (unused imports, empty exports, dead code)
26
+ (init analyzes your project and writes this section in free-form — framework, state management, styling, testing, risks, etc.)
@@ -1,99 +0,0 @@
1
- # all-for-claudecode Configuration
2
-
3
- > This file defines project-specific settings for the afc command system.
4
- > All afc commands reference this file to determine project-specific behavior.
5
-
6
- ## CI Commands
7
-
8
- ```yaml
9
- ci: "npm run build && npm run lint && npm run test" # Full CI (build + lint + test)
10
- typecheck: "npx tsc --noEmit" # Typecheck only
11
- lint: "npx eslint src/" # Lint only
12
- lint_fix: "npx eslint src/ --fix" # Auto-fix lint
13
- gate: "npx tsc --noEmit && npx eslint src/" # Phase gate (run repeatedly during implement)
14
- test: "npx jest --runInBand" # Tests
15
- ```
16
-
17
- ## Architecture
18
-
19
- ```yaml
20
- style: "Layered" # Layered architecture
21
- layers: # Top → bottom order
22
- - src/routes
23
- - src/controllers
24
- - src/services
25
- - src/repositories
26
- - src/models
27
- - src/middleware
28
- - src/lib
29
- - src/types
30
- - src/config
31
- import_rule: "Upper layers (routes) depend only in order: controllers → services → repositories"
32
- segments: []
33
- path_alias: "@/* → ./src/*"
34
- ```
35
-
36
- ## Framework
37
-
38
- ```yaml
39
- name: "Express.js"
40
- runtime: "Node.js (CommonJS or ESM)"
41
- client_directive: "" # Server-only — not applicable
42
- server_client_boundary: false # Server-only application
43
- ```
44
-
45
- ## Code Style
46
-
47
- ```yaml
48
- language: "TypeScript"
49
- strict_mode: true
50
- type_keyword: "type" # Use type instead of interface
51
- import_type: true # Use import type { ... }
52
- component_style: "" # No UI components
53
- props_position: "" # No UI components
54
- handler_naming: "camelCase"
55
- boolean_naming: "is/has/can[State]"
56
- constant_naming: "UPPER_SNAKE_CASE"
57
- any_policy: "banned (use unknown with strict mode)"
58
- ```
59
-
60
- ## State Management
61
-
62
- ```yaml
63
- global_state: "" # Server — stateless
64
- server_state: ""
65
- local_state: ""
66
- store_location: ""
67
- query_location: ""
68
- ```
69
-
70
- ## Styling
71
-
72
- ```yaml
73
- framework: "" # Not applicable
74
- ```
75
-
76
- ## Testing
77
-
78
- ```yaml
79
- framework: "Jest + Supertest"
80
- ```
81
-
82
- ## Project-Specific Risks
83
-
84
- > Project-specific risk patterns that must be checked in the Plan's RISK Critic
85
-
86
- 1. Prisma migration and schema mismatch
87
- 2. Express middleware ordering errors (auth → validation → handler)
88
- 3. Missing async/await error handling (try-catch or wrapper)
89
- 4. Runtime errors when environment variables (.env) are not set
90
- 5. SQL injection (caution with raw queries when using Prisma)
91
-
92
- ## Mini-Review Checklist
93
-
94
- > Items to inspect for each file in the Mini-Review of the Implement Phase gate
95
-
96
- 1. TypeScript strict mode violations
97
- 2. Error handling (try-catch or asyncHandler on async routes)
98
- 3. Input validation (type checking of req.body/params/query)
99
- 4. Unused imports / dead code