moai-adk 0.4.10__py3-none-any.whl → 0.5.0__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.

@@ -55,6 +55,7 @@ Setup sys.path for package imports
55
55
  import json
56
56
  import sys
57
57
  from pathlib import Path
58
+ from typing import Any
58
59
 
59
60
  from core import HookResult
60
61
  from handlers import (
@@ -136,7 +136,8 @@ class HookResult:
136
136
  Examples:
137
137
  >>> result = HookResult(context_files=["tests/"])
138
138
  >>> result.to_user_prompt_submit_dict()
139
- {'continue': True, 'hookSpecificOutput': {'hookEventName': 'UserPromptSubmit', 'additionalContext': '📎 Context: tests/'}}
139
+ {'continue': True, 'hookSpecificOutput': \
140
+ {'hookEventName': 'UserPromptSubmit', 'additionalContext': '📎 Context: tests/'}}
140
141
  """
141
142
  # Convert context_files to additionalContext string
142
143
  if self.context_files:
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env python3
2
+ # @CODE:HOOK-TAG-001 | SPEC: TBD | TEST: tests/hooks/test_tag_validation.py
3
+ """TAG validation helpers for MoAI-ADK hooks
4
+
5
+ Fast checks used by PreToolUse/PostToolUse to nudge users when
6
+ new or modified files are missing required @TAG annotations.
7
+
8
+ Configurable rules with sensible defaults:
9
+ - Load patterns from .moai/tag-rules.json if present.
10
+ - Otherwise, apply default glob patterns (folder names are not hard-coded only).
11
+
12
+ Defaults (order matters; first match wins):
13
+ 1) SPEC
14
+ - .moai/specs/**
15
+ - **/SPEC-*/spec.md
16
+ 2) TEST
17
+ - **/*_test.py, **/test_*.py, **/*.test.* (ts,tsx,js,jsx,go,rs)
18
+ - **/*.spec.* (ts,tsx,js,jsx)
19
+ - tests/**
20
+ 3) DOC
21
+ - docs/**/*.md, **/README.md, **/*.api.md
22
+ 4) CODE
23
+ - Source extensions: .py,.ts,.tsx,.js,.jsx,.go,.rs,.java,.kt,.rb,.php,.c,.cpp,.cs,.swift,.scala
24
+ - Excluding TEST patterns
25
+
26
+ Notes:
27
+ - Best-effort: skip binary/large files and non-target paths
28
+ - Do not block execution; return a list of issues for messaging
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import fnmatch
34
+ import json
35
+ import subprocess
36
+ from dataclasses import dataclass
37
+ from pathlib import Path
38
+ from typing import Iterable, List, Optional
39
+
40
+ DEFAULT_CODE_EXTS = (
41
+ ".py", ".ts", ".tsx", ".js", ".jsx", ".go", ".rs",
42
+ ".java", ".kt", ".rb", ".php", ".c", ".cpp", ".cs",
43
+ ".swift", ".scala"
44
+ )
45
+
46
+
47
+ @dataclass
48
+ class TagIssue:
49
+ path: str
50
+ expected: str # one of @SPEC, @TEST, @CODE, @DOC
51
+ reason: str
52
+
53
+
54
+ @dataclass
55
+ class Rule:
56
+ include: List[str]
57
+ expect: str # '@SPEC:' | '@TEST:' | '@CODE:' | '@DOC:'
58
+ exclude: List[str]
59
+
60
+
61
+ def _load_rules(cwd: str) -> List[Rule]:
62
+ """Load tag rules from .moai/tag-rules.json or return defaults.
63
+
64
+ Schema example:
65
+ {
66
+ "rules": [
67
+ {"include": ["**/*_test.py", "**/*.test.ts"], "expect": "@TEST:", "exclude": []},
68
+ {"include": ["docs/**/*.md", "**/README.md"], "expect": "@DOC:", "exclude": []}
69
+ ]
70
+ }
71
+ """
72
+ cfg = Path(cwd) / ".moai" / "tag-rules.json"
73
+ if cfg.exists():
74
+ try:
75
+ data = json.loads(cfg.read_text(encoding="utf-8"))
76
+ items = data.get("rules", [])
77
+ rules: List[Rule] = []
78
+ for it in items:
79
+ include = list(it.get("include", []))
80
+ expect = str(it.get("expect", ""))
81
+ exclude = list(it.get("exclude", []))
82
+ if include and expect in ("@SPEC:", "@TEST:", "@CODE:", "@DOC:"):
83
+ rules.append(Rule(include=include, expect=expect, exclude=exclude))
84
+ if rules:
85
+ return rules
86
+ except Exception:
87
+ pass
88
+
89
+ # Defaults (ordered)
90
+ return [
91
+ Rule(
92
+ include=[".moai/specs/**", "**/SPEC-*/spec.md"],
93
+ expect="@SPEC:",
94
+ exclude=[]
95
+ ),
96
+ Rule(
97
+ include=[
98
+ "**/*_test.py", "**/test_*.py", "**/*.test.ts",
99
+ "**/*.test.tsx", "**/*.test.js", "**/*.test.jsx",
100
+ "**/*.test.go", "**/*.test.rs", "**/*.spec.ts",
101
+ "**/*.spec.tsx", "tests/**"
102
+ ],
103
+ expect="@TEST:",
104
+ exclude=[".claude/**"]
105
+ ),
106
+ Rule(
107
+ include=["docs/**/*.md", "**/README.md", "**/*.api.md"],
108
+ expect="@DOC:",
109
+ exclude=[".claude/**"]
110
+ ),
111
+ Rule(
112
+ include=["**/*"],
113
+ expect="@CODE:",
114
+ exclude=[
115
+ "tests/**", "docs/**", ".moai/**", ".claude/**",
116
+ "**/*.md", "**/*.json", "**/*.yml", "**/*.yaml",
117
+ "**/*.toml", "**/*.lock", "**/*.svg", "**/*.png",
118
+ "**/*.jpg", "**/*.jpeg", "**/*.gif"
119
+ ]
120
+ ),
121
+ ]
122
+
123
+
124
+ def _match_any(path: str, patterns: List[str]) -> bool:
125
+ return any(fnmatch.fnmatch(path, pat) for pat in patterns)
126
+
127
+
128
+ def _needs_tag_str(path_str: str, rules: List[Rule]) -> Optional[str]:
129
+ p = path_str
130
+ for rule in rules:
131
+ if _match_any(p, rule.include) and not _match_any(p, rule.exclude):
132
+ if rule.expect == "@CODE:":
133
+ # CODE: limit to source-like extensions to reduce noise
134
+ if not any(p.endswith(ext) for ext in DEFAULT_CODE_EXTS):
135
+ continue
136
+ return rule.expect
137
+ return None
138
+
139
+
140
+ def _has_tag(content: str, expected: str) -> bool:
141
+ return expected in content
142
+
143
+
144
+ def _iter_recent_changes(cwd: str) -> Iterable[Path]:
145
+ root = Path(cwd)
146
+ try:
147
+ # Staged files
148
+ r1 = subprocess.run(
149
+ ["git", "diff", "--name-only", "--cached"],
150
+ cwd=cwd, capture_output=True, text=True, timeout=1
151
+ )
152
+ # Modified (unstaged) tracked files
153
+ r2 = subprocess.run(
154
+ ["git", "ls-files", "-m"],
155
+ cwd=cwd, capture_output=True, text=True, timeout=1
156
+ )
157
+ # Untracked (other) files respecting .gitignore
158
+ r3 = subprocess.run(
159
+ ["git", "ls-files", "-o", "--exclude-standard"],
160
+ cwd=cwd, capture_output=True, text=True, timeout=1
161
+ )
162
+ names = set()
163
+ if r1.returncode == 0:
164
+ names.update([line.strip() for line in r1.stdout.splitlines() if line.strip()])
165
+ if r2.returncode == 0:
166
+ names.update([line.strip() for line in r2.stdout.splitlines() if line.strip()])
167
+ if r3.returncode == 0:
168
+ names.update([line.strip() for line in r3.stdout.splitlines() if line.strip()])
169
+ for n in names:
170
+ p = (root / n).resolve()
171
+ if p.is_file():
172
+ yield p
173
+ except Exception:
174
+ return []
175
+
176
+
177
+ def scan_recent_changes_for_missing_tags(cwd: str) -> list[TagIssue]:
178
+ issues: list[TagIssue] = []
179
+ rules = _load_rules(cwd)
180
+ root = Path(cwd).resolve()
181
+ for path in _iter_recent_changes(cwd):
182
+ try:
183
+ content = path.read_text(encoding="utf-8", errors="ignore")
184
+ except Exception:
185
+ continue
186
+ # compute relative path once and use for matching/excluding
187
+ try:
188
+ rel = path.resolve().relative_to(root)
189
+ rel_s = rel.as_posix()
190
+ except Exception:
191
+ rel_s = path.name
192
+
193
+ expected = _needs_tag_str(rel_s, rules)
194
+ if not expected:
195
+ continue
196
+ if not _has_tag(content, expected):
197
+ issues.append(TagIssue(path=rel_s, expected=expected, reason="missing tag"))
198
+ return issues
@@ -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
 
@@ -23,7 +23,7 @@ HOOKS_DIR = Path(__file__).parent
23
23
  if str(HOOKS_DIR) not in sys.path:
24
24
  sys.path.insert(0, str(HOOKS_DIR))
25
25
 
26
- from core import HookResult
26
+ from core import HookResult # noqa: E402
27
27
 
28
28
 
29
29
  def test_basic_output():
@@ -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,10 +1,11 @@
1
+ <!-- @DOC:CLAUDE-001 | SPEC: TBD -->
1
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
6
  > **Document Language**: {{conversation_language_name}} ({{conversation_language}})
6
7
  > **Project Owner**: {{project_owner}}
7
- > **Config**: `.moai/config.json` → `project.conversation_language`
8
+ > **Config**: `.moai/config.json`
8
9
  >
9
10
  > All interactions with Alfred can use `Skill("moai-alfred-interactive-questions")` for TUI-based responses.
10
11
 
@@ -81,6 +82,7 @@ The **code-builder pipeline** runs two Sonnet specialists in sequence: **impleme
81
82
  The **Explore** agent excels at navigating large codebases.
82
83
 
83
84
  **Use cases**:
85
+
84
86
  - ✅ **Code analysis** (understand complex implementations, trace dependencies, study architecture)
85
87
  - ✅ Search for specific keywords or patterns (e.g., "API endpoints", "authentication logic")
86
88
  - ✅ Locate files (e.g., `src/components/**/*.tsx`)
@@ -88,6 +90,7 @@ The **Explore** agent excels at navigating large codebases.
88
90
  - ✅ Search across many files (Glob + Grep patterns)
89
91
 
90
92
  **Recommend Explore when**:
93
+
91
94
  - 🔍 You need to understand a complex structure
92
95
  - 🔍 The implementation spans multiple files
93
96
  - 🔍 You want the end-to-end flow of a feature
@@ -95,6 +98,7 @@ The **Explore** agent excels at navigating large codebases.
95
98
  - 🔍 You're planning a refactor and need impact analysis
96
99
 
97
100
  **Usage examples**:
101
+
98
102
  ```python
99
103
  # 1. Deep code analysis
100
104
  Task(
@@ -125,6 +129,9 @@ User: "Where is JWT authentication implemented in this project?"
125
129
  ```
126
130
 
127
131
  **thoroughness levels** (declare explicitly inside the prompt text):
132
+
133
+ **thoroughness levels** (declare explicitly inside the prompt text):
134
+
128
135
  - `quick`: fast scan (basic patterns)
129
136
  - `medium`: moderate sweep (multiple locations + naming rules) — **recommended**
130
137
  - `very thorough`: exhaustive scan (full codebase analysis)
@@ -145,7 +152,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
145
152
  | Claude Code Ops | 1 | Session management |
146
153
  | **Total** | **55** | Complete knowledge capsule library |
147
154
 
148
- **Foundation Tier (6)**
155
+ ### Foundation Tier (6)
149
156
 
150
157
  | Skill | Purpose | Auto-load |
151
158
  | ----------------------- | --------------------------------------- | ------------------------------ |
@@ -156,7 +163,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
156
163
  | `moai-foundation-git` | GitFlow automation & PR policy | Plan/Run/Sync |
157
164
  | `moai-foundation-langs` | Language detection & Skill preload | SessionStart, `/alfred:2-run` |
158
165
 
159
- **Essentials Tier (4)**
166
+ ### Essentials Tier (4)
160
167
 
161
168
  | Skill | Purpose | Auto-load |
162
169
  | -------------------------- | --------------------------------------------- | ------------------------------------------ |
@@ -165,7 +172,7 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
165
172
  | `moai-essentials-refactor` | Refactoring patterns & code-smell remediation | `/alfred:2-run` |
166
173
  | `moai-essentials-review` | Code review checklist & quality feedback | `/alfred:3-sync` |
167
174
 
168
- **Alfred Tier (11)** — Internal workflow orchestration
175
+ ### Alfred Tier (11) — Internal workflow orchestration
169
176
 
170
177
  | Skill | Purpose | Auto-load |
171
178
  | -------------------------------------- | ------------------------------------ | --------------------------------- |
@@ -181,11 +188,11 @@ Alfred relies on 55 Claude Skills grouped by tier. Skills load via Progressive D
181
188
  | `moai-alfred-trust-validation` | TRUST 5 principle verification | All phases |
182
189
  | `moai-alfred-interactive-questions` | Interactive user surveys & menus | On demand |
183
190
 
184
- **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`
185
192
 
186
- **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
187
194
 
188
- **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
189
196
 
190
197
  Skills keep the core knowledge lightweight while allowing Alfred to assemble the right expertise for each request.
191
198
 
@@ -205,6 +212,7 @@ Skills keep the core knowledge lightweight while allowing Alfred to assemble the
205
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 |
206
213
 
207
214
  **Guidelines**:
215
+
208
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.
209
217
  - Record any manual model switch in the task notes (who, why, expected benefit).
210
218
  - Combine both models when needed: e.g., Sonnet plans a refactor, Haiku formats and validates the resulting docs.
@@ -230,13 +238,14 @@ Alfred commands follow a three-phase loop, with an optional bootstrap stage for
230
238
  #### Pre-suggestion Checklist
231
239
 
232
240
  Before suggesting the next step, always verify:
241
+
233
242
  - You have the latest status from agents.
234
243
  - All blockers are documented with context.
235
244
  - Required approvals or user confirmations are noted.
236
245
  - Suggested tasks include clear owners and outcomes.
237
246
  - There is at most one "must-do" suggestion per step.
238
247
 
239
- **cc-manager validation sequence**
248
+ ### cc-manager validation sequence
240
249
 
241
250
  1. **SPEC** – Confirm the SPEC file exists and note its status (`draft`, `active`, `completed`, `archived`). If missing, queue `/alfred:1-plan`.
242
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.
@@ -290,7 +299,7 @@ Before suggesting the next step, always verify:
290
299
 
291
300
  #### Message Format
292
301
 
293
- ```
302
+ ```text
294
303
  🔴 <Title>
295
304
  - Cause: <root cause>
296
305
  - Scope: <affected components>
@@ -310,7 +319,7 @@ Before suggesting the next step, always verify:
310
319
 
311
320
  #### Commit Structure
312
321
 
313
- ```
322
+ ```text
314
323
  <type>(scope): <subject>
315
324
 
316
325
  - Context of the change
@@ -374,7 +383,7 @@ Claude Code now features an **Interactive Question Tool** powered by the `moai-a
374
383
 
375
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:
376
385
 
377
- ```
386
+ ```text
378
387
  User: "Add a completion page for the competition."
379
388
 
380
389
  Alfred analyzes codebase & context
@@ -410,6 +419,7 @@ Execution with confirmed specifications
410
419
  ```
411
420
 
412
421
  **Where it's used**:
422
+
413
423
  - Sub-agents (spec-builder, code-builder pipeline) invoke this skill when ambiguity is detected
414
424
  - Alfred commands may trigger interactive surveys during Plan/Run/Sync phases
415
425
  - User approvals and architectural decisions benefit most from TUI-based selection
@@ -427,6 +437,7 @@ Execution with confirmed specifications
427
437
  ### When to Use Interactive Questions
428
438
 
429
439
  **Ideal for**:
440
+
430
441
  - 🎯 Complex features with multiple valid approaches
431
442
  - 🎯 Architectural decisions with trade-offs
432
443
  - 🎯 Ambiguous or high-level requirements
@@ -434,6 +445,7 @@ Execution with confirmed specifications
434
445
  - 🎯 Decisions involving user experience or data flow
435
446
 
436
447
  **Example triggers**:
448
+
437
449
  - "Add a dashboard" → needs clarification on layout, data sources, authentication
438
450
  - "Refactor the auth system" → needs clarification on scope, backwards compatibility, migration strategy
439
451
  - "Optimize performance" → needs clarification on which bottleneck, acceptable trade-offs
@@ -469,14 +481,16 @@ Execution with confirmed specifications
469
481
 
470
482
  **User Request**: "Competition is over. Add a completion page."
471
483
 
472
- **Step 1: Code Analysis**
484
+ #### Step 1: Code Analysis
485
+
473
486
  Alfred scans the codebase and detects:
487
+
474
488
  - Existing `/end` page (auth required, shows results)
475
489
  - Need for clarification on scope and user behavior
476
490
 
477
- **Step 2: Interactive Survey (moai-alfred-interactive-questions activated)**
491
+ #### Step 2: Interactive Survey (moai-alfred-interactive-questions activated)
478
492
 
479
- ```
493
+ ```text
480
494
  ────────────────────────────────────────────────────────────────
481
495
  ALFRED: How should the completion page be implemented?
482
496
  ────────────────────────────────────────────────────────────────
@@ -501,7 +515,7 @@ ALFRED: How should the completion page be implemented?
501
515
  → Selection: Create a new public page (/competition-closed)
502
516
  ```
503
517
 
504
- ```
518
+ ```text
505
519
  ────────────────────────────────────────────────────────────────
506
520
  ALFRED: For logged-in participants accessing the new page?
507
521
  ────────────────────────────────────────────────────────────────
@@ -525,9 +539,9 @@ ALFRED: For logged-in participants accessing the new page?
525
539
  → Selection: Show simple completion message only
526
540
  ```
527
541
 
528
- **Step 3: Review & Confirmation**
542
+ #### Step 3: Review & Confirmation
529
543
 
530
- ```
544
+ ```text
531
545
  ────────────────────────────────────────────────────────────────
532
546
  ALFRED: Review your answers
533
547
  ────────────────────────────────────────────────────────────────
@@ -549,9 +563,10 @@ ALFRED: Review your answers
549
563
  → Action: Submit answers (enter)
550
564
  ```
551
565
 
552
- **Step 4: Execution**
566
+ #### Step 4: Execution
553
567
 
554
568
  Alfred now executes with **confirmed specifications**:
569
+
555
570
  - ✅ Creates `/app/competition-closed/page.tsx` (public route)
556
571
  - ✅ Implements simple "Competition concluded" message
557
572
  - ✅ Handles authenticated users appropriately
@@ -655,7 +670,7 @@ Combine layers when necessary: a command triggers sub-agents, sub-agents activat
655
670
 
656
671
  ### TAG Block Template
657
672
 
658
- ```
673
+ ```text
659
674
  // @CODE:AUTH-001 | SPEC: SPEC-AUTH-001.md | TEST: tests/auth/service.test.ts
660
675
  ```
661
676
 
@@ -686,6 +701,7 @@ Combine layers when necessary: a command triggers sub-agents, sub-agents activat
686
701
  ### TAG Validation & Integrity
687
702
 
688
703
  **Avoid duplicates**:
704
+
689
705
  ```bash
690
706
  rg "@SPEC:AUTH" -n # Search AUTH specs
691
707
  rg "@CODE:AUTH-001" -n # Targeted ID search
@@ -693,6 +709,7 @@ rg "AUTH-001" -n # Global ID search
693
709
  ```
694
710
 
695
711
  **TAG chain verification** (`/alfred:3-sync` runs automatically):
712
+
696
713
  ```bash
697
714
  rg '@(SPEC|TEST|CODE|DOC):' -n .moai/specs/ tests/ src/ docs/
698
715
 
@@ -722,18 +739,21 @@ Alfred enforces these quality gates on every change:
722
739
  ## Language-specific Code Rules
723
740
 
724
741
  **Global constraints**:
742
+
725
743
  - Files ≤ 300 LOC
726
744
  - Functions ≤ 50 LOC
727
745
  - Parameters ≤ 5
728
746
  - Cyclomatic complexity ≤ 10
729
747
 
730
748
  **Quality targets**:
749
+
731
750
  - Test coverage ≥ 85%
732
751
  - Intent-revealing names
733
752
  - Early guard clauses
734
753
  - Use language-standard tooling
735
754
 
736
755
  **Testing strategy**:
756
+
737
757
  - Prefer the standard framework per language
738
758
  - Keep tests isolated and deterministic
739
759
  - Derive cases directly from the SPEC
@@ -743,6 +763,7 @@ Alfred enforces these quality gates on every change:
743
763
  ## TDD Workflow Checklist
744
764
 
745
765
  **Step 1: SPEC authoring** (`/alfred:1-plan`)
766
+
746
767
  - [ ] Create `.moai/specs/SPEC-<ID>/spec.md` (with directory structure)
747
768
  - [ ] Add YAML front matter (id, version: 0.0.1, status: draft, created)
748
769
  - [ ] Include the `@SPEC:ID` TAG
@@ -751,12 +772,14 @@ Alfred enforces these quality gates on every change:
751
772
  - [ ] Check for duplicate IDs: `rg "@SPEC:<ID>" -n`
752
773
 
753
774
  **Step 2: TDD implementation** (`/alfred:2-run`)
775
+
754
776
  - [ ] **RED**: Write `@TEST:ID` under `tests/` and watch it fail
755
777
  - [ ] **GREEN**: Add `@CODE:ID` under `src/` and make the test pass
756
778
  - [ ] **REFACTOR**: Improve code quality; document TDD history in comments
757
779
  - [ ] List SPEC/TEST file paths in the TAG block
758
780
 
759
781
  **Step 3: Documentation sync** (`/alfred:3-sync`)
782
+
760
783
  - [ ] Scan TAGs: `rg '@(SPEC|TEST|CODE):' -n`
761
784
  - [ ] Ensure no orphan TAGs remain
762
785
  - [ ] Regenerate the Living Document
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moai-adk
3
- Version: 0.4.10
3
+ Version: 0.5.0
4
4
  Summary: MoAI Agentic Development Kit - SPEC-First TDD with Alfred SuperAgent & Complete Skills v2.0
5
5
  Project-URL: Homepage, https://github.com/modu-ai/moai-adk
6
6
  Project-URL: Repository, https://github.com/modu-ai/moai-adk
@@ -190,7 +190,7 @@ uv tool install moai-adk
190
190
 
191
191
  # Verify installation
192
192
  moai-adk --version
193
- # Output: MoAI-ADK v0.4.10
193
+ # Output: MoAI-ADK v0.4.11
194
194
  ```
195
195
 
196
196
  Once installed, you can use the `moai-adk` command anywhere.
@@ -1108,7 +1108,7 @@ Hooks are **event-driven** scripts that trigger automatically at specific points
1108
1108
  #### 2. PreToolUse (Before Tool Execution)
1109
1109
 
1110
1110
  **Triggers**: Before executing file edits, Bash commands, or MultiEdit operations
1111
- **Purpose**: Detect risky operations and automatically create safety checkpoints
1111
+ **Purpose**: Detect risky operations and automatically create safety checkpoints + TAG Guard
1112
1112
 
1113
1113
  **Protection Against**:
1114
1114
  - `rm -rf` (file deletion)
@@ -1116,13 +1116,30 @@ Hooks are **event-driven** scripts that trigger automatically at specific points
1116
1116
  - Editing critical files (`CLAUDE.md`, `config.json`)
1117
1117
  - Mass edits (10+ files at once via MultiEdit)
1118
1118
 
1119
+ **TAG Guard (New in v0.4.11)**:
1120
+ Automatically detects missing @TAG annotations in changed files:
1121
+ - Scans staged, modified, and untracked files
1122
+ - Warns when SPEC/TEST/CODE/DOC files lack required @TAG markers
1123
+ - Configurable rules via `.moai/tag-rules.json`
1124
+ - Non-blocking (gentle reminder, doesn't stop execution)
1125
+
1119
1126
  **What You See**:
1120
1127
  ```
1121
1128
  🛡️ Checkpoint created: before-delete-20251023-143000
1122
1129
  Operation: delete
1123
1130
  ```
1124
1131
 
1125
- **Why It Matters**: Prevents data loss from mistakes. You can always restore from the checkpoint if something goes wrong.
1132
+ Or when TAGs are missing:
1133
+ ```
1134
+ ⚠️ TAG 누락 감지: 생성/수정한 파일 중 @TAG가 없는 항목이 있습니다.
1135
+ - src/auth/service.py → 기대 태그: @CODE:
1136
+ - tests/test_auth.py → 기대 태그: @TEST:
1137
+ 권장 조치:
1138
+ 1) SPEC/TEST/CODE/DOC 유형에 맞는 @TAG를 파일 상단 주석이나 헤더에 추가
1139
+ 2) rg로 확인: rg '@(SPEC|TEST|CODE|DOC):' -n <경로>
1140
+ ```
1141
+
1142
+ **Why It Matters**: Prevents data loss from mistakes and ensures @TAG traceability. You can always restore from the checkpoint if something goes wrong.
1126
1143
 
1127
1144
  #### 3. UserPromptSubmit (Prompt Input)
1128
1145
 
@@ -1185,7 +1202,7 @@ If you need to temporarily disable hooks, edit `.claude/settings.json`:
1185
1202
  | Hook | Status | Feature |
1186
1203
  |------|--------|---------|
1187
1204
  | **SessionStart** | ✅ Active | Project status summary (language, Git, SPEC progress, checkpoints) |
1188
- | **PreToolUse** | ✅ Active | Risk detection + auto checkpoint (critical-delete, delete, merge, script) |
1205
+ | **PreToolUse** | ✅ Active | Risk detection + auto checkpoint (critical-delete, delete, merge, script) + **TAG Guard** (missing @TAG detection) |
1189
1206
  | **UserPromptSubmit** | ✅ Active | JIT context loading (auto-load related SPEC, tests, code, docs) |
1190
1207
  | **PostToolUse** | ✅ Active | Auto-run tests after code changes (9 languages: Python, TS, JS, Go, Rust, Java, Kotlin, Swift, Dart) |
1191
1208
  | **SessionEnd** | ✅ Active | Session cleanup and state saving |
@@ -1219,18 +1236,18 @@ If you need to temporarily disable hooks, edit `.claude/settings.json`:
1219
1236
 
1220
1237
  ---
1221
1238
 
1222
- ## v0.4 Series Updates (New!)
1239
+ ## Latest Updates (New!)
1223
1240
 
1224
1241
  | Version | Key Features | Date |
1225
1242
  | ---------- | ------------------------------------------------------------------------------------ | ---------- |
1243
+ | **v0.4.11** | ✨ TAG Guard system + CLAUDE.md formatting improvements + Code cleanup | 2025-10-23 |
1226
1244
  | **v0.4.10** | 🔧 Hook robustness improvements + Bilingual documentation + Template language config | 2025-10-23 |
1227
1245
  | **v0.4.9** | 🎯 Hook JSON schema validation fixes + Comprehensive tests (468/468 passing) | 2025-10-23 |
1228
1246
  | **v0.4.8** | 🚀 Release automation + PyPI deployment + Skills refinement | 2025-10-23 |
1229
1247
  | **v0.4.7** | 📖 Korean language optimization + SPEC-First principle documentation | 2025-10-22 |
1230
1248
  | **v0.4.6** | 🎉 Complete Skills v2.0 (100% Production-Ready) + 85,000 lines official docs + 300+ TDD examples | 2025-10-22 |
1231
- | **v0.4.5** | ✅ CI/CD fixes + Multi-language README + Deployment cleanup | 2025-10-22 |
1232
1249
 
1233
- > 📦 **Install Now**: `pip install moai-adk==0.4.10` or `uv tool install moai-adk==0.4.10`
1250
+ > 📦 **Install Now**: `pip install moai-adk==0.4.11` or `uv tool install moai-adk==0.4.11`
1234
1251
 
1235
1252
  ---
1236
1253
 
@@ -1254,24 +1271,24 @@ Let’s build a Mini Kanban Board web application designed to help you master Mo
1254
1271
 
1255
1272
  ```mermaid
1256
1273
  gantt
1257
- title Mini Kanban Board 4week plan
1274
+ title Mini Kanban Board - 4-week plan
1258
1275
  dateFormat YYYY-MM-DD
1259
1276
 
1260
1277
  section Phase 1: Backend Basics
1261
- CH07: Define SPEC-001~004 :active, ch07-spec, 2025-11-03, 1d
1262
- CH07: Implement SpecScanner (TDD) :active, ch07-impl, 2025-11-04, 1d
1278
+ Define SPEC-001-004 :active, ch07-spec, 2025-11-03, 1d
1279
+ Implement SpecScanner (TDD) :active, ch07-impl, 2025-11-04, 1d
1263
1280
 
1264
1281
  section Phase 2: Backend Advanced
1265
- CH08: Implement REST API :active, ch08-api, 2025-11-05, 1d
1266
- CH08: WebSocket + File Watch :active, ch08-ws, 2025-11-06, 1d
1282
+ Implement REST API :active, ch08-api, 2025-11-05, 1d
1283
+ WebSocket + File Watch :active, ch08-ws, 2025-11-06, 1d
1267
1284
 
1268
1285
  section Phase 3: Frontend Basics
1269
- CH09: React init + SPEC-009~012 :active, ch09-spec, 2025-11-10, 1d
1270
- CH09: Kanban Board (TDD) :active, ch09-impl, 2025-11-11, 1d
1286
+ React init + SPEC-009-012 :active, ch09-spec, 2025-11-10, 1d
1287
+ Kanban Board (TDD) :active, ch09-impl, 2025-11-11, 1d
1271
1288
 
1272
1289
  section Phase 4: Advanced + Deploy
1273
- CH10: E2E + CI/CD :active, ch10-e2e, 2025-11-12, 1d
1274
- CH10: Docker Compose + Optimize :active, ch10-deploy, 2025-11-13, 1d
1290
+ E2E + CI/CD :active, ch10-e2e, 2025-11-12, 1d
1291
+ Docker Compose + Optimize :active, ch10-deploy, 2025-11-13, 1d
1275
1292
  ```
1276
1293
 
1277
1294
  ### 16‑SPEC Roadmap
@@ -1522,8 +1539,8 @@ cd frontend
1522
1539
  | ------------------------ | ------------------------------------------------------- |
1523
1540
  | **GitHub Repository** | https://github.com/modu-ai/moai-adk |
1524
1541
  | **Issues & Discussions** | https://github.com/modu-ai/moai-adk/issues |
1525
- | **PyPI Package** | https://pypi.org/project/moai-adk/ (Latest: v0.4.6) |
1526
- | **Latest Release** | https://github.com/modu-ai/moai-adk/releases/tag/v0.4.6 |
1542
+ | **PyPI Package** | https://pypi.org/project/moai-adk/ (Latest: v0.4.11) |
1543
+ | **Latest Release** | https://github.com/modu-ai/moai-adk/releases/tag/v0.4.11 |
1527
1544
  | **Documentation** | See `.moai/`, `.claude/`, `docs/` within project |
1528
1545
 
1529
1546
  ---
@@ -1544,11 +1561,12 @@ Start a new experience of **trustworthy AI development** with Alfred! 🤖
1544
1561
 
1545
1562
  ---
1546
1563
 
1547
- **MoAI-ADK v0.4.10** — SPEC-First TDD with AI SuperAgent & Complete Skills v2.0
1564
+ **MoAI-ADK v0.4.11** — SPEC-First TDD with AI SuperAgent & Complete Skills v2.0 + TAG Guard
1548
1565
  - 📦 PyPI: https://pypi.org/project/moai-adk/
1549
1566
  - 🏠 GitHub: https://github.com/modu-ai/moai-adk
1550
1567
  - 📝 License: MIT
1551
1568
  - ⭐ Skills: 55+ Production-Ready Guides
1552
- - ✅ Tests: 468/468 Passing (86% coverage)
1569
+ - ✅ Tests: 467/476 Passing (85.60% coverage)
1570
+ - 🏷️ TAG Guard: Automatic @TAG validation in PreToolUse Hook
1553
1571
 
1554
1572
  ---
@@ -38,7 +38,7 @@ moai_adk/core/template/languages.py,sha256=V0wLcxCIOve9Q_0_NhrHGQevSIN_MB612GwrO
38
38
  moai_adk/core/template/merger.py,sha256=ZV8_U1HZJ3bfAtgyNmSxgj8KdTMt4eUnUG6kVVRT7bE,6909
39
39
  moai_adk/core/template/processor.py,sha256=W4M3BNrlfA0dHRwvPWIkJmJwhkNDglXaNzsYBoVTSnQ,17019
40
40
  moai_adk/templates/.gitignore,sha256=6VNKResdDpyaii3cmJA4pOLwK2PhYARIWkUODYtKyxg,310
41
- moai_adk/templates/CLAUDE.md,sha256=9eF_fWzNJucNBKAChoaJzVXa-LLhK4Cv7j4XZ1Whl8o,42030
41
+ moai_adk/templates/CLAUDE.md,sha256=k4XxvngGZkdGO24As5cNIGv9R7wdA0JlLt4_FMDZ7pE,42149
42
42
  moai_adk/templates/__init__.py,sha256=6MV1gCB7PLZMiL4gaD_dZSKxtcQyo45MMTuN8fVdchA,104
43
43
  moai_adk/templates/.claude/settings.json,sha256=sXQ8gV3oyZJHqPHMxYaH-ps-LXliIMpLMj-Xx2jjE7o,3269
44
44
  moai_adk/templates/.claude/agents/alfred/cc-manager.md,sha256=nyiNtcSqvLKK8Mp88hhTFBqrpsRiTqtNTpnAo1m0qQg,8048
@@ -59,16 +59,17 @@ moai_adk/templates/.claude/commands/alfred/2-run.md,sha256=UMscmBrpqysmWoKvwyGXE
59
59
  moai_adk/templates/.claude/commands/alfred/3-sync.md,sha256=xF9XnP20cJrRuCFEG_J3RnZtwMy5Ym3nj_f6eryBFBE,21535
60
60
  moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md,sha256=5dd6KRFQXzp0L8lAWKRN7Momgg_8XNV1QZ6VGs03_pc,9064
61
61
  moai_adk/templates/.claude/hooks/alfred/README.md,sha256=8JirNg3Jn2OUFmHySYBd8QxQgPkG7kcev86Zkf80asY,6852
62
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py,sha256=dPlwlj7LlsJd-c-D5ONiQGkih4qULFcjzNvZQyto_kc,7547
63
- moai_adk/templates/.claude/hooks/alfred/test_hook_output.py,sha256=zxA330umo4HHoYe_reOocqDeIU3OMBd31rcEfY9QR-U,5632
64
- moai_adk/templates/.claude/hooks/alfred/core/__init__.py,sha256=Cz1YeL6c5j2ZhJwG3y-lpxde7paJ00tEaYRduc5gDoM,6375
62
+ moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py,sha256=ILYbruVD1o284wmKPFaE2LPARekVtecpcovCvqy7eEc,7570
63
+ moai_adk/templates/.claude/hooks/alfred/test_hook_output.py,sha256=3pk-JBUPdSQZBjx27qKu-db7D1WFYBmlIZmeAFBil6M,5646
64
+ moai_adk/templates/.claude/hooks/alfred/core/__init__.py,sha256=nx_02kZDVFlKOgxBfFz3nqVrxMkmrkE0x7crJhdjl5E,6377
65
65
  moai_adk/templates/.claude/hooks/alfred/core/checkpoint.py,sha256=dsvFDSXQNSQlaQLpvhqFbytGOrOivyovi43Y18EmNeI,8483
66
66
  moai_adk/templates/.claude/hooks/alfred/core/context.py,sha256=RQd6yk8OGT-twgYtUiNmJIL-UEt_h4oktxqiRP_wXAI,2103
67
67
  moai_adk/templates/.claude/hooks/alfred/core/project.py,sha256=XVm-Y5TVjBBznW8AkFhk_uVg-EF1lZ2wx59Rxt_LOBA,9125
68
+ moai_adk/templates/.claude/hooks/alfred/core/tags.py,sha256=XcYYCS1VmCejp7Ga9xZ3hDfrWWsKM-WyPD_N5gY1q1w,6359
68
69
  moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py,sha256=j5L7nayKt7tnFQOZuO5sWiie815vmbmYJOn2VRiidLY,569
69
70
  moai_adk/templates/.claude/hooks/alfred/handlers/notification.py,sha256=8TcEqGlz4EpLf2lpouaIuhVbpKOVeY31KPmIq2snt9U,662
70
71
  moai_adk/templates/.claude/hooks/alfred/handlers/session.py,sha256=jGmiDPY-unTlQlTWQVisr82Rxhbt1Rkhrun4bggTxQ4,3374
71
- moai_adk/templates/.claude/hooks/alfred/handlers/tool.py,sha256=PBtx72UbHwTt59jlL3Wkv54O3_N-Px5Ow-WEmDMAEpM,2260
72
+ moai_adk/templates/.claude/hooks/alfred/handlers/tool.py,sha256=0bNtAf2M7nupTAkcrEiZMBCmD2f-dLjjZa5p1CWiNyM,3383
72
73
  moai_adk/templates/.claude/hooks/alfred/handlers/user.py,sha256=PyQI201oezWBzLrKo8ntWoRa9GDyVwLYktdu9vLT84s,1389
73
74
  moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md,sha256=nSP5iB5TOVf7WOqAibb28WpWFehCTG3-8WLY77l5o1M,19376
74
75
  moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md,sha256=fXsSMavQ3v9l64JST1LCR3BRJ8id9AvJ4N3pf1KwCog,17294
@@ -103,7 +104,7 @@ moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md
103
104
  moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md,sha256=ZZmnr68CJUVQ_nvVzISm3Dbi3CdMYbeU7y9riGQ7SN8,6114
104
105
  moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh,sha256=_I5PrOGLp6uSDgRyoXFbO1-OpCPRte0tyPdB-JzRiMQ,319
105
106
  moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh,sha256=aZt473lVf5zL3t3ZVwEVsFYGneeyqWgJQe6ZXA9ewBI,474
106
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py,sha256=9-7Em28aS9wGEVeo3FXGglJ_5RNKEBOOWzNzTeJb5Ps,592
107
+ moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py,sha256=EUuQO_QFufNIRA4O1MkacM9ij0Rwsgzxe2okFcc_nJM,675
107
108
  moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md,sha256=O2QBmBKe6lyU-sXyxhWzTdgTLuxxKvKzES-hV4EQetA,4887
108
109
  moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json,sha256=t2B7_Jd6DQbrSi2HmhdLLTYphy9UTOnch9FsV79onMw,968
109
110
  moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md,sha256=H51IpkBCD2vCYIjynO_77whsamCuPE2uieudybW0yJU,7726
@@ -260,8 +261,8 @@ moai_adk/templates/.moai/project/tech.md,sha256=REecMv8wOvutt-pQZ5nlGk5YdReTan7A
260
261
  moai_adk/utils/__init__.py,sha256=VnVfQzzKHvKw4bNdEw5xdscnRQYFrnr-v_TOBr3naPs,225
261
262
  moai_adk/utils/banner.py,sha256=znppKd5yo-tTqgyhgPVJjstrTrfcy_v3X1_RFQxP4Fk,1878
262
263
  moai_adk/utils/logger.py,sha256=g-m07PGKjK2bKRIInfSn6m-024Bedai-pV_WjZKDeu8,5064
263
- moai_adk-0.4.10.dist-info/METADATA,sha256=o-wzIPH9FTTUj3Ta4mbhbeepWXmxWALSCVBmySStonk,61844
264
- moai_adk-0.4.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
265
- moai_adk-0.4.10.dist-info/entry_points.txt,sha256=P9no1794UipqH72LP-ltdyfVd_MeB1WKJY_6-JQgV3U,52
266
- moai_adk-0.4.10.dist-info/licenses/LICENSE,sha256=M1M2b07fWcSWRM6_P3wbZKndZvyfHyYk_Wu9bS8F7o8,1069
267
- moai_adk-0.4.10.dist-info/RECORD,,
264
+ moai_adk-0.5.0.dist-info/METADATA,sha256=dFI90diNaxzvg1y4Absc81b8jNrwfd-jzN35eO5S5os,62659
265
+ moai_adk-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
266
+ moai_adk-0.5.0.dist-info/entry_points.txt,sha256=P9no1794UipqH72LP-ltdyfVd_MeB1WKJY_6-JQgV3U,52
267
+ moai_adk-0.5.0.dist-info/licenses/LICENSE,sha256=M1M2b07fWcSWRM6_P3wbZKndZvyfHyYk_Wu9bS8F7o8,1069
268
+ moai_adk-0.5.0.dist-info/RECORD,,