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,307 @@
|
|
|
1
|
+
# ruff: noqa: F401,F403,F405,I001
|
|
2
|
+
# Legacy split module: dependencies are synced by cli_surface.py.
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shutil
|
|
6
|
+
|
|
7
|
+
from .cli_common import *
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _chat_prompt_session_completion_count(mode: str) -> int:
|
|
11
|
+
from ..chat_slash_completer import max_completions_for_mode
|
|
12
|
+
|
|
13
|
+
# Chat keeps one PromptSession while the user can enter/leave Forge, so
|
|
14
|
+
# reserve enough room for the larger static command surface at creation.
|
|
15
|
+
return max(
|
|
16
|
+
max_completions_for_mode(mode),
|
|
17
|
+
max_completions_for_mode("chat"),
|
|
18
|
+
max_completions_for_mode("forge"),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _chat_prompt_completion_menu_height(mode: str) -> int:
|
|
23
|
+
completion_count = _chat_prompt_session_completion_count(mode)
|
|
24
|
+
terminal_lines = shutil.get_terminal_size((80, 24)).lines
|
|
25
|
+
return min(completion_count, max(8, int(terminal_lines * 0.6)))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _handle_chat_command(
|
|
29
|
+
*,
|
|
30
|
+
input_text: str,
|
|
31
|
+
root: Path,
|
|
32
|
+
session: Any,
|
|
33
|
+
pending_images: list[str],
|
|
34
|
+
console: Console,
|
|
35
|
+
forge_state: _ForgeChatState,
|
|
36
|
+
plan_mode_state: _ChatPlanModeState,
|
|
37
|
+
) -> str | _ChatExecutionRequest:
|
|
38
|
+
from ..chat import _handle_chat_command_impl
|
|
39
|
+
|
|
40
|
+
return _handle_chat_command_impl(
|
|
41
|
+
_cli_module_for_legacy_impl(),
|
|
42
|
+
input_text=input_text,
|
|
43
|
+
root=root,
|
|
44
|
+
session=session,
|
|
45
|
+
pending_images=pending_images,
|
|
46
|
+
console=console,
|
|
47
|
+
forge_state=forge_state,
|
|
48
|
+
plan_mode_state=plan_mode_state,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _maybe_make_chat_prompt_session(
|
|
53
|
+
*,
|
|
54
|
+
console: Console,
|
|
55
|
+
root: Path,
|
|
56
|
+
pending_images: list[str],
|
|
57
|
+
forge_state: _ForgeChatState,
|
|
58
|
+
session: Any | None = None,
|
|
59
|
+
plan_mode_state: _ChatPlanModeState | None = None,
|
|
60
|
+
) -> Any | None:
|
|
61
|
+
if _patchable("_is_non_interactive_terminal", _is_non_interactive_terminal)():
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
from prompt_toolkit import PromptSession
|
|
66
|
+
from prompt_toolkit.application import run_in_terminal
|
|
67
|
+
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
68
|
+
from prompt_toolkit.history import FileHistory
|
|
69
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
70
|
+
|
|
71
|
+
from ..chat_slash_completer import ChatSlashCompleter
|
|
72
|
+
except Exception:
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
kb = KeyBindings()
|
|
76
|
+
|
|
77
|
+
def _run_paste_image() -> None:
|
|
78
|
+
def _do_paste() -> None:
|
|
79
|
+
try:
|
|
80
|
+
saved = _patchable("paste_clipboard_image", paste_clipboard_image)(
|
|
81
|
+
root=root, output_path=None
|
|
82
|
+
)
|
|
83
|
+
except ClipboardError as e:
|
|
84
|
+
console.print(f"[red]Clipboard error:[/red] {e}")
|
|
85
|
+
return
|
|
86
|
+
pending_images.append(os.fspath(saved))
|
|
87
|
+
console.print(f"Pasted clipboard image: {saved}")
|
|
88
|
+
|
|
89
|
+
run_in_terminal(_do_paste)
|
|
90
|
+
|
|
91
|
+
@kb.add("escape")
|
|
92
|
+
def _escape_hotkey(event: Any) -> None:
|
|
93
|
+
current_buffer = getattr(event, "current_buffer", None)
|
|
94
|
+
if getattr(current_buffer, "complete_state", None) is not None:
|
|
95
|
+
cancel_completion = getattr(current_buffer, "cancel_completion", None)
|
|
96
|
+
if callable(cancel_completion):
|
|
97
|
+
cancel_completion()
|
|
98
|
+
return
|
|
99
|
+
action = _resolve_chat_prompt_escape_action(
|
|
100
|
+
ui_mode=forge_state.ui_mode,
|
|
101
|
+
plan_mode_enabled=_chat_plan_mode_enabled(plan_mode_state),
|
|
102
|
+
buffer_text=str(getattr(current_buffer, "text", "") or ""),
|
|
103
|
+
)
|
|
104
|
+
if action == _CHAT_ESCAPE_ACTION_PLAN_OFF:
|
|
105
|
+
event.app.exit(result=_CHAT_PROMPT_RESULT_PLAN_MODE_OFF)
|
|
106
|
+
return
|
|
107
|
+
if action == _CHAT_ESCAPE_ACTION_NOOP:
|
|
108
|
+
return
|
|
109
|
+
_run_paste_image()
|
|
110
|
+
|
|
111
|
+
@kb.add("c-b")
|
|
112
|
+
def _paste_image_hotkey(_event: Any) -> None:
|
|
113
|
+
_run_paste_image()
|
|
114
|
+
|
|
115
|
+
@kb.add("escape", "c-v")
|
|
116
|
+
def _paste_image_ctrl_alt_v_hotkey(_event: Any) -> None:
|
|
117
|
+
_run_paste_image()
|
|
118
|
+
|
|
119
|
+
@kb.add("c-l")
|
|
120
|
+
def _clear_screen(_event: Any) -> None:
|
|
121
|
+
run_in_terminal(console.clear)
|
|
122
|
+
|
|
123
|
+
@kb.add("tab")
|
|
124
|
+
def _accept_suggestion_or_complete(event: Any) -> None:
|
|
125
|
+
_accept_chat_suggestion_or_complete(event)
|
|
126
|
+
|
|
127
|
+
def _completion_mode() -> str:
|
|
128
|
+
return "forge" if _is_forge_ui_mode(forge_state.ui_mode) else "chat"
|
|
129
|
+
|
|
130
|
+
completer = ChatSlashCompleter(
|
|
131
|
+
mode_provider=_completion_mode,
|
|
132
|
+
skill_names_provider=lambda: sorted(
|
|
133
|
+
str(name) for name in getattr(session, "skill_registry", {})
|
|
134
|
+
),
|
|
135
|
+
)
|
|
136
|
+
prompt_session_kwargs = {
|
|
137
|
+
"key_bindings": kb,
|
|
138
|
+
"auto_suggest": AutoSuggestFromHistory(),
|
|
139
|
+
"completer": completer,
|
|
140
|
+
"complete_while_typing": True,
|
|
141
|
+
"reserve_space_for_menu": _chat_prompt_completion_menu_height(_completion_mode()),
|
|
142
|
+
}
|
|
143
|
+
try:
|
|
144
|
+
history_path = default_chat_history_path()
|
|
145
|
+
history_path.parent.mkdir(parents=True, exist_ok=True)
|
|
146
|
+
prompt_session_kwargs["history"] = FileHistory(os.fspath(history_path))
|
|
147
|
+
except OSError:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
def _prompt_session_supports_cpr(candidate: Any) -> bool:
|
|
151
|
+
output = getattr(getattr(candidate, "app", None), "output", None)
|
|
152
|
+
if output is None:
|
|
153
|
+
return False
|
|
154
|
+
responds_to_cpr = getattr(output, "responds_to_cpr", None)
|
|
155
|
+
if callable(responds_to_cpr):
|
|
156
|
+
try:
|
|
157
|
+
responds_to_cpr = responds_to_cpr()
|
|
158
|
+
except Exception:
|
|
159
|
+
responds_to_cpr = None
|
|
160
|
+
return bool(responds_to_cpr)
|
|
161
|
+
|
|
162
|
+
try:
|
|
163
|
+
prompt_session = PromptSession(
|
|
164
|
+
erase_when_done=True,
|
|
165
|
+
**prompt_session_kwargs,
|
|
166
|
+
)
|
|
167
|
+
prompt_session._alysis_erase_when_done = True # type: ignore[attr-defined]
|
|
168
|
+
except TypeError as e:
|
|
169
|
+
if "erase_when_done" not in str(e):
|
|
170
|
+
raise
|
|
171
|
+
prompt_session = PromptSession(**prompt_session_kwargs)
|
|
172
|
+
prompt_session._alysis_erase_when_done = False # type: ignore[attr-defined]
|
|
173
|
+
|
|
174
|
+
_apply_chat_prompt_escape_sequence_timeout(prompt_session)
|
|
175
|
+
|
|
176
|
+
if not _prompt_session_supports_cpr(prompt_session):
|
|
177
|
+
return None
|
|
178
|
+
return prompt_session
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _apply_chat_prompt_escape_sequence_timeout(prompt_session: Any) -> None:
|
|
182
|
+
"""
|
|
183
|
+
Give VT100 escape sequences a slightly longer grace window before treating
|
|
184
|
+
the leading byte as a standalone Esc hotkey.
|
|
185
|
+
|
|
186
|
+
This keeps the existing plain-Esc behavior, but reduces accidental Plan
|
|
187
|
+
Mode exits on slower terminals where arrow-key sequences can arrive late.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
app = getattr(prompt_session, "app", None)
|
|
191
|
+
if app is None:
|
|
192
|
+
return
|
|
193
|
+
current = getattr(app, "ttimeoutlen", None)
|
|
194
|
+
if isinstance(current, (int, float)):
|
|
195
|
+
app.ttimeoutlen = max(float(current), _CHAT_PROMPT_ESCAPE_SEQUENCE_TIMEOUT_S)
|
|
196
|
+
return
|
|
197
|
+
app.ttimeoutlen = _CHAT_PROMPT_ESCAPE_SEQUENCE_TIMEOUT_S
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _resolve_chat_prompt_escape_action(
|
|
201
|
+
*,
|
|
202
|
+
ui_mode: str,
|
|
203
|
+
plan_mode_enabled: bool,
|
|
204
|
+
buffer_text: str,
|
|
205
|
+
) -> str:
|
|
206
|
+
if _is_forge_ui_mode(ui_mode):
|
|
207
|
+
return _CHAT_ESCAPE_ACTION_PASTE_IMAGE
|
|
208
|
+
if not plan_mode_enabled:
|
|
209
|
+
return _CHAT_ESCAPE_ACTION_PASTE_IMAGE
|
|
210
|
+
if str(buffer_text or "").strip():
|
|
211
|
+
return _CHAT_ESCAPE_ACTION_NOOP
|
|
212
|
+
return _CHAT_ESCAPE_ACTION_PLAN_OFF
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@contextmanager
|
|
216
|
+
def _chat_turn_interrupt_monitor() -> Any:
|
|
217
|
+
# Only enable raw-key monitoring while a turn is running in interactive POSIX terminals.
|
|
218
|
+
if not (sys.stdin.isatty() and os.name == "posix"):
|
|
219
|
+
yield
|
|
220
|
+
return
|
|
221
|
+
try:
|
|
222
|
+
import select
|
|
223
|
+
import signal
|
|
224
|
+
import termios
|
|
225
|
+
import tty
|
|
226
|
+
except Exception:
|
|
227
|
+
yield
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
stop_event = threading.Event()
|
|
231
|
+
|
|
232
|
+
def _watch_escape() -> None:
|
|
233
|
+
try:
|
|
234
|
+
fd = sys.stdin.fileno()
|
|
235
|
+
original = termios.tcgetattr(fd)
|
|
236
|
+
except Exception:
|
|
237
|
+
return
|
|
238
|
+
cbreak_active = False
|
|
239
|
+
|
|
240
|
+
def _enter_cbreak() -> None:
|
|
241
|
+
nonlocal cbreak_active
|
|
242
|
+
if cbreak_active:
|
|
243
|
+
return
|
|
244
|
+
tty.setcbreak(fd)
|
|
245
|
+
cbreak_active = True
|
|
246
|
+
|
|
247
|
+
def _restore_terminal() -> None:
|
|
248
|
+
nonlocal cbreak_active
|
|
249
|
+
if not cbreak_active:
|
|
250
|
+
return
|
|
251
|
+
try:
|
|
252
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, original)
|
|
253
|
+
except Exception:
|
|
254
|
+
pass
|
|
255
|
+
cbreak_active = False
|
|
256
|
+
|
|
257
|
+
try:
|
|
258
|
+
while not stop_event.is_set():
|
|
259
|
+
if is_interactive_prompt_active():
|
|
260
|
+
if not is_interactive_prompt_terminal_owner():
|
|
261
|
+
_restore_terminal()
|
|
262
|
+
stop_event.wait(0.05)
|
|
263
|
+
continue
|
|
264
|
+
_enter_cbreak()
|
|
265
|
+
try:
|
|
266
|
+
readable, _, _ = select.select([fd], [], [], 0.1)
|
|
267
|
+
except Exception:
|
|
268
|
+
return
|
|
269
|
+
if not readable:
|
|
270
|
+
continue
|
|
271
|
+
# A nested approval prompt may have claimed stdin while this
|
|
272
|
+
# watcher was already blocked in select(). Leave the pending
|
|
273
|
+
# byte untouched so the prompt can read it after we restore the
|
|
274
|
+
# terminal to cooked mode.
|
|
275
|
+
if is_interactive_prompt_active():
|
|
276
|
+
continue
|
|
277
|
+
try:
|
|
278
|
+
chunk = os.read(fd, 1)
|
|
279
|
+
except Exception:
|
|
280
|
+
return
|
|
281
|
+
if chunk != b"\x1b":
|
|
282
|
+
continue
|
|
283
|
+
try:
|
|
284
|
+
os.kill(os.getpid(), signal.SIGINT)
|
|
285
|
+
except Exception:
|
|
286
|
+
try:
|
|
287
|
+
signal.raise_signal(signal.SIGINT)
|
|
288
|
+
except Exception:
|
|
289
|
+
return
|
|
290
|
+
return
|
|
291
|
+
finally:
|
|
292
|
+
_restore_terminal()
|
|
293
|
+
|
|
294
|
+
watcher = threading.Thread(
|
|
295
|
+
target=_watch_escape,
|
|
296
|
+
name="alysis-chat-escape-interrupt",
|
|
297
|
+
daemon=True,
|
|
298
|
+
)
|
|
299
|
+
watcher.start()
|
|
300
|
+
try:
|
|
301
|
+
yield
|
|
302
|
+
finally:
|
|
303
|
+
stop_event.set()
|
|
304
|
+
watcher.join(timeout=0.25)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
__all__ = [name for name in globals() if (not name.startswith("__") or name == "__version__")]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from ...config import ConfigError, load_config
|
|
8
|
+
from ...feedback_report import (
|
|
9
|
+
FeedbackReportError,
|
|
10
|
+
create_feedback_bundle,
|
|
11
|
+
create_feedback_github_issue_draft,
|
|
12
|
+
feedback_github_issue_status_lines,
|
|
13
|
+
resolve_feedback_workspace_root,
|
|
14
|
+
)
|
|
15
|
+
from . import _patchable
|
|
16
|
+
from ._shared import _console
|
|
17
|
+
|
|
18
|
+
report_app = typer.Typer(add_completion=False, help="Feedback bundle commands.")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@report_app.command("create")
|
|
22
|
+
def report_create(
|
|
23
|
+
feedback: str | None = typer.Argument(None, help="Optional feedback text."),
|
|
24
|
+
path: Path = typer.Option(Path("."), "--path", help="Workspace path."),
|
|
25
|
+
session_id: str | None = typer.Option(None, "--session-id", help="Retained session id."),
|
|
26
|
+
run_id: str | None = typer.Option(None, "--run-id", help="Forge run id."),
|
|
27
|
+
latest: bool = typer.Option(
|
|
28
|
+
False,
|
|
29
|
+
"--latest",
|
|
30
|
+
help="Use the latest retained session when no active session exists.",
|
|
31
|
+
),
|
|
32
|
+
github: bool | None = typer.Option(
|
|
33
|
+
None,
|
|
34
|
+
"--github/--no-github",
|
|
35
|
+
help="Override feedback GitHub issue draft creation.",
|
|
36
|
+
),
|
|
37
|
+
local_only: bool = typer.Option(
|
|
38
|
+
False,
|
|
39
|
+
"--local-only",
|
|
40
|
+
help="Only create the local bundle; do not create a GitHub issue draft URL.",
|
|
41
|
+
),
|
|
42
|
+
open_browser: bool | None = typer.Option(
|
|
43
|
+
None,
|
|
44
|
+
"--open/--no-open",
|
|
45
|
+
help="Open the GitHub issue draft in a browser. CLI defaults to URL-only.",
|
|
46
|
+
),
|
|
47
|
+
) -> None:
|
|
48
|
+
console = _console()
|
|
49
|
+
if local_only and github is True:
|
|
50
|
+
console.print("[red]Feedback report failed:[/red] Use either --github or --local-only.")
|
|
51
|
+
raise typer.Exit(code=2)
|
|
52
|
+
try:
|
|
53
|
+
cfg = _patchable("load_config", load_config)()
|
|
54
|
+
workspace_root = _patchable(
|
|
55
|
+
"resolve_feedback_workspace_root", resolve_feedback_workspace_root
|
|
56
|
+
)(path)
|
|
57
|
+
result = _patchable("create_feedback_bundle", create_feedback_bundle)(
|
|
58
|
+
workspace_root=workspace_root,
|
|
59
|
+
feedback_text=feedback,
|
|
60
|
+
cfg=cfg,
|
|
61
|
+
session_id=session_id,
|
|
62
|
+
run_id=run_id,
|
|
63
|
+
latest=latest,
|
|
64
|
+
)
|
|
65
|
+
except (ConfigError, FeedbackReportError) as e:
|
|
66
|
+
console.print(f"[red]Feedback report failed:[/red] {e}")
|
|
67
|
+
raise typer.Exit(code=2) from e
|
|
68
|
+
|
|
69
|
+
console.print(f"Feedback bundle directory: {result.bundle_dir}")
|
|
70
|
+
console.print(f"Feedback bundle archive: {result.zip_path}")
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
issue_result = _patchable(
|
|
74
|
+
"create_feedback_github_issue_draft",
|
|
75
|
+
create_feedback_github_issue_draft,
|
|
76
|
+
)(
|
|
77
|
+
bundle_result=result,
|
|
78
|
+
feedback_text=feedback,
|
|
79
|
+
cfg=cfg,
|
|
80
|
+
github_enabled=False if local_only else github,
|
|
81
|
+
open_browser=False if open_browser is None else open_browser,
|
|
82
|
+
)
|
|
83
|
+
except Exception as e: # noqa: BLE001 - GitHub issue drafting is best-effort.
|
|
84
|
+
console.print(f"[yellow]GitHub issue draft skipped:[/yellow] {e}")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
for line in feedback_github_issue_status_lines(issue_result):
|
|
88
|
+
console.print(line)
|