aria-code 0.167.0__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) hide show
  1. aria_bots/__init__.py +7 -0
  2. aria_bots/channels/README.md +97 -0
  3. aria_bots/channels/__init__.py +1 -0
  4. aria_bots/channels/approvals.py +263 -0
  5. aria_bots/channels/conversation.py +280 -0
  6. aria_bots/channels/digest.py +186 -0
  7. aria_bots/channels/registry.py +95 -0
  8. aria_bots/engine.py +144 -0
  9. aria_bots/feishu_bot.py +1385 -0
  10. aria_bots/logistics/__init__.py +1 -0
  11. aria_bots/logistics/carriers.py +253 -0
  12. aria_bots/logistics/freight.py +154 -0
  13. aria_bots/logistics/inventory.py +242 -0
  14. aria_bots/logistics/mcp_server.py +156 -0
  15. aria_bots/logistics/records.py +119 -0
  16. aria_bots/logistics/tenancy.py +152 -0
  17. aria_bots/market.py +91 -0
  18. aria_bots/relay_client.py +326 -0
  19. aria_bots/telegram_bot.py +299 -0
  20. aria_code/__init__.py +111 -0
  21. aria_code/_bin/aria-native.exe +0 -0
  22. aria_code/_bin/aria-runtime.exe +0 -0
  23. aria_code/_version.py +20 -0
  24. aria_code/account_memory.py +296 -0
  25. aria_code/account_session.py +166 -0
  26. aria_code/adk_apps/__init__.py +1 -0
  27. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  28. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  29. aria_code/adk_apps/aria_research/__init__.py +1 -0
  30. aria_code/adk_apps/aria_research/agent.py +31 -0
  31. aria_code/agents/__init__.py +49 -0
  32. aria_code/agents/base.py +329 -0
  33. aria_code/agents/code_review.py +200 -0
  34. aria_code/agents/deep/__init__.py +37 -0
  35. aria_code/agents/deep/calibration_loop.py +144 -0
  36. aria_code/agents/deep/critic.py +125 -0
  37. aria_code/agents/deep/deepen.py +193 -0
  38. aria_code/agents/deep/models.py +149 -0
  39. aria_code/agents/deep/pipeline.py +164 -0
  40. aria_code/agents/deep/quant_fusion.py +192 -0
  41. aria_code/agents/deep/themes.py +95 -0
  42. aria_code/agents/deep/tiers.py +106 -0
  43. aria_code/agents/engineering/__init__.py +14 -0
  44. aria_code/agents/engineering/coder.py +222 -0
  45. aria_code/agents/engineering/tester.py +145 -0
  46. aria_code/agents/financial/__init__.py +21 -0
  47. aria_code/agents/financial/cashflow_burn.py +119 -0
  48. aria_code/agents/financial/catalyst.py +279 -0
  49. aria_code/agents/financial/corporate_finance.py +175 -0
  50. aria_code/agents/financial/debate.py +224 -0
  51. aria_code/agents/financial/earnings.py +315 -0
  52. aria_code/agents/financial/fundamental.py +178 -0
  53. aria_code/agents/financial/macro.py +111 -0
  54. aria_code/agents/financial/news.py +231 -0
  55. aria_code/agents/financial/risk.py +146 -0
  56. aria_code/agents/financial/sector.py +279 -0
  57. aria_code/agents/financial/strategist.py +121 -0
  58. aria_code/agents/financial/stripe_revenue.py +127 -0
  59. aria_code/agents/financial/synthesis.py +274 -0
  60. aria_code/agents/financial/technical.py +277 -0
  61. aria_code/agents/orchestrator.py +44 -0
  62. aria_code/agents/portfolio_agent.py +392 -0
  63. aria_code/agents/realty/__init__.py +62 -0
  64. aria_code/agents/realty/asset_diagnosis.py +152 -0
  65. aria_code/agents/realty/business_match.py +166 -0
  66. aria_code/agents/realty/cashflow_verify.py +209 -0
  67. aria_code/agents/realty/contract_rules.py +210 -0
  68. aria_code/agents/realty/energy_anomaly.py +189 -0
  69. aria_code/agents/realty/exit_settlement.py +208 -0
  70. aria_code/agents/realty/fulfillment_risk.py +206 -0
  71. aria_code/agents/realty/ops_optimize.py +160 -0
  72. aria_code/agents/realty/revenue_share.py +215 -0
  73. aria_code/agents/registry.py +168 -0
  74. aria_code/agents/signal_scheme.py +111 -0
  75. aria_code/agents/sports/__init__.py +0 -0
  76. aria_code/agents/sports/football_agent.py +197 -0
  77. aria_code/agents/supervisor.py +113 -0
  78. aria_code/agents/team.py +500 -0
  79. aria_code/agents/video/__init__.py +16 -0
  80. aria_code/agents/video/director.py +376 -0
  81. aria_code/agents/video/qa_agent.py +143 -0
  82. aria_code/agents/video/script_doctor.py +112 -0
  83. aria_code/agents/warehouse/__init__.py +25 -0
  84. aria_code/agents/warehouse/contracts.py +26 -0
  85. aria_code/agents/warehouse/dashboard.py +155 -0
  86. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  87. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  88. aria_code/agents/warehouse/inventory_health.py +24 -0
  89. aria_code/agents/warehouse/local_run.py +71 -0
  90. aria_code/agents/warehouse/local_snapshot.py +132 -0
  91. aria_code/agents/warehouse/logistics_cost.py +84 -0
  92. aria_code/agents/warehouse/logistics_sync.py +21 -0
  93. aria_code/agents/warehouse/navigation.schema.json +110 -0
  94. aria_code/agents/warehouse/task_agent.py +172 -0
  95. aria_code/agents/warehouse/workflow.py +31 -0
  96. aria_code/aliyun_data_client.py +4 -0
  97. aria_code/apps/README.md +12 -0
  98. aria_code/apps/__init__.py +2 -0
  99. aria_code/apps/channels/README.md +9 -0
  100. aria_code/apps/channels/__init__.py +17 -0
  101. aria_code/apps/channels/approvals.py +11 -0
  102. aria_code/apps/channels/conversation.py +11 -0
  103. aria_code/apps/channels/digest.py +11 -0
  104. aria_code/apps/channels/intake.py +92 -0
  105. aria_code/apps/channels/registry.py +11 -0
  106. aria_code/apps/channels/tradingview.py +94 -0
  107. aria_code/apps/cli/README.md +13 -0
  108. aria_code/apps/cli/__init__.py +2 -0
  109. aria_code/apps/cli/_optional.py +120 -0
  110. aria_code/apps/cli/app_server.py +656 -0
  111. aria_code/apps/cli/auto_update.py +125 -0
  112. aria_code/apps/cli/bootstrap.py +206 -0
  113. aria_code/apps/cli/broker_render.py +206 -0
  114. aria_code/apps/cli/chat_turn.py +1327 -0
  115. aria_code/apps/cli/cloud_models.py +231 -0
  116. aria_code/apps/cli/codegen_paths.py +29 -0
  117. aria_code/apps/cli/commands/__init__.py +34 -0
  118. aria_code/apps/cli/commands/_business_render.py +78 -0
  119. aria_code/apps/cli/commands/_ui.py +71 -0
  120. aria_code/apps/cli/commands/analysis_cmds.py +378 -0
  121. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  122. aria_code/apps/cli/commands/auth_cmds.py +215 -0
  123. aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
  124. aria_code/apps/cli/commands/broker_cmds.py +1236 -0
  125. aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
  126. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  127. aria_code/apps/cli/commands/catalog.py +189 -0
  128. aria_code/apps/cli/commands/core_cmds.py +2748 -0
  129. aria_code/apps/cli/commands/data_cmds.py +521 -0
  130. aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
  131. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  132. aria_code/apps/cli/commands/engineering_cmds.py +399 -0
  133. aria_code/apps/cli/commands/file_cmds.py +312 -0
  134. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  135. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  136. aria_code/apps/cli/commands/market.py +544 -0
  137. aria_code/apps/cli/commands/market_cmds.py +1419 -0
  138. aria_code/apps/cli/commands/market_context.py +432 -0
  139. aria_code/apps/cli/commands/market_render.py +7 -0
  140. aria_code/apps/cli/commands/model_cmds.py +2374 -0
  141. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  142. aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
  143. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  144. aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
  145. aria_code/apps/cli/commands/report.py +476 -0
  146. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  147. aria_code/apps/cli/commands/session_cmds.py +236 -0
  148. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  149. aria_code/apps/cli/commands/team.py +723 -0
  150. aria_code/apps/cli/commands/team_render.py +8 -0
  151. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  152. aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
  153. aria_code/apps/cli/commands/workflow_cmds.py +629 -0
  154. aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
  155. aria_code/apps/cli/config_paths.py +73 -0
  156. aria_code/apps/cli/config_store.py +158 -0
  157. aria_code/apps/cli/constants.py +88 -0
  158. aria_code/apps/cli/context.py +34 -0
  159. aria_code/apps/cli/conversation_policy.py +53 -0
  160. aria_code/apps/cli/deterministic.py +200 -0
  161. aria_code/apps/cli/direct.py +48 -0
  162. aria_code/apps/cli/earnings_view.py +172 -0
  163. aria_code/apps/cli/endpoint_migration.py +64 -0
  164. aria_code/apps/cli/exec_events.py +255 -0
  165. aria_code/apps/cli/file_references.py +155 -0
  166. aria_code/apps/cli/finance_service_catalog.py +111 -0
  167. aria_code/apps/cli/football_reports.py +231 -0
  168. aria_code/apps/cli/github_app_auth.py +135 -0
  169. aria_code/apps/cli/google_login.py +239 -0
  170. aria_code/apps/cli/handlers/__init__.py +11 -0
  171. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  172. aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
  173. aria_code/apps/cli/handlers/market_handlers.py +2570 -0
  174. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  175. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  176. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  177. aria_code/apps/cli/headless.py +352 -0
  178. aria_code/apps/cli/helpers.py +326 -0
  179. aria_code/apps/cli/hooks.py +180 -0
  180. aria_code/apps/cli/i18n.py +310 -0
  181. aria_code/apps/cli/intent.py +136 -0
  182. aria_code/apps/cli/intent_router.py +305 -0
  183. aria_code/apps/cli/intent_shadow.py +72 -0
  184. aria_code/apps/cli/intent_signals.py +347 -0
  185. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  186. aria_code/apps/cli/local_tool_schemas.py +550 -0
  187. aria_code/apps/cli/main.py +39 -0
  188. aria_code/apps/cli/market_hours.py +100 -0
  189. aria_code/apps/cli/market_metadata.py +135 -0
  190. aria_code/apps/cli/market_universe.py +487 -0
  191. aria_code/apps/cli/message_processing.py +310 -0
  192. aria_code/apps/cli/mixin_binding.py +32 -0
  193. aria_code/apps/cli/model_catalog.py +652 -0
  194. aria_code/apps/cli/model_probe.py +169 -0
  195. aria_code/apps/cli/model_retirement.py +65 -0
  196. aria_code/apps/cli/native_branding.py +12 -0
  197. aria_code/apps/cli/native_bridge.py +118 -0
  198. aria_code/apps/cli/native_entry.py +58 -0
  199. aria_code/apps/cli/pdf_report.py +977 -0
  200. aria_code/apps/cli/plan_mode.py +139 -0
  201. aria_code/apps/cli/plotly_html.py +15 -0
  202. aria_code/apps/cli/prediction_feedback.py +202 -0
  203. aria_code/apps/cli/preflight.py +502 -0
  204. aria_code/apps/cli/project_aria.py +60 -0
  205. aria_code/apps/cli/prompt_assembly.py +78 -0
  206. aria_code/apps/cli/prompts/__init__.py +0 -0
  207. aria_code/apps/cli/prompts/coding.py +71 -0
  208. aria_code/apps/cli/prompts/select.py +193 -0
  209. aria_code/apps/cli/prompts/system_prompts.py +562 -0
  210. aria_code/apps/cli/prompts/ui.py +436 -0
  211. aria_code/apps/cli/provider_endpoints.py +237 -0
  212. aria_code/apps/cli/provider_keys.py +73 -0
  213. aria_code/apps/cli/providers/__init__.py +1 -0
  214. aria_code/apps/cli/providers/base.py +775 -0
  215. aria_code/apps/cli/providers/chat_routing.py +139 -0
  216. aria_code/apps/cli/providers/collaboration.py +98 -0
  217. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  218. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  219. aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
  220. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  221. aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
  222. aria_code/apps/cli/providers/runtime_bridge.py +586 -0
  223. aria_code/apps/cli/providers/vertexai_stream.py +592 -0
  224. aria_code/apps/cli/release_download.py +159 -0
  225. aria_code/apps/cli/review_runner.py +111 -0
  226. aria_code/apps/cli/runtime_consumer.py +769 -0
  227. aria_code/apps/cli/sandbox.py +32 -0
  228. aria_code/apps/cli/session_export.py +120 -0
  229. aria_code/apps/cli/session_jsonl.py +208 -0
  230. aria_code/apps/cli/session_refresh.py +123 -0
  231. aria_code/apps/cli/session_store.py +125 -0
  232. aria_code/apps/cli/skills_catalog.py +273 -0
  233. aria_code/apps/cli/task_isolation.py +211 -0
  234. aria_code/apps/cli/terminal_chrome.py +412 -0
  235. aria_code/apps/cli/todo_tracker.py +190 -0
  236. aria_code/apps/cli/tool_executor.py +932 -0
  237. aria_code/apps/cli/tool_registry.py +34 -0
  238. aria_code/apps/cli/tool_scope.py +113 -0
  239. aria_code/apps/cli/tools/__init__.py +40 -0
  240. aria_code/apps/cli/tools/context.py +46 -0
  241. aria_code/apps/cli/tools/file_tools.py +181 -0
  242. aria_code/apps/cli/tools/market_tools.py +626 -0
  243. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  244. aria_code/apps/cli/tools/system_tools.py +656 -0
  245. aria_code/apps/cli/tools/write_tools.py +961 -0
  246. aria_code/apps/cli/tradingview_bridge.py +529 -0
  247. aria_code/apps/cli/transactions.py +269 -0
  248. aria_code/apps/cli/turn_planning.py +137 -0
  249. aria_code/apps/cli/update_check.py +257 -0
  250. aria_code/apps/cli/updater.py +373 -0
  251. aria_code/apps/cli/utils/__init__.py +0 -0
  252. aria_code/apps/cli/utils/market_detect.py +1663 -0
  253. aria_code/apps/cli/web_login.py +136 -0
  254. aria_code/apps/cli/workflow_runner.py +127 -0
  255. aria_code/apps/cli/workspace_route.py +121 -0
  256. aria_code/apps/daemon/README.md +14 -0
  257. aria_code/apps/vscode/README.md +115 -0
  258. aria_code/apps/vscode/package.json +70 -0
  259. aria_code/aria_cli.py +5244 -0
  260. aria_code/aria_daemon.py +1372 -0
  261. aria_code/aria_feishu_bot.py +16 -0
  262. aria_code/aria_mcp_server.py +61 -0
  263. aria_code/aria_relay_client.py +4 -0
  264. aria_code/aria_telegram_bot.py +11 -0
  265. aria_code/ariarc.py +385 -0
  266. aria_code/artifacts.py +581 -0
  267. aria_code/backtest_engine.py +4 -0
  268. aria_code/backtest_report.py +4 -0
  269. aria_code/brokers/__init__.py +78 -0
  270. aria_code/brokers/automation.py +193 -0
  271. aria_code/brokers/base.py +231 -0
  272. aria_code/brokers/capabilities.py +264 -0
  273. aria_code/brokers/cn/__init__.py +10 -0
  274. aria_code/brokers/cn/easytrader_broker.py +193 -0
  275. aria_code/brokers/cn/futu_broker.py +194 -0
  276. aria_code/brokers/cn/longbridge_broker.py +190 -0
  277. aria_code/brokers/cn/tiger_broker.py +196 -0
  278. aria_code/brokers/cn/xtquant_broker.py +225 -0
  279. aria_code/brokers/config.py +414 -0
  280. aria_code/brokers/intl/__init__.py +5 -0
  281. aria_code/brokers/intl/alpaca_broker.py +183 -0
  282. aria_code/brokers/intl/ibkr_broker.py +215 -0
  283. aria_code/brokers/intl/trading212_broker.py +183 -0
  284. aria_code/brokers/intl/webull_broker.py +156 -0
  285. aria_code/brokers/paper_broker.py +266 -0
  286. aria_code/brokers/planning.py +296 -0
  287. aria_code/brokers/registry.py +213 -0
  288. aria_code/brokers/trading.py +267 -0
  289. aria_code/canva_client.py +4 -0
  290. aria_code/change_store.py +127 -0
  291. aria_code/clients/__init__.py +0 -0
  292. aria_code/clients/aliyun_data_client.py +660 -0
  293. aria_code/clients/aria_relay_client.py +16 -0
  294. aria_code/clients/canva_client.py +284 -0
  295. aria_code/clients/figma_client.py +100 -0
  296. aria_code/clients/football_data_client.py +1671 -0
  297. aria_code/clients/kling_video_client.py +182 -0
  298. aria_code/clients/market_data_client.py +1985 -0
  299. aria_code/clients/openai_image_client.py +242 -0
  300. aria_code/clients/runway_video_client.py +157 -0
  301. aria_code/clients/warehouse_erp_client.py +105 -0
  302. aria_code/cloud_memory.py +190 -0
  303. aria_code/command_safety.py +19 -0
  304. aria_code/computer_use_server.py +276 -0
  305. aria_code/computer_use_tools.py +4 -0
  306. aria_code/dashboard_generator.py +579 -0
  307. aria_code/data_analysis_tools.py +4 -0
  308. aria_code/data_cleaner.py +483 -0
  309. aria_code/data_service.py +513 -0
  310. aria_code/datasources/__init__.py +23 -0
  311. aria_code/datasources/base.py +166 -0
  312. aria_code/datasources/router.py +253 -0
  313. aria_code/datasources/sec_statements.py +217 -0
  314. aria_code/datasources/sources/__init__.py +15 -0
  315. aria_code/datasources/sources/akshare_source.py +269 -0
  316. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  317. aria_code/datasources/sources/edgar_source.py +219 -0
  318. aria_code/datasources/sources/finnhub_source.py +198 -0
  319. aria_code/datasources/sources/fred_source.py +223 -0
  320. aria_code/datasources/sources/tushare_source.py +143 -0
  321. aria_code/datasources/sources/web_scraper_source.py +278 -0
  322. aria_code/datasources/sources/world_bank_source.py +206 -0
  323. aria_code/datasources/sources/yfinance_source.py +152 -0
  324. aria_code/doctor.py +860 -0
  325. aria_code/domain/__init__.py +0 -0
  326. aria_code/domain/_finance_core/__init__.py +5 -0
  327. aria_code/domain/_finance_core/backtest_engine.py +325 -0
  328. aria_code/domain/_finance_core/performance_stats.py +101 -0
  329. aria_code/domain/backtest_engine.py +75 -0
  330. aria_code/domain/backtest_report.py +488 -0
  331. aria_code/domain/finance_formulas.py +389 -0
  332. aria_code/domain/performance_stats.py +6 -0
  333. aria_code/domain/portfolio_ledger.py +307 -0
  334. aria_code/domain/strategy_vault.py +421 -0
  335. aria_code/evals/__init__.py +37 -0
  336. aria_code/evals/behavior.py +113 -0
  337. aria_code/evals/gap.py +93 -0
  338. aria_code/evals/harness.py +949 -0
  339. aria_code/evals/review_probe.py +132 -0
  340. aria_code/evals/runner.py +425 -0
  341. aria_code/evals/scorecard.py +322 -0
  342. aria_code/evals/summary.py +125 -0
  343. aria_code/external_agent_runner.py +115 -0
  344. aria_code/figma_client.py +4 -0
  345. aria_code/file_analysis_tools.py +4 -0
  346. aria_code/finance_formulas.py +4 -0
  347. aria_code/football_data_client.py +4 -0
  348. aria_code/image_gen_tools.py +4 -0
  349. aria_code/intent_classifier.py +459 -0
  350. aria_code/kling_video_client.py +4 -0
  351. aria_code/licensing.py +151 -0
  352. aria_code/local_finance_tools.py +4 -0
  353. aria_code/local_image_provider.py +4 -0
  354. aria_code/local_llm_provider.py +4 -0
  355. aria_code/macro_tools.py +4 -0
  356. aria_code/markdown_pdf.py +289 -0
  357. aria_code/market_data_client.py +4 -0
  358. aria_code/mcp_client.py +744 -0
  359. aria_code/memory_manager.py +273 -0
  360. aria_code/model_capability.py +512 -0
  361. aria_code/notification_tools.py +4 -0
  362. aria_code/openai_image_client.py +4 -0
  363. aria_code/packages/__init__.py +26 -0
  364. aria_code/packages/adk_bridge/__init__.py +11 -0
  365. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  366. aria_code/packages/adk_bridge/market_tools.py +125 -0
  367. aria_code/packages/aria_agents/__init__.py +5 -0
  368. aria_code/packages/aria_agents/manifest.py +78 -0
  369. aria_code/packages/aria_core/__init__.py +34 -0
  370. aria_code/packages/aria_core/architecture.py +269 -0
  371. aria_code/packages/aria_core/export.py +147 -0
  372. aria_code/packages/aria_core/manifest.py +65 -0
  373. aria_code/packages/aria_core/paths.py +57 -0
  374. aria_code/packages/aria_core/secure_file.py +68 -0
  375. aria_code/packages/aria_infra/__init__.py +15 -0
  376. aria_code/packages/aria_infra/arthera.py +58 -0
  377. aria_code/packages/aria_infra/doctor.py +246 -0
  378. aria_code/packages/aria_infra/product.py +40 -0
  379. aria_code/packages/aria_mcp/__init__.py +25 -0
  380. aria_code/packages/aria_mcp/bridge.py +232 -0
  381. aria_code/packages/aria_mcp/circuit.py +82 -0
  382. aria_code/packages/aria_mcp/config.py +162 -0
  383. aria_code/packages/aria_mcp/installer.py +95 -0
  384. aria_code/packages/aria_mcp/server.py +1705 -0
  385. aria_code/packages/aria_mcp/tools.py +81 -0
  386. aria_code/packages/aria_sdk/__init__.py +19 -0
  387. aria_code/packages/aria_sdk/client.py +393 -0
  388. aria_code/packages/aria_sdk/providers.py +70 -0
  389. aria_code/packages/aria_sdk/streaming.py +75 -0
  390. aria_code/packages/aria_sdk/types.py +86 -0
  391. aria_code/packages/aria_services/__init__.py +92 -0
  392. aria_code/packages/aria_services/cache.py +60 -0
  393. aria_code/packages/aria_services/context.py +356 -0
  394. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  395. aria_code/packages/aria_services/data.py +11 -0
  396. aria_code/packages/aria_services/provider_health.py +304 -0
  397. aria_code/packages/aria_services/references.py +247 -0
  398. aria_code/packages/aria_services/registry.py +249 -0
  399. aria_code/packages/aria_services/research_protocol.py +137 -0
  400. aria_code/packages/aria_services/research_quality.py +186 -0
  401. aria_code/packages/aria_services/settings.py +160 -0
  402. aria_code/packages/aria_services/usage.py +151 -0
  403. aria_code/packages/aria_skills/__init__.py +46 -0
  404. aria_code/packages/aria_skills/catalog.py +149 -0
  405. aria_code/packages/aria_skills/loader.py +455 -0
  406. aria_code/packages/aria_skills/registry.py +84 -0
  407. aria_code/packages/aria_tools/__init__.py +5 -0
  408. aria_code/packages/aria_tools/financial/__init__.py +5 -0
  409. aria_code/packages/aria_tools/financial/_paths.py +92 -0
  410. aria_code/packages/aria_tools/registry.py +129 -0
  411. aria_code/packages/quant_engine/__init__.py +33 -0
  412. aria_code/packages/quant_engine/_namespace.py +24 -0
  413. aria_code/packages/quant_engine/backtest/__init__.py +10 -0
  414. aria_code/packages/quant_engine/backtest/core.py +53 -0
  415. aria_code/packages/quant_engine/backtest/engine.py +102 -0
  416. aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
  417. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  418. aria_code/packages/quant_engine/sports/__init__.py +76 -0
  419. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  420. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  421. aria_code/packages/quant_engine/sports/elo.py +300 -0
  422. aria_code/packages/quant_engine/sports/form.py +188 -0
  423. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  424. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  425. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  426. aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
  427. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  428. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  429. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  430. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  431. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  432. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  433. aria_code/packs/__init__.py +85 -0
  434. aria_code/packs/base.py +168 -0
  435. aria_code/packs/finance/__init__.py +250 -0
  436. aria_code/packs/healthcare/__init__.py +40 -0
  437. aria_code/packs/logistics/__init__.py +171 -0
  438. aria_code/packs/payments/__init__.py +139 -0
  439. aria_code/packs/realty/__init__.py +190 -0
  440. aria_code/packs/registry.py +202 -0
  441. aria_code/packs/rules.py +90 -0
  442. aria_code/plan_utils.py +194 -0
  443. aria_code/plugin_loader.py +328 -0
  444. aria_code/portfolio_ledger.py +4 -0
  445. aria_code/preview_server.py +449 -0
  446. aria_code/privacy/__init__.py +5 -0
  447. aria_code/privacy/feedback.py +123 -0
  448. aria_code/project_review.py +278 -0
  449. aria_code/project_review_api.py +235 -0
  450. aria_code/project_review_server.py +18 -0
  451. aria_code/project_tools.py +4 -0
  452. aria_code/providers/__init__.py +30 -0
  453. aria_code/providers/google_video_provider.py +256 -0
  454. aria_code/providers/llm/__init__.py +19 -0
  455. aria_code/providers/llm/anthropic.py +184 -0
  456. aria_code/providers/llm/arthera_gateway.py +90 -0
  457. aria_code/providers/llm/autoconfig.py +213 -0
  458. aria_code/providers/llm/base.py +139 -0
  459. aria_code/providers/llm/custom.py +158 -0
  460. aria_code/providers/llm/ollama.py +137 -0
  461. aria_code/providers/llm/openai_compat.py +350 -0
  462. aria_code/providers/llm/registry.py +457 -0
  463. aria_code/providers/local_image_provider.py +202 -0
  464. aria_code/providers/local_llm_provider.py +549 -0
  465. aria_code/providers/ollama_models.py +79 -0
  466. aria_code/providers/openai_params.py +32 -0
  467. aria_code/providers/tool_messages.py +100 -0
  468. aria_code/realty_data_tools.py +4 -0
  469. aria_code/report_exporters.py +150 -0
  470. aria_code/report_generator.py +1764 -0
  471. aria_code/review_service.py +497 -0
  472. aria_code/runtime/__init__.py +176 -0
  473. aria_code/runtime/acceptance.py +632 -0
  474. aria_code/runtime/agent_loop.py +1851 -0
  475. aria_code/runtime/agent_profiles.py +75 -0
  476. aria_code/runtime/approval.py +71 -0
  477. aria_code/runtime/baseline.py +219 -0
  478. aria_code/runtime/budget.py +232 -0
  479. aria_code/runtime/checkpoints.py +481 -0
  480. aria_code/runtime/consult.py +65 -0
  481. aria_code/runtime/contract.py +282 -0
  482. aria_code/runtime/delivery.py +432 -0
  483. aria_code/runtime/events.py +113 -0
  484. aria_code/runtime/gateway.py +167 -0
  485. aria_code/runtime/lsp.py +484 -0
  486. aria_code/runtime/native_index.py +153 -0
  487. aria_code/runtime/orchestrator.py +55 -0
  488. aria_code/runtime/processes.py +343 -0
  489. aria_code/runtime/project_graph.py +614 -0
  490. aria_code/runtime/repo_map.py +712 -0
  491. aria_code/runtime/research_bundle.py +105 -0
  492. aria_code/runtime/review.py +269 -0
  493. aria_code/runtime/run_state.py +127 -0
  494. aria_code/runtime/run_store.py +522 -0
  495. aria_code/runtime/scoped_runs.py +113 -0
  496. aria_code/runtime/self_healing.py +422 -0
  497. aria_code/runtime/semantic_diff.py +171 -0
  498. aria_code/runtime/subagent.py +721 -0
  499. aria_code/runtime/symbol_edit.py +117 -0
  500. aria_code/runtime/task_brief.py +46 -0
  501. aria_code/runtime/task_context.py +145 -0
  502. aria_code/runtime/task_ledger.py +108 -0
  503. aria_code/runtime/task_orchestrator.py +90 -0
  504. aria_code/runtime/task_outcome.py +33 -0
  505. aria_code/runtime/task_verification.py +266 -0
  506. aria_code/runtime/task_worktree.py +448 -0
  507. aria_code/runtime/tool_executor.py +329 -0
  508. aria_code/runtime/tool_policy.py +107 -0
  509. aria_code/runtime/transactions.py +216 -0
  510. aria_code/runtime/windows_job.py +115 -0
  511. aria_code/runtime/workflows.py +222 -0
  512. aria_code/runtime/worktrees.py +215 -0
  513. aria_code/runway_video_client.py +4 -0
  514. aria_code/safety/__init__.py +27 -0
  515. aria_code/safety/client_isolation.py +178 -0
  516. aria_code/safety/permissions.py +339 -0
  517. aria_code/safety/risk.py +699 -0
  518. aria_code/safety/sandbox.py +148 -0
  519. aria_code/safety/service.py +102 -0
  520. aria_code/service_endpoints.py +14 -0
  521. aria_code/setup_wizard.py +684 -0
  522. aria_code/spreadsheet_tools.py +4 -0
  523. aria_code/strategy_vault.py +4 -0
  524. aria_code/tools/__init__.py +0 -0
  525. aria_code/tools/artifact_tools.py +252 -0
  526. aria_code/tools/broker_tools.py +92 -0
  527. aria_code/tools/build_quant_engine.py +97 -0
  528. aria_code/tools/code_audit_tools.py +192 -0
  529. aria_code/tools/computer_use_tools.py +509 -0
  530. aria_code/tools/data_analysis_tools.py +831 -0
  531. aria_code/tools/enterprise_finance_tools.py +202 -0
  532. aria_code/tools/extended_tools.py +240 -0
  533. aria_code/tools/file_analysis_tools.py +880 -0
  534. aria_code/tools/image_gen_tools.py +114 -0
  535. aria_code/tools/local_finance_tools.py +3488 -0
  536. aria_code/tools/logistics_carriers.py +11 -0
  537. aria_code/tools/logistics_inventory.py +11 -0
  538. aria_code/tools/logistics_io.py +11 -0
  539. aria_code/tools/logistics_tenancy.py +11 -0
  540. aria_code/tools/logistics_tools.py +11 -0
  541. aria_code/tools/macro_tools.py +412 -0
  542. aria_code/tools/notification_tools.py +249 -0
  543. aria_code/tools/project_tools.py +525 -0
  544. aria_code/tools/realty_data_tools.py +662 -0
  545. aria_code/tools/spreadsheet_tools.py +399 -0
  546. aria_code/tools/stripe_tools.py +115 -0
  547. aria_code/tools/video_tools.py +500 -0
  548. aria_code/training/__init__.py +1 -0
  549. aria_code/training/compare.py +117 -0
  550. aria_code/training/prelude_commands.py +111 -0
  551. aria_code/training/prelude_eval.py +390 -0
  552. aria_code/training/prelude_real.py +183 -0
  553. aria_code/training/prelude_train.py +248 -0
  554. aria_code/training/sft_dataset.py +230 -0
  555. aria_code/training/trajectory_dataset.py +263 -0
  556. aria_code/ui/__init__.py +105 -0
  557. aria_code/ui/banner.py +404 -0
  558. aria_code/ui/completer.py +571 -0
  559. aria_code/ui/console.py +285 -0
  560. aria_code/ui/input_box.py +505 -0
  561. aria_code/ui/mentions.py +206 -0
  562. aria_code/ui/picker.py +248 -0
  563. aria_code/ui/render/__init__.py +11 -0
  564. aria_code/ui/render/actions.py +297 -0
  565. aria_code/ui/render/finance.py +1732 -0
  566. aria_code/ui/render/market.py +253 -0
  567. aria_code/ui/render/output.py +954 -0
  568. aria_code/ui/render/responsive.py +75 -0
  569. aria_code/ui/render/team.py +367 -0
  570. aria_code/ui/robot.py +239 -0
  571. aria_code/ui/startup_dashboard.py +110 -0
  572. aria_code/video_analysis.py +147 -0
  573. aria_code/video_editor.py +518 -0
  574. aria_code/video_workflow/__init__.py +8 -0
  575. aria_code/video_workflow/__main__.py +61 -0
  576. aria_code/video_workflow/engines/__init__.py +18 -0
  577. aria_code/video_workflow/engines/base.py +69 -0
  578. aria_code/video_workflow/engines/custom_model.py +204 -0
  579. aria_code/video_workflow/engines/google_veo.py +94 -0
  580. aria_code/video_workflow/engines/local_engine.py +71 -0
  581. aria_code/video_workflow/engines/registry.py +98 -0
  582. aria_code/video_workflow/google_models.py +278 -0
  583. aria_code/video_workflow/music/__init__.py +5 -0
  584. aria_code/video_workflow/music/foley_service.py +132 -0
  585. aria_code/video_workflow/music/service.py +212 -0
  586. aria_code/video_workflow/pipeline.py +620 -0
  587. aria_code/video_workflow/plan.py +202 -0
  588. aria_code/video_workflow/session.py +297 -0
  589. aria_code/workspace/__init__.py +6 -0
  590. aria_code/workspace/files.py +219 -0
  591. aria_code/workspace/verify.py +167 -0
  592. aria_code/workspace_changes.py +199 -0
  593. aria_code/workspace_service.py +196 -0
  594. aria_code/workspace_tools.py +150 -0
  595. aria_code-0.167.0.dist-info/METADATA +330 -0
  596. aria_code-0.167.0.dist-info/RECORD +601 -0
  597. aria_code-0.167.0.dist-info/WHEEL +5 -0
  598. aria_code-0.167.0.dist-info/entry_points.txt +5 -0
  599. aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
  600. aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
  601. aria_code-0.167.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,571 @@
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.apps.cli.commands.catalog import (
21
+ COMMAND_ALIASES,
22
+ CORE_SLASH_COMMANDS,
23
+ ENTRY_SLASH_COMMANDS,
24
+ describe,
25
+ popup_rank,
26
+ )
27
+ from aria_code.packages.aria_services.references import REFERENCE_KINDS, reference_search_roots
28
+
29
+ _REFERENCE_KIND_NAMES = frozenset(item.name for item in REFERENCE_KINDS)
30
+
31
+ # ── Category map ────────────────────────────────────────────────────────────
32
+ # Keyed on command name fragments; first match wins.
33
+ _CATS: List[Tuple[Tuple[str, ...], str]] = [
34
+ (("/quote", "/market", "/macro", "/watch", "/alert", "/hot", "/indices",
35
+ "/cn", "/hk", "/crypto", "/forex", "/commodity", "/funding", "/feargreed",
36
+ "/edgar", "/datasource"), "市场"),
37
+ (("/team", "/analyze", "/options", "/factor", "/ta", "/ichimoku",
38
+ "/peer", "/quality", "/risk", "/signal", "/predict", "/earnings",
39
+ "/insights", "/deep", "/morning", "/trade-idea", "/research"), "分析"),
40
+ (("/backtest", "/wf", "/compare", "/execution", "/stat-arb",
41
+ "/ptbt", "/corr", "/optimize", "/stress", "/auto-strategy",
42
+ "/portfolio", "/journal"), "量化"),
43
+ (("/chart", "/report", "/shortterm", "/longterm", "/cloudbt"), "图表"),
44
+ (("/project", "/file", "/run", "/code", "/scaffold", "/init",
45
+ "/review", "/vision", "/browser", "/web"), "工具"),
46
+ (("/config", "/model", "/apikey", "/setup", "/local", "/mcp",
47
+ "/memory", "/cost", "/version"), "设置"),
48
+ (("/help", "/clear", "/btw", "/recap", "/exit", "/quit", "/history", "/session",
49
+ "/bug", "/feedback", "/privacy"), "系统"),
50
+ ]
51
+
52
+ _CAT_BADGE: dict[str, str] = {
53
+ "市场": "mkt",
54
+ "分析": "ana",
55
+ "量化": "qnt",
56
+ "图表": "viz",
57
+ "工具": "dev",
58
+ "设置": "cfg",
59
+ "系统": "sys",
60
+ }
61
+
62
+
63
+ def _get_cat(name: str) -> str:
64
+ for prefixes, cat in _CATS:
65
+ for p in prefixes:
66
+ if name.startswith(p):
67
+ return cat
68
+ return ""
69
+
70
+
71
+ # ── Fuzzy matching ───────────────────────────────────────────────────────────
72
+
73
+ def _fuzzy(pattern: str, text: str) -> Tuple[bool, List[int]]:
74
+ """
75
+ Sequential fuzzy match — pattern chars must appear in order in text.
76
+ Returns (matched, indices_of_matched_chars_in_text).
77
+ Consecutive matches score higher because they produce a compact index list.
78
+ """
79
+ if not pattern:
80
+ return True, []
81
+ pi = 0
82
+ indices: List[int] = []
83
+ for i, ch in enumerate(text):
84
+ if ch.lower() == pattern[pi].lower():
85
+ indices.append(i)
86
+ pi += 1
87
+ if pi == len(pattern):
88
+ return True, indices
89
+ return False, []
90
+
91
+
92
+ def _score(name: str, pattern: str, indices: List[int]) -> int:
93
+ """
94
+ Lower score = better.
95
+ 0 exact match
96
+ 1 exact prefix (/ch → /chart)
97
+ 5 word-segment exact match (/arb → /stat-arb because '-arb' segment)
98
+ 10 consecutive run from position 0
99
+ 12+ consecutive run from a word boundary
100
+ 15+ consecutive run from elsewhere
101
+ 20+ non-consecutive from a word boundary
102
+ 30+ scattered fuzzy match
103
+ """
104
+ if name == pattern:
105
+ return 0
106
+ if name.startswith(pattern):
107
+ return 1
108
+ if not indices:
109
+ return 99
110
+
111
+ # Word-segment exact match: pattern matches a whole segment after "-" or "_"
112
+ bare = name.lstrip("/")
113
+ pat_bare = pattern.lstrip("/")
114
+ for sep in ("-", "_"):
115
+ for seg in bare.split(sep)[1:]: # skip first segment (already caught by prefix)
116
+ if seg == pat_bare or seg.startswith(pat_bare):
117
+ return 5 + len(sep) # score 6 for "-", 6 for "_"
118
+
119
+ start = indices[0]
120
+ consecutive = (indices == list(range(start, start + len(indices))))
121
+ at_boundary = start == 0 or (start > 0 and bare[start - 1] in "-_")
122
+
123
+ if consecutive:
124
+ if start == 0:
125
+ return 10
126
+ if at_boundary:
127
+ return 12 + start
128
+ return 15 + start
129
+ if at_boundary:
130
+ return 20 + start
131
+ return 30 + start
132
+
133
+
134
+ # ── FormattedText display builder ────────────────────────────────────────────
135
+
136
+ def _highlighted(name: str, matched_indices: List[int]) -> List[Tuple[str, str]]:
137
+ """
138
+ Build a FormattedText list: matched chars get 'class:fz-hi', rest are plain.
139
+ """
140
+ idx_set = set(matched_indices)
141
+ parts: List[Tuple[str, str]] = []
142
+ for i, ch in enumerate(name):
143
+ if i in idx_set:
144
+ parts.append(("class:fz-hi", ch))
145
+ else:
146
+ parts.append(("", ch))
147
+ return parts
148
+
149
+
150
+ if HAS_PT:
151
+ import os as _os
152
+ from prompt_toolkit.completion import Completer, Completion
153
+ from prompt_toolkit.formatted_text import FormattedText
154
+ from prompt_toolkit.styles import Style as PTStyle
155
+
156
+ class AriaPTCompleter(Completer):
157
+ """
158
+ Slash-command completer with instant popup + fuzzy search.
159
+
160
+ Activates the moment the user types "/" (complete_while_typing=True
161
+ is already set in PromptSession, so no extra keypress is needed).
162
+
163
+ Triggers:
164
+ / → show ALL slash commands (fuzzy matched)
165
+ @ → file/directory path autocomplete (@ anywhere in input)
166
+ ! → shell history autocomplete (first word after !)
167
+
168
+ Matching:
169
+ / → show ALL commands sorted by category order
170
+ /ch → fuzzy-match "ch" against command names, highlight hits
171
+ /stat → matches /stat-arb even though it's not a prefix
172
+ /team AAPL → only complete the command part (stop after first space)
173
+ """
174
+
175
+ def __init__(
176
+ self,
177
+ commands_dict: dict,
178
+ skills: list,
179
+ watchlist: list,
180
+ *,
181
+ workspace: Path | str | None = None,
182
+ output_root: Path | str | None = None,
183
+ lang: str = "en",
184
+ ):
185
+ self.commands = commands_dict
186
+ self.skills = skills
187
+ self.workspace = Path(workspace or Path.cwd()).expanduser().resolve()
188
+ self.output_root = Path(output_root).expanduser().resolve() if output_root else None
189
+ self.lang = "zh" if str(lang).lower().startswith("zh") else "en"
190
+ self._shell_history: list[str] = [] # populated by REPL after ! commands
191
+ self.symbols = sorted(set([
192
+ "AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "NVDA", "META",
193
+ "NFLX", "AMD", "INTC", "SPY", "QQQ", "DIA", "IWM",
194
+ "BTC-USD", "ETH-USD", "SOL-USD",
195
+ "JPM", "BAC", "GS", "V", "MA", "UNH", "JNJ", "XOM",
196
+ "GLD", "SLV", "USO", "TLT", "HYG",
197
+ ] + list(watchlist)))
198
+
199
+ # Pre-compute category for each command
200
+ self._cmd_cat: dict[str, str] = {}
201
+ for name in self.commands:
202
+ self._cmd_cat[name] = _get_cat(name)
203
+ for s in self.skills:
204
+ self._cmd_cat[s["command"]] = _get_cat(s["command"])
205
+
206
+ def get_completions(self, document, complete_event) -> Iterator[Completion]:
207
+ text = document.text_before_cursor
208
+ ltext = text.lstrip()
209
+
210
+ # ── @ context reference autocomplete ───────────────────────────
211
+ # References work anywhere in a prompt. Email addresses do not.
212
+ ref_match = re.search(r"(?<![\w@])@([^\s@]*)$", text)
213
+ if ref_match:
214
+ yield from self._reference_completions(ref_match.group(1))
215
+ return
216
+
217
+ # ── ! shell command autocomplete ────────────────────────────────
218
+ if ltext.startswith("!"):
219
+ shell_frag = ltext[1:].lstrip()
220
+ if shell_frag:
221
+ for hist_cmd in reversed(self._shell_history):
222
+ if hist_cmd.startswith(shell_frag) and hist_cmd != shell_frag:
223
+ yield Completion(
224
+ hist_cmd,
225
+ start_position=-(len(ltext) - 1),
226
+ display=FormattedText([("class:fz-hi", hist_cmd)]),
227
+ display_meta="shell history",
228
+ )
229
+ return
230
+
231
+ # Only activate for slash commands
232
+ if not ltext.startswith("/"):
233
+ return
234
+
235
+ # Don't complete after first space — user is typing arguments
236
+ if " " in ltext:
237
+ return
238
+
239
+ # The typed prefix after "/"
240
+ pattern = ltext # includes leading "/"
241
+
242
+ # --- Build candidate list with scores ---
243
+ candidates: list[tuple[int, int, str, list[int], str, str]] = []
244
+ # (score, tier, name, matched_indices, desc, category)
245
+
246
+ # A bare "/" opens on the core commands and the entry points, in
247
+ # their set order — not on all 181 commands and skills. Every other
248
+ # command is one or two letters away.
249
+ if pattern == "/":
250
+ for name in (*CORE_SLASH_COMMANDS, *ENTRY_SLASH_COMMANDS):
251
+ if name in self.commands:
252
+ candidates.append((0, popup_rank(name), name, [], self.commands[name][1],
253
+ self._cmd_cat.get(name, "")))
254
+ yield from self._emit(candidates, pattern)
255
+ return
256
+
257
+ all_cmds = list(self.commands.items())
258
+ for name, (_, desc) in all_cmds:
259
+ cmd_part = name # e.g. "/chart"
260
+ matched, indices = _fuzzy(pattern.lstrip("/"), cmd_part.lstrip("/"))
261
+ if not matched and pattern != "/":
262
+ # Also try matching with the slash included
263
+ matched2, indices2 = _fuzzy(pattern, cmd_part)
264
+ if not matched2:
265
+ continue
266
+ indices = indices2
267
+ score = _score(cmd_part, pattern, indices)
268
+ # An alias shows only when it is what was typed.
269
+ if name in COMMAND_ALIASES and score > 1:
270
+ continue
271
+ cat = self._cmd_cat.get(name, "")
272
+ candidates.append((score, popup_rank(name), name, indices, desc, cat))
273
+
274
+ for s in self.skills:
275
+ cmd = s["command"]
276
+ desc = s.get("description", "")
277
+ matched, indices = _fuzzy(pattern.lstrip("/"), cmd.lstrip("/"))
278
+ if not matched and pattern != "/":
279
+ continue
280
+ score = _score(cmd, pattern, indices)
281
+ cat = self._cmd_cat.get(cmd, "")
282
+ candidates.append((score, popup_rank(cmd), cmd, indices, desc, cat))
283
+
284
+ # Best match first; among equals, core commands, then entry points.
285
+ candidates.sort(key=lambda x: (x[0], x[1], x[2]))
286
+ # Letters scattered through a name ("/re" in "/providers") are noise
287
+ # once there is a popup's worth of closer matches.
288
+ if sum(1 for c in candidates if c[0] < 30) >= 8:
289
+ candidates = [c for c in candidates if c[0] < 30]
290
+ yield from self._emit(candidates, pattern)
291
+
292
+ def _emit(self, candidates, pattern: str) -> Iterator[Completion]:
293
+ for score, _tier, name, indices, desc, cat in candidates:
294
+ # Build highlighted display (amber on matched chars)
295
+ display_parts = _highlighted(name, indices if pattern != "/" else [])
296
+
297
+ # No badge after the name: "/help sys" next to "Session · …"
298
+ # said the category twice.
299
+
300
+ # Truncate description to ~45 chars for meta column
301
+ cat_label = {
302
+ "市场": "市场" if self.lang == "zh" else "Market",
303
+ "分析": "研究" if self.lang == "zh" else "Research",
304
+ "量化": "量化" if self.lang == "zh" else "Quant",
305
+ "图表": "可视化" if self.lang == "zh" else "Visualize",
306
+ "工具": "开发工具" if self.lang == "zh" else "Developer",
307
+ "设置": "运行设置" if self.lang == "zh" else "Runtime",
308
+ "系统": "会话" if self.lang == "zh" else "Session",
309
+ }.get(cat, "")
310
+ desc = describe(name, desc, self.lang)
311
+ meta_body = desc[:44] + ("…" if len(desc) > 44 else "")
312
+ meta_str = f"{cat_label} · {meta_body}" if cat_label else meta_body
313
+
314
+ # start_position: replace the entire typed prefix
315
+ start = -len(pattern)
316
+
317
+ yield Completion(
318
+ text = name,
319
+ start_position = start,
320
+ display = FormattedText(display_parts),
321
+ display_meta = meta_str,
322
+ )
323
+
324
+ def _mention_index(self):
325
+ if getattr(self, "_mentions", None) is None:
326
+ from aria_code.ui.mentions import MentionIndex
327
+
328
+ self._mentions = MentionIndex(self.workspace, output_root=self.output_root, symbols=self.symbols)
329
+ return self._mentions
330
+
331
+ def _kind_label(self, name: str) -> str:
332
+ for kind in REFERENCE_KINDS:
333
+ if kind.name == name:
334
+ return kind.label_zh if self.lang == "zh" else kind.label_en
335
+ return name
336
+
337
+ def _kind_shortcuts(self, frag: str) -> Iterator[Completion]:
338
+ lowered = frag.lower()
339
+ for kind in REFERENCE_KINDS:
340
+ if kind.name.startswith(lowered):
341
+ yield Completion(
342
+ f"{kind.name}:",
343
+ start_position=-len(frag),
344
+ display=FormattedText([("class:fz-hi", f"@{kind.name}"), ("class:fz-cat", ":")]),
345
+ display_meta=(f"只看{self._kind_label(kind.name)}" if self.lang == "zh"
346
+ else f"{self._kind_label(kind.name)} only"),
347
+ )
348
+
349
+ def _mention_completions(self, mentions, replace: int) -> Iterator[Completion]:
350
+ for mention in mentions:
351
+ hits = set(mention.matched)
352
+ parts = [("class:fz-hi" if i in hits else "", ch) for i, ch in enumerate(mention.label)]
353
+ yield Completion(
354
+ mention.insert_text,
355
+ start_position=-replace,
356
+ display=FormattedText(parts),
357
+ display_meta=self._kind_label(mention.kind),
358
+ )
359
+
360
+ def _reference_completions(self, frag: str) -> Iterator[Completion]:
361
+ """Complete "@" references: results across every kind first.
362
+
363
+ "@" used to open on the kinds (file:, asset: …) and list files only
364
+ after a path character, so attaching a file took three steps. A
365
+ bare "@" now shows recently changed files, "@fx" searches files,
366
+ folders, assets and saved resources together, and "@file:" or
367
+ another kind prefix narrows to that kind.
368
+ """
369
+ if ":" not in frag:
370
+ # Browsing by path ("@src/", "@./", "@~/") works as before.
371
+ if frag and (frag.startswith((".", "/", "~")) or "/" in frag):
372
+ yield from self._file_completions(frag)
373
+ return
374
+ index = self._mention_index()
375
+ if not frag:
376
+ from aria_code.ui.mentions import Mention
377
+
378
+ recent = [Mention("file", path, 0) for path in index.recent_files()]
379
+ yield from self._mention_completions(recent, 0)
380
+ yield from self._kind_shortcuts("")
381
+ return
382
+ if len(frag) >= 2:
383
+ yield from self._kind_shortcuts(frag)
384
+ yield from self._mention_completions(index.search(frag), len(frag))
385
+ return
386
+
387
+ kind, value_frag = frag.split(":", 1)
388
+ kind = kind.lower()
389
+ path_like = value_frag.startswith((".", "/", "~")) or "/" in value_frag
390
+ if kind in {"file", "folder"} and value_frag and not path_like:
391
+ found = self._mention_index().search(value_frag, kind=kind)
392
+ yield from self._mention_completions(found, len(frag))
393
+ return
394
+ if kind == "asset":
395
+ for symbol in self.symbols:
396
+ if symbol.lower().startswith(value_frag.lower()):
397
+ yield Completion(
398
+ f"asset:{symbol}",
399
+ start_position=-len(frag),
400
+ display=FormattedText([("class:fz-hi", symbol)]),
401
+ display_meta="市场资产" if self.lang == "zh" else "market asset",
402
+ )
403
+ return
404
+ if kind in {"file", "folder"}:
405
+ yield from self._file_completions(
406
+ value_frag,
407
+ value_prefix=f"{kind}:",
408
+ directories_only=(kind == "folder"),
409
+ )
410
+ return
411
+ if kind in _REFERENCE_KIND_NAMES:
412
+ yield from self._named_resource_completions(kind, value_frag)
413
+
414
+ def _file_completions(
415
+ self,
416
+ frag: str,
417
+ *,
418
+ value_prefix: str = "",
419
+ directories_only: bool = False,
420
+ ) -> Iterator[Completion]:
421
+ """Yield workspace-relative file/directory reference completions."""
422
+ try:
423
+ expanded = _os.path.expanduser(frag) if frag.startswith("~") else frag
424
+ base_fragment = _os.path.dirname(expanded) or "."
425
+ base_dir = Path(base_fragment)
426
+ if not base_dir.is_absolute():
427
+ base_dir = self.workspace / base_dir
428
+ prefix = _os.path.basename(frag)
429
+ if not base_dir.is_dir():
430
+ return
431
+ for entry in sorted(_os.listdir(base_dir))[:60]:
432
+ if entry.startswith("."):
433
+ continue
434
+ if not entry.lower().startswith(prefix.lower()):
435
+ continue
436
+ candidate = base_dir / entry
437
+ is_dir = candidate.is_dir()
438
+ if directories_only and not is_dir:
439
+ continue
440
+ if Path(expanded).is_absolute():
441
+ full = str(candidate)
442
+ else:
443
+ parent = _os.path.dirname(frag)
444
+ full = _os.path.join(parent, entry) if parent else entry
445
+ display_parts = [("class:fz-hi", prefix), ("", entry[len(prefix):])]
446
+ if is_dir:
447
+ display_parts.append(("class:fz-cat", "/"))
448
+ yield Completion(
449
+ value_prefix + full + ("/" if is_dir else ""),
450
+ start_position=-(len(value_prefix) + len(frag)),
451
+ display=FormattedText(display_parts),
452
+ display_meta="dir" if is_dir else "file",
453
+ )
454
+ except Exception:
455
+ pass
456
+
457
+ def _named_resource_completions(self, kind: str, frag: str) -> Iterator[Completion]:
458
+ seen: set[str] = set()
459
+ emitted = 0
460
+ for root in reference_search_roots(kind, self.workspace, self.output_root):
461
+ if not root.is_dir():
462
+ continue
463
+ try:
464
+ for path in root.rglob("*"):
465
+ if not path.is_file() or any(part.startswith(".") for part in path.relative_to(root).parts):
466
+ continue
467
+ name = path.stem
468
+ if name in seen or not name.lower().startswith(frag.lower()):
469
+ continue
470
+ seen.add(name)
471
+ yield Completion(
472
+ f"{kind}:{name}",
473
+ start_position=-(len(kind) + 1 + len(frag)),
474
+ display=FormattedText([("class:fz-hi", name)]),
475
+ display_meta=kind,
476
+ )
477
+ emitted += 1
478
+ if emitted >= 40:
479
+ return
480
+ except OSError:
481
+ continue
482
+
483
+ def add_shell_history(self, cmd: str) -> None:
484
+ """Called by REPL after each ! command to update shell autocomplete."""
485
+ cmd = cmd.strip()
486
+ if cmd and cmd not in self._shell_history:
487
+ self._shell_history.append(cmd)
488
+ if len(self._shell_history) > 200:
489
+ self._shell_history = self._shell_history[-200:]
490
+
491
+ # ── Style ────────────────────────────────────────────────────────────────
492
+ # Theme-aware completion menu in the 5-color palette.
493
+ # Selection + fuzzy highlight use copper (brand); the menu surface
494
+ # matches the terminal theme so it never floats as a dark popup on a
495
+ # light terminal (or vice-versa).
496
+
497
+ # Copper-palette menu colors per theme.
498
+ # bg = menu surface (sits clearly above terminal bg)
499
+ # fg = row text
500
+ # sel_bg = selected row (copper tint)
501
+ # sel_fg = selected row text (copper, bold-applied at use site)
502
+ # meta = description column (dim)
503
+ # hi = fuzzy-matched chars (copper)
504
+ _MENU_THEMES = {
505
+ "dark": dict(
506
+ bg="#161b22", fg="#c9d1d9",
507
+ sel_bg="#3a2e20", sel_fg="#e8c9a6",
508
+ meta="#6e7681", meta_cur="#c0a585",
509
+ scroll_bg="#161b22", scroll_btn="#C08050", # copper position handle
510
+ hi="#C08050", cat="#6e7681",
511
+ base_bg="#0d1117", prompt="#8b949e", ph="#484f58",
512
+ tb_fg="#8b949e", tb_bg="#161b22",
513
+ ),
514
+ "light": dict(
515
+ bg="#f2eee4", fg="#24292f", # warm surface, high contrast
516
+ sel_bg="#e7e1d3", sel_fg="#8a5a00", # stronger copper selection
517
+ meta="#6e7781", meta_cur="#8a5a00",
518
+ scroll_bg="#e7e1d3", scroll_btn="#9a6700", # copper position handle
519
+ hi="#9a6700", cat="#6e7781",
520
+ base_bg="default", prompt="#57606a", ph="#6e7781",
521
+ tb_fg="#57606a", tb_bg="#e7e1d3",
522
+ ),
523
+ }
524
+
525
+ def _detect_theme() -> str:
526
+ try:
527
+ from ui.input_box import detect_terminal_theme
528
+ return detect_terminal_theme()
529
+ except Exception:
530
+ return "dark"
531
+
532
+ def build_aria_pt_style(theme: str = "auto") -> "PTStyle":
533
+ """Build a theme-aware PromptSession style in the copper palette."""
534
+ if theme == "auto":
535
+ theme = _detect_theme()
536
+ c = _MENU_THEMES.get(theme, _MENU_THEMES["dark"])
537
+ base = f"{c['fg']} bg:{c['base_bg']}" if c["base_bg"] != "default" else c["fg"]
538
+ return PTStyle.from_dict({
539
+ "": base,
540
+ "prompt": c["prompt"],
541
+ "placeholder": c["ph"],
542
+ "input-bg": base,
543
+ "bottom-toolbar": f"noreverse {c['tb_fg']} bg:{c['tb_bg']}",
544
+ "bottom-toolbar.text":f"noreverse {c['tb_fg']} bg:{c['tb_bg']}",
545
+
546
+ # Completion menu — theme-aware surface, copper selection
547
+ "completion-menu": f"bg:{c['bg']} {c['fg']}",
548
+ "completion-menu.completion": f"bg:{c['bg']} {c['fg']}",
549
+ "completion-menu.completion.current": f"bg:{c['sel_bg']} {c['sel_fg']} bold",
550
+ "completion-menu.meta.completion": f"bg:{c['bg']} {c['meta']}",
551
+ "completion-menu.meta.completion.current": f"bg:{c['sel_bg']} {c['meta_cur']}",
552
+ "completion-menu.multi-column-meta": f"bg:{c['bg']} {c['meta']}",
553
+ "scrollbar.background": f"bg:{c['scroll_bg']}",
554
+ "scrollbar.button": f"bg:{c['scroll_btn']}",
555
+
556
+ # Fuzzy highlight classes — copper
557
+ "fz-hi": f"bold {c['hi']}",
558
+ "fz-cat": c["cat"],
559
+ })
560
+
561
+ # Back-compat default (dark). Prefer build_aria_pt_style(theme) at call sites.
562
+ ARIA_PT_STYLE = build_aria_pt_style("dark")
563
+
564
+ else:
565
+ def build_aria_pt_style(theme: str = "auto"): # type: ignore
566
+ return None
567
+ class AriaPTCompleter: # type: ignore
568
+ def __init__(self, *a, **kw): pass
569
+ def get_completions(self, *a, **kw): return iter([])
570
+
571
+ ARIA_PT_STYLE = None