alysis-code 0.13.0__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 (458) hide show
  1. alysis_code/__init__.py +3 -0
  2. alysis_code/__main__.py +4 -0
  3. alysis_code/_build_info.py +14 -0
  4. alysis_code/account_login.py +468 -0
  5. alysis_code/agent/README.md +35 -0
  6. alysis_code/agent/__init__.py +11 -0
  7. alysis_code/agent/acceptance_contract.py +2217 -0
  8. alysis_code/agent/blast_radius.py +1403 -0
  9. alysis_code/agent/cache_keepalive.py +227 -0
  10. alysis_code/agent/completion_certificate.py +366 -0
  11. alysis_code/agent/completion_gate.py +306 -0
  12. alysis_code/agent/empty_response_stall.py +403 -0
  13. alysis_code/agent/errors.py +28 -0
  14. alysis_code/agent/llm_calls.py +475 -0
  15. alysis_code/agent/mutation_classification.py +227 -0
  16. alysis_code/agent/prompt_context.py +2508 -0
  17. alysis_code/agent/read_ledger.py +253 -0
  18. alysis_code/agent/regression_baseline.py +642 -0
  19. alysis_code/agent/reproduction_first.py +610 -0
  20. alysis_code/agent/sensitive_output.py +629 -0
  21. alysis_code/agent/session.py +3218 -0
  22. alysis_code/agent/steering.py +191 -0
  23. alysis_code/agent/subagent_execution.py +5177 -0
  24. alysis_code/agent/subagent_workspace.py +666 -0
  25. alysis_code/agent/tools_assembly.py +4728 -0
  26. alysis_code/agent/turn/__init__.py +101 -0
  27. alysis_code/agent/turn/core.py +8483 -0
  28. alysis_code/agent/turn/events.py +113 -0
  29. alysis_code/agent/turn/exploration.py +590 -0
  30. alysis_code/agent/turn/interventions.py +65 -0
  31. alysis_code/agent/turn/read_cache.py +420 -0
  32. alysis_code/agent/turn/snapshot.py +179 -0
  33. alysis_code/agent/turn_contract.py +661 -0
  34. alysis_code/agent/turn_path.py +129 -0
  35. alysis_code/agent/verification.py +2885 -0
  36. alysis_code/agent/verification_commands.py +512 -0
  37. alysis_code/agent/verification_evidence.py +738 -0
  38. alysis_code/agent_loop.py +693 -0
  39. alysis_code/agent_runtimes/__init__.py +51 -0
  40. alysis_code/agent_runtimes/base.py +114 -0
  41. alysis_code/agent_runtimes/builtins.py +129 -0
  42. alysis_code/agent_runtimes/codex_cli.py +664 -0
  43. alysis_code/agent_runtimes/host.py +263 -0
  44. alysis_code/agent_runtimes/registry.py +64 -0
  45. alysis_code/agent_runtimes/service.py +150 -0
  46. alysis_code/agentbox_client.py +416 -0
  47. alysis_code/agentbox_integration.py +310 -0
  48. alysis_code/alysis_cloud.py +152 -0
  49. alysis_code/approval_scope.py +276 -0
  50. alysis_code/assets/README.md +33 -0
  51. alysis_code/assets/__init__.py +126 -0
  52. alysis_code/assets/asset_read_core.py +281 -0
  53. alysis_code/assets/budget_allocator.py +456 -0
  54. alysis_code/assets/comprehender.py +759 -0
  55. alysis_code/assets/index.py +654 -0
  56. alysis_code/assets/ingestion.py +275 -0
  57. alysis_code/assets/legacy_migration.py +413 -0
  58. alysis_code/assets/models.py +263 -0
  59. alysis_code/assets/ocr.py +239 -0
  60. alysis_code/assets/owl/ascii/f-000.txt +13 -0
  61. alysis_code/assets/owl/ascii/f-001.txt +13 -0
  62. alysis_code/assets/owl/ascii/f-002.txt +13 -0
  63. alysis_code/assets/owl/ascii/f-003.txt +13 -0
  64. alysis_code/assets/owl/ascii/f-004.txt +13 -0
  65. alysis_code/assets/owl/ascii/f-005.txt +13 -0
  66. alysis_code/assets/owl/ascii/f-006.txt +13 -0
  67. alysis_code/assets/owl/ascii/f-007.txt +13 -0
  68. alysis_code/assets/owl/ascii/f-008.txt +13 -0
  69. alysis_code/assets/owl/ascii/f-009.txt +13 -0
  70. alysis_code/assets/owl/ascii/f-010.txt +13 -0
  71. alysis_code/assets/owl/ascii/f-011.txt +13 -0
  72. alysis_code/assets/owl/ascii/f-012.txt +13 -0
  73. alysis_code/assets/owl/ascii/f-013.txt +13 -0
  74. alysis_code/assets/owl/ascii/f-014.txt +13 -0
  75. alysis_code/assets/owl/ascii/f-015.txt +13 -0
  76. alysis_code/assets/owl/ascii/f-016.txt +13 -0
  77. alysis_code/assets/owl/ascii/f-017.txt +13 -0
  78. alysis_code/assets/owl/ascii/f-018.txt +13 -0
  79. alysis_code/assets/owl/ascii/f-019.txt +13 -0
  80. alysis_code/assets/owl/ascii/f-020.txt +13 -0
  81. alysis_code/assets/owl/index.html +98 -0
  82. alysis_code/assets/owl/show-owl.sh +761 -0
  83. alysis_code/assets/paths.py +49 -0
  84. alysis_code/assets/plan_binding.py +326 -0
  85. alysis_code/assets/planner_context.py +466 -0
  86. alysis_code/assets/planner_tools.py +184 -0
  87. alysis_code/assets/prompts.py +101 -0
  88. alysis_code/assets/replanner_context.py +239 -0
  89. alysis_code/assets/surface.py +521 -0
  90. alysis_code/assets/untrusted_content.py +48 -0
  91. alysis_code/assets/usage_logger.py +94 -0
  92. alysis_code/assets/worker_mirror.py +428 -0
  93. alysis_code/assets/worker_section.py +303 -0
  94. alysis_code/assets/worker_tools.py +468 -0
  95. alysis_code/atomic_io.py +83 -0
  96. alysis_code/auth_diagnostics.py +272 -0
  97. alysis_code/background_runner.py +366 -0
  98. alysis_code/branding.py +270 -0
  99. alysis_code/budget_policy.py +390 -0
  100. alysis_code/build_identity.py +465 -0
  101. alysis_code/builtin_hooks/__init__.py +7 -0
  102. alysis_code/builtin_hooks/notify_done_windows.py +65 -0
  103. alysis_code/bwrap_etc.py +76 -0
  104. alysis_code/cancellation.py +41 -0
  105. alysis_code/capabilities.py +137 -0
  106. alysis_code/chatgpt_codex_static_provider.py +133 -0
  107. alysis_code/cli.py +51 -0
  108. alysis_code/cli_impl/__init__.py +1 -0
  109. alysis_code/cli_impl/assets_cli.py +537 -0
  110. alysis_code/cli_impl/assets_modal.py +412 -0
  111. alysis_code/cli_impl/chat/__init__.py +156 -0
  112. alysis_code/cli_impl/chat/commands.py +2616 -0
  113. alysis_code/cli_impl/chat/loop.py +4508 -0
  114. alysis_code/cli_impl/chat/mid_turn_policy.py +125 -0
  115. alysis_code/cli_impl/chat/rendering.py +444 -0
  116. alysis_code/cli_impl/chat/state.py +124 -0
  117. alysis_code/cli_impl/chat_resume.py +830 -0
  118. alysis_code/cli_impl/chat_slash_completer.py +258 -0
  119. alysis_code/cli_impl/commands/__init__.py +11 -0
  120. alysis_code/cli_impl/commands/_shared.py +89 -0
  121. alysis_code/cli_impl/commands/auth.py +623 -0
  122. alysis_code/cli_impl/commands/chat_resume_helpers.py +1531 -0
  123. alysis_code/cli_impl/commands/chat_state.py +158 -0
  124. alysis_code/cli_impl/commands/chat_status.py +1248 -0
  125. alysis_code/cli_impl/commands/chat_terminal.py +942 -0
  126. alysis_code/cli_impl/commands/chat_tui_panels.py +1018 -0
  127. alysis_code/cli_impl/commands/cli_common.py +1223 -0
  128. alysis_code/cli_impl/commands/cli_surface.py +77 -0
  129. alysis_code/cli_impl/commands/config.py +131 -0
  130. alysis_code/cli_impl/commands/conventions.py +85 -0
  131. alysis_code/cli_impl/commands/execution_helpers.py +350 -0
  132. alysis_code/cli_impl/commands/extensions.py +401 -0
  133. alysis_code/cli_impl/commands/forge.py +1282 -0
  134. alysis_code/cli_impl/commands/forge_asset_view.py +121 -0
  135. alysis_code/cli_impl/commands/forge_helpers.py +1215 -0
  136. alysis_code/cli_impl/commands/hooks.py +737 -0
  137. alysis_code/cli_impl/commands/ide_bridge.py +31 -0
  138. alysis_code/cli_impl/commands/mcp.py +700 -0
  139. alysis_code/cli_impl/commands/profile.py +453 -0
  140. alysis_code/cli_impl/commands/prompt_helpers.py +307 -0
  141. alysis_code/cli_impl/commands/report.py +88 -0
  142. alysis_code/cli_impl/commands/root.py +1118 -0
  143. alysis_code/cli_impl/commands/sandbox.py +184 -0
  144. alysis_code/cli_impl/commands/server.py +54 -0
  145. alysis_code/cli_impl/commands/sessions.py +252 -0
  146. alysis_code/cli_impl/commands/skills.py +404 -0
  147. alysis_code/cli_impl/commands/startup.py +946 -0
  148. alysis_code/cli_impl/commands/tools.py +335 -0
  149. alysis_code/cli_impl/commands/update.py +364 -0
  150. alysis_code/cli_impl/commands/welcome.py +972 -0
  151. alysis_code/cli_impl/config_menu.py +3882 -0
  152. alysis_code/cli_impl/forge.py +4509 -0
  153. alysis_code/cli_impl/forge_recovery.py +485 -0
  154. alysis_code/cli_impl/setup_wizard.py +2409 -0
  155. alysis_code/cli_impl/tui/__init__.py +58 -0
  156. alysis_code/cli_impl/tui/app.py +4551 -0
  157. alysis_code/cli_impl/tui/config.py +32 -0
  158. alysis_code/cli_impl/tui/config_flow.py +2754 -0
  159. alysis_code/cli_impl/tui/config_overlay.py +566 -0
  160. alysis_code/cli_impl/tui/content.py +78 -0
  161. alysis_code/cli_impl/tui/footer.py +218 -0
  162. alysis_code/cli_impl/tui/forge_status.py +136 -0
  163. alysis_code/cli_impl/tui/markdown.py +244 -0
  164. alysis_code/cli_impl/tui/owl.py +109 -0
  165. alysis_code/cli_impl/tui/plan_meta.py +477 -0
  166. alysis_code/cli_impl/tui/setup_app.py +519 -0
  167. alysis_code/cli_impl/tui/setup_flow.py +1622 -0
  168. alysis_code/cli_impl/tui/state.py +101 -0
  169. alysis_code/cli_impl/tui/subagent_identity.py +66 -0
  170. alysis_code/cli_impl/tui/subagent_panel.py +186 -0
  171. alysis_code/cli_impl/tui/surface.py +796 -0
  172. alysis_code/cli_impl/tui/transcript.py +514 -0
  173. alysis_code/cli_impl/tui/update_prompt.py +79 -0
  174. alysis_code/cli_impl/tui/workspace_guard.py +384 -0
  175. alysis_code/clipboard.py +172 -0
  176. alysis_code/code_review.py +1211 -0
  177. alysis_code/compaction/__init__.py +28 -0
  178. alysis_code/compaction/conversation_compactor.py +2932 -0
  179. alysis_code/compaction/importance.py +177 -0
  180. alysis_code/compaction/settings.py +297 -0
  181. alysis_code/compaction/tool_output_offload.py +447 -0
  182. alysis_code/config.py +3509 -0
  183. alysis_code/conflict_auto_resolver.py +895 -0
  184. alysis_code/context/__init__.py +1 -0
  185. alysis_code/context/tool_schema_budgeter.py +220 -0
  186. alysis_code/crash_diagnostics.py +282 -0
  187. alysis_code/custom_tools/README.md +34 -0
  188. alysis_code/custom_tools/__init__.py +43 -0
  189. alysis_code/custom_tools/discovery.py +903 -0
  190. alysis_code/custom_tools/runtime.py +1516 -0
  191. alysis_code/custom_tools/session.py +227 -0
  192. alysis_code/custom_tools/trust.py +232 -0
  193. alysis_code/diff_paths.py +113 -0
  194. alysis_code/direction_change.py +293 -0
  195. alysis_code/dispatch_timing.py +306 -0
  196. alysis_code/durable_service_manager.py +1236 -0
  197. alysis_code/edit_discipline.py +659 -0
  198. alysis_code/error_text.py +73 -0
  199. alysis_code/execution_budget.py +411 -0
  200. alysis_code/execution_context.py +915 -0
  201. alysis_code/execution_deadline.py +1065 -0
  202. alysis_code/execution_shared.py +1904 -0
  203. alysis_code/extensions/README.md +30 -0
  204. alysis_code/extensions/__init__.py +93 -0
  205. alysis_code/extensions/activation.py +138 -0
  206. alysis_code/extensions/install.py +1436 -0
  207. alysis_code/extensions/manifest.py +487 -0
  208. alysis_code/extensions/models.py +74 -0
  209. alysis_code/extensions/paths.py +56 -0
  210. alysis_code/extensions/registry.json +4 -0
  211. alysis_code/extensions/registry.py +52 -0
  212. alysis_code/extensions/state.py +83 -0
  213. alysis_code/extensions/workspace_trust.py +101 -0
  214. alysis_code/failed_task_evidence.py +369 -0
  215. alysis_code/failure_category.py +315 -0
  216. alysis_code/feedback_report.py +1647 -0
  217. alysis_code/file_classification.py +485 -0
  218. alysis_code/forge.py +2064 -0
  219. alysis_code/forge_completion.py +362 -0
  220. alysis_code/forge_events.py +475 -0
  221. alysis_code/frontmatter_utils.py +95 -0
  222. alysis_code/git_evidence.py +1181 -0
  223. alysis_code/git_ops.py +560 -0
  224. alysis_code/git_safe.py +62 -0
  225. alysis_code/git_worktrees.py +190 -0
  226. alysis_code/hooks/README.md +33 -0
  227. alysis_code/hooks/__init__.py +67 -0
  228. alysis_code/hooks/audit.py +171 -0
  229. alysis_code/hooks/config.py +225 -0
  230. alysis_code/hooks/dispatcher.py +1110 -0
  231. alysis_code/hooks/models.py +447 -0
  232. alysis_code/hooks/trust.py +202 -0
  233. alysis_code/host_actions.py +543 -0
  234. alysis_code/host_browser.py +103 -0
  235. alysis_code/ide/__init__.py +5 -0
  236. alysis_code/ide/activity_events.py +399 -0
  237. alysis_code/ide/approvals.py +337 -0
  238. alysis_code/ide/artifacts.py +153 -0
  239. alysis_code/ide/browser_egress_proxy.py +1076 -0
  240. alysis_code/ide/cdp_websocket_transport.py +1192 -0
  241. alysis_code/ide/change_ledger.py +1721 -0
  242. alysis_code/ide/context_blocks.py +979 -0
  243. alysis_code/ide/event_stream.py +531 -0
  244. alysis_code/ide/forge_protocol.py +3112 -0
  245. alysis_code/ide/forge_request_ledger.py +737 -0
  246. alysis_code/ide/health.py +965 -0
  247. alysis_code/ide/managed_browser.py +2251 -0
  248. alysis_code/ide/management_protocol.py +3414 -0
  249. alysis_code/ide/mcp_oauth_coordinator.py +744 -0
  250. alysis_code/ide/mcp_oauth_lifecycle.py +1504 -0
  251. alysis_code/ide/prompt_queue.py +1070 -0
  252. alysis_code/ide/protocol.py +191 -0
  253. alysis_code/ide/resumable_swarm.py +1543 -0
  254. alysis_code/ide/session_search.py +295 -0
  255. alysis_code/ide/stdio_bridge.py +9935 -0
  256. alysis_code/ide/structured_state.py +1579 -0
  257. alysis_code/ide/swarm_protocol.py +816 -0
  258. alysis_code/integration_gate.py +506 -0
  259. alysis_code/interactive_input_guard.py +39 -0
  260. alysis_code/interactive_plan_mode.py +26 -0
  261. alysis_code/internal_artifacts.py +179 -0
  262. alysis_code/knowledge_base.py +1409 -0
  263. alysis_code/knowledge_capture.py +1190 -0
  264. alysis_code/knowledge_librarian.py +605 -0
  265. alysis_code/language_policy.py +34 -0
  266. alysis_code/litellm_static_provider.py +535 -0
  267. alysis_code/llm/__init__.py +1 -0
  268. alysis_code/llm/anthropic_messages.py +2288 -0
  269. alysis_code/llm/base.py +71 -0
  270. alysis_code/llm/cache_capabilities.py +985 -0
  271. alysis_code/llm/cache_control_blocks.py +244 -0
  272. alysis_code/llm/cache_policy.py +388 -0
  273. alysis_code/llm/factory.py +373 -0
  274. alysis_code/llm/gemini_generate_content.py +2652 -0
  275. alysis_code/llm/gemini_interactions.py +739 -0
  276. alysis_code/llm/metadata.py +450 -0
  277. alysis_code/llm/openai_compat.py +2947 -0
  278. alysis_code/llm/openai_responses.py +2604 -0
  279. alysis_code/llm/protocols.py +609 -0
  280. alysis_code/llm/provider_limits.py +525 -0
  281. alysis_code/llm/request_plan.py +389 -0
  282. alysis_code/llm/request_shape.py +238 -0
  283. alysis_code/llm/streaming.py +108 -0
  284. alysis_code/llm/temperature_compat.py +78 -0
  285. alysis_code/llm/types.py +195 -0
  286. alysis_code/llm/usage_normalization.py +222 -0
  287. alysis_code/llm_error_display.py +315 -0
  288. alysis_code/logging_redaction.py +326 -0
  289. alysis_code/managed_host_deadline.py +196 -0
  290. alysis_code/mcp/README.md +33 -0
  291. alysis_code/mcp/__init__.py +24 -0
  292. alysis_code/mcp/client.py +1137 -0
  293. alysis_code/mcp/config.py +597 -0
  294. alysis_code/mcp/errors.py +113 -0
  295. alysis_code/mcp/forge_scope.py +154 -0
  296. alysis_code/mcp/jsonrpc.py +214 -0
  297. alysis_code/mcp/manager.py +2308 -0
  298. alysis_code/mcp/models.py +666 -0
  299. alysis_code/mcp/oauth.py +972 -0
  300. alysis_code/mcp/oauth_runtime.py +310 -0
  301. alysis_code/mcp/oauth_store.py +276 -0
  302. alysis_code/mcp/prompts.py +329 -0
  303. alysis_code/mcp/resources.py +295 -0
  304. alysis_code/mcp/roots.py +106 -0
  305. alysis_code/mcp/server_requests.py +75 -0
  306. alysis_code/mcp/token_store.py +859 -0
  307. alysis_code/mcp/transport_http.py +1338 -0
  308. alysis_code/mcp/transport_stdio.py +1267 -0
  309. alysis_code/mcp/untrusted_content.py +119 -0
  310. alysis_code/merge_conflict_reviewer.py +729 -0
  311. alysis_code/model_catalog/__init__.py +1 -0
  312. alysis_code/model_catalog/chatgpt_codex_subscription_snapshot.json +186 -0
  313. alysis_code/model_catalog/litellm_model_prices_snapshot.json +44715 -0
  314. alysis_code/model_catalog/litellm_model_prices_snapshot.meta.json +17 -0
  315. alysis_code/model_metadata_policy.py +223 -0
  316. alysis_code/model_metadata_utils.py +103 -0
  317. alysis_code/model_registry.py +1420 -0
  318. alysis_code/model_router.py +147 -0
  319. alysis_code/permission_policy.py +1016 -0
  320. alysis_code/personas.py +451 -0
  321. alysis_code/pipeline_facts.py +233 -0
  322. alysis_code/plan_assistant.py +4763 -0
  323. alysis_code/plan_mode.py +393 -0
  324. alysis_code/plan_reconciliation.py +1228 -0
  325. alysis_code/plan_repair.py +652 -0
  326. alysis_code/plan_validation.py +1099 -0
  327. alysis_code/planning_constraints.py +904 -0
  328. alysis_code/policy.py +95 -0
  329. alysis_code/preview_server.py +457 -0
  330. alysis_code/process_reaping.py +566 -0
  331. alysis_code/profile_presets.py +1834 -0
  332. alysis_code/profiles.py +666 -0
  333. alysis_code/provider_auth/__init__.py +29 -0
  334. alysis_code/provider_auth/base.py +99 -0
  335. alysis_code/provider_auth/openai_codex.py +951 -0
  336. alysis_code/provider_auth/registry.py +76 -0
  337. alysis_code/provider_auth/store.py +125 -0
  338. alysis_code/provider_diagnostics.py +1209 -0
  339. alysis_code/provider_model_catalog.py +685 -0
  340. alysis_code/provider_telemetry.py +1699 -0
  341. alysis_code/provider_url.py +75 -0
  342. alysis_code/reasoning_contracts.py +911 -0
  343. alysis_code/remote_sync.py +350 -0
  344. alysis_code/replanning.py +1195 -0
  345. alysis_code/repo_scan.py +1152 -0
  346. alysis_code/request_estimation.py +296 -0
  347. alysis_code/review_gate.py +617 -0
  348. alysis_code/run_lock.py +1141 -0
  349. alysis_code/run_outcome.py +58 -0
  350. alysis_code/run_provenance.py +774 -0
  351. alysis_code/run_state.py +445 -0
  352. alysis_code/runtime_artifacts.py +116 -0
  353. alysis_code/runtime_context_features.py +78 -0
  354. alysis_code/runtime_kind.py +52 -0
  355. alysis_code/safety/__init__.py +11 -0
  356. alysis_code/safety/mcp_sanitize.py +29 -0
  357. alysis_code/safety/safe_http.py +297 -0
  358. alysis_code/safety/subagent_report.py +184 -0
  359. alysis_code/sandbox_doctor.py +682 -0
  360. alysis_code/sandbox_runner.py +1025 -0
  361. alysis_code/sandbox_settings.py +423 -0
  362. alysis_code/serialized_paths.py +355 -0
  363. alysis_code/server/__init__.py +3 -0
  364. alysis_code/server/app.py +367 -0
  365. alysis_code/server/auth.py +34 -0
  366. alysis_code/server/job_config.py +30 -0
  367. alysis_code/server/settings.py +215 -0
  368. alysis_code/server/store.py +193 -0
  369. alysis_code/server/worker_runner.py +657 -0
  370. alysis_code/service_persistence.py +355 -0
  371. alysis_code/session_artifacts.py +108 -0
  372. alysis_code/session_metrics.py +331 -0
  373. alysis_code/session_store.py +624 -0
  374. alysis_code/skills/README.md +34 -0
  375. alysis_code/skills/__init__.py +104 -0
  376. alysis_code/skills/conventions.py +84 -0
  377. alysis_code/skills/discovery.py +176 -0
  378. alysis_code/skills/eval_models.py +232 -0
  379. alysis_code/skills/eval_runner.py +372 -0
  380. alysis_code/skills/evals.py +1344 -0
  381. alysis_code/skills/install.py +293 -0
  382. alysis_code/skills/loader.py +118 -0
  383. alysis_code/skills/matching.py +103 -0
  384. alysis_code/skills/models.py +71 -0
  385. alysis_code/skills/paths.py +56 -0
  386. alysis_code/skills/prompting.py +500 -0
  387. alysis_code/skills/scaffold.py +142 -0
  388. alysis_code/skills/state.py +441 -0
  389. alysis_code/skills/transactions.py +125 -0
  390. alysis_code/skills/validation.py +304 -0
  391. alysis_code/step_budget.py +238 -0
  392. alysis_code/subagent_labels.py +49 -0
  393. alysis_code/subagents.py +1072 -0
  394. alysis_code/surface/__init__.py +80 -0
  395. alysis_code/surface/base.py +305 -0
  396. alysis_code/surface/console.py +387 -0
  397. alysis_code/surface/events.py +372 -0
  398. alysis_code/surface/hidden_surface.py +529 -0
  399. alysis_code/surface/noop_surface.py +219 -0
  400. alysis_code/surface/rich_surface.py +1555 -0
  401. alysis_code/surface/styles.py +67 -0
  402. alysis_code/surface/theme.py +455 -0
  403. alysis_code/surface/types.py +100 -0
  404. alysis_code/swarm_backend.py +926 -0
  405. alysis_code/swarm_orchestrator.py +4020 -0
  406. alysis_code/swarm_scheduler.py +441 -0
  407. alysis_code/swarm_trace.py +429 -0
  408. alysis_code/swarm_worker.py +2119 -0
  409. alysis_code/swarm_write_guard.py +348 -0
  410. alysis_code/task_dependencies.py +170 -0
  411. alysis_code/task_readiness.py +992 -0
  412. alysis_code/task_scope.py +2148 -0
  413. alysis_code/terminal_manager.py +762 -0
  414. alysis_code/terminal_ownership.py +460 -0
  415. alysis_code/text_normalization.py +30 -0
  416. alysis_code/token_budget.py +97 -0
  417. alysis_code/tools/README.md +34 -0
  418. alysis_code/tools/__init__.py +1 -0
  419. alysis_code/tools/artifacts.py +127 -0
  420. alysis_code/tools/availability.py +188 -0
  421. alysis_code/tools/fs.py +1456 -0
  422. alysis_code/tools/git.py +461 -0
  423. alysis_code/tools/history.py +229 -0
  424. alysis_code/tools/http_timeout.py +78 -0
  425. alysis_code/tools/image_generation.py +552 -0
  426. alysis_code/tools/registry.py +2936 -0
  427. alysis_code/tools/repo_map.py +476 -0
  428. alysis_code/tools/search.py +563 -0
  429. alysis_code/tools/shell.py +135 -0
  430. alysis_code/tools/symbols.py +1350 -0
  431. alysis_code/tools/test_discovery.py +643 -0
  432. alysis_code/tools/web.py +482 -0
  433. alysis_code/tools/web_search.py +2012 -0
  434. alysis_code/tools/web_search_dashscope.py +557 -0
  435. alysis_code/tools/web_search_ddgs.py +221 -0
  436. alysis_code/tools/web_search_provider_adapters.py +1429 -0
  437. alysis_code/tools/web_search_tavily.py +194 -0
  438. alysis_code/updates.py +933 -0
  439. alysis_code/usage_tracker.py +1990 -0
  440. alysis_code/verification_command_analysis.py +1004 -0
  441. alysis_code/verification_contract.py +574 -0
  442. alysis_code/verification_failure_summary.py +273 -0
  443. alysis_code/verification_repair.py +385 -0
  444. alysis_code/verify_gate.py +3129 -0
  445. alysis_code/web_research.py +1872 -0
  446. alysis_code/web_search_adapters.py +66 -0
  447. alysis_code/web_search_policy.py +27 -0
  448. alysis_code/workspace_binding.py +389 -0
  449. alysis_code/workspace_binding_ui.py +408 -0
  450. alysis_code/workspace_context.py +273 -0
  451. alysis_code/workspace_isolation.py +138 -0
  452. alysis_code/workspace_provisioning.py +455 -0
  453. alysis_code-0.13.0.dist-info/METADATA +507 -0
  454. alysis_code-0.13.0.dist-info/RECORD +458 -0
  455. alysis_code-0.13.0.dist-info/WHEEL +4 -0
  456. alysis_code-0.13.0.dist-info/entry_points.txt +3 -0
  457. alysis_code-0.13.0.dist-info/licenses/LICENSE +176 -0
  458. alysis_code-0.13.0.dist-info/licenses/NOTICE +4 -0
