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,355 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path, PurePosixPath, PureWindowsPath
|
|
5
|
+
|
|
6
|
+
_ROOT_IDENTITY_FIELDS = frozenset({"workspace_root", "git_root"})
|
|
7
|
+
_PATH_FIELDS = frozenset(
|
|
8
|
+
{
|
|
9
|
+
"artifact_root",
|
|
10
|
+
"binding_requested_path",
|
|
11
|
+
"bundle_dir",
|
|
12
|
+
"copied_log_path",
|
|
13
|
+
"current_run_pointer_path",
|
|
14
|
+
"cwd",
|
|
15
|
+
"focus_dir",
|
|
16
|
+
"focus_path",
|
|
17
|
+
"log_path",
|
|
18
|
+
"original_path",
|
|
19
|
+
"path",
|
|
20
|
+
"run_dir",
|
|
21
|
+
"session_artifact_dir",
|
|
22
|
+
"source_log_path",
|
|
23
|
+
"zip_path",
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
_COMMON_POSIX_ROOT_SEGMENTS = frozenset(
|
|
27
|
+
{
|
|
28
|
+
"Applications",
|
|
29
|
+
"Library",
|
|
30
|
+
"System",
|
|
31
|
+
"Users",
|
|
32
|
+
"Volumes",
|
|
33
|
+
"bin",
|
|
34
|
+
"boot",
|
|
35
|
+
"data",
|
|
36
|
+
"dev",
|
|
37
|
+
"etc",
|
|
38
|
+
"home",
|
|
39
|
+
"lib",
|
|
40
|
+
"lib64",
|
|
41
|
+
"media",
|
|
42
|
+
"mnt",
|
|
43
|
+
"nix",
|
|
44
|
+
"opt",
|
|
45
|
+
"private",
|
|
46
|
+
"proc",
|
|
47
|
+
"root",
|
|
48
|
+
"run",
|
|
49
|
+
"sbin",
|
|
50
|
+
"snap",
|
|
51
|
+
"srv",
|
|
52
|
+
"sys",
|
|
53
|
+
"tmp",
|
|
54
|
+
"usr",
|
|
55
|
+
"var",
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
_TEXT_PATH_TERMINATORS = frozenset(" \t\r\n`\"'<>(),;![]{}")
|
|
59
|
+
_WINDOWS_DRIVE_ABS_RE = re.compile(r"^[A-Za-z]:[\\/]")
|
|
60
|
+
_WINDOWS_UNC_ABS_RE = re.compile(r"^\\\\[^\\/\s]+[\\/][^\\/\s]+(?:[\\/].*)?$")
|
|
61
|
+
_GENERIC_POSIX_PATH_RE = re.compile(
|
|
62
|
+
r"(?<![:/A-Za-z0-9])(/(?!/)[^\s`\"'<>(),;!()[\]{}]+(?:/[^\s`\"'<>(),;!()[\]{}]+)*)"
|
|
63
|
+
)
|
|
64
|
+
_GENERIC_WINDOWS_PATH_RE = re.compile(
|
|
65
|
+
r"(?<![A-Za-z0-9])([A-Za-z]:[\\/][^\s`\"'<>(),;!()[\]{}\\\/]+(?:[\\/][^\s`\"'<>(),;!()[\]{}\\\/]+)*)"
|
|
66
|
+
)
|
|
67
|
+
_GENERIC_WINDOWS_UNC_PATH_RE = re.compile(
|
|
68
|
+
r"(?<![A-Za-z0-9])((?:\\\\)[^\s`\"'<>(),;!()[\]{}\\\/]+(?:[\\/][^\s`\"'<>(),;!()[\]{}\\\/]+)+)"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _path_is_relative_to(path: Path, root: Path) -> bool:
|
|
73
|
+
try:
|
|
74
|
+
path.relative_to(root)
|
|
75
|
+
return True
|
|
76
|
+
except ValueError:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _normalize_key_name(value: str | None) -> str:
|
|
81
|
+
return str(value or "").strip().lower()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _coerce_path_value(value: str | Path | None) -> tuple[Path, str] | None:
|
|
85
|
+
if value is None:
|
|
86
|
+
return None
|
|
87
|
+
if isinstance(value, Path):
|
|
88
|
+
raw = str(value).strip()
|
|
89
|
+
if not raw:
|
|
90
|
+
return None
|
|
91
|
+
return value, raw
|
|
92
|
+
raw = str(value).strip()
|
|
93
|
+
if not raw:
|
|
94
|
+
return None
|
|
95
|
+
return Path(raw), raw
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _is_posix_absolute_path_text(raw: str) -> bool:
|
|
99
|
+
return raw.startswith("/") and not raw.startswith("//")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _is_windows_drive_absolute_path_text(raw: str) -> bool:
|
|
103
|
+
return bool(_WINDOWS_DRIVE_ABS_RE.match(raw))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _is_windows_unc_absolute_path_text(raw: str) -> bool:
|
|
107
|
+
return bool(_WINDOWS_UNC_ABS_RE.match(raw))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _is_windows_absolute_path_text(raw: str) -> bool:
|
|
111
|
+
return _is_windows_drive_absolute_path_text(raw) or _is_windows_unc_absolute_path_text(raw)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _looks_like_absolute_path_text(raw: str) -> bool:
|
|
115
|
+
return _is_posix_absolute_path_text(raw) or _is_windows_absolute_path_text(raw)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _host_windows_root(root: Path | None) -> PureWindowsPath | None:
|
|
119
|
+
if root is None:
|
|
120
|
+
return None
|
|
121
|
+
raw = str(root.resolve())
|
|
122
|
+
if not _is_windows_absolute_path_text(raw):
|
|
123
|
+
return None
|
|
124
|
+
return PureWindowsPath(raw)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _pure_path_is_relative_to(
|
|
128
|
+
path: PurePosixPath | PureWindowsPath, root: PurePosixPath | PureWindowsPath
|
|
129
|
+
) -> bool:
|
|
130
|
+
try:
|
|
131
|
+
path.relative_to(root)
|
|
132
|
+
return True
|
|
133
|
+
except ValueError:
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _serialized_path_basename(raw: str) -> str:
|
|
138
|
+
if _is_windows_absolute_path_text(raw):
|
|
139
|
+
basename = PureWindowsPath(raw).name
|
|
140
|
+
if basename:
|
|
141
|
+
return basename
|
|
142
|
+
elif _is_posix_absolute_path_text(raw):
|
|
143
|
+
basename = PurePosixPath(raw).name
|
|
144
|
+
if basename:
|
|
145
|
+
return basename
|
|
146
|
+
|
|
147
|
+
parts = [part for part in re.split(r"[\\/]+", raw.rstrip("\\/")) if part]
|
|
148
|
+
if not parts:
|
|
149
|
+
return "path"
|
|
150
|
+
return parts[-1].rstrip(":") or "path"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def redacted_host_path_label(value: str | Path | None) -> str | None:
|
|
154
|
+
coerced = _coerce_path_value(value)
|
|
155
|
+
if coerced is None:
|
|
156
|
+
return None
|
|
157
|
+
_, raw = coerced
|
|
158
|
+
basename = _serialized_path_basename(raw)
|
|
159
|
+
return f"[redacted host path: {basename}]"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _workspace_root_candidates(workspace_root: Path) -> tuple[str, ...]:
|
|
163
|
+
resolved = workspace_root.resolve()
|
|
164
|
+
candidates = [str(resolved)]
|
|
165
|
+
posix = resolved.as_posix()
|
|
166
|
+
if posix not in candidates:
|
|
167
|
+
candidates.append(posix)
|
|
168
|
+
return tuple(sorted(candidates, key=len, reverse=True))
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _consume_path_suffix(text: str, *, start: int) -> tuple[str, int]:
|
|
172
|
+
end = start
|
|
173
|
+
while end < len(text) and text[end] not in _TEXT_PATH_TERMINATORS:
|
|
174
|
+
end += 1
|
|
175
|
+
return text[start:end], end
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _sanitize_workspace_root_paths_in_text(text: str, *, workspace_root: Path) -> str:
|
|
179
|
+
sanitized = text
|
|
180
|
+
for root_text in _workspace_root_candidates(workspace_root):
|
|
181
|
+
pieces: list[str] = []
|
|
182
|
+
cursor = 0
|
|
183
|
+
while True:
|
|
184
|
+
index = sanitized.find(root_text, cursor)
|
|
185
|
+
if index < 0:
|
|
186
|
+
pieces.append(sanitized[cursor:])
|
|
187
|
+
break
|
|
188
|
+
pieces.append(sanitized[cursor:index])
|
|
189
|
+
suffix, end = _consume_path_suffix(sanitized, start=index + len(root_text))
|
|
190
|
+
full_path = root_text + suffix
|
|
191
|
+
pieces.append(
|
|
192
|
+
safe_serialized_path(full_path, workspace_root=workspace_root) or full_path
|
|
193
|
+
)
|
|
194
|
+
cursor = end
|
|
195
|
+
sanitized = "".join(pieces)
|
|
196
|
+
return sanitized
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _posix_root_segment_exists(root_segment: str) -> bool:
|
|
200
|
+
try:
|
|
201
|
+
return Path("/" + root_segment).exists()
|
|
202
|
+
except OSError:
|
|
203
|
+
return False
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _looks_like_generic_posix_path(candidate: str) -> bool:
|
|
207
|
+
coerced = _coerce_path_value(candidate)
|
|
208
|
+
if coerced is None:
|
|
209
|
+
return False
|
|
210
|
+
_, raw = coerced
|
|
211
|
+
if not _is_posix_absolute_path_text(raw):
|
|
212
|
+
return False
|
|
213
|
+
parts = PurePosixPath(raw).parts
|
|
214
|
+
if len(parts) < 2:
|
|
215
|
+
return False
|
|
216
|
+
root_segment = str(parts[1] or "").strip()
|
|
217
|
+
if not root_segment:
|
|
218
|
+
return False
|
|
219
|
+
# Free-form bundle sanitization must not treat arbitrary slash routes like
|
|
220
|
+
# /v1/chat/completions as host paths. Only redact generic POSIX candidates
|
|
221
|
+
# when they start from a known filesystem root or an actual root directory
|
|
222
|
+
# on the current host.
|
|
223
|
+
return root_segment in _COMMON_POSIX_ROOT_SEGMENTS or _posix_root_segment_exists(root_segment)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def sanitize_paths_in_text(text: str, *, workspace_root: Path | None = None) -> str:
|
|
227
|
+
sanitized = str(text or "")
|
|
228
|
+
if workspace_root is not None:
|
|
229
|
+
# Replace known workspace-root prefixes first so repo-owned paths become
|
|
230
|
+
# repo-relative even in plain-text artifacts like markdown summaries and logs.
|
|
231
|
+
sanitized = _sanitize_workspace_root_paths_in_text(sanitized, workspace_root=workspace_root)
|
|
232
|
+
|
|
233
|
+
def _replace(match: re.Match[str]) -> str:
|
|
234
|
+
candidate = match.group(1)
|
|
235
|
+
if not _looks_like_generic_posix_path(candidate):
|
|
236
|
+
return candidate
|
|
237
|
+
return safe_serialized_path(candidate, workspace_root=workspace_root) or candidate
|
|
238
|
+
|
|
239
|
+
def _replace_windows(match: re.Match[str]) -> str:
|
|
240
|
+
candidate = match.group(1)
|
|
241
|
+
if not _is_windows_absolute_path_text(candidate):
|
|
242
|
+
return candidate
|
|
243
|
+
return safe_serialized_path(candidate, workspace_root=workspace_root) or candidate
|
|
244
|
+
|
|
245
|
+
sanitized = _GENERIC_POSIX_PATH_RE.sub(_replace, sanitized)
|
|
246
|
+
sanitized = _GENERIC_WINDOWS_UNC_PATH_RE.sub(_replace_windows, sanitized)
|
|
247
|
+
sanitized = _GENERIC_WINDOWS_PATH_RE.sub(_replace_windows, sanitized)
|
|
248
|
+
return sanitized
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def safe_serialized_path(
|
|
252
|
+
value: str | Path | None,
|
|
253
|
+
*,
|
|
254
|
+
workspace_root: Path | None = None,
|
|
255
|
+
bundle_root: Path | None = None,
|
|
256
|
+
prefer_bundle_relative: bool = False,
|
|
257
|
+
) -> str | None:
|
|
258
|
+
coerced = _coerce_path_value(value)
|
|
259
|
+
if coerced is None:
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
_, raw = coerced
|
|
263
|
+
if not _looks_like_absolute_path_text(raw):
|
|
264
|
+
return raw
|
|
265
|
+
|
|
266
|
+
if _is_windows_absolute_path_text(raw):
|
|
267
|
+
candidate = PureWindowsPath(raw)
|
|
268
|
+
bundle_root_windows = _host_windows_root(bundle_root)
|
|
269
|
+
workspace_root_windows = _host_windows_root(workspace_root)
|
|
270
|
+
|
|
271
|
+
if (
|
|
272
|
+
prefer_bundle_relative
|
|
273
|
+
and bundle_root_windows is not None
|
|
274
|
+
and _pure_path_is_relative_to(candidate, bundle_root_windows)
|
|
275
|
+
):
|
|
276
|
+
rel = candidate.relative_to(bundle_root_windows).as_posix()
|
|
277
|
+
return rel or "."
|
|
278
|
+
|
|
279
|
+
if workspace_root_windows is not None and _pure_path_is_relative_to(
|
|
280
|
+
candidate, workspace_root_windows
|
|
281
|
+
):
|
|
282
|
+
rel = candidate.relative_to(workspace_root_windows).as_posix()
|
|
283
|
+
return rel or "."
|
|
284
|
+
|
|
285
|
+
return redacted_host_path_label(raw)
|
|
286
|
+
|
|
287
|
+
# pathlib.Path absolute detection is host-dependent, so serialized Windows
|
|
288
|
+
# strings are handled above with PureWindowsPath. Real host POSIX paths keep
|
|
289
|
+
# the existing resolved/relative behavior here.
|
|
290
|
+
resolved = Path(raw).expanduser().resolve(strict=False)
|
|
291
|
+
bundle_root_resolved = bundle_root.resolve() if bundle_root is not None else None
|
|
292
|
+
workspace_root_resolved = workspace_root.resolve() if workspace_root is not None else None
|
|
293
|
+
|
|
294
|
+
if (
|
|
295
|
+
prefer_bundle_relative
|
|
296
|
+
and bundle_root_resolved is not None
|
|
297
|
+
and _path_is_relative_to(resolved, bundle_root_resolved)
|
|
298
|
+
):
|
|
299
|
+
rel = resolved.relative_to(bundle_root_resolved).as_posix()
|
|
300
|
+
return rel or "."
|
|
301
|
+
|
|
302
|
+
if workspace_root_resolved is not None and _path_is_relative_to(
|
|
303
|
+
resolved, workspace_root_resolved
|
|
304
|
+
):
|
|
305
|
+
rel = resolved.relative_to(workspace_root_resolved).as_posix()
|
|
306
|
+
return rel or "."
|
|
307
|
+
|
|
308
|
+
return redacted_host_path_label(raw)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def safe_serialized_path_field(
|
|
312
|
+
field_name: str,
|
|
313
|
+
value: str | Path | None,
|
|
314
|
+
*,
|
|
315
|
+
workspace_root: Path | None = None,
|
|
316
|
+
bundle_root: Path | None = None,
|
|
317
|
+
prefer_bundle_relative: bool = False,
|
|
318
|
+
) -> str | None:
|
|
319
|
+
normalized = _normalize_key_name(field_name)
|
|
320
|
+
if normalized == "workspace_root":
|
|
321
|
+
if workspace_root is not None:
|
|
322
|
+
coerced = _coerce_path_value(value)
|
|
323
|
+
if coerced is not None:
|
|
324
|
+
resolved = coerced[0].expanduser().resolve(strict=False)
|
|
325
|
+
if resolved == workspace_root.resolve():
|
|
326
|
+
return "<workspace-root>"
|
|
327
|
+
return safe_serialized_path(
|
|
328
|
+
value,
|
|
329
|
+
workspace_root=workspace_root,
|
|
330
|
+
bundle_root=bundle_root,
|
|
331
|
+
prefer_bundle_relative=prefer_bundle_relative,
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
if normalized == "git_root" and workspace_root is not None:
|
|
335
|
+
coerced = _coerce_path_value(value)
|
|
336
|
+
if coerced is not None:
|
|
337
|
+
resolved = coerced[0].expanduser().resolve(strict=False)
|
|
338
|
+
if resolved == workspace_root.resolve():
|
|
339
|
+
return "<workspace-root>"
|
|
340
|
+
|
|
341
|
+
return safe_serialized_path(
|
|
342
|
+
value,
|
|
343
|
+
workspace_root=workspace_root,
|
|
344
|
+
bundle_root=bundle_root,
|
|
345
|
+
prefer_bundle_relative=prefer_bundle_relative,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def looks_like_serialized_path_field(field_name: str | None) -> bool:
|
|
350
|
+
normalized = _normalize_key_name(field_name)
|
|
351
|
+
if not normalized:
|
|
352
|
+
return False
|
|
353
|
+
if normalized in _ROOT_IDENTITY_FIELDS or normalized in _PATH_FIELDS:
|
|
354
|
+
return True
|
|
355
|
+
return normalized.endswith(("_path", "_dir", "_root"))
|