flyee 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/bin/install.js +357 -0
  4. package/bridge/bridge.py +1780 -0
  5. package/bridge/local_tracker.py +722 -0
  6. package/core/agents/backend-specialist.md +266 -0
  7. package/core/agents/code-archaeologist.md +106 -0
  8. package/core/agents/database-architect.md +226 -0
  9. package/core/agents/debugger.md +225 -0
  10. package/core/agents/devops-engineer.md +323 -0
  11. package/core/agents/documentation-writer.md +104 -0
  12. package/core/agents/explorer-agent.md +73 -0
  13. package/core/agents/frontend-specialist.md +743 -0
  14. package/core/agents/game-developer.md +162 -0
  15. package/core/agents/mobile-developer.md +377 -0
  16. package/core/agents/orchestrator.md +416 -0
  17. package/core/agents/penetration-tester.md +188 -0
  18. package/core/agents/performance-optimizer.md +187 -0
  19. package/core/agents/product-manager.md +112 -0
  20. package/core/agents/product-owner.md +95 -0
  21. package/core/agents/project-planner.md +470 -0
  22. package/core/agents/qa-automation-engineer.md +103 -0
  23. package/core/agents/security-auditor.md +170 -0
  24. package/core/agents/seo-specialist.md +111 -0
  25. package/core/agents/stitch-designer.md +190 -0
  26. package/core/agents/tdd-reviewer.md +282 -0
  27. package/core/agents/test-engineer.md +158 -0
  28. package/core/scripts/auto_preview.py +148 -0
  29. package/core/scripts/checklist.py +243 -0
  30. package/core/scripts/cost_report.py +149 -0
  31. package/core/scripts/doc-sync-check.py +461 -0
  32. package/core/scripts/parse_user_stories.py +79 -0
  33. package/core/scripts/prepare_notion_updates.py +172 -0
  34. package/core/scripts/print_create_payload.py +18 -0
  35. package/core/scripts/session_manager.py +120 -0
  36. package/core/scripts/task_complete.py +127 -0
  37. package/core/scripts/verify_all.py +327 -0
  38. package/core/skills/analytics-strategy/SKILL.md +128 -0
  39. package/core/skills/api-patterns/SKILL.md +81 -0
  40. package/core/skills/api-patterns/api-style.md +42 -0
  41. package/core/skills/api-patterns/auth.md +24 -0
  42. package/core/skills/api-patterns/documentation.md +26 -0
  43. package/core/skills/api-patterns/graphql.md +41 -0
  44. package/core/skills/api-patterns/rate-limiting.md +31 -0
  45. package/core/skills/api-patterns/response.md +37 -0
  46. package/core/skills/api-patterns/rest.md +40 -0
  47. package/core/skills/api-patterns/scripts/api_validator.py +211 -0
  48. package/core/skills/api-patterns/security-testing.md +122 -0
  49. package/core/skills/api-patterns/trpc.md +41 -0
  50. package/core/skills/api-patterns/versioning.md +22 -0
  51. package/core/skills/app-builder/SKILL.md +75 -0
  52. package/core/skills/app-builder/agent-coordination.md +71 -0
  53. package/core/skills/app-builder/feature-building.md +53 -0
  54. package/core/skills/app-builder/project-detection.md +34 -0
  55. package/core/skills/app-builder/scaffolding.md +118 -0
  56. package/core/skills/app-builder/tech-stack.md +40 -0
  57. package/core/skills/app-builder/templates/SKILL.md +39 -0
  58. package/core/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  59. package/core/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  60. package/core/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  61. package/core/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  62. package/core/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  63. package/core/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  64. package/core/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  65. package/core/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
  66. package/core/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
  67. package/core/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
  68. package/core/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
  69. package/core/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  70. package/core/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
  71. package/core/skills/architecture/SKILL.md +55 -0
  72. package/core/skills/architecture/context-discovery.md +43 -0
  73. package/core/skills/architecture/examples.md +94 -0
  74. package/core/skills/architecture/pattern-selection.md +68 -0
  75. package/core/skills/architecture/patterns-reference.md +50 -0
  76. package/core/skills/architecture/trade-off-analysis.md +77 -0
  77. package/core/skills/atomic-design/SKILL.md +282 -0
  78. package/core/skills/atomic-design/references/classification-guide.md +132 -0
  79. package/core/skills/atomic-design/references/quality-checklist.md +60 -0
  80. package/core/skills/atomic-design/references/stacks/stack-blade.md +254 -0
  81. package/core/skills/atomic-design/references/stacks/stack-nextjs.md +272 -0
  82. package/core/skills/atomic-design/references/stacks/stack-react.md +239 -0
  83. package/core/skills/atomic-design/references/stacks/stack-vue.md +224 -0
  84. package/core/skills/bash-linux/SKILL.md +199 -0
  85. package/core/skills/behavioral-modes/SKILL.md +242 -0
  86. package/core/skills/brainstorming/SKILL.md +163 -0
  87. package/core/skills/brainstorming/dynamic-questioning.md +373 -0
  88. package/core/skills/checkpointing-patterns/SKILL.md +163 -0
  89. package/core/skills/clean-code/SKILL.md +201 -0
  90. package/core/skills/code-review-checklist/SKILL.md +109 -0
  91. package/core/skills/code-truth-validation/SKILL.md +149 -0
  92. package/core/skills/component-library-discovery/SKILL.md +154 -0
  93. package/core/skills/content-strategy/SKILL.md +222 -0
  94. package/core/skills/context-budget/SKILL.md +155 -0
  95. package/core/skills/context-gathering-patterns/SKILL.md +278 -0
  96. package/core/skills/cost-tracking/SKILL.md +206 -0
  97. package/core/skills/database-design/SKILL.md +52 -0
  98. package/core/skills/database-design/database-selection.md +43 -0
  99. package/core/skills/database-design/indexing.md +39 -0
  100. package/core/skills/database-design/migrations.md +48 -0
  101. package/core/skills/database-design/optimization.md +36 -0
  102. package/core/skills/database-design/orm-selection.md +30 -0
  103. package/core/skills/database-design/schema-design.md +56 -0
  104. package/core/skills/database-design/scripts/schema_validator.py +172 -0
  105. package/core/skills/deployment-procedures/SKILL.md +295 -0
  106. package/core/skills/design-md/README.md +34 -0
  107. package/core/skills/design-md/SKILL.md +172 -0
  108. package/core/skills/design-md/examples/DESIGN.md +154 -0
  109. package/core/skills/design-system-enforcement/SKILL.md +339 -0
  110. package/core/skills/doc.md +177 -0
  111. package/core/skills/document-registry/SKILL.md +130 -0
  112. package/core/skills/documentation-publishing/SKILL.md +174 -0
  113. package/core/skills/documentation-templates/SKILL.md +194 -0
  114. package/core/skills/enhance-prompt/README.md +34 -0
  115. package/core/skills/enhance-prompt/SKILL.md +204 -0
  116. package/core/skills/enhance-prompt/references/KEYWORDS.md +114 -0
  117. package/core/skills/frontend-design/SKILL.md +430 -0
  118. package/core/skills/frontend-design/animation-guide.md +331 -0
  119. package/core/skills/frontend-design/color-system.md +311 -0
  120. package/core/skills/frontend-design/decision-trees.md +418 -0
  121. package/core/skills/frontend-design/motion-graphics.md +306 -0
  122. package/core/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  123. package/core/skills/frontend-design/scripts/ux_audit.py +722 -0
  124. package/core/skills/frontend-design/typography-system.md +345 -0
  125. package/core/skills/frontend-design/ux-psychology.md +541 -0
  126. package/core/skills/frontend-design/visual-effects.md +383 -0
  127. package/core/skills/game-development/2d-games/SKILL.md +119 -0
  128. package/core/skills/game-development/3d-games/SKILL.md +135 -0
  129. package/core/skills/game-development/SKILL.md +167 -0
  130. package/core/skills/game-development/game-art/SKILL.md +185 -0
  131. package/core/skills/game-development/game-audio/SKILL.md +190 -0
  132. package/core/skills/game-development/game-design/SKILL.md +129 -0
  133. package/core/skills/game-development/mobile-games/SKILL.md +108 -0
  134. package/core/skills/game-development/multiplayer/SKILL.md +132 -0
  135. package/core/skills/game-development/pc-games/SKILL.md +144 -0
  136. package/core/skills/game-development/vr-ar/SKILL.md +123 -0
  137. package/core/skills/game-development/web-games/SKILL.md +150 -0
  138. package/core/skills/geo-fundamentals/SKILL.md +156 -0
  139. package/core/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  140. package/core/skills/git-workflow/SKILL.md +263 -0
  141. package/core/skills/history-check-patterns/SKILL.md +125 -0
  142. package/core/skills/i18n-localization/SKILL.md +154 -0
  143. package/core/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  144. package/core/skills/integration-completeness/SKILL.md +219 -0
  145. package/core/skills/intelligent-routing/SKILL.md +370 -0
  146. package/core/skills/lint-and-validate/SKILL.md +45 -0
  147. package/core/skills/lint-and-validate/scripts/lint_runner.py +173 -0
  148. package/core/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  149. package/core/skills/local-verification/SKILL.md +195 -0
  150. package/core/skills/mcp-builder/SKILL.md +176 -0
  151. package/core/skills/mobile-design/SKILL.md +394 -0
  152. package/core/skills/mobile-design/decision-trees.md +516 -0
  153. package/core/skills/mobile-design/mobile-backend.md +491 -0
  154. package/core/skills/mobile-design/mobile-color-system.md +420 -0
  155. package/core/skills/mobile-design/mobile-debugging.md +122 -0
  156. package/core/skills/mobile-design/mobile-design-thinking.md +357 -0
  157. package/core/skills/mobile-design/mobile-navigation.md +458 -0
  158. package/core/skills/mobile-design/mobile-performance.md +767 -0
  159. package/core/skills/mobile-design/mobile-testing.md +356 -0
  160. package/core/skills/mobile-design/mobile-typography.md +433 -0
  161. package/core/skills/mobile-design/platform-android.md +666 -0
  162. package/core/skills/mobile-design/platform-ios.md +561 -0
  163. package/core/skills/mobile-design/scripts/mobile_audit.py +670 -0
  164. package/core/skills/mobile-design/touch-psychology.md +537 -0
  165. package/core/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +312 -0
  166. package/core/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -0
  167. package/core/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -0
  168. package/core/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -0
  169. package/core/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
  170. package/core/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -0
  171. package/core/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -0
  172. package/core/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -0
  173. package/core/skills/nextjs-react-expert/SKILL.md +267 -0
  174. package/core/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
  175. package/core/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
  176. package/core/skills/nodejs-best-practices/SKILL.md +333 -0
  177. package/core/skills/notion-task-patterns/SKILL.md +2529 -0
  178. package/core/skills/page-specifications/SKILL.md +367 -0
  179. package/core/skills/parallel-agents/SKILL.md +175 -0
  180. package/core/skills/performance-profiling/SKILL.md +143 -0
  181. package/core/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  182. package/core/skills/plan-writing/SKILL.md +190 -0
  183. package/core/skills/powershell-windows/SKILL.md +167 -0
  184. package/core/skills/project-foundation/SKILL.md +117 -0
  185. package/core/skills/project-setup/SKILL.md +141 -0
  186. package/core/skills/project-tracking-patterns/SKILL.md +357 -0
  187. package/core/skills/project-type-discovery/SKILL.md +239 -0
  188. package/core/skills/python-patterns/SKILL.md +441 -0
  189. package/core/skills/qa-test-generation/SKILL.md +156 -0
  190. package/core/skills/react-components/README.md +36 -0
  191. package/core/skills/react-components/SKILL.md +47 -0
  192. package/core/skills/react-components/examples/gold-standard-card.tsx +80 -0
  193. package/core/skills/react-components/package-lock.json +231 -0
  194. package/core/skills/react-components/package.json +16 -0
  195. package/core/skills/react-components/resources/architecture-checklist.md +15 -0
  196. package/core/skills/react-components/resources/component-template.tsx +37 -0
  197. package/core/skills/react-components/resources/stitch-api-reference.md +14 -0
  198. package/core/skills/react-components/resources/style-guide.json +27 -0
  199. package/core/skills/react-components/scripts/fetch-stitch.sh +30 -0
  200. package/core/skills/react-components/scripts/validate.js +68 -0
  201. package/core/skills/red-team-tactics/SKILL.md +199 -0
  202. package/core/skills/remotion/README.md +105 -0
  203. package/core/skills/remotion/SKILL.md +393 -0
  204. package/core/skills/remotion/examples/WalkthroughComposition.tsx +78 -0
  205. package/core/skills/remotion/examples/screens.json +56 -0
  206. package/core/skills/remotion/resources/composition-checklist.md +124 -0
  207. package/core/skills/remotion/resources/screen-slide-template.tsx +123 -0
  208. package/core/skills/remotion/scripts/download-stitch-asset.sh +38 -0
  209. package/core/skills/seo-fundamentals/SKILL.md +129 -0
  210. package/core/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  211. package/core/skills/server-management/SKILL.md +161 -0
  212. package/core/skills/session-resilience/SKILL.md +199 -0
  213. package/core/skills/shadcn-ui/README.md +248 -0
  214. package/core/skills/shadcn-ui/SKILL.md +326 -0
  215. package/core/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
  216. package/core/skills/shadcn-ui/examples/data-table.tsx +313 -0
  217. package/core/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
  218. package/core/skills/shadcn-ui/resources/component-catalog.md +481 -0
  219. package/core/skills/shadcn-ui/resources/customization-guide.md +516 -0
  220. package/core/skills/shadcn-ui/resources/migration-guide.md +463 -0
  221. package/core/skills/shadcn-ui/resources/setup-guide.md +412 -0
  222. package/core/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
  223. package/core/skills/state-machine/SKILL.md +264 -0
  224. package/core/skills/stitch-loop/README.md +54 -0
  225. package/core/skills/stitch-loop/SKILL.md +203 -0
  226. package/core/skills/stitch-loop/examples/SITE.md +73 -0
  227. package/core/skills/stitch-loop/examples/next-prompt.md +25 -0
  228. package/core/skills/stitch-loop/resources/baton-schema.md +61 -0
  229. package/core/skills/stitch-loop/resources/site-template.md +104 -0
  230. package/core/skills/systematic-debugging/SKILL.md +109 -0
  231. package/core/skills/tailwind-patterns/SKILL.md +284 -0
  232. package/core/skills/tdd-validation/SKILL.md +243 -0
  233. package/core/skills/tdd-workflow/SKILL.md +284 -0
  234. package/core/skills/testing-patterns/SKILL.md +196 -0
  235. package/core/skills/testing-patterns/scripts/test_runner.py +219 -0
  236. package/core/skills/ui-ux-discovery/SKILL.md +329 -0
  237. package/core/skills/ui-validation/SKILL.md +190 -0
  238. package/core/skills/ui-validation/scripts/ui_antipattern_check.py +317 -0
  239. package/core/skills/verification-gate/SKILL.md +205 -0
  240. package/core/skills/vulnerability-scanner/SKILL.md +276 -0
  241. package/core/skills/vulnerability-scanner/checklists.md +121 -0
  242. package/core/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  243. package/core/skills/web-design-guidelines/SKILL.md +57 -0
  244. package/core/skills/webapp-testing/SKILL.md +187 -0
  245. package/core/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  246. package/core/templates/ARCHITECTURE.template.md +407 -0
  247. package/core/templates/project-resources.example.json +71 -0
  248. package/core/workflows/atomic.md +182 -0
  249. package/core/workflows/brainstorm.md +134 -0
  250. package/core/workflows/check-task.md +242 -0
  251. package/core/workflows/copy-collect.md +306 -0
  252. package/core/workflows/create-agent.md +33 -0
  253. package/core/workflows/create-skill.md +39 -0
  254. package/core/workflows/create-workflow.md +33 -0
  255. package/core/workflows/create.md +92 -0
  256. package/core/workflows/debug.md +186 -0
  257. package/core/workflows/demand.md +443 -0
  258. package/core/workflows/deploy.md +260 -0
  259. package/core/workflows/discovery.md +267 -0
  260. package/core/workflows/document.md +272 -0
  261. package/core/workflows/ds-components.md +296 -0
  262. package/core/workflows/ds-init.md +58 -0
  263. package/core/workflows/ds-refactor.md +245 -0
  264. package/core/workflows/ds-references.md +197 -0
  265. package/core/workflows/ds-styleguide.md +237 -0
  266. package/core/workflows/ds-token-diff.md +103 -0
  267. package/core/workflows/ds-tokens.md +317 -0
  268. package/core/workflows/ds-validate.md +309 -0
  269. package/core/workflows/execute.md +483 -0
  270. package/core/workflows/extract-template.md +278 -0
  271. package/core/workflows/fix-failed-tests.md +160 -0
  272. package/core/workflows/init-project.md +386 -0
  273. package/core/workflows/legacy-project.md +849 -0
  274. package/core/workflows/log.md +97 -0
  275. package/core/workflows/new-project.md +610 -0
  276. package/core/workflows/new-project.md.bak +3292 -0
  277. package/core/workflows/new-task.md +404 -0
  278. package/core/workflows/orchestrate.md +237 -0
  279. package/core/workflows/page-build.md +296 -0
  280. package/core/workflows/plan.md +89 -0
  281. package/core/workflows/prd.md +255 -0
  282. package/core/workflows/preview.md +81 -0
  283. package/core/workflows/review-page.md +304 -0
  284. package/core/workflows/status.md +86 -0
  285. package/core/workflows/stitch.md +226 -0
  286. package/core/workflows/task-complete.md +473 -0
  287. package/core/workflows/task-update.md +163 -0
  288. package/core/workflows/tdd.md +344 -0
  289. package/core/workflows/test.md +251 -0
  290. package/core/workflows/ui-ux-pro-max.md +437 -0
  291. package/core/workflows/ux-mobile-optimize.md +262 -0
  292. package/core/workflows/ux-mobile-validate.md +297 -0
  293. package/engine-files/GEMINI.md +69 -0
  294. package/package.json +47 -0
  295. package/runtime-adapters/antigravity.js +26 -0
  296. package/runtime-adapters/claude.js +57 -0
  297. package/runtime-adapters/codex.js +51 -0
  298. package/runtime-adapters/copilot.js +51 -0
  299. package/runtime-adapters/cursor.js +51 -0
  300. package/runtime-adapters/gemini-cli.js +30 -0
  301. package/runtime-adapters/opencode.js +51 -0
  302. package/runtime-adapters/windsurf.js +51 -0