@@ -0,0 +1,307 @@
1
+ # ruff: noqa: F401,F403,F405,I001
2
+ # Legacy split module: dependencies are synced by cli_surface.py.
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+
7
+ from .cli_common import *
8
+
9
+
10
+ def _chat_prompt_session_completion_count(mode: str) -> int:
11
+ from ..chat_slash_completer import max_completions_for_mode
12
+
13
+ # Chat keeps one PromptSession while the user can enter/leave Forge, so
14
+ # reserve enough room for the larger static command surface at creation.
15
+ return max(
16
+ max_completions_for_mode(mode),
17
+ max_completions_for_mode("chat"),
18
+ max_completions_for_mode("forge"),
19
+ )
20
+
21
+
22
+ def _chat_prompt_completion_menu_height(mode: str) -> int:
23
+ completion_count = _chat_prompt_session_completion_count(mode)
24
+ terminal_lines = shutil.get_terminal_size((80, 24)).lines
25
+ return min(completion_count, max(8, int(terminal_lines * 0.6)))
26
+
27
+
28
+ def _handle_chat_command(
29
+ *,
30
+ input_text: str,
31
+ root: Path,
32
+ session: Any,
33
+ pending_images: list[str],
34
+ console: Console,
35
+ forge_state: _ForgeChatState,
36
+ plan_mode_state: _ChatPlanModeState,
37
+ ) -> str | _ChatExecutionRequest:
38
+ from ..chat import _handle_chat_command_impl
39
+
40
+ return _handle_chat_command_impl(
41
+ _cli_module_for_legacy_impl(),
42
+ input_text=input_text,
43
+ root=root,
44
+ session=session,
45
+ pending_images=pending_images,
46
+ console=console,
47
+ forge_state=forge_state,
48
+ plan_mode_state=plan_mode_state,
49
+ )
50
+
51
+
52
+ def _maybe_make_chat_prompt_session(
53
+ *,
54
+ console: Console,
55
+ root: Path,
56
+ pending_images: list[str],
57
+ forge_state: _ForgeChatState,
58
+ session: Any | None = None,
59
+ plan_mode_state: _ChatPlanModeState | None = None,
60
+ ) -> Any | None:
61
+ if _patchable("_is_non_interactive_terminal", _is_non_interactive_terminal)():
62
+ return None
63
+
64
+ try:
65
+ from prompt_toolkit import PromptSession
66
+ from prompt_toolkit.application import run_in_terminal
67
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
68
+ from prompt_toolkit.history import FileHistory
69
+ from prompt_toolkit.key_binding import KeyBindings
70
+
71
+ from ..chat_slash_completer import ChatSlashCompleter
72
+ except Exception:
73
+ return None
74
+
75
+ kb = KeyBindings()
76
+
77
+ def _run_paste_image() -> None:
78
+ def _do_paste() -> None:
79
+ try:
80
+ saved = _patchable("paste_clipboard_image", paste_clipboard_image)(
81
+ root=root, output_path=None
82
+ )
83
+ except ClipboardError as e:
84
+ console.print(f"[red]Clipboard error:[/red] {e}")
85
+ return
86
+ pending_images.append(os.fspath(saved))
87
+ console.print(f"Pasted clipboard image: {saved}")
88
+
89
+ run_in_terminal(_do_paste)
90
+
91
+ @kb.add("escape")
92
+ def _escape_hotkey(event: Any) -> None:
93
+ current_buffer = getattr(event, "current_buffer", None)
94
+ if getattr(current_buffer, "complete_state", None) is not None:
95
+ cancel_completion = getattr(current_buffer, "cancel_completion", None)
96
+ if callable(cancel_completion):
97
+ cancel_completion()
98
+ return
99
+ action = _resolve_chat_prompt_escape_action(
100
+ ui_mode=forge_state.ui_mode,
101
+ plan_mode_enabled=_chat_plan_mode_enabled(plan_mode_state),
102
+ buffer_text=str(getattr(current_buffer, "text", "") or ""),
103
+ )
104
+ if action == _CHAT_ESCAPE_ACTION_PLAN_OFF:
105
+ event.app.exit(result=_CHAT_PROMPT_RESULT_PLAN_MODE_OFF)
106
+ return
107
+ if action == _CHAT_ESCAPE_ACTION_NOOP:
108
+ return
109
+ _run_paste_image()
110
+
111
+ @kb.add("c-b")
112
+ def _paste_image_hotkey(_event: Any) -> None:
113
+ _run_paste_image()
114
+
115
+ @kb.add("escape", "c-v")
116
+ def _paste_image_ctrl_alt_v_hotkey(_event: Any) -> None:
117
+ _run_paste_image()
118
+
119
+ @kb.add("c-l")
120
+ def _clear_screen(_event: Any) -> None:
121
+ run_in_terminal(console.clear)
122
+
123
+ @kb.add("tab")
124
+ def _accept_suggestion_or_complete(event: Any) -> None:
125
+ _accept_chat_suggestion_or_complete(event)
126
+
127
+ def _completion_mode() -> str:
128
+ return "forge" if _is_forge_ui_mode(forge_state.ui_mode) else "chat"
129
+
130
+ completer = ChatSlashCompleter(
131
+ mode_provider=_completion_mode,
132
+ skill_names_provider=lambda: sorted(
133
+ str(name) for name in getattr(session, "skill_registry", {})
134
+ ),
135
+ )
136
+ prompt_session_kwargs = {
137
+ "key_bindings": kb,
138
+ "auto_suggest": AutoSuggestFromHistory(),
139
+ "completer": completer,
140
+ "complete_while_typing": True,
141
+ "reserve_space_for_menu": _chat_prompt_completion_menu_height(_completion_mode()),
142
+ }
143
+ try:
144
+ history_path = default_chat_history_path()
145
+ history_path.parent.mkdir(parents=True, exist_ok=True)
146
+ prompt_session_kwargs["history"] = FileHistory(os.fspath(history_path))
147
+ except OSError:
148
+ pass
149
+
150
+ def _prompt_session_supports_cpr(candidate: Any) -> bool:
151
+ output = getattr(getattr(candidate, "app", None), "output", None)
152
+ if output is None:
153
+ return False
154
+ responds_to_cpr = getattr(output, "responds_to_cpr", None)
155
+ if callable(responds_to_cpr):
156
+ try:
157
+ responds_to_cpr = responds_to_cpr()
158
+ except Exception:
159
+ responds_to_cpr = None
160
+ return bool(responds_to_cpr)
161
+
162
+ try:
163
+ prompt_session = PromptSession(
164
+ erase_when_done=True,
165
+ **prompt_session_kwargs,
166
+ )
167
+ prompt_session._alysis_erase_when_done = True # type: ignore[attr-defined]
168
+ except TypeError as e:
169
+ if "erase_when_done" not in str(e):
170
+ raise
171
+ prompt_session = PromptSession(**prompt_session_kwargs)
172
+ prompt_session._alysis_erase_when_done = False # type: ignore[attr-defined]
173
+
174
+ _apply_chat_prompt_escape_sequence_timeout(prompt_session)
175
+
176
+ if not _prompt_session_supports_cpr(prompt_session):
177
+ return None
178
+ return prompt_session
179
+
180
+
181
+ def _apply_chat_prompt_escape_sequence_timeout(prompt_session: Any) -> None:
182
+ """
183
+ Give VT100 escape sequences a slightly longer grace window before treating
184
+ the leading byte as a standalone Esc hotkey.
185
+
186
+ This keeps the existing plain-Esc behavior, but reduces accidental Plan
187
+ Mode exits on slower terminals where arrow-key sequences can arrive late.
188
+ """
189
+
190
+ app = getattr(prompt_session, "app", None)
191
+ if app is None:
192
+ return
193
+ current = getattr(app, "ttimeoutlen", None)
194
+ if isinstance(current, (int, float)):
195
+ app.ttimeoutlen = max(float(current), _CHAT_PROMPT_ESCAPE_SEQUENCE_TIMEOUT_S)
196
+ return
197
+ app.ttimeoutlen = _CHAT_PROMPT_ESCAPE_SEQUENCE_TIMEOUT_S
198
+
199
+
200
+ def _resolve_chat_prompt_escape_action(
201
+ *,
202
+ ui_mode: str,
203
+ plan_mode_enabled: bool,
204
+ buffer_text: str,
205
+ ) -> str:
206
+ if _is_forge_ui_mode(ui_mode):
207
+ return _CHAT_ESCAPE_ACTION_PASTE_IMAGE
208
+ if not plan_mode_enabled:
209
+ return _CHAT_ESCAPE_ACTION_PASTE_IMAGE
210
+ if str(buffer_text or "").strip():
211
+ return _CHAT_ESCAPE_ACTION_NOOP
212
+ return _CHAT_ESCAPE_ACTION_PLAN_OFF
213
+
214
+
215
+ @contextmanager
216
+ def _chat_turn_interrupt_monitor() -> Any:
217
+ # Only enable raw-key monitoring while a turn is running in interactive POSIX terminals.
218
+ if not (sys.stdin.isatty() and os.name == "posix"):
219
+ yield
220
+ return
221
+ try:
222
+ import select
223
+ import signal
224
+ import termios
225
+ import tty
226
+ except Exception:
227
+ yield
228
+ return
229
+
230
+ stop_event = threading.Event()
231
+
232
+ def _watch_escape() -> None:
233
+ try:
234
+ fd = sys.stdin.fileno()
235
+ original = termios.tcgetattr(fd)
236
+ except Exception:
237
+ return
238
+ cbreak_active = False
239
+
240
+ def _enter_cbreak() -> None:
241
+ nonlocal cbreak_active
242
+ if cbreak_active:
243
+ return
244
+ tty.setcbreak(fd)
245
+ cbreak_active = True
246
+
247
+ def _restore_terminal() -> None:
248
+ nonlocal cbreak_active
249
+ if not cbreak_active:
250
+ return
251
+ try:
252
+ termios.tcsetattr(fd, termios.TCSADRAIN, original)
253
+ except Exception:
254
+ pass
255
+ cbreak_active = False
256
+
257
+ try:
258
+ while not stop_event.is_set():
259
+ if is_interactive_prompt_active():
260
+ if not is_interactive_prompt_terminal_owner():
261
+ _restore_terminal()
262
+ stop_event.wait(0.05)
263
+ continue
264
+ _enter_cbreak()
265
+ try:
266
+ readable, _, _ = select.select([fd], [], [], 0.1)
267
+ except Exception:
268
+ return
269
+ if not readable:
270
+ continue
271
+ # A nested approval prompt may have claimed stdin while this
272
+ # watcher was already blocked in select(). Leave the pending
273
+ # byte untouched so the prompt can read it after we restore the
274
+ # terminal to cooked mode.
275
+ if is_interactive_prompt_active():
276
+ continue
277
+ try:
278
+ chunk = os.read(fd, 1)
279
+ except Exception:
280
+ return
281
+ if chunk != b"\x1b":
282
+ continue
283
+ try:
284
+ os.kill(os.getpid(), signal.SIGINT)
285
+ except Exception:
286
+ try:
287
+ signal.raise_signal(signal.SIGINT)
288
+ except Exception:
289
+ return
290
+ return
291
+ finally:
292
+ _restore_terminal()
293
+
294
+ watcher = threading.Thread(
295
+ target=_watch_escape,
296
+ name="alysis-chat-escape-interrupt",
297
+ daemon=True,
298
+ )
299
+ watcher.start()
300
+ try:
301
+ yield
302
+ finally:
303
+ stop_event.set()
304
+ watcher.join(timeout=0.25)
305
+
306
+
307
+ __all__ = [name for name in globals() if (not name.startswith("__") or name == "__version__")]
@@ -0,0 +1,88 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import typer
6
+
7
+ from ...config import ConfigError, load_config
8
+ from ...feedback_report import (
9
+ FeedbackReportError,
10
+ create_feedback_bundle,
11
+ create_feedback_github_issue_draft,
12
+ feedback_github_issue_status_lines,
13
+ resolve_feedback_workspace_root,
14
+ )
15
+ from . import _patchable
16
+ from ._shared import _console
17
+
18
+ report_app = typer.Typer(add_completion=False, help="Feedback bundle commands.")
19
+
20
+
21
+ @report_app.command("create")
22
+ def report_create(
23
+ feedback: str | None = typer.Argument(None, help="Optional feedback text."),
24
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path."),
25
+ session_id: str | None = typer.Option(None, "--session-id", help="Retained session id."),
26
+ run_id: str | None = typer.Option(None, "--run-id", help="Forge run id."),
27
+ latest: bool = typer.Option(
28
+ False,
29
+ "--latest",
30
+ help="Use the latest retained session when no active session exists.",
31
+ ),
32
+ github: bool | None = typer.Option(
33
+ None,
34
+ "--github/--no-github",
35
+ help="Override feedback GitHub issue draft creation.",
36
+ ),
37
+ local_only: bool = typer.Option(
38
+ False,
39
+ "--local-only",
40
+ help="Only create the local bundle; do not create a GitHub issue draft URL.",
41
+ ),
42
+ open_browser: bool | None = typer.Option(
43
+ None,
44
+ "--open/--no-open",
45
+ help="Open the GitHub issue draft in a browser. CLI defaults to URL-only.",
46
+ ),
47
+ ) -> None:
48
+ console = _console()
49
+ if local_only and github is True:
50
+ console.print("[red]Feedback report failed:[/red] Use either --github or --local-only.")
51
+ raise typer.Exit(code=2)
52
+ try:
53
+ cfg = _patchable("load_config", load_config)()
54
+ workspace_root = _patchable(
55
+ "resolve_feedback_workspace_root", resolve_feedback_workspace_root
56
+ )(path)
57
+ result = _patchable("create_feedback_bundle", create_feedback_bundle)(
58
+ workspace_root=workspace_root,
59
+ feedback_text=feedback,
60
+ cfg=cfg,
61
+ session_id=session_id,
62
+ run_id=run_id,
63
+ latest=latest,
64
+ )
65
+ except (ConfigError, FeedbackReportError) as e:
66
+ console.print(f"[red]Feedback report failed:[/red] {e}")
67
+ raise typer.Exit(code=2) from e
68
+
69
+ console.print(f"Feedback bundle directory: {result.bundle_dir}")
70
+ console.print(f"Feedback bundle archive: {result.zip_path}")
71
+
72
+ try:
73
+ issue_result = _patchable(
74
+ "create_feedback_github_issue_draft",
75
+ create_feedback_github_issue_draft,
76
+ )(
77
+ bundle_result=result,
78
+ feedback_text=feedback,
79
+ cfg=cfg,
80
+ github_enabled=False if local_only else github,
81
+ open_browser=False if open_browser is None else open_browser,
82
+ )
83
+ except Exception as e: # noqa: BLE001 - GitHub issue drafting is best-effort.
84
+ console.print(f"[yellow]GitHub issue draft skipped:[/yellow] {e}")
85
+ return
86
+
87
+ for line in feedback_github_issue_status_lines(issue_result):
88
+ console.print(line)