igel-qe-core 1.0.3 → 1.0.7

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 (628) hide show
  1. package/dist/cli/index.js +638 -54
  2. package/dist/cli/platform.js +115 -72
  3. package/dist/mcp/server.js +258 -17
  4. package/package.json +4 -4
  5. package/src/__pycache__/__init__.cpython-311.pyc +0 -0
  6. package/src/__pycache__/__init__.cpython-313.pyc +0 -0
  7. package/src/__pycache__/__init__.cpython-314.pyc +0 -0
  8. package/src/agents/__init__.py +3 -0
  9. package/src/agents/__pycache__/__init__.cpython-311.pyc +0 -0
  10. package/src/agents/__pycache__/__init__.cpython-313.pyc +0 -0
  11. package/src/agents/__pycache__/__init__.cpython-314.pyc +0 -0
  12. package/src/agents/__pycache__/automation_design_agent.cpython-311.pyc +0 -0
  13. package/src/agents/__pycache__/automation_design_agent.cpython-313.pyc +0 -0
  14. package/src/agents/__pycache__/automation_design_agent.cpython-314.pyc +0 -0
  15. package/src/agents/__pycache__/code_intelligence_agent.cpython-311.pyc +0 -0
  16. package/src/agents/__pycache__/code_intelligence_agent.cpython-313.pyc +0 -0
  17. package/src/agents/__pycache__/confidence_agent.cpython-311.pyc +0 -0
  18. package/src/agents/__pycache__/confidence_agent.cpython-313.pyc +0 -0
  19. package/src/agents/__pycache__/confidence_agent.cpython-314.pyc +0 -0
  20. package/src/agents/__pycache__/execution_validation_agent.cpython-311.pyc +0 -0
  21. package/src/agents/__pycache__/execution_validation_agent.cpython-313.pyc +0 -0
  22. package/src/agents/__pycache__/execution_validation_agent.cpython-314.pyc +0 -0
  23. package/src/agents/__pycache__/framework_analyzer_agent.cpython-311.pyc +0 -0
  24. package/src/agents/__pycache__/framework_analyzer_agent.cpython-313.pyc +0 -0
  25. package/src/agents/__pycache__/fusion_agent.cpython-314.pyc +0 -0
  26. package/src/agents/__pycache__/graph.cpython-314.pyc +0 -0
  27. package/src/agents/__pycache__/intent_agent.cpython-313.pyc +0 -0
  28. package/src/agents/__pycache__/intent_agent.cpython-314.pyc +0 -0
  29. package/src/agents/__pycache__/kg_agent.cpython-314.pyc +0 -0
  30. package/src/agents/__pycache__/memory_agent.cpython-314.pyc +0 -0
  31. package/src/agents/__pycache__/reflection_agent.cpython-314.pyc +0 -0
  32. package/src/agents/__pycache__/regression_agent.cpython-311.pyc +0 -0
  33. package/src/agents/__pycache__/regression_agent.cpython-313.pyc +0 -0
  34. package/src/agents/__pycache__/requirement_agent.cpython-311.pyc +0 -0
  35. package/src/agents/__pycache__/requirement_agent.cpython-313.pyc +0 -0
  36. package/src/agents/__pycache__/requirement_agent.cpython-314.pyc +0 -0
  37. package/src/agents/__pycache__/retrieval_agent.cpython-314.pyc +0 -0
  38. package/src/agents/__pycache__/scenario_agent.cpython-311.pyc +0 -0
  39. package/src/agents/__pycache__/scenario_agent.cpython-313.pyc +0 -0
  40. package/src/agents/__pycache__/scenario_agent.cpython-314.pyc +0 -0
  41. package/src/agents/__pycache__/script_agent.cpython-314.pyc +0 -0
  42. package/src/agents/__pycache__/script_generator_agent.cpython-311.pyc +0 -0
  43. package/src/agents/__pycache__/script_generator_agent.cpython-313.pyc +0 -0
  44. package/src/agents/__pycache__/script_generator_agent.cpython-314.pyc +0 -0
  45. package/src/agents/__pycache__/state.cpython-314.pyc +0 -0
  46. package/src/agents/__pycache__/temporal_agent.cpython-314.pyc +0 -0
  47. package/src/agents/__pycache__/testcase_agent.cpython-311.pyc +0 -0
  48. package/src/agents/__pycache__/testcase_agent.cpython-313.pyc +0 -0
  49. package/src/agents/__pycache__/testcase_agent.cpython-314.pyc +0 -0
  50. package/src/agents/__pycache__/validation_agent.cpython-311.pyc +0 -0
  51. package/src/agents/__pycache__/validation_agent.cpython-313.pyc +0 -0
  52. package/src/agents/__pycache__/validation_agent.cpython-314.pyc +0 -0
  53. package/src/agents/__pycache__/workflow_engine.cpython-311.pyc +0 -0
  54. package/src/agents/__pycache__/workflow_engine.cpython-313.pyc +0 -0
  55. package/src/agents/__pycache__/workflow_engine.cpython-314.pyc +0 -0
  56. package/{knowledge_base → src}/agents/automation_design_agent.py +14 -17
  57. package/{knowledge_base → src}/agents/code_intelligence_agent.py +2 -2
  58. package/src/agents/confidence_agent.py +114 -0
  59. package/{knowledge_base → src}/agents/execution_validation_agent.py +1 -1
  60. package/src/agents/feedback_agent.py +89 -0
  61. package/src/agents/framework_analyzer_agent.py +43 -0
  62. package/{knowledge_base → src}/agents/fusion_agent.py +3 -3
  63. package/{knowledge_base → src}/agents/graph.py +10 -10
  64. package/{knowledge_base → src}/agents/healing_agent.py +4 -4
  65. package/src/agents/intent_agent.py +30 -0
  66. package/src/agents/internal/__init__.py +3 -0
  67. package/src/agents/internal/__pycache__/__init__.cpython-313.pyc +0 -0
  68. package/src/agents/internal/__pycache__/approval_manager.cpython-313.pyc +0 -0
  69. package/src/agents/internal/__pycache__/question_engine.cpython-313.pyc +0 -0
  70. package/src/agents/internal/approval_manager.py +111 -0
  71. package/src/agents/internal/question_engine.py +111 -0
  72. package/src/agents/internal/workflow_engine.py +28 -0
  73. package/{knowledge_base → src}/agents/kg_agent.py +3 -3
  74. package/{knowledge_base → src}/agents/memory_agent.py +4 -4
  75. package/src/agents/orchestrator/__init__.py +3 -0
  76. package/src/agents/orchestrator/__pycache__/__init__.cpython-313.pyc +0 -0
  77. package/src/agents/orchestrator/__pycache__/orchestrator.cpython-313.pyc +0 -0
  78. package/src/agents/orchestrator/orchestrator.py +63 -0
  79. package/{knowledge_base → src}/agents/rca_agent.py +4 -4
  80. package/{knowledge_base → src}/agents/reflection_agent.py +1 -1
  81. package/{knowledge_base → src}/agents/regression_agent.py +2 -2
  82. package/src/agents/requirement_agent.py +97 -0
  83. package/{knowledge_base → src}/agents/retrieval_agent.py +2 -2
  84. package/{knowledge_base → src}/agents/scenario_agent.py +11 -17
  85. package/{knowledge_base → src}/agents/script_agent.py +6 -6
  86. package/{knowledge_base → src}/agents/script_generator_agent.py +12 -10
  87. package/{knowledge_base → src}/agents/temporal_agent.py +3 -3
  88. package/src/agents/testcase_agent.py +163 -0
  89. package/{knowledge_base → src}/agents/validation_agent.py +1 -1
  90. package/src/agents/workflow_engine.py +109 -0
  91. package/{knowledge_base → src}/alembic/README.md +4 -4
  92. package/{knowledge_base → src}/alembic/env.py +1 -1
  93. package/{knowledge_base → src}/alembic/script.py.mako +1 -1
  94. package/{knowledge_base → src}/api/middleware.py +3 -3
  95. package/{knowledge_base → src}/api/server.py +28 -28
  96. package/{knowledge_base → src}/chunking/chunker.py +3 -3
  97. package/src/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  98. package/src/cli/__pycache__/__init__.cpython-313.pyc +0 -0
  99. package/src/cli/__pycache__/__init__.cpython-314.pyc +0 -0
  100. package/src/cli/__pycache__/workflow_cli.cpython-311.pyc +0 -0
  101. package/src/cli/__pycache__/workflow_cli.cpython-313.pyc +0 -0
  102. package/src/cli/__pycache__/workflow_cli.cpython-314.pyc +0 -0
  103. package/{knowledge_base → src}/cli/feedback_cli.py +10 -10
  104. package/{knowledge_base → src}/cli/generate.py +11 -11
  105. package/src/cli/index.ts +704 -0
  106. package/src/cli/platform.ts +147 -0
  107. package/src/cli/workflow_cli.py +930 -0
  108. package/{knowledge_base → src}/config/__init__.py +1 -1
  109. package/src/config/__pycache__/__init__.cpython-311.pyc +0 -0
  110. package/src/config/__pycache__/__init__.cpython-313.pyc +0 -0
  111. package/src/config/__pycache__/__init__.cpython-314.pyc +0 -0
  112. package/src/config/__pycache__/policy_config.cpython-311.pyc +0 -0
  113. package/src/config/__pycache__/policy_config.cpython-313.pyc +0 -0
  114. package/src/config/__pycache__/settings.cpython-311.pyc +0 -0
  115. package/src/config/__pycache__/settings.cpython-313.pyc +0 -0
  116. package/src/config/__pycache__/settings.cpython-314.pyc +0 -0
  117. package/src/config/policy_config.py +85 -0
  118. package/src/config/policy_rules.yaml +50 -0
  119. package/{knowledge_base → src}/config/settings.py +51 -6
  120. package/{knowledge_base → src}/connectors/__init__.py +1 -1
  121. package/src/connectors/__pycache__/__init__.cpython-311.pyc +0 -0
  122. package/src/connectors/__pycache__/__init__.cpython-313.pyc +0 -0
  123. package/src/connectors/__pycache__/__init__.cpython-314.pyc +0 -0
  124. package/src/connectors/__pycache__/base.cpython-311.pyc +0 -0
  125. package/src/connectors/__pycache__/base.cpython-313.pyc +0 -0
  126. package/src/connectors/__pycache__/base.cpython-314.pyc +0 -0
  127. package/src/connectors/__pycache__/jira_connector.cpython-311.pyc +0 -0
  128. package/src/connectors/__pycache__/jira_connector.cpython-313.pyc +0 -0
  129. package/src/connectors/__pycache__/jira_connector.cpython-314.pyc +0 -0
  130. package/src/connectors/__pycache__/query_bridge.cpython-313.pyc +0 -0
  131. package/src/connectors/__pycache__/query_bridge.cpython-314.pyc +0 -0
  132. package/src/connectors/bitbucket_connector.py +334 -0
  133. package/{knowledge_base → src}/connectors/community_connector.py +6 -6
  134. package/{knowledge_base → src}/connectors/confluence_connector.py +4 -4
  135. package/{knowledge_base → src}/connectors/jira_connector.py +7 -11
  136. package/{knowledge_base → src}/connectors/kb_igel_connector.py +6 -6
  137. package/{knowledge_base → src}/connectors/query_bridge.py +11 -11
  138. package/{knowledge_base → src}/connectors/search_backends.py +1 -1
  139. package/{knowledge_base → src}/connectors/serviceNow_connector.py +2 -2
  140. package/{knowledge_base → src}/connectors/sync_scheduler.py +12 -10
  141. package/{knowledge_base → src}/connectors/teamcity_connector.py +2 -2
  142. package/{knowledge_base → src}/connectors/testRail_connector.py +2 -2
  143. package/{knowledge_base → src}/connectors/web_fetcher.py +1 -1
  144. package/src/connectors/xray_connector.py +337 -0
  145. package/{knowledge_base → src}/core/__init__.py +1 -1
  146. package/src/core/__pycache__/__init__.cpython-311.pyc +0 -0
  147. package/src/core/__pycache__/__init__.cpython-313.pyc +0 -0
  148. package/src/core/__pycache__/__init__.cpython-314.pyc +0 -0
  149. package/src/core/__pycache__/circuit_breaker.cpython-313.pyc +0 -0
  150. package/src/core/__pycache__/circuit_breaker.cpython-314.pyc +0 -0
  151. package/src/core/__pycache__/confidence.cpython-311.pyc +0 -0
  152. package/src/core/__pycache__/confidence.cpython-313.pyc +0 -0
  153. package/src/core/__pycache__/confidence.cpython-314.pyc +0 -0
  154. package/src/core/__pycache__/context_engine.cpython-311.pyc +0 -0
  155. package/src/core/__pycache__/context_engine.cpython-313.pyc +0 -0
  156. package/src/core/__pycache__/evidence_resolver.cpython-311.pyc +0 -0
  157. package/src/core/__pycache__/evidence_resolver.cpython-313.pyc +0 -0
  158. package/src/core/__pycache__/guardrails.cpython-311.pyc +0 -0
  159. package/src/core/__pycache__/guardrails.cpython-313.pyc +0 -0
  160. package/src/core/__pycache__/hooks.cpython-311.pyc +0 -0
  161. package/src/core/__pycache__/hooks.cpython-313.pyc +0 -0
  162. package/src/core/__pycache__/intent_service.cpython-313.pyc +0 -0
  163. package/src/core/__pycache__/llm_executor.cpython-311.pyc +0 -0
  164. package/src/core/__pycache__/llm_executor.cpython-313.pyc +0 -0
  165. package/src/core/__pycache__/model_router.cpython-311.pyc +0 -0
  166. package/src/core/__pycache__/model_router.cpython-313.pyc +0 -0
  167. package/src/core/__pycache__/orchestration_contracts.cpython-311.pyc +0 -0
  168. package/src/core/__pycache__/orchestration_contracts.cpython-313.pyc +0 -0
  169. package/src/core/__pycache__/precedence.cpython-311.pyc +0 -0
  170. package/src/core/__pycache__/precedence.cpython-313.pyc +0 -0
  171. package/src/core/__pycache__/prompt_builder.cpython-311.pyc +0 -0
  172. package/src/core/__pycache__/prompt_builder.cpython-313.pyc +0 -0
  173. package/src/core/__pycache__/prompt_policy_engine.cpython-311.pyc +0 -0
  174. package/src/core/__pycache__/prompt_policy_engine.cpython-313.pyc +0 -0
  175. package/{knowledge_base → src}/core/cache.py +2 -2
  176. package/{knowledge_base → src}/core/confidence.py +2 -2
  177. package/src/core/context_engine.py +138 -0
  178. package/src/core/evidence_resolver.py +72 -0
  179. package/src/core/guardrails.py +22 -0
  180. package/src/core/hooks.py +57 -0
  181. package/src/core/intent_service.py +74 -0
  182. package/src/core/llm_executor.py +138 -0
  183. package/{knowledge_base → src}/core/logging_setup.py +1 -1
  184. package/src/core/model_router.py +246 -0
  185. package/src/core/orchestration_contracts.py +66 -0
  186. package/src/core/persistence_engine.py +159 -0
  187. package/src/core/prompt_builder.py +49 -0
  188. package/src/core/prompt_policy_engine.py +35 -0
  189. package/src/core/traceability_engine.py +56 -0
  190. package/src/db/__pycache__/__init__.cpython-311.pyc +0 -0
  191. package/src/db/__pycache__/__init__.cpython-313.pyc +0 -0
  192. package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
  193. package/src/db/__pycache__/client.cpython-311.pyc +0 -0
  194. package/src/db/__pycache__/client.cpython-313.pyc +0 -0
  195. package/src/db/__pycache__/client.cpython-314.pyc +0 -0
  196. package/src/db/__pycache__/igel_schema.cpython-311.pyc +0 -0
  197. package/src/db/__pycache__/igel_schema.cpython-313.pyc +0 -0
  198. package/src/db/__pycache__/igel_schema.cpython-314.pyc +0 -0
  199. package/src/db/__pycache__/kg_introspect.cpython-311.pyc +0 -0
  200. package/src/db/__pycache__/kg_introspect.cpython-313.pyc +0 -0
  201. package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-314.pyc +0 -0
  202. package/{knowledge_base → src}/db/client.py +1 -1
  203. package/{knowledge_base → src}/db/connector_sync.py +1 -1
  204. package/{knowledge_base → src}/db/feedback_schema.py +2 -2
  205. package/{knowledge_base → src}/db/igel_schema.py +29 -4
  206. package/{knowledge_base → src}/db/kg_introspect.py +1 -1
  207. package/src/db/migrations.py +237 -0
  208. package/{knowledge_base → src}/db/schema.py +6 -6
  209. package/{knowledge_base → src}/deploy/Dockerfile +3 -3
  210. package/{knowledge_base → src}/deploy/feedback_automation.sh +3 -3
  211. package/{knowledge_base → src}/deploy/firecrawl-docker.sh +4 -4
  212. package/{knowledge_base → src}/deploy/igel-testgen.service +2 -2
  213. package/{knowledge_base → src}/deploy/install_reranker.sh +1 -1
  214. package/{knowledge_base → src}/deploy/requirements.txt +1 -2
  215. package/{knowledge_base → src}/deploy/run_server.sh +1 -1
  216. package/{knowledge_base → src}/docs/TEST_GENERATION_GUIDE.md +15 -15
  217. package/src/embeddings/__pycache__/__init__.cpython-311.pyc +0 -0
  218. package/src/embeddings/__pycache__/__init__.cpython-313.pyc +0 -0
  219. package/src/embeddings/__pycache__/__init__.cpython-314.pyc +0 -0
  220. package/src/embeddings/__pycache__/azure_embedder.cpython-311.pyc +0 -0
  221. package/src/embeddings/__pycache__/azure_embedder.cpython-313.pyc +0 -0
  222. package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-314.pyc +0 -0
  223. package/{knowledge_base → src}/embeddings/azure_embedder.py +10 -1
  224. package/{knowledge_base → src}/eval/__init__.py +3 -3
  225. package/{knowledge_base → src}/eval/__main__.py +7 -7
  226. package/src/eval/__pycache__/__init__.cpython-311.pyc +0 -0
  227. package/src/eval/__pycache__/__init__.cpython-313.pyc +0 -0
  228. package/src/eval/__pycache__/__init__.cpython-314.pyc +0 -0
  229. package/src/eval/__pycache__/baseline.cpython-311.pyc +0 -0
  230. package/src/eval/__pycache__/baseline.cpython-313.pyc +0 -0
  231. package/src/eval/__pycache__/baseline.cpython-314.pyc +0 -0
  232. package/src/eval/__pycache__/harness.cpython-311.pyc +0 -0
  233. package/src/eval/__pycache__/harness.cpython-313.pyc +0 -0
  234. package/src/eval/__pycache__/harness.cpython-314.pyc +0 -0
  235. package/src/eval/__pycache__/scorers.cpython-311.pyc +0 -0
  236. package/src/eval/__pycache__/scorers.cpython-313.pyc +0 -0
  237. package/src/eval/__pycache__/scorers.cpython-314.pyc +0 -0
  238. package/{knowledge_base → src}/eval/harness.py +6 -6
  239. package/{knowledge_base → src}/feedback/__init__.py +1 -1
  240. package/{knowledge_base → src}/feedback/analytics.py +1 -1
  241. package/{knowledge_base → src}/feedback/applier.py +4 -4
  242. package/{knowledge_base → src}/feedback/curator.py +2 -2
  243. package/{knowledge_base → src}/feedback/handler.py +1 -1
  244. package/src/generation/__pycache__/__init__.cpython-313.pyc +0 -0
  245. package/src/generation/__pycache__/__init__.cpython-314.pyc +0 -0
  246. package/src/generation/__pycache__/input_classifier.cpython-313.pyc +0 -0
  247. package/src/generation/__pycache__/manual_tc_parser.cpython-313.pyc +0 -0
  248. package/src/generation/__pycache__/prompts.cpython-313.pyc +0 -0
  249. package/src/generation/__pycache__/prompts.cpython-314.pyc +0 -0
  250. package/src/generation/__pycache__/test_generator.cpython-313.pyc +0 -0
  251. package/src/generation/__pycache__/test_generator.cpython-314.pyc +0 -0
  252. package/{knowledge_base → src}/generation/input_classifier.py +1 -1
  253. package/{knowledge_base → src}/generation/prompts.py +1 -1
  254. package/{knowledge_base → src}/generation/tc_transformer.py +10 -10
  255. package/{knowledge_base → src}/generation/test_generator.py +56 -10
  256. package/{knowledge_base → src}/graph_db/__init__.py +1 -1
  257. package/{knowledge_base → src}/graph_db/graphiti_client.py +2 -2
  258. package/{knowledge_base → src}/graph_db/kg_traversal.py +3 -3
  259. package/{knowledge_base → src}/graph_db/migrate_kg.py +4 -4
  260. package/{knowledge_base → src}/graph_db/neo4j_client.py +1 -1
  261. package/{knowledge_base → src}/graph_db/temporal_ingest.py +1 -1
  262. package/{knowledge_base → src}/ingestion/kg_extractor.py +6 -6
  263. package/{knowledge_base → src}/ingestion/web_ingest.py +6 -6
  264. package/src/intelligence/__pycache__/__init__.cpython-311.pyc +0 -0
  265. package/src/intelligence/__pycache__/__init__.cpython-313.pyc +0 -0
  266. package/src/intelligence/__pycache__/diff_analyzer.cpython-311.pyc +0 -0
  267. package/src/intelligence/__pycache__/diff_analyzer.cpython-313.pyc +0 -0
  268. package/src/intelligence/__pycache__/routing_engine.cpython-311.pyc +0 -0
  269. package/src/intelligence/__pycache__/routing_engine.cpython-313.pyc +0 -0
  270. package/src/intelligence/diff_analyzer.py +109 -0
  271. package/{knowledge_base → src}/intelligence/execution_ingest.py +3 -3
  272. package/src/intelligence/routing_engine.py +74 -0
  273. package/src/mcp/server.ts +384 -0
  274. package/src/memory/__init__.py +6 -0
  275. package/src/memory/__pycache__/__init__.cpython-314.pyc +0 -0
  276. package/src/memory/__pycache__/cognee_client.cpython-314.pyc +0 -0
  277. package/src/memory/__pycache__/memory_types.cpython-314.pyc +0 -0
  278. package/{knowledge_base → src}/memory/cognee_client.py +3 -3
  279. package/src/models/__pycache__/test_requirement.cpython-311.pyc +0 -0
  280. package/src/models/__pycache__/test_requirement.cpython-313.pyc +0 -0
  281. package/src/models/__pycache__/test_requirement.cpython-314.pyc +0 -0
  282. package/{knowledge_base → src}/models/test_requirement.py +12 -7
  283. package/{knowledge_base → src}/parsers/csv_parser.py +1 -1
  284. package/{knowledge_base → src}/parsers/doc_parser.py +1 -1
  285. package/{knowledge_base → src}/parsers/html_parser.py +1 -1
  286. package/{knowledge_base → src}/parsers/pdf_parser.py +1 -1
  287. package/src/project/__pycache__/__init__.cpython-311.pyc +0 -0
  288. package/src/project/__pycache__/__init__.cpython-313.pyc +0 -0
  289. package/src/project/__pycache__/ai_folder.cpython-311.pyc +0 -0
  290. package/src/project/__pycache__/ai_folder.cpython-313.pyc +0 -0
  291. package/src/project/__pycache__/context_enricher.cpython-313.pyc +0 -0
  292. package/src/project/__pycache__/context_projection_builder.cpython-311.pyc +0 -0
  293. package/src/project/__pycache__/context_projection_builder.cpython-313.pyc +0 -0
  294. package/src/project/__pycache__/context_requirement_sync.cpython-311.pyc +0 -0
  295. package/src/project/__pycache__/context_requirement_sync.cpython-313.pyc +0 -0
  296. package/src/project/ai_folder.py +602 -0
  297. package/src/project/context_enricher.py +333 -0
  298. package/src/project/context_projection_builder.py +167 -0
  299. package/src/project/context_requirement_sync.py +205 -0
  300. package/src/project/init_check.py +214 -0
  301. package/src/prompts/__pycache__/prompt_loader.cpython-313.pyc +0 -0
  302. package/src/prompts/automation_design.md +12 -0
  303. package/src/prompts/policies/automation_generation_policy.md +11 -0
  304. package/src/prompts/policies/generation_instructions.md +24 -0
  305. package/src/prompts/policies/guardrails.md +6 -0
  306. package/src/prompts/policies/traceability_policy.md +9 -0
  307. package/src/prompts/prompt_loader.py +56 -0
  308. package/src/prompts/requirement_understanding.md +17 -0
  309. package/src/prompts/scenario_generator.md +17 -0
  310. package/src/prompts/script_generator.md +13 -0
  311. package/src/prompts/test_case_generator.md +23 -0
  312. package/src/retrieval/__pycache__/__init__.cpython-311.pyc +0 -0
  313. package/src/retrieval/__pycache__/__init__.cpython-313.pyc +0 -0
  314. package/src/retrieval/__pycache__/__init__.cpython-314.pyc +0 -0
  315. package/src/retrieval/__pycache__/knowledge_graph.cpython-311.pyc +0 -0
  316. package/src/retrieval/__pycache__/knowledge_graph.cpython-313.pyc +0 -0
  317. package/src/retrieval/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  318. package/src/retrieval/__pycache__/retriever.cpython-311.pyc +0 -0
  319. package/src/retrieval/__pycache__/retriever.cpython-313.pyc +0 -0
  320. package/src/retrieval/__pycache__/retriever.cpython-314.pyc +0 -0
  321. package/src/retrieval/__pycache__/unified_query.cpython-313.pyc +0 -0
  322. package/src/retrieval/__pycache__/unified_query.cpython-314.pyc +0 -0
  323. package/{knowledge_base → src}/retrieval/context_fusion.py +3 -3
  324. package/{knowledge_base → src}/retrieval/knowledge_graph.py +4 -4
  325. package/{knowledge_base → src}/retrieval/reranker.py +2 -2
  326. package/{knowledge_base → src}/retrieval/retriever.py +11 -11
  327. package/{knowledge_base → src}/retrieval/unified_query.py +7 -7
  328. package/{knowledge_base → src}/retrieval/web_retriever.py +6 -6
  329. package/{knowledge_base → src}/validators/step_fidelity.py +1 -1
  330. package/src/vision/__init__.py +0 -0
  331. package/{knowledge_base → src}/vision/image_describer.py +1 -1
  332. package/knowledge_base/__pycache__/__init__.cpython-314.pyc +0 -0
  333. package/knowledge_base/agents/__init__.py +0 -6
  334. package/knowledge_base/agents/confidence_agent.py +0 -94
  335. package/knowledge_base/agents/feedback_agent.py +0 -56
  336. package/knowledge_base/agents/intent_agent.py +0 -76
  337. package/knowledge_base/agents/requirement_agent.py +0 -71
  338. package/knowledge_base/agents/testcase_agent.py +0 -111
  339. package/knowledge_base/agents/workflow_engine.py +0 -87
  340. package/knowledge_base/cli/generate_qcapps134.py +0 -391
  341. package/knowledge_base/cli/workflow_cli.py +0 -93
  342. package/knowledge_base/config/.env +0 -100
  343. package/knowledge_base/config/.env.example +0 -75
  344. package/knowledge_base/connectors/bitbucket_connector.py +0 -25
  345. package/knowledge_base/db/__pycache__/__init__.cpython-314.pyc +0 -0
  346. package/knowledge_base/db/__pycache__/client.cpython-314.pyc +0 -0
  347. package/knowledge_base/db/migrations.py +0 -22
  348. package/knowledge_base/embeddings/__pycache__/__init__.cpython-314.pyc +0 -0
  349. package/knowledge_base/ingestion/ingest.py +0 -346
  350. package/knowledge_base/ingestion/ingest_images.py +0 -330
  351. package/knowledge_base/memory/__init__.py +0 -6
  352. package/knowledge_base/memory/ingest_memory.py +0 -60
  353. /package/{knowledge_base → src}/__init__.py +0 -0
  354. /package/{knowledge_base → src}/__pycache__/__init__.cpython-37.pyc +0 -0
  355. /package/{knowledge_base → src}/__pycache__/__init__.cpython-38.pyc +0 -0
  356. /package/{knowledge_base → src}/__pycache__/confidence.cpython-37.pyc +0 -0
  357. /package/{knowledge_base → src}/__pycache__/config.cpython-314.pyc +0 -0
  358. /package/{knowledge_base → src}/__pycache__/config.cpython-37.pyc +0 -0
  359. /package/{knowledge_base → src}/__pycache__/config.cpython-38.pyc +0 -0
  360. /package/{knowledge_base → src}/__pycache__/context_fusion.cpython-314.pyc +0 -0
  361. /package/{knowledge_base → src}/__pycache__/context_fusion.cpython-37.pyc +0 -0
  362. /package/{knowledge_base → src}/__pycache__/feedback_analytics.cpython-37.pyc +0 -0
  363. /package/{knowledge_base → src}/__pycache__/feedback_applier.cpython-37.pyc +0 -0
  364. /package/{knowledge_base → src}/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  365. /package/{knowledge_base → src}/__pycache__/feedback_curator.cpython-37.pyc +0 -0
  366. /package/{knowledge_base → src}/__pycache__/feedback_handler.cpython-37.pyc +0 -0
  367. /package/{knowledge_base → src}/__pycache__/generate.cpython-37.pyc +0 -0
  368. /package/{knowledge_base → src}/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  369. /package/{knowledge_base → src}/__pycache__/input_classifier.cpython-314.pyc +0 -0
  370. /package/{knowledge_base → src}/__pycache__/input_classifier.cpython-37.pyc +0 -0
  371. /package/{knowledge_base → src}/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  372. /package/{knowledge_base → src}/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  373. /package/{knowledge_base → src}/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  374. /package/{knowledge_base → src}/__pycache__/manual_tc_parser.cpython-314.pyc +0 -0
  375. /package/{knowledge_base → src}/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  376. /package/{knowledge_base → src}/__pycache__/precedence.cpython-37.pyc +0 -0
  377. /package/{knowledge_base → src}/__pycache__/prompts.cpython-314.pyc +0 -0
  378. /package/{knowledge_base → src}/__pycache__/prompts.cpython-37.pyc +0 -0
  379. /package/{knowledge_base → src}/__pycache__/reranker.cpython-314.pyc +0 -0
  380. /package/{knowledge_base → src}/__pycache__/reranker.cpython-37.pyc +0 -0
  381. /package/{knowledge_base → src}/__pycache__/retrieval_debug.cpython-314.pyc +0 -0
  382. /package/{knowledge_base → src}/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  383. /package/{knowledge_base → src}/__pycache__/retriever.cpython-314.pyc +0 -0
  384. /package/{knowledge_base → src}/__pycache__/retriever.cpython-37.pyc +0 -0
  385. /package/{knowledge_base → src}/__pycache__/server.cpython-37.pyc +0 -0
  386. /package/{knowledge_base → src}/__pycache__/tc_transformer.cpython-314.pyc +0 -0
  387. /package/{knowledge_base → src}/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  388. /package/{knowledge_base → src}/__pycache__/test_generator.cpython-314.pyc +0 -0
  389. /package/{knowledge_base → src}/__pycache__/test_generator.cpython-37.pyc +0 -0
  390. /package/{knowledge_base → src}/agents/__pycache__/__init__.cpython-37.pyc +0 -0
  391. /package/{knowledge_base → src}/agents/__pycache__/__init__.cpython-38.pyc +0 -0
  392. /package/{knowledge_base → src}/agents/__pycache__/fusion_agent.cpython-37.pyc +0 -0
  393. /package/{knowledge_base → src}/agents/__pycache__/fusion_agent.cpython-38.pyc +0 -0
  394. /package/{knowledge_base → src}/agents/__pycache__/graph.cpython-37.pyc +0 -0
  395. /package/{knowledge_base → src}/agents/__pycache__/graph.cpython-38.pyc +0 -0
  396. /package/{knowledge_base → src}/agents/__pycache__/healing_agent.cpython-37.pyc +0 -0
  397. /package/{knowledge_base → src}/agents/__pycache__/intent_agent.cpython-37.pyc +0 -0
  398. /package/{knowledge_base → src}/agents/__pycache__/intent_agent.cpython-38.pyc +0 -0
  399. /package/{knowledge_base → src}/agents/__pycache__/kg_agent.cpython-37.pyc +0 -0
  400. /package/{knowledge_base → src}/agents/__pycache__/kg_agent.cpython-38.pyc +0 -0
  401. /package/{knowledge_base → src}/agents/__pycache__/memory_agent.cpython-37.pyc +0 -0
  402. /package/{knowledge_base → src}/agents/__pycache__/memory_agent.cpython-38.pyc +0 -0
  403. /package/{knowledge_base → src}/agents/__pycache__/rca_agent.cpython-37.pyc +0 -0
  404. /package/{knowledge_base → src}/agents/__pycache__/reflection_agent.cpython-37.pyc +0 -0
  405. /package/{knowledge_base → src}/agents/__pycache__/reflection_agent.cpython-38.pyc +0 -0
  406. /package/{knowledge_base → src}/agents/__pycache__/regression_agent.cpython-37.pyc +0 -0
  407. /package/{knowledge_base → src}/agents/__pycache__/retrieval_agent.cpython-37.pyc +0 -0
  408. /package/{knowledge_base → src}/agents/__pycache__/retrieval_agent.cpython-38.pyc +0 -0
  409. /package/{knowledge_base → src}/agents/__pycache__/script_agent.cpython-37.pyc +0 -0
  410. /package/{knowledge_base → src}/agents/__pycache__/script_agent.cpython-38.pyc +0 -0
  411. /package/{knowledge_base → src}/agents/__pycache__/state.cpython-37.pyc +0 -0
  412. /package/{knowledge_base → src}/agents/__pycache__/state.cpython-38.pyc +0 -0
  413. /package/{knowledge_base → src}/agents/__pycache__/temporal_agent.cpython-37.pyc +0 -0
  414. /package/{knowledge_base → src}/agents/__pycache__/temporal_agent.cpython-38.pyc +0 -0
  415. /package/{knowledge_base → src}/agents/__pycache__/validation_agent.cpython-37.pyc +0 -0
  416. /package/{knowledge_base → src}/agents/__pycache__/validation_agent.cpython-38.pyc +0 -0
  417. /package/{knowledge_base → src}/agents/state.py +0 -0
  418. /package/{knowledge_base → src}/alembic/__pycache__/env.cpython-37.pyc +0 -0
  419. /package/{knowledge_base → src}/alembic/__pycache__/env.cpython-38.pyc +0 -0
  420. /package/{knowledge_base → src}/alembic/versions/.gitkeep +0 -0
  421. /package/{knowledge_base → src}/alembic/versions/001_phase0_feedback.py +0 -0
  422. /package/{knowledge_base → src}/alembic/versions/002_feedback_promotions.py +0 -0
  423. /package/{knowledge_base → src}/alembic/versions/003_enterprise_hardening.py +0 -0
  424. /package/{knowledge_base → src}/alembic/versions/__pycache__/001_phase0_feedback.cpython-37.pyc +0 -0
  425. /package/{knowledge_base → src}/alembic/versions/__pycache__/001_phase0_feedback.cpython-38.pyc +0 -0
  426. /package/{knowledge_base → src}/alembic/versions/__pycache__/002_feedback_promotions.cpython-37.pyc +0 -0
  427. /package/{knowledge_base → src}/alembic/versions/__pycache__/002_feedback_promotions.cpython-38.pyc +0 -0
  428. /package/{knowledge_base → src}/api/__init__.py +0 -0
  429. /package/{knowledge_base → src}/api/__pycache__/__init__.cpython-37.pyc +0 -0
  430. /package/{knowledge_base → src}/api/__pycache__/__init__.cpython-38.pyc +0 -0
  431. /package/{knowledge_base → src}/api/__pycache__/middleware.cpython-38.pyc +0 -0
  432. /package/{knowledge_base → src}/api/__pycache__/server.cpython-37.pyc +0 -0
  433. /package/{knowledge_base → src}/api/__pycache__/server.cpython-38.pyc +0 -0
  434. /package/{knowledge_base → src}/chunking/__init__.py +0 -0
  435. /package/{knowledge_base → src}/chunking/__pycache__/__init__.cpython-37.pyc +0 -0
  436. /package/{knowledge_base → src}/chunking/__pycache__/__init__.cpython-38.pyc +0 -0
  437. /package/{knowledge_base → src}/chunking/__pycache__/chunker.cpython-37.pyc +0 -0
  438. /package/{knowledge_base → src}/chunking/__pycache__/chunker.cpython-38.pyc +0 -0
  439. /package/{knowledge_base → src}/chunking/__pycache__/validators.cpython-37.pyc +0 -0
  440. /package/{knowledge_base → src}/chunking/__pycache__/validators.cpython-38.pyc +0 -0
  441. /package/{knowledge_base → src}/chunking/validators.py +0 -0
  442. /package/{knowledge_base → src}/cli/__init__.py +0 -0
  443. /package/{knowledge_base → src}/cli/__pycache__/__init__.cpython-37.pyc +0 -0
  444. /package/{knowledge_base → src}/cli/__pycache__/__init__.cpython-38.pyc +0 -0
  445. /package/{knowledge_base → src}/cli/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  446. /package/{knowledge_base → src}/cli/__pycache__/feedback_cli.cpython-38.pyc +0 -0
  447. /package/{knowledge_base → src}/cli/__pycache__/generate.cpython-37.pyc +0 -0
  448. /package/{knowledge_base → src}/cli/__pycache__/generate.cpython-38.pyc +0 -0
  449. /package/{knowledge_base → src}/cli/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  450. /package/{knowledge_base → src}/config/__pycache__/__init__.cpython-37.pyc +0 -0
  451. /package/{knowledge_base → src}/config/__pycache__/__init__.cpython-38.pyc +0 -0
  452. /package/{knowledge_base → src}/config/__pycache__/settings.cpython-37.pyc +0 -0
  453. /package/{knowledge_base → src}/config/__pycache__/settings.cpython-38.pyc +0 -0
  454. /package/{knowledge_base → src}/connectors/__pycache__/__init__.cpython-37.pyc +0 -0
  455. /package/{knowledge_base → src}/connectors/__pycache__/__init__.cpython-38.pyc +0 -0
  456. /package/{knowledge_base → src}/connectors/__pycache__/base.cpython-37.pyc +0 -0
  457. /package/{knowledge_base → src}/connectors/__pycache__/base.cpython-38.pyc +0 -0
  458. /package/{knowledge_base → src}/connectors/__pycache__/bitbucket_connector.cpython-37.pyc +0 -0
  459. /package/{knowledge_base → src}/connectors/__pycache__/bitbucket_connector.cpython-38.pyc +0 -0
  460. /package/{knowledge_base → src}/connectors/__pycache__/community_connector.cpython-38.pyc +0 -0
  461. /package/{knowledge_base → src}/connectors/__pycache__/confluence_connector.cpython-37.pyc +0 -0
  462. /package/{knowledge_base → src}/connectors/__pycache__/confluence_connector.cpython-38.pyc +0 -0
  463. /package/{knowledge_base → src}/connectors/__pycache__/jira_connector.cpython-37.pyc +0 -0
  464. /package/{knowledge_base → src}/connectors/__pycache__/jira_connector.cpython-38.pyc +0 -0
  465. /package/{knowledge_base → src}/connectors/__pycache__/kb_igel_connector.cpython-38.pyc +0 -0
  466. /package/{knowledge_base → src}/connectors/__pycache__/playwright_fetcher.cpython-38.pyc +0 -0
  467. /package/{knowledge_base → src}/connectors/__pycache__/query_bridge.cpython-38.pyc +0 -0
  468. /package/{knowledge_base → src}/connectors/__pycache__/search_backends.cpython-38.pyc +0 -0
  469. /package/{knowledge_base → src}/connectors/__pycache__/serviceNow_connector.cpython-37.pyc +0 -0
  470. /package/{knowledge_base → src}/connectors/__pycache__/serviceNow_connector.cpython-38.pyc +0 -0
  471. /package/{knowledge_base → src}/connectors/__pycache__/sync_scheduler.cpython-37.pyc +0 -0
  472. /package/{knowledge_base → src}/connectors/__pycache__/sync_scheduler.cpython-38.pyc +0 -0
  473. /package/{knowledge_base → src}/connectors/__pycache__/teamcity_connector.cpython-37.pyc +0 -0
  474. /package/{knowledge_base → src}/connectors/__pycache__/teamcity_connector.cpython-38.pyc +0 -0
  475. /package/{knowledge_base → src}/connectors/__pycache__/testRail_connector.cpython-37.pyc +0 -0
  476. /package/{knowledge_base → src}/connectors/__pycache__/testRail_connector.cpython-38.pyc +0 -0
  477. /package/{knowledge_base → src}/connectors/__pycache__/web_fetcher.cpython-38.pyc +0 -0
  478. /package/{knowledge_base → src}/connectors/base.py +0 -0
  479. /package/{knowledge_base → src}/connectors/playwright_fetcher.py +0 -0
  480. /package/{knowledge_base → src}/core/__pycache__/__init__.cpython-37.pyc +0 -0
  481. /package/{knowledge_base → src}/core/__pycache__/__init__.cpython-38.pyc +0 -0
  482. /package/{knowledge_base → src}/core/__pycache__/cache.cpython-38.pyc +0 -0
  483. /package/{knowledge_base → src}/core/__pycache__/circuit_breaker.cpython-38.pyc +0 -0
  484. /package/{knowledge_base → src}/core/__pycache__/confidence.cpython-37.pyc +0 -0
  485. /package/{knowledge_base → src}/core/__pycache__/confidence.cpython-38.pyc +0 -0
  486. /package/{knowledge_base → src}/core/__pycache__/logging_setup.cpython-38.pyc +0 -0
  487. /package/{knowledge_base → src}/core/__pycache__/metrics.cpython-38.pyc +0 -0
  488. /package/{knowledge_base → src}/core/__pycache__/precedence.cpython-37.pyc +0 -0
  489. /package/{knowledge_base → src}/core/__pycache__/precedence.cpython-38.pyc +0 -0
  490. /package/{knowledge_base → src}/core/__pycache__/request_context.cpython-38.pyc +0 -0
  491. /package/{knowledge_base → src}/core/circuit_breaker.py +0 -0
  492. /package/{knowledge_base → src}/core/metrics.py +0 -0
  493. /package/{knowledge_base → src}/core/precedence.py +0 -0
  494. /package/{knowledge_base → src}/core/request_context.py +0 -0
  495. /package/{knowledge_base → src}/db/__init__.py +0 -0
  496. /package/{knowledge_base → src}/db/__pycache__/__init__.cpython-37.pyc +0 -0
  497. /package/{knowledge_base → src}/db/__pycache__/__init__.cpython-38.pyc +0 -0
  498. /package/{knowledge_base → src}/db/__pycache__/client.cpython-37.pyc +0 -0
  499. /package/{knowledge_base → src}/db/__pycache__/client.cpython-38.pyc +0 -0
  500. /package/{knowledge_base → src}/db/__pycache__/connector_sync.cpython-38.pyc +0 -0
  501. /package/{knowledge_base → src}/db/__pycache__/feedback_schema.cpython-37.pyc +0 -0
  502. /package/{knowledge_base → src}/db/__pycache__/feedback_schema.cpython-38.pyc +0 -0
  503. /package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-37.pyc +0 -0
  504. /package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-38.pyc +0 -0
  505. /package/{knowledge_base → src}/db/__pycache__/schema.cpython-37.pyc +0 -0
  506. /package/{knowledge_base → src}/db/__pycache__/schema.cpython-38.pyc +0 -0
  507. /package/{knowledge_base → src}/embeddings/__init__.py +0 -0
  508. /package/{knowledge_base → src}/embeddings/__pycache__/__init__.cpython-37.pyc +0 -0
  509. /package/{knowledge_base → src}/embeddings/__pycache__/__init__.cpython-38.pyc +0 -0
  510. /package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-37.pyc +0 -0
  511. /package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-38.pyc +0 -0
  512. /package/{knowledge_base → src}/eval/__pycache__/__init__.cpython-37.pyc +0 -0
  513. /package/{knowledge_base → src}/eval/__pycache__/__init__.cpython-38.pyc +0 -0
  514. /package/{knowledge_base → src}/eval/__pycache__/__main__.cpython-37.pyc +0 -0
  515. /package/{knowledge_base → src}/eval/__pycache__/baseline.cpython-37.pyc +0 -0
  516. /package/{knowledge_base → src}/eval/__pycache__/baseline.cpython-38.pyc +0 -0
  517. /package/{knowledge_base → src}/eval/__pycache__/harness.cpython-37.pyc +0 -0
  518. /package/{knowledge_base → src}/eval/__pycache__/harness.cpython-38.pyc +0 -0
  519. /package/{knowledge_base → src}/eval/__pycache__/scorers.cpython-37.pyc +0 -0
  520. /package/{knowledge_base → src}/eval/__pycache__/scorers.cpython-38.pyc +0 -0
  521. /package/{knowledge_base → src}/eval/baseline.py +0 -0
  522. /package/{knowledge_base → src}/eval/queries_50.json +0 -0
  523. /package/{knowledge_base → src}/eval/scorers.py +0 -0
  524. /package/{knowledge_base → src}/exemplars/README.md +0 -0
  525. /package/{knowledge_base → src}/exemplars/__pycache__/pytest_reference_snippet.cpython-37.pyc +0 -0
  526. /package/{knowledge_base → src}/exemplars/gold_manual_concise_snippet.md +0 -0
  527. /package/{knowledge_base → src}/exemplars/gold_manual_detailed_snippet.md +0 -0
  528. /package/{knowledge_base → src}/exemplars/pytest_reference_snippet.py +0 -0
  529. /package/{knowledge_base → src}/feedback/__pycache__/__init__.cpython-37.pyc +0 -0
  530. /package/{knowledge_base → src}/feedback/__pycache__/__init__.cpython-38.pyc +0 -0
  531. /package/{knowledge_base → src}/feedback/__pycache__/analytics.cpython-37.pyc +0 -0
  532. /package/{knowledge_base → src}/feedback/__pycache__/analytics.cpython-38.pyc +0 -0
  533. /package/{knowledge_base → src}/feedback/__pycache__/applier.cpython-37.pyc +0 -0
  534. /package/{knowledge_base → src}/feedback/__pycache__/applier.cpython-38.pyc +0 -0
  535. /package/{knowledge_base → src}/feedback/__pycache__/curator.cpython-37.pyc +0 -0
  536. /package/{knowledge_base → src}/feedback/__pycache__/curator.cpython-38.pyc +0 -0
  537. /package/{knowledge_base → src}/feedback/__pycache__/handler.cpython-37.pyc +0 -0
  538. /package/{knowledge_base → src}/feedback/__pycache__/handler.cpython-38.pyc +0 -0
  539. /package/{knowledge_base → src}/generation/__init__.py +0 -0
  540. /package/{knowledge_base → src}/generation/__pycache__/__init__.cpython-37.pyc +0 -0
  541. /package/{knowledge_base → src}/generation/__pycache__/__init__.cpython-38.pyc +0 -0
  542. /package/{knowledge_base → src}/generation/__pycache__/input_classifier.cpython-37.pyc +0 -0
  543. /package/{knowledge_base → src}/generation/__pycache__/input_classifier.cpython-38.pyc +0 -0
  544. /package/{knowledge_base → src}/generation/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  545. /package/{knowledge_base → src}/generation/__pycache__/manual_tc_parser.cpython-38.pyc +0 -0
  546. /package/{knowledge_base → src}/generation/__pycache__/prompts.cpython-37.pyc +0 -0
  547. /package/{knowledge_base → src}/generation/__pycache__/prompts.cpython-38.pyc +0 -0
  548. /package/{knowledge_base → src}/generation/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  549. /package/{knowledge_base → src}/generation/__pycache__/test_generator.cpython-37.pyc +0 -0
  550. /package/{knowledge_base → src}/generation/__pycache__/test_generator.cpython-38.pyc +0 -0
  551. /package/{knowledge_base → src}/generation/manual_tc_parser.py +0 -0
  552. /package/{knowledge_base → src}/graph_db/__pycache__/__init__.cpython-37.pyc +0 -0
  553. /package/{knowledge_base → src}/graph_db/__pycache__/__init__.cpython-38.pyc +0 -0
  554. /package/{knowledge_base → src}/graph_db/__pycache__/graphiti_client.cpython-37.pyc +0 -0
  555. /package/{knowledge_base → src}/graph_db/__pycache__/kg_traversal.cpython-37.pyc +0 -0
  556. /package/{knowledge_base → src}/graph_db/__pycache__/migrate_kg.cpython-37.pyc +0 -0
  557. /package/{knowledge_base → src}/graph_db/__pycache__/neo4j_client.cpython-37.pyc +0 -0
  558. /package/{knowledge_base → src}/graph_db/__pycache__/neo4j_client.cpython-38.pyc +0 -0
  559. /package/{knowledge_base → src}/graph_db/__pycache__/schema.cpython-37.pyc +0 -0
  560. /package/{knowledge_base → src}/graph_db/__pycache__/temporal_ingest.cpython-37.pyc +0 -0
  561. /package/{knowledge_base → src}/graph_db/schema.py +0 -0
  562. /package/{knowledge_base → src}/ingestion/__init__.py +0 -0
  563. /package/{knowledge_base → src}/ingestion/__pycache__/__init__.cpython-37.pyc +0 -0
  564. /package/{knowledge_base → src}/ingestion/__pycache__/__init__.cpython-38.pyc +0 -0
  565. /package/{knowledge_base → src}/ingestion/__pycache__/ingest.cpython-37.pyc +0 -0
  566. /package/{knowledge_base → src}/ingestion/__pycache__/ingest.cpython-38.pyc +0 -0
  567. /package/{knowledge_base → src}/ingestion/__pycache__/ingest_images.cpython-37.pyc +0 -0
  568. /package/{knowledge_base → src}/ingestion/__pycache__/ingest_images.cpython-38.pyc +0 -0
  569. /package/{knowledge_base → src}/ingestion/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  570. /package/{knowledge_base → src}/ingestion/__pycache__/kg_extractor.cpython-38.pyc +0 -0
  571. /package/{knowledge_base → src}/ingestion/__pycache__/web_ingest.cpython-38.pyc +0 -0
  572. /package/{knowledge_base → src}/intelligence/__init__.py +0 -0
  573. /package/{knowledge_base → src}/intelligence/__pycache__/__init__.cpython-37.pyc +0 -0
  574. /package/{knowledge_base → src}/intelligence/__pycache__/execution_ingest.cpython-37.pyc +0 -0
  575. /package/{knowledge_base → src}/intelligence/__pycache__/predictive_engine.cpython-37.pyc +0 -0
  576. /package/{knowledge_base → src}/intelligence/__pycache__/risk_scorer.cpython-37.pyc +0 -0
  577. /package/{knowledge_base → src}/intelligence/predictive_engine.py +0 -0
  578. /package/{knowledge_base → src}/intelligence/risk_scorer.py +0 -0
  579. /package/{knowledge_base → src}/memory/__pycache__/__init__.cpython-37.pyc +0 -0
  580. /package/{knowledge_base → src}/memory/__pycache__/__init__.cpython-38.pyc +0 -0
  581. /package/{knowledge_base → src}/memory/__pycache__/cognee_client.cpython-37.pyc +0 -0
  582. /package/{knowledge_base → src}/memory/__pycache__/cognee_client.cpython-38.pyc +0 -0
  583. /package/{knowledge_base → src}/memory/__pycache__/ingest_memory.cpython-37.pyc +0 -0
  584. /package/{knowledge_base → src}/memory/__pycache__/memory_types.cpython-37.pyc +0 -0
  585. /package/{knowledge_base → src}/memory/__pycache__/memory_types.cpython-38.pyc +0 -0
  586. /package/{knowledge_base → src}/memory/memory_types.py +0 -0
  587. /package/{knowledge_base → src}/parsers/__init__.py +0 -0
  588. /package/{knowledge_base → src}/parsers/__pycache__/__init__.cpython-37.pyc +0 -0
  589. /package/{knowledge_base → src}/parsers/__pycache__/__init__.cpython-38.pyc +0 -0
  590. /package/{knowledge_base → src}/parsers/__pycache__/csv_parser.cpython-37.pyc +0 -0
  591. /package/{knowledge_base → src}/parsers/__pycache__/csv_parser.cpython-38.pyc +0 -0
  592. /package/{knowledge_base → src}/parsers/__pycache__/doc_parser.cpython-37.pyc +0 -0
  593. /package/{knowledge_base → src}/parsers/__pycache__/doc_parser.cpython-38.pyc +0 -0
  594. /package/{knowledge_base → src}/parsers/__pycache__/html_parser.cpython-38.pyc +0 -0
  595. /package/{knowledge_base → src}/parsers/__pycache__/image_extractor.cpython-37.pyc +0 -0
  596. /package/{knowledge_base → src}/parsers/__pycache__/image_extractor.cpython-38.pyc +0 -0
  597. /package/{knowledge_base → src}/parsers/__pycache__/markdown_parser.cpython-37.pyc +0 -0
  598. /package/{knowledge_base → src}/parsers/__pycache__/markdown_parser.cpython-38.pyc +0 -0
  599. /package/{knowledge_base → src}/parsers/__pycache__/pdf_parser.cpython-37.pyc +0 -0
  600. /package/{knowledge_base → src}/parsers/__pycache__/pdf_parser.cpython-38.pyc +0 -0
  601. /package/{knowledge_base → src}/parsers/image_extractor.py +0 -0
  602. /package/{knowledge_base → src}/parsers/markdown_parser.py +0 -0
  603. /package/{knowledge_base/vision → src/project}/__init__.py +0 -0
  604. /package/{knowledge_base → src}/retrieval/__init__.py +0 -0
  605. /package/{knowledge_base → src}/retrieval/__pycache__/__init__.cpython-37.pyc +0 -0
  606. /package/{knowledge_base → src}/retrieval/__pycache__/__init__.cpython-38.pyc +0 -0
  607. /package/{knowledge_base → src}/retrieval/__pycache__/context_fusion.cpython-37.pyc +0 -0
  608. /package/{knowledge_base → src}/retrieval/__pycache__/context_fusion.cpython-38.pyc +0 -0
  609. /package/{knowledge_base → src}/retrieval/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  610. /package/{knowledge_base → src}/retrieval/__pycache__/knowledge_graph.cpython-38.pyc +0 -0
  611. /package/{knowledge_base → src}/retrieval/__pycache__/reranker.cpython-37.pyc +0 -0
  612. /package/{knowledge_base → src}/retrieval/__pycache__/reranker.cpython-38.pyc +0 -0
  613. /package/{knowledge_base → src}/retrieval/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  614. /package/{knowledge_base → src}/retrieval/__pycache__/retrieval_debug.cpython-38.pyc +0 -0
  615. /package/{knowledge_base → src}/retrieval/__pycache__/retriever.cpython-37.pyc +0 -0
  616. /package/{knowledge_base → src}/retrieval/__pycache__/retriever.cpython-38.pyc +0 -0
  617. /package/{knowledge_base → src}/retrieval/__pycache__/unified_query.cpython-38.pyc +0 -0
  618. /package/{knowledge_base → src}/retrieval/__pycache__/web_retriever.cpython-38.pyc +0 -0
  619. /package/{knowledge_base → src}/retrieval/retrieval_debug.py +0 -0
  620. /package/{knowledge_base → src}/validators/__init__.py +0 -0
  621. /package/{knowledge_base → src}/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  622. /package/{knowledge_base → src}/validators/__pycache__/__init__.cpython-37.pyc +0 -0
  623. /package/{knowledge_base → src}/validators/__pycache__/step_fidelity.cpython-314.pyc +0 -0
  624. /package/{knowledge_base → src}/validators/__pycache__/step_fidelity.cpython-37.pyc +0 -0
  625. /package/{knowledge_base → src}/vision/__pycache__/__init__.cpython-37.pyc +0 -0
  626. /package/{knowledge_base → src}/vision/__pycache__/__init__.cpython-38.pyc +0 -0
  627. /package/{knowledge_base → src}/vision/__pycache__/image_describer.cpython-37.pyc +0 -0
  628. /package/{knowledge_base → src}/vision/__pycache__/image_describer.cpython-38.pyc +0 -0
