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

Files changed (39) hide show
  1. moai_adk/core/issue_creator.py +309 -0
  2. moai_adk/core/project/phase_executor.py +1 -2
  3. moai_adk/core/template_engine.py +253 -0
  4. moai_adk/templates/.claude/agents/alfred/cc-manager.md +1 -1
  5. moai_adk/templates/.claude/agents/alfred/debug-helper.md +2 -2
  6. moai_adk/templates/.claude/agents/alfred/doc-syncer.md +2 -2
  7. moai_adk/templates/.claude/agents/alfred/git-manager.md +27 -4
  8. moai_adk/templates/.claude/agents/alfred/implementation-planner.md +2 -2
  9. moai_adk/templates/.claude/agents/alfred/project-manager.md +6 -6
  10. moai_adk/templates/.claude/agents/alfred/quality-gate.md +2 -2
  11. moai_adk/templates/.claude/agents/alfred/skill-factory.md +7 -7
  12. moai_adk/templates/.claude/agents/alfred/spec-builder.md +2 -2
  13. moai_adk/templates/.claude/agents/alfred/tag-agent.md +2 -2
  14. moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +2 -2
  15. moai_adk/templates/.claude/agents/alfred/trust-checker.md +2 -2
  16. moai_adk/templates/.claude/commands/alfred/0-project.md +9 -9
  17. moai_adk/templates/.claude/commands/alfred/1-plan.md +3 -3
  18. moai_adk/templates/.claude/commands/alfred/2-run.md +4 -4
  19. moai_adk/templates/.claude/commands/alfred/3-sync.md +5 -5
  20. moai_adk/templates/.claude/commands/alfred/9-feedback.md +149 -0
  21. moai_adk/templates/.claude/hooks/alfred/core/project.py +145 -13
  22. moai_adk/templates/.claude/hooks/alfred/handlers/session.py +90 -20
  23. moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +1 -1
  24. moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +1 -1
  25. moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +1 -1
  26. moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +5 -3
  27. moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +20 -8
  28. moai_adk/templates/.github/workflows/moai-gitflow.yml +22 -16
  29. moai_adk/templates/.github/workflows/spec-issue-sync.yml +10 -6
  30. moai_adk/templates/.moai/config.json +12 -0
  31. moai_adk/templates/.moai/docs/quick-issue-creation-guide.md +219 -0
  32. moai_adk/templates/.moai/memory/issue-label-mapping.md +150 -0
  33. moai_adk/templates/CLAUDE.md +67 -1
  34. {moai_adk-0.7.0.dist-info → moai_adk-0.8.1.dist-info}/METADATA +123 -1
  35. {moai_adk-0.7.0.dist-info → moai_adk-0.8.1.dist-info}/RECORD +38 -34
  36. moai_adk/templates/.claude/hooks/alfred/test_hook_output.py +0 -175
  37. {moai_adk-0.7.0.dist-info → moai_adk-0.8.1.dist-info}/WHEEL +0 -0
  38. {moai_adk-0.7.0.dist-info → moai_adk-0.8.1.dist-info}/entry_points.txt +0 -0
  39. {moai_adk-0.7.0.dist-info → moai_adk-0.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -5,11 +5,44 @@ Project information inquiry (language, Git, SPEC progress, etc.)
5
5
  """
6
6
 
7
7
  import json
8
+ import signal
8
9
  import subprocess
10
+ from contextlib import contextmanager
9
11
  from pathlib import Path
10
12
  from typing import Any
11
13
 
12
14
 
15
+ class TimeoutError(Exception):
16
+ """Signal-based timeout exception"""
17
+ pass
18
+
19
+
20
+ @contextmanager
21
+ def timeout_handler(seconds: int):
22
+ """Hard timeout using SIGALRM (works on Unix systems including macOS)
23
+
24
+ This uses kernel-level signal to interrupt ANY blocking operation,
25
+ even if subprocess.run() timeout fails on macOS.
26
+
27
+ Args:
28
+ seconds: Timeout duration in seconds
29
+
30
+ Raises:
31
+ TimeoutError: If operation exceeds timeout
32
+ """
33
+ def _handle_timeout(signum, frame):
34
+ raise TimeoutError(f"Operation timed out after {seconds} seconds")
35
+
36
+ # Set the signal handler
37
+ old_handler = signal.signal(signal.SIGALRM, _handle_timeout)
38
+ signal.alarm(seconds)
39
+ try:
40
+ yield
41
+ finally:
42
+ signal.alarm(0) # Disable alarm
43
+ signal.signal(signal.SIGALRM, old_handler)
44
+
45
+
13
46
  def detect_language(cwd: str) -> str:
14
47
  """Detect project language (supports 20 items languages)
15
48
 
@@ -89,9 +122,10 @@ def detect_language(cwd: str) -> str:
89
122
 
90
123
 
91
124
  def _run_git_command(args: list[str], cwd: str, timeout: int = 2) -> str:
92
- """Git command execution helper function
125
+ """Git command execution with HARD timeout protection
93
126
 
94
127
  Safely execute Git commands and return output.
128
+ Uses SIGALRM (kernel-level interrupt) to handle macOS subprocess timeout bug.
95
129
  Eliminates code duplication and provides consistent error handling.
96
130
 
97
131
  Args:
@@ -103,29 +137,46 @@ def _run_git_command(args: list[str], cwd: str, timeout: int = 2) -> str:
103
137
  Git command output (stdout, removing leading and trailing spaces)
104
138
 
105
139
  Raises:
106
- subprocess.TimeoutExpired: Timeout exceeded
140
+ subprocess.TimeoutExpired: Timeout exceeded (via TimeoutError)
107
141
  subprocess.CalledProcessError: Git command failed
108
142
 
109
143
  Examples:
110
144
  >>> _run_git_command(["branch", "--show-current"], ".")
111
145
  'main'
146
+
147
+ TDD History:
148
+ - RED: Git command hang scenario test
149
+ - GREEN: SIGALRM-based timeout implementation
150
+ - REFACTOR: Exception conversion to subprocess.TimeoutExpired
112
151
  """
113
- result = subprocess.run(
114
- ["git"] + args,
115
- cwd=cwd,
116
- capture_output=True,
117
- text=True,
118
- timeout=timeout,
119
- check=True,
120
- )
121
- return result.stdout.strip()
152
+ try:
153
+ with timeout_handler(timeout):
154
+ result = subprocess.run(
155
+ ["git"] + args,
156
+ cwd=cwd,
157
+ capture_output=True,
158
+ text=True,
159
+ check=False, # Don't raise on non-zero exit - we'll check manually
160
+ )
161
+
162
+ # Check exit code manually
163
+ if result.returncode != 0:
164
+ raise subprocess.CalledProcessError(
165
+ result.returncode, ["git"] + args, result.stdout, result.stderr
166
+ )
167
+
168
+ return result.stdout.strip()
169
+
170
+ except TimeoutError:
171
+ # Convert to subprocess.TimeoutExpired for consistent error handling
172
+ raise subprocess.TimeoutExpired(["git"] + args, timeout)
122
173
 
123
174
 
124
175
  def get_git_info(cwd: str) -> dict[str, Any]:
125
176
  """Gather Git repository information
126
177
 
127
178
  View the current status of a Git repository.
128
- Returns the branch name, commit hash, and number of changes.
179
+ Returns the branch name, commit hash, number of changes, and last commit message.
129
180
  If it is not a Git repository, it returns an empty dictionary.
130
181
 
131
182
  Args:
@@ -136,12 +187,13 @@ def get_git_info(cwd: str) -> dict[str, Any]:
136
187
  - branch: Current branch name (str)
137
188
  - commit: Current commit hash (str, full hash)
138
189
  - changes: Number of changed files (int, staged + unstaged)
190
+ - last_commit: Last commit message (str, subject only)
139
191
 
140
192
  Empty dictionary {} if it is not a Git repository or the query fails.
141
193
 
142
194
  Examples:
143
195
  >>> get_git_info("/path/to/git/repo")
144
- {'branch': 'main', 'commit': 'abc123...', 'changes': 3}
196
+ {'branch': 'main', 'commit': 'abc123...', 'changes': 3, 'last_commit': 'Fix bug'}
145
197
  >>> get_git_info("/path/to/non-git")
146
198
  {}
147
199
 
@@ -149,11 +201,13 @@ def get_git_info(cwd: str) -> dict[str, Any]:
149
201
  - Timeout: 2 seconds for each Git command
150
202
  - Security: Safe execution with subprocess.run(shell=False)
151
203
  - Error handling: Returns an empty dictionary in case of all exceptions
204
+ - Commit message limited to 50 characters for display purposes
152
205
 
153
206
  TDD History:
154
207
  - RED: 3 items scenario test (Git repo, non-Git, error)
155
208
  - GREEN: Implementation of subprocess-based Git command execution
156
209
  - REFACTOR: Add timeout (2 seconds), strengthen exception handling, remove duplicates with helper function
210
+ - UPDATE: Added last_commit message field for SessionStart display
157
211
  """
158
212
  try:
159
213
  # Check if it's a git repository
@@ -165,10 +219,16 @@ def get_git_info(cwd: str) -> dict[str, Any]:
165
219
  status_output = _run_git_command(["status", "--short"], cwd)
166
220
  changes = len([line for line in status_output.splitlines() if line])
167
221
 
222
+ # Get last commit message (subject only, limited to 50 chars)
223
+ last_commit = _run_git_command(["log", "-1", "--format=%s"], cwd)
224
+ if len(last_commit) > 50:
225
+ last_commit = last_commit[:47] + "..."
226
+
168
227
  return {
169
228
  "branch": branch,
170
229
  "commit": commit,
171
230
  "changes": changes,
231
+ "last_commit": last_commit,
172
232
  }
173
233
 
174
234
  except (subprocess.TimeoutExpired, subprocess.CalledProcessError, FileNotFoundError):
@@ -276,9 +336,81 @@ def get_project_language(cwd: str) -> str:
276
336
  return detect_language(cwd)
277
337
 
278
338
 
339
+ def get_package_version_info() -> dict[str, Any]:
340
+ """Check MoAI-ADK current and latest version from PyPI
341
+
342
+ Compares the installed version with the latest version available on PyPI.
343
+ Returns version information for SessionStart hook to display update recommendations.
344
+
345
+ Returns:
346
+ dict with keys:
347
+ - "current": Current installed version
348
+ - "latest": Latest version available on PyPI
349
+ - "update_available": Boolean indicating if update is available
350
+ - "upgrade_command": Recommended upgrade command (if update available)
351
+
352
+ Note:
353
+ - Has 1-second timeout to avoid blocking SessionStart
354
+ - Returns graceful fallback if PyPI check fails
355
+ - Handles version parsing gracefully
356
+ """
357
+ import urllib.error
358
+ import urllib.request
359
+ from importlib.metadata import PackageNotFoundError, version
360
+
361
+ result = {
362
+ "current": "unknown",
363
+ "latest": "unknown",
364
+ "update_available": False,
365
+ "upgrade_command": ""
366
+ }
367
+
368
+ # Get current version
369
+ try:
370
+ result["current"] = version("moai-adk")
371
+ except PackageNotFoundError:
372
+ result["current"] = "dev"
373
+ return result
374
+
375
+ # Get latest version from PyPI (with 1-second timeout)
376
+ try:
377
+ with timeout_handler(1):
378
+ url = "https://pypi.org/pypi/moai-adk/json"
379
+ headers = {"Accept": "application/json"}
380
+ req = urllib.request.Request(url, headers=headers)
381
+ with urllib.request.urlopen(req, timeout=0.8) as response:
382
+ data = json.load(response)
383
+ result["latest"] = data.get("info", {}).get("version", "unknown")
384
+ except (urllib.error.URLError, TimeoutError, Exception):
385
+ # Network error or timeout - return with unknown latest version
386
+ return result
387
+
388
+ # Compare versions (simple comparison)
389
+ if result["current"] != "unknown" and result["latest"] != "unknown":
390
+ try:
391
+ # Parse versions for comparison
392
+ current_parts = [int(x) for x in result["current"].split(".")]
393
+ latest_parts = [int(x) for x in result["latest"].split(".")]
394
+
395
+ # Pad shorter version with zeros
396
+ max_len = max(len(current_parts), len(latest_parts))
397
+ current_parts.extend([0] * (max_len - len(current_parts)))
398
+ latest_parts.extend([0] * (max_len - len(latest_parts)))
399
+
400
+ if latest_parts > current_parts:
401
+ result["update_available"] = True
402
+ result["upgrade_command"] = f"uv pip install --upgrade moai-adk>={result['latest']}"
403
+ except (ValueError, AttributeError):
404
+ # Version parsing failed - skip comparison
405
+ pass
406
+
407
+ return result
408
+
409
+
279
410
  __all__ = [
280
411
  "detect_language",
281
412
  "get_git_info",
282
413
  "count_specs",
283
414
  "get_project_language",
415
+ "get_package_version_info",
284
416
  ]
@@ -6,14 +6,16 @@ SessionStart, SessionEnd event handling
6
6
 
7
7
  from core import HookPayload, HookResult
8
8
  from core.checkpoint import list_checkpoints
9
- from core.project import count_specs, detect_language, get_git_info
9
+ from core.project import count_specs, detect_language, get_git_info, get_package_version_info
10
10
 
11
11
 
12
12
  def handle_session_start(payload: HookPayload) -> HookResult:
13
- """SessionStart event handler (with Checkpoint list)
13
+ """SessionStart event handler with GRACEFUL DEGRADATION
14
14
 
15
15
  When Claude Code Session starts, it displays a summary of project status.
16
16
  You can check the language, Git status, SPEC progress, and checkpoint list at a glance.
17
+ All optional operations are wrapped in try-except to ensure hook completes quickly even if
18
+ Git commands, file I/O, or other operations timeout or fail.
17
19
 
18
20
  Args:
19
21
  payload: Claude Code event payload (cwd key required)
@@ -24,15 +26,23 @@ def handle_session_start(payload: HookPayload) -> HookResult:
24
26
  Message Format:
25
27
  🚀 MoAI-ADK Session Started
26
28
  Language: {language}
27
- Branch: {branch} ({commit hash})
28
- Changes: {Number of Changed Files}
29
- SPEC Progress: {Complete}/{Total} ({percent}%)
30
- Checkpoints: {number} available (showing the latest 3 items)
29
+ [Branch: {branch} ({commit hash})] - optional if git fails
30
+ [Changes: {Number of Changed Files}] - optional if git fails
31
+ [SPEC Progress: {Complete}/{Total} ({percent}%)] - optional if specs fail
32
+ [Checkpoints: {number} available] - optional if checkpoint list fails
33
+
34
+ Graceful Degradation Strategy:
35
+ - CRITICAL: Language detection (must succeed - no try-except)
36
+ - OPTIONAL: Git info (skip if timeout/failure)
37
+ - OPTIONAL: SPEC progress (skip if timeout/failure)
38
+ - OPTIONAL: Checkpoint list (skip if timeout/failure)
39
+ - Always display SOMETHING to user, never return empty message
31
40
 
32
41
  Note:
33
42
  - Claude Code processes SessionStart in several stages (clear → compact)
34
43
  - Display message only at "compact" stage to prevent duplicate output
35
44
  - "clear" step returns minimal result (empty hookSpecificOutput)
45
+ - CRITICAL: All optional operations must complete within 2-3 seconds total
36
46
 
37
47
  TDD History:
38
48
  - RED: Session startup message format test
@@ -40,8 +50,10 @@ def handle_session_start(payload: HookPayload) -> HookResult:
40
50
  - REFACTOR: Improved message format, improved readability, added checkpoint list
41
51
  - FIX: Prevent duplicate output of clear step (only compact step is displayed)
42
52
  - UPDATE: Migrated to Claude Code standard Hook schema
53
+ - HOTFIX: Add graceful degradation for timeout scenarios (Issue #66)
43
54
 
44
55
  @TAG:CHECKPOINT-EVENT-001
56
+ @TAG:HOOKS-TIMEOUT-001
45
57
  """
46
58
  # Claude Code SessionStart runs in several stages (clear, compact, etc.)
47
59
  # Ignore the "clear" stage and output messages only at the "compact" stage
@@ -51,32 +63,90 @@ def handle_session_start(payload: HookPayload) -> HookResult:
51
63
  return HookResult(continue_execution=True)
52
64
 
53
65
  cwd = payload.get("cwd", ".")
66
+
67
+ # CRITICAL: Language detection - MUST succeed (no try-except)
54
68
  language = detect_language(cwd)
55
- git_info = get_git_info(cwd)
56
- specs = count_specs(cwd)
57
- checkpoints = list_checkpoints(cwd, max_count=10)
58
69
 
59
- branch = git_info.get("branch", "N/A")
60
- commit = git_info.get("commit", "N/A")[:7]
61
- changes = git_info.get("changes", 0)
62
- spec_progress = f"{specs['completed']}/{specs['total']}"
70
+ # OPTIONAL: Git info - skip if timeout/failure
71
+ git_info = {}
72
+ try:
73
+ git_info = get_git_info(cwd)
74
+ except Exception:
75
+ # Graceful degradation - continue without git info
76
+ pass
77
+
78
+ # OPTIONAL: SPEC progress - skip if timeout/failure
79
+ specs = {"completed": 0, "total": 0, "percentage": 0}
80
+ try:
81
+ specs = count_specs(cwd)
82
+ except Exception:
83
+ # Graceful degradation - continue without spec info
84
+ pass
85
+
86
+ # OPTIONAL: Checkpoint list - skip if timeout/failure
87
+ checkpoints = []
88
+ try:
89
+ checkpoints = list_checkpoints(cwd, max_count=10)
90
+ except Exception:
91
+ # Graceful degradation - continue without checkpoints
92
+ pass
93
+
94
+ # OPTIONAL: Package version info - skip if timeout/failure
95
+ version_info = {}
96
+ try:
97
+ version_info = get_package_version_info()
98
+ except Exception:
99
+ # Graceful degradation - continue without version info
100
+ pass
101
+
102
+ # Build message with available information
103
+ branch = git_info.get("branch", "N/A") if git_info else "N/A"
104
+ commit = git_info.get("commit", "N/A")[:7] if git_info else "N/A"
105
+ changes = git_info.get("changes", 0) if git_info else 0
106
+ spec_progress = f"{specs['completed']}/{specs['total']}" if specs["total"] > 0 else "0/0"
63
107
 
64
108
  # system_message: displayed directly to the user
65
109
  lines = [
66
110
  "🚀 MoAI-ADK Session Started",
67
- f" Language: {language}",
68
- f" Branch: {branch} ({commit})",
69
- f" Changes: {changes}",
70
- f" SPEC Progress: {spec_progress} ({specs['percentage']}%)",
111
+ "", # Blank line after title
71
112
  ]
72
113
 
114
+ # Add version info first (at the top, right after title)
115
+ if version_info and version_info.get("current") != "unknown":
116
+ version_line = f" 🗿 MoAI-ADK Ver: {version_info['current']}"
117
+ if version_info.get("update_available"):
118
+ version_line += f" → {version_info['latest']} available ✨"
119
+ lines.append(version_line)
120
+
121
+ # Add upgrade recommendation if update is available
122
+ if version_info.get("update_available") and version_info.get("upgrade_command"):
123
+ lines.append(f" ⬆️ Upgrade: {version_info['upgrade_command']}")
124
+
125
+ # Add language info
126
+ lines.append(f" 🐍 Language: {language}")
127
+
128
+ # Add Git info only if available (not degraded)
129
+ if git_info:
130
+ lines.append(f" 🌿 Branch: {branch} ({commit})")
131
+ lines.append(f" 📝 Changes: {changes}")
132
+
133
+ # Add last commit message if available
134
+ last_commit = git_info.get("last_commit", "")
135
+ if last_commit:
136
+ lines.append(f" 🔨 Last: {last_commit}")
137
+
73
138
  # Add Checkpoint list (show only the latest 3 items)
74
139
  if checkpoints:
75
- lines.append(f" Checkpoints: {len(checkpoints)} available")
140
+ lines.append(f" 🗂️ Checkpoints: {len(checkpoints)} available")
76
141
  for cp in reversed(checkpoints[-3:]): # Latest 3 items
77
142
  branch_short = cp["branch"].replace("before-", "")
78
- lines.append(f" - {branch_short}")
79
- lines.append(" Restore: /alfred:0-project restore")
143
+ lines.append(f" 📌 {branch_short}")
144
+ lines.append("") # Blank line before restore command
145
+ lines.append(" ↩️ Restore: /alfred:0-project restore")
146
+
147
+ # Add SPEC progress only if available (not degraded) - at the bottom
148
+ if specs["total"] > 0:
149
+ lines.append(f" 📋 SPEC Progress: {spec_progress} ({specs['percentage']}%)")
80
150
 
81
151
  system_message = "\n".join(lines)
82
152
 
@@ -8,7 +8,7 @@ description: "Agent-based coding mode that integrates hands-on development and c
8
8
  ---
9
9
 
10
10
  # Agentic Coding
11
- > Interactive prompts rely on `Skill("moai-alfred-interactive-questions")` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
11
+ > Interactive prompts rely on `AskUserQuestion tool (documented in moai-alfred-interactive-questions skill)` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
12
12
 
13
13
  **Audience**: Professional developers, team leaders, architects
14
14
 
@@ -8,7 +8,7 @@ description: "Learning mode to easily learn MoAI-ADK concepts and workflow"
8
8
  ---
9
9
 
10
10
  # MoAI ADK Learning
11
- > Interactive prompts rely on `Skill("moai-alfred-interactive-questions")` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
11
+ > Interactive prompts rely on `AskUserQuestion tool (documented in moai-alfred-interactive-questions skill)` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
12
12
 
13
13
  **Audience**: Developers new to MoAI-ADK
14
14
 
@@ -8,7 +8,7 @@ description: "Learning mode to easily learn new skills with Alfred"
8
8
  ---
9
9
 
10
10
  # Study with Alfred
11
- > Interactive prompts rely on `Skill("moai-alfred-interactive-questions")` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
11
+ > Interactive prompts rely on `AskUserQuestion tool (documented in moai-alfred-interactive-questions skill)` so AskUserQuestion renders TUI selection menus for user surveys and approvals.
12
12
 
13
13
  **Audience**: Developers looking to learn new technologies/languages/frameworks
14
14
 
@@ -170,7 +170,9 @@ body:
170
170
  value: |
171
171
  ## 📚 Reference
172
172
 
173
- - **SPEC Metadata Guide**: See `.moai/memory/spec-metadata.md`
174
- - **EARS Syntax Guide**: See `.moai/memory/development-guide.md`
173
+ - **SPEC Metadata Guide**: See `{{DOCS_DIR}}/spec-metadata.md`
174
+ - **EARS Syntax Guide**: See `{{DOCS_DIR}}/development-guide.md`
175
175
  - **Acceptance Criteria**: Use Given-When-Then (Gherkin) format
176
- - **@TAG System**: @SPEC, @TEST, @CODE, @DOC traceability
176
+ {% if ENABLE_TAG_SYSTEM -%}
177
+ - **Traceability System**: @SPEC, @TEST, @CODE, @DOC traceability
178
+ {% endif -%}
@@ -1,20 +1,25 @@
1
- # MoAI-ADK GitFlow PR
1
+ # {{PROJECT_NAME}} GitFlow PR
2
2
 
3
- > 🗿 Full GitFlow Transparency — the agent auto-fills information
3
+ > Full GitFlow Transparency — the agent auto-fills information
4
4
 
5
5
  ## 📝 SPEC Info
6
6
 
7
7
  - Related SPEC: `SPEC-AUTH-001` (e.g., JWT authentication system)
8
- - Directory: `.moai/specs/SPEC-AUTH-001/`
8
+ - Directory: `{{SPEC_DIR}}/SPEC-AUTH-001/`
9
+ {% if ENABLE_TAG_SYSTEM -%}
9
10
  - @TAG Links: @SPEC:AUTH-001 @CODE:AUTH-001 (auto-tagging)
11
+ {% endif -%}
10
12
 
11
13
  ## ✅ SPEC Quality Checks
12
14
 
13
15
  - [ ] YAML Front Matter: 7 required fields (id, version, status, created, updated, author, priority)
14
16
  - [ ] HISTORY Section: Record versioned change log (include v0.0.1 INITIAL)
15
17
  - [ ] EARS Requirements: Ubiquitous, Event-driven, State-driven, Optional, Constraints
18
+ {% if ENABLE_TAG_SYSTEM -%}
16
19
  - [ ] @SPEC:ID TAG: Include TAG in doc and check duplicates (`rg "@SPEC:<ID>" -n`)
20
+ {% endif -%}
17
21
 
22
+ {% if ENABLE_ALFRED_COMMANDS -%}
18
23
  ## 🤖 Automated Validation Status
19
24
 
20
25
  <!-- The checklist below is auto-updated by the agent -->
@@ -25,24 +30,29 @@
25
30
  - [ ] spec-builder: Complete EARS spec and create feature branch
26
31
  - [ ] code-builder: Finish TDD RED-GREEN-REFACTOR
27
32
  - [ ] doc-syncer: Sync Living Documents and mark PR Ready
33
+ {% endif -%}
28
34
 
35
+ {% if ENABLE_TRUST_5 -%}
29
36
  ## 📊 Quality Metrics (auto-calculated)
30
37
 
31
38
  - TRUST 5 Principles: ✅ Compliant
32
39
  - Test Coverage: XX% (target ≥ 85%)
40
+ {% if ENABLE_TAG_SYSTEM -%}
33
41
  - @TAG Traceability: 100%
42
+ {% endif -%}
43
+ {% endif -%}
34
44
 
35
45
  ## 🌍 Locale Settings
36
46
 
37
- - Project Language: <!-- ko/en/ja/zh -->
47
+ - Project Language: {{CONVERSATION_LANGUAGE}}
38
48
  - Commit Messages: <!-- generated automatically according to locale -->
39
49
 
40
50
  ## 🎯 Changes
41
51
 
42
- <!-- code-builder auto-fills TDD results -->
52
+ <!-- auto-fills TDD results -->
43
53
 
44
54
  ### 🔴 RED (Test Authoring)
45
- - Test File: `tests/auth/service.test.ts`
55
+ - Test File: `{{TEST_DIR}}/auth/service.test.ts`
46
56
  - Test Description: [describe the failing test]
47
57
 
48
58
  ### 🟢 GREEN (Implementation)
@@ -58,12 +68,14 @@
58
68
 
59
69
  - [ ] Update README
60
70
  - [ ] Sync API docs
71
+ {% if ENABLE_TAG_SYSTEM -%}
61
72
  - [ ] Update TAG index
73
+ {% endif -%}
62
74
  - [ ] Update HISTORY section (SPEC docs)
63
75
 
64
76
  ---
65
77
 
66
- 🚀 MoAI-ADK: Professional development without Git commands via a 3-stage pipeline!
78
+ 🚀 {{PROJECT_NAME}}: Professional development via a 3-stage pipeline!
67
79
 
68
- Reviewers: Check TRUST 5 compliance and SPEC metadata completeness only.
80
+ Reviewers: Check quality compliance and SPEC metadata completeness only.
69
81
 
@@ -1,6 +1,6 @@
1
- name: MoAI-ADK GitFlow Automation
1
+ name: "{{PROJECT_NAME}} GitFlow Automation"
2
2
 
3
- # MoAI-ADK 3-stage pipeline: spec → build → sync
3
+ # {{PROJECT_NAME}} 3-stage pipeline: spec → build → sync
4
4
  # Full GitFlow transparency — no Git expertise needed
5
5
 
6
6
  on:
@@ -11,7 +11,7 @@ on:
11
11
 
12
12
  jobs:
13
13
  moai-pipeline:
14
- name: 🗿 MoAI-ADK Pipeline
14
+ name: "{{PROJECT_NAME}} Pipeline"
15
15
  runs-on: ubuntu-latest
16
16
  steps:
17
17
  - name: Checkout
@@ -86,13 +86,13 @@ jobs:
86
86
  distribution: "temurin"
87
87
  java-version: "21"
88
88
 
89
- # TRUST 5 Principles — automated validation
90
- # Note: Validation is handled by TypeScript-based tools
91
- - name: 🧭 TRUST 5 Principles Check
89
+ # TRUST 5 Principles — automated validation (if enabled)
90
+ {% if ENABLE_TRUST_5 -%}
91
+ - name: 🧭 Quality Principles Check
92
92
  run: |
93
- echo "✅ TRUST validation is performed by TypeScript-based tools"
94
- echo " - Uses @agent-trust-checker"
95
- echo " - Leverages TypeScript hook system"
93
+ echo "✅ Quality validation is performed"
94
+ echo " - Automated quality checks enabled"
95
+ {% endif -%}
96
96
 
97
97
  # Ignore test failures on Draft PRs; fail CI on Ready PRs
98
98
  - name: Run language-aware tests
@@ -221,11 +221,14 @@ jobs:
221
221
  fi
222
222
  fi
223
223
 
224
- # TAG system validation (code files only)
225
- - name: 🏷️ TAG System Validation
224
+ # TAG system validation (if enabled)
225
+ {% if ENABLE_TAG_SYSTEM -%}
226
+ - name: 🏷️ Traceability Validation
226
227
  run: |
227
- echo "✅ TAG validation is handled automatically in the tag_validator.py hook"
228
+ echo "✅ Traceability validation is handled automatically"
229
+ {% endif -%}
228
230
 
231
+ {% if ENABLE_ALFRED_COMMANDS -%}
229
232
  # Run per-branch stages
230
233
  - name: 📝 SPEC Stage (feature branch)
231
234
  if: startsWith(github.ref, 'refs/heads/feature/')
@@ -239,7 +242,9 @@ jobs:
239
242
  run: |
240
243
  echo "📝 Draft PR: TDD implementation stage"
241
244
  echo "- code-builder agent runs RED-GREEN-REFACTOR"
242
- echo "- Validate TRUST 5 Principles compliance"
245
+ {% if ENABLE_TRUST_5 -%}
246
+ echo "- Validate Quality Principles compliance"
247
+ {% endif -%}
243
248
 
244
249
  - name: 📚 SYNC Stage (Ready PR)
245
250
  if: github.event.pull_request.draft == false && github.event.action == 'ready_for_review'
@@ -247,10 +252,11 @@ jobs:
247
252
  echo "✅ Ready PR: documentation sync stage"
248
253
  echo "- doc-syncer agent synchronizes Living Documents"
249
254
  echo "- PR is ready for review"
255
+ {% endif -%}
250
256
 
251
257
  # Final result report
252
- - name: 📊 MoAI Pipeline Complete
258
+ - name: "🎯 {{PROJECT_NAME}} Pipeline Complete"
253
259
  run: |
254
- echo "🗿 MoAI-ADK GitFlow automation complete"
255
- echo "✨ Professional workflow without needing to know Git"
260
+ echo "{{PROJECT_NAME}} GitFlow automation complete"
261
+ echo "✨ Professional workflow enabled"
256
262
 
@@ -3,7 +3,7 @@ name: 📋 SPEC Issue Sync
3
3
  on:
4
4
  pull_request:
5
5
  paths:
6
- - '.moai/specs/SPEC-*/spec.md'
6
+ - '{{SPEC_DIR}}/SPEC-*/spec.md'
7
7
  types: [opened, synchronize]
8
8
 
9
9
  permissions:
@@ -33,18 +33,18 @@ jobs:
33
33
  pwd
34
34
  ls -la
35
35
 
36
- echo "=== Debug: Looking for .moai/specs ==="
37
- ls -la .moai/ 2>&1 || echo ".moai/ directory not found"
36
+ echo "=== Debug: Looking for {{SPEC_DIR}} ==="
37
+ ls -la {{SPEC_DIR}}/ 2>&1 || echo "{{SPEC_DIR}}/ directory not found"
38
38
 
39
39
  # Find SPEC files in the PR
40
40
  echo "=== Debug: Searching for SPEC files ==="
41
41
  find . -name "spec.md" -type f 2>&1 || echo "find command failed"
42
42
 
43
- spec_file=$(find .moai/specs -name "spec.md" -type f 2>&1 | head -1)
43
+ spec_file=$(find {{SPEC_DIR}} -name "spec.md" -type f 2>&1 | head -1)
44
44
  echo "Found spec_file: [$spec_file]"
45
45
 
46
46
  if [ -z "$spec_file" ]; then
47
- echo "⚠️ No SPEC file found in .moai/specs"
47
+ echo "⚠️ No SPEC file found in {{SPEC_DIR}}"
48
48
  echo "Exiting gracefully (this is expected if no SPEC files changed)"
49
49
  exit 0
50
50
  fi
@@ -59,7 +59,11 @@ jobs:
59
59
  spec_priority=$(grep "^priority:" "$spec_file" | sed 's/^priority: *//' | tr -d ' "')
60
60
 
61
61
  # Extract title from H1 heading
62
+ {% if ENABLE_TAG_SYSTEM -%}
62
63
  spec_title=$(grep "^# @SPEC:" "$spec_file" | sed 's/^# @SPEC:[^:]*: //')
64
+ {% else -%}
65
+ spec_title=$(grep "^# " "$spec_file" | head -1 | sed 's/^# //')
66
+ {% endif -%}
63
67
 
64
68
  echo "✅ Extracted SPEC metadata:"
65
69
  echo " ID: $spec_id"
@@ -158,7 +162,7 @@ jobs:
158
162
  echo "This SPEC has been synchronized to GitHub Issue."
159
163
  echo ""
160
164
  echo "📋 **Issue**: [#$issue_num - SPEC-$spec_id: $spec_title](../issues/$issue_num)"
161
- echo "🔗 **SPEC File**: \`.moai/specs/SPEC-$spec_id/spec.md\`"
165
+ echo "🔗 **SPEC File**: \`{{SPEC_DIR}}/SPEC-$spec_id/spec.md\`"
162
166
  echo ""
163
167
  echo "The issue will be automatically updated as you modify the SPEC document."
164
168
  } > /tmp/pr_comment.txt