solokit 0.1.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.
Files changed (323) hide show
  1. solokit/__init__.py +10 -0
  2. solokit/__version__.py +3 -0
  3. solokit/cli.py +374 -0
  4. solokit/core/__init__.py +1 -0
  5. solokit/core/cache.py +102 -0
  6. solokit/core/command_runner.py +278 -0
  7. solokit/core/config.py +453 -0
  8. solokit/core/config_validator.py +204 -0
  9. solokit/core/constants.py +291 -0
  10. solokit/core/error_formatter.py +279 -0
  11. solokit/core/error_handlers.py +346 -0
  12. solokit/core/exceptions.py +1567 -0
  13. solokit/core/file_ops.py +309 -0
  14. solokit/core/logging_config.py +166 -0
  15. solokit/core/output.py +99 -0
  16. solokit/core/performance.py +57 -0
  17. solokit/core/protocols.py +141 -0
  18. solokit/core/types.py +312 -0
  19. solokit/deployment/__init__.py +1 -0
  20. solokit/deployment/executor.py +411 -0
  21. solokit/git/__init__.py +1 -0
  22. solokit/git/integration.py +619 -0
  23. solokit/init/__init__.py +41 -0
  24. solokit/init/claude_commands_installer.py +87 -0
  25. solokit/init/dependency_installer.py +313 -0
  26. solokit/init/docs_structure.py +90 -0
  27. solokit/init/env_generator.py +160 -0
  28. solokit/init/environment_validator.py +334 -0
  29. solokit/init/git_hooks_installer.py +71 -0
  30. solokit/init/git_setup.py +188 -0
  31. solokit/init/gitignore_updater.py +195 -0
  32. solokit/init/initial_commit.py +145 -0
  33. solokit/init/initial_scans.py +109 -0
  34. solokit/init/orchestrator.py +246 -0
  35. solokit/init/readme_generator.py +207 -0
  36. solokit/init/session_structure.py +239 -0
  37. solokit/init/template_installer.py +424 -0
  38. solokit/learning/__init__.py +1 -0
  39. solokit/learning/archiver.py +115 -0
  40. solokit/learning/categorizer.py +126 -0
  41. solokit/learning/curator.py +428 -0
  42. solokit/learning/extractor.py +352 -0
  43. solokit/learning/reporter.py +351 -0
  44. solokit/learning/repository.py +254 -0
  45. solokit/learning/similarity.py +342 -0
  46. solokit/learning/validator.py +144 -0
  47. solokit/project/__init__.py +1 -0
  48. solokit/project/init.py +1162 -0
  49. solokit/project/stack.py +436 -0
  50. solokit/project/sync_plugin.py +438 -0
  51. solokit/project/tree.py +375 -0
  52. solokit/quality/__init__.py +1 -0
  53. solokit/quality/api_validator.py +424 -0
  54. solokit/quality/checkers/__init__.py +25 -0
  55. solokit/quality/checkers/base.py +114 -0
  56. solokit/quality/checkers/context7.py +221 -0
  57. solokit/quality/checkers/custom.py +162 -0
  58. solokit/quality/checkers/deployment.py +323 -0
  59. solokit/quality/checkers/documentation.py +179 -0
  60. solokit/quality/checkers/formatting.py +161 -0
  61. solokit/quality/checkers/integration.py +394 -0
  62. solokit/quality/checkers/linting.py +159 -0
  63. solokit/quality/checkers/security.py +261 -0
  64. solokit/quality/checkers/spec_completeness.py +127 -0
  65. solokit/quality/checkers/tests.py +184 -0
  66. solokit/quality/env_validator.py +306 -0
  67. solokit/quality/gates.py +655 -0
  68. solokit/quality/reporters/__init__.py +10 -0
  69. solokit/quality/reporters/base.py +25 -0
  70. solokit/quality/reporters/console.py +98 -0
  71. solokit/quality/reporters/json_reporter.py +34 -0
  72. solokit/quality/results.py +98 -0
  73. solokit/session/__init__.py +1 -0
  74. solokit/session/briefing/__init__.py +245 -0
  75. solokit/session/briefing/documentation_loader.py +53 -0
  76. solokit/session/briefing/formatter.py +476 -0
  77. solokit/session/briefing/git_context.py +282 -0
  78. solokit/session/briefing/learning_loader.py +212 -0
  79. solokit/session/briefing/milestone_builder.py +78 -0
  80. solokit/session/briefing/orchestrator.py +137 -0
  81. solokit/session/briefing/stack_detector.py +51 -0
  82. solokit/session/briefing/tree_generator.py +52 -0
  83. solokit/session/briefing/work_item_loader.py +209 -0
  84. solokit/session/briefing.py +353 -0
  85. solokit/session/complete.py +1188 -0
  86. solokit/session/status.py +246 -0
  87. solokit/session/validate.py +452 -0
  88. solokit/templates/.claude/commands/end.md +109 -0
  89. solokit/templates/.claude/commands/init.md +159 -0
  90. solokit/templates/.claude/commands/learn-curate.md +88 -0
  91. solokit/templates/.claude/commands/learn-search.md +62 -0
  92. solokit/templates/.claude/commands/learn-show.md +69 -0
  93. solokit/templates/.claude/commands/learn.md +136 -0
  94. solokit/templates/.claude/commands/start.md +114 -0
  95. solokit/templates/.claude/commands/status.md +22 -0
  96. solokit/templates/.claude/commands/validate.md +27 -0
  97. solokit/templates/.claude/commands/work-delete.md +119 -0
  98. solokit/templates/.claude/commands/work-graph.md +139 -0
  99. solokit/templates/.claude/commands/work-list.md +26 -0
  100. solokit/templates/.claude/commands/work-new.md +114 -0
  101. solokit/templates/.claude/commands/work-next.md +25 -0
  102. solokit/templates/.claude/commands/work-show.md +24 -0
  103. solokit/templates/.claude/commands/work-update.md +141 -0
  104. solokit/templates/CHANGELOG.md +17 -0
  105. solokit/templates/WORK_ITEM_TYPES.md +141 -0
  106. solokit/templates/__init__.py +1 -0
  107. solokit/templates/bug_spec.md +217 -0
  108. solokit/templates/config.schema.json +150 -0
  109. solokit/templates/dashboard_refine/base/.gitignore +36 -0
  110. solokit/templates/dashboard_refine/base/app/(dashboard)/layout.tsx +22 -0
  111. solokit/templates/dashboard_refine/base/app/(dashboard)/page.tsx +68 -0
  112. solokit/templates/dashboard_refine/base/app/(dashboard)/users/page.tsx +77 -0
  113. solokit/templates/dashboard_refine/base/app/globals.css +60 -0
  114. solokit/templates/dashboard_refine/base/app/layout.tsx +23 -0
  115. solokit/templates/dashboard_refine/base/app/page.tsx +9 -0
  116. solokit/templates/dashboard_refine/base/components/client-refine-wrapper.tsx +21 -0
  117. solokit/templates/dashboard_refine/base/components/layout/header.tsx +44 -0
  118. solokit/templates/dashboard_refine/base/components/layout/sidebar.tsx +82 -0
  119. solokit/templates/dashboard_refine/base/components/ui/button.tsx +53 -0
  120. solokit/templates/dashboard_refine/base/components/ui/card.tsx +78 -0
  121. solokit/templates/dashboard_refine/base/components/ui/table.tsx +116 -0
  122. solokit/templates/dashboard_refine/base/components.json +16 -0
  123. solokit/templates/dashboard_refine/base/lib/refine.tsx +65 -0
  124. solokit/templates/dashboard_refine/base/lib/utils.ts +13 -0
  125. solokit/templates/dashboard_refine/base/next.config.ts +10 -0
  126. solokit/templates/dashboard_refine/base/package.json.template +40 -0
  127. solokit/templates/dashboard_refine/base/postcss.config.mjs +8 -0
  128. solokit/templates/dashboard_refine/base/providers/refine-provider.tsx +26 -0
  129. solokit/templates/dashboard_refine/base/tailwind.config.ts +57 -0
  130. solokit/templates/dashboard_refine/base/tsconfig.json +27 -0
  131. solokit/templates/dashboard_refine/docker/Dockerfile +57 -0
  132. solokit/templates/dashboard_refine/docker/docker-compose.prod.yml +31 -0
  133. solokit/templates/dashboard_refine/docker/docker-compose.yml +21 -0
  134. solokit/templates/dashboard_refine/tier-1-essential/.eslintrc.json +7 -0
  135. solokit/templates/dashboard_refine/tier-1-essential/jest.config.ts +17 -0
  136. solokit/templates/dashboard_refine/tier-1-essential/jest.setup.ts +1 -0
  137. solokit/templates/dashboard_refine/tier-1-essential/package.json.tier1.template +57 -0
  138. solokit/templates/dashboard_refine/tier-1-essential/tests/setup.ts +26 -0
  139. solokit/templates/dashboard_refine/tier-1-essential/tests/unit/example.test.tsx +73 -0
  140. solokit/templates/dashboard_refine/tier-2-standard/package.json.tier2.template +62 -0
  141. solokit/templates/dashboard_refine/tier-3-comprehensive/eslint.config.mjs +22 -0
  142. solokit/templates/dashboard_refine/tier-3-comprehensive/package.json.tier3.template +79 -0
  143. solokit/templates/dashboard_refine/tier-3-comprehensive/playwright.config.ts +66 -0
  144. solokit/templates/dashboard_refine/tier-3-comprehensive/stryker.conf.json +38 -0
  145. solokit/templates/dashboard_refine/tier-3-comprehensive/tests/e2e/dashboard.spec.ts +88 -0
  146. solokit/templates/dashboard_refine/tier-3-comprehensive/tests/e2e/user-management.spec.ts +102 -0
  147. solokit/templates/dashboard_refine/tier-3-comprehensive/tests/integration/dashboard.test.tsx +90 -0
  148. solokit/templates/dashboard_refine/tier-3-comprehensive/type-coverage.json +16 -0
  149. solokit/templates/dashboard_refine/tier-4-production/instrumentation.ts +9 -0
  150. solokit/templates/dashboard_refine/tier-4-production/k6/dashboard-load-test.js +70 -0
  151. solokit/templates/dashboard_refine/tier-4-production/next.config.ts +46 -0
  152. solokit/templates/dashboard_refine/tier-4-production/package.json.tier4.template +89 -0
  153. solokit/templates/dashboard_refine/tier-4-production/sentry.client.config.ts +26 -0
  154. solokit/templates/dashboard_refine/tier-4-production/sentry.edge.config.ts +11 -0
  155. solokit/templates/dashboard_refine/tier-4-production/sentry.server.config.ts +11 -0
  156. solokit/templates/deployment_spec.md +500 -0
  157. solokit/templates/feature_spec.md +248 -0
  158. solokit/templates/fullstack_nextjs/base/.gitignore +36 -0
  159. solokit/templates/fullstack_nextjs/base/app/api/example/route.ts +65 -0
  160. solokit/templates/fullstack_nextjs/base/app/globals.css +27 -0
  161. solokit/templates/fullstack_nextjs/base/app/layout.tsx +20 -0
  162. solokit/templates/fullstack_nextjs/base/app/page.tsx +32 -0
  163. solokit/templates/fullstack_nextjs/base/components/example-component.tsx +20 -0
  164. solokit/templates/fullstack_nextjs/base/lib/prisma.ts +17 -0
  165. solokit/templates/fullstack_nextjs/base/lib/utils.ts +13 -0
  166. solokit/templates/fullstack_nextjs/base/lib/validations.ts +20 -0
  167. solokit/templates/fullstack_nextjs/base/next.config.ts +7 -0
  168. solokit/templates/fullstack_nextjs/base/package.json.template +32 -0
  169. solokit/templates/fullstack_nextjs/base/postcss.config.mjs +8 -0
  170. solokit/templates/fullstack_nextjs/base/prisma/schema.prisma +21 -0
  171. solokit/templates/fullstack_nextjs/base/tailwind.config.ts +19 -0
  172. solokit/templates/fullstack_nextjs/base/tsconfig.json +27 -0
  173. solokit/templates/fullstack_nextjs/docker/Dockerfile +60 -0
  174. solokit/templates/fullstack_nextjs/docker/docker-compose.prod.yml +57 -0
  175. solokit/templates/fullstack_nextjs/docker/docker-compose.yml +47 -0
  176. solokit/templates/fullstack_nextjs/tier-1-essential/.eslintrc.json +7 -0
  177. solokit/templates/fullstack_nextjs/tier-1-essential/jest.config.ts +17 -0
  178. solokit/templates/fullstack_nextjs/tier-1-essential/jest.setup.ts +1 -0
  179. solokit/templates/fullstack_nextjs/tier-1-essential/package.json.tier1.template +48 -0
  180. solokit/templates/fullstack_nextjs/tier-1-essential/tests/api/example.test.ts +88 -0
  181. solokit/templates/fullstack_nextjs/tier-1-essential/tests/setup.ts +22 -0
  182. solokit/templates/fullstack_nextjs/tier-1-essential/tests/unit/example.test.tsx +22 -0
  183. solokit/templates/fullstack_nextjs/tier-2-standard/package.json.tier2.template +52 -0
  184. solokit/templates/fullstack_nextjs/tier-3-comprehensive/eslint.config.mjs +39 -0
  185. solokit/templates/fullstack_nextjs/tier-3-comprehensive/package.json.tier3.template +68 -0
  186. solokit/templates/fullstack_nextjs/tier-3-comprehensive/playwright.config.ts +66 -0
  187. solokit/templates/fullstack_nextjs/tier-3-comprehensive/stryker.conf.json +33 -0
  188. solokit/templates/fullstack_nextjs/tier-3-comprehensive/tests/e2e/flow.spec.ts +59 -0
  189. solokit/templates/fullstack_nextjs/tier-3-comprehensive/tests/integration/api.test.ts +165 -0
  190. solokit/templates/fullstack_nextjs/tier-3-comprehensive/type-coverage.json +12 -0
  191. solokit/templates/fullstack_nextjs/tier-4-production/instrumentation.ts +9 -0
  192. solokit/templates/fullstack_nextjs/tier-4-production/k6/load-test.js +45 -0
  193. solokit/templates/fullstack_nextjs/tier-4-production/next.config.ts +46 -0
  194. solokit/templates/fullstack_nextjs/tier-4-production/package.json.tier4.template +77 -0
  195. solokit/templates/fullstack_nextjs/tier-4-production/sentry.client.config.ts +26 -0
  196. solokit/templates/fullstack_nextjs/tier-4-production/sentry.edge.config.ts +11 -0
  197. solokit/templates/fullstack_nextjs/tier-4-production/sentry.server.config.ts +11 -0
  198. solokit/templates/git-hooks/prepare-commit-msg +24 -0
  199. solokit/templates/integration_test_spec.md +363 -0
  200. solokit/templates/learnings.json +15 -0
  201. solokit/templates/ml_ai_fastapi/base/.gitignore +104 -0
  202. solokit/templates/ml_ai_fastapi/base/alembic/env.py +96 -0
  203. solokit/templates/ml_ai_fastapi/base/alembic.ini +114 -0
  204. solokit/templates/ml_ai_fastapi/base/pyproject.toml.template +91 -0
  205. solokit/templates/ml_ai_fastapi/base/requirements.txt.template +28 -0
  206. solokit/templates/ml_ai_fastapi/base/src/__init__.py +5 -0
  207. solokit/templates/ml_ai_fastapi/base/src/api/__init__.py +3 -0
  208. solokit/templates/ml_ai_fastapi/base/src/api/dependencies.py +20 -0
  209. solokit/templates/ml_ai_fastapi/base/src/api/routes/__init__.py +3 -0
  210. solokit/templates/ml_ai_fastapi/base/src/api/routes/example.py +134 -0
  211. solokit/templates/ml_ai_fastapi/base/src/api/routes/health.py +66 -0
  212. solokit/templates/ml_ai_fastapi/base/src/core/__init__.py +3 -0
  213. solokit/templates/ml_ai_fastapi/base/src/core/config.py +64 -0
  214. solokit/templates/ml_ai_fastapi/base/src/core/database.py +50 -0
  215. solokit/templates/ml_ai_fastapi/base/src/main.py +64 -0
  216. solokit/templates/ml_ai_fastapi/base/src/models/__init__.py +7 -0
  217. solokit/templates/ml_ai_fastapi/base/src/models/example.py +61 -0
  218. solokit/templates/ml_ai_fastapi/base/src/services/__init__.py +3 -0
  219. solokit/templates/ml_ai_fastapi/base/src/services/example.py +115 -0
  220. solokit/templates/ml_ai_fastapi/docker/Dockerfile +59 -0
  221. solokit/templates/ml_ai_fastapi/docker/docker-compose.prod.yml +112 -0
  222. solokit/templates/ml_ai_fastapi/docker/docker-compose.yml +77 -0
  223. solokit/templates/ml_ai_fastapi/tier-1-essential/pyproject.toml.tier1.template +112 -0
  224. solokit/templates/ml_ai_fastapi/tier-1-essential/pyrightconfig.json +41 -0
  225. solokit/templates/ml_ai_fastapi/tier-1-essential/pytest.ini +69 -0
  226. solokit/templates/ml_ai_fastapi/tier-1-essential/requirements-dev.txt +17 -0
  227. solokit/templates/ml_ai_fastapi/tier-1-essential/ruff.toml +81 -0
  228. solokit/templates/ml_ai_fastapi/tier-1-essential/tests/__init__.py +3 -0
  229. solokit/templates/ml_ai_fastapi/tier-1-essential/tests/conftest.py +72 -0
  230. solokit/templates/ml_ai_fastapi/tier-1-essential/tests/test_main.py +49 -0
  231. solokit/templates/ml_ai_fastapi/tier-1-essential/tests/unit/__init__.py +3 -0
  232. solokit/templates/ml_ai_fastapi/tier-1-essential/tests/unit/test_example.py +113 -0
  233. solokit/templates/ml_ai_fastapi/tier-2-standard/pyproject.toml.tier2.template +130 -0
  234. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/locustfile.py +99 -0
  235. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/mutmut_config.py +53 -0
  236. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/pyproject.toml.tier3.template +150 -0
  237. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/__init__.py +3 -0
  238. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/conftest.py +74 -0
  239. solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/test_api.py +131 -0
  240. solokit/templates/ml_ai_fastapi/tier-4-production/pyproject.toml.tier4.template +162 -0
  241. solokit/templates/ml_ai_fastapi/tier-4-production/requirements-prod.txt +25 -0
  242. solokit/templates/ml_ai_fastapi/tier-4-production/src/api/routes/metrics.py +19 -0
  243. solokit/templates/ml_ai_fastapi/tier-4-production/src/core/logging.py +74 -0
  244. solokit/templates/ml_ai_fastapi/tier-4-production/src/core/monitoring.py +68 -0
  245. solokit/templates/ml_ai_fastapi/tier-4-production/src/core/sentry.py +66 -0
  246. solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/__init__.py +3 -0
  247. solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/logging.py +79 -0
  248. solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/tracing.py +60 -0
  249. solokit/templates/refactor_spec.md +287 -0
  250. solokit/templates/saas_t3/base/.gitignore +36 -0
  251. solokit/templates/saas_t3/base/app/api/trpc/[trpc]/route.ts +33 -0
  252. solokit/templates/saas_t3/base/app/globals.css +27 -0
  253. solokit/templates/saas_t3/base/app/layout.tsx +23 -0
  254. solokit/templates/saas_t3/base/app/page.tsx +31 -0
  255. solokit/templates/saas_t3/base/lib/api.tsx +77 -0
  256. solokit/templates/saas_t3/base/lib/utils.ts +13 -0
  257. solokit/templates/saas_t3/base/next.config.ts +7 -0
  258. solokit/templates/saas_t3/base/package.json.template +38 -0
  259. solokit/templates/saas_t3/base/postcss.config.mjs +8 -0
  260. solokit/templates/saas_t3/base/prisma/schema.prisma +20 -0
  261. solokit/templates/saas_t3/base/server/api/root.ts +19 -0
  262. solokit/templates/saas_t3/base/server/api/routers/example.ts +28 -0
  263. solokit/templates/saas_t3/base/server/api/trpc.ts +52 -0
  264. solokit/templates/saas_t3/base/server/db.ts +17 -0
  265. solokit/templates/saas_t3/base/tailwind.config.ts +19 -0
  266. solokit/templates/saas_t3/base/tsconfig.json +27 -0
  267. solokit/templates/saas_t3/docker/Dockerfile +60 -0
  268. solokit/templates/saas_t3/docker/docker-compose.prod.yml +59 -0
  269. solokit/templates/saas_t3/docker/docker-compose.yml +49 -0
  270. solokit/templates/saas_t3/tier-1-essential/.eslintrc.json +7 -0
  271. solokit/templates/saas_t3/tier-1-essential/jest.config.ts +17 -0
  272. solokit/templates/saas_t3/tier-1-essential/jest.setup.ts +1 -0
  273. solokit/templates/saas_t3/tier-1-essential/package.json.tier1.template +54 -0
  274. solokit/templates/saas_t3/tier-1-essential/tests/setup.ts +22 -0
  275. solokit/templates/saas_t3/tier-1-essential/tests/unit/example.test.tsx +24 -0
  276. solokit/templates/saas_t3/tier-2-standard/package.json.tier2.template +58 -0
  277. solokit/templates/saas_t3/tier-3-comprehensive/eslint.config.mjs +39 -0
  278. solokit/templates/saas_t3/tier-3-comprehensive/package.json.tier3.template +74 -0
  279. solokit/templates/saas_t3/tier-3-comprehensive/playwright.config.ts +66 -0
  280. solokit/templates/saas_t3/tier-3-comprehensive/stryker.conf.json +34 -0
  281. solokit/templates/saas_t3/tier-3-comprehensive/tests/e2e/home.spec.ts +41 -0
  282. solokit/templates/saas_t3/tier-3-comprehensive/tests/integration/api.test.ts +44 -0
  283. solokit/templates/saas_t3/tier-3-comprehensive/type-coverage.json +12 -0
  284. solokit/templates/saas_t3/tier-4-production/instrumentation.ts +9 -0
  285. solokit/templates/saas_t3/tier-4-production/k6/load-test.js +51 -0
  286. solokit/templates/saas_t3/tier-4-production/next.config.ts +46 -0
  287. solokit/templates/saas_t3/tier-4-production/package.json.tier4.template +83 -0
  288. solokit/templates/saas_t3/tier-4-production/sentry.client.config.ts +26 -0
  289. solokit/templates/saas_t3/tier-4-production/sentry.edge.config.ts +11 -0
  290. solokit/templates/saas_t3/tier-4-production/sentry.server.config.ts +11 -0
  291. solokit/templates/saas_t3/tier-4-production/vercel.json +37 -0
  292. solokit/templates/security_spec.md +287 -0
  293. solokit/templates/stack-versions.yaml +617 -0
  294. solokit/templates/status_update.json +6 -0
  295. solokit/templates/template-registry.json +257 -0
  296. solokit/templates/work_items.json +11 -0
  297. solokit/testing/__init__.py +1 -0
  298. solokit/testing/integration_runner.py +550 -0
  299. solokit/testing/performance.py +637 -0
  300. solokit/visualization/__init__.py +1 -0
  301. solokit/visualization/dependency_graph.py +788 -0
  302. solokit/work_items/__init__.py +1 -0
  303. solokit/work_items/creator.py +217 -0
  304. solokit/work_items/delete.py +264 -0
  305. solokit/work_items/get_dependencies.py +185 -0
  306. solokit/work_items/get_dependents.py +113 -0
  307. solokit/work_items/get_metadata.py +121 -0
  308. solokit/work_items/get_next_recommendations.py +133 -0
  309. solokit/work_items/manager.py +235 -0
  310. solokit/work_items/milestones.py +137 -0
  311. solokit/work_items/query.py +376 -0
  312. solokit/work_items/repository.py +267 -0
  313. solokit/work_items/scheduler.py +184 -0
  314. solokit/work_items/spec_parser.py +838 -0
  315. solokit/work_items/spec_validator.py +493 -0
  316. solokit/work_items/updater.py +157 -0
  317. solokit/work_items/validator.py +205 -0
  318. solokit-0.1.1.dist-info/METADATA +640 -0
  319. solokit-0.1.1.dist-info/RECORD +323 -0
  320. solokit-0.1.1.dist-info/WHEEL +5 -0
  321. solokit-0.1.1.dist-info/entry_points.txt +2 -0
  322. solokit-0.1.1.dist-info/licenses/LICENSE +21 -0
  323. solokit-0.1.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Console reporter for quality gate results.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Any