@@ -0,0 +1,930 @@
1
+ """Workflow CLI — Python engine invoked by Node.js MCP server and igel-qe CLI.
2
+
3
+ Action dispatch table:
4
+ plan_test_cases — Req → Understanding → Context → Scenarios → Business Rules (plan only)
5
+ generate_test_cases — Req → Understanding → Scenarios → Business Rules → Test Cases
6
+ (reuses a plan_test_cases artifact when present)
7
+ plan_automation — Approved test cases → Automation Plan (plan only, no script)
8
+ generate_automation — Approved test cases → Automation Plan → pytest script
9
+ (reuses a plan_automation artifact when present)
10
+ init_check — Read-only pre-flight connectivity checks (no side effects)
11
+ sync_from_files — Delta-index a list of changed file paths into Asset Registry
12
+ sync_from_commit — Resolve changed files for a commit, then delta-index
13
+ impact_analysis — Return requirements/scripts/assets affected by changed files
14
+ submit_feedback — Store 4-level granular feedback
15
+
16
+ Each action reads a JSON --args payload and writes a single JSON line to stdout.
17
+ """
18
+ import argparse
19
+ import json
20
+ import logging
21
+ import sys
22
+ from pathlib import Path
23
+
24
+ # Bootstrap: ensure the project root is in PYTHONPATH so that
25
+ # `src` is importable whether called via `python -m` or directly.
26
+ _PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
27
+ if str(_PROJECT_ROOT) not in sys.path:
28
+ sys.path.insert(0, str(_PROJECT_ROOT))
29
+
30
+ from src.db.igel_schema import ensure_igel_tables
31
+ from src.connectors.jira_connector import JiraConnector
32
+ from src.agents.workflow_engine import WorkflowEngine
33
+ from src.intelligence.diff_analyzer import analyze_diff_scope
34
+ from src.intelligence.routing_engine import RouteInputs, compute_weighted_score, classify_route
35
+ from src.agents.framework_analyzer_agent import FrameworkAnalyzerAgent
36
+ from src.agents.orchestrator.orchestrator import Orchestrator
37
+ from src.agents.internal.approval_manager import ApprovalError
38
+ from src.config import cfg
39
+ from src.project.context_projection_builder import ContextProjectionBuilder
40
+ from src.project.context_requirement_sync import sync_requirement_context
41
+ from src.project.context_enricher import enrich_context_files
42
+
43
+ logging.basicConfig(level=logging.ERROR) # Only output strict JSON to stdout
44
+
45
+ ALL_ACTIONS = [
46
+ "plan_test_cases",
47
+ "generate_test_cases",
48
+ "plan_automation",
49
+ "generate_automation",
50
+ "sync_from_files",
51
+ "sync_from_commit",
52
+ "impact_analysis",
53
+ "submit_feedback",
54
+ "init_project",
55
+ "init_check",
56
+ "sync_push_event",
57
+ "get_project_status",
58
+ "scaffold_ai_folder",
59
+ "analyze_framework_scope",
60
+ "project_context_cache",
61
+ "enrich_requirement_context",
62
+ "enrich_framework_context",
63
+ "update_context_file",
64
+ "record_approval",
65
+ # Legacy alias kept for MCP server backward compat — maps to sync_from_commit
66
+ "sync_bitbucket",
67
+ ]
68
+
69
+
70
+ def _ok(data: dict) -> None:
71
+ print(json.dumps({"status": "success", **data}))
72
+
73
+
74
+ def _err(message: str) -> None:
75
+ print(json.dumps({"status": "error", "message": message}))
76
+ sys.exit(1)
77
+
78
+
79
+ def _best_effort_project_context(repo_path: Path) -> dict:
80
+ """Refresh .ai/context.md without breaking the main workflow on failure."""
81
+ try:
82
+ return ContextProjectionBuilder(repo_path).build()
83
+ except Exception as e:
84
+ logging.warning("Context projection refresh skipped: %s", e)
85
+ return {
86
+ "context_path": str(repo_path / ".ai" / "context.md"),
87
+ "error": str(e),
88
+ }
89
+
90
+
91
+ def main():
92
+ parser = argparse.ArgumentParser(description="Workflow CLI for Node.js IPC")
93
+ parser.add_argument("--action", required=True, choices=ALL_ACTIONS)
94
+ parser.add_argument("--args", required=True, help="JSON arguments for the action")
95
+ args = parser.parse_args()
96
+
97
+ try:
98
+ payload = json.loads(args.args)
99
+ except json.JSONDecodeError:
100
+ _err("Invalid JSON args")
101
+
102
+ # ── DB init ────────────────────────────────────────────────────────────────
103
+ if args.action not in ("submit_feedback",):
104
+ try:
105
+ ensure_igel_tables()
106
+ except Exception as e:
107
+ _err(f"Database Init Failed: {e}")
108
+
109
+ # ── plan_test_cases ────────────────────────────────────────────────────────
110
+ if args.action == "plan_test_cases":
111
+ jira_key = payload.get("jira_key")
112
+ if not jira_key:
113
+ _err("Missing jira_key")
114
+
115
+ try:
116
+ connector = JiraConnector()
117
+ req = connector.get_test_requirement(jira_key)
118
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
119
+ orchestrator = Orchestrator(repo_path)
120
+ engine = WorkflowEngine(repo_path)
121
+ test_reqid = payload.get("test_reqid")
122
+ requirement_hash = (req.summary or "") + "|" + (req.description or "")
123
+
124
+ req, scenarios, resolved_context, source_report = engine.run_requirement_flow(req)
125
+
126
+ artifact_summary = {}
127
+ try:
128
+ from src.project.ai_folder import write_requirement_plan_artifact
129
+ artifact_summary = write_requirement_plan_artifact(
130
+ repo_root=repo_path,
131
+ jira_key=jira_key,
132
+ test_reqid=test_reqid,
133
+ scenarios_with_rules=scenarios,
134
+ resolved_context=resolved_context,
135
+ source_report=source_report,
136
+ requirement_hash=requirement_hash,
137
+ )
138
+ except Exception as e:
139
+ logging.warning("Failed to write plan artifact (non-fatal): %s", e)
140
+
141
+ governance = {
142
+ "approval_required": False,
143
+ "questions": [],
144
+ "stage": "testcase_plan",
145
+ }
146
+ if cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED:
147
+ decision = orchestrator.plan_gate(
148
+ jira_key=jira_key,
149
+ test_reqid=test_reqid,
150
+ summary=req.summary or "",
151
+ description=req.description or "",
152
+ stage="testcase_plan",
153
+ )
154
+ governance = {
155
+ "approval_required": decision.approval_required,
156
+ "questions": decision.questions,
157
+ "stage": decision.workflow,
158
+ "question_batching": True,
159
+ "sequential_questions": False,
160
+ }
161
+
162
+ _ok({
163
+ "jira_key": jira_key,
164
+ "test_reqid": test_reqid or jira_key,
165
+ "scenarios_count": len(scenarios),
166
+ "scenarios": [
167
+ {
168
+ "step": sr.scenario.action,
169
+ "business_rules": [
170
+ {"type": br.rule_type, "description": br.description}
171
+ for br in sr.business_rules
172
+ ],
173
+ }
174
+ for sr in scenarios
175
+ ],
176
+ "source_report": {
177
+ "jira_found": source_report.jira_found,
178
+ "confluence_found": source_report.confluence_found,
179
+ "postgres_kb_found": source_report.postgres_kb_found,
180
+ "igel_os12_docs_found": source_report.igel_os12_docs_found,
181
+ "conflicts": source_report.conflicts,
182
+ },
183
+ "resolved_context": {
184
+ "source": resolved_context.source,
185
+ "conflicting_sources": resolved_context.conflicting_sources,
186
+ "resolution_rationale": resolved_context.resolution_rationale,
187
+ },
188
+ "artifact": artifact_summary,
189
+ "governance": governance,
190
+ })
191
+
192
+ except ApprovalError as e:
193
+ _err(str(e))
194
+ except Exception as e:
195
+ _err(str(e))
196
+
197
+ # ── generate_test_cases ────────────────────────────────────────────────────
198
+ elif args.action == "generate_test_cases":
199
+ jira_key = payload.get("jira_key")
200
+ if not jira_key:
201
+ _err("Missing jira_key")
202
+
203
+ try:
204
+ connector = JiraConnector()
205
+ req = connector.get_test_requirement(jira_key)
206
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
207
+ orchestrator = Orchestrator(repo_path)
208
+ engine = WorkflowEngine(repo_path)
209
+ test_reqid = payload.get("test_reqid")
210
+ requirement_hash = (req.summary or "") + "|" + (req.description or "")
211
+
212
+ if cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED:
213
+ orchestrator.assert_generation_gate(
214
+ jira_key=jira_key,
215
+ test_reqid=test_reqid,
216
+ stage="testcase_plan",
217
+ )
218
+
219
+ scenarios = resolved_context = source_report = None
220
+ plan_artifact_used = False
221
+
222
+ # Enterprise routing decision (Copilot-constrained strategy mode)
223
+ route_inputs = RouteInputs(
224
+ complexity=float(payload.get("complexity_score", 0.5)),
225
+ risk=float(payload.get("risk_score", 0.5)),
226
+ context_confidence=float(payload.get("context_confidence", 0.5)),
227
+ repo_impact=float(payload.get("repository_impact", 0.5)),
228
+ historical_success=float(payload.get("historical_success", 0.5)),
229
+ )
230
+ route_score = compute_weighted_score(route_inputs)
231
+ routing_decision = {
232
+ "score": route_score,
233
+ **classify_route(route_score),
234
+ "weights": {
235
+ "complexity": 0.30,
236
+ "risk": 0.25,
237
+ "context_confidence": 0.20,
238
+ "repository_impact": 0.10,
239
+ "historical_success": 0.15,
240
+ },
241
+ }
242
+
243
+ try:
244
+ from src.models.test_requirement import ScenarioWithRules
245
+ from src.core.evidence_resolver import ResolvedContext
246
+ from src.core.context_engine import SourceReport
247
+ from src.project.ai_folder import read_plan_artifact
248
+ plan_artifact = read_plan_artifact(repo_path, jira_key, test_reqid)
249
+ if plan_artifact:
250
+ if plan_artifact.get("staleness", {}).get("requirement_hash") == requirement_hash:
251
+ scenarios = [ScenarioWithRules.model_validate(s) for s in plan_artifact.get("scenarios", [])]
252
+ resolved_context = ResolvedContext(**plan_artifact["resolved_context"])
253
+ source_report = SourceReport(**plan_artifact["source_report"])
254
+ plan_artifact_used = True
255
+ else:
256
+ logging.warning(
257
+ "Plan artifact for %s/%s is stale (requirement changed); replanning.",
258
+ jira_key, test_reqid,
259
+ )
260
+ except Exception as e:
261
+ logging.warning("Failed to read plan artifact; falling back to fresh planning: %s", e)
262
+
263
+ if not plan_artifact_used:
264
+ req, scenarios, resolved_context, source_report = engine.run_requirement_flow(req)
265
+
266
+ test_cases = engine.run_testcase_flow(req, scenarios, resolved_context, source_report)
267
+
268
+ approved = [tc for tc in test_cases if tc.is_approved]
269
+ unapproved = [
270
+ {"tc_reference": tc.test_case.tc_reference, "confidence": round(tc.confidence.total_score, 3)}
271
+ for tc in test_cases if not tc.is_approved
272
+ ]
273
+
274
+ # Persist generated/approved testcases as .ai artifacts for script-generation reuse
275
+ artifact_summary = {}
276
+ try:
277
+ from src.project.ai_folder import write_testcase_artifacts
278
+ artifact_summary = write_testcase_artifacts(
279
+ repo_root=repo_path,
280
+ jira_key=jira_key,
281
+ test_reqid=test_reqid,
282
+ generated_cases=test_cases,
283
+ approved_cases=approved,
284
+ requirement_hash=requirement_hash,
285
+ )
286
+ except Exception as e:
287
+ logging.warning("Failed to write testcase artifacts (non-fatal): %s", e)
288
+
289
+ _ok({
290
+ "jira_key": jira_key,
291
+ "total_cases": len(test_cases),
292
+ "approved_cases": len(approved),
293
+ "unapproved_cases": unapproved,
294
+ "scenarios_count": len(scenarios),
295
+ "plan_artifact_used": plan_artifact_used,
296
+ "routing_decision": routing_decision,
297
+ "artifact": artifact_summary,
298
+ "governance": {
299
+ "stage": "testcase_plan",
300
+ "approval_checked": bool(cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED),
301
+ },
302
+ "context_projection": _best_effort_project_context(repo_path),
303
+ })
304
+
305
+ except Exception as e:
306
+ _err(str(e))
307
+
308
+ # ── plan_automation ────────────────────────────────────────────────────────
309
+ elif args.action == "plan_automation":
310
+ jira_key = payload.get("jira_key")
311
+ if not jira_key:
312
+ _err("Missing jira_key")
313
+
314
+ try:
315
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
316
+ orchestrator = Orchestrator(repo_path)
317
+ test_reqid = payload.get("test_reqid")
318
+
319
+ from src.models.test_requirement import TestCaseWithConfidence
320
+ from src.project.ai_folder import (
321
+ read_approved_testcase_artifact,
322
+ write_automation_plan_artifact,
323
+ compute_cases_content_hash,
324
+ )
325
+ from src.agents.automation_design_agent import design_automation_plan
326
+
327
+ artifact = read_approved_testcase_artifact(repo_path, jira_key, test_reqid)
328
+ cases = artifact.get("cases", []) if isinstance(artifact, dict) else []
329
+
330
+ if cases:
331
+ approved = [TestCaseWithConfidence.model_validate(c) for c in cases]
332
+ else:
333
+ # No approved-testcase artifact yet — fall back to the full
334
+ # req->testcase pipeline (mirrors generate_automation's existing
335
+ # fallback), stopping short of script generation.
336
+ connector = JiraConnector()
337
+ req = connector.get_test_requirement(jira_key)
338
+ engine = WorkflowEngine(repo_path)
339
+ req, scenarios, resolved_context, source_report = engine.run_requirement_flow(req)
340
+ test_cases = engine.run_testcase_flow(req, scenarios, resolved_context, source_report)
341
+ approved = [tc for tc in test_cases if tc.is_approved]
342
+ if not approved:
343
+ _ok({
344
+ "jira_key": jira_key,
345
+ "plan_generated": False,
346
+ "message": "No test cases met the confidence threshold (>=0.80); nothing to plan automation for.",
347
+ })
348
+ return
349
+
350
+ plan = design_automation_plan(approved)
351
+ approved_content_hash = compute_cases_content_hash(approved)
352
+
353
+ artifact_summary = write_automation_plan_artifact(
354
+ repo_root=repo_path,
355
+ jira_key=jira_key,
356
+ test_reqid=test_reqid,
357
+ plan=plan,
358
+ approved_content_hash=approved_content_hash,
359
+ )
360
+
361
+ governance = {
362
+ "approval_required": False,
363
+ "questions": [],
364
+ "stage": "automation_plan",
365
+ }
366
+ if cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED:
367
+ decision = orchestrator.plan_gate(
368
+ jira_key=jira_key,
369
+ test_reqid=test_reqid,
370
+ summary=f"Automation plan for {jira_key}",
371
+ description="",
372
+ stage="automation_plan",
373
+ )
374
+ governance = {
375
+ "approval_required": decision.approval_required,
376
+ "questions": decision.questions,
377
+ "stage": decision.workflow,
378
+ "question_batching": True,
379
+ "sequential_questions": False,
380
+ }
381
+
382
+ _ok({
383
+ "jira_key": jira_key,
384
+ "test_reqid": test_reqid or jira_key,
385
+ "page_objects": plan.page_objects,
386
+ "fixtures": plan.fixtures,
387
+ "utilities": plan.utilities,
388
+ "approved_cases_considered": len(approved),
389
+ "artifact": artifact_summary,
390
+ "governance": governance,
391
+ })
392
+ except Exception as e:
393
+ _err(str(e))
394
+
395
+ # ── generate_automation ────────────────────────────────────────────────────
396
+ # NOTE: Confidence gate is intentionally respected here.
397
+ # Only test cases with is_approved=True (confidence >= 0.80) are scripted.
398
+ # Unapproved TCs are returned in the response so engineers know what needs review.
399
+ elif args.action == "generate_automation":
400
+ jira_key = payload.get("jira_key")
401
+ if not jira_key:
402
+ _err("Missing jira_key")
403
+
404
+ try:
405
+ connector = JiraConnector()
406
+ req = connector.get_test_requirement(jira_key)
407
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
408
+ orchestrator = Orchestrator(repo_path)
409
+ output_dir = Path(payload.get("output_dir", str(repo_path / "tests")))
410
+ engine = WorkflowEngine(repo_path)
411
+ test_reqid = payload.get("test_reqid")
412
+
413
+ if cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED:
414
+ orchestrator.assert_generation_gate(
415
+ jira_key=jira_key,
416
+ test_reqid=test_reqid,
417
+ stage="automation_plan",
418
+ )
419
+
420
+ approved = []
421
+ unapproved = []
422
+ artifact_used = False
423
+
424
+ # Enterprise routing decision (Copilot-constrained strategy mode)
425
+ route_inputs = RouteInputs(
426
+ complexity=float(payload.get("complexity_score", 0.5)),
427
+ risk=float(payload.get("risk_score", 0.5)),
428
+ context_confidence=float(payload.get("context_confidence", 0.5)),
429
+ repo_impact=float(payload.get("repository_impact", 0.5)),
430
+ historical_success=float(payload.get("historical_success", 0.5)),
431
+ )
432
+ route_score = compute_weighted_score(route_inputs)
433
+ routing_decision = {
434
+ "score": route_score,
435
+ **classify_route(route_score),
436
+ "weights": {
437
+ "complexity": 0.30,
438
+ "risk": 0.25,
439
+ "context_confidence": 0.20,
440
+ "repository_impact": 0.10,
441
+ "historical_success": 0.15,
442
+ },
443
+ }
444
+
445
+ # Artifact-first: consume approved testcase artifact when present
446
+ try:
447
+ from src.models.test_requirement import TestCaseWithConfidence
448
+ from src.project.ai_folder import read_approved_testcase_artifact
449
+ artifact = read_approved_testcase_artifact(repo_path, jira_key, test_reqid)
450
+ cases = artifact.get("cases", []) if isinstance(artifact, dict) else []
451
+ if cases:
452
+ approved = [TestCaseWithConfidence.model_validate(c) for c in cases]
453
+ artifact_used = True
454
+ except Exception as e:
455
+ logging.warning("Failed to read approved testcase artifact; falling back to regeneration: %s", e)
456
+
457
+ # Fallback path: regenerate cases, then enforce confidence gate
458
+ if not approved:
459
+ req, scenarios, resolved_context, source_report = engine.run_requirement_flow(req)
460
+ test_cases = engine.run_testcase_flow(req, scenarios, resolved_context, source_report)
461
+
462
+ approved = [tc for tc in test_cases if tc.is_approved]
463
+ unapproved = [
464
+ {"tc_reference": tc.test_case.tc_reference, "confidence": round(tc.confidence.total_score, 3)}
465
+ for tc in test_cases if not tc.is_approved
466
+ ]
467
+
468
+ if not approved:
469
+ _ok({
470
+ "jira_key": jira_key,
471
+ "script_generated": False,
472
+ "approved_cases": 0,
473
+ "unapproved_cases": unapproved,
474
+ "message": "No test cases met the confidence threshold (>=0.80). Review unapproved_cases.",
475
+ })
476
+ return
477
+
478
+ # Automation-plan artifact-first: reuse a persisted AutomationPlan if it
479
+ # matches the exact approved test cases we're about to script.
480
+ from src.project.ai_folder import (
481
+ read_automation_plan_artifact,
482
+ write_automation_plan_artifact,
483
+ compute_cases_content_hash,
484
+ )
485
+ from src.agents.automation_design_agent import AutomationPlan
486
+
487
+ approved_content_hash = compute_cases_content_hash(approved)
488
+ automation_plan = None
489
+ automation_plan_used = False
490
+ try:
491
+ plan_artifact = read_automation_plan_artifact(repo_path, jira_key, test_reqid)
492
+ if plan_artifact and plan_artifact.get("staleness", {}).get("approved_content_hash") == approved_content_hash:
493
+ automation_plan = AutomationPlan.model_validate(plan_artifact["plan"])
494
+ automation_plan_used = True
495
+ except Exception as e:
496
+ logging.warning("Failed to read automation plan artifact; will design fresh: %s", e)
497
+
498
+ output_script = output_dir / f"test_{jira_key.replace('-', '_').lower()}.py"
499
+ ok, msg, used_plan = engine.run_script_flow(req, approved, output_script, plan=automation_plan)
500
+
501
+ if ok and not automation_plan_used and used_plan is not None:
502
+ try:
503
+ write_automation_plan_artifact(
504
+ repo_root=repo_path, jira_key=jira_key, test_reqid=test_reqid,
505
+ plan=used_plan, approved_content_hash=approved_content_hash,
506
+ )
507
+ except Exception as e:
508
+ logging.warning("Failed to persist automation plan artifact (non-fatal): %s", e)
509
+
510
+ if ok:
511
+ _ok({
512
+ "jira_key": jira_key,
513
+ "script_generated": True,
514
+ "script_path": str(output_script),
515
+ "approved_cases": len(approved),
516
+ "unapproved_cases": unapproved,
517
+ "artifact_used": artifact_used,
518
+ "automation_plan_used": automation_plan_used,
519
+ "routing_decision": routing_decision,
520
+ "governance": {
521
+ "stage": "automation_plan",
522
+ "approval_checked": bool(cfg.V2_ORCHESTRATOR_ENABLED or cfg.V2_GOVERNANCE_ENFORCED or cfg.V2_APPROVAL_MANAGER_ENABLED),
523
+ },
524
+ "context_projection": _best_effort_project_context(repo_path),
525
+ })
526
+ else:
527
+ _err(msg)
528
+
529
+ except ApprovalError as e:
530
+ _err(str(e))
531
+ except Exception as e:
532
+ _err(str(e))
533
+
534
+ # ── record_approval ───────────────────────────────────────────────────────
535
+ elif args.action == "record_approval":
536
+ jira_key = payload.get("jira_key")
537
+ stage = payload.get("stage")
538
+ decision = payload.get("decision")
539
+ actor = payload.get("actor")
540
+ test_reqid = payload.get("test_reqid")
541
+ reason = payload.get("reason")
542
+
543
+ if not jira_key:
544
+ _err("Missing jira_key")
545
+ if not stage:
546
+ _err("Missing stage")
547
+ if not decision:
548
+ _err("Missing decision")
549
+ if not actor:
550
+ _err("Missing actor")
551
+
552
+ try:
553
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
554
+ from src.agents.internal.approval_manager import ApprovalManager
555
+
556
+ manager = ApprovalManager(repo_path)
557
+ record = manager.record_decision(
558
+ jira_key=jira_key,
559
+ stage=stage,
560
+ decision=decision,
561
+ actor=actor,
562
+ reason=reason,
563
+ test_reqid=test_reqid,
564
+ )
565
+ _ok({
566
+ "jira_key": jira_key,
567
+ "stage": stage,
568
+ "approval": record,
569
+ })
570
+ except ApprovalError as e:
571
+ _err(str(e))
572
+ except Exception as e:
573
+ _err(str(e))
574
+
575
+ # ── sync_from_files ────────────────────────────────────────────────────────
576
+ # Accepts: { "changed_files": ["path/to/file.py", ...], "repo_path": "..." }
577
+ elif args.action == "sync_from_files":
578
+ changed_files = payload.get("changed_files")
579
+ if not changed_files or not isinstance(changed_files, list):
580
+ _err("Missing or invalid changed_files list (must be list of path strings)")
581
+
582
+ try:
583
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
584
+ analyzer = FrameworkAnalyzerAgent(repo_path)
585
+ file_paths = [Path(f) for f in changed_files]
586
+
587
+ # Diff Analyzer first: build impacted scope before framework indexing.
588
+ diff_scope = analyze_diff_scope(repo_path, file_paths)
589
+ analysis_targets = [
590
+ repo_path / p for p in diff_scope.get("analysis_targets", [])
591
+ if (repo_path / p).exists()
592
+ ]
593
+ analysis_result = analyzer.analyze_scope(analysis_targets)
594
+ _ok({
595
+ "files_indexed": analysis_result["indexed_assets"],
596
+ "changed_files_count": len(file_paths),
597
+ "analysis_targets_count": analysis_result["analysis_targets_count"],
598
+ "diff_scope": diff_scope,
599
+ "framework_analysis": analysis_result,
600
+ "context_projection": _best_effort_project_context(repo_path),
601
+ })
602
+ except Exception as e:
603
+ _err(str(e))
604
+
605
+ # ── sync_from_commit ───────────────────────────────────────────────────────
606
+ # Accepts: { "commit_hash": "abc123", "repo_slug": "...", "workspace": "..." }
607
+ elif args.action in ("sync_from_commit", "sync_bitbucket"):
608
+ commit_hash = payload.get("commit_hash")
609
+ if not commit_hash:
610
+ _err("Missing commit_hash")
611
+
612
+ try:
613
+ from src.connectors.bitbucket_connector import BitbucketConnector
614
+ connector = BitbucketConnector()
615
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
616
+ analyzer = FrameworkAnalyzerAgent(repo_path)
617
+ repo_slug = payload.get("repo_slug", "")
618
+ workspace = payload.get("workspace", "")
619
+
620
+ # Fetch changed files from Bitbucket API
621
+ file_diffs = connector.fetch_file_locs(repo_slug, commit_hash, workspace)
622
+ changed_paths = [Path(f["file_path"]) for f in file_diffs]
623
+
624
+ # Diff Analyzer first, then scope-limited delta sync.
625
+ local_changed = [repo_path / p for p in changed_paths if (repo_path / p).exists()]
626
+ diff_scope = analyze_diff_scope(repo_path, local_changed)
627
+ analysis_targets = [
628
+ repo_path / p for p in diff_scope.get("analysis_targets", [])
629
+ if (repo_path / p).exists()
630
+ ]
631
+ analysis_result = analyzer.analyze_scope(analysis_targets)
632
+
633
+ _ok({
634
+ "synced_commit": commit_hash,
635
+ "files_found": len(file_diffs),
636
+ "files_indexed": analysis_result["indexed_assets"],
637
+ "analysis_targets_count": analysis_result["analysis_targets_count"],
638
+ "changed_files": [str(p) for p in changed_paths],
639
+ "diff_scope": diff_scope,
640
+ "framework_analysis": analysis_result,
641
+ "context_projection": _best_effort_project_context(repo_path),
642
+ })
643
+ except Exception as e:
644
+ _err(str(e))
645
+
646
+ # ── analyze_framework_scope ───────────────────────────────────────────────
647
+ # Accepts: { "changed_files": [...], "repo_path": "..." }
648
+ elif args.action == "analyze_framework_scope":
649
+ changed_files = payload.get("changed_files")
650
+ if not changed_files or not isinstance(changed_files, list):
651
+ _err("Missing or invalid changed_files list")
652
+
653
+ try:
654
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
655
+ analyzer = FrameworkAnalyzerAgent(repo_path)
656
+ file_paths = [Path(f) for f in changed_files]
657
+ diff_scope = analyze_diff_scope(repo_path, file_paths)
658
+ analysis_targets = [
659
+ repo_path / p for p in diff_scope.get("analysis_targets", [])
660
+ if (repo_path / p).exists()
661
+ ]
662
+ analysis_result = analyzer.analyze_scope(analysis_targets)
663
+ _ok({
664
+ "changed_files_count": len(file_paths),
665
+ "diff_scope": diff_scope,
666
+ "framework_analysis": analysis_result,
667
+ })
668
+ except Exception as e:
669
+ _err(str(e))
670
+
671
+ # ── project_context_cache ─────────────────────────────────────────────────
672
+ # Accepts: { "repo_path": "..." }
673
+ elif args.action == "project_context_cache":
674
+ try:
675
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
676
+ builder = ContextProjectionBuilder(repo_path)
677
+ result = builder.build()
678
+ _ok(result)
679
+ except Exception as e:
680
+ _err(str(e))
681
+
682
+ # ── enrich_requirement_context ───────────────────────────────────────────
683
+ # Accepts: {
684
+ # "jira_key": "QCL-1762",
685
+ # "context_text": "...",
686
+ # "changed_files": ["tests/...", ...],
687
+ # "repo_path": "..."
688
+ # }
689
+ elif args.action == "enrich_requirement_context":
690
+ jira_key = payload.get("jira_key")
691
+ context_text = payload.get("context_text")
692
+ if not jira_key:
693
+ _err("Missing jira_key")
694
+ if not context_text or not str(context_text).strip():
695
+ _err("Missing context_text")
696
+
697
+ try:
698
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
699
+ changed_files = payload.get("changed_files")
700
+ if changed_files is not None and not isinstance(changed_files, list):
701
+ _err("Invalid changed_files: must be a list of file paths")
702
+
703
+ result = sync_requirement_context(
704
+ repo_root=repo_path,
705
+ jira_key=jira_key,
706
+ context_text=str(context_text),
707
+ changed_files=changed_files,
708
+ )
709
+
710
+ _ok({
711
+ "jira_key": result.jira_key,
712
+ "requirement_id": result.requirement_id,
713
+ "affected_files": result.affected_files,
714
+ "affected_files_count": len(result.affected_files),
715
+ "mapped_assets": result.mapped_assets,
716
+ "requirement_context_path": result.requirement_context_path,
717
+ "context_projection": result.projection,
718
+ })
719
+ except Exception as e:
720
+ _err(str(e))
721
+
722
+ # ── enrich_framework_context ────────────────────────────────────────────
723
+ # Accepts: {
724
+ # "repo_path": "...",
725
+ # "context_paths": ["tests/context.md", ...],
726
+ # "changed_files": ["tests/e2e/test_login.py", ...],
727
+ # "persist_only": true
728
+ # }
729
+ elif args.action == "enrich_framework_context":
730
+ try:
731
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
732
+ context_paths = payload.get("context_paths")
733
+ changed_files = payload.get("changed_files")
734
+ persist_only = bool(payload.get("persist_only", False))
735
+
736
+ if context_paths is not None and not isinstance(context_paths, list):
737
+ _err("Invalid context_paths: must be a list of context.md paths")
738
+ if changed_files is not None and not isinstance(changed_files, list):
739
+ _err("Invalid changed_files: must be a list of file paths")
740
+
741
+ framework_analysis = None
742
+ if changed_files:
743
+ analyzer = FrameworkAnalyzerAgent(repo_path)
744
+ file_paths = [Path(f) for f in changed_files]
745
+ diff_scope = analyze_diff_scope(repo_path, file_paths)
746
+ analysis_targets = [
747
+ repo_path / p for p in diff_scope.get("analysis_targets", [])
748
+ if (repo_path / p).exists()
749
+ ]
750
+ framework_analysis = {
751
+ "diff_scope": diff_scope,
752
+ "analysis": analyzer.analyze_scope(analysis_targets),
753
+ }
754
+
755
+ enriched = enrich_context_files(
756
+ repo_path,
757
+ context_paths=context_paths,
758
+ rewrite_files=not persist_only,
759
+ )
760
+ projection = _best_effort_project_context(repo_path)
761
+
762
+ _ok({
763
+ "enriched_count": len(enriched),
764
+ "enriched": [
765
+ {
766
+ "path": r.path,
767
+ "folder": r.folder,
768
+ "files_scanned": r.files_scanned,
769
+ "python_files": r.python_files,
770
+ "dependency_edges": r.dependency_edges,
771
+ "key_assets": r.key_assets,
772
+ }
773
+ for r in enriched
774
+ ],
775
+ "framework_analysis": framework_analysis,
776
+ "persist_only": persist_only,
777
+ "context_projection": projection,
778
+ })
779
+ except Exception as e:
780
+ _err(str(e))
781
+
782
+ # ── update_context_file ─────────────────────────────────────────────────
783
+ # Accepts: {
784
+ # "context_path": "tests/e2e/context.md",
785
+ # "repo_path": "...",
786
+ # "changed_files": ["tests/e2e/test_login.py"]
787
+ # }
788
+ elif args.action == "update_context_file":
789
+ context_path = payload.get("context_path")
790
+ if not context_path:
791
+ _err("Missing context_path")
792
+
793
+ try:
794
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
795
+ changed_files = payload.get("changed_files")
796
+ if changed_files is not None and not isinstance(changed_files, list):
797
+ _err("Invalid changed_files: must be a list of file paths")
798
+
799
+ framework_analysis = None
800
+ if changed_files:
801
+ analyzer = FrameworkAnalyzerAgent(repo_path)
802
+ file_paths = [Path(f) for f in changed_files]
803
+ diff_scope = analyze_diff_scope(repo_path, file_paths)
804
+ analysis_targets = [
805
+ repo_path / p for p in diff_scope.get("analysis_targets", [])
806
+ if (repo_path / p).exists()
807
+ ]
808
+ framework_analysis = {
809
+ "diff_scope": diff_scope,
810
+ "analysis": analyzer.analyze_scope(analysis_targets),
811
+ }
812
+
813
+ enriched = enrich_context_files(repo_path, context_paths=[str(context_path)])
814
+ if not enriched:
815
+ _err(f"No context.md file found for context_path: {context_path}")
816
+
817
+ projection = _best_effort_project_context(repo_path)
818
+ first = enriched[0]
819
+ _ok({
820
+ "updated": {
821
+ "path": first.path,
822
+ "folder": first.folder,
823
+ "files_scanned": first.files_scanned,
824
+ "python_files": first.python_files,
825
+ "dependency_edges": first.dependency_edges,
826
+ "key_assets": first.key_assets,
827
+ },
828
+ "framework_analysis": framework_analysis,
829
+ "context_projection": projection,
830
+ })
831
+ except Exception as e:
832
+ _err(str(e))
833
+
834
+ # ── impact_analysis ────────────────────────────────────────────────────────
835
+ # Accepts: { "changed_files": ["path/to/file.py", ...], "repo_path": "..." }
836
+ elif args.action == "impact_analysis":
837
+ changed_files = payload.get("changed_files")
838
+ if not changed_files or not isinstance(changed_files, list):
839
+ _err("Missing or invalid changed_files list")
840
+
841
+ try:
842
+ from src.agents.regression_agent import RegressionAgent
843
+ repo_path = Path(payload.get("repo_path", str(Path.cwd())))
844
+ changed_paths = [Path(f) for f in changed_files]
845
+ agent = RegressionAgent()
846
+ impact = agent.analyze_impact(changed_paths, repo_path)
847
+ _ok({"impact": impact})
848
+ except Exception as e:
849
+ _err(str(e))
850
+
851
+ # ── submit_feedback ────────────────────────────────────────────────────────
852
+ elif args.action == "submit_feedback":
853
+ level = payload.get("level")
854
+ target_id = payload.get("target_id")
855
+ feedback_type = payload.get("feedback_type")
856
+ user_comment = payload.get("user_comment", "")
857
+
858
+ if not all([level, target_id, feedback_type]):
859
+ _err("Missing required fields: level, target_id, feedback_type")
860
+
861
+ try:
862
+ from src.agents.feedback_agent import FeedbackAgent
863
+ agent = FeedbackAgent()
864
+ stored = agent.submit(
865
+ level=level,
866
+ target_id=target_id,
867
+ feedback_type=feedback_type,
868
+ user_comment=user_comment,
869
+ corrected_data=payload.get("corrected_data"),
870
+ )
871
+ _ok({"stored": stored, "target_id": target_id, "level": level})
872
+ except Exception as e:
873
+ _err(str(e))
874
+
875
+ # ── init_project / init_check ─────────────────────────────────────────────
876
+ # Both are read-only pre-flight connectivity checks — no side effects (no scaffolding).
877
+ elif args.action in ("init_project", "init_check"):
878
+ try:
879
+ from src.project.init_check import run_checks
880
+ checks = run_checks()
881
+ _ok(checks)
882
+ except Exception as e:
883
+ _err(str(e))
884
+
885
+ # ── scaffold_ai_folder ─────────────────────────────────────────────────────
886
+ elif args.action == "scaffold_ai_folder":
887
+ repo_path = Path(payload.get("repo_path") or _PROJECT_ROOT)
888
+ try:
889
+ from src.project.ai_folder import scaffold_ai_folder, detect_repo_root
890
+ root = detect_repo_root(repo_path)
891
+ scaffold_ai_folder(root)
892
+ _ok({"scaffolded": str(root / ".ai")})
893
+ except Exception as e:
894
+ _err(str(e))
895
+
896
+ # ── sync_push_event ────────────────────────────────────────────────────────
897
+ elif args.action == "sync_push_event":
898
+ webhook_payload = payload.get("payload")
899
+ signature = payload.get("signature")
900
+ if not webhook_payload:
901
+ _err("Missing required field: payload (Bitbucket webhook body)")
902
+ try:
903
+ from src.connectors.bitbucket_connector import BitbucketConnector
904
+ connector = BitbucketConnector()
905
+ # Optional HMAC signature validation
906
+ if signature:
907
+ import json as _json
908
+ raw_body = _json.dumps(webhook_payload).encode()
909
+ if not connector.validate_webhook_signature(raw_body, signature):
910
+ _err("Webhook signature validation failed")
911
+ result = connector.sync_pull_event(webhook_payload)
912
+ _ok(result if isinstance(result, dict) else {"result": str(result)})
913
+ except Exception as e:
914
+ _err(str(e))
915
+
916
+ # ── get_project_status ─────────────────────────────────────────────────────
917
+ elif args.action == "get_project_status":
918
+ repo_path = Path(payload.get("repo_path") or _PROJECT_ROOT)
919
+ try:
920
+ from src.project.ai_folder import rebuild_system_state_from_db, detect_repo_root
921
+ root = detect_repo_root(repo_path)
922
+ summary = rebuild_system_state_from_db(root)
923
+ _ok(summary)
924
+ except Exception as e:
925
+ _err(str(e))
926
+
927
+
928
+ if __name__ == "__main__":
929
+ main()
930
+