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,404 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ import typer
7
+
8
+ from ...skills import (
9
+ discover_skills,
10
+ install_skill_bundle,
11
+ load_global_skill_state,
12
+ load_project_skill_state,
13
+ remove_managed_skill,
14
+ render_skill_info_text,
15
+ resolve_skill_catalog,
16
+ resolve_skill_catalog_entry,
17
+ save_global_skill_state,
18
+ save_project_skill_state,
19
+ scaffold_skill_bundle,
20
+ set_global_skill_disabled,
21
+ set_project_skill_override,
22
+ validate_skill_bundle,
23
+ )
24
+ from ...workspace_context import resolve_workspace_context
25
+ from . import _patchable
26
+ from ._shared import _console, _resolve_tool_workspace_root, _Table
27
+
28
+ if TYPE_CHECKING:
29
+ from rich.console import Console
30
+ from rich.table import Table
31
+
32
+
33
+ skill_app = typer.Typer(
34
+ add_completion=False,
35
+ help="Skill discovery, authoring, validation, and lifecycle commands.",
36
+ )
37
+
38
+
39
+ def _discover_skills_for_path(
40
+ *,
41
+ path: Path,
42
+ ) -> Any:
43
+ resolved = path.resolve()
44
+ workspace_context = _patchable("resolve_workspace_context", resolve_workspace_context)(
45
+ resolved if resolved.is_dir() else resolved.parent
46
+ )
47
+ return discover_skills(
48
+ focus_path=workspace_context.focus_path,
49
+ workspace_root=workspace_context.workspace_root,
50
+ )
51
+
52
+
53
+ def _resolve_skill_catalog_for_path(
54
+ *,
55
+ path: Path,
56
+ ) -> tuple[Path, Any]:
57
+ resolved = path.resolve()
58
+ workspace_context = _patchable("resolve_workspace_context", resolve_workspace_context)(
59
+ resolved if resolved.is_dir() else resolved.parent
60
+ )
61
+ discovered = discover_skills(
62
+ focus_path=workspace_context.focus_path,
63
+ workspace_root=workspace_context.workspace_root,
64
+ )
65
+ catalog = resolve_skill_catalog(
66
+ discovered=discovered,
67
+ workspace_root=workspace_context.workspace_root,
68
+ )
69
+ return workspace_context.workspace_root, catalog
70
+
71
+
72
+ def _print_skill_catalog_issues(*, console: Console, catalog: Any) -> None:
73
+ for issue in getattr(catalog.effective, "issues", ()):
74
+ console.print(f"[yellow]Skipped skill:[/yellow] {issue.source_path} ({issue.message})")
75
+ for issue in getattr(catalog, "lifecycle_issues", ()):
76
+ console.print(
77
+ f"[yellow]Lifecycle state warning:[/yellow] {issue.source_path} ({issue.message})"
78
+ )
79
+
80
+
81
+ def _skills_table(*, skills: list[Any] | tuple[Any, ...], title: str) -> Table:
82
+ table = _Table(title=title)
83
+ table.add_column("name", no_wrap=True)
84
+ table.add_column("enabled", no_wrap=True)
85
+ table.add_column("managed", no_wrap=True)
86
+ table.add_column("description")
87
+ table.add_column("source", no_wrap=True)
88
+ table.add_column("trust", no_wrap=True)
89
+ table.add_column("path")
90
+ for skill in skills:
91
+ enabled = getattr(skill, "enabled", None)
92
+ managed = getattr(skill, "managed", None)
93
+ bundle = getattr(skill, "skill", skill)
94
+ table.add_row(
95
+ str(getattr(bundle, "name", "")),
96
+ "-" if enabled is None else ("yes" if enabled else "no"),
97
+ "-" if managed is None else ("yes" if managed else "no"),
98
+ str(getattr(bundle, "description", "")),
99
+ (
100
+ f"{getattr(bundle, 'source_scope', '')}/"
101
+ f"{getattr(bundle, 'source_kind', '')}/"
102
+ f"{getattr(bundle, 'source_family', '')}"
103
+ ),
104
+ str(getattr(bundle, "trust_level", "")),
105
+ str(getattr(bundle, "source_path", "")),
106
+ )
107
+ return table
108
+
109
+
110
+ def _render_skill_validation_summary(result: Any) -> str:
111
+ lines = [
112
+ f"bundle_path: {getattr(result, 'bundle_path', '')}",
113
+ f"valid: {'yes' if getattr(result, 'valid', False) else 'no'}",
114
+ ]
115
+ name = str(getattr(result, "name", "") or "").strip()
116
+ if name:
117
+ lines.append(f"name: {name}")
118
+ description = str(getattr(result, "description", "") or "").strip()
119
+ if description:
120
+ lines.append(f"description: {description}")
121
+ issues = tuple(getattr(result, "issues", ()) or ())
122
+ if issues:
123
+ lines.append("issues:")
124
+ for issue in issues:
125
+ severity = str(getattr(issue, "severity", "error") or "error")
126
+ message = str(getattr(issue, "message", "") or "").strip()
127
+ issue_path = str(getattr(issue, "path", "") or "").strip()
128
+ lines.append(f"- [{severity}] {message} ({issue_path})")
129
+ return "\n".join(lines)
130
+
131
+
132
+ @skill_app.command("list")
133
+ def skill_list(
134
+ path: Path = typer.Option(Path("."), "--path", help="Workspace or repository path."),
135
+ ) -> None:
136
+ console = _console()
137
+ _workspace_root, catalog = _resolve_skill_catalog_for_path(path=path)
138
+ if not catalog.entries:
139
+ console.print("No skills discovered in the supported skill roots.")
140
+ _print_skill_catalog_issues(console=console, catalog=catalog)
141
+ return
142
+ console.print(_skills_table(skills=catalog.entries, title=f"Skills ({len(catalog.entries)})"))
143
+ _print_skill_catalog_issues(console=console, catalog=catalog)
144
+
145
+
146
+ @skill_app.command("info")
147
+ def skill_info(
148
+ name: str = typer.Argument(..., help="Skill name or alias."),
149
+ path: Path = typer.Option(Path("."), "--path", help="Workspace or repository path."),
150
+ ) -> None:
151
+ console = _console()
152
+ _workspace_root, catalog = _resolve_skill_catalog_for_path(path=path)
153
+ entry = resolve_skill_catalog_entry(entries=catalog.entries, raw_name=name)
154
+ if entry is None:
155
+ _print_skill_catalog_issues(console=console, catalog=catalog)
156
+ console.print(f"[red]Skill not found:[/red] {name}")
157
+ if catalog.entries:
158
+ console.print(
159
+ "Available skills: "
160
+ + ", ".join(str(getattr(item.skill, "name", "")) for item in catalog.entries)
161
+ )
162
+ raise typer.Exit(code=1)
163
+ console.print(render_skill_info_text(entry.skill, catalog_entry=entry))
164
+ _print_skill_catalog_issues(console=console, catalog=catalog)
165
+
166
+
167
+ @skill_app.command("init")
168
+ @skill_app.command("create")
169
+ def skill_init(
170
+ name: str = typer.Argument(..., help="Skill display name."),
171
+ description: str = typer.Option("", "--description", help="Short skill description."),
172
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path for project skills."),
173
+ project: bool = typer.Option(False, "--project", help="Create the skill in the project root."),
174
+ user: bool = typer.Option(
175
+ False, "--user", help="Create the skill in the user-global managed root."
176
+ ),
177
+ family: str = typer.Option(
178
+ "native", "--family", help="Project family: native|agents|claude|github."
179
+ ),
180
+ portable: bool = typer.Option(
181
+ False, "--portable", help="Project-local portable alias for --family agents."
182
+ ),
183
+ force: bool = typer.Option(False, "--force", help="Overwrite an existing scaffold."),
184
+ ) -> None:
185
+ console = _console()
186
+ if project and user:
187
+ console.print("[red]Choose only one of --project or --user.[/red]")
188
+ raise typer.Exit(code=2)
189
+ use_project = not user
190
+ selected_family = "agents" if portable else family
191
+ if not use_project and portable:
192
+ console.print("[red]--portable can only be used with project-local scaffolds.[/red]")
193
+ raise typer.Exit(code=2)
194
+ if not use_project and str(family or "native").strip().lower() != "native":
195
+ console.print("[red]--family only applies to project-local scaffolds.[/red]")
196
+ raise typer.Exit(code=2)
197
+ workspace_root = _resolve_tool_workspace_root(path=path)
198
+ try:
199
+ result = scaffold_skill_bundle(
200
+ name=name,
201
+ description=description,
202
+ workspace_root=workspace_root,
203
+ project=use_project,
204
+ family=selected_family,
205
+ force=force,
206
+ )
207
+ except Exception as exc:
208
+ console.print(f"[red]Skill scaffold failed:[/red] {exc}")
209
+ raise typer.Exit(code=1) from exc
210
+ console.print(f"Created skill scaffold: {result.bundle_path}")
211
+ console.print("Next steps:")
212
+ console.print(f"1. Edit {result.bundle_path / 'SKILL.md'}")
213
+ console.print(f"2. Run `alysis skill validate {result.bundle_path}`")
214
+ if result.managed:
215
+ console.print(
216
+ "3. The skill is already in a managed native root and can be enabled/disabled later."
217
+ )
218
+ else:
219
+ console.print(
220
+ "3. This portable scaffold is unmanaged; lifecycle remove/install commands will not manage it automatically."
221
+ )
222
+
223
+
224
+ @skill_app.command("validate")
225
+ def skill_validate(
226
+ bundle: Path | None = typer.Argument(None, help="Path to a skill bundle directory."),
227
+ name: str | None = typer.Option(None, "--name", help="Validate a discovered skill by name."),
228
+ path: Path = typer.Option(
229
+ Path("."), "--path", help="Workspace path for discovery or project state."
230
+ ),
231
+ validate_all: bool = typer.Option(
232
+ False, "--all", help="Validate all discovered skills for the workspace."
233
+ ),
234
+ ) -> None:
235
+ console = _console()
236
+ if sum(1 for item in (bundle is not None, bool(name), validate_all) if item) != 1:
237
+ console.print("[red]Choose exactly one of <bundle>, --name, or --all.[/red]")
238
+ raise typer.Exit(code=2)
239
+ results: list[Any] = []
240
+ if bundle is not None:
241
+ results.append(validate_skill_bundle(bundle))
242
+ else:
243
+ _workspace_root, catalog = _resolve_skill_catalog_for_path(path=path)
244
+ if validate_all:
245
+ seen_paths: set[Path] = set()
246
+ for entry in catalog.entries:
247
+ if entry.skill.bundle_path in seen_paths:
248
+ continue
249
+ seen_paths.add(entry.skill.bundle_path)
250
+ results.append(validate_skill_bundle(entry.skill.bundle_path))
251
+ for issue in catalog.effective.issues:
252
+ message = str(getattr(issue, "message", "") or "")
253
+ if message.startswith("failed to scan skill root"):
254
+ continue
255
+ source_path = getattr(issue, "source_path", None)
256
+ if (
257
+ isinstance(source_path, Path)
258
+ and source_path.is_dir()
259
+ and source_path not in seen_paths
260
+ ):
261
+ seen_paths.add(source_path)
262
+ results.append(validate_skill_bundle(source_path))
263
+ else:
264
+ entry = resolve_skill_catalog_entry(entries=catalog.entries, raw_name=name or "")
265
+ if entry is None:
266
+ console.print(f"[red]Skill not found:[/red] {name}")
267
+ raise typer.Exit(code=1)
268
+ results.append(validate_skill_bundle(entry.skill.bundle_path))
269
+ exit_code = 0
270
+ for result in results:
271
+ console.print(_render_skill_validation_summary(result))
272
+ console.print()
273
+ if not getattr(result, "valid", False):
274
+ exit_code = 1
275
+ if exit_code:
276
+ raise typer.Exit(code=exit_code)
277
+
278
+
279
+ @skill_app.command("install")
280
+ def skill_install(
281
+ source: str = typer.Argument(..., help="Local dir, zip archive, or git repository URL."),
282
+ subdir: str | None = typer.Option(
283
+ None, "--subdir", help="Subdirectory containing the skill bundle."
284
+ ),
285
+ project: bool = typer.Option(
286
+ False, "--project", help="Install into the managed project-local native root."
287
+ ),
288
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path for project installs."),
289
+ force: bool = typer.Option(False, "--force", help="Replace an existing managed install."),
290
+ ) -> None:
291
+ console = _console()
292
+ workspace_root = _resolve_tool_workspace_root(path=path)
293
+ try:
294
+ result = install_skill_bundle(
295
+ source=source,
296
+ workspace_root=workspace_root,
297
+ project=project,
298
+ subdir=subdir,
299
+ force=force,
300
+ )
301
+ except Exception as exc:
302
+ console.print(f"[red]Skill install failed:[/red] {exc}")
303
+ raise typer.Exit(code=1) from exc
304
+ console.print(f"Installed skill: {result.installed_name}")
305
+ console.print(f"bundle_path: {result.bundle_path}")
306
+ console.print(f"source_kind: {result.source_kind}")
307
+ if result.source_commit:
308
+ console.print(f"source_commit: {result.source_commit}")
309
+
310
+
311
+ def _set_skill_enabled_state(
312
+ *,
313
+ name: str,
314
+ project: bool,
315
+ path: Path,
316
+ enabled: bool,
317
+ ) -> None:
318
+ console = _console()
319
+ workspace_root = _resolve_tool_workspace_root(path=path)
320
+ try:
321
+ _workspace_root, catalog = _resolve_skill_catalog_for_path(path=path)
322
+ key = str(name or "").strip().casefold()
323
+ if project:
324
+ project_state = load_project_skill_state(workspace_root)
325
+ if (
326
+ resolve_skill_catalog_entry(entries=catalog.entries, raw_name=name) is None
327
+ and key not in project_state.managed_installs
328
+ ):
329
+ raise RuntimeError(f"Skill not found for project override: {name}")
330
+ state = set_project_skill_override(
331
+ project_state,
332
+ name=name,
333
+ enabled=enabled,
334
+ )
335
+ save_project_skill_state(workspace_root, state)
336
+ console.print(
337
+ f"{'Enabled' if enabled else 'Disabled'} skill for project workspace: {name}"
338
+ )
339
+ return
340
+ global_state = load_global_skill_state()
341
+ visible_user_skill = next(
342
+ (
343
+ entry
344
+ for entry in catalog.entries
345
+ if str(getattr(entry.skill, "source_scope", "")) == "user"
346
+ and key in entry.skill.lookup_keys()
347
+ ),
348
+ None,
349
+ )
350
+ if visible_user_skill is None and key not in global_state.managed_installs:
351
+ raise RuntimeError(f"Global skill not found: {name}")
352
+ state = set_global_skill_disabled(
353
+ global_state,
354
+ name=name,
355
+ disabled=not enabled,
356
+ )
357
+ save_global_skill_state(state)
358
+ console.print(f"{'Enabled' if enabled else 'Disabled'} global skill: {name}")
359
+ except Exception as exc:
360
+ console.print(f"[red]Skill state update failed:[/red] {exc}")
361
+ raise typer.Exit(code=1) from exc
362
+
363
+
364
+ @skill_app.command("enable")
365
+ def skill_enable(
366
+ name: str = typer.Argument(..., help="Skill name."),
367
+ project: bool = typer.Option(
368
+ False, "--project", help="Apply the toggle as a project override."
369
+ ),
370
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path for project overrides."),
371
+ ) -> None:
372
+ _set_skill_enabled_state(name=name, project=project, path=path, enabled=True)
373
+
374
+
375
+ @skill_app.command("disable")
376
+ def skill_disable(
377
+ name: str = typer.Argument(..., help="Skill name."),
378
+ project: bool = typer.Option(
379
+ False, "--project", help="Apply the toggle as a project override."
380
+ ),
381
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path for project overrides."),
382
+ ) -> None:
383
+ _set_skill_enabled_state(name=name, project=project, path=path, enabled=False)
384
+
385
+
386
+ @skill_app.command("remove")
387
+ @skill_app.command("uninstall")
388
+ def skill_remove(
389
+ name: str = typer.Argument(..., help="Managed skill name."),
390
+ project: bool = typer.Option(
391
+ False, "--project", help="Remove from the managed project-local native root."
392
+ ),
393
+ path: Path = typer.Option(Path("."), "--path", help="Workspace path for project removals."),
394
+ ) -> None:
395
+ console = _console()
396
+ workspace_root = _resolve_tool_workspace_root(path=path)
397
+ try:
398
+ result = remove_managed_skill(name=name, workspace_root=workspace_root, project=project)
399
+ except Exception as exc:
400
+ console.print(f"[red]Skill remove failed:[/red] {exc}")
401
+ raise typer.Exit(code=1) from exc
402
+ console.print(f"Removed managed skill: {result.removed_name}")
403
+ if result.bundle_path is not None:
404
+ console.print(f"bundle_path: {result.bundle_path}")