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,221 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Context7 library verification checker.
4
+
5
+ Verifies important libraries via Context7 MCP integration by parsing
6
+ libraries from stack.txt and querying Context7 for security and version status.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import time
12
+ from pathlib import Path
13
+ from typing import Any, Union, cast
14
+
15
+ from solokit.core.command_runner import CommandRunner
16
+ from solokit.core.constants import QUALITY_CHECK_LONG_TIMEOUT
17
+ from solokit.core.exceptions import FileOperationError
18
+ from solokit.core.logging_config import get_logger
19
+ from solokit.quality.checkers.base import CheckResult, QualityChecker
20
+
21
+ logger = get_logger(__name__)
22
+
23
+
24
+ class Context7Checker(QualityChecker):
25
+ """Context7 library verification for important dependencies."""
26
+
27
+ def __init__(
28
+ self,
29
+ config: dict[str, Any],
30
+ project_root: Path | None = None,
31
+ runner: CommandRunner | None = None,
32
+ ):
33
+ """Initialize Context7 checker.
34
+
35
+ Args:
36
+ config: Context7 configuration
37
+ project_root: Project root directory
38
+ runner: Optional CommandRunner instance (for testing)
39
+ """
40
+ super().__init__(config, project_root)
41
+ self.runner = (
42
+ runner
43
+ if runner is not None
44
+ else CommandRunner(default_timeout=QUALITY_CHECK_LONG_TIMEOUT)
45
+ )
46
+
47
+ def name(self) -> str:
48
+ """Return checker name."""
49
+ return "context7"
50
+
51
+ def is_enabled(self) -> bool:
52
+ """Check if Context7 verification is enabled."""
53
+ return bool(self.config.get("enabled", False))
54
+
55
+ def run(self) -> CheckResult:
56
+ """Run Context7 library verification."""
57
+ start_time = time.time()
58
+
59
+ if not self.is_enabled():
60
+ return self._create_skipped_result(reason="not enabled")
61
+
62
+ # Get stack.txt path (relative to project root or .session/tracking)
63
+ stack_file = self.project_root / ".session" / "tracking" / "stack.txt"
64
+ if not stack_file.exists():
65
+ return self._create_skipped_result(reason="no stack.txt")
66
+
67
+ logger.info("Running Context7 library verification")
68
+
69
+ # Parse libraries from stack.txt
70
+ try:
71
+ libraries = self._parse_libraries_from_stack(stack_file)
72
+ except FileOperationError as e:
73
+ execution_time = time.time() - start_time
74
+ return CheckResult(
75
+ checker_name=self.name(),
76
+ passed=False,
77
+ status="failed",
78
+ errors=[{"message": f"Failed to read stack.txt: {e}"}],
79
+ warnings=[],
80
+ info={"reason": "stack file read error"},
81
+ execution_time=execution_time,
82
+ )
83
+
84
+ # Verify libraries
85
+ results: dict[str, Any] = {"libraries": [], "verified": 0, "failed": 0}
86
+
87
+ for lib in libraries:
88
+ # Check if library should be verified
89
+ if not self._should_verify_library(lib):
90
+ continue
91
+
92
+ # Query Context7 MCP
93
+ verified = self._query_context7(lib)
94
+
95
+ results["libraries"].append(
96
+ {
97
+ "name": lib["name"],
98
+ "version": lib.get("version", "unknown"),
99
+ "verified": verified,
100
+ }
101
+ )
102
+
103
+ if verified:
104
+ results["verified"] += 1
105
+ else:
106
+ results["failed"] += 1
107
+
108
+ passed = results["failed"] == 0
109
+ execution_time = time.time() - start_time
110
+
111
+ errors = []
112
+ if not passed:
113
+ for lib in results["libraries"]:
114
+ if not lib["verified"]:
115
+ errors.append(
116
+ {
117
+ "message": f"Library verification failed: {lib['name']} {lib['version']}",
118
+ "library": lib["name"],
119
+ "version": lib["version"],
120
+ }
121
+ )
122
+
123
+ return CheckResult(
124
+ checker_name=self.name(),
125
+ passed=passed,
126
+ status="passed" if passed else "failed",
127
+ errors=cast(list[Union[dict[str, Any], str]], errors),
128
+ warnings=[],
129
+ info={
130
+ "total_libraries": len(results["libraries"]),
131
+ "verified": results["verified"],
132
+ "failed": results["failed"],
133
+ "libraries": results["libraries"],
134
+ },
135
+ execution_time=execution_time,
136
+ )
137
+
138
+ def _parse_libraries_from_stack(self, stack_file: Path) -> list[dict[str, str]]:
139
+ """
140
+ Parse libraries from stack.txt.
141
+
142
+ Args:
143
+ stack_file: Path to stack.txt file
144
+
145
+ Returns:
146
+ List of library dictionaries with 'name' and 'version' keys
147
+
148
+ Raises:
149
+ FileOperationError: If stack file cannot be read
150
+ """
151
+ libraries = []
152
+
153
+ try:
154
+ with open(stack_file) as f:
155
+ content = f.read()
156
+
157
+ # Parse libraries - expecting format like "Python 3.x" or "pytest (testing)"
158
+ lines = content.split("\n")
159
+ for line in lines:
160
+ line = line.strip()
161
+ if not line or line.startswith("#"):
162
+ continue
163
+
164
+ # Extract library name and version
165
+ parts = line.split()
166
+ if len(parts) >= 1:
167
+ name = parts[0]
168
+ version = parts[1] if len(parts) > 1 else "unknown"
169
+ libraries.append({"name": name, "version": version})
170
+
171
+ except OSError as e:
172
+ raise FileOperationError(
173
+ operation="read",
174
+ file_path=str(stack_file),
175
+ details="Failed to read stack.txt file",
176
+ cause=e,
177
+ ) from e
178
+
179
+ return libraries
180
+
181
+ def _should_verify_library(self, lib: dict[str, str]) -> bool:
182
+ """Check if library should be verified via Context7.
183
+
184
+ Args:
185
+ lib: Library dictionary with 'name' and 'version' keys
186
+
187
+ Returns:
188
+ True if library should be verified, False otherwise
189
+ """
190
+ # Check if library is in important list (if configured)
191
+ important_libs = self.config.get("important_libraries", [])
192
+ if important_libs:
193
+ return lib["name"] in important_libs
194
+
195
+ # By default, verify all libraries
196
+ return True
197
+
198
+ def _query_context7(self, lib: dict[str, str]) -> bool:
199
+ """Query Context7 MCP for library verification (stub).
200
+
201
+ Args:
202
+ lib: Library dictionary with 'name' and 'version' keys
203
+
204
+ Returns:
205
+ True if library is current/secure, False otherwise
206
+
207
+ Note:
208
+ This is currently a stub implementation. When fully implemented, this should:
209
+ 1. Connect to Context7 MCP server
210
+ 2. Query library version and security status
211
+ 3. Return True if library is current/secure, False otherwise
212
+
213
+ Returns True by default to allow framework operation.
214
+ """
215
+ # NOTE: Future integration - Context7 MCP for library verification
216
+ # When implemented, this should:
217
+ # 1. Connect to Context7 MCP server
218
+ # 2. Query library version and security status
219
+ # 3. Return True if library is current/secure, False otherwise
220
+ # Returns True by default to allow framework operation
221
+ return True
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Custom validation checker.
4
+
5
+ Runs user-defined validation rules.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import time
11
+ from pathlib import Path
12
+ from typing import Any, Union, cast
13
+
14
+ from solokit.core.command_runner import CommandRunner
15
+ from solokit.core.constants import QUALITY_CHECK_LONG_TIMEOUT, QUALITY_CHECK_STANDARD_TIMEOUT
16
+ from solokit.core.logging_config import get_logger
17
+ from solokit.quality.checkers.base import CheckResult, QualityChecker
18
+
19
+ logger = get_logger(__name__)
20
+
21
+
22
+ class CustomValidationChecker(QualityChecker):
23
+ """Custom validation rules execution."""
24
+
25
+ def __init__(
26
+ self,
27
+ config: dict[str, Any],
28
+ project_root: Path | None = None,
29
+ work_item: dict[str, Any] | None = None,
30
+ runner: CommandRunner | None = None,
31
+ ):
32
+ """Initialize custom validation checker.
33
+
34
+ Args:
35
+ config: Custom validations configuration
36
+ project_root: Project root directory
37
+ work_item: Work item dictionary (for work-item-specific rules)
38
+ runner: Optional CommandRunner instance (for testing)
39
+ """
40
+ super().__init__(config, project_root)
41
+ self.runner = (
42
+ runner
43
+ if runner is not None
44
+ else CommandRunner(default_timeout=QUALITY_CHECK_LONG_TIMEOUT)
45
+ )
46
+ self.work_item = work_item or {}
47
+
48
+ def name(self) -> str:
49
+ """Return checker name."""
50
+ return "custom_validations"
51
+
52
+ def is_enabled(self) -> bool:
53
+ """Check if custom validations are enabled."""
54
+ # Custom validations are enabled if there are any rules defined
55
+ work_item_rules = self.work_item.get("validation_rules", [])
56
+ project_rules = self.config.get("rules", [])
57
+ return len(work_item_rules) > 0 or len(project_rules) > 0
58
+
59
+ def run(self) -> CheckResult:
60
+ """Run custom validation rules."""
61
+ start_time = time.time()
62
+
63
+ # Get rules from both work item and project config
64
+ work_item_rules = self.work_item.get("validation_rules", [])
65
+ project_rules = self.config.get("rules", [])
66
+ all_rules = work_item_rules + project_rules
67
+
68
+ if not all_rules:
69
+ return self._create_skipped_result(reason="no custom rules defined")
70
+
71
+ logger.info(f"Running {len(all_rules)} custom validation rules")
72
+
73
+ validations = []
74
+ passed = True
75
+
76
+ for rule in all_rules:
77
+ rule_type = rule.get("type")
78
+ required = rule.get("required", False)
79
+
80
+ # Execute rule based on type
81
+ if rule_type == "command":
82
+ rule_passed = self._run_command_validation(rule)
83
+ elif rule_type == "file_exists":
84
+ rule_passed = self._check_file_exists(rule)
85
+ elif rule_type == "grep":
86
+ rule_passed = self._run_grep_validation(rule)
87
+ else:
88
+ logger.warning(f"Unknown validation rule type: {rule_type}")
89
+ rule_passed = True
90
+
91
+ validations.append(
92
+ {
93
+ "name": rule.get("name", "unknown"),
94
+ "passed": rule_passed,
95
+ "required": required,
96
+ "type": rule_type,
97
+ }
98
+ )
99
+
100
+ if not rule_passed and required:
101
+ passed = False
102
+
103
+ execution_time = time.time() - start_time
104
+
105
+ errors = []
106
+ for validation in validations:
107
+ if not validation["passed"] and validation["required"]:
108
+ errors.append({"message": f"Required validation failed: {validation['name']}"})
109
+
110
+ warnings = []
111
+ for validation in validations:
112
+ if not validation["passed"] and not validation["required"]:
113
+ warnings.append({"message": f"Optional validation failed: {validation['name']}"})
114
+
115
+ return CheckResult(
116
+ checker_name=self.name(),
117
+ passed=passed,
118
+ status="passed" if passed else "failed",
119
+ errors=cast(list[Union[dict[str, Any], str]], errors),
120
+ warnings=cast(list[Union[dict[str, Any], str]], warnings),
121
+ info={"validations": validations},
122
+ execution_time=execution_time,
123
+ )
124
+
125
+ def _run_command_validation(self, rule: dict[str, Any]) -> bool:
126
+ """Run command validation rule."""
127
+ command = rule.get("command")
128
+ if not command:
129
+ logger.warning("Command validation missing 'command' field")
130
+ return True
131
+
132
+ logger.debug(f"Running command validation: {command}")
133
+ result = self.runner.run(command.split(), timeout=QUALITY_CHECK_LONG_TIMEOUT)
134
+ return result.success
135
+
136
+ def _check_file_exists(self, rule: dict[str, Any]) -> bool:
137
+ """Check if file exists at path."""
138
+ file_path = rule.get("path")
139
+ if not file_path:
140
+ logger.warning("File exists validation missing 'path' field")
141
+ return True
142
+
143
+ path = self.project_root / file_path
144
+ exists = path.exists()
145
+ logger.debug(f"Checking file exists: {file_path} -> {exists}")
146
+ return bool(exists)
147
+
148
+ def _run_grep_validation(self, rule: dict[str, Any]) -> bool:
149
+ """Run grep validation rule."""
150
+ pattern = rule.get("pattern")
151
+ files = rule.get("files", ".")
152
+
153
+ if not pattern:
154
+ logger.warning("Grep validation missing 'pattern' field")
155
+ return True
156
+
157
+ logger.debug(f"Running grep validation: pattern={pattern}, files={files}")
158
+ result = self.runner.run(
159
+ ["grep", "-r", pattern, files], timeout=QUALITY_CHECK_STANDARD_TIMEOUT
160
+ )
161
+ # grep returns 0 if pattern found
162
+ return result.success