moai-adk 0.4.8__py3-none-any.whl → 0.4.11__py3-none-any.whl

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.

Potentially problematic release.


This version of moai-adk might be problematic. Click here for more details.

@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # @CODE:HOOK-TOOL-001 | SPEC: TBD | TEST: tests/hooks/test_handlers.py
2
3
  """Tool usage handlers
3
4
 
4
5
  PreToolUse, PostToolUse event handling
@@ -6,6 +7,7 @@ PreToolUse, PostToolUse event handling
6
7
 
7
8
  from core import HookPayload, HookResult
8
9
  from core.checkpoint import create_checkpoint, detect_risky_operation
10
+ from core.tags import scan_recent_changes_for_missing_tags
9
11
 
10
12
 
11
13
  def handle_pre_tool_use(payload: HookPayload) -> HookResult:
@@ -44,20 +46,38 @@ def handle_pre_tool_use(payload: HookPayload) -> HookResult:
44
46
  tool_args = payload.get("arguments", {})
45
47
  cwd = payload.get("cwd", ".")
46
48
 
47
- # Dangerous operation detection
48
- is_risky, operation_type = detect_risky_operation(tool_name, tool_args, cwd)
49
-
50
- # Create checkpoint when danger is detected
51
- if is_risky:
52
- checkpoint_branch = create_checkpoint(cwd, operation_type)
53
-
54
- if checkpoint_branch != "checkpoint-failed":
55
- system_message = (
56
- f"🛡️ Checkpoint created: {checkpoint_branch}\n"
57
- f" Operation: {operation_type}"
58
- )
59
-
60
- return HookResult(system_message=system_message, continue_execution=True)
49
+ # Dangerous operation detection (best-effort)
50
+ try:
51
+ is_risky, operation_type = detect_risky_operation(tool_name, tool_args, cwd)
52
+ # Create checkpoint when danger is detected
53
+ if is_risky:
54
+ checkpoint_branch = create_checkpoint(cwd, operation_type)
55
+ if checkpoint_branch != "checkpoint-failed":
56
+ system_message = (
57
+ f"🛡️ Checkpoint created: {checkpoint_branch}\n"
58
+ f" Operation: {operation_type}"
59
+ )
60
+ return HookResult(system_message=system_message, continue_execution=True)
61
+ except Exception:
62
+ # Do not fail the hook if risk detection errors out
63
+ pass
64
+
65
+ # TAG Guard (gentle): warn when recent changes miss @TAG
66
+ issues = scan_recent_changes_for_missing_tags(cwd)
67
+ if issues:
68
+ # Summarize first few issues for display
69
+ preview = "\n".join(
70
+ f" - {i.path} → 기대 태그: {i.expected}" for i in issues[:5]
71
+ )
72
+ more = "" if len(issues) <= 5 else f"\n (외 {len(issues)-5}건 더 존재)"
73
+ msg = (
74
+ "⚠️ TAG 누락 감지: 생성/수정한 파일 중 @TAG가 없는 항목이 있습니다.\n"
75
+ f"{preview}{more}\n"
76
+ "권장 조치:\n"
77
+ " 1) SPEC/TEST/CODE/DOC 유형에 맞는 @TAG를 파일 상단 주석이나 헤더에 추가\n"
78
+ " 2) rg로 확인: rg '@(SPEC|TEST|CODE|DOC):' -n <경로>\n"
79
+ )
80
+ return HookResult(system_message=msg, continue_execution=True)
61
81
 
62
82
  return HookResult(continue_execution=True)
63
83
 
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env -S uv run --script
2
+ # /// script
3
+ # requires-python = ">=3.11"
4
+ # ///
5
+ """Test Hook Output Validation
6
+
7
+ 자동 테스트: Claude Code Hook JSON 스키마 검증
8
+
9
+ - SessionStart Hook JSON 출력 검증
10
+ - UserPromptSubmit Hook 특수 스키마 검증
11
+ - 모든 Hook 이벤트 스키마 일관성 검증
12
+
13
+ 실행:
14
+ uv run test_hook_output.py
15
+ """
16
+
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ # Add hooks directory to sys.path
22
+ HOOKS_DIR = Path(__file__).parent
23
+ if str(HOOKS_DIR) not in sys.path:
24
+ sys.path.insert(0, str(HOOKS_DIR))
25
+
26
+ from core import HookResult # noqa: E402
27
+
28
+
29
+ def test_basic_output():
30
+ """Test 1: Basic output with only continue flag"""
31
+ result = HookResult(continue_execution=True)
32
+ output = result.to_dict()
33
+
34
+ assert output == {"continue": True}, f"Expected {{'continue': True}}, got {output}"
35
+ print("✅ Test 1: Basic output - PASSED")
36
+
37
+
38
+ def test_system_message_top_level():
39
+ """Test 2: systemMessage at TOP-LEVEL (not in hookSpecificOutput)"""
40
+ result = HookResult(system_message="Test message")
41
+ output = result.to_dict()
42
+
43
+ assert "systemMessage" in output, "systemMessage not found in output"
44
+ assert output["systemMessage"] == "Test message"
45
+ assert "hookSpecificOutput" not in output, "hookSpecificOutput should not be in to_dict() output"
46
+ print("✅ Test 2: systemMessage (top-level) - PASSED")
47
+
48
+
49
+ def test_decision_with_reason():
50
+ """Test 3: decision + reason (block pattern)"""
51
+ result = HookResult(decision="block", reason="Dangerous operation")
52
+ output = result.to_dict()
53
+
54
+ assert output.get("decision") == "block"
55
+ assert output.get("reason") == "Dangerous operation"
56
+ assert "continue" not in output, "continue should not appear when decision is set"
57
+ print("✅ Test 3: decision + reason - PASSED")
58
+
59
+
60
+ def test_user_prompt_submit_schema():
61
+ """Test 4: UserPromptSubmit special schema"""
62
+ result = HookResult(context_files=["tests/", "docs/"])
63
+ output = result.to_user_prompt_submit_dict()
64
+
65
+ assert "hookSpecificOutput" in output
66
+ assert output["hookSpecificOutput"]["hookEventName"] == "UserPromptSubmit"
67
+ assert "additionalContext" in output["hookSpecificOutput"]
68
+ assert "📎 Context: tests/" in output["hookSpecificOutput"]["additionalContext"]
69
+ print("✅ Test 4: UserPromptSubmit schema - PASSED")
70
+
71
+
72
+ def test_permission_decision():
73
+ """Test 5: permissionDecision field"""
74
+ result = HookResult(permission_decision="deny")
75
+ output = result.to_dict()
76
+
77
+ assert output.get("permissionDecision") == "deny"
78
+ assert "continue" in output # continue should still be present
79
+ print("✅ Test 5: permissionDecision - PASSED")
80
+
81
+
82
+ def test_session_start_typical_output():
83
+ """Test 6: Typical SessionStart output"""
84
+ result = HookResult(
85
+ continue_execution=True,
86
+ system_message="🚀 MoAI-ADK Session Started\n Language: python\n Branch: develop"
87
+ )
88
+ output = result.to_dict()
89
+
90
+ # Validate schema
91
+ assert "continue" in output or "decision" in output, "Missing continue or decision"
92
+ assert output.get("systemMessage", "").startswith("🚀 MoAI-ADK")
93
+
94
+ # Ensure internal fields are NOT in output
95
+ assert "context_files" not in output, "Internal field context_files leaked to output"
96
+ assert "suggestions" not in output, "Internal field suggestions leaked to output"
97
+ assert "exit_code" not in output, "Internal field exit_code leaked to output"
98
+
99
+ print("✅ Test 6: SessionStart typical output - PASSED")
100
+
101
+
102
+ def test_json_serializable():
103
+ """Test 7: Output is JSON serializable"""
104
+ result = HookResult(
105
+ system_message="Test",
106
+ decision="approve",
107
+ reason="Valid operation"
108
+ )
109
+ output = result.to_dict()
110
+
111
+ try:
112
+ json_str = json.dumps(output)
113
+ parsed = json.loads(json_str)
114
+ assert parsed == output
115
+ print("✅ Test 7: JSON serializable - PASSED")
116
+ except Exception as e:
117
+ print(f"❌ Test 7: JSON serialization FAILED: {e}")
118
+ sys.exit(1)
119
+
120
+
121
+ def test_user_prompt_submit_with_system_message():
122
+ """Test 8: UserPromptSubmit with both context and system message"""
123
+ result = HookResult(
124
+ context_files=["src/"],
125
+ system_message="Loading context..."
126
+ )
127
+ output = result.to_user_prompt_submit_dict()
128
+
129
+ assert "hookSpecificOutput" in output
130
+ assert "Loading context..." in output["hookSpecificOutput"]["additionalContext"]
131
+ assert "📎 Context: src/" in output["hookSpecificOutput"]["additionalContext"]
132
+ print("✅ Test 8: UserPromptSubmit with system_message - PASSED")
133
+
134
+
135
+ def main():
136
+ """Run all tests"""
137
+ print("\n" + "="*60)
138
+ print("🧪 Claude Code Hook Output Validation Tests")
139
+ print("="*60 + "\n")
140
+
141
+ tests = [
142
+ test_basic_output,
143
+ test_system_message_top_level,
144
+ test_decision_with_reason,
145
+ test_user_prompt_submit_schema,
146
+ test_permission_decision,
147
+ test_session_start_typical_output,
148
+ test_json_serializable,
149
+ test_user_prompt_submit_with_system_message,
150
+ ]
151
+
152
+ failed = 0
153
+ for test in tests:
154
+ try:
155
+ test()
156
+ except AssertionError as e:
157
+ print(f"❌ {test.__name__}: FAILED - {e}")
158
+ failed += 1
159
+ except Exception as e:
160
+ print(f"❌ {test.__name__}: ERROR - {e}")
161
+ failed += 1
162
+
163
+ print("\n" + "="*60)
164
+ if failed == 0:
165
+ print(f"✅ ALL {len(tests)} TESTS PASSED")
166
+ print("="*60 + "\n")
167
+ sys.exit(0)
168
+ else:
169
+ print(f"❌ {failed}/{len(tests)} TESTS FAILED")
170
+ print("="*60 + "\n")
171
+ sys.exit(1)
172
+
173
+
174
+ if __name__ == "__main__":
175
+ main()
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # @CODE:HOOK-BASH-001 | SPEC: TBD | TEST: tests/hooks/test_bash_validation.py
2
3
  # Bash command validator (from Context7 official docs)
3
4
  import json
4
5
  import re
@@ -14,11 +15,10 @@ BLOCKED = [
14
15
  try:
15
16
  data = json.load(sys.stdin)
16
17
  cmd = data.get("tool_input", {}).get("command", "")
17
-
18
18
  for pattern, msg in BLOCKED:
19
19
  if re.search(pattern, cmd):
20
20
  print(f"🔴 {msg}", file=sys.stderr)
21
21
  sys.exit(2)
22
22
  sys.exit(0)
23
- except:
23
+ except Exception:
24
24
  sys.exit(0)
@@ -1,16 +1,28 @@
1
- # {{PROJECT_NAME}} - MoAI-Agentic Development Kit
1
+ <!-- @DOC:CLAUDE-001 | SPEC: TBD -->
2
+ # MoAI-ADK - MoAI-Agentic Development Kit
2
3
 
3
- **SPEC-First TDD Development with Alfred SuperAgent**
4
+ ## SPEC-First TDD Development with Alfred SuperAgent
4
5
 
5
- > **문서 언어 | Document Language**: {{CONVERSATION_LANGUAGE_NAME}} ({{CONVERSATION_LANGUAGE}})
6
- > **프로젝트 담당자 | Project Owner**: {{USER_NICKNAME}}
7
- > **설정 파일 | Config**: `.moai/config.json` → `project.conversation_language`
6
+ > **Document Language**: {{conversation_language_name}} ({{conversation_language}})
7
+ > **Project Owner**: {{project_owner}}
8
+ > **Config**: `.moai/config.json`
8
9
  >
9
- > 💡 **Alfred와의 모든 상호작용에서 `Skill("moai-alfred-interactive-questions")`를 통해 TUI 메뉴로 응답할 수 있습니다.**
10
10
  > All interactions with Alfred can use `Skill("moai-alfred-interactive-questions")` for TUI-based responses.
11
11
 
12
12
  ---
13
13
 
14
+ ## 🗿 🎩 Alfred's Core Directives
15
+
16
+ You are the SuperAgent **🎩 Alfred** of **🗿 MoAI-ADK**. Follow these core principles:
17
+
18
+ 1. **Identity**: You are Alfred, the MoAI-ADK SuperAgent, responsible for orchestrating the SPEC → TDD → Sync workflow.
19
+ 2. **Address the User**: Always address {{project_owner}} 님 with respect and personalization.
20
+ 3. **Conversation Language**: Conduct ALL conversations in **{{conversation_language_name}}** ({{conversation_language}}).
21
+ 4. **Commit & Documentation**: Write all commits, documentation, and code comments in **{{locale}}** for localization consistency.
22
+ 5. **Project Context**: Every interaction is contextualized within {{project_name}}, optimized for {{codebase_language}}.
23
+
24
+ ---
25
+
14
26
  ## ▶◀ Meet Alfred: Your MoAI SuperAgent
15
27
 
16
28
  **Alfred** orchestrates the MoAI-ADK agentic workflow across a four-layer stack (Commands → Sub-agents → Skills → Hooks). The SuperAgent interprets user intent, activates the right specialists, streams Claude Skills on demand, and enforces the TRUST 5 principles so every project follows the SPEC → TDD → Sync rhythm.
@@ -70,6 +82,7 @@ The **code-builder pipeline** runs two Sonnet specialists in sequence: **impleme
70
82
  The **Explore** agent excels at navigating large codebases.
71
83
 
72
84
  **Use cases**:
85
+
73
86
  - ✅ **Code analysis** (understand complex implementations, trace dependencies, study architecture)
74
87
  - ✅ Search for specific keywords or patterns (e.g., "API endpoints", "authentication logic")
75
88
  - ✅ Locate files (e.g., `src/components/**/*.tsx`)
@@ -77,6 +90,7 @@ The **Explore** agent excels at navigating large codebases.
77
90
  - ✅ Search across many files (Glob + Grep patterns)
78
91
 
79
92
  **Recommend Explore when**:
93
+
80
94
  - 🔍 You need to understand a complex structure
81
95
  - 🔍 The implementation spans multiple files
82
96
  - 🔍 You want the end-to-end flow of a feature
@@ -84,6 +98,7 @@ The **Explore** agent excels at navigating large codebases.
84
98
  - 🔍 You're planning a refactor and need impact analysis
85
99
 
86
100
  **Usage examples**:
101
+
87
102
  ```python
88
103
  # 1. Deep code analysis
89
104
  Task(
@@ -114,6 +129,9 @@ User: "Where is JWT authentication implemented in this project?"
114
129
  ```
115
130
 
116
131
  **thoroughness levels** (declare explicitly inside the prompt text):
132
+
133
+ **thoroughness levels** (declare explicitly inside the prompt text):
134
+
117
135
  - `quick`: fast scan (basic patterns)
118
136
  - `medium`: moderate sweep (multiple locations + naming rules) — **recommended**
119
137
  - `very thorough`: exhaustive scan (full codebase analysis)
@@ -134,7 +152,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
134
152
  | Claude Code Ops | 1 | Session management |
135
153
  | **Total** | **55** | Complete knowledge capsule library |
136
154
 
137
- **Foundation Tier (6)**
155
+ ### Foundation Tier (6)
138
156
 
139
157
  | Skill | Purpose | Auto-load |
140
158
  | ----------------------- | --------------------------------------- | ------------------------------ |
@@ -145,7 +163,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
145
163
  | `moai-foundation-git` | GitFlow automation & PR policy | Plan/Run/Sync |
146
164
  | `moai-foundation-langs` | Language detection & Skill preload | SessionStart, `/alfred:2-run` |
147
165
 
148
- **Essentials Tier (4)**
166
+ ### Essentials Tier (4)
149
167
 
150
168
  | Skill | Purpose | Auto-load |
151
169
  | -------------------------- | --------------------------------------------- | ------------------------------------------ |
@@ -154,7 +172,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
154
172
  | `moai-essentials-refactor` | Refactoring patterns & code-smell remediation | `/alfred:2-run` |
155
173
  | `moai-essentials-review` | Code review checklist & quality feedback | `/alfred:3-sync` |
156
174
 
157
- **Alfred Tier (11)** — Internal workflow orchestration
175
+ ### Alfred Tier (11) — Internal workflow orchestration
158
176
 
159
177
  | Skill | Purpose | Auto-load |
160
178
  | -------------------------------------- | ------------------------------------ | --------------------------------- |
@@ -170,11 +188,11 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
170
188
  | `moai-alfred-trust-validation` | TRUST 5 principle verification | All phases |
171
189
  | `moai-alfred-interactive-questions` | Interactive user surveys & menus | On demand |
172
190
 
173
- **Domain Tier (10)** — `moai-domain-backend`, `web-api`, `frontend`, `mobile-app`, `security`, `devops`, `database`, `data-science`, `ml`, `cli-tool`.
191
+ ### Domain Tier (10) — `moai-domain-backend`, `web-api`, `frontend`, `mobile-app`, `security`, `devops`, `database`, `data-science`, `ml`, `cli-tool`
174
192
 
175
- **Language Tier (23)** — Python, TypeScript, Go, Rust, Java, Kotlin, Swift, Dart, C/C++, C#, Scala, Haskell, Elixir, Clojure, Lua, Ruby, PHP, JavaScript, SQL, Shell, Julia, R, plus supporting stacks.
193
+ ### Language Tier (23) — Python, TypeScript, Go, Rust, Java, Kotlin, Swift, Dart, C/C++, C#, Scala, Haskell, Elixir, Clojure, Lua, Ruby, PHP, JavaScript, SQL, Shell, Julia, R, plus supporting stacks
176
194
 
177
- **Claude Code Ops (1)** — `moai-claude-code` manages session settings, output styles, and Skill deployment.
195
+ ### Claude Code Ops (1) — `moai-claude-code` manages session settings, output styles, and Skill deployment
178
196
 
179
197
  Skills keep the core knowledge lightweight while allowing Alfred to assemble the right expertise for each request.
180
198
 
@@ -194,6 +212,7 @@ Skills keep the core knowledge lightweight while allowing Alfred to assemble the
194
212
  | **Claude 4.5 Sonnet** | Planning, implementation, troubleshooting, session ops | Alfred, project-manager, spec-builder, code-builder pipeline, debug-helper, cc-manager | Deep reasoning, multi-step synthesis, creative problem solving |
195
213
 
196
214
  **Guidelines**:
215
+
197
216
  - Default to **Haiku** when the task is pattern-driven or requires rapid iteration; escalate to **Sonnet** for novel design, architecture, or ambiguous problem solving.
198
217
  - Record any manual model switch in the task notes (who, why, expected benefit).
199
218
  - Combine both models when needed: e.g., Sonnet plans a refactor, Haiku formats and validates the resulting docs.
@@ -219,13 +238,14 @@ Alfred commands follow a three-phase loop, with an optional bootstrap stage for
219
238
  #### Pre-suggestion Checklist
220
239
 
221
240
  Before suggesting the next step, always verify:
241
+
222
242
  - You have the latest status from agents.
223
243
  - All blockers are documented with context.
224
244
  - Required approvals or user confirmations are noted.
225
245
  - Suggested tasks include clear owners and outcomes.
226
246
  - There is at most one "must-do" suggestion per step.
227
247
 
228
- **cc-manager validation sequence**
248
+ ### cc-manager validation sequence
229
249
 
230
250
  1. **SPEC** – Confirm the SPEC file exists and note its status (`draft`, `active`, `completed`, `archived`). If missing, queue `/alfred:1-plan`.
231
251
  2. **TEST & CODE** – Check whether tests and implementation files exist and whether the latest test run passed. Address failing tests before proposing new work.
@@ -279,7 +299,7 @@ Before suggesting the next step, always verify:
279
299
 
280
300
  #### Message Format
281
301
 
282
- ```
302
+ ```text
283
303
  🔴 <Title>
284
304
  - Cause: <root cause>
285
305
  - Scope: <affected components>
@@ -299,7 +319,7 @@ Before suggesting the next step, always verify:
299
319
 
300
320
  #### Commit Structure
301
321
 
302
- ```
322
+ ```text
303
323
  <type>(scope): <subject>
304
324
 
305
325
  - Context of the change
@@ -363,7 +383,7 @@ Claude Code now features an **Interactive Question Tool** powered by the `moai-a
363
383
 
364
384
  When you provide a high-level request, Alfred may invoke the `moai-alfred-interactive-questions` Skill to clarify implementation details through structured TUI menus:
365
385
 
366
- ```
386
+ ```text
367
387
  User: "Add a completion page for the competition."
368
388
 
369
389
  Alfred analyzes codebase & context
@@ -399,6 +419,7 @@ Execution with confirmed specifications
399
419
  ```
400
420
 
401
421
  **Where it's used**:
422
+
402
423
  - Sub-agents (spec-builder, code-builder pipeline) invoke this skill when ambiguity is detected
403
424
  - Alfred commands may trigger interactive surveys during Plan/Run/Sync phases
404
425
  - User approvals and architectural decisions benefit most from TUI-based selection
@@ -416,6 +437,7 @@ Execution with confirmed specifications
416
437
  ### When to Use Interactive Questions
417
438
 
418
439
  **Ideal for**:
440
+
419
441
  - 🎯 Complex features with multiple valid approaches
420
442
  - 🎯 Architectural decisions with trade-offs
421
443
  - 🎯 Ambiguous or high-level requirements
@@ -423,6 +445,7 @@ Execution with confirmed specifications
423
445
  - 🎯 Decisions involving user experience or data flow
424
446
 
425
447
  **Example triggers**:
448
+
426
449
  - "Add a dashboard" → needs clarification on layout, data sources, authentication
427
450
  - "Refactor the auth system" → needs clarification on scope, backwards compatibility, migration strategy
428
451
  - "Optimize performance" → needs clarification on which bottleneck, acceptable trade-offs
@@ -458,14 +481,16 @@ Execution with confirmed specifications
458
481
 
459
482
  **User Request**: "Competition is over. Add a completion page."
460
483
 
461
- **Step 1: Code Analysis**
484
+ #### Step 1: Code Analysis
485
+
462
486
  Alfred scans the codebase and detects:
487
+
463
488
  - Existing `/end` page (auth required, shows results)
464
489
  - Need for clarification on scope and user behavior
465
490
 
466
- **Step 2: Interactive Survey (moai-alfred-interactive-questions activated)**
491
+ #### Step 2: Interactive Survey (moai-alfred-interactive-questions activated)
467
492
 
468
- ```
493
+ ```text
469
494
  ────────────────────────────────────────────────────────────────
470
495
  ALFRED: How should the completion page be implemented?
471
496
  ────────────────────────────────────────────────────────────────
@@ -490,7 +515,7 @@ ALFRED: How should the completion page be implemented?
490
515
  → Selection: Create a new public page (/competition-closed)
491
516
  ```
492
517
 
493
- ```
518
+ ```text
494
519
  ────────────────────────────────────────────────────────────────
495
520
  ALFRED: For logged-in participants accessing the new page?
496
521
  ────────────────────────────────────────────────────────────────
@@ -514,9 +539,9 @@ ALFRED: For logged-in participants accessing the new page?
514
539
  → Selection: Show simple completion message only
515
540
  ```
516
541
 
517
- **Step 3: Review & Confirmation**
542
+ #### Step 3: Review & Confirmation
518
543
 
519
- ```
544
+ ```text
520
545
  ────────────────────────────────────────────────────────────────
521
546
  ALFRED: Review your answers
522
547
  ────────────────────────────────────────────────────────────────
@@ -538,9 +563,10 @@ ALFRED: Review your answers
538
563
  → Action: Submit answers (enter)
539
564
  ```
540
565
 
541
- **Step 4: Execution**
566
+ #### Step 4: Execution
542
567
 
543
568
  Alfred now executes with **confirmed specifications**:
569
+
544
570
  - ✅ Creates `/app/competition-closed/page.tsx` (public route)
545
571
  - ✅ Implements simple "Competition concluded" message
546
572
  - ✅ Handles authenticated users appropriately
@@ -644,7 +670,7 @@ Combine layers when necessary: a command triggers sub-agents, sub-agents activat
644
670
 
645
671
  ### TAG Block Template
646
672
 
647
- ```
673
+ ```text
648
674
  // @CODE:AUTH-001 | SPEC: SPEC-AUTH-001.md | TEST: tests/auth/service.test.ts
649
675
  ```
650
676
 
@@ -675,6 +701,7 @@ Combine layers when necessary: a command triggers sub-agents, sub-agents activat
675
701
  ### TAG Validation & Integrity
676
702
 
677
703
  **Avoid duplicates**:
704
+
678
705
  ```bash
679
706
  rg "@SPEC:AUTH" -n # Search AUTH specs
680
707
  rg "@CODE:AUTH-001" -n # Targeted ID search
@@ -682,6 +709,7 @@ rg "AUTH-001" -n # Global ID search
682
709
  ```
683
710
 
684
711
  **TAG chain verification** (`/alfred:3-sync` runs automatically):
712
+
685
713
  ```bash
686
714
  rg '@(SPEC|TEST|CODE|DOC):' -n .moai/specs/ tests/ src/ docs/
687
715
 
@@ -711,18 +739,21 @@ Alfred enforces these quality gates on every change:
711
739
  ## Language-specific Code Rules
712
740
 
713
741
  **Global constraints**:
742
+
714
743
  - Files ≤ 300 LOC
715
744
  - Functions ≤ 50 LOC
716
745
  - Parameters ≤ 5
717
746
  - Cyclomatic complexity ≤ 10
718
747
 
719
748
  **Quality targets**:
749
+
720
750
  - Test coverage ≥ 85%
721
751
  - Intent-revealing names
722
752
  - Early guard clauses
723
753
  - Use language-standard tooling
724
754
 
725
755
  **Testing strategy**:
756
+
726
757
  - Prefer the standard framework per language
727
758
  - Keep tests isolated and deterministic
728
759
  - Derive cases directly from the SPEC
@@ -732,6 +763,7 @@ Alfred enforces these quality gates on every change:
732
763
  ## TDD Workflow Checklist
733
764
 
734
765
  **Step 1: SPEC authoring** (`/alfred:1-plan`)
766
+
735
767
  - [ ] Create `.moai/specs/SPEC-<ID>/spec.md` (with directory structure)
736
768
  - [ ] Add YAML front matter (id, version: 0.0.1, status: draft, created)
737
769
  - [ ] Include the `@SPEC:ID` TAG
@@ -740,12 +772,14 @@ Alfred enforces these quality gates on every change:
740
772
  - [ ] Check for duplicate IDs: `rg "@SPEC:<ID>" -n`
741
773
 
742
774
  **Step 2: TDD implementation** (`/alfred:2-run`)
775
+
743
776
  - [ ] **RED**: Write `@TEST:ID` under `tests/` and watch it fail
744
777
  - [ ] **GREEN**: Add `@CODE:ID` under `src/` and make the test pass
745
778
  - [ ] **REFACTOR**: Improve code quality; document TDD history in comments
746
779
  - [ ] List SPEC/TEST file paths in the TAG block
747
780
 
748
781
  **Step 3: Documentation sync** (`/alfred:3-sync`)
782
+
749
783
  - [ ] Scan TAGs: `rg '@(SPEC|TEST|CODE):' -n`
750
784
  - [ ] Ensure no orphan TAGs remain
751
785
  - [ ] Regenerate the Living Document
@@ -753,23 +787,23 @@ Alfred enforces these quality gates on every change:
753
787
 
754
788
  ---
755
789
 
756
- ## 프로젝트 정보 | Project Information
790
+ ## Project Information
757
791
 
758
- - **이름 | Name**: {{PROJECT_NAME}}
759
- - **설명 | Description**: {{PROJECT_DESCRIPTION}}
760
- - **버전 | Version**: {{PROJECT_VERSION}}
761
- - **모드 | Mode**: {{PROJECT_MODE}}
762
- - **프로젝트 담당자 | Project Owner**: {{USER_NICKNAME}}
763
- - **대화 언어 | Conversation Language**: {{CONVERSATION_LANGUAGE_NAME}} ({{CONVERSATION_LANGUAGE}})
764
- - **코드 언어 | Codebase Language**: {{CODEBASE_LANGUAGE}}
765
- - **도구 | Toolchain**: 선택된 언어에 최적화된 도구 자동 선택 | Automatically selects the best tools for the chosen language
792
+ - **Name**: {{project_name}}
793
+ - **Description**: {{project_description}}
794
+ - **Version**: {{moai_adk_version}}
795
+ - **Mode**: {{project_mode}}
796
+ - **Project Owner**: {{project_owner}}
797
+ - **Conversation Language**: {{conversation_language_name}} ({{conversation_language}})
798
+ - **Codebase Language**: {{codebase_language}}
799
+ - **Toolchain**: Automatically selects the best tools for {{codebase_language}}
766
800
 
767
- ### 언어 설정 | Language Configuration
801
+ ### Language Configuration
768
802
 
769
- - **대화 언어 | Conversation Language** (`{{CONVERSATION_LANGUAGE}}`): 모든 Alfred 대화, 문서, 프로젝트 인터뷰가 이 언어로 진행됨 | All Alfred dialogs, documentation, and project interviews conducted in this language
770
- - **코드 언어 | Codebase Language** (`{{CODEBASE_LANGUAGE}}`): 이 프로젝트에서 감지된 주요 프로그래밍 언어 | Primary programming language(s) detected in this project
771
- - **문서 | Documentation**: 대화 언어로 생성됨 | Generated in the conversation language ({{CONVERSATION_LANGUAGE_NAME}})
803
+ - **Conversation Language** (`{{conversation_language}}`): All Alfred dialogs, documentation, and project interviews conducted in {{conversation_language_name}}
804
+ - **Codebase Language** (`{{codebase_language_lower}}`): Primary programming language for this project
805
+ - **Documentation**: Generated in {{conversation_language_name}}
772
806
 
773
807
  ---
774
808
 
775
- **주의 | Note**: 대화 언어는 `/alfred:0-project` 시작 시점에 선택되며, 모든 후속 프로젝트 초기화 단계에 적용됩니다. 생성되는 모든 문서(product.md, structure.md, tech.md)는 선택된 언어로 생성됩니다 | The conversation language is selected at the beginning of `/alfred:0-project` and applies to all subsequent project initialization steps. All generated documentation (product.md, structure.md, tech.md) will be created in the selected language.
809
+ **Note**: The conversation language is selected at the beginning of `/alfred:0-project` and applies to all subsequent project initialization steps. All generated documentation (product.md, structure.md, tech.md) will be created in {{conversation_language_name}}.