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,401 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import json
5
+ from collections.abc import Callable
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import typer
10
+
11
+ from ...branding import env_get
12
+ from ...extensions.install import (
13
+ EnableResult,
14
+ PluginInstallError,
15
+ TrustPromptRequest,
16
+ disable_plugin,
17
+ enable_plugin,
18
+ install_plugin,
19
+ uninstall_plugin,
20
+ )
21
+ from ...extensions.models import normalize_extension_id
22
+ from ...extensions.paths import project_extensions_path
23
+ from ...extensions.registry import find_by_id, load_registry
24
+ from ...extensions.registry import search as search_extensions
25
+ from ...extensions.state import (
26
+ compute_effective_enabled,
27
+ load_global_state,
28
+ load_project_overrides,
29
+ load_project_state,
30
+ )
31
+ from ...extensions.workspace_trust import is_workspace_trusted
32
+ from . import _patchable
33
+ from ._shared import _console, _Table
34
+
35
+ ext_app = typer.Typer(add_completion=False, help="Extension management commands.")
36
+
37
+
38
+ @ext_app.command("search")
39
+ def ext_search(
40
+ query: str = typer.Argument(..., help="Search query for extension id/name/description/tags."),
41
+ ) -> None:
42
+ console = _console()
43
+ try:
44
+ registry = _patchable("load_registry", load_registry)()
45
+ except RuntimeError as e:
46
+ console.print(f"[red]Extension registry error:[/red] {e}")
47
+ raise typer.Exit(code=2) from e
48
+
49
+ matches = search_extensions(registry, query)
50
+ if not matches:
51
+ console.print(f"No extensions found for query: {query}")
52
+ return
53
+
54
+ table = _Table(title=f"Extensions matching '{query}'")
55
+ table.add_column("id")
56
+ table.add_column("name")
57
+ table.add_column("version")
58
+ table.add_column("tags")
59
+ for entry in matches:
60
+ tags = ", ".join(entry.tags) if entry.tags else "-"
61
+ table.add_row(entry.id, entry.name, entry.version or "-", tags)
62
+ console.print(table)
63
+
64
+
65
+ def _ext_component_list(values: tuple[str, ...]) -> str:
66
+ return ", ".join(values) if values else "-"
67
+
68
+
69
+ def _print_plugin_trust_request(console: Any, request: TrustPromptRequest) -> None:
70
+ permissions = request.permissions_summary
71
+ console.print("[bold]Plugin install trust request[/bold]")
72
+ console.print(f"Plugin: {request.plugin_name} ({request.plugin_id})")
73
+ console.print(f"Version: {request.version}")
74
+ console.print(f"Source: {request.source_url}")
75
+ console.print(f"Commit: {request.commit}")
76
+ console.print(f"Manifest SHA-256: {request.manifest_sha256}")
77
+ console.print(f"Description: {request.description}")
78
+ if request.is_reinstall_with_new_commit:
79
+ console.print(
80
+ "[yellow]This reinstall uses a new commit and requires renewed trust.[/yellow]"
81
+ )
82
+ console.print(
83
+ "Components: "
84
+ f"skills={len(request.components.skill_ids)}, "
85
+ f"tools={len(request.components.tool_ids)}, "
86
+ f"mcp_servers={len(request.components.mcp_server_ids)}, "
87
+ f"hooks={len(request.components.hook_ids)}"
88
+ )
89
+ console.print(
90
+ "Permissions: "
91
+ f"network={'yes' if permissions.network else 'no'}, "
92
+ f"filesystem_write={'yes' if permissions.filesystem_write else 'no'}, "
93
+ f"env={_ext_component_list(permissions.required_env)}, "
94
+ f"mcp_scopes={_ext_component_list(permissions.mcp_scopes)}, "
95
+ f"hook_events={_ext_component_list(permissions.hook_events)}"
96
+ )
97
+ if request.security is not None:
98
+ console.print(f"Security contact: {request.security.contact}")
99
+
100
+
101
+ def _ext_trust_prompt(*, yes: bool, ci: bool, console: Any) -> Callable[[TrustPromptRequest], bool]:
102
+ silent_accept = ci or env_get("ALYSIS_CI") == "1"
103
+
104
+ def prompt(request: TrustPromptRequest) -> bool:
105
+ if silent_accept:
106
+ return True
107
+ _print_plugin_trust_request(console, request)
108
+ if yes:
109
+ return True
110
+ return bool(typer.confirm("Trust and install this plugin?", default=False))
111
+
112
+ return prompt
113
+
114
+
115
+ @ext_app.command("install")
116
+ def ext_install(
117
+ source: str = typer.Argument(..., help="Registry id or pinned git source."),
118
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project installs."),
119
+ project: bool = typer.Option(False, "--project", help="Install into this repository."),
120
+ yes: bool = typer.Option(False, "--yes", help="Accept the trust prompt without asking."),
121
+ ci: bool = typer.Option(False, "--ci", help="Accept trust silently for CI automation."),
122
+ ) -> None:
123
+ console = _console()
124
+ try:
125
+ result = _patchable("install_plugin", install_plugin)(
126
+ source=source,
127
+ repo_root=path.resolve(),
128
+ project=project,
129
+ trust_prompt=_ext_trust_prompt(yes=yes, ci=ci, console=console),
130
+ )
131
+ except PluginInstallError as exc:
132
+ console.print(f"[red]Plugin install failed:[/red] {exc}")
133
+ for rollback_error in exc.rollback_errors:
134
+ console.print(f"[yellow]Rollback issue:[/yellow] {rollback_error}")
135
+ raise typer.Exit(code=1) from exc
136
+ except RuntimeError as exc:
137
+ console.print(f"[red]Plugin install error:[/red] {exc}")
138
+ raise typer.Exit(code=2) from exc
139
+
140
+ console.print(
141
+ f"Installed plugin {result.plugin_id} {result.version} "
142
+ f"({result.scope}, {result.commit[:12]})."
143
+ )
144
+
145
+
146
+ @ext_app.command("uninstall")
147
+ def ext_uninstall(
148
+ plugin_id: str = typer.Argument(..., help="Plugin id."),
149
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project installs."),
150
+ project: bool = typer.Option(False, "--project", help="Uninstall from this repository."),
151
+ yes: bool = typer.Option(False, "--yes", help="Confirm uninstall without asking."),
152
+ ) -> None:
153
+ console = _console()
154
+ scope = "project" if project else "user"
155
+ if not yes and not typer.confirm(
156
+ f"Uninstall plugin {plugin_id!r} from {scope} scope?", default=False
157
+ ):
158
+ console.print("Plugin uninstall cancelled.")
159
+ raise typer.Exit(code=1)
160
+ try:
161
+ result = _patchable("uninstall_plugin", uninstall_plugin)(
162
+ plugin_id=plugin_id,
163
+ repo_root=path.resolve(),
164
+ project=project,
165
+ )
166
+ except PluginInstallError as exc:
167
+ console.print(f"[red]Plugin uninstall failed:[/red] {exc}")
168
+ for rollback_error in exc.rollback_errors:
169
+ console.print(f"[yellow]Removal issue:[/yellow] {rollback_error}")
170
+ raise typer.Exit(code=1) from exc
171
+ except RuntimeError as exc:
172
+ console.print(f"[red]Plugin uninstall error:[/red] {exc}")
173
+ raise typer.Exit(code=2) from exc
174
+
175
+ console.print(f"Uninstalled plugin {result.plugin_id} from {result.scope} scope.")
176
+
177
+
178
+ def _print_enable_result(console: Any, result: EnableResult) -> None:
179
+ noop = " (no-op)" if result.no_op else ""
180
+ console.print(f"Plugin {result.plugin_id} is {result.new_state} in {result.scope} scope{noop}.")
181
+
182
+
183
+ def _confirm_extension_state_change(
184
+ *,
185
+ plugin_id: str,
186
+ scope: str,
187
+ action: str,
188
+ yes: bool,
189
+ console: Any,
190
+ ) -> bool:
191
+ if yes:
192
+ return True
193
+ if typer.confirm(
194
+ f"{action.capitalize()} plugin {plugin_id!r} in {scope} scope?", default=False
195
+ ):
196
+ return True
197
+ console.print(f"Plugin {action} cancelled.")
198
+ return False
199
+
200
+
201
+ def _installed_record_for_id(state: Any, ext_id: str) -> Any | None:
202
+ normalized = normalize_extension_id(ext_id)
203
+ for installed_id, installed in state.installed.items():
204
+ if normalize_extension_id(installed_id) == normalized:
205
+ return installed
206
+ return None
207
+
208
+
209
+ def _workspace_trust_status(repo_root: Path) -> str:
210
+ overrides_path = project_extensions_path(repo_root)
211
+ if not overrides_path.exists():
212
+ return "no overrides file"
213
+ try:
214
+ raw_bytes = overrides_path.read_bytes()
215
+ except OSError as exc:
216
+ raise RuntimeError(f"Failed to read {overrides_path}") from exc
217
+ overrides_sha256 = hashlib.sha256(raw_bytes).hexdigest()
218
+ return (
219
+ f"trusted ({overrides_sha256})"
220
+ if is_workspace_trusted(repo_root=repo_root, overrides_sha256=overrides_sha256)
221
+ else f"untrusted ({overrides_sha256})"
222
+ )
223
+
224
+
225
+ @ext_app.command("enable")
226
+ def ext_enable(
227
+ plugin_id: str = typer.Argument(..., help="Plugin id."),
228
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project overrides."),
229
+ project: bool = typer.Option(False, "--project", help="Enable in this repository."),
230
+ yes: bool = typer.Option(False, "--yes", help="Confirm enable without asking."),
231
+ ) -> None:
232
+ console = _console()
233
+ scope = "project" if project else "user"
234
+ if not _confirm_extension_state_change(
235
+ plugin_id=plugin_id,
236
+ scope=scope,
237
+ action="enable",
238
+ yes=yes,
239
+ console=console,
240
+ ):
241
+ raise typer.Exit(code=1)
242
+ try:
243
+ result = _patchable("enable_plugin", enable_plugin)(
244
+ plugin_id=plugin_id,
245
+ repo_root=path.resolve(),
246
+ project=project,
247
+ )
248
+ except PluginInstallError as exc:
249
+ console.print(f"[red]Plugin enable failed:[/red] {exc}")
250
+ raise typer.Exit(code=1) from exc
251
+ except RuntimeError as exc:
252
+ console.print(f"[red]Plugin enable error:[/red] {exc}")
253
+ raise typer.Exit(code=2) from exc
254
+ _print_enable_result(console, result)
255
+
256
+
257
+ @ext_app.command("disable")
258
+ def ext_disable(
259
+ plugin_id: str = typer.Argument(..., help="Plugin id."),
260
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project overrides."),
261
+ project: bool = typer.Option(False, "--project", help="Disable in this repository."),
262
+ yes: bool = typer.Option(False, "--yes", help="Confirm disable without asking."),
263
+ ) -> None:
264
+ console = _console()
265
+ scope = "project" if project else "user"
266
+ if not _confirm_extension_state_change(
267
+ plugin_id=plugin_id,
268
+ scope=scope,
269
+ action="disable",
270
+ yes=yes,
271
+ console=console,
272
+ ):
273
+ raise typer.Exit(code=1)
274
+ try:
275
+ result = _patchable("disable_plugin", disable_plugin)(
276
+ plugin_id=plugin_id,
277
+ repo_root=path.resolve(),
278
+ project=project,
279
+ )
280
+ except PluginInstallError as exc:
281
+ console.print(f"[red]Plugin disable failed:[/red] {exc}")
282
+ raise typer.Exit(code=1) from exc
283
+ except RuntimeError as exc:
284
+ console.print(f"[red]Plugin disable error:[/red] {exc}")
285
+ raise typer.Exit(code=2) from exc
286
+ _print_enable_result(console, result)
287
+
288
+
289
+ @ext_app.command("info")
290
+ def ext_info(
291
+ ext_id: str = typer.Argument(..., help="Extension id."),
292
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project overrides."),
293
+ ) -> None:
294
+ console = _console()
295
+ try:
296
+ registry = _patchable("load_registry", load_registry)()
297
+ global_state = load_global_state()
298
+ project_overrides = load_project_overrides(path.resolve())
299
+ project_state = load_project_state(path.resolve())
300
+ except RuntimeError as e:
301
+ console.print(f"[red]Extensions state error:[/red] {e}")
302
+ raise typer.Exit(code=2) from e
303
+
304
+ entry = find_by_id(registry, ext_id)
305
+ normalized = normalize_extension_id(entry.id if entry is not None else ext_id)
306
+ global_record = _installed_record_for_id(global_state, normalized)
307
+ project_record = _installed_record_for_id(project_state, normalized)
308
+ installed_record = global_record or project_record
309
+ if entry is None and installed_record is None:
310
+ console.print(f"[red]Extension not found:[/red] {ext_id}")
311
+ raise typer.Exit(code=1)
312
+
313
+ effective_enabled = compute_effective_enabled(global_state, project_overrides)
314
+ installed_scopes = []
315
+ if global_record is not None:
316
+ installed_scopes.append("user")
317
+ if project_record is not None:
318
+ installed_scopes.append("project")
319
+ user_enabled = normalized in {
320
+ normalize_extension_id(item) for item in global_state.enabled
321
+ } or bool(global_record and global_record.enabled)
322
+ if normalized in {normalize_extension_id(item) for item in project_overrides.enabled}:
323
+ project_override_state = "enabled"
324
+ elif normalized in {normalize_extension_id(item) for item in project_overrides.disabled}:
325
+ project_override_state = "disabled"
326
+ else:
327
+ project_override_state = "absent"
328
+
329
+ table = _Table(title=f"Extension: {entry.id if entry is not None else ext_id}")
330
+ table.add_column("field")
331
+ table.add_column("value")
332
+ table.add_row("id", entry.id if entry is not None else ext_id)
333
+ table.add_row(
334
+ "name",
335
+ entry.name
336
+ if entry is not None
337
+ else ((installed_record.id or ext_id) if installed_record else ext_id),
338
+ )
339
+ table.add_row("description", entry.description if entry is not None else "-")
340
+ table.add_row("repo", entry.repo if entry is not None else "-")
341
+ table.add_row("commit", entry.commit if entry is not None else installed_record.commit or "-")
342
+ table.add_row(
343
+ "version", (entry.version if entry is not None else installed_record.version) or "-"
344
+ )
345
+ table.add_row("tags", ", ".join(entry.tags) if entry is not None and entry.tags else "-")
346
+ table.add_row(
347
+ "permissions",
348
+ ", ".join(entry.permissions) if entry is not None and entry.permissions else "-",
349
+ )
350
+ table.add_row("installed", "yes" if installed_record is not None else "no")
351
+ table.add_row("installed scopes", ", ".join(installed_scopes) if installed_scopes else "-")
352
+ table.add_row("enabled (user)", "yes" if user_enabled else "no")
353
+ table.add_row("enabled (project override)", project_override_state)
354
+ table.add_row("enabled (effective)", "yes" if normalized in effective_enabled else "no")
355
+ table.add_row("workspace trust", _workspace_trust_status(path.resolve()))
356
+ if installed_record is not None:
357
+ table.add_row("installed trust", installed_record.trust or "-")
358
+ table.add_row("installed source", installed_record.source or "-")
359
+ table.add_row("installed commit", installed_record.commit or "-")
360
+ table.add_row("manifest_sha256", installed_record.manifest_sha256 or "-")
361
+ table.add_row("installed_at", installed_record.installed_at or "-")
362
+ table.add_row("source_url", installed_record.source_url or "-")
363
+ table.add_row("scope", installed_record.scope or "-")
364
+ table.add_row("component_ids", json.dumps(installed_record.component_ids, sort_keys=True))
365
+ console.print(table)
366
+
367
+
368
+ @ext_app.command("list")
369
+ def ext_list(
370
+ path: Path = typer.Option(Path("."), "--path", help="Repository root for project overrides."),
371
+ ) -> None:
372
+ console = _console()
373
+ try:
374
+ global_state = load_global_state()
375
+ project_overrides = load_project_overrides(path.resolve())
376
+ except RuntimeError as e:
377
+ console.print(f"[red]Extensions state error:[/red] {e}")
378
+ raise typer.Exit(code=2) from e
379
+
380
+ if not global_state.installed:
381
+ console.print("No extensions installed.")
382
+ return
383
+
384
+ effective_enabled = compute_effective_enabled(global_state, project_overrides)
385
+ table = _Table(title="Installed Extensions")
386
+ table.add_column("id")
387
+ table.add_column("enabled")
388
+ table.add_column("version")
389
+ table.add_column("trust")
390
+ table.add_column("commit")
391
+ for ext_id in sorted(global_state.installed):
392
+ installed = global_state.installed[ext_id]
393
+ enabled = "yes" if normalize_extension_id(ext_id) in effective_enabled else "no"
394
+ table.add_row(
395
+ ext_id,
396
+ enabled,
397
+ installed.version or "-",
398
+ installed.trust or "-",
399
+ installed.commit or "-",
400
+ )
401
+ console.print(table)