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,629 @@
1
+ """WorkflowCommandsMixin — hooks, regen, undo, retry, note, review commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import os
7
+ import pathlib
8
+ from datetime import datetime
9
+
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ import json
15
+ import asyncio
16
+ import datetime
17
+ import time
18
+ import shlex
19
+ from typing import Dict, Any, Optional
20
+
21
+ def _run_event_hook(*args, **kwargs):
22
+ from aria_cli import _run_event_hook as fn
23
+ return fn(*args, **kwargs)
24
+ def _load_hooks(*args, **kwargs):
25
+ from aria_cli import _load_hooks as fn
26
+ return fn(*args, **kwargs)
27
+ # display_path lives in ui.render.output; aria_cli only re-exports it under a
28
+ # private alias, so going through aria_cli was a pointless second hop.
29
+ from aria_code.ui.render.output import display_path as _display_path
30
+ def _get_MODELS():
31
+ from aria_code.apps.cli.model_catalog import MODELS as val
32
+ return val
33
+ def _get__HAS_JSON_HOOKS():
34
+ from aria_cli import _HAS_JSON_HOOKS as val
35
+ return val
36
+ def _tool_run_command(*args, **kwargs):
37
+ from aria_cli import _tool_run_command as fn
38
+ return fn(*args, **kwargs)
39
+ def resolve_model_key(*args, **kwargs):
40
+ from ..model_catalog import resolve_model_key as fn
41
+ return fn(*args, **kwargs)
42
+ def _load_project_context(*args, **kwargs):
43
+ from aria_code.apps.cli.helpers import _load_project_context as fn
44
+ return fn(*args, **kwargs)
45
+ def _fire_json_hook(*args, **kwargs):
46
+ from aria_cli import _fire_json_hook as fn
47
+ return fn(*args, **kwargs)
48
+ def _print_phase(*args, **kwargs):
49
+ from aria_cli import _print_phase as fn
50
+ return fn(*args, **kwargs)
51
+ def _get_CONFIG_DIR():
52
+ from aria_cli import CONFIG_DIR as val
53
+ return val
54
+
55
+ import json
56
+ import asyncio
57
+ import datetime
58
+ import time
59
+ import shlex
60
+ import sys
61
+ import os
62
+ from typing import Dict, Any, Optional
63
+
64
+
65
+ import json
66
+ import asyncio
67
+ import datetime
68
+ import time
69
+ import shlex
70
+ import sys
71
+ import os
72
+ from typing import Dict, Any, Optional
73
+
74
+
75
+ class WorkflowCommandsMixin:
76
+ """Mixin: interactive workflow and edit-review commands."""
77
+
78
+ def cmd_hooks(self, args: str):
79
+ global _JSON_HOOKS
80
+ hooks_dirs = [
81
+ _get_CONFIG_DIR() / "hooks",
82
+ pathlib.Path.cwd() / ".aria" / "hooks",
83
+ ]
84
+ parts = args.strip().split(maxsplit=1)
85
+ sub = parts[0].lower() if parts else "list"
86
+ rest = parts[1].strip() if len(parts) > 1 else ""
87
+
88
+ if sub == "reload":
89
+ if _get__HAS_JSON_HOOKS():
90
+ try:
91
+ _JSON_HOOKS = _load_hooks()
92
+ n = sum(len(v) for v in _JSON_HOOKS.values())
93
+ if self.context.has_rich:
94
+ self.context.console.print(f" [green]✓[/green] [dim]hooks.json reloaded ({n} entries)[/dim]")
95
+ else:
96
+ print(f" hooks.json reloaded ({n} entries)")
97
+ except Exception as exc:
98
+ if self.context.has_rich:
99
+ self.context.console.print(f" [red]✗ reload failed: {exc}[/red]")
100
+ else:
101
+ print(f" reload failed: {exc}")
102
+ return
103
+
104
+ if sub == "list":
105
+ if _get__HAS_JSON_HOOKS():
106
+ try:
107
+ from apps.cli.hooks import list_hooks as _list_json_hooks
108
+ _json_rows = _list_json_hooks()
109
+ if _json_rows:
110
+ if self.context.has_rich:
111
+ self.context.console.print()
112
+ self.context.console.print(" [bold]JSON Hooks[/bold] [dim](~/.arthera/hooks.json)[/dim]")
113
+ for r in _json_rows:
114
+ _block = " [red][blocking][/red]" if r["blocking"] else ""
115
+ _tool = f"[{r['tool']}]" if r["tool"] != "*" else ""
116
+ self.context.console.print(
117
+ f" [cyan]{r['event']:<16}[/cyan]{_tool:<14} "
118
+ f"[dim]{r['command']}[/dim]{_block}"
119
+ )
120
+ else:
121
+ for r in _json_rows:
122
+ print(f" {r['event']:<16} {r['tool']:<12} {r['command']}")
123
+ except Exception:
124
+ pass
125
+
126
+ found: list[tuple] = []
127
+ for hdir in hooks_dirs:
128
+ if hdir.exists():
129
+ for f in sorted(hdir.iterdir()):
130
+ if f.is_file() and not f.name.startswith("."):
131
+ found.append((str(hdir), f.name, str(f)))
132
+ if not found:
133
+ if self.context.has_rich:
134
+ self.context.console.print(" [dim]No hooks found.[/dim]")
135
+ self.context.console.print(" [dim]Hook dirs:[/dim]")
136
+ for d in hooks_dirs:
137
+ self.context.console.print(f" [dim]{_display_path(d, fallback='hook dir')}[/dim]")
138
+ self.context.console.print(" [dim]Events: prompt_submit response_done tool_use compact[/dim]")
139
+ else:
140
+ print("No hooks. Dirs:", [str(d) for d in hooks_dirs])
141
+ return
142
+ if self.context.has_rich:
143
+ self.context.console.print()
144
+ for hdir, name, path in found:
145
+ self.context.console.print(f" [dim]{name:<28}[/dim] {_display_path(path, fallback='hook')}")
146
+ self.context.console.print()
147
+ else:
148
+ for hdir, name, path in found:
149
+ print(f" {name} {_display_path(path, fallback='hook')}")
150
+
151
+ elif sub == "edit":
152
+ if not rest:
153
+ if _get__HAS_JSON_HOOKS():
154
+ from apps.cli.hooks import hooks_file_path, create_example_hooks
155
+ _hpath = hooks_file_path("global")
156
+ create_example_hooks(_hpath)
157
+ editor = os.getenv("EDITOR", "nano")
158
+ try:
159
+ import subprocess as _sp
160
+ _sp.run([editor, str(_hpath)])
161
+ _JSON_HOOKS = _load_hooks()
162
+ except Exception as exc:
163
+ if self.context.has_rich:
164
+ self.context.console.print(f"[red]Could not open editor: {exc}[/red]")
165
+ else:
166
+ print(f"Could not open editor: {exc}")
167
+ return
168
+ event = rest
169
+ hdir = _get_CONFIG_DIR() / "hooks"
170
+ hdir.mkdir(parents=True, exist_ok=True)
171
+ script = hdir / f"{event}.sh"
172
+ if not script.exists():
173
+ script.write_text(
174
+ f"#!/bin/bash\n# Aria hook: {event}\n# "
175
+ f"Env vars: ARIA_EVENT ARIA_TOOL ARIA_TOOL_PARAMS ARIA_RESPONSE ARIA_SESSION\n\n"
176
+ f'echo "Hook {event} fired"\n',
177
+ encoding="utf-8"
178
+ )
179
+ script.chmod(0o755)
180
+ editor = os.getenv("EDITOR", "nano")
181
+ try:
182
+ import subprocess as _sp
183
+ _sp.run([editor, str(script)])
184
+ except Exception as exc:
185
+ self.context.console.print(f"[red]Could not open editor: {exc}[/red]" if self.context.has_rich else str(exc))
186
+
187
+ elif sub == "run":
188
+ event = rest or "ResponseDone"
189
+ if _get__HAS_JSON_HOOKS():
190
+ _fire_json_hook(event, session_id=getattr(self.terminal, "session_id", ""), hooks=_JSON_HOOKS)
191
+ _run_event_hook(event, {"ARIA_EVENT": event, "ARIA_SESSION": getattr(self.terminal, "session_id", "")})
192
+ if self.context.has_rich:
193
+ self.context.console.print(f" [dim]Hook '{event}' triggered[/dim]")
194
+ else:
195
+ print(f"Hook '{event}' triggered")
196
+
197
+ else:
198
+ if self.context.has_rich:
199
+ self.context.console.print("[dim]Usage: /hooks list|edit [event]|reload|run [event][/dim]")
200
+ else:
201
+ print("Usage: /hooks list|edit [event]|reload|run [event]")
202
+
203
+ async def cmd_regen(self, args: str):
204
+ last_user_msg = None
205
+ for i in range(len(self.terminal.conversation) - 1, -1, -1):
206
+ if self.terminal.conversation[i]["role"] == "assistant":
207
+ self.terminal.conversation.pop(i)
208
+ break
209
+ for msg in reversed(self.terminal.conversation):
210
+ if msg["role"] == "user":
211
+ last_user_msg = msg["content"]
212
+ break
213
+ if last_user_msg:
214
+ for i in range(len(self.terminal.conversation) - 1, -1, -1):
215
+ if self.terminal.conversation[i]["role"] == "user" and self.terminal.conversation[i]["content"] == last_user_msg:
216
+ self.terminal.conversation.pop(i)
217
+ break
218
+ self.context.console.print("[dim]Regenerating...[/dim]" if self.context.has_rich else "Regenerating...")
219
+ await self.terminal.send_message(last_user_msg)
220
+ else:
221
+ self.context.console.print("[dim]No message to regenerate[/dim]" if self.context.has_rich else "Nothing to regenerate")
222
+
223
+ def cmd_undo(self, args: str):
224
+ if len(self.terminal.conversation) < 2:
225
+ self.context.console.print("[dim]Nothing to undo[/dim]" if self.context.has_rich else "Nothing to undo")
226
+ return
227
+ removed = 0
228
+ for role in ("assistant", "user"):
229
+ for i in range(len(self.terminal.conversation) - 1, -1, -1):
230
+ if self.terminal.conversation[i]["role"] == role:
231
+ self.terminal.conversation.pop(i)
232
+ removed += 1
233
+ break
234
+ if self.context.has_rich:
235
+ self.context.console.print(f"[dim]Undone ({removed} messages removed, {len(self.terminal.conversation)} remaining)[/dim]")
236
+ else:
237
+ print(f"Undone ({removed} removed)")
238
+
239
+ def cmd_rewind(self, args: str):
240
+ """Restore code checkpoints, conversation history, or both."""
241
+ from runtime.checkpoints import (
242
+ CheckpointConflictError,
243
+ CheckpointNotFoundError,
244
+ CheckpointStore,
245
+ )
246
+
247
+ parts = [part for part in args.strip().split() if part]
248
+ assume_yes = "--yes" in parts or "-y" in parts
249
+ parts = [part for part in parts if part not in {"--yes", "-y"}]
250
+ mode = parts[0].lower() if parts else "code"
251
+ identifier = parts[1] if len(parts) > 1 else ""
252
+ is_zh = str(self.terminal.config.get("ui_lang", "en")).lower().startswith("zh")
253
+
254
+ if mode in {"conversation", "chat"}:
255
+ self.cmd_undo("")
256
+ return
257
+ if mode in {"turn", "turns", "green"}:
258
+ self._rewind_transaction(mode, identifier, assume_yes=assume_yes, is_zh=is_zh)
259
+ return
260
+ if mode not in {"code", "both", "list"}:
261
+ identifier = parts[0]
262
+ mode = "code"
263
+
264
+ try:
265
+ store = CheckpointStore()
266
+ except Exception as exc:
267
+ message = f"无法打开检查点存储: {exc}" if is_zh else f"Cannot open checkpoint store: {exc}"
268
+ self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
269
+ return
270
+
271
+ if mode == "list":
272
+ records = store.list(session_id=self.terminal.session_id, status="active", limit=12)
273
+ if not records:
274
+ records = store.list(status="active", limit=12)
275
+ if not records:
276
+ message = "没有可恢复的代码检查点" if is_zh else "No active code checkpoints"
277
+ self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
278
+ return
279
+ if self.context.has_rich:
280
+ self.context.console.print()
281
+ self.context.console.print(" [bold]Code checkpoints[/bold]")
282
+ for record in records:
283
+ paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
284
+ run_label = (record.run_id or "standalone")[:10]
285
+ self.context.console.print(
286
+ f" [#C08050]{record.checkpoint_id[:10]}[/#C08050] "
287
+ f"[dim]{run_label:<10} · {record.source:<10} · {paths}[/dim]"
288
+ )
289
+ self.context.console.print()
290
+ else:
291
+ for record in records:
292
+ paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
293
+ print(f"{record.checkpoint_id[:10]} {record.run_id or '-'} {record.source} {paths}")
294
+ return
295
+
296
+ if not assume_yes:
297
+ prompt = (
298
+ " 恢复代码到检查点状态?检查点之后的修改不会被覆盖,存在冲突时会停止。 [y/N] "
299
+ if is_zh else
300
+ " Rewind code to its checkpoint? Later changes are protected by conflict checks. [y/N] "
301
+ )
302
+ try:
303
+ answer = (self.context.console.input(prompt) if self.context.has_rich else input(prompt)).strip().lower()
304
+ except (EOFError, KeyboardInterrupt):
305
+ return
306
+ if answer not in {"y", "yes"}:
307
+ message = "已取消" if is_zh else "Cancelled"
308
+ self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
309
+ return
310
+
311
+ try:
312
+ if identifier:
313
+ checkpoint = store.get(identifier)
314
+ if checkpoint is not None:
315
+ result = store.restore_checkpoint(checkpoint.checkpoint_id)
316
+ else:
317
+ result = store.restore_run(identifier)
318
+ else:
319
+ try:
320
+ result = store.restore_latest(session_id=self.terminal.session_id)
321
+ except CheckpointNotFoundError:
322
+ result = store.restore_latest()
323
+ except CheckpointConflictError as exc:
324
+ message = f"恢复已停止: {exc}" if is_zh else f"Rewind stopped: {exc}"
325
+ self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
326
+ return
327
+ except CheckpointNotFoundError:
328
+ message = "未找到可恢复的检查点" if is_zh else "No restorable checkpoint found"
329
+ self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
330
+ return
331
+ except Exception as exc:
332
+ message = f"恢复失败: {exc}" if is_zh else f"Rewind failed: {exc}"
333
+ self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
334
+ return
335
+
336
+ if mode == "both":
337
+ self.cmd_undo("")
338
+ count = len(result.restored_paths)
339
+ message = (
340
+ f"已恢复 {count} 个文件" if is_zh else f"Rewound {count} file{'s' if count != 1 else ''}"
341
+ )
342
+ if self.context.has_rich:
343
+ self.context.console.print(f"[green]✓[/green] [dim]{message}[/dim]")
344
+ for path in result.restored_paths:
345
+ self.context.console.print(f" [dim]{path}[/dim]")
346
+ else:
347
+ print(message)
348
+ for path in result.restored_paths:
349
+ print(f" {path}")
350
+
351
+ def _rewind_transaction(self, mode: str, ref: str, *, assume_yes: bool, is_zh: bool) -> None:
352
+ """``/rewind turns`` · ``/rewind turn [N|id]`` · ``/rewind green``.
353
+
354
+ A turn rewind puts back files, conversation, task list, approvals,
355
+ background tasks and the task worktree as they were before that turn.
356
+ """
357
+ from apps.cli import transactions
358
+ from aria_code.runtime.checkpoints import CheckpointConflictError
359
+
360
+ con = self.context.console if self.context.has_rich else None
361
+
362
+ def say(text: str, style: str = "dim") -> None:
363
+ if con is not None:
364
+ from rich.markup import escape
365
+ con.print(f"[{style}]{escape(text)}[/{style}]" if style else escape(text))
366
+ else:
367
+ print(text)
368
+
369
+ session_id = str(self.terminal.session_id or "default")
370
+ store = transactions.store()
371
+ if mode == "turns":
372
+ points = store.list(session_id)
373
+ if not points:
374
+ say("还没有可回退的轮次" if is_zh else "No turns to rewind yet")
375
+ return
376
+ say("回退点(✓ 检查通过 ✗ 失败 ≈ 仅改动前已有的失败 · 未验证)" if is_zh
377
+ else "Rewind points (✓ checks passed ✗ failed ≈ only failures that predate it · unverified)", "bold")
378
+ for line in transactions.describe(points):
379
+ say(line, "")
380
+ say("/rewind turn N · /rewind green")
381
+ return
382
+
383
+ point = store.latest_green(session_id) if mode == "green" else store.find(session_id, ref or "1")
384
+ if point is None:
385
+ if mode == "green":
386
+ say("没有检查通过的回退点" if is_zh else "No point where the checks passed")
387
+ else:
388
+ say(f"没有回退点 {ref or '1'}" if is_zh else f"No rewind point {ref or '1'}; see /rewind turns")
389
+ return
390
+ if not assume_yes:
391
+ question = (
392
+ f" 回退到第 {point.turn} 轮之前(文件、对话、待办、授权一起恢复)? [y/N] " if is_zh else
393
+ f" Rewind to before turn {point.turn} — files, conversation, tasks and approvals? [y/N] "
394
+ )
395
+ try:
396
+ answer = (con.input(question) if con is not None else input(question)).strip().lower()
397
+ except (EOFError, KeyboardInterrupt):
398
+ return
399
+ if answer not in {"y", "yes"}:
400
+ say("已取消" if is_zh else "Cancelled")
401
+ return
402
+ try:
403
+ outcome = transactions.rewind(self.terminal, point)
404
+ except CheckpointConflictError as exc:
405
+ say((f"回退已停止,未做任何改动: {exc}" if is_zh else f"Rewind stopped, nothing changed: {exc}"), "red")
406
+ return
407
+ except Exception as exc:
408
+ say((f"回退失败: {exc}" if is_zh else f"Rewind failed: {exc}"), "red")
409
+ return
410
+ for index, line in enumerate(outcome.lines()):
411
+ say(line, "green" if index == 0 else "dim")
412
+
413
+ def _workflow_workspace(self) -> str:
414
+ return self.terminal.config.get("_session_workspace_root") or os.getcwd()
415
+
416
+ def _wf_say(self, text: str, style: str = "dim") -> None:
417
+ if self.context.has_rich:
418
+ from rich.markup import escape
419
+ self.context.console.print(f"[{style}]{escape(text)}[/{style}]" if style else escape(text))
420
+ else:
421
+ print(text)
422
+
423
+ def _wf_ask(self, question: str) -> bool:
424
+ try:
425
+ answer = (self.context.console.input(question) if self.context.has_rich else input(question))
426
+ except (EOFError, KeyboardInterrupt):
427
+ return False
428
+ return answer.strip().lower() in {"y", "yes"}
429
+
430
+ async def cmd_workflow(self, args: str):
431
+ """/workflow list | show <name> | run <name> [args] | new <name>."""
432
+ from aria_code.runtime import workflows
433
+
434
+ parts = args.strip().split(maxsplit=2)
435
+ sub = parts[0].lower() if parts else "list"
436
+ name = parts[1].lstrip("/").lower() if len(parts) > 1 else ""
437
+ rest = parts[2] if len(parts) > 2 else ""
438
+ workspace = self._workflow_workspace()
439
+
440
+ if sub == "list":
441
+ found = workflows.names(workspace)
442
+ if not found:
443
+ self._wf_say("No workflows. /workflow new <name> creates .aria/workflows/<name>.yaml")
444
+ return
445
+ for item in found:
446
+ try:
447
+ workflow = workflows.find(workspace, item)
448
+ self._wf_say(f" /{item:<14} {workflow.description or ''} ({len(workflow.steps)} steps)", "")
449
+ except workflows.WorkflowError as exc:
450
+ self._wf_say(f" /{item:<14} invalid: {exc}", "red")
451
+ return
452
+ if sub == "new":
453
+ if not name:
454
+ self._wf_say("Usage: /workflow new <name>")
455
+ return
456
+ target = pathlib.Path(workspace) / ".aria" / "workflows" / f"{name}.yaml"
457
+ if target.exists():
458
+ self._wf_say(f"{target} already exists", "yellow")
459
+ return
460
+ target.parent.mkdir(parents=True, exist_ok=True)
461
+ target.write_text(workflows.TEMPLATE.format(name=name), encoding="utf-8")
462
+ self._wf_say(f"Created {target}; edit its steps, then run /{name}", "green")
463
+ return
464
+ if sub not in {"show", "run"} or not name:
465
+ self._wf_say("Usage: /workflow list | show <name> | run <name> [args] | new <name>")
466
+ return
467
+ try:
468
+ workflow = workflows.find(workspace, name)
469
+ except workflows.WorkflowError as exc:
470
+ self._wf_say(str(exc), "red")
471
+ return
472
+ if workflow is None:
473
+ self._wf_say(f"No workflow '{name}' in .aria/workflows; /workflow list", "yellow")
474
+ return
475
+ if sub == "show":
476
+ for line in workflow.outline():
477
+ self._wf_say(line, "")
478
+ return
479
+ await self._run_workflow(workflow, rest)
480
+
481
+ async def _run_workflow(self, workflow, args: str) -> None:
482
+ from aria_code.runtime.workflows import TrustStore
483
+ from aria_code.apps.cli.workflow_runner import run_workflow, summary_lines
484
+
485
+ trust = TrustStore.load()
486
+ if not trust.trusted(workflow):
487
+ self._wf_say("This workflow comes from the repository and has not run here before"
488
+ " (or its file changed). It will run:", "yellow")
489
+ for line in workflow.outline():
490
+ self._wf_say(line, "")
491
+ if not self._wf_ask(" Trust and run it? [y/N] "):
492
+ self._wf_say("Cancelled")
493
+ return
494
+ trust.trust(workflow)
495
+ results = await run_workflow(self.terminal, workflow, args, ask=self._wf_ask, say=self._wf_say)
496
+ for index, line in enumerate(summary_lines(workflow, results)):
497
+ style = ("red" if "FAILED" in line else "yellow" if "STOPPED" in line else "green") if index == 0 else "dim"
498
+ self._wf_say(line, style)
499
+
500
+ async def cmd_retry(self, args: str):
501
+ last_user_msg = None
502
+ for i in range(len(self.terminal.conversation) - 1, -1, -1):
503
+ if self.terminal.conversation[i]["role"] == "assistant":
504
+ self.terminal.conversation.pop(i)
505
+ break
506
+ for msg in reversed(self.terminal.conversation):
507
+ if msg["role"] == "user":
508
+ last_user_msg = msg["content"]
509
+ break
510
+ if not last_user_msg:
511
+ self.context.console.print("[dim]No message to retry[/dim]" if self.context.has_rich else "Nothing to retry")
512
+ return
513
+ for i in range(len(self.terminal.conversation) - 1, -1, -1):
514
+ if self.terminal.conversation[i]["role"] == "user" and self.terminal.conversation[i]["content"] == last_user_msg:
515
+ self.terminal.conversation.pop(i)
516
+ break
517
+ orig_model_key = resolve_model_key(self.terminal.config.get("model", "qwen2.5:7b"))
518
+ _fallback_model = _get_MODELS().get("qwen-fast") or _get_MODELS().get("qwen7b") or next(iter(_get_MODELS().values()))
519
+ orig_temp = _get_MODELS().get(orig_model_key, _fallback_model).get("temperature", 0.3)
520
+ _get_MODELS()[orig_model_key]["temperature"] = min(0.9, orig_temp + 0.3)
521
+ if self.context.has_rich:
522
+ self.context.console.print(f"[dim]Retrying with temperature {_get_MODELS()[orig_model_key]['temperature']:.1f}...[/dim]")
523
+ else:
524
+ print("Retrying (temp +0.3)...")
525
+ try:
526
+ await self.terminal.send_message(last_user_msg)
527
+ finally:
528
+ _get_MODELS()[orig_model_key]["temperature"] = orig_temp
529
+
530
+ def cmd_note(self, args: str):
531
+ text = args.strip()
532
+ if not text:
533
+ self.context.console.print("[dim]Usage: /note <text>[/dim]" if self.context.has_rich else "Usage: /note <text>")
534
+ return
535
+ aria_md = pathlib.Path.cwd() / "ARIA.md"
536
+ now_str = datetime.now().strftime("%Y-%m-%d %H:%M")
537
+ entry = f"\n- [{now_str}] {text}"
538
+ if aria_md.exists():
539
+ content = aria_md.read_text(encoding="utf-8")
540
+ if "## Notes" not in content:
541
+ content += "\n\n## Notes\n"
542
+ content += entry
543
+ else:
544
+ content = f"# Aria Project Notes\n\n## Notes\n{entry}\n"
545
+ aria_md.write_text(content, encoding="utf-8")
546
+ global _PROJECT_CONTEXT
547
+ _PROJECT_CONTEXT = _load_project_context()
548
+ if self.context.has_rich:
549
+ self.context.console.print(f"[dim]Note saved to {aria_md.name}[/dim]")
550
+ else:
551
+ print(f"Saved to {aria_md.name}")
552
+
553
+ async def cmd_review(self, args: str):
554
+ """Review a change with an isolated reviewer: /review [--staged | --base B | --commit SHA | PATH] [--json]."""
555
+ from aria_code import review_service as rs
556
+ from aria_code.apps.cli.review_runner import make_model_call
557
+
558
+ console = self.context.console if self.context.has_rich else None
559
+ say = (lambda text, style="": console.print(f"[{style}]{text}[/{style}]" if style else text)) if console \
560
+ else (lambda text, style="": print(text))
561
+ lang = "zh" if str(self.terminal.config.get("ui_lang", "en")).lower().startswith("zh") else "en"
562
+ try:
563
+ tokens = shlex.split(args)
564
+ as_json = "--json" in tokens
565
+ target = rs.target_from_args([t for t in tokens if t != "--json"])
566
+ inp = rs.collect(target, pathlib.Path.cwd())
567
+ except (ValueError, rs.ReviewError) as exc:
568
+ say(str(exc), "red")
569
+ say("Usage: /review [--staged | --base BRANCH | --commit SHA | PATH] [--json]", "dim")
570
+ return
571
+ if not inp.diff.strip():
572
+ say("No changes to review." if lang == "en" else "没有可审查的改动。", "dim")
573
+ return
574
+ say(f" ↳ {target.describe()} · {len(inp.files)} files · +{inp.added} −{inp.removed}", "dim")
575
+ if inp.truncated:
576
+ say(f" ↳ too large to review whole; not included: {', '.join(inp.omitted_files)}", "yellow")
577
+ _print_phase("Reviewing")
578
+ try:
579
+ result = await rs.run_review(inp, make_model_call(self.terminal.config), lang=lang)
580
+ except rs.ReviewError as exc:
581
+ say(str(exc), "red")
582
+ return
583
+ if as_json:
584
+ print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2))
585
+ elif console:
586
+ _print_review(console, result, lang)
587
+ else:
588
+ print(rs.render_text(result, lang=lang))
589
+ # The main conversation remembers the review, so "fix finding 2" works.
590
+ self.terminal.conversation.append({"role": "user", "content": f"/review {args}".strip()})
591
+ self.terminal.conversation.append({"role": "assistant", "content": rs.history_note(result)})
592
+
593
+
594
+ _PRIORITY_STYLE = {0: "bold red", 1: "red", 2: "yellow", 3: "dim"}
595
+
596
+
597
+ def _print_review(console, result, lang: str) -> None:
598
+ from rich.markup import escape
599
+
600
+ from aria_code import review_service as rs
601
+
602
+ if not result.structured:
603
+ console.print(escape(rs.render_text(result, lang=lang)))
604
+ return
605
+ t = rs._TEXT["zh" if lang == "zh" else "en"]
606
+ verdict, style = ((t["unknown"], "dim") if result.correct is None else
607
+ (t["correct"], "green") if result.correct else (t["incorrect"], "red"))
608
+ console.print(f"[bold {style}]{verdict}[/bold {style}] [dim]· {t['confidence']} {result.confidence:.2f}[/dim]")
609
+ if result.explanation:
610
+ console.print(escape(result.explanation))
611
+ if not result.findings:
612
+ console.print(f"[dim]{t['none']}[/dim]")
613
+ shown_outside = False
614
+ for number, f in enumerate(result.findings, 1):
615
+ if not f.in_change and not shown_outside:
616
+ console.print(f"[dim]— {t['outside']} —[/dim]")
617
+ shown_outside = True
618
+ style = _PRIORITY_STYLE.get(f.priority, "dim")
619
+ console.print(f"\n[{style}]{number}. {escape('[' + f.label + ']')}[/{style}] [bold]{escape(f.title)}[/bold] "
620
+ f"[dim]{escape(f.location)} · {f.confidence:.2f}[/dim]")
621
+ # Under the finding's title, wrapped rows included: printed with
622
+ # three leading spaces, a long explanation fell back to column 0.
623
+ from aria_code.ui.render.output import print_hanging
624
+
625
+ for line in f.body.splitlines():
626
+ if line.strip():
627
+ print_hanging(console, " ", line.strip())
628
+ if result.omitted_files:
629
+ console.print(f"\n[yellow]{t['omitted']}: {escape(', '.join(result.omitted_files))}[/yellow]")