@@ -0,0 +1,461 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ doc-sync-check.py — Detecta divergências entre codebase e documentação.
4
+
5
+ Verifica:
6
+ 1. Features em frontend/src/features/ vs PRD Sec 6.1
7
+ 2. SDK modules em frontend/src/lib/flyee-sdk/ vs SDD Sec 3.2
8
+ 3. Implementation Order no SDD vs estado real dos sprints
9
+ 4. Arquivos em docs/ vs INDEX.md
10
+
11
+ Uso:
12
+ python3 .agent/scripts/doc-sync-check.py
13
+ python3 .agent/scripts/doc-sync-check.py --verbose
14
+ python3 .agent/scripts/doc-sync-check.py --section prd
15
+ python3 .agent/scripts/doc-sync-check.py --section sdd
16
+ python3 .agent/scripts/doc-sync-check.py --section index
17
+ """
18
+
19
+ import os
20
+ import re
21
+ import sys
22
+ import argparse
23
+ from pathlib import Path
24
+
25
+ # ─── Paths ──────────────────────────────────────────────────────────────────
26
+
27
+ ROOT = Path(__file__).parent.parent.parent # /home/bruno/flyee
28
+ FEATURES_DIR = ROOT / "frontend/src/features"
29
+ SDK_DIR = ROOT / "frontend/src/lib/flyee-sdk"
30
+ PRD_PATH = ROOT / "docs/PRD-flyee.md"
31
+ SDD_PATH = ROOT / "docs/design/SDD-flyee.md"
32
+ INDEX_PATH = ROOT / "docs/INDEX.md"
33
+
34
+ # ─── ANSI colors ────────────────────────────────────────────────────────────
35
+
36
+ GREEN = "\033[92m"
37
+ YELLOW = "\033[93m"
38
+ RED = "\033[91m"
39
+ CYAN = "\033[96m"
40
+ BOLD = "\033[1m"
41
+ RESET = "\033[0m"
42
+
43
+ ok = f"{GREEN}✅{RESET}"
44
+ warn = f"{YELLOW}⚠️ {RESET}"
45
+ err = f"{RED}❌{RESET}"
46
+
47
+
48
+ # ─── Helpers ────────────────────────────────────────────────────────────────
49
+
50
+ def read_file(path: Path) -> str:
51
+ try:
52
+ return path.read_text(encoding="utf-8")
53
+ except FileNotFoundError:
54
+ return ""
55
+
56
+
57
+ def section(title: str):
58
+ print(f"\n{BOLD}{CYAN}{'─'*60}{RESET}")
59
+ print(f"{BOLD}{CYAN} {title}{RESET}")
60
+ print(f"{BOLD}{CYAN}{'─'*60}{RESET}")
61
+
62
+
63
+ # ─── Check 1: Features vs PRD ───────────────────────────────────────────────
64
+
65
+ def check_features_vs_prd(verbose: bool) -> int:
66
+ section("1. Features implementadas vs PRD Sec 6.1")
67
+ issues = 0
68
+
69
+ if not FEATURES_DIR.exists():
70
+ print(f" {warn} features dir não encontrado: {FEATURES_DIR}")
71
+ return 1
72
+
73
+ implemented = sorted([d.name for d in FEATURES_DIR.iterdir() if d.is_dir()])
74
+ prd_text = read_file(PRD_PATH)
75
+
76
+ # Extract feature table rows from PRD (lines with | F\d+ |)
77
+ prd_feature_rows = re.findall(r"\|\s*(F\d+)\s*\|.*?\|.*?\|\s*(✅[^|]*|⏳[^|]*|\?[^|]*)\|", prd_text)
78
+ prd_statuses = {f_id.strip(): status.strip() for f_id, status in prd_feature_rows}
79
+
80
+ # Map known feature dirs to F-IDs (extend as project grows)
81
+ feature_map = {
82
+ "activity": ("F7", "Activity Feed"),
83
+ "decisions": ("F5", "Decision Log"),
84
+ "dev-activity": ("F7", "Activity Feed (Dev)"),
85
+ "documents": ("F4", "Document Viewer + Planning History"),
86
+ "health": (None, "Health check (internal)"),
87
+ "knowledge": ("F6", "Knowledge Hub"),
88
+ "okrs": ("F10", "OKR Dashboard"),
89
+ "projects": ("F2", "Project CRUD"),
90
+ "proposals": ("F9", "Proposal Module"),
91
+ "tasks": ("F3", "Task Management + F10 QA Gate"),
92
+ }
93
+
94
+ print(f" {'Feature Dir':<20} {'F-ID':<8} {'PRD Status':<30} {'Check'}")
95
+ print(f" {'─'*20} {'─'*8} {'─'*30} {'─'*10}")
96
+
97
+ for feat_dir in implemented:
98
+ mapping = feature_map.get(feat_dir)
99
+ if mapping is None:
100
+ if verbose:
101
+ print(f" {warn} {feat_dir:<20} {'?':<8} {'Not in feature_map':<30} {warn} unmapped")
102
+ issues += 1
103
+ continue
104
+
105
+ f_id, label = mapping
106
+ if f_id is None:
107
+ if verbose:
108
+ print(f" {feat_dir:<22} {'—':<8} {'Internal':<30} {ok}")
109
+ continue
110
+
111
+ # Check if f_id documented in PRD
112
+ documented = f_id in prd_statuses
113
+ status_in_prd = prd_statuses.get(f_id, "NOT IN PRD")
114
+ has_done = "Done" in status_in_prd or "✅" in status_in_prd
115
+
116
+ if not documented:
117
+ symbol = err
118
+ issues += 1
119
+ elif not has_done:
120
+ symbol = warn
121
+ issues += 1
122
+ else:
123
+ symbol = ok
124
+
125
+ print(f" {feat_dir:<22} {f_id:<8} {status_in_prd[:30]:<32} {symbol}")
126
+
127
+ # Check if PRD has F-IDs that don't map to any feature dir
128
+ all_known_fids = {v[0] for v in feature_map.values() if v[0]}
129
+ for f_id, status in prd_statuses.items():
130
+ if f_id not in all_known_fids:
131
+ if verbose:
132
+ print(f" {warn} PRD has {f_id} but no matching feature dir")
133
+
134
+ return issues
135
+
136
+
137
+ # ─── Check 2: SDK modules vs SDD ────────────────────────────────────────────
138
+
139
+ def check_sdk_vs_sdd(verbose: bool) -> int:
140
+ section("2. SDK modules vs SDD Sec 3.2")
141
+ issues = 0
142
+
143
+ if not SDK_DIR.exists():
144
+ print(f" {warn} SDK dir não encontrado: {SDK_DIR}")
145
+ return 1
146
+
147
+ sdk_files = sorted([f.stem for f in SDK_DIR.glob("*.ts") if f.stem not in ("index", "client")])
148
+ sdd_text = read_file(SDD_PATH)
149
+
150
+ # Extract SDK module rows only from Section 3.2 of SDD
151
+ # Look for the table between "### 3.2 Flyee SDK Layer" and the next "###"
152
+ sdk_section_match = re.search(
153
+ r"### 3\.2 Flyee SDK Layer(.+?)(?=^###|\.\.\.END)",
154
+ sdd_text, re.DOTALL | re.MULTILINE
155
+ )
156
+ sdk_section = sdk_section_match.group(1) if sdk_section_match else sdd_text
157
+ sdd_sdk_rows = re.findall(r"\|\s*`([a-z][a-z0-9\-]+\.ts)`\s*\|", sdk_section)
158
+ sdd_modules = {r.replace(".ts", "") for r in sdd_sdk_rows}
159
+
160
+ # Only check files actually in flyee-sdk/ (not stores or other libs)
161
+ sdk_files_to_check = [f for f in sdk_files if f != "types"] # types.ts is internal
162
+
163
+ # Known stores (live in lib/stores/, NOT in flyee-sdk/) — exclude from SDD check
164
+ known_stores = {"auth-store", "collections", "organizations", "sources", "usage", "user", "webhooks",
165
+ "activityStore", "decisionsStore", "projectsStore", "sidePanelStore", "tasksStore",
166
+ "okrsStore", "documentsStore", "apiKeys", "authProviders", "uiStore", "index"}
167
+
168
+ print(f" {'SDK File':<30} {'In SDD':<10} {'Status'}")
169
+ print(f" {'─'*30} {'─'*10} {'─'*10}")
170
+
171
+ for sdk_file in sdk_files_to_check:
172
+ in_sdd = sdk_file in sdd_modules
173
+ symbol = ok if in_sdd else err
174
+ if not in_sdd:
175
+ issues += 1
176
+ print(f" {sdk_file+'.ts':<32} {'✓' if in_sdd else 'MISSING':<10} {symbol}")
177
+
178
+ # Modules in SDD but not in filesystem and not in known_stores
179
+ for sdd_mod in sorted(sdd_modules):
180
+ if sdd_mod in known_stores:
181
+ continue # skip stores — they live in lib/stores/, not lib/flyee-sdk/
182
+ actual_file = SDK_DIR / f"{sdd_mod}.ts"
183
+ if not actual_file.exists():
184
+ print(f" {warn} SDD documenta `{sdd_mod}.ts` mas arquivo não existe no SDK dir")
185
+ issues += 1
186
+
187
+ return issues
188
+
189
+
190
+ # ─── Check 3: Implementation Order vs sprints ────────────────────────────────
191
+
192
+ def check_impl_order(verbose: bool) -> int:
193
+ section("3. SDD Sec 13 — Implementation Order")
194
+ issues = 0
195
+
196
+ sdd_text = read_file(SDD_PATH)
197
+
198
+ # Find Implementation Order table rows: | N | Description | Status | Dependency |
199
+ rows = re.findall(
200
+ r"\|\s*(\d+)\s*\|\s*(.+?)\s*\|\s*(✅[^|]*|⏳[^|]*|\?[^|]*|[^|]+)\s*\|\s*([^|]+)\s*\|",
201
+ sdd_text
202
+ )
203
+
204
+ if not rows:
205
+ print(f" {warn} Não encontrei tabela de Implementation Order no SDD")
206
+ return 1
207
+
208
+ pending = []
209
+ done = []
210
+ for num, component, status, dep in rows:
211
+ status = status.strip()
212
+ component = component.strip()
213
+ if "Done" in status or "✅" in status:
214
+ done.append((num, component))
215
+ elif "⏳" in status or "Pendente" in status:
216
+ pending.append((num, component))
217
+ else:
218
+ pending.append((num, component))
219
+ issues += 1
220
+
221
+ print(f" {ok} Concluídos: {len(done)} itens")
222
+ print(f" {'⏳'} Pendentes: {len(pending)} itens")
223
+
224
+ if pending:
225
+ print(f"\n Pendentes:")
226
+ for num, comp in pending:
227
+ print(f" #{num} {comp[:60]}")
228
+
229
+ if len(done) == 0:
230
+ print(f" {err} Nenhum item marcado como Done — SDD pode estar desatualizado")
231
+ issues += 1
232
+
233
+ return issues
234
+
235
+
236
+ # ─── Check 4: docs/ vs INDEX.md ─────────────────────────────────────────────
237
+
238
+ def check_docs_index(verbose: bool) -> int:
239
+ section("4. docs/ vs INDEX.md")
240
+ issues = 0
241
+
242
+ docs_dir = ROOT / "docs"
243
+ if not docs_dir.exists():
244
+ print(f" {warn} docs/ dir não encontrado")
245
+ return 1
246
+
247
+ # All .md files (excluding INDEX itself, recursively)
248
+ all_docs = sorted([
249
+ f.relative_to(ROOT)
250
+ for f in docs_dir.rglob("*.md")
251
+ if f.name != "INDEX.md"
252
+ ])
253
+
254
+ index_text = read_file(INDEX_PATH)
255
+
256
+ print(f" {'Arquivo':<50} {'Em INDEX.md'}")
257
+ print(f" {'─'*50} {'─'*12}")
258
+
259
+ for doc_path in all_docs:
260
+ doc_name = doc_path.name
261
+ in_index = doc_name in index_text or str(doc_path) in index_text
262
+ symbol = ok if in_index else warn
263
+ if not in_index:
264
+ issues += 1
265
+ if verbose or not in_index:
266
+ print(f" {str(doc_path):<52} {symbol}")
267
+
268
+ if not verbose:
269
+ print(f"\n {ok} {len(all_docs) - issues}/{len(all_docs)} documentos registrados no INDEX.md")
270
+ if issues:
271
+ print(f" {warn} {issues} doc(s) não encontrados no INDEX — rode com --verbose para ver quais")
272
+
273
+ return issues
274
+
275
+
276
+ # ─── Check 5: BREAKDOWN-tasks.md vs Flyee ────────────────────────────────────
277
+
278
+ def check_breakdown_vs_flyee(verbose: bool) -> int:
279
+ section("5. BREAKDOWN-tasks.md vs Flyee")
280
+ issues = 0
281
+
282
+ breakdown_path = ROOT / "docs/BREAKDOWN-tasks.md"
283
+ if not breakdown_path.exists():
284
+ print(f" {warn} docs/BREAKDOWN-tasks.md não encontrado")
285
+ return 1
286
+
287
+ # ── Parse BREAKDOWN: extrair headers das tasks + sprint ────────────────
288
+ breakdown_text = read_file(breakdown_path)
289
+
290
+ sprint_pattern = re.compile(r"^## Sprint (\d+)[:\s]+(.+)$", re.MULTILINE)
291
+ task_pattern = re.compile(r"^### (T\d+\.\d+) — (.+)$", re.MULTILINE)
292
+
293
+ sprints = [(int(m.group(1)), m.start()) for m in sprint_pattern.finditer(breakdown_text)]
294
+ tasks_raw = [(m.group(1), m.group(2).strip(), m.start()) for m in task_pattern.finditer(breakdown_text)]
295
+
296
+ def find_sprint_for_pos(pos: int) -> int:
297
+ sprint = 0
298
+ for s_num, s_pos in sprints:
299
+ if s_pos <= pos:
300
+ sprint = s_num
301
+ return sprint
302
+
303
+ breakdown_tasks: dict = {}
304
+ for t_id, t_name, t_pos in tasks_raw:
305
+ sprint_num = find_sprint_for_pos(t_pos)
306
+ breakdown_tasks[t_id] = {"name": t_name, "sprint": sprint_num}
307
+
308
+
309
+ # ── Sprints concluídos: ler tabela Summary do próprio BREAKDOWN ─────────
310
+ # Busca linhas da tabela com "✅ Done" — sprints sem esse marcador são pendentes
311
+ pending_sprints: set = set()
312
+ for line in breakdown_text.splitlines():
313
+ # Linha da tabela: | **N** | T... | 🔲 Pendente | ... |
314
+ m = re.match(r"\|\s*\*\*(\d+)\*\*\s*\|.+?🔲", line)
315
+ if m:
316
+ pending_sprints.add(int(m.group(1)))
317
+
318
+ # Todos os sprints encontrados no breakdown
319
+ all_sprints = {info["sprint"] for info in breakdown_tasks.values() if info["sprint"] > 0}
320
+ completed_sprints = all_sprints - pending_sprints
321
+
322
+
323
+ # ── Carregar tasks do Flyee via bridge CLI ─────────────────────────────
324
+ import subprocess
325
+ bridge = ROOT / ".agent/flyee-bridge/bridge.py"
326
+
327
+ flyee_tasks: dict = {} # "T1.1" -> "completed" | "running" | ...
328
+ if bridge.exists():
329
+ try:
330
+ result = subprocess.run(
331
+ ["python3", str(bridge), "--list-tasks"],
332
+ capture_output=True, text=True, timeout=15, cwd=str(ROOT)
333
+ )
334
+ for line in result.stdout.splitlines():
335
+ # Format: "N T1.1 — Name status uuid"
336
+ m = re.match(
337
+ r"\s*\d+\s+(T\d+\.\d+)[^\t]+?\s{2,}(completed|running|pending|failed|testing|cancelled)\s",
338
+ line
339
+ )
340
+ if m:
341
+ t_label, t_status = m.group(1), m.group(2)
342
+ flyee_tasks[t_label] = t_status # last occurrence wins
343
+ except Exception as e:
344
+ print(f" {warn} Não foi possível carregar tasks do Flyee: {e}")
345
+ else:
346
+ print(f" {warn} Bridge não encontrado — pulando verificação Flyee")
347
+
348
+ # ── Comparar ────────────────────────────────────────────────────────────
349
+ ghost_running = [] # sprint Done no SDD mas task ainda 'running' no Flyee
350
+
351
+ for t_id, info in sorted(breakdown_tasks.items()):
352
+ sprint = info["sprint"]
353
+ if sprint not in completed_sprints:
354
+ continue # sprint ainda em andamento — OK estar running
355
+ flyee_status = flyee_tasks.get(t_id)
356
+ if flyee_status is not None and flyee_status != "completed":
357
+ ghost_running.append((t_id, info["name"], sprint, flyee_status))
358
+ issues += 1
359
+
360
+ # Tasks no Flyee como 'running' cujo sprint já é Done
361
+ for t_label, t_status in flyee_tasks.items():
362
+ if t_status == "running" and t_label in breakdown_tasks:
363
+ sprint = breakdown_tasks[t_label]["sprint"]
364
+ if sprint in completed_sprints and not any(g[0] == t_label for g in ghost_running):
365
+ ghost_running.append((t_label, breakdown_tasks[t_label]["name"], sprint, "running"))
366
+ issues += 1
367
+
368
+ # ── Output ──────────────────────────────────────────────────────────────
369
+ total_bd = len(breakdown_tasks)
370
+ matched = sum(1 for t in breakdown_tasks if t in flyee_tasks)
371
+
372
+ print(f" Tasks no BREAKDOWN: {total_bd}")
373
+ print(f" Tasks encontradas no Flyee: {matched}/{total_bd}")
374
+ print(f" Sprints concluídos (SDD): {sorted(completed_sprints)}")
375
+
376
+ if not ghost_running:
377
+ print(f"\n {ok} Nenhuma divergência BREAKDOWN ↔ Flyee")
378
+ else:
379
+ print(f"\n {err} {len(ghost_running)} task(s) com status desatualizado no Flyee:")
380
+ print(f" {'Task':<12} {'Sprint':<8} {'Status Flyee':<16} {'Nome'}")
381
+ print(f" {'─'*12} {'─'*8} {'─'*16} {'─'*40}")
382
+ for t_id, name, sprint, status in sorted(ghost_running):
383
+ print(f" {t_id:<14} {str(sprint):<8} {status:<18} {name[:40]}")
384
+ print(f"\n Para corrigir (substitua <uuid> pelo ID real do Flyee):")
385
+ print(f" python3 .agent/flyee-bridge/bridge.py --update-task <uuid> --status completed --result success")
386
+
387
+ # Tasks de sprints concluídos não encontradas no Flyee (verbose only)
388
+ if verbose:
389
+ not_in_flyee = [
390
+ (t_id, info) for t_id, info in breakdown_tasks.items()
391
+ if t_id not in flyee_tasks and info["sprint"] in completed_sprints
392
+ ]
393
+ if not_in_flyee:
394
+ print(f"\n {warn} Tasks de sprints concluídos não encontradas no Flyee:")
395
+ for t_id, info in sorted(not_in_flyee):
396
+ print(f" Sprint {info['sprint']}: {t_id} — {info['name']}")
397
+
398
+ return issues
399
+
400
+
401
+ # ─── Summary ─────────────────────────────────────────────────────────────────
402
+
403
+ def print_summary(total_issues: int):
404
+ section("Resumo")
405
+ if total_issues == 0:
406
+ print(f" {ok} {GREEN}{BOLD}Docs sincronizados — nenhuma divergência encontrada.{RESET}")
407
+ else:
408
+ print(f" {err} {RED}{BOLD}{total_issues} divergência(s) encontrada(s).{RESET}")
409
+ print(f"\n Próximos passos:")
410
+ print(f" 1. Corrija as divergências ANTES de marcar a task como concluída")
411
+ print(f" 2. Features F-level: atualizar PRD Sec 6.1 + SDD Sec 13")
412
+ print(f" 3. SDK changes: atualizar SDD Sec 3.2")
413
+ print(f" 4. Novos docs: atualizar docs/INDEX.md")
414
+ print(f" 5. Tasks desatualizadas: bridge.py --update-task <uuid> --status completed")
415
+ print()
416
+ print(f" Docs relevantes:")
417
+ print(f" PRD: docs/PRD-flyee.md")
418
+ print(f" SDD: docs/design/SDD-flyee.md")
419
+ print(f" INDEX: docs/INDEX.md")
420
+ print(f" BREAKDOWN: docs/BREAKDOWN-tasks.md")
421
+
422
+
423
+ # ─── Main ───────────────────────────────────────────────────────────────────
424
+
425
+ def main():
426
+ parser = argparse.ArgumentParser(
427
+ description="Detecta divergências entre codebase e documentação do projeto Flyee."
428
+ )
429
+ parser.add_argument("--verbose", "-v", action="store_true", help="Output detalhado")
430
+ parser.add_argument(
431
+ "--section", "-s",
432
+ choices=["prd", "sdd", "index", "breakdown", "all"],
433
+ default="all",
434
+ help="Rodar apenas uma seção específica (default: all)"
435
+ )
436
+ args = parser.parse_args()
437
+
438
+ print(f"\n{BOLD}🔍 doc-sync-check — Flyee Documentation Audit{RESET}")
439
+ print(f" Root: {ROOT}")
440
+
441
+ total_issues = 0
442
+
443
+ if args.section in ("prd", "all"):
444
+ total_issues += check_features_vs_prd(args.verbose)
445
+
446
+ if args.section in ("sdd", "all"):
447
+ total_issues += check_sdk_vs_sdd(args.verbose)
448
+ total_issues += check_impl_order(args.verbose)
449
+
450
+ if args.section in ("index", "all"):
451
+ total_issues += check_docs_index(args.verbose)
452
+
453
+ if args.section in ("breakdown", "all"):
454
+ total_issues += check_breakdown_vs_flyee(args.verbose)
455
+
456
+ print_summary(total_issues)
457
+ sys.exit(0 if total_issues == 0 else 1)
458
+
459
+
460
+ if __name__ == "__main__":
461
+ main()
@@ -0,0 +1,79 @@
1
+
2
+ import re
3
+ import json
4
+
5
+ import argparse
6
+ import os
7
+
8
+ def parse_user_stories(file_path):
9
+ if not os.path.exists(file_path):
10
+ raise FileNotFoundError(f"Input file not found: {file_path}")
11
+
12
+ with open(file_path, 'r', encoding='utf-8') as f:
13
+ content = f.read()
14
+
15
+ stories = []
16
+ # Regex to find story blocks
17
+ # Looking for ### Title then content until next ### or ---
18
+
19
+ sections = re.split(r'### ', content)[1:] # Skip preamble
20
+
21
+ for section in sections:
22
+ lines = section.split('\n')
23
+ title_line = lines[0].strip()
24
+
25
+ # Extract ID and Title (e.g., "1.1 Setup Inicial Next.js")
26
+ match = re.match(r'(\d+\.\d+)\s+(.+)', title_line)
27
+ if not match:
28
+ continue
29
+
30
+ story_id = match.group(1)
31
+ story_title = match.group(2)
32
+ full_title = f"{story_id} {story_title}"
33
+
34
+ # Parse fields
35
+ body = section
36
+
37
+ priority_match = re.search(r'\*\*Priority:\*\*\s*(.+)', body)
38
+ priority = priority_match.group(1).strip() if priority_match else "Medium"
39
+
40
+ estimate_match = re.search(r'\*\*Estimate:\*\*\s*(.+)', body)
41
+ estimate = estimate_match.group(1).strip() if estimate_match else "M"
42
+
43
+ agent_match = re.search(r'\*\*Agent:\*\*\s*(.+)', body)
44
+ agent = agent_match.group(1).strip() if agent_match else "Pending"
45
+
46
+ # Extract User Story and Acceptance Criteria for Description
47
+ desc_start = body.find('**User Story:**')
48
+ desc_end = body.find('**Verification:**')
49
+ if desc_end == -1:
50
+ desc_end = body.find('---', desc_start)
51
+
52
+ description = body[desc_start:desc_end].strip() if desc_start != -1 else body.strip()
53
+
54
+ stories.append({
55
+ "id": story_id,
56
+ "title": full_title,
57
+ "priority": priority,
58
+ "estimate": estimate,
59
+ "agent": agent,
60
+ "description": description
61
+ })
62
+
63
+ return stories
64
+
65
+ if __name__ == "__main__":
66
+ parser = argparse.ArgumentParser(description="Parse User Stories from Markdown to JSON")
67
+ parser.add_argument("--input", required=True, help="Input Markdown file path")
68
+ parser.add_argument("--output", default="stories.json", help="Output JSON file path")
69
+
70
+ args = parser.parse_args()
71
+
72
+ try:
73
+ results = parse_user_stories(args.input)
74
+ with open(args.output, 'w', encoding='utf-8') as f:
75
+ json.dump(results, f, indent=2, ensure_ascii=False)
76
+ print(f"✅ Successfully wrote {len(results)} stories to {args.output}")
77
+ except Exception as e:
78
+ print(f"❌ Error: {e}")
79
+