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.
- alysis_code/__init__.py +3 -0
- alysis_code/__main__.py +4 -0
- alysis_code/_build_info.py +14 -0
- alysis_code/account_login.py +468 -0
- alysis_code/agent/README.md +35 -0
- alysis_code/agent/__init__.py +11 -0
- alysis_code/agent/acceptance_contract.py +2217 -0
- alysis_code/agent/blast_radius.py +1403 -0
- alysis_code/agent/cache_keepalive.py +227 -0
- alysis_code/agent/completion_certificate.py +366 -0
- alysis_code/agent/completion_gate.py +306 -0
- alysis_code/agent/empty_response_stall.py +403 -0
- alysis_code/agent/errors.py +28 -0
- alysis_code/agent/llm_calls.py +475 -0
- alysis_code/agent/mutation_classification.py +227 -0
- alysis_code/agent/prompt_context.py +2508 -0
- alysis_code/agent/read_ledger.py +253 -0
- alysis_code/agent/regression_baseline.py +642 -0
- alysis_code/agent/reproduction_first.py +610 -0
- alysis_code/agent/sensitive_output.py +629 -0
- alysis_code/agent/session.py +3218 -0
- alysis_code/agent/steering.py +191 -0
- alysis_code/agent/subagent_execution.py +5177 -0
- alysis_code/agent/subagent_workspace.py +666 -0
- alysis_code/agent/tools_assembly.py +4728 -0
- alysis_code/agent/turn/__init__.py +101 -0
- alysis_code/agent/turn/core.py +8483 -0
- alysis_code/agent/turn/events.py +113 -0
- alysis_code/agent/turn/exploration.py +590 -0
- alysis_code/agent/turn/interventions.py +65 -0
- alysis_code/agent/turn/read_cache.py +420 -0
- alysis_code/agent/turn/snapshot.py +179 -0
- alysis_code/agent/turn_contract.py +661 -0
- alysis_code/agent/turn_path.py +129 -0
- alysis_code/agent/verification.py +2885 -0
- alysis_code/agent/verification_commands.py +512 -0
- alysis_code/agent/verification_evidence.py +738 -0
- alysis_code/agent_loop.py +693 -0
- alysis_code/agent_runtimes/__init__.py +51 -0
- alysis_code/agent_runtimes/base.py +114 -0
- alysis_code/agent_runtimes/builtins.py +129 -0
- alysis_code/agent_runtimes/codex_cli.py +664 -0
- alysis_code/agent_runtimes/host.py +263 -0
- alysis_code/agent_runtimes/registry.py +64 -0
- alysis_code/agent_runtimes/service.py +150 -0
- alysis_code/agentbox_client.py +416 -0
- alysis_code/agentbox_integration.py +310 -0
- alysis_code/alysis_cloud.py +152 -0
- alysis_code/approval_scope.py +276 -0
- alysis_code/assets/README.md +33 -0
- alysis_code/assets/__init__.py +126 -0
- alysis_code/assets/asset_read_core.py +281 -0
- alysis_code/assets/budget_allocator.py +456 -0
- alysis_code/assets/comprehender.py +759 -0
- alysis_code/assets/index.py +654 -0
- alysis_code/assets/ingestion.py +275 -0
- alysis_code/assets/legacy_migration.py +413 -0
- alysis_code/assets/models.py +263 -0
- alysis_code/assets/ocr.py +239 -0
- alysis_code/assets/owl/ascii/f-000.txt +13 -0
- alysis_code/assets/owl/ascii/f-001.txt +13 -0
- alysis_code/assets/owl/ascii/f-002.txt +13 -0
- alysis_code/assets/owl/ascii/f-003.txt +13 -0
- alysis_code/assets/owl/ascii/f-004.txt +13 -0
- alysis_code/assets/owl/ascii/f-005.txt +13 -0
- alysis_code/assets/owl/ascii/f-006.txt +13 -0
- alysis_code/assets/owl/ascii/f-007.txt +13 -0
- alysis_code/assets/owl/ascii/f-008.txt +13 -0
- alysis_code/assets/owl/ascii/f-009.txt +13 -0
- alysis_code/assets/owl/ascii/f-010.txt +13 -0
- alysis_code/assets/owl/ascii/f-011.txt +13 -0
- alysis_code/assets/owl/ascii/f-012.txt +13 -0
- alysis_code/assets/owl/ascii/f-013.txt +13 -0
- alysis_code/assets/owl/ascii/f-014.txt +13 -0
- alysis_code/assets/owl/ascii/f-015.txt +13 -0
- alysis_code/assets/owl/ascii/f-016.txt +13 -0
- alysis_code/assets/owl/ascii/f-017.txt +13 -0
- alysis_code/assets/owl/ascii/f-018.txt +13 -0
- alysis_code/assets/owl/ascii/f-019.txt +13 -0
- alysis_code/assets/owl/ascii/f-020.txt +13 -0
- alysis_code/assets/owl/index.html +98 -0
- alysis_code/assets/owl/show-owl.sh +761 -0
- alysis_code/assets/paths.py +49 -0
- alysis_code/assets/plan_binding.py +326 -0
- alysis_code/assets/planner_context.py +466 -0
- alysis_code/assets/planner_tools.py +184 -0
- alysis_code/assets/prompts.py +101 -0
- alysis_code/assets/replanner_context.py +239 -0
- alysis_code/assets/surface.py +521 -0
- alysis_code/assets/untrusted_content.py +48 -0
- alysis_code/assets/usage_logger.py +94 -0
- alysis_code/assets/worker_mirror.py +428 -0
- alysis_code/assets/worker_section.py +303 -0
- alysis_code/assets/worker_tools.py +468 -0
- alysis_code/atomic_io.py +83 -0
- alysis_code/auth_diagnostics.py +272 -0
- alysis_code/background_runner.py +366 -0
- alysis_code/branding.py +270 -0
- alysis_code/budget_policy.py +390 -0
- alysis_code/build_identity.py +465 -0
- alysis_code/builtin_hooks/__init__.py +7 -0
- alysis_code/builtin_hooks/notify_done_windows.py +65 -0
- alysis_code/bwrap_etc.py +76 -0
- alysis_code/cancellation.py +41 -0
- alysis_code/capabilities.py +137 -0
- alysis_code/chatgpt_codex_static_provider.py +133 -0
- alysis_code/cli.py +51 -0
- alysis_code/cli_impl/__init__.py +1 -0
- alysis_code/cli_impl/assets_cli.py +537 -0
- alysis_code/cli_impl/assets_modal.py +412 -0
- alysis_code/cli_impl/chat/__init__.py +156 -0
- alysis_code/cli_impl/chat/commands.py +2616 -0
- alysis_code/cli_impl/chat/loop.py +4508 -0
- alysis_code/cli_impl/chat/mid_turn_policy.py +125 -0
- alysis_code/cli_impl/chat/rendering.py +444 -0
- alysis_code/cli_impl/chat/state.py +124 -0
- alysis_code/cli_impl/chat_resume.py +830 -0
- alysis_code/cli_impl/chat_slash_completer.py +258 -0
- alysis_code/cli_impl/commands/__init__.py +11 -0
- alysis_code/cli_impl/commands/_shared.py +89 -0
- alysis_code/cli_impl/commands/auth.py +623 -0
- alysis_code/cli_impl/commands/chat_resume_helpers.py +1531 -0
- alysis_code/cli_impl/commands/chat_state.py +158 -0
- alysis_code/cli_impl/commands/chat_status.py +1248 -0
- alysis_code/cli_impl/commands/chat_terminal.py +942 -0
- alysis_code/cli_impl/commands/chat_tui_panels.py +1018 -0
- alysis_code/cli_impl/commands/cli_common.py +1223 -0
- alysis_code/cli_impl/commands/cli_surface.py +77 -0
- alysis_code/cli_impl/commands/config.py +131 -0
- alysis_code/cli_impl/commands/conventions.py +85 -0
- alysis_code/cli_impl/commands/execution_helpers.py +350 -0
- alysis_code/cli_impl/commands/extensions.py +401 -0
- alysis_code/cli_impl/commands/forge.py +1282 -0
- alysis_code/cli_impl/commands/forge_asset_view.py +121 -0
- alysis_code/cli_impl/commands/forge_helpers.py +1215 -0
- alysis_code/cli_impl/commands/hooks.py +737 -0
- alysis_code/cli_impl/commands/ide_bridge.py +31 -0
- alysis_code/cli_impl/commands/mcp.py +700 -0
- alysis_code/cli_impl/commands/profile.py +453 -0
- alysis_code/cli_impl/commands/prompt_helpers.py +307 -0
- alysis_code/cli_impl/commands/report.py +88 -0
- alysis_code/cli_impl/commands/root.py +1118 -0
- alysis_code/cli_impl/commands/sandbox.py +184 -0
- alysis_code/cli_impl/commands/server.py +54 -0
- alysis_code/cli_impl/commands/sessions.py +252 -0
- alysis_code/cli_impl/commands/skills.py +404 -0
- alysis_code/cli_impl/commands/startup.py +946 -0
- alysis_code/cli_impl/commands/tools.py +335 -0
- alysis_code/cli_impl/commands/update.py +364 -0
- alysis_code/cli_impl/commands/welcome.py +972 -0
- alysis_code/cli_impl/config_menu.py +3882 -0
- alysis_code/cli_impl/forge.py +4509 -0
- alysis_code/cli_impl/forge_recovery.py +485 -0
- alysis_code/cli_impl/setup_wizard.py +2409 -0
- alysis_code/cli_impl/tui/__init__.py +58 -0
- alysis_code/cli_impl/tui/app.py +4551 -0
- alysis_code/cli_impl/tui/config.py +32 -0
- alysis_code/cli_impl/tui/config_flow.py +2754 -0
- alysis_code/cli_impl/tui/config_overlay.py +566 -0
- alysis_code/cli_impl/tui/content.py +78 -0
- alysis_code/cli_impl/tui/footer.py +218 -0
- alysis_code/cli_impl/tui/forge_status.py +136 -0
- alysis_code/cli_impl/tui/markdown.py +244 -0
- alysis_code/cli_impl/tui/owl.py +109 -0
- alysis_code/cli_impl/tui/plan_meta.py +477 -0
- alysis_code/cli_impl/tui/setup_app.py +519 -0
- alysis_code/cli_impl/tui/setup_flow.py +1622 -0
- alysis_code/cli_impl/tui/state.py +101 -0
- alysis_code/cli_impl/tui/subagent_identity.py +66 -0
- alysis_code/cli_impl/tui/subagent_panel.py +186 -0
- alysis_code/cli_impl/tui/surface.py +796 -0
- alysis_code/cli_impl/tui/transcript.py +514 -0
- alysis_code/cli_impl/tui/update_prompt.py +79 -0
- alysis_code/cli_impl/tui/workspace_guard.py +384 -0
- alysis_code/clipboard.py +172 -0
- alysis_code/code_review.py +1211 -0
- alysis_code/compaction/__init__.py +28 -0
- alysis_code/compaction/conversation_compactor.py +2932 -0
- alysis_code/compaction/importance.py +177 -0
- alysis_code/compaction/settings.py +297 -0
- alysis_code/compaction/tool_output_offload.py +447 -0
- alysis_code/config.py +3509 -0
- alysis_code/conflict_auto_resolver.py +895 -0
- alysis_code/context/__init__.py +1 -0
- alysis_code/context/tool_schema_budgeter.py +220 -0
- alysis_code/crash_diagnostics.py +282 -0
- alysis_code/custom_tools/README.md +34 -0
- alysis_code/custom_tools/__init__.py +43 -0
- alysis_code/custom_tools/discovery.py +903 -0
- alysis_code/custom_tools/runtime.py +1516 -0
- alysis_code/custom_tools/session.py +227 -0
- alysis_code/custom_tools/trust.py +232 -0
- alysis_code/diff_paths.py +113 -0
- alysis_code/direction_change.py +293 -0
- alysis_code/dispatch_timing.py +306 -0
- alysis_code/durable_service_manager.py +1236 -0
- alysis_code/edit_discipline.py +659 -0
- alysis_code/error_text.py +73 -0
- alysis_code/execution_budget.py +411 -0
- alysis_code/execution_context.py +915 -0
- alysis_code/execution_deadline.py +1065 -0
- alysis_code/execution_shared.py +1904 -0
- alysis_code/extensions/README.md +30 -0
- alysis_code/extensions/__init__.py +93 -0
- alysis_code/extensions/activation.py +138 -0
- alysis_code/extensions/install.py +1436 -0
- alysis_code/extensions/manifest.py +487 -0
- alysis_code/extensions/models.py +74 -0
- alysis_code/extensions/paths.py +56 -0
- alysis_code/extensions/registry.json +4 -0
- alysis_code/extensions/registry.py +52 -0
- alysis_code/extensions/state.py +83 -0
- alysis_code/extensions/workspace_trust.py +101 -0
- alysis_code/failed_task_evidence.py +369 -0
- alysis_code/failure_category.py +315 -0
- alysis_code/feedback_report.py +1647 -0
- alysis_code/file_classification.py +485 -0
- alysis_code/forge.py +2064 -0
- alysis_code/forge_completion.py +362 -0
- alysis_code/forge_events.py +475 -0
- alysis_code/frontmatter_utils.py +95 -0
- alysis_code/git_evidence.py +1181 -0
- alysis_code/git_ops.py +560 -0
- alysis_code/git_safe.py +62 -0
- alysis_code/git_worktrees.py +190 -0
- alysis_code/hooks/README.md +33 -0
- alysis_code/hooks/__init__.py +67 -0
- alysis_code/hooks/audit.py +171 -0
- alysis_code/hooks/config.py +225 -0
- alysis_code/hooks/dispatcher.py +1110 -0
- alysis_code/hooks/models.py +447 -0
- alysis_code/hooks/trust.py +202 -0
- alysis_code/host_actions.py +543 -0
- alysis_code/host_browser.py +103 -0
- alysis_code/ide/__init__.py +5 -0
- alysis_code/ide/activity_events.py +399 -0
- alysis_code/ide/approvals.py +337 -0
- alysis_code/ide/artifacts.py +153 -0
- alysis_code/ide/browser_egress_proxy.py +1076 -0
- alysis_code/ide/cdp_websocket_transport.py +1192 -0
- alysis_code/ide/change_ledger.py +1721 -0
- alysis_code/ide/context_blocks.py +979 -0
- alysis_code/ide/event_stream.py +531 -0
- alysis_code/ide/forge_protocol.py +3112 -0
- alysis_code/ide/forge_request_ledger.py +737 -0
- alysis_code/ide/health.py +965 -0
- alysis_code/ide/managed_browser.py +2251 -0
- alysis_code/ide/management_protocol.py +3414 -0
- alysis_code/ide/mcp_oauth_coordinator.py +744 -0
- alysis_code/ide/mcp_oauth_lifecycle.py +1504 -0
- alysis_code/ide/prompt_queue.py +1070 -0
- alysis_code/ide/protocol.py +191 -0
- alysis_code/ide/resumable_swarm.py +1543 -0
- alysis_code/ide/session_search.py +295 -0
- alysis_code/ide/stdio_bridge.py +9935 -0
- alysis_code/ide/structured_state.py +1579 -0
- alysis_code/ide/swarm_protocol.py +816 -0
- alysis_code/integration_gate.py +506 -0
- alysis_code/interactive_input_guard.py +39 -0
- alysis_code/interactive_plan_mode.py +26 -0
- alysis_code/internal_artifacts.py +179 -0
- alysis_code/knowledge_base.py +1409 -0
- alysis_code/knowledge_capture.py +1190 -0
- alysis_code/knowledge_librarian.py +605 -0
- alysis_code/language_policy.py +34 -0
- alysis_code/litellm_static_provider.py +535 -0
- alysis_code/llm/__init__.py +1 -0
- alysis_code/llm/anthropic_messages.py +2288 -0
- alysis_code/llm/base.py +71 -0
- alysis_code/llm/cache_capabilities.py +985 -0
- alysis_code/llm/cache_control_blocks.py +244 -0
- alysis_code/llm/cache_policy.py +388 -0
- alysis_code/llm/factory.py +373 -0
- alysis_code/llm/gemini_generate_content.py +2652 -0
- alysis_code/llm/gemini_interactions.py +739 -0
- alysis_code/llm/metadata.py +450 -0
- alysis_code/llm/openai_compat.py +2947 -0
- alysis_code/llm/openai_responses.py +2604 -0
- alysis_code/llm/protocols.py +609 -0
- alysis_code/llm/provider_limits.py +525 -0
- alysis_code/llm/request_plan.py +389 -0
- alysis_code/llm/request_shape.py +238 -0
- alysis_code/llm/streaming.py +108 -0
- alysis_code/llm/temperature_compat.py +78 -0
- alysis_code/llm/types.py +195 -0
- alysis_code/llm/usage_normalization.py +222 -0
- alysis_code/llm_error_display.py +315 -0
- alysis_code/logging_redaction.py +326 -0
- alysis_code/managed_host_deadline.py +196 -0
- alysis_code/mcp/README.md +33 -0
- alysis_code/mcp/__init__.py +24 -0
- alysis_code/mcp/client.py +1137 -0
- alysis_code/mcp/config.py +597 -0
- alysis_code/mcp/errors.py +113 -0
- alysis_code/mcp/forge_scope.py +154 -0
- alysis_code/mcp/jsonrpc.py +214 -0
- alysis_code/mcp/manager.py +2308 -0
- alysis_code/mcp/models.py +666 -0
- alysis_code/mcp/oauth.py +972 -0
- alysis_code/mcp/oauth_runtime.py +310 -0
- alysis_code/mcp/oauth_store.py +276 -0
- alysis_code/mcp/prompts.py +329 -0
- alysis_code/mcp/resources.py +295 -0
- alysis_code/mcp/roots.py +106 -0
- alysis_code/mcp/server_requests.py +75 -0
- alysis_code/mcp/token_store.py +859 -0
- alysis_code/mcp/transport_http.py +1338 -0
- alysis_code/mcp/transport_stdio.py +1267 -0
- alysis_code/mcp/untrusted_content.py +119 -0
- alysis_code/merge_conflict_reviewer.py +729 -0
- alysis_code/model_catalog/__init__.py +1 -0
- alysis_code/model_catalog/chatgpt_codex_subscription_snapshot.json +186 -0
- alysis_code/model_catalog/litellm_model_prices_snapshot.json +44715 -0
- alysis_code/model_catalog/litellm_model_prices_snapshot.meta.json +17 -0
- alysis_code/model_metadata_policy.py +223 -0
- alysis_code/model_metadata_utils.py +103 -0
- alysis_code/model_registry.py +1420 -0
- alysis_code/model_router.py +147 -0
- alysis_code/permission_policy.py +1016 -0
- alysis_code/personas.py +451 -0
- alysis_code/pipeline_facts.py +233 -0
- alysis_code/plan_assistant.py +4763 -0
- alysis_code/plan_mode.py +393 -0
- alysis_code/plan_reconciliation.py +1228 -0
- alysis_code/plan_repair.py +652 -0
- alysis_code/plan_validation.py +1099 -0
- alysis_code/planning_constraints.py +904 -0
- alysis_code/policy.py +95 -0
- alysis_code/preview_server.py +457 -0
- alysis_code/process_reaping.py +566 -0
- alysis_code/profile_presets.py +1834 -0
- alysis_code/profiles.py +666 -0
- alysis_code/provider_auth/__init__.py +29 -0
- alysis_code/provider_auth/base.py +99 -0
- alysis_code/provider_auth/openai_codex.py +951 -0
- alysis_code/provider_auth/registry.py +76 -0
- alysis_code/provider_auth/store.py +125 -0
- alysis_code/provider_diagnostics.py +1209 -0
- alysis_code/provider_model_catalog.py +685 -0
- alysis_code/provider_telemetry.py +1699 -0
- alysis_code/provider_url.py +75 -0
- alysis_code/reasoning_contracts.py +911 -0
- alysis_code/remote_sync.py +350 -0
- alysis_code/replanning.py +1195 -0
- alysis_code/repo_scan.py +1152 -0
- alysis_code/request_estimation.py +296 -0
- alysis_code/review_gate.py +617 -0
- alysis_code/run_lock.py +1141 -0
- alysis_code/run_outcome.py +58 -0
- alysis_code/run_provenance.py +774 -0
- alysis_code/run_state.py +445 -0
- alysis_code/runtime_artifacts.py +116 -0
- alysis_code/runtime_context_features.py +78 -0
- alysis_code/runtime_kind.py +52 -0
- alysis_code/safety/__init__.py +11 -0
- alysis_code/safety/mcp_sanitize.py +29 -0
- alysis_code/safety/safe_http.py +297 -0
- alysis_code/safety/subagent_report.py +184 -0
- alysis_code/sandbox_doctor.py +682 -0
- alysis_code/sandbox_runner.py +1025 -0
- alysis_code/sandbox_settings.py +423 -0
- alysis_code/serialized_paths.py +355 -0
- alysis_code/server/__init__.py +3 -0
- alysis_code/server/app.py +367 -0
- alysis_code/server/auth.py +34 -0
- alysis_code/server/job_config.py +30 -0
- alysis_code/server/settings.py +215 -0
- alysis_code/server/store.py +193 -0
- alysis_code/server/worker_runner.py +657 -0
- alysis_code/service_persistence.py +355 -0
- alysis_code/session_artifacts.py +108 -0
- alysis_code/session_metrics.py +331 -0
- alysis_code/session_store.py +624 -0
- alysis_code/skills/README.md +34 -0
- alysis_code/skills/__init__.py +104 -0
- alysis_code/skills/conventions.py +84 -0
- alysis_code/skills/discovery.py +176 -0
- alysis_code/skills/eval_models.py +232 -0
- alysis_code/skills/eval_runner.py +372 -0
- alysis_code/skills/evals.py +1344 -0
- alysis_code/skills/install.py +293 -0
- alysis_code/skills/loader.py +118 -0
- alysis_code/skills/matching.py +103 -0
- alysis_code/skills/models.py +71 -0
- alysis_code/skills/paths.py +56 -0
- alysis_code/skills/prompting.py +500 -0
- alysis_code/skills/scaffold.py +142 -0
- alysis_code/skills/state.py +441 -0
- alysis_code/skills/transactions.py +125 -0
- alysis_code/skills/validation.py +304 -0
- alysis_code/step_budget.py +238 -0
- alysis_code/subagent_labels.py +49 -0
- alysis_code/subagents.py +1072 -0
- alysis_code/surface/__init__.py +80 -0
- alysis_code/surface/base.py +305 -0
- alysis_code/surface/console.py +387 -0
- alysis_code/surface/events.py +372 -0
- alysis_code/surface/hidden_surface.py +529 -0
- alysis_code/surface/noop_surface.py +219 -0
- alysis_code/surface/rich_surface.py +1555 -0
- alysis_code/surface/styles.py +67 -0
- alysis_code/surface/theme.py +455 -0
- alysis_code/surface/types.py +100 -0
- alysis_code/swarm_backend.py +926 -0
- alysis_code/swarm_orchestrator.py +4020 -0
- alysis_code/swarm_scheduler.py +441 -0
- alysis_code/swarm_trace.py +429 -0
- alysis_code/swarm_worker.py +2119 -0
- alysis_code/swarm_write_guard.py +348 -0
- alysis_code/task_dependencies.py +170 -0
- alysis_code/task_readiness.py +992 -0
- alysis_code/task_scope.py +2148 -0
- alysis_code/terminal_manager.py +762 -0
- alysis_code/terminal_ownership.py +460 -0
- alysis_code/text_normalization.py +30 -0
- alysis_code/token_budget.py +97 -0
- alysis_code/tools/README.md +34 -0
- alysis_code/tools/__init__.py +1 -0
- alysis_code/tools/artifacts.py +127 -0
- alysis_code/tools/availability.py +188 -0
- alysis_code/tools/fs.py +1456 -0
- alysis_code/tools/git.py +461 -0
- alysis_code/tools/history.py +229 -0
- alysis_code/tools/http_timeout.py +78 -0
- alysis_code/tools/image_generation.py +552 -0
- alysis_code/tools/registry.py +2936 -0
- alysis_code/tools/repo_map.py +476 -0
- alysis_code/tools/search.py +563 -0
- alysis_code/tools/shell.py +135 -0
- alysis_code/tools/symbols.py +1350 -0
- alysis_code/tools/test_discovery.py +643 -0
- alysis_code/tools/web.py +482 -0
- alysis_code/tools/web_search.py +2012 -0
- alysis_code/tools/web_search_dashscope.py +557 -0
- alysis_code/tools/web_search_ddgs.py +221 -0
- alysis_code/tools/web_search_provider_adapters.py +1429 -0
- alysis_code/tools/web_search_tavily.py +194 -0
- alysis_code/updates.py +933 -0
- alysis_code/usage_tracker.py +1990 -0
- alysis_code/verification_command_analysis.py +1004 -0
- alysis_code/verification_contract.py +574 -0
- alysis_code/verification_failure_summary.py +273 -0
- alysis_code/verification_repair.py +385 -0
- alysis_code/verify_gate.py +3129 -0
- alysis_code/web_research.py +1872 -0
- alysis_code/web_search_adapters.py +66 -0
- alysis_code/web_search_policy.py +27 -0
- alysis_code/workspace_binding.py +389 -0
- alysis_code/workspace_binding_ui.py +408 -0
- alysis_code/workspace_context.py +273 -0
- alysis_code/workspace_isolation.py +138 -0
- alysis_code/workspace_provisioning.py +455 -0
- alysis_code-0.13.0.dist-info/METADATA +507 -0
- alysis_code-0.13.0.dist-info/RECORD +458 -0
- alysis_code-0.13.0.dist-info/WHEEL +4 -0
- alysis_code-0.13.0.dist-info/entry_points.txt +3 -0
- alysis_code-0.13.0.dist-info/licenses/LICENSE +176 -0
- 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)
|