moai-adk 0.4.5__py3-none-any.whl → 0.20.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 (433) hide show
  1. moai_adk/__init__.py +1 -1
  2. moai_adk/__main__.py +74 -1
  3. moai_adk/cli/commands/__init__.py +1 -1
  4. moai_adk/cli/commands/analyze.py +119 -0
  5. moai_adk/cli/commands/backup.py +25 -1
  6. moai_adk/cli/commands/doctor.py +31 -5
  7. moai_adk/cli/commands/improve_user_experience.py +307 -0
  8. moai_adk/cli/commands/init.py +111 -10
  9. moai_adk/cli/commands/status.py +33 -3
  10. moai_adk/cli/commands/update.py +921 -130
  11. moai_adk/cli/commands/validate_links.py +120 -0
  12. moai_adk/cli/prompts/init_prompts.py +22 -87
  13. moai_adk/core/analysis/__init__.py +9 -0
  14. moai_adk/core/analysis/session_analyzer.py +388 -0
  15. moai_adk/core/analysis/tag_chain_analyzer.py +344 -0
  16. moai_adk/core/analysis/tag_chain_repair.py +879 -0
  17. moai_adk/core/config/__init__.py +19 -0
  18. moai_adk/core/config/migration.py +235 -0
  19. moai_adk/core/git/__init__.py +1 -1
  20. moai_adk/core/git/branch.py +1 -1
  21. moai_adk/core/git/commit.py +1 -1
  22. moai_adk/core/git/manager.py +1 -1
  23. moai_adk/core/issue_creator.py +313 -0
  24. moai_adk/core/mcp/setup.py +56 -0
  25. moai_adk/core/mcp/setup_old.py +296 -0
  26. moai_adk/core/project/backup_utils.py +1 -1
  27. moai_adk/core/project/checker.py +2 -2
  28. moai_adk/core/project/detector.py +211 -12
  29. moai_adk/core/project/initializer.py +85 -15
  30. moai_adk/core/project/phase_executor.py +76 -13
  31. moai_adk/core/project/validator.py +13 -13
  32. moai_adk/core/quality/__init__.py +1 -1
  33. moai_adk/core/quality/trust_checker.py +1 -1
  34. moai_adk/core/quality/validators/__init__.py +1 -1
  35. moai_adk/core/quality/validators/base_validator.py +1 -1
  36. moai_adk/core/tags/__init__.py +86 -0
  37. moai_adk/core/tags/auto_corrector.py +693 -0
  38. moai_adk/core/tags/ci_validator.py +463 -0
  39. moai_adk/core/tags/cli.py +283 -0
  40. moai_adk/core/tags/generator.py +109 -0
  41. moai_adk/core/tags/inserter.py +99 -0
  42. moai_adk/core/tags/mapper.py +126 -0
  43. moai_adk/core/tags/parser.py +76 -0
  44. moai_adk/core/tags/policy_validator.py +580 -0
  45. moai_adk/core/tags/pre_commit_validator.py +421 -0
  46. moai_adk/core/tags/reporter.py +956 -0
  47. moai_adk/core/tags/rollback_manager.py +525 -0
  48. moai_adk/core/tags/tags.py +149 -0
  49. moai_adk/core/tags/validator.py +897 -0
  50. moai_adk/core/template/__init__.py +1 -1
  51. moai_adk/core/template/backup.py +1 -1
  52. moai_adk/core/template/merger.py +50 -1
  53. moai_adk/core/template/processor.py +119 -13
  54. moai_adk/core/template_engine.py +268 -0
  55. moai_adk/templates/.claude/agents/alfred/backend-expert.md +348 -0
  56. moai_adk/templates/.claude/agents/alfred/cc-manager.md +209 -944
  57. moai_adk/templates/.claude/agents/alfred/database-expert.md +352 -0
  58. moai_adk/templates/.claude/agents/alfred/debug-helper.md +34 -5
  59. moai_adk/templates/.claude/agents/alfred/devops-expert.md +464 -0
  60. moai_adk/templates/.claude/agents/alfred/doc-syncer.md +38 -8
  61. moai_adk/templates/.claude/agents/alfred/format-expert.md +469 -0
  62. moai_adk/templates/.claude/agents/alfred/frontend-expert.md +357 -0
  63. moai_adk/templates/.claude/agents/alfred/git-manager.md +128 -9
  64. moai_adk/templates/.claude/agents/alfred/implementation-planner.md +104 -6
  65. moai_adk/templates/.claude/agents/alfred/project-manager.md +88 -16
  66. moai_adk/templates/.claude/agents/alfred/quality-gate.md +36 -9
  67. moai_adk/templates/.claude/agents/alfred/security-expert.md +270 -0
  68. moai_adk/templates/.claude/agents/alfred/skill-factory.md +865 -0
  69. moai_adk/templates/.claude/agents/alfred/spec-builder.md +214 -43
  70. moai_adk/templates/.claude/agents/alfred/tag-agent.md +111 -9
  71. moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +309 -160
  72. moai_adk/templates/.claude/agents/alfred/trust-checker.md +36 -7
  73. moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +605 -0
  74. moai_adk/templates/.claude/commands/alfred/0-project.md +393 -966
  75. moai_adk/templates/.claude/commands/alfred/1-plan.md +651 -367
  76. moai_adk/templates/.claude/commands/alfred/2-run.md +388 -241
  77. moai_adk/templates/.claude/commands/alfred/3-sync.md +1921 -410
  78. moai_adk/templates/.claude/commands/alfred/9-feedback.md +153 -0
  79. moai_adk/templates/.claude/commands/alfred/release-new.md +3604 -0
  80. moai_adk/templates/.claude/hooks/alfred/core/project.py +484 -20
  81. moai_adk/templates/.claude/hooks/alfred/core/timeout.py +136 -0
  82. moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +108 -0
  83. moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
  84. moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +14 -6
  85. moai_adk/templates/.claude/hooks/alfred/post_tool__enable_streaming_ui.py +50 -0
  86. moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +93 -0
  87. moai_adk/templates/.claude/hooks/alfred/post_tool__tag_auto_corrector.py +407 -0
  88. moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +99 -0
  89. moai_adk/templates/.claude/hooks/alfred/pre_tool__realtime_tag_monitor.py +335 -0
  90. moai_adk/templates/.claude/hooks/alfred/pre_tool__tag_policy_validator.py +325 -0
  91. moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +93 -0
  92. moai_adk/templates/.claude/hooks/alfred/session_start__auto_cleanup.py +580 -0
  93. moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +298 -0
  94. moai_adk/templates/.claude/hooks/alfred/shared/core/__init__.py +170 -0
  95. moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +3 -3
  96. moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +5 -5
  97. moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +749 -0
  98. moai_adk/templates/.claude/hooks/alfred/shared/core/tags.py +230 -0
  99. moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
  100. moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +21 -0
  101. moai_adk/templates/.claude/hooks/alfred/shared/handlers/daily_analysis.py +351 -0
  102. moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +154 -0
  103. moai_adk/templates/.claude/hooks/alfred/shared/handlers/session.py +174 -0
  104. moai_adk/templates/.claude/hooks/alfred/shared/handlers/tool.py +87 -0
  105. moai_adk/templates/.claude/hooks/alfred/shared/handlers/user.py +61 -0
  106. moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +111 -0
  107. moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +1 -0
  108. moai_adk/templates/.claude/hooks/alfred/utils/hook_config.py +94 -0
  109. moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +161 -0
  110. moai_adk/templates/.claude/output-styles/alfred/alfred-moai-adk-beginner.md +267 -0
  111. moai_adk/templates/.claude/output-styles/alfred/keating-personal-tutor.md +440 -0
  112. moai_adk/templates/.claude/output-styles/alfred/r2d2-agentic-coding.md +583 -0
  113. moai_adk/templates/.claude/settings.json +96 -14
  114. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +70 -0
  115. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +62 -0
  116. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/reference.md +242 -0
  117. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/SKILL.md +237 -0
  118. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/examples.md +871 -0
  119. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/reference.md +653 -0
  120. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/README.md +162 -0
  121. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/SKILL.md +227 -0
  122. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/examples.md +354 -0
  123. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/reference.md +158 -0
  124. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/SKILL.md +179 -79
  125. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/examples.md +117 -0
  126. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/scripts/pre-review-check.sh +62 -0
  127. moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +132 -0
  128. moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +28 -0
  129. moai_adk/templates/.claude/skills/moai-alfred-config-schema/reference.md +444 -0
  130. moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +62 -0
  131. moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +28 -0
  132. moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +405 -0
  133. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +51 -0
  134. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +355 -0
  135. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +239 -0
  136. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +323 -0
  137. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +286 -0
  138. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +126 -0
  139. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +229 -0
  140. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +4 -0
  141. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +150 -0
  142. moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +87 -73
  143. moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +29 -0
  144. moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +28 -0
  145. moai_adk/templates/.claude/skills/moai-alfred-personas/README.md +42 -0
  146. moai_adk/templates/.claude/skills/moai-alfred-personas/SKILL.md +429 -0
  147. moai_adk/templates/.claude/skills/moai-alfred-personas/examples.md +520 -0
  148. moai_adk/templates/.claude/skills/moai-alfred-personas/reference.md +405 -0
  149. moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +89 -0
  150. moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +122 -0
  151. moai_adk/templates/.claude/skills/moai-alfred-practices/reference.md +369 -0
  152. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +508 -0
  153. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +481 -0
  154. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +100 -0
  155. moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +77 -0
  156. moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +265 -0
  157. moai_adk/templates/.claude/skills/moai-alfred-rules/reference.md +539 -0
  158. moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +320 -0
  159. moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +4 -0
  160. moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +84 -0
  161. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +137 -0
  162. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +219 -0
  163. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples/validate-spec.sh +161 -0
  164. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +541 -0
  165. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +622 -0
  166. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +19 -0
  167. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +4 -0
  168. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +211 -0
  169. moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +288 -0
  170. moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +269 -0
  171. moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +32 -0
  172. moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +298 -0
  173. moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +26 -0
  174. moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +307 -0
  175. moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +21 -0
  176. moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +252 -0
  177. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +19 -0
  178. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +19 -0
  179. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +24 -0
  180. moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +199 -0
  181. moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +39 -0
  182. moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +316 -0
  183. moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +18 -0
  184. moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +263 -0
  185. moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +30 -0
  186. moai_adk/templates/.claude/skills/moai-cc-skill-factory/CHECKLIST.md +482 -0
  187. moai_adk/templates/.claude/skills/moai-cc-skill-factory/EXAMPLES.md +303 -0
  188. moai_adk/templates/.claude/skills/moai-cc-skill-factory/INTERACTIVE-DISCOVERY.md +524 -0
  189. moai_adk/templates/.claude/skills/moai-cc-skill-factory/METADATA.md +477 -0
  190. moai_adk/templates/.claude/skills/moai-cc-skill-factory/PARALLEL-ANALYSIS-REPORT.md +429 -0
  191. moai_adk/templates/.claude/skills/moai-cc-skill-factory/PYTHON-VERSION-MATRIX.md +391 -0
  192. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-FACTORY-WORKFLOW.md +431 -0
  193. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-UPDATE-ADVISOR.md +577 -0
  194. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL.md +273 -0
  195. moai_adk/templates/.claude/skills/moai-cc-skill-factory/STEP-BY-STEP-GUIDE.md +466 -0
  196. moai_adk/templates/.claude/skills/moai-cc-skill-factory/STRUCTURE.md +583 -0
  197. moai_adk/templates/.claude/skills/moai-cc-skill-factory/WEB-RESEARCH.md +526 -0
  198. moai_adk/templates/.claude/skills/moai-cc-skill-factory/reference.md +608 -0
  199. moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/generate-structure.sh +328 -0
  200. moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/validate-skill.sh +312 -0
  201. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/SKILL_TEMPLATE.md +245 -0
  202. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/examples-template.md +285 -0
  203. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/reference-template.md +278 -0
  204. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/scripts-template.sh +303 -0
  205. moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +291 -0
  206. moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +15 -0
  207. moai_adk/templates/.claude/skills/moai-change-logger/SKILL.md +563 -0
  208. moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +802 -0
  209. moai_adk/templates/.claude/skills/moai-design-systems/examples.md +1238 -0
  210. moai_adk/templates/.claude/skills/moai-design-systems/reference.md +673 -0
  211. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +234 -43
  212. moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +1633 -0
  213. moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +660 -0
  214. moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +97 -69
  215. moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +29 -0
  216. moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +30 -0
  217. moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +97 -72
  218. moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +29 -0
  219. moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +30 -0
  220. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +97 -74
  221. moai_adk/templates/.claude/skills/moai-domain-database/examples.md +29 -0
  222. moai_adk/templates/.claude/skills/moai-domain-database/reference.md +30 -0
  223. moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +98 -74
  224. moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +29 -0
  225. moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +31 -0
  226. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +102 -73
  227. moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +29 -0
  228. moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +31 -0
  229. moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +97 -73
  230. moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +29 -0
  231. moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +30 -0
  232. moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +97 -67
  233. moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +29 -0
  234. moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +30 -0
  235. moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +97 -79
  236. moai_adk/templates/.claude/skills/moai-domain-security/examples.md +29 -0
  237. moai_adk/templates/.claude/skills/moai-domain-security/reference.md +30 -0
  238. moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +97 -71
  239. moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +29 -0
  240. moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +30 -0
  241. moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +265 -64
  242. moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +1064 -0
  243. moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +1047 -0
  244. moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +87 -78
  245. moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +29 -0
  246. moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +28 -0
  247. moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +87 -70
  248. moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +29 -0
  249. moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +28 -0
  250. moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +87 -86
  251. moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +29 -0
  252. moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +28 -0
  253. moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +80 -62
  254. moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +29 -0
  255. moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +28 -0
  256. moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +207 -50
  257. moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +29 -0
  258. moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +29 -0
  259. moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +90 -71
  260. moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +29 -0
  261. moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +28 -0
  262. moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +78 -58
  263. moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +29 -0
  264. moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +28 -0
  265. moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +78 -51
  266. moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +29 -0
  267. moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +28 -0
  268. moai_adk/templates/.claude/skills/moai-foundation-trust/.!11330!examples.md +0 -0
  269. moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +253 -32
  270. moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
  271. moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +1099 -0
  272. moai_adk/templates/.claude/skills/moai-jit-docs-enhanced/SKILL.md +460 -0
  273. moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +98 -74
  274. moai_adk/templates/.claude/skills/moai-lang-c/examples.md +29 -0
  275. moai_adk/templates/.claude/skills/moai-lang-c/reference.md +31 -0
  276. moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +98 -76
  277. moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +29 -0
  278. moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +31 -0
  279. moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +2358 -70
  280. moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +29 -0
  281. moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +30 -0
  282. moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +2962 -68
  283. moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +29 -0
  284. moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +30 -0
  285. moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +1898 -70
  286. moai_adk/templates/.claude/skills/moai-lang-go/examples.md +29 -0
  287. moai_adk/templates/.claude/skills/moai-lang-go/reference.md +31 -0
  288. moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +1465 -68
  289. moai_adk/templates/.claude/skills/moai-lang-java/examples.md +29 -0
  290. moai_adk/templates/.claude/skills/moai-lang-java/reference.md +31 -0
  291. moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +2364 -66
  292. moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +29 -0
  293. moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +32 -0
  294. moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +1630 -69
  295. moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +29 -0
  296. moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +31 -0
  297. moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +89 -61
  298. moai_adk/templates/.claude/skills/moai-lang-php/examples.md +29 -0
  299. moai_adk/templates/.claude/skills/moai-lang-php/reference.md +30 -0
  300. moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +735 -66
  301. moai_adk/templates/.claude/skills/moai-lang-python/examples.md +624 -0
  302. moai_adk/templates/.claude/skills/moai-lang-python/reference.md +316 -0
  303. moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +97 -73
  304. moai_adk/templates/.claude/skills/moai-lang-r/examples.md +29 -0
  305. moai_adk/templates/.claude/skills/moai-lang-r/reference.md +30 -0
  306. moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +98 -73
  307. moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +29 -0
  308. moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +31 -0
  309. moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +1834 -70
  310. moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +29 -0
  311. moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +31 -0
  312. moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +99 -74
  313. moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +29 -0
  314. moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +30 -0
  315. moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +97 -74
  316. moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +29 -0
  317. moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +30 -0
  318. moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +98 -74
  319. moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +29 -0
  320. moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +31 -0
  321. moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +1959 -69
  322. moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +29 -0
  323. moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +30 -0
  324. moai_adk/templates/.claude/skills/moai-lang-template/SKILL.md +348 -0
  325. moai_adk/templates/.claude/skills/moai-lang-template/VARIABLES.md +98 -0
  326. moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +1230 -66
  327. moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +29 -0
  328. moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +34 -0
  329. moai_adk/templates/.claude/skills/moai-learning-optimizer/SKILL.md +575 -0
  330. moai_adk/templates/.claude/skills/moai-project-batch-questions/README.md +50 -0
  331. moai_adk/templates/.claude/skills/moai-project-batch-questions/SKILL.md +304 -0
  332. moai_adk/templates/.claude/skills/moai-project-batch-questions/examples.md +417 -0
  333. moai_adk/templates/.claude/skills/moai-project-batch-questions/reference.md +704 -0
  334. moai_adk/templates/.claude/skills/moai-project-config-manager/README.md +87 -0
  335. moai_adk/templates/.claude/skills/moai-project-config-manager/SKILL.md +552 -0
  336. moai_adk/templates/.claude/skills/moai-project-config-manager/examples.md +1109 -0
  337. moai_adk/templates/.claude/skills/moai-project-config-manager/reference.md +514 -0
  338. moai_adk/templates/.claude/skills/moai-project-config-manager/validate.py +106 -0
  339. moai_adk/templates/.claude/skills/moai-project-documentation/README.md +11 -0
  340. moai_adk/templates/.claude/skills/moai-project-documentation/SKILL.md +622 -0
  341. moai_adk/templates/.claude/skills/moai-project-documentation/examples.md +20 -0
  342. moai_adk/templates/.claude/skills/moai-project-documentation/reference.md +12 -0
  343. moai_adk/templates/.claude/skills/moai-project-language-initializer/README.md +152 -0
  344. moai_adk/templates/.claude/skills/moai-project-language-initializer/SKILL.md +285 -0
  345. moai_adk/templates/.claude/skills/moai-project-language-initializer/examples.md +333 -0
  346. moai_adk/templates/.claude/skills/moai-project-language-initializer/reference.md +386 -0
  347. moai_adk/templates/.claude/skills/moai-project-template-optimizer/README.md +49 -0
  348. moai_adk/templates/.claude/skills/moai-project-template-optimizer/SKILL.md +319 -0
  349. moai_adk/templates/.claude/skills/moai-project-template-optimizer/examples.md +58 -0
  350. moai_adk/templates/.claude/skills/moai-project-template-optimizer/reference.md +123 -0
  351. moai_adk/templates/.claude/skills/moai-session-info/SKILL.md +314 -0
  352. moai_adk/templates/.claude/skills/moai-streaming-ui/SKILL.md +552 -0
  353. moai_adk/templates/.claude/skills/moai-tag-policy-validator/SKILL.md +570 -0
  354. moai_adk/templates/.git-hooks/pre-commit +66 -0
  355. moai_adk/templates/.git-hooks/pre-push +255 -0
  356. moai_adk/templates/.github/workflows/c-tag-validation.yml +11 -0
  357. moai_adk/templates/.github/workflows/cpp-tag-validation.yml +11 -0
  358. moai_adk/templates/.github/workflows/csharp-tag-validation.yml +11 -0
  359. moai_adk/templates/.github/workflows/dart-tag-validation.yml +11 -0
  360. moai_adk/templates/.github/workflows/go-tag-validation.yml +130 -0
  361. moai_adk/templates/.github/workflows/java-tag-validation.yml +11 -0
  362. moai_adk/templates/.github/workflows/javascript-tag-validation.yml +135 -0
  363. moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +11 -0
  364. moai_adk/templates/.github/workflows/moai-gitflow.yml +166 -3
  365. moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
  366. moai_adk/templates/.github/workflows/moai-release-pipeline.yml +188 -0
  367. moai_adk/templates/.github/workflows/php-tag-validation.yml +11 -0
  368. moai_adk/templates/.github/workflows/python-tag-validation.yml +118 -0
  369. moai_adk/templates/.github/workflows/release.yml +118 -0
  370. moai_adk/templates/.github/workflows/ruby-tag-validation.yml +11 -0
  371. moai_adk/templates/.github/workflows/rust-tag-validation.yml +11 -0
  372. moai_adk/templates/.github/workflows/shell-tag-validation.yml +11 -0
  373. moai_adk/templates/.github/workflows/spec-issue-sync.yml +338 -0
  374. moai_adk/templates/.github/workflows/swift-tag-validation.yml +11 -0
  375. moai_adk/templates/.github/workflows/tag-report.yml +269 -0
  376. moai_adk/templates/.github/workflows/tag-validation.yml +186 -0
  377. moai_adk/templates/.github/workflows/typescript-tag-validation.yml +154 -0
  378. moai_adk/templates/.mcp.json +31 -0
  379. moai_adk/templates/.moai/config.json +80 -7
  380. moai_adk/templates/CLAUDE.md +562 -546
  381. moai_adk/utils/banner.py +5 -5
  382. moai_adk/utils/common.py +294 -0
  383. moai_adk/utils/link_validator.py +235 -0
  384. moai_adk/utils/logger.py +8 -8
  385. moai_adk/utils/user_experience.py +451 -0
  386. moai_adk-0.20.1.dist-info/METADATA +233 -0
  387. moai_adk-0.20.1.dist-info/RECORD +404 -0
  388. moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
  389. moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -156
  390. moai_adk/templates/.claude/hooks/alfred/core/__init__.py +0 -85
  391. moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
  392. moai_adk/templates/.claude/hooks/alfred/handlers/session.py +0 -92
  393. moai_adk/templates/.claude/hooks/alfred/handlers/tool.py +0 -70
  394. moai_adk/templates/.claude/hooks/alfred/handlers/user.py +0 -41
  395. moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -636
  396. moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -692
  397. moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -470
  398. moai_adk/templates/.claude/skills/moai-alfred-debugger-pro/SKILL.md +0 -103
  399. moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -103
  400. moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -95
  401. moai_adk/templates/.claude/skills/moai-alfred-performance-optimizer/SKILL.md +0 -105
  402. moai_adk/templates/.claude/skills/moai-alfred-refactoring-coach/SKILL.md +0 -97
  403. moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -97
  404. moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -90
  405. moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -99
  406. moai_adk/templates/.claude/skills/moai-alfred-tui-survey/SKILL.md +0 -87
  407. moai_adk/templates/.claude/skills/moai-alfred-tui-survey/examples.md +0 -62
  408. moai_adk/templates/.claude/skills/moai-claude-code/SKILL.md +0 -94
  409. moai_adk/templates/.claude/skills/moai-claude-code/examples.md +0 -513
  410. moai_adk/templates/.claude/skills/moai-claude-code/reference.md +0 -433
  411. moai_adk/templates/.claude/skills/moai-claude-code/templates/agent-full.md +0 -332
  412. moai_adk/templates/.claude/skills/moai-claude-code/templates/command-full.md +0 -384
  413. moai_adk/templates/.claude/skills/moai-claude-code/templates/plugin-full.json +0 -363
  414. moai_adk/templates/.claude/skills/moai-claude-code/templates/settings-full.json +0 -595
  415. moai_adk/templates/.claude/skills/moai-claude-code/templates/skill-full.md +0 -496
  416. moai_adk/templates/.claude/skills/moai-lang-clojure/SKILL.md +0 -100
  417. moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +0 -99
  418. moai_adk/templates/.claude/skills/moai-lang-haskell/SKILL.md +0 -100
  419. moai_adk/templates/.claude/skills/moai-lang-julia/SKILL.md +0 -98
  420. moai_adk/templates/.claude/skills/moai-lang-lua/SKILL.md +0 -98
  421. moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
  422. moai_adk/templates/.moai/memory/development-guide.md +0 -344
  423. moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
  424. moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
  425. moai_adk/templates/.moai/project/product.md +0 -161
  426. moai_adk/templates/.moai/project/structure.md +0 -156
  427. moai_adk/templates/.moai/project/tech.md +0 -227
  428. moai_adk/templates/__init__.py +0 -2
  429. moai_adk-0.4.5.dist-info/METADATA +0 -369
  430. moai_adk-0.4.5.dist-info/RECORD +0 -152
  431. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/WHEEL +0 -0
  432. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/entry_points.txt +0 -0
  433. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,956 @@