9
+
10
+ from solokit.quality.reporters.base import Reporter
11
+
12
+
13
+ class ConsoleReporter(Reporter):
14
+ """Generates human-readable console reports."""
15
+
16
+ def generate(self, aggregated_results: dict[str, Any]) -> str:
17
+ """Generate a console-friendly report.
18
+
19
+ Args:
20
+ aggregated_results: Aggregated results from ResultAggregator
21
+
22
+ Returns:
23
+ Formatted console report
24
+ """
25
+ report = []
26
+ report.append("=" * 60)
27
+ report.append("QUALITY GATE RESULTS")
28
+ report.append("=" * 60)
29
+
30
+ # Overall summary
31
+ if aggregated_results["overall_passed"]:
32
+ report.append("\n✓ ALL CHECKS PASSED")
33
+ else:
34
+ report.append("\n✗ SOME CHECKS FAILED")
35
+
36
+ report.append(f"\nTotal Checks: {aggregated_results['total_checks']}")
37
+ report.append(f"Passed: {aggregated_results['passed_checks']}")
38
+ report.append(f"Failed: {aggregated_results['failed_checks']}")
39
+ report.append(f"Skipped: {aggregated_results['skipped_checks']}")
40
+ report.append(f"Execution Time: {aggregated_results['total_execution_time']:.2f}s")
41
+
42
+ # Individual checker results
43
+ report.append("\n" + "-" * 60)
44
+ report.append("INDIVIDUAL CHECKER RESULTS")
45
+ report.append("-" * 60)
46
+
47
+ for checker_name, result in aggregated_results["by_checker"].items():
48
+ status = result["status"]
49
+ if status == "passed":
50
+ status_symbol = "✓"
51
+ elif status == "skipped":
52
+ status_symbol = "⊘"
53
+ else:
54
+ status_symbol = "✗"
55
+
56
+ report.append(f"\n{status_symbol} {checker_name.upper()}: {status.upper()}")
57
+
58
+ # Add execution time
59
+ if result.get("execution_time", 0) > 0:
60
+ report.append(f" Execution time: {result['execution_time']:.2f}s")
61
+
62
+ # Show errors
63
+ if result.get("errors"):
64
+ report.append(" Errors:")
65
+ for error in result["errors"][:5]: # Limit to first 5
66
+ if isinstance(error, dict):
67
+ error_msg = error.get("message", str(error))
68
+ else:
69
+ error_msg = str(error)
70
+ report.append(f" - {error_msg}")
71
+ if len(result["errors"]) > 5:
72
+ report.append(f" ... and {len(result['errors']) - 5} more")
73
+
74
+ # Show warnings
75
+ if result.get("warnings"):
76
+ report.append(" Warnings:")
77
+ for warning in result["warnings"][:3]: # Limit to first 3
78
+ if isinstance(warning, dict):
79
+ warning_msg = warning.get("message", str(warning))
80
+ else:
81
+ warning_msg = str(warning)
82
+ report.append(f" - {warning_msg}")
83
+ if len(result["warnings"]) > 3:
84
+ report.append(f" ... and {len(result['warnings']) - 3} more")
85
+
86
+ # Show key info
87
+ if result.get("info"):
88
+ info = result["info"]
89
+ # Show coverage if present
90
+ if "coverage" in info:
91
+ report.append(f" Coverage: {info['coverage']}%")
92
+ # Show reason for skipped
93
+ if "reason" in info and status == "skipped":
94
+ report.append(f" Reason: {info['reason']}")
95
+
96
+ report.append("\n" + "=" * 60)
97
+
98
+ return "\n".join(report)
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ JSON reporter for quality gate results.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ from typing import Any
10
+
11
+ from solokit.quality.reporters.base import Reporter
12
+
13
+
14
+ class JSONReporter(Reporter):
15
+ """Generates JSON-formatted reports."""
16
+
17
+ def __init__(self, indent: int = 2):
18
+ """Initialize the JSON reporter.
19
+
20
+ Args:
21
+ indent: Number of spaces for JSON indentation (default: 2)
22
+ """
23
+ self.indent = indent
24
+
25
+ def generate(self, aggregated_results: dict[str, Any]) -> str:
26
+ """Generate a JSON report.
27
+
28
+ Args:
29
+ aggregated_results: Aggregated results from ResultAggregator
30
+
31
+ Returns:
32
+ JSON-formatted report string
33
+ """
34
+ return json.dumps(aggregated_results, indent=self.indent)
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Result aggregation for quality gates.
4
+
5
+ Combines results from multiple checkers into a comprehensive report.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+
12
+ from solokit.quality.checkers.base import CheckResult
13
+
14
+
15
+ class ResultAggregator:
16
+ """Aggregates results from multiple quality checkers."""
17
+
18
+ def aggregate(self, results: list[CheckResult]) -> dict[str, Any]:
19
+ """Aggregate multiple check results into a summary.
20
+
21
+ Args:
22
+ results: List of CheckResult objects from various checkers
23
+
24
+ Returns:
25
+ Dictionary containing aggregated results with:
26
+ - overall_passed: Whether all checks passed
27
+ - total_checks: Number of checks run
28
+ - passed_checks: Number of checks that passed
29
+ - failed_checks: Number of checks that failed
30
+ - skipped_checks: Number of checks that were skipped
31
+ - by_checker: Results organized by checker name
32
+ - failed_checkers: List of checker names that failed
33
+ """
34
+ aggregated: dict[str, Any] = {
35
+ "overall_passed": True,
36
+ "total_checks": len(results),
37
+ "passed_checks": 0,
38
+ "failed_checks": 0,
39
+ "skipped_checks": 0,
40
+ "by_checker": {},
41
+ "failed_checkers": [],
42
+ "total_execution_time": 0.0,
43
+ }
44
+
45
+ for result in results:
46
+ # Add to by_checker mapping
47
+ aggregated["by_checker"][result.checker_name] = {
48
+ "passed": result.passed,
49
+ "status": result.status,
50
+ "errors": result.errors,
51
+ "warnings": result.warnings,
52
+ "info": result.info,
53
+ "execution_time": result.execution_time,
54
+ }
55
+
56
+ # Update counters
57
+ if result.status == "skipped":
58
+ aggregated["skipped_checks"] += 1
59
+ elif result.passed:
60
+ aggregated["passed_checks"] += 1
61
+ else:
62
+ aggregated["failed_checks"] += 1
63
+ aggregated["overall_passed"] = False
64
+ aggregated["failed_checkers"].append(result.checker_name)
65
+
66
+ # Add execution time
67
+ aggregated["total_execution_time"] += result.execution_time
68
+
69
+ return aggregated
70
+
71
+ def get_summary_text(self, aggregated: dict[str, Any]) -> str:
72
+ """Generate a text summary of aggregated results.
73
+
74
+ Args:
75
+ aggregated: Aggregated results dictionary
76
+
77
+ Returns:
78
+ Human-readable summary string
79
+ """
80
+ total = aggregated["total_checks"]
81
+ passed = aggregated["passed_checks"]
82
+ failed = aggregated["failed_checks"]
83
+ skipped = aggregated["skipped_checks"]
84
+ exec_time = aggregated["total_execution_time"]
85
+
86
+ summary = []
87
+ summary.append(f"Total Checks: {total}")
88
+ summary.append(f"Passed: {passed}")
89
+ summary.append(f"Failed: {failed}")
90
+ summary.append(f"Skipped: {skipped}")
91
+ summary.append(f"Execution Time: {exec_time:.2f}s")
92
+
93
+ if aggregated["overall_passed"]:
94
+ summary.append("\n✓ All quality checks passed")
95
+ else:
96
+ summary.append(f"\n✗ Quality checks failed: {', '.join(aggregated['failed_checkers'])}")
97
+
98
+ return "\n".join(summary)
@@ -0,0 +1 @@
1
+ """Session management for Solokit workflow."""
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Session briefing package.
4
+
5
+ This package provides modular components for generating comprehensive session briefings.
6
+ The package is organized into focused, single-responsibility modules.
7
+
8
+ Public API exports maintain backward compatibility with the original briefing.py module.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import sys
14
+ from pathlib import Path
15
+ from typing import Any
16
+
17
+ from solokit.core.logging_config import get_logger
18
+
19
+ from .documentation_loader import DocumentationLoader
20
+ from .formatter import BriefingFormatter
21
+ from .git_context import GitContext
22
+ from .learning_loader import LearningLoader
23
+ from .milestone_builder import MilestoneBuilder
24
+ from .orchestrator import SessionBriefing
25
+ from .stack_detector import StackDetector
26
+ from .tree_generator import TreeGenerator
27
+ from .work_item_loader import WorkItemLoader
28
+
29
+ # Package-level logger for backward compatibility
30
+ logger = get_logger(__name__)
31
+
32
+ # Get the parent module (solokit.session)
33
+ _parent_module_path = Path(__file__).parent.parent
34
+ if str(_parent_module_path) not in sys.path:
35
+ sys.path.insert(0, str(_parent_module_path))
36
+
37
+
38
+ # Import main from the briefing.py module (not package)
39
+ # This is a bit tricky since briefing is now a package, but main() is in briefing.py
40
+ # We need to import the actual module file, not the package
41
+ def main() -> int:
42
+ """Main entry point - delegates to briefing.py main()."""
43
+ # Import the briefing module file (not the package) using importlib
44
+ import importlib.util
45
+ import sys
46
+ from pathlib import Path
47
+
48
+ # Get the path to briefing.py (the module file, not the package)
49
+ module_path = Path(__file__).parent.parent / "briefing.py"
50
+
51
+ # Load the module directly from the file
52
+ spec = importlib.util.spec_from_file_location("solokit.session._briefing_module", module_path)
53
+ if spec is None or spec.loader is None:
54
+ raise ImportError(f"Could not load briefing module from {module_path}")
55
+ briefing_module = importlib.util.module_from_spec(spec)
56
+ sys.modules["solokit.session._briefing_module"] = briefing_module
57
+ spec.loader.exec_module(briefing_module)
58
+
59
+ # Call the main function from the loaded module
60
+ return briefing_module.main() # type: ignore[no-any-return]
61
+
62
+
63
+ # Export commonly used functions for backward compatibility
64
+ # These maintain the original module-level function API
65
+
66
+ __all__ = [
67
+ # Classes
68
+ "SessionBriefing",
69
+ "WorkItemLoader",
70
+ "LearningLoader",
71
+ "DocumentationLoader",
72
+ "StackDetector",
73
+ "TreeGenerator",
74
+ "GitContext",
75
+ "MilestoneBuilder",
76
+ "BriefingFormatter",
77
+ # Functions (for backward compatibility with old code that imports functions)
78
+ "load_work_items",
79
+ "load_learnings",
80
+ "get_next_work_item",
81
+ "get_relevant_learnings",
82
+ "load_milestone_context",
83
+ "load_project_docs",
84
+ "load_current_stack",
85
+ "load_current_tree",
86
+ "load_work_item_spec",
87
+ "shift_heading_levels",
88
+ "extract_section",
89
+ "generate_previous_work_section",
90
+ "extract_keywords",
91
+ "calculate_days_ago",
92
+ "validate_environment",
93
+ "check_git_status",
94
+ "generate_briefing",
95
+ "check_command_exists",
96
+ "generate_integration_test_briefing",
97
+ "generate_deployment_briefing",
98
+ "determine_git_branch_final_status",
99
+ "finalize_previous_work_item_git_status",
100
+ "main", # Add main to exports
101
+ ]
102
+
103
+
104
+ # Backward compatibility: Module-level function wrappers
105
+
106
+
107
+ def load_work_items() -> dict[str, Any]:
108
+ """Load work items from tracking file (backward compatibility wrapper)."""
109
+ from pathlib import Path
110
+
111
+ work_items_file = Path(".session/tracking/work_items.json")
112
+ logger.debug("Loading work items from: %s", work_items_file)
113
+
114
+ loader = WorkItemLoader()
115
+ return loader.load_work_items()
116
+
117
+
118
+ def load_learnings() -> dict[str, Any]:
119
+ """Load learnings from tracking file (backward compatibility wrapper)."""
120
+ loader = LearningLoader()
121
+ return loader.load_learnings()
122
+
123
+
124
+ def get_next_work_item(work_items_data: dict) -> tuple[str | None, dict | None]:
125
+ """Find next available work item (backward compatibility wrapper)."""
126
+ loader = WorkItemLoader()
127
+ return loader.get_next_work_item(work_items_data)
128
+
129
+
130
+ def get_relevant_learnings(
131
+ learnings_data: dict, work_item: dict, spec_content: str = ""
132
+ ) -> list[dict]:
133
+ """Get relevant learnings (backward compatibility wrapper)."""
134
+ loader = LearningLoader()
135
+ return loader.get_relevant_learnings(learnings_data, work_item, spec_content)
136
+
137
+
138
+ def load_milestone_context(work_item: dict) -> dict | None:
139
+ """Load milestone context (backward compatibility wrapper)."""
140
+ builder = MilestoneBuilder()
141
+ return builder.load_milestone_context(work_item)
142
+
143
+
144
+ def load_project_docs() -> dict[str, str]:
145
+ """Load project documentation (backward compatibility wrapper)."""
146
+ loader = DocumentationLoader()
147
+ return loader.load_project_docs()
148
+
149
+
150
+ def load_current_stack() -> str:
151
+ """Load current technology stack (backward compatibility wrapper)."""
152
+ detector = StackDetector()
153
+ return detector.load_current_stack()
154
+
155
+
156
+ def load_current_tree() -> str:
157
+ """Load current project structure (backward compatibility wrapper)."""
158
+ generator = TreeGenerator()
159
+ return generator.load_current_tree()
160
+
161
+
162
+ def load_work_item_spec(work_item: str | dict[str, Any]) -> str:
163
+ """Load work item specification file (backward compatibility wrapper)."""
164
+ loader = WorkItemLoader()
165
+ return loader.load_work_item_spec(work_item)
166
+
167
+
168
+ def shift_heading_levels(markdown_content: str, shift: int) -> str:
169
+ """Shift markdown heading levels (backward compatibility wrapper)."""
170
+ formatter = BriefingFormatter()
171
+ return formatter.shift_heading_levels(markdown_content, shift)
172
+
173
+
174
+ def extract_section(markdown: str, heading: str) -> str:
175
+ """Extract section from markdown (backward compatibility wrapper)."""
176
+ formatter = BriefingFormatter()
177
+ return formatter.extract_section(markdown, heading)
178
+
179
+
180
+ def generate_previous_work_section(item_id: str, item: dict) -> str:
181
+ """Generate previous work context (backward compatibility wrapper)."""
182
+ formatter = BriefingFormatter()
183
+ return formatter.generate_previous_work_section(item_id, item)
184
+
185
+
186
+ def extract_keywords(text: str) -> set[str]:
187
+ """Extract meaningful keywords from text (backward compatibility wrapper)."""
188
+ loader = LearningLoader()
189
+ return loader._extract_keywords(text)
190
+
191
+
192
+ def calculate_days_ago(timestamp: str) -> int:
193
+ """Calculate days since timestamp (backward compatibility wrapper)."""
194
+ loader = LearningLoader()
195
+ return loader._calculate_days_ago(timestamp)
196
+
197
+
198
+ def validate_environment() -> list[str]:
199
+ """Validate development environment (backward compatibility wrapper)."""
200
+ formatter = BriefingFormatter()
201
+ return formatter.validate_environment()
202
+
203
+
204
+ def check_git_status() -> dict[str, Any]:
205
+ """Check git status for session start (backward compatibility wrapper)."""
206
+ context = GitContext()
207
+ return context.check_git_status()
208
+
209
+
210
+ def generate_briefing(item_id: str, item: dict, learnings_data: dict) -> str:
211
+ """Generate comprehensive markdown briefing (backward compatibility wrapper)."""
212
+ briefing = SessionBriefing()
213
+ return briefing.generate_briefing(item_id, item, learnings_data)
214
+
215
+
216
+ def check_command_exists(command: str) -> bool:
217
+ """Check if a command is available (backward compatibility wrapper)."""
218
+ formatter = BriefingFormatter()
219
+ return formatter.check_command_exists(command)
220
+
221
+
222
+ def generate_integration_test_briefing(work_item: dict) -> str:
223
+ """Generate integration test briefing (backward compatibility wrapper)."""
224
+ formatter = BriefingFormatter()
225
+ return formatter.generate_integration_test_briefing(work_item)
226
+
227
+
228
+ def generate_deployment_briefing(work_item: dict) -> str:
229
+ """Generate deployment briefing (backward compatibility wrapper)."""
230
+ formatter = BriefingFormatter()
231
+ return formatter.generate_deployment_briefing(work_item)
232
+
233
+
234
+ def determine_git_branch_final_status(branch_name: str, git_info: dict) -> str:
235
+ """Determine final git branch status (backward compatibility wrapper)."""
236
+ context = GitContext()
237
+ return context.determine_git_branch_final_status(branch_name, git_info)
238
+
239
+
240
+ def finalize_previous_work_item_git_status(
241
+ work_items_data: dict, current_work_item_id: str
242
+ ) -> str | None:
243
+ """Finalize git status for previous work item (backward compatibility wrapper)."""
244
+ context = GitContext()
245
+ return context.finalize_previous_work_item_git_status(work_items_data, current_work_item_id)
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Documentation discovery and loading.
4
+ Part of the briefing module decomposition.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+
11
+ from solokit.core.exceptions import FileOperationError
12
+ from solokit.core.logging_config import get_logger
13
+
14
+ logger = get_logger(__name__)
15
+
16
+
17
+ class DocumentationLoader:
18
+ """Load project documentation for context."""
19
+
20
+ def __init__(self, project_root: Path | None = None):
21
+ """Initialize documentation loader.
22
+
23
+ Args:
24
+ project_root: Path to project root (defaults to current directory)
25
+ """
26
+ self.project_root = project_root or Path.cwd()
27
+
28
+ def load_project_docs(self) -> dict[str, str]:
29
+ """Load project documentation for context.
30
+
31
+ Returns:
32
+ Dictionary mapping doc filename to content
33
+ """
34
+ docs = {}
35
+
36
+ # Look for common doc files
37
+ doc_files = ["docs/vision.md", "docs/prd.md", "docs/architecture.md", "README.md"]
38
+
39
+ for doc_file in doc_files:
40
+ path = self.project_root / doc_file
41
+ if path.exists():
42
+ try:
43
+ docs[path.name] = path.read_text()
44
+ logger.debug("Loaded documentation: %s", doc_file)
45
+ except (OSError, UnicodeDecodeError) as e:
46
+ raise FileOperationError(
47
+ operation="read",
48
+ file_path=str(path),
49
+ details=f"Failed to read documentation file: {e}",
50
+ cause=e,
51
+ ) from e
52
+
53
+ return docs