aria-code 0.52.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.
- aria_code/__init__.py +42 -0
- aria_code/_version.py +20 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +34 -0
- aria_code/agents/base.py +318 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +303 -0
- aria_code/agents/financial/fundamental.py +191 -0
- aria_code/agents/financial/macro.py +99 -0
- aria_code/agents/financial/news.py +207 -0
- aria_code/agents/financial/risk.py +165 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +258 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +363 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +158 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +492 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +15 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +95 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/bootstrap.py +145 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +16 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +369 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +239 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
- aria_code/apps/cli/commands/broker_cmds.py +1234 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +87 -0
- aria_code/apps/cli/commands/core_cmds.py +2520 -0
- aria_code/apps/cli/commands/data_cmds.py +457 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +434 -0
- aria_code/apps/cli/commands/market_cmds.py +1381 -0
- aria_code/apps/cli/commands/market_context.py +425 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2153 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
- aria_code/apps/cli/commands/report.py +437 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +669 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
- aria_code/apps/cli/commands/workflow_cmds.py +480 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +78 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/deterministic.py +191 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +196 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
- aria_code/apps/cli/handlers/market_handlers.py +2513 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/helpers.py +302 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +297 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +276 -0
- aria_code/apps/cli/intent_signals.py +344 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +536 -0
- aria_code/apps/cli/main.py +29 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/model_catalog.py +620 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +59 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +53 -0
- aria_code/apps/cli/prompts/select.py +142 -0
- aria_code/apps/cli/prompts/system_prompts.py +552 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +521 -0
- aria_code/apps/cli/providers/chat_routing.py +128 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
- aria_code/apps/cli/providers/runtime_bridge.py +353 -0
- aria_code/apps/cli/providers/vertexai_stream.py +316 -0
- aria_code/apps/cli/runtime_consumer.py +657 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_store.py +112 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +823 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +106 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +180 -0
- aria_code/apps/cli/tools/market_tools.py +620 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +726 -0
- aria_code/apps/cli/tools/write_tools.py +845 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +153 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1597 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +6743 -0
- aria_code/aria_daemon.py +1398 -0
- aria_code/aria_feishu_bot.py +1423 -0
- aria_code/aria_mcp_server.py +7 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_relay_server.py +490 -0
- aria_code/aria_telegram_bot.py +202 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +182 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1976 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +181 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/demo_player.py +207 -0
- aria_code/doctor.py +813 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/backtest_engine.py +354 -0
- aria_code/domain/backtest_report.py +472 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/harness.py +598 -0
- aria_code/evals/runner.py +238 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +386 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +639 -0
- aria_code/memory_manager.py +246 -0
- aria_code/model_capability.py +486 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +23 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +52 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +201 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +111 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1550 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +396 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +79 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +268 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +57 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +157 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +8 -0
- aria_code/packages/aria_tools/financial/_paths.py +130 -0
- aria_code/packages/aria_tools/financial/compliance.py +31 -0
- aria_code/packages/aria_tools/financial/factors.py +33 -0
- aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
- aria_code/packages/aria_tools/financial/strategy.py +31 -0
- aria_code/packages/aria_tools/registry.py +128 -0
- aria_code/packages/quant_engine/__init__.py +34 -0
- aria_code/packages/quant_engine/_namespace.py +62 -0
- aria_code/packages/quant_engine/backtest/__init__.py +14 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +96 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +80 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/ml_model.py +377 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/logistics/__init__.py +169 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +129 -0
- aria_code/providers/llm/openai_compat.py +313 -0
- aria_code/providers/llm/registry.py +444 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +589 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/runtime/__init__.py +169 -0
- aria_code/runtime/acceptance.py +481 -0
- aria_code/runtime/agent_loop.py +1520 -0
- aria_code/runtime/approval.py +57 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +432 -0
- aria_code/runtime/crash_report.py +174 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +150 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/repo_map.py +700 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +450 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/subagent.py +547 -0
- aria_code/runtime/task_ledger.py +86 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/tool_executor.py +217 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +23 -0
- aria_code/safety/permissions.py +306 -0
- aria_code/safety/service.py +102 -0
- aria_code/setup_wizard.py +673 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +504 -0
- aria_code/tools/data_analysis_tools.py +809 -0
- aria_code/tools/enterprise_finance_tools.py +156 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +885 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3417 -0
- aria_code/tools/logistics_tools.py +135 -0
- aria_code/tools/macro_tools.py +369 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +659 -0
- aria_code/tools/spreadsheet_tools.py +388 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +508 -0
- aria_code/ui/completer.py +501 -0
- aria_code/ui/console.py +281 -0
- aria_code/ui/image_render.py +243 -0
- aria_code/ui/input_box.py +488 -0
- aria_code/ui/picker.py +201 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/finance.py +1705 -0
- aria_code/ui/render/market.py +225 -0
- aria_code/ui/render/output.py +775 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +354 -0
- aria_code/ui/robot.py +235 -0
- aria_code/ui/startup_dashboard.py +109 -0
- aria_code/utils/vscode_uri.py +37 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +271 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +193 -0
- aria_code/workspace/verify.py +113 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_context.py +233 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.52.0.dist-info/METADATA +237 -0
- aria_code-0.52.0.dist-info/RECORD +478 -0
- aria_code-0.52.0.dist-info/WHEEL +5 -0
- aria_code-0.52.0.dist-info/entry_points.txt +3 -0
- aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.52.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"""prompt_toolkit completer and base style for the Aria REPL.
|
|
2
|
+
|
|
3
|
+
Improvements over the original:
|
|
4
|
+
- Instant popup: triggers as soon as "/" is typed (no extra keypress needed)
|
|
5
|
+
- Fuzzy match: "/ch" matches /chart, /check, /watch; "/ta" matches /stat-arb
|
|
6
|
+
- Matched chars highlighted in amber so they're visible in all rows
|
|
7
|
+
- Results ranked: exact-prefix > fuzzy-command > description-fuzzy
|
|
8
|
+
- Category tag shown in display_meta (市场 / 分析 / 量化 / 数据源 …)
|
|
9
|
+
|
|
10
|
+
from ui.completer import AriaPTCompleter, ARIA_PT_STYLE
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import re
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Iterator, List, Tuple
|
|
18
|
+
|
|
19
|
+
from aria_code.ui.console import HAS_PT
|
|
20
|
+
from aria_code.packages.aria_services.references import REFERENCE_KINDS, reference_search_roots
|
|
21
|
+
|
|
22
|
+
_REFERENCE_KIND_NAMES = frozenset(item.name for item in REFERENCE_KINDS)
|
|
23
|
+
|
|
24
|
+
# ── Category map ────────────────────────────────────────────────────────────
|
|
25
|
+
# Keyed on command name fragments; first match wins.
|
|
26
|
+
_CATS: List[Tuple[Tuple[str, ...], str]] = [
|
|
27
|
+
(("/quote", "/market", "/macro", "/watch", "/alert", "/hot", "/indices",
|
|
28
|
+
"/cn", "/hk", "/crypto", "/forex", "/commodity", "/funding", "/feargreed",
|
|
29
|
+
"/edgar", "/datasource"), "市场"),
|
|
30
|
+
(("/team", "/analyze", "/options", "/factor", "/ta", "/ichimoku",
|
|
31
|
+
"/peer", "/quality", "/risk", "/signal", "/predict", "/earnings",
|
|
32
|
+
"/insights", "/deep", "/morning", "/trade-idea", "/research"), "分析"),
|
|
33
|
+
(("/backtest", "/wf", "/compare", "/execution", "/stat-arb",
|
|
34
|
+
"/ptbt", "/corr", "/optimize", "/stress", "/auto-strategy",
|
|
35
|
+
"/portfolio", "/journal"), "量化"),
|
|
36
|
+
(("/chart", "/report", "/shortterm", "/longterm", "/cloudbt"), "图表"),
|
|
37
|
+
(("/project", "/file", "/run", "/code", "/scaffold", "/init",
|
|
38
|
+
"/review", "/vision", "/browser", "/web"), "工具"),
|
|
39
|
+
(("/config", "/model", "/apikey", "/setup", "/local", "/mcp",
|
|
40
|
+
"/memory", "/cost", "/version"), "设置"),
|
|
41
|
+
(("/help", "/clear", "/btw", "/recap", "/exit", "/quit", "/history", "/session",
|
|
42
|
+
"/bug", "/feedback", "/privacy"), "系统"),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
_CAT_BADGE: dict[str, str] = {
|
|
46
|
+
"市场": "mkt",
|
|
47
|
+
"分析": "ana",
|
|
48
|
+
"量化": "qnt",
|
|
49
|
+
"图表": "viz",
|
|
50
|
+
"工具": "dev",
|
|
51
|
+
"设置": "cfg",
|
|
52
|
+
"系统": "sys",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _get_cat(name: str) -> str:
|
|
57
|
+
for prefixes, cat in _CATS:
|
|
58
|
+
for p in prefixes:
|
|
59
|
+
if name.startswith(p):
|
|
60
|
+
return cat
|
|
61
|
+
return ""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ── Fuzzy matching ───────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
def _fuzzy(pattern: str, text: str) -> Tuple[bool, List[int]]:
|
|
67
|
+
"""
|
|
68
|
+
Sequential fuzzy match — pattern chars must appear in order in text.
|
|
69
|
+
Returns (matched, indices_of_matched_chars_in_text).
|
|
70
|
+
Consecutive matches score higher because they produce a compact index list.
|
|
71
|
+
"""
|
|
72
|
+
if not pattern:
|
|
73
|
+
return True, []
|
|
74
|
+
pi = 0
|
|
75
|
+
indices: List[int] = []
|
|
76
|
+
for i, ch in enumerate(text):
|
|
77
|
+
if ch.lower() == pattern[pi].lower():
|
|
78
|
+
indices.append(i)
|
|
79
|
+
pi += 1
|
|
80
|
+
if pi == len(pattern):
|
|
81
|
+
return True, indices
|
|
82
|
+
return False, []
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _score(name: str, pattern: str, indices: List[int]) -> int:
|
|
86
|
+
"""
|
|
87
|
+
Lower score = better.
|
|
88
|
+
0 exact match
|
|
89
|
+
1 exact prefix (/ch → /chart)
|
|
90
|
+
5 word-segment exact match (/arb → /stat-arb because '-arb' segment)
|
|
91
|
+
10 consecutive run from position 0
|
|
92
|
+
12+ consecutive run from a word boundary
|
|
93
|
+
15+ consecutive run from elsewhere
|
|
94
|
+
20+ non-consecutive from a word boundary
|
|
95
|
+
30+ scattered fuzzy match
|
|
96
|
+
"""
|
|
97
|
+
if name == pattern:
|
|
98
|
+
return 0
|
|
99
|
+
if name.startswith(pattern):
|
|
100
|
+
return 1
|
|
101
|
+
if not indices:
|
|
102
|
+
return 99
|
|
103
|
+
|
|
104
|
+
# Word-segment exact match: pattern matches a whole segment after "-" or "_"
|
|
105
|
+
bare = name.lstrip("/")
|
|
106
|
+
pat_bare = pattern.lstrip("/")
|
|
107
|
+
for sep in ("-", "_"):
|
|
108
|
+
for seg in bare.split(sep)[1:]: # skip first segment (already caught by prefix)
|
|
109
|
+
if seg == pat_bare or seg.startswith(pat_bare):
|
|
110
|
+
return 5 + len(sep) # score 6 for "-", 6 for "_"
|
|
111
|
+
|
|
112
|
+
start = indices[0]
|
|
113
|
+
consecutive = (indices == list(range(start, start + len(indices))))
|
|
114
|
+
at_boundary = start == 0 or (start > 0 and bare[start - 1] in "-_")
|
|
115
|
+
|
|
116
|
+
if consecutive:
|
|
117
|
+
if start == 0:
|
|
118
|
+
return 10
|
|
119
|
+
if at_boundary:
|
|
120
|
+
return 12 + start
|
|
121
|
+
return 15 + start
|
|
122
|
+
if at_boundary:
|
|
123
|
+
return 20 + start
|
|
124
|
+
return 30 + start
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# ── FormattedText display builder ────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
def _highlighted(name: str, matched_indices: List[int]) -> List[Tuple[str, str]]:
|
|
130
|
+
"""
|
|
131
|
+
Build a FormattedText list: matched chars get 'class:fz-hi', rest are plain.
|
|
132
|
+
"""
|
|
133
|
+
idx_set = set(matched_indices)
|
|
134
|
+
parts: List[Tuple[str, str]] = []
|
|
135
|
+
for i, ch in enumerate(name):
|
|
136
|
+
if i in idx_set:
|
|
137
|
+
parts.append(("class:fz-hi", ch))
|
|
138
|
+
else:
|
|
139
|
+
parts.append(("", ch))
|
|
140
|
+
return parts
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
if HAS_PT:
|
|
144
|
+
import os as _os
|
|
145
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
146
|
+
from prompt_toolkit.formatted_text import FormattedText
|
|
147
|
+
from prompt_toolkit.styles import Style as PTStyle
|
|
148
|
+
|
|
149
|
+
class AriaPTCompleter(Completer):
|
|
150
|
+
"""
|
|
151
|
+
Slash-command completer with instant popup + fuzzy search.
|
|
152
|
+
|
|
153
|
+
Activates the moment the user types "/" (complete_while_typing=True
|
|
154
|
+
is already set in PromptSession, so no extra keypress is needed).
|
|
155
|
+
|
|
156
|
+
Triggers:
|
|
157
|
+
/ → show ALL slash commands (fuzzy matched)
|
|
158
|
+
@ → file/directory path autocomplete (@ anywhere in input)
|
|
159
|
+
! → shell history autocomplete (first word after !)
|
|
160
|
+
|
|
161
|
+
Matching:
|
|
162
|
+
/ → show ALL commands sorted by category order
|
|
163
|
+
/ch → fuzzy-match "ch" against command names, highlight hits
|
|
164
|
+
/stat → matches /stat-arb even though it's not a prefix
|
|
165
|
+
/team AAPL → only complete the command part (stop after first space)
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def __init__(
|
|
169
|
+
self,
|
|
170
|
+
commands_dict: dict,
|
|
171
|
+
skills: list,
|
|
172
|
+
watchlist: list,
|
|
173
|
+
*,
|
|
174
|
+
workspace: Path | str | None = None,
|
|
175
|
+
output_root: Path | str | None = None,
|
|
176
|
+
lang: str = "en",
|
|
177
|
+
):
|
|
178
|
+
self.commands = commands_dict
|
|
179
|
+
self.skills = skills
|
|
180
|
+
self.workspace = Path(workspace or Path.cwd()).expanduser().resolve()
|
|
181
|
+
self.output_root = Path(output_root).expanduser().resolve() if output_root else None
|
|
182
|
+
self.lang = "zh" if str(lang).lower().startswith("zh") else "en"
|
|
183
|
+
self._shell_history: list[str] = [] # populated by REPL after ! commands
|
|
184
|
+
self.symbols = sorted(set([
|
|
185
|
+
"AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "NVDA", "META",
|
|
186
|
+
"NFLX", "AMD", "INTC", "SPY", "QQQ", "DIA", "IWM",
|
|
187
|
+
"BTC-USD", "ETH-USD", "SOL-USD",
|
|
188
|
+
"JPM", "BAC", "GS", "V", "MA", "UNH", "JNJ", "XOM",
|
|
189
|
+
"GLD", "SLV", "USO", "TLT", "HYG",
|
|
190
|
+
] + list(watchlist)))
|
|
191
|
+
|
|
192
|
+
# Pre-compute category for each command
|
|
193
|
+
self._cmd_cat: dict[str, str] = {}
|
|
194
|
+
for name in self.commands:
|
|
195
|
+
self._cmd_cat[name] = _get_cat(name)
|
|
196
|
+
for s in self.skills:
|
|
197
|
+
self._cmd_cat[s["command"]] = _get_cat(s["command"])
|
|
198
|
+
|
|
199
|
+
def get_completions(self, document, complete_event) -> Iterator[Completion]:
|
|
200
|
+
text = document.text_before_cursor
|
|
201
|
+
ltext = text.lstrip()
|
|
202
|
+
|
|
203
|
+
# ── @ context reference autocomplete ───────────────────────────
|
|
204
|
+
# References work anywhere in a prompt. Email addresses do not.
|
|
205
|
+
ref_match = re.search(r"(?<![\w@])@([^\s@]*)$", text)
|
|
206
|
+
if ref_match:
|
|
207
|
+
yield from self._reference_completions(ref_match.group(1))
|
|
208
|
+
return
|
|
209
|
+
|
|
210
|
+
# ── ! shell command autocomplete ────────────────────────────────
|
|
211
|
+
if ltext.startswith("!"):
|
|
212
|
+
shell_frag = ltext[1:].lstrip()
|
|
213
|
+
if shell_frag:
|
|
214
|
+
for hist_cmd in reversed(self._shell_history):
|
|
215
|
+
if hist_cmd.startswith(shell_frag) and hist_cmd != shell_frag:
|
|
216
|
+
yield Completion(
|
|
217
|
+
hist_cmd,
|
|
218
|
+
start_position=-(len(ltext) - 1),
|
|
219
|
+
display=FormattedText([("class:fz-hi", hist_cmd)]),
|
|
220
|
+
display_meta="shell history",
|
|
221
|
+
)
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
# Only activate for slash commands
|
|
225
|
+
if not ltext.startswith("/"):
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
# Don't complete after first space — user is typing arguments
|
|
229
|
+
if " " in ltext:
|
|
230
|
+
return
|
|
231
|
+
|
|
232
|
+
# The typed prefix after "/"
|
|
233
|
+
pattern = ltext # includes leading "/"
|
|
234
|
+
|
|
235
|
+
# --- Build candidate list with scores ---
|
|
236
|
+
candidates: list[tuple[int, str, list[int], str, str]] = []
|
|
237
|
+
# (score, name, matched_indices, desc, category)
|
|
238
|
+
|
|
239
|
+
all_cmds = list(self.commands.items())
|
|
240
|
+
for name, (_, desc) in all_cmds:
|
|
241
|
+
cmd_part = name # e.g. "/chart"
|
|
242
|
+
matched, indices = _fuzzy(pattern.lstrip("/"), cmd_part.lstrip("/"))
|
|
243
|
+
if not matched and pattern != "/":
|
|
244
|
+
# Also try matching with the slash included
|
|
245
|
+
matched2, indices2 = _fuzzy(pattern, cmd_part)
|
|
246
|
+
if not matched2:
|
|
247
|
+
continue
|
|
248
|
+
indices = indices2
|
|
249
|
+
score = _score(cmd_part, pattern, indices)
|
|
250
|
+
cat = self._cmd_cat.get(name, "")
|
|
251
|
+
candidates.append((score, name, indices, desc, cat))
|
|
252
|
+
|
|
253
|
+
for s in self.skills:
|
|
254
|
+
cmd = s["command"]
|
|
255
|
+
desc = s.get("description", "")
|
|
256
|
+
matched, indices = _fuzzy(pattern.lstrip("/"), cmd.lstrip("/"))
|
|
257
|
+
if not matched and pattern != "/":
|
|
258
|
+
continue
|
|
259
|
+
score = _score(cmd, pattern, indices)
|
|
260
|
+
cat = self._cmd_cat.get(cmd, "")
|
|
261
|
+
candidates.append((score, cmd, indices, desc, cat))
|
|
262
|
+
|
|
263
|
+
# Sort: primary = score, secondary = name
|
|
264
|
+
candidates.sort(key=lambda x: (x[0], x[1]))
|
|
265
|
+
|
|
266
|
+
# Emit Completions
|
|
267
|
+
for score, name, indices, desc, cat in candidates:
|
|
268
|
+
# Build highlighted display (amber on matched chars)
|
|
269
|
+
display_parts = _highlighted(name, indices if pattern != "/" else [])
|
|
270
|
+
|
|
271
|
+
# Category badge as short suffix in display
|
|
272
|
+
badge = _CAT_BADGE.get(cat, "")
|
|
273
|
+
if badge:
|
|
274
|
+
display_parts += [("class:fz-cat", f" {badge}")]
|
|
275
|
+
|
|
276
|
+
# Truncate description to ~45 chars for meta column
|
|
277
|
+
cat_label = {
|
|
278
|
+
"市场": "市场" if self.lang == "zh" else "Market",
|
|
279
|
+
"分析": "研究" if self.lang == "zh" else "Research",
|
|
280
|
+
"量化": "量化" if self.lang == "zh" else "Quant",
|
|
281
|
+
"图表": "可视化" if self.lang == "zh" else "Visualize",
|
|
282
|
+
"工具": "开发工具" if self.lang == "zh" else "Developer",
|
|
283
|
+
"设置": "运行设置" if self.lang == "zh" else "Runtime",
|
|
284
|
+
"系统": "会话" if self.lang == "zh" else "Session",
|
|
285
|
+
}.get(cat, "")
|
|
286
|
+
meta_body = desc[:38] + ("…" if len(desc) > 38 else "")
|
|
287
|
+
meta_str = f"{cat_label} · {meta_body}" if cat_label else meta_body
|
|
288
|
+
|
|
289
|
+
# start_position: replace the entire typed prefix
|
|
290
|
+
start = -len(pattern)
|
|
291
|
+
|
|
292
|
+
yield Completion(
|
|
293
|
+
text = name,
|
|
294
|
+
start_position = start,
|
|
295
|
+
display = FormattedText(display_parts),
|
|
296
|
+
display_meta = meta_str,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def _reference_completions(self, frag: str) -> Iterator[Completion]:
|
|
300
|
+
"""Complete typed reference namespaces and their values."""
|
|
301
|
+
if ":" not in frag:
|
|
302
|
+
lowered = frag.lower()
|
|
303
|
+
for kind in REFERENCE_KINDS:
|
|
304
|
+
if kind.name.startswith(lowered):
|
|
305
|
+
label = kind.label_zh if self.lang == "zh" else kind.label_en
|
|
306
|
+
yield Completion(
|
|
307
|
+
f"{kind.name}:",
|
|
308
|
+
start_position=-len(frag),
|
|
309
|
+
display=FormattedText([
|
|
310
|
+
("class:fz-hi", f"@{kind.name}"),
|
|
311
|
+
("class:fz-cat", ":"),
|
|
312
|
+
]),
|
|
313
|
+
display_meta=label,
|
|
314
|
+
)
|
|
315
|
+
# Keep the first-level @ menu semantic and compact. Plain-path
|
|
316
|
+
# completion remains available only after an explicit path
|
|
317
|
+
# prefix; normal discovery goes through @file:/@folder:.
|
|
318
|
+
if frag and (frag.startswith((".", "/", "~")) or "/" in frag):
|
|
319
|
+
yield from self._file_completions(frag)
|
|
320
|
+
return
|
|
321
|
+
|
|
322
|
+
kind, value_frag = frag.split(":", 1)
|
|
323
|
+
kind = kind.lower()
|
|
324
|
+
if kind == "asset":
|
|
325
|
+
for symbol in self.symbols:
|
|
326
|
+
if symbol.lower().startswith(value_frag.lower()):
|
|
327
|
+
yield Completion(
|
|
328
|
+
f"asset:{symbol}",
|
|
329
|
+
start_position=-len(frag),
|
|
330
|
+
display=FormattedText([("class:fz-hi", symbol)]),
|
|
331
|
+
display_meta="市场资产" if self.lang == "zh" else "market asset",
|
|
332
|
+
)
|
|
333
|
+
return
|
|
334
|
+
if kind in {"file", "folder"}:
|
|
335
|
+
yield from self._file_completions(
|
|
336
|
+
value_frag,
|
|
337
|
+
value_prefix=f"{kind}:",
|
|
338
|
+
directories_only=(kind == "folder"),
|
|
339
|
+
)
|
|
340
|
+
return
|
|
341
|
+
if kind in _REFERENCE_KIND_NAMES:
|
|
342
|
+
yield from self._named_resource_completions(kind, value_frag)
|
|
343
|
+
|
|
344
|
+
def _file_completions(
|
|
345
|
+
self,
|
|
346
|
+
frag: str,
|
|
347
|
+
*,
|
|
348
|
+
value_prefix: str = "",
|
|
349
|
+
directories_only: bool = False,
|
|
350
|
+
) -> Iterator[Completion]:
|
|
351
|
+
"""Yield workspace-relative file/directory reference completions."""
|
|
352
|
+
try:
|
|
353
|
+
expanded = _os.path.expanduser(frag) if frag.startswith("~") else frag
|
|
354
|
+
base_fragment = _os.path.dirname(expanded) or "."
|
|
355
|
+
base_dir = Path(base_fragment)
|
|
356
|
+
if not base_dir.is_absolute():
|
|
357
|
+
base_dir = self.workspace / base_dir
|
|
358
|
+
prefix = _os.path.basename(frag)
|
|
359
|
+
if not base_dir.is_dir():
|
|
360
|
+
return
|
|
361
|
+
for entry in sorted(_os.listdir(base_dir))[:60]:
|
|
362
|
+
if entry.startswith("."):
|
|
363
|
+
continue
|
|
364
|
+
if not entry.lower().startswith(prefix.lower()):
|
|
365
|
+
continue
|
|
366
|
+
candidate = base_dir / entry
|
|
367
|
+
is_dir = candidate.is_dir()
|
|
368
|
+
if directories_only and not is_dir:
|
|
369
|
+
continue
|
|
370
|
+
if Path(expanded).is_absolute():
|
|
371
|
+
full = str(candidate)
|
|
372
|
+
else:
|
|
373
|
+
parent = _os.path.dirname(frag)
|
|
374
|
+
full = _os.path.join(parent, entry) if parent else entry
|
|
375
|
+
display_parts = [("class:fz-hi", prefix), ("", entry[len(prefix):])]
|
|
376
|
+
if is_dir:
|
|
377
|
+
display_parts.append(("class:fz-cat", "/"))
|
|
378
|
+
yield Completion(
|
|
379
|
+
value_prefix + full + ("/" if is_dir else ""),
|
|
380
|
+
start_position=-(len(value_prefix) + len(frag)),
|
|
381
|
+
display=FormattedText(display_parts),
|
|
382
|
+
display_meta="dir" if is_dir else "file",
|
|
383
|
+
)
|
|
384
|
+
except Exception:
|
|
385
|
+
pass
|
|
386
|
+
|
|
387
|
+
def _named_resource_completions(self, kind: str, frag: str) -> Iterator[Completion]:
|
|
388
|
+
seen: set[str] = set()
|
|
389
|
+
emitted = 0
|
|
390
|
+
for root in reference_search_roots(kind, self.workspace, self.output_root):
|
|
391
|
+
if not root.is_dir():
|
|
392
|
+
continue
|
|
393
|
+
try:
|
|
394
|
+
for path in root.rglob("*"):
|
|
395
|
+
if not path.is_file() or any(part.startswith(".") for part in path.relative_to(root).parts):
|
|
396
|
+
continue
|
|
397
|
+
name = path.stem
|
|
398
|
+
if name in seen or not name.lower().startswith(frag.lower()):
|
|
399
|
+
continue
|
|
400
|
+
seen.add(name)
|
|
401
|
+
yield Completion(
|
|
402
|
+
f"{kind}:{name}",
|
|
403
|
+
start_position=-(len(kind) + 1 + len(frag)),
|
|
404
|
+
display=FormattedText([("class:fz-hi", name)]),
|
|
405
|
+
display_meta=kind,
|
|
406
|
+
)
|
|
407
|
+
emitted += 1
|
|
408
|
+
if emitted >= 40:
|
|
409
|
+
return
|
|
410
|
+
except OSError:
|
|
411
|
+
continue
|
|
412
|
+
|
|
413
|
+
def add_shell_history(self, cmd: str) -> None:
|
|
414
|
+
"""Called by REPL after each ! command to update shell autocomplete."""
|
|
415
|
+
cmd = cmd.strip()
|
|
416
|
+
if cmd and cmd not in self._shell_history:
|
|
417
|
+
self._shell_history.append(cmd)
|
|
418
|
+
if len(self._shell_history) > 200:
|
|
419
|
+
self._shell_history = self._shell_history[-200:]
|
|
420
|
+
|
|
421
|
+
# ── Style ────────────────────────────────────────────────────────────────
|
|
422
|
+
# Theme-aware completion menu in the 5-color palette.
|
|
423
|
+
# Selection + fuzzy highlight use copper (brand); the menu surface
|
|
424
|
+
# matches the terminal theme so it never floats as a dark popup on a
|
|
425
|
+
# light terminal (or vice-versa).
|
|
426
|
+
|
|
427
|
+
# Copper-palette menu colors per theme.
|
|
428
|
+
# bg = menu surface (sits clearly above terminal bg)
|
|
429
|
+
# fg = row text
|
|
430
|
+
# sel_bg = selected row (copper tint)
|
|
431
|
+
# sel_fg = selected row text (copper, bold-applied at use site)
|
|
432
|
+
# meta = description column (dim)
|
|
433
|
+
# hi = fuzzy-matched chars (copper)
|
|
434
|
+
_MENU_THEMES = {
|
|
435
|
+
"dark": dict(
|
|
436
|
+
bg="#161b22", fg="#c9d1d9",
|
|
437
|
+
sel_bg="#3a2e20", sel_fg="#e8c9a6",
|
|
438
|
+
meta="#6e7681", meta_cur="#c0a585",
|
|
439
|
+
scroll_bg="#161b22", scroll_btn="#C08050", # copper position handle
|
|
440
|
+
hi="#C08050", cat="#6e7681",
|
|
441
|
+
base_bg="#0d1117", prompt="#8b949e", ph="#484f58",
|
|
442
|
+
tb_fg="#8b949e", tb_bg="#161b22",
|
|
443
|
+
),
|
|
444
|
+
"light": dict(
|
|
445
|
+
bg="#f2eee4", fg="#24292f", # warm surface, high contrast
|
|
446
|
+
sel_bg="#e7e1d3", sel_fg="#8a5a00", # stronger copper selection
|
|
447
|
+
meta="#6e7781", meta_cur="#8a5a00",
|
|
448
|
+
scroll_bg="#e7e1d3", scroll_btn="#9a6700", # copper position handle
|
|
449
|
+
hi="#9a6700", cat="#6e7781",
|
|
450
|
+
base_bg="default", prompt="#57606a", ph="#6e7781",
|
|
451
|
+
tb_fg="#57606a", tb_bg="#e7e1d3",
|
|
452
|
+
),
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
def _detect_theme() -> str:
|
|
456
|
+
try:
|
|
457
|
+
from ui.input_box import detect_terminal_theme
|
|
458
|
+
return detect_terminal_theme()
|
|
459
|
+
except Exception:
|
|
460
|
+
return "dark"
|
|
461
|
+
|
|
462
|
+
def build_aria_pt_style(theme: str = "auto") -> "PTStyle":
|
|
463
|
+
"""Build a theme-aware PromptSession style in the copper palette."""
|
|
464
|
+
if theme == "auto":
|
|
465
|
+
theme = _detect_theme()
|
|
466
|
+
c = _MENU_THEMES.get(theme, _MENU_THEMES["dark"])
|
|
467
|
+
base = f"{c['fg']} bg:{c['base_bg']}" if c["base_bg"] != "default" else c["fg"]
|
|
468
|
+
return PTStyle.from_dict({
|
|
469
|
+
"": base,
|
|
470
|
+
"prompt": c["prompt"],
|
|
471
|
+
"placeholder": c["ph"],
|
|
472
|
+
"input-bg": base,
|
|
473
|
+
"bottom-toolbar": f"noreverse {c['tb_fg']} bg:{c['tb_bg']}",
|
|
474
|
+
"bottom-toolbar.text":f"noreverse {c['tb_fg']} bg:{c['tb_bg']}",
|
|
475
|
+
|
|
476
|
+
# Completion menu — theme-aware surface, copper selection
|
|
477
|
+
"completion-menu": f"bg:{c['bg']} {c['fg']}",
|
|
478
|
+
"completion-menu.completion": f"bg:{c['bg']} {c['fg']}",
|
|
479
|
+
"completion-menu.completion.current": f"bg:{c['sel_bg']} {c['sel_fg']} bold",
|
|
480
|
+
"completion-menu.meta.completion": f"bg:{c['bg']} {c['meta']}",
|
|
481
|
+
"completion-menu.meta.completion.current": f"bg:{c['sel_bg']} {c['meta_cur']}",
|
|
482
|
+
"completion-menu.multi-column-meta": f"bg:{c['bg']} {c['meta']}",
|
|
483
|
+
"scrollbar.background": f"bg:{c['scroll_bg']}",
|
|
484
|
+
"scrollbar.button": f"bg:{c['scroll_btn']}",
|
|
485
|
+
|
|
486
|
+
# Fuzzy highlight classes — copper
|
|
487
|
+
"fz-hi": f"bold {c['hi']}",
|
|
488
|
+
"fz-cat": c["cat"],
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
# Back-compat default (dark). Prefer build_aria_pt_style(theme) at call sites.
|
|
492
|
+
ARIA_PT_STYLE = build_aria_pt_style("dark")
|
|
493
|
+
|
|
494
|
+
else:
|
|
495
|
+
def build_aria_pt_style(theme: str = "auto"): # type: ignore
|
|
496
|
+
return None
|
|
497
|
+
class AriaPTCompleter: # type: ignore
|
|
498
|
+
def __init__(self, *a, **kw): pass
|
|
499
|
+
def get_completions(self, *a, **kw): return iter([])
|
|
500
|
+
|
|
501
|
+
ARIA_PT_STYLE = None
|