1
+ #!/usr/bin/env python3
2
+ # @CODE:DOC-TAG-004 | Component 4: Documentation & Reporting system
3
+ """TAG reporting and documentation generation for MoAI-ADK
4
+
5
+ This module provides automated reporting for TAG system health and coverage:
6
+ - Generates TAG inventories across entire codebase
7
+ - Creates coverage matrices showing SPEC implementation status
8
+ - Analyzes SPEC→CODE→TEST→DOC chain completeness
9
+ - Produces statistics and metrics in multiple formats
10
+ - Formats reports as Markdown, JSON, CSV, and HTML (optional)
11
+
12
+ Architecture:
13
+ ReportGenerator (orchestrator)
14
+ ├── InventoryGenerator (tag-inventory.md)
15
+ ├── MatrixGenerator (tag-matrix.md)
16
+ ├── CoverageAnalyzer (coverage analysis)
17
+ ├── StatisticsGenerator (tag-statistics.json)
18
+ └── ReportFormatter (multi-format output)
19
+
20
+ Usage:
21
+ generator = ReportGenerator()
22
+ result = generator.generate_all_reports("/path/to/project", "/path/to/output")
23
+ print(f"Generated reports: {result.inventory_path}, {result.matrix_path}")
24
+ """
25
+
26
+ import json
27
+ import re
28
+ from dataclasses import dataclass, field
29
+ from datetime import datetime
30
+ from pathlib import Path
31
+ from typing import Dict, List, Set
32
+
33
+ # ============================================================================
34
+ # Data Models
35
+ # ============================================================================
36
+
37
+ @dataclass
38
+ class TagInventory:
39
+ """Single TAG inventory item with metadata
40
+
41
+ Attributes:
42
+ tag_id: TAG identifier (e.g., "DOC-TAG-001")
43
+ file_path: File path where TAG is located
44
+ line_number: Line number of TAG
45
+ context: Surrounding code snippet
46
+ related_tags: List of related TAG strings
47
+ last_modified: Last modification timestamp
48
+ status: TAG status (active|deprecated|orphan|incomplete)
49
+ """
50
+ tag_id: str
51
+ file_path: str
52
+ line_number: int
53
+ context: str
54
+ related_tags: List[str] = field(default_factory=list)
55
+ last_modified: datetime = field(default_factory=datetime.now)
56
+ status: str = "active"
57
+
58
+
59
+ @dataclass
60
+ class TagMatrix:
61
+ """Coverage matrix showing implementation status
62
+
63
+ Attributes:
64
+ rows: Dict mapping SPEC ID to coverage status
65
+ {
66
+ "AUTH-001": {
67
+ "SPEC": True,
68
+ "CODE": True,
69
+ "TEST": False,
70
+ "DOC": False
71
+ }
72
+ }
73
+ completion_percentages: Dict mapping SPEC ID to completion percentage
74
+ """
75
+ rows: Dict[str, Dict[str, bool]] = field(default_factory=dict)
76
+ completion_percentages: Dict[str, float] = field(default_factory=dict)
77
+
78
+
79
+ @dataclass
80
+ class CoverageMetrics:
81
+ """Coverage metrics for a single SPEC
82
+
83
+ Attributes:
84
+ spec_id: SPEC identifier
85
+ has_code: Whether CODE implementation exists
86
+ has_test: Whether TEST exists
87
+ has_doc: Whether DOC exists
88
+ coverage_percentage: Overall completion percentage
89
+ """
90
+ spec_id: str
91
+ has_code: bool = False
92
+ has_test: bool = False
93
+ has_doc: bool = False
94
+ coverage_percentage: float = 0.0
95
+
96
+
97
+ @dataclass
98
+ class StatisticsReport:
99
+ """Overall TAG statistics
100
+
101
+ Attributes:
102
+ generated_at: Report generation timestamp
103
+ total_tags: Total TAG count
104
+ by_type: Count by TAG type (SPEC, CODE, TEST, DOC)
105
+ by_domain: Count by domain (AUTH, USER, etc.)
106
+ coverage: Coverage metrics
107
+ issues: Issue counts (orphans, incomplete chains, etc.)
108
+ """
109
+ generated_at: datetime
110
+ total_tags: int
111
+ by_type: Dict[str, int] = field(default_factory=dict)
112
+ by_domain: Dict[str, int] = field(default_factory=dict)
113
+ coverage: Dict[str, float] = field(default_factory=dict)
114
+ issues: Dict[str, int] = field(default_factory=dict)
115
+
116
+
117
+ @dataclass
118
+ class ReportResult:
119
+ """Result of report generation
120
+
121
+ Attributes:
122
+ inventory_path: Path to generated inventory file
123
+ matrix_path: Path to generated matrix file
124
+ statistics_path: Path to generated statistics file
125
+ success: Whether generation succeeded
126
+ error_message: Error message if failed
127
+ """
128
+ inventory_path: Path
129
+ matrix_path: Path
130
+ statistics_path: Path
131
+ success: bool = True
132
+ error_message: str = ""
133
+
134
+
135
+ # ============================================================================
136
+ # Core Generators
137
+ # ============================================================================
138
+
139
+ class InventoryGenerator:
140
+ """Generates TAG inventory across codebase
141
+
142
+ Scans entire codebase for TAGs and creates comprehensive inventory
143
+ grouped by domain and type.
144
+ """
145
+
146
+ TAG_PATTERN = re.compile(r"@(SPEC|CODE|TEST|DOC):([A-Z]+(?:-[A-Z]+)*-\d{3})")
147
+ IGNORE_PATTERNS = [".git/*", "node_modules/*", "__pycache__/*", "*.pyc", ".venv/*", "venv/*"]
148
+
149
+ def generate_inventory(self, root_path: str) -> List[TagInventory]:
150
+ """Scan directory and generate TAG inventory
151
+
152
+ Args:
153
+ root_path: Root directory to scan
154
+
155
+ Returns:
156
+ List of TagInventory objects
157
+ """
158
+ inventory: list[TagInventory] = []
159
+ root = Path(root_path)
160
+
161
+ if not root.exists() or not root.is_dir():
162
+ return inventory
163
+
164
+ # Scan all files recursively
165
+ for filepath in root.rglob("*"):
166
+ if not filepath.is_file():
167
+ continue
168
+
169
+ # Check ignore patterns
170
+ if self._should_ignore(filepath, root):
171
+ continue
172
+
173
+ # Extract TAGs from file
174
+ tags = self._extract_tags_from_file(filepath, root)
175
+ inventory.extend(tags)
176
+
177
+ return inventory
178
+
179
+ def _should_ignore(self, filepath: Path, root: Path) -> bool:
180
+ """Check if file should be ignored
181
+
182
+ Args:
183
+ filepath: File path to check
184
+ root: Root directory
185
+
186
+ Returns:
187
+ True if file should be ignored
188
+ """
189
+ try:
190
+ relative = filepath.relative_to(root)
191
+ relative_str = str(relative)
192
+
193
+ for pattern in self.IGNORE_PATTERNS:
194
+ pattern_clean = pattern.replace("/*", "").replace("*", "")
195
+ if pattern_clean in relative_str:
196
+ return True
197
+
198
+ return False
199
+
200
+ except ValueError:
201
+ return True
202
+
203
+ def _extract_tags_from_file(self, filepath: Path, root: Path) -> List[TagInventory]:
204
+ """Extract TAGs from a single file
205
+
206
+ Args:
207
+ filepath: File to scan
208
+ root: Root directory for relative paths
209
+
210
+ Returns:
211
+ List of TagInventory objects
212
+ """
213
+ inventory = []
214
+
215
+ try:
216
+ content = filepath.read_text(encoding="utf-8", errors="ignore")
217
+ lines = content.splitlines()
218
+
219
+ # Get file modification time
220
+ last_modified = datetime.fromtimestamp(filepath.stat().st_mtime)
221
+
222
+ for line_num, line in enumerate(lines, start=1):
223
+ matches = self.TAG_PATTERN.findall(line)
224
+
225
+ for tag_type, domain in matches:
226
+ tag_id = domain
227
+
228
+ # Extract context (±2 lines)
229
+ context_lines = []
230
+ for i in range(max(0, line_num - 3), min(len(lines), line_num + 2)):
231
+ if i < len(lines):
232
+ context_lines.append(lines[i])
233
+ context = "\n".join(context_lines)
234
+
235
+ # Create inventory item
236
+ relative_path = str(filepath.relative_to(root))
237
+ inventory.append(TagInventory(
238
+ tag_id=tag_id,
239
+ file_path=relative_path,
240
+ line_number=line_num,
241
+ context=context,
242
+ related_tags=[], # Will be populated later
243
+ last_modified=last_modified,
244
+ status="active"
245
+ ))
246
+
247
+ except Exception:
248
+ pass
249
+
250
+ return inventory
251
+
252
+ def group_by_domain(self, inventory: List[TagInventory]) -> Dict[str, List[TagInventory]]:
253
+ """Group inventory by domain
254
+
255
+ Args:
256
+ inventory: List of TagInventory objects
257
+
258
+ Returns:
259
+ Dict mapping domain prefix to list of tags
260
+ """
261
+ grouped: Dict[str, List[TagInventory]] = {}
262
+
263
+ for item in inventory:
264
+ # Extract domain prefix (e.g., "AUTH" from "AUTH-LOGIN-001")
265
+ parts = item.tag_id.split("-")
266
+ if parts:
267
+ domain = parts[0]
268
+ if domain not in grouped:
269
+ grouped[domain] = []
270
+ grouped[domain].append(item)
271
+
272
+ return grouped
273
+
274
+ def format_as_markdown(self, grouped: Dict[str, List[TagInventory]]) -> str:
275
+ """Format grouped inventory as markdown
276
+
277
+ Args:
278
+ grouped: Grouped inventory dict
279
+
280
+ Returns:
281
+ Markdown-formatted string
282
+ """
283
+ lines = []
284
+ lines.append("# TAG Inventory")
285
+ lines.append("")
286
+ lines.append(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
287
+
288
+ # Calculate totals
289
+ total_tags = sum(len(tags) for tags in grouped.values())
290
+ lines.append(f"Total TAGs: {total_tags}")
291
+ lines.append("")
292
+
293
+ # Group by domain
294
+ lines.append("## By Domain")
295
+ lines.append("")
296
+
297
+ for domain in sorted(grouped.keys()):
298
+ lines.append(f"### {domain}")
299
+ lines.append("")
300
+
301
+ for item in sorted(grouped[domain], key=lambda x: x.tag_id):
302
+ lines.append(f"- **{item.tag_id}** (`{item.file_path}:{item.line_number}`)")
303
+
304
+ lines.append("")
305
+
306
+ return "\n".join(lines)
307
+
308
+
309
+ class MatrixGenerator:
310
+ """Generates TAG coverage matrix
311
+
312
+ Creates matrix showing SPEC implementation status across
313
+ CODE, TEST, and DOC components.
314
+ """
315
+
316
+ def generate_matrix(self, tags: Dict[str, Set[str]]) -> TagMatrix:
317
+ """Generate coverage matrix from tags
318
+
319
+ Args:
320
+ tags: Dict mapping type to set of domain IDs
321
+ {"SPEC": {"AUTH-001"}, "CODE": {"AUTH-001"}, ...}
322
+
323
+ Returns:
324
+ TagMatrix object
325
+ """
326
+ matrix = TagMatrix()
327
+
328
+ # Get all unique domains
329
+ all_domains = set()
330
+ for tag_set in tags.values():
331
+ all_domains.update(tag_set)
332
+
333
+ # Build matrix rows
334
+ for domain in all_domains:
335
+ matrix.rows[domain] = {
336
+ "SPEC": domain in tags.get("SPEC", set()),
337
+ "CODE": domain in tags.get("CODE", set()),
338
+ "TEST": domain in tags.get("TEST", set()),
339
+ "DOC": domain in tags.get("DOC", set())
340
+ }
341
+
342
+ # Calculate completion percentage
343
+ matrix.completion_percentages[domain] = self.calculate_completion_percentage(domain, tags)
344
+
345
+ return matrix
346
+
347
+ def calculate_completion_percentage(self, spec_id: str, tags: Dict[str, Set[str]]) -> float:
348
+ """Calculate completion percentage for a SPEC
349
+
350
+ Args:
351
+ spec_id: SPEC domain ID
352
+ tags: Tags dict
353
+
354
+ Returns:
355
+ Completion percentage (0-100)
356
+ """
357
+ components = ["SPEC", "CODE", "TEST", "DOC"]
358
+ present = sum(1 for comp in components if spec_id in tags.get(comp, set()))
359
+
360
+ return (present / len(components)) * 100.0
361
+
362
+ def format_as_markdown_table(self, matrix: TagMatrix) -> str:
363
+ """Format matrix as markdown table
364
+
365
+ Args:
366
+ matrix: TagMatrix object
367
+
368
+ Returns:
369
+ Markdown table string
370
+ """
371
+ lines = []
372
+ lines.append("# TAG Coverage Matrix")
373
+ lines.append("")
374
+ lines.append(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
375
+ lines.append("")
376
+
377
+ # Table header
378
+ lines.append("| SPEC | CODE | TEST | DOC | Completion |")
379
+ lines.append("|------|------|------|-----|------------|")
380
+
381
+ # Table rows
382
+ for domain in sorted(matrix.rows.keys()):
383
+ row = matrix.rows[domain]
384
+ spec_mark = "✅" if row["SPEC"] else "❌"
385
+ code_mark = "✅" if row["CODE"] else "❌"
386
+ test_mark = "✅" if row["TEST"] else "❌"
387
+ doc_mark = "✅" if row["DOC"] else "❌"
388
+ completion = f"{matrix.completion_percentages[domain]:.0f}%"
389
+
390
+ lines.append(f"| {domain} ({spec_mark}) | {code_mark} | {test_mark} | {doc_mark} | {completion} |")
391
+
392
+ lines.append("")
393
+
394
+ # Summary
395
+ total_specs = len(matrix.rows)
396
+ fully_implemented = sum(1 for pct in matrix.completion_percentages.values() if pct == 100.0)
397
+
398
+ lines.append("## Summary")
399
+ lines.append("")
400
+ lines.append(f"- Total SPECs: {total_specs}")
401
+ lines.append(f"- Fully Implemented (100%): {fully_implemented}")
402
+ lines.append("")
403
+
404
+ return "\n".join(lines)
405
+
406
+ def format_as_csv(self, matrix: TagMatrix) -> str:
407
+ """Format matrix as CSV
408
+
409
+ Args:
410
+ matrix: TagMatrix object
411
+
412
+ Returns:
413
+ CSV string
414
+ """
415
+ lines = []
416
+ lines.append("SPEC,CODE,TEST,DOC,Completion")
417
+
418
+ for domain in sorted(matrix.rows.keys()):
419
+ row = matrix.rows[domain]
420
+ spec = "1" if row["SPEC"] else "0"
421
+ code = "1" if row["CODE"] else "0"
422
+ test = "1" if row["TEST"] else "0"
423
+ "1" if row["DOC"] else "0"
424
+ completion = f"{matrix.completion_percentages[domain]:.1f}"
425
+
426
+ lines.append(f"{domain},{spec},{code},{test},{completion}")
427
+
428
+ return "\n".join(lines)
429
+
430
+
431
+ class CoverageAnalyzer:
432
+ """Analyzes TAG coverage and chain integrity
433
+
434
+ Analyzes SPEC→CODE→TEST→DOC chains to identify
435
+ coverage gaps and orphan TAGs.
436
+ """
437
+
438
+ TAG_PATTERN = re.compile(r"@(SPEC|CODE|TEST|DOC):([A-Z]+(?:-[A-Z]+)*-\d{3})")
439
+ IGNORE_PATTERNS = [".git/*", "node_modules/*", "__pycache__/*", "*.pyc", ".venv/*", "venv/*"]
440
+
441
+ def analyze_spec_coverage(self, spec_id: str, root_path: str) -> CoverageMetrics:
442
+ """Analyze coverage for a specific SPEC
443
+
444
+ Args:
445
+ spec_id: SPEC domain ID
446
+ root_path: Root directory to scan
447
+
448
+ Returns:
449
+ CoverageMetrics object
450
+ """
451
+ tags = self._collect_tags(root_path)
452
+
453
+ metrics = CoverageMetrics(spec_id=spec_id)
454
+ metrics.has_code = spec_id in tags.get("CODE", set())
455
+ metrics.has_test = spec_id in tags.get("TEST", set())
456
+ metrics.has_doc = spec_id in tags.get("DOC", set())
457
+
458
+ # Calculate coverage percentage
459
+ components = [metrics.has_code, metrics.has_test, metrics.has_doc]
460
+ metrics.coverage_percentage = (sum(components) / 3.0) * 100.0
461
+
462
+ return metrics
463
+
464
+ def get_specs_without_code(self, root_path: str) -> List[str]:
465
+ """Find SPECs without CODE implementation
466
+
467
+ Args:
468
+ root_path: Root directory to scan
469
+
470
+ Returns:
471
+ List of SPEC IDs without CODE
472
+ """
473
+ tags = self._collect_tags(root_path)
474
+
475
+ specs = tags.get("SPEC", set())
476
+ codes = tags.get("CODE", set())
477
+
478
+ return list(specs - codes)
479
+
480
+ def get_code_without_tests(self, root_path: str) -> List[str]:
481
+ """Find CODE without TEST
482
+
483
+ Args:
484
+ root_path: Root directory to scan
485
+
486
+ Returns:
487
+ List of CODE IDs without TEST
488
+ """
489
+ tags = self._collect_tags(root_path)
490
+
491
+ codes = tags.get("CODE", set())
492
+ tests = tags.get("TEST", set())
493
+
494
+ return list(codes - tests)
495
+
496
+ def get_code_without_docs(self, root_path: str) -> List[str]:
497
+ """Find CODE without DOC
498
+
499
+ Args:
500
+ root_path: Root directory to scan
501
+
502
+ Returns:
503
+ List of CODE IDs without DOC
504
+ """
505
+ tags = self._collect_tags(root_path)
506
+
507
+ codes = tags.get("CODE", set())
508
+ docs = tags.get("DOC", set())
509
+
510
+ return list(codes - docs)
511
+
512
+ def calculate_overall_coverage(self, root_path: str) -> float:
513
+ """Calculate overall coverage percentage
514
+
515
+ Args:
516
+ root_path: Root directory to scan
517
+
518
+ Returns:
519
+ Overall coverage percentage (0-100)
520
+ """
521
+ tags = self._collect_tags(root_path)
522
+
523
+ specs = tags.get("SPEC", set())
524
+ if not specs:
525
+ return 0.0 if tags.get("CODE", set()) else 100.0
526
+
527
+ # Calculate average coverage for all SPECs
528
+ total_coverage = 0.0
529
+ for spec_id in specs:
530
+ metrics = self.analyze_spec_coverage(spec_id, root_path)
531
+ total_coverage += metrics.coverage_percentage
532
+
533
+ return total_coverage / len(specs)
534
+
535
+ def _collect_tags(self, root_path: str) -> Dict[str, Set[str]]:
536
+ """Collect all TAGs from directory
537
+
538
+ Args:
539
+ root_path: Root directory to scan
540
+
541
+ Returns:
542
+ Dict mapping type to set of domain IDs
543
+ """
544
+ tags: Dict[str, Set[str]] = {
545
+ "SPEC": set(),
546
+ "CODE": set(),
547
+ "TEST": set(),
548
+ "DOC": set()
549
+ }
550
+
551
+ root = Path(root_path)
552
+ if not root.exists():
553
+ return tags
554
+
555
+ for filepath in root.rglob("*"):
556
+ if not filepath.is_file():
557
+ continue
558
+
559
+ # Check ignore patterns
560
+ if self._should_ignore(filepath, root):
561
+ continue
562
+
563
+ # Extract tags
564
+ try:
565
+ content = filepath.read_text(encoding="utf-8", errors="ignore")
566
+ matches = self.TAG_PATTERN.findall(content)
567
+
568
+ for tag_type, domain in matches:
569
+ tags[tag_type].add(domain)
570
+
571
+ except Exception:
572
+ pass
573
+
574
+ return tags
575
+
576
+ def _should_ignore(self, filepath: Path, root: Path) -> bool:
577
+ """Check if file should be ignored
578
+
579
+ Args:
580
+ filepath: File path
581
+ root: Root directory
582
+
583
+ Returns:
584
+ True if should ignore
585
+ """
586
+ try:
587
+ relative = filepath.relative_to(root)
588
+ relative_str = str(relative)
589
+
590
+ for pattern in self.IGNORE_PATTERNS:
591
+ pattern_clean = pattern.replace("/*", "").replace("*", "")
592
+ if pattern_clean in relative_str:
593
+ return True
594
+
595
+ return False
596
+
597
+ except ValueError:
598
+ return True
599
+
600
+
601
+ class StatisticsGenerator:
602
+ """Generates overall TAG statistics
603
+
604
+ Produces aggregated statistics and metrics for TAG system health.
605
+ """
606
+
607
+ TAG_PATTERN = re.compile(r"@(SPEC|CODE|TEST|DOC):([A-Z]+(?:-[A-Z]+)*-\d{3})")
608
+
609
+ def generate_statistics(self, tags: Dict[str, Set[str]]) -> StatisticsReport:
610
+ """Generate statistics from tags
611
+
612
+ Args:
613
+ tags: Dict mapping type to set of domain IDs
614
+
615
+ Returns:
616
+ StatisticsReport object
617
+ """
618
+ report = StatisticsReport(
619
+ generated_at=datetime.now(),
620
+ total_tags=0,
621
+ by_type={},
622
+ by_domain={},
623
+ coverage={},
624
+ issues={}
625
+ )
626
+
627
+ # Count by type
628
+ for tag_type, domains in tags.items():
629
+ report.by_type[tag_type] = len(domains)
630
+ report.total_tags += len(domains)
631
+
632
+ # Count by domain
633
+ all_domains = set()
634
+ for domains in tags.values():
635
+ all_domains.update(domains)
636
+
637
+ for domain in all_domains:
638
+ # Extract domain prefix
639
+ parts = domain.split("-")
640
+ if parts:
641
+ domain_prefix = parts[0]
642
+ if domain_prefix not in report.by_domain:
643
+ report.by_domain[domain_prefix] = 0
644
+ report.by_domain[domain_prefix] += 1
645
+
646
+ # Calculate coverage metrics
647
+ specs = tags.get("SPEC", set())
648
+ codes = tags.get("CODE", set())
649
+ tests = tags.get("TEST", set())
650
+
651
+ if specs:
652
+ spec_to_code = len(specs & codes) / len(specs) * 100.0
653
+ report.coverage["spec_to_code"] = round(spec_to_code, 2)
654
+
655
+ if codes:
656
+ code_to_test = len(codes & tests) / len(codes) * 100.0
657
+ report.coverage["code_to_test"] = round(code_to_test, 2)
658
+
659
+ # Calculate overall coverage
660
+ if specs:
661
+ total_coverage = 0.0
662
+ for spec in specs:
663
+ components = 0
664
+ if spec in codes:
665
+ components += 1
666
+ if spec in tests:
667
+ components += 1
668
+ if spec in tags.get("DOC", set()):
669
+ components += 1
670
+ total_coverage += (components / 3.0) * 100.0
671
+
672
+ report.coverage["overall_percentage"] = round(total_coverage / len(specs), 2)
673
+ else:
674
+ report.coverage["overall_percentage"] = 0.0
675
+
676
+ # Detect issues
677
+ orphan_codes = codes - tests
678
+ orphan_tests = tests - codes
679
+ report.issues["orphan_count"] = len(orphan_codes) + len(orphan_tests)
680
+
681
+ incomplete_specs = specs - codes
682
+ incomplete_chains = len(incomplete_specs)
683
+ for spec in specs & codes:
684
+ if spec not in tests:
685
+ incomplete_chains += 1
686
+
687
+ report.issues["incomplete_chains"] = incomplete_chains
688
+ report.issues["deprecated_count"] = 0 # Placeholder
689
+
690
+ return report
691
+
692
+ def format_as_json(self, stats: StatisticsReport) -> str:
693
+ """Format statistics as JSON
694
+
695
+ Args:
696
+ stats: StatisticsReport object
697
+
698
+ Returns:
699
+ JSON string
700
+ """
701
+ data = {
702
+ "generated_at": stats.generated_at.isoformat(),
703
+ "total_tags": stats.total_tags,
704
+ "by_type": stats.by_type,
705
+ "by_domain": stats.by_domain,
706
+ "coverage": stats.coverage,
707
+ "issues": stats.issues
708
+ }
709
+
710
+ return json.dumps(data, indent=2)
711
+
712
+ def format_as_human_readable(self, stats: StatisticsReport) -> str:
713
+ """Format statistics as human-readable text
714
+
715
+ Args:
716
+ stats: StatisticsReport object
717
+
718
+ Returns:
719
+ Human-readable string
720
+ """
721
+ lines = []
722
+ lines.append("# TAG Statistics")
723
+ lines.append("")
724
+ lines.append(f"Generated: {stats.generated_at.strftime('%Y-%m-%d %H:%M:%S')}")
725
+ lines.append("")
726
+
727
+ lines.append(f"Total TAGs: {stats.total_tags}")
728
+ lines.append("")
729
+
730
+ lines.append("## By Type")
731
+ for tag_type, count in sorted(stats.by_type.items()):
732
+ lines.append(f"- {tag_type}: {count}")
733
+ lines.append("")
734
+
735
+ lines.append("## By Domain")
736
+ for domain, count in sorted(stats.by_domain.items()):
737
+ lines.append(f"- {domain}: {count}")
738
+ lines.append("")
739
+
740
+ lines.append("## Coverage")
741
+ for metric, value in sorted(stats.coverage.items()):
742
+ lines.append(f"- {metric}: {value}%")
743
+ lines.append("")
744
+
745
+ return "\n".join(lines)
746
+
747
+
748
+ class ReportFormatter:
749
+ """Formats reports in multiple output formats
750
+
751
+ Provides formatting utilities for inventory, matrix, and statistics
752
+ in Markdown, HTML, CSV, and JSON formats.
753
+ """
754
+
755
+ def format_inventory_md(self, inventory: List[TagInventory]) -> str:
756
+ """Format inventory as markdown
757
+
758
+ Args:
759
+ inventory: List of TagInventory objects
760
+
761
+ Returns:
762
+ Markdown string
763
+ """
764
+ generator = InventoryGenerator()
765
+ grouped = generator.group_by_domain(inventory)
766
+ return generator.format_as_markdown(grouped)
767
+
768
+ def format_matrix_md(self, matrix: TagMatrix) -> str:
769
+ """Format matrix as markdown
770
+
771
+ Args:
772
+ matrix: TagMatrix object
773
+
774
+ Returns:
775
+ Markdown string
776
+ """
777
+ generator = MatrixGenerator()
778
+ return generator.format_as_markdown_table(matrix)
779
+
780
+ def format_table(self, headers: List[str], rows: List[List[str]]) -> str:
781
+ """Format data as markdown table
782
+
783
+ Args:
784
+ headers: Table headers
785
+ rows: Table rows
786
+
787
+ Returns:
788
+ Markdown table string
789
+ """
790
+ lines = []
791
+
792
+ # Header row
793
+ lines.append("| " + " | ".join(headers) + " |")
794
+
795
+ # Separator row
796
+ lines.append("| " + " | ".join(["---"] * len(headers)) + " |")
797
+
798
+ # Data rows
799
+ for row in rows:
800
+ lines.append("| " + " | ".join(row) + " |")
801
+
802
+ return "\n".join(lines)
803
+
804
+ def format_html_dashboard(self, inventory: List[TagInventory]) -> str:
805
+ """Format inventory as HTML dashboard (OPTIONAL)
806
+
807
+ Args:
808
+ inventory: List of TagInventory objects
809
+
810
+ Returns:
811
+ HTML string
812
+
813
+ Raises:
814
+ NotImplementedError: HTML formatting is optional
815
+ """
816
+ raise NotImplementedError("HTML dashboard formatting is optional")
817
+
818
+
819
+ class ReportGenerator:
820
+ """Main orchestrator for report generation
821
+
822
+ Coordinates all generators to produce complete reporting suite:
823
+ - tag-inventory.md
824
+ - tag-matrix.md
825
+ - tag-statistics.json
826
+ """
827
+
828
+ def __init__(self):
829
+ """Initialize report generator"""
830
+ self.inventory_gen = InventoryGenerator()
831
+ self.matrix_gen = MatrixGenerator()
832
+ self.coverage_analyzer = CoverageAnalyzer()
833
+ self.stats_gen = StatisticsGenerator()
834
+ self.formatter = ReportFormatter()
835
+
836
+ def generate_inventory_report(self, root_path: str) -> str:
837
+ """Generate inventory report
838
+
839
+ Args:
840
+ root_path: Root directory to scan
841
+
842
+ Returns:
843
+ Markdown inventory report
844
+ """
845
+ inventory = self.inventory_gen.generate_inventory(root_path)
846
+ return self.formatter.format_inventory_md(inventory)
847
+
848
+ def generate_matrix_report(self, root_path: str) -> str:
849
+ """Generate coverage matrix report
850
+
851
+ Args:
852
+ root_path: Root directory to scan
853
+
854
+ Returns:
855
+ Markdown matrix report
856
+ """
857
+ tags = self.coverage_analyzer._collect_tags(root_path)
858
+ matrix = self.matrix_gen.generate_matrix(tags)
859
+ return self.formatter.format_matrix_md(matrix)
860
+
861
+ def generate_statistics_report(self, root_path: str) -> str:
862
+ """Generate statistics report
863
+
864
+ Args:
865
+ root_path: Root directory to scan
866
+
867
+ Returns:
868
+ JSON statistics report
869
+ """
870
+ tags = self.coverage_analyzer._collect_tags(root_path)
871
+ stats = self.stats_gen.generate_statistics(tags)
872
+ return self.stats_gen.format_as_json(stats)
873
+
874
+ def generate_combined_report(self, root_path: str) -> str:
875
+ """Generate combined report with all sections
876
+
877
+ Args:
878
+ root_path: Root directory to scan
879
+
880
+ Returns:
881
+ Combined markdown report
882
+ """
883
+ lines = []
884
+ lines.append("# MoAI-ADK TAG System Report")
885
+ lines.append("")
886
+ lines.append(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
887
+ lines.append("")
888
+
889
+ # Inventory section
890
+ lines.append("---")
891
+ lines.append("")
892
+ lines.append(self.generate_inventory_report(root_path))
893
+ lines.append("")
894
+
895
+ # Matrix section
896
+ lines.append("---")
897
+ lines.append("")
898
+ lines.append(self.generate_matrix_report(root_path))
899
+ lines.append("")
900
+
901
+ # Statistics section
902
+ lines.append("---")
903
+ lines.append("")
904
+ lines.append("# Statistics")
905
+ lines.append("")
906
+ lines.append("```json")
907
+ lines.append(self.generate_statistics_report(root_path))
908
+ lines.append("```")
909
+ lines.append("")
910
+
911
+ return "\n".join(lines)
912
+
913
+ def generate_all_reports(self, root_path: str, output_dir: str) -> ReportResult:
914
+ """Generate all reports and save to output directory
915
+
916
+ Args:
917
+ root_path: Root directory to scan
918
+ output_dir: Output directory for reports
919
+
920
+ Returns:
921
+ ReportResult with file paths
922
+ """
923
+ output = Path(output_dir)
924
+ output.mkdir(parents=True, exist_ok=True)
925
+
926
+ try:
927
+ # Generate inventory
928
+ inventory_path = output / "tag-inventory.md"
929
+ inventory_report = self.generate_inventory_report(root_path)
930
+ inventory_path.write_text(inventory_report, encoding="utf-8")
931
+
932
+ # Generate matrix
933
+ matrix_path = output / "tag-matrix.md"
934
+ matrix_report = self.generate_matrix_report(root_path)
935
+ matrix_path.write_text(matrix_report, encoding="utf-8")
936
+
937
+ # Generate statistics
938
+ statistics_path = output / "tag-statistics.json"
939
+ statistics_report = self.generate_statistics_report(root_path)
940
+ statistics_path.write_text(statistics_report, encoding="utf-8")
941
+
942
+ return ReportResult(
943
+ inventory_path=inventory_path,
944
+ matrix_path=matrix_path,
945
+ statistics_path=statistics_path,
946
+ success=True
947
+ )
948
+
949
+ except Exception as e:
950
+ return ReportResult(
951
+ inventory_path=output / "tag-inventory.md",
952
+ matrix_path=output / "tag-matrix.md",
953
+ statistics_path=output / "tag-statistics.json",
954
+ success=False,
955
+ error_message=str(e)
956
+ )