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,115 @@
1
+ """Keep a Windows background command's descendants in one owned Job Object.
2
+
3
+ Lazy-imported only on Windows. Closing the last handle kills descendants,
4
+ including those still running after the command's original parent exited.
5
+ This manages lifetime; it is not a filesystem/network sandbox.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import ctypes as c
10
+ from ctypes import wintypes as w
11
+
12
+
13
+ class _Limits(c.Structure):
14
+ _fields_ = [("process_time", c.c_longlong), ("job_time", c.c_longlong),
15
+ ("flags", w.DWORD), ("min_working", c.c_size_t), ("max_working", c.c_size_t),
16
+ ("active_limit", w.DWORD), ("affinity", c.c_size_t),
17
+ ("priority", w.DWORD), ("scheduling", w.DWORD)]
18
+
19
+
20
+ class _IOCounters(c.Structure):
21
+ _fields_ = [(name, c.c_ulonglong) for name in ("read_ops", "write_ops", "other_ops",
22
+ "read_bytes", "write_bytes", "other_bytes")]
23
+
24
+
25
+ class _ExtendedLimits(c.Structure):
26
+ _fields_ = [("basic", _Limits), ("io", _IOCounters), ("process_memory", c.c_size_t),
27
+ ("job_memory", c.c_size_t), ("peak_process_memory", c.c_size_t),
28
+ ("peak_job_memory", c.c_size_t)]
29
+
30
+
31
+ class _Accounting(c.Structure):
32
+ _fields_ = [(name, c.c_longlong) for name in ("user_time", "kernel_time", "period_user", "period_kernel")]
33
+ _fields_ += [(name, w.DWORD) for name in ("page_faults", "total", "active", "terminated")]
34
+
35
+
36
+ class _ThreadEntry(c.Structure):
37
+ _fields_ = [("size", w.DWORD), ("usage", w.DWORD), ("thread_id", w.DWORD),
38
+ ("owner_pid", w.DWORD), ("priority", w.LONG), ("delta", w.LONG), ("flags", w.DWORD)]
39
+
40
+
41
+ class WindowsJob:
42
+ def __init__(self, popen):
43
+ self.api = c.WinDLL("kernel32", use_last_error=True)
44
+ signatures = {
45
+ "CreateJobObjectW": ([c.c_void_p, w.LPCWSTR], w.HANDLE),
46
+ "SetInformationJobObject": ([w.HANDLE, c.c_int, c.c_void_p, w.DWORD], w.BOOL),
47
+ "AssignProcessToJobObject": ([w.HANDLE, w.HANDLE], w.BOOL),
48
+ "QueryInformationJobObject": ([w.HANDLE, c.c_int, c.c_void_p, w.DWORD, c.c_void_p], w.BOOL),
49
+ "TerminateJobObject": ([w.HANDLE, w.UINT], w.BOOL),
50
+ "CloseHandle": ([w.HANDLE], w.BOOL),
51
+ "CreateToolhelp32Snapshot": ([w.DWORD, w.DWORD], w.HANDLE),
52
+ "Thread32First": ([w.HANDLE, c.POINTER(_ThreadEntry)], w.BOOL),
53
+ "Thread32Next": ([w.HANDLE, c.POINTER(_ThreadEntry)], w.BOOL),
54
+ "OpenThread": ([w.DWORD, w.BOOL, w.DWORD], w.HANDLE),
55
+ "ResumeThread": ([w.HANDLE], w.DWORD),
56
+ }
57
+ for name, (args, result) in signatures.items():
58
+ fn = getattr(self.api, name)
59
+ fn.argtypes, fn.restype = args, result
60
+ self.handle = self.api.CreateJobObjectW(None, None)
61
+ if not self.handle:
62
+ raise c.WinError(c.get_last_error())
63
+ try:
64
+ limits = _ExtendedLimits()
65
+ limits.basic.flags = 0x2000 # JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
66
+ if not self.api.SetInformationJobObject(self.handle, 9, c.byref(limits), c.sizeof(limits)):
67
+ raise c.WinError(c.get_last_error())
68
+ if not self.api.AssignProcessToJobObject(self.handle, int(popen._handle)):
69
+ raise c.WinError(c.get_last_error())
70
+ except BaseException:
71
+ self.close()
72
+ raise
73
+
74
+ def resume(self, pid: int) -> None:
75
+ # Popen closes CreateProcess's thread handle. Find the sole suspended
76
+ # initial thread using the documented Toolhelp API, then resume it.
77
+ snapshot = self.api.CreateToolhelp32Snapshot(0x4, 0) # TH32CS_SNAPTHREAD
78
+ if snapshot == c.c_void_p(-1).value:
79
+ raise c.WinError(c.get_last_error())
80
+ try:
81
+ entry = _ThreadEntry()
82
+ entry.size = c.sizeof(entry)
83
+ more = self.api.Thread32First(snapshot, c.byref(entry))
84
+ while more:
85
+ if entry.owner_pid == pid:
86
+ thread = self.api.OpenThread(0x2, False, entry.thread_id) # THREAD_SUSPEND_RESUME
87
+ if not thread:
88
+ raise c.WinError(c.get_last_error())
89
+ try:
90
+ if self.api.ResumeThread(thread) == 0xFFFFFFFF:
91
+ raise c.WinError(c.get_last_error())
92
+ return
93
+ finally:
94
+ self.api.CloseHandle(thread)
95
+ more = self.api.Thread32Next(snapshot, c.byref(entry))
96
+ raise OSError("Cannot find the background command's suspended thread")
97
+ finally:
98
+ self.api.CloseHandle(snapshot)
99
+
100
+ def running(self) -> bool:
101
+ if not self.handle:
102
+ return False
103
+ info = _Accounting()
104
+ if not self.api.QueryInformationJobObject(self.handle, 1, c.byref(info), c.sizeof(info), None):
105
+ raise c.WinError(c.get_last_error())
106
+ return bool(info.active)
107
+
108
+ def terminate(self) -> None:
109
+ if self.handle and not self.api.TerminateJobObject(self.handle, 1):
110
+ raise c.WinError(c.get_last_error())
111
+
112
+ def close(self) -> None:
113
+ if self.handle:
114
+ self.api.CloseHandle(self.handle)
115
+ self.handle = None
@@ -0,0 +1,222 @@
1
+ """User-defined workflows: ``.aria/workflows/<name>.yaml``, run as ``/<name>``.
2
+
3
+ A release is the same five steps every time — test, build, review, write
4
+ the changelog, open the PR — and typing them is where one gets skipped. A
5
+ workflow file names them once::
6
+
7
+ # .aria/workflows/release.yaml
8
+ description: Test, build, review, changelog, PR
9
+ steps:
10
+ - name: Tests
11
+ run: python -m pytest -q
12
+ - name: Build
13
+ run: python -m build
14
+ timeout: 600
15
+ - name: Security review
16
+ command: /review --base main
17
+ - name: Changelog
18
+ prompt: Add a CHANGELOG.md entry for the changes since the last tag. {{args}}
19
+ - name: Open the PR
20
+ run: gh pr create --fill
21
+ confirm: true
22
+
23
+ A step has exactly one of ``run`` (a shell command, through the same
24
+ ``run_command`` tool, policy and sandbox as the model's commands),
25
+ ``prompt`` (a full Aria turn with tools — its checks decide whether it
26
+ passed) or ``command`` (any slash command). ``confirm`` asks before the step,
27
+ ``continue_on_error`` keeps going past a failure, ``timeout`` bounds a
28
+ ``run``. ``{{args}}`` is what followed the command, ``{{date}}`` today.
29
+
30
+ The file comes with the repository, so whoever wrote it chose those
31
+ commands. The first run of a workflow — and the first after its file
32
+ changes — shows every step and asks; the answer is remembered by content
33
+ hash in ``<aria home>/trusted_workflows.json``.
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ import datetime as _dt
39
+ import hashlib
40
+ import json
41
+ import os
42
+ import re
43
+ from dataclasses import dataclass, field
44
+ from pathlib import Path
45
+ from typing import Optional
46
+
47
+ STEP_KINDS = ("run", "prompt", "command")
48
+ _STEP_KEYS = {"name", "run", "prompt", "command", "confirm", "continue_on_error", "timeout"}
49
+ _TOP_KEYS = {"name", "description", "steps"}
50
+ _NAME = re.compile(r"^[a-z0-9][a-z0-9_-]*$")
51
+ _PLACEHOLDER = re.compile(r"\{\{\s*(\w+)\s*\}\}")
52
+
53
+
54
+ class WorkflowError(ValueError):
55
+ """A workflow file that cannot be run, with the reason."""
56
+
57
+
58
+ @dataclass(frozen=True)
59
+ class WorkflowStep:
60
+ name: str
61
+ kind: str # run | prompt | command
62
+ body: str
63
+ confirm: bool = False
64
+ continue_on_error: bool = False
65
+ timeout: int = 300
66
+
67
+ def render(self, variables: dict) -> str:
68
+ return _PLACEHOLDER.sub(lambda m: str(variables.get(m.group(1), m.group(0))), self.body).strip()
69
+
70
+
71
+ @dataclass(frozen=True)
72
+ class Workflow:
73
+ name: str
74
+ path: str
75
+ description: str
76
+ steps: tuple[WorkflowStep, ...]
77
+ digest: str = ""
78
+
79
+ def outline(self) -> list[str]:
80
+ lines = [f"/{self.name} — {self.description}" if self.description else f"/{self.name}",
81
+ f" from {self.path}"]
82
+ for index, step in enumerate(self.steps, 1):
83
+ flags = [flag for flag, on in (("asks first", step.confirm),
84
+ ("continues on error", step.continue_on_error)) if on]
85
+ suffix = f" ({', '.join(flags)})" if flags else ""
86
+ body = " ".join(step.body.split())
87
+ lines.append(f" {index}. {step.name} — {step.kind}: {body[:90]}{suffix}")
88
+ return lines
89
+
90
+
91
+ def workflow_dirs(workspace: Path | str) -> list[Path]:
92
+ """``.aria/workflows`` in the workspace, then in its git root if different."""
93
+ start = Path(workspace).expanduser().resolve()
94
+ dirs = [start / ".aria" / "workflows"]
95
+ for parent in start.parents:
96
+ if (parent / ".git").exists():
97
+ if parent / ".aria" / "workflows" not in dirs:
98
+ dirs.append(parent / ".aria" / "workflows")
99
+ break
100
+ return [d for d in dirs if d.is_dir()]
101
+
102
+
103
+ def _files(workspace: Path | str) -> dict[str, Path]:
104
+ found: dict[str, Path] = {}
105
+ for directory in workflow_dirs(workspace):
106
+ for path in sorted(directory.glob("*.y*ml")):
107
+ if path.suffix in (".yaml", ".yml"):
108
+ found.setdefault(path.stem.lower(), path)
109
+ return found
110
+
111
+
112
+ def names(workspace: Path | str) -> list[str]:
113
+ return sorted(_files(workspace))
114
+
115
+
116
+ def _parse_step(index: int, raw: object, path: Path) -> WorkflowStep:
117
+ where = f"{path.name}, step {index}"
118
+ if not isinstance(raw, dict):
119
+ raise WorkflowError(f"{where}: a step is a mapping with run, prompt or command")
120
+ unknown = set(raw) - _STEP_KEYS
121
+ if unknown:
122
+ raise WorkflowError(f"{where}: unknown key {', '.join(sorted(unknown))}")
123
+ kinds = [kind for kind in STEP_KINDS if raw.get(kind) not in (None, "")]
124
+ if len(kinds) != 1:
125
+ raise WorkflowError(f"{where}: needs exactly one of run, prompt, command")
126
+ kind = kinds[0]
127
+ body = str(raw[kind])
128
+ if kind == "command" and not body.lstrip().startswith("/"):
129
+ raise WorkflowError(f"{where}: command must be a slash command, e.g. /review")
130
+ try:
131
+ timeout = int(raw.get("timeout", 300))
132
+ except (TypeError, ValueError):
133
+ raise WorkflowError(f"{where}: timeout must be a number of seconds") from None
134
+ default_name = " ".join(body.split())[:40]
135
+ return WorkflowStep(name=str(raw.get("name") or default_name), kind=kind, body=body,
136
+ confirm=bool(raw.get("confirm", False)),
137
+ continue_on_error=bool(raw.get("continue_on_error", False)),
138
+ timeout=max(1, timeout))
139
+
140
+
141
+ def parse(path: Path | str) -> Workflow:
142
+ path = Path(path)
143
+ try:
144
+ text = path.read_text(encoding="utf-8")
145
+ except OSError as exc:
146
+ raise WorkflowError(f"{path}: cannot read: {exc}") from exc
147
+ try:
148
+ import yaml
149
+
150
+ data = yaml.safe_load(text)
151
+ except Exception as exc:
152
+ raise WorkflowError(f"{path.name}: not valid YAML: {exc}") from exc
153
+ if not isinstance(data, dict):
154
+ raise WorkflowError(f"{path.name}: expected a mapping with steps")
155
+ unknown = set(data) - _TOP_KEYS
156
+ if unknown:
157
+ raise WorkflowError(f"{path.name}: unknown key {', '.join(sorted(unknown))}")
158
+ steps = data.get("steps")
159
+ if not isinstance(steps, list) or not steps:
160
+ raise WorkflowError(f"{path.name}: steps must be a non-empty list")
161
+ name = str(data.get("name") or path.stem).lower()
162
+ if not _NAME.match(name):
163
+ raise WorkflowError(f"{path.name}: name '{name}' must be lowercase letters, digits, - or _")
164
+ return Workflow(
165
+ name=name, path=str(path), description=str(data.get("description") or ""),
166
+ steps=tuple(_parse_step(i, raw, path) for i, raw in enumerate(steps, 1)),
167
+ digest=hashlib.sha256(text.encode("utf-8")).hexdigest(),
168
+ )
169
+
170
+
171
+ def find(workspace: Path | str, name: str) -> Optional[Workflow]:
172
+ """The workflow called ``name`` (``/name`` works too), or None. Invalid files raise."""
173
+ path = _files(workspace).get(name.lstrip("/").lower())
174
+ return parse(path) if path is not None else None
175
+
176
+
177
+ def variables(workflow: Workflow, args: str) -> dict:
178
+ return {"args": args.strip(), "date": _dt.date.today().isoformat(), "workflow": workflow.name}
179
+
180
+
181
+ # ── trust ──────────────────────────────────────────────────────────────────
182
+
183
+ @dataclass
184
+ class TrustStore:
185
+ path: Path
186
+ entries: dict = field(default_factory=dict)
187
+
188
+ @classmethod
189
+ def load(cls, path: Optional[Path] = None) -> "TrustStore":
190
+ if path is None:
191
+ from ..packages.aria_core.paths import aria_home
192
+
193
+ path = aria_home() / "trusted_workflows.json"
194
+ try:
195
+ entries = json.loads(Path(path).read_text(encoding="utf-8"))
196
+ except (OSError, ValueError):
197
+ entries = {}
198
+ return cls(Path(path), entries if isinstance(entries, dict) else {})
199
+
200
+ def trusted(self, workflow: Workflow) -> bool:
201
+ return self.entries.get(str(Path(workflow.path).resolve())) == workflow.digest
202
+
203
+ def trust(self, workflow: Workflow) -> None:
204
+ self.entries[str(Path(workflow.path).resolve())] = workflow.digest
205
+ self.path.parent.mkdir(parents=True, exist_ok=True)
206
+ temp = self.path.with_suffix(".tmp")
207
+ temp.write_text(json.dumps(self.entries, indent=2, sort_keys=True), encoding="utf-8")
208
+ os.replace(temp, self.path)
209
+
210
+
211
+ TEMPLATE = """\
212
+ # /{name} — run with /{name} [args]; {{{{args}}}} is what you type after it.
213
+ description: Test, review and summarise the current change
214
+ steps:
215
+ - name: Tests
216
+ run: python -m pytest -q
217
+ - name: Review
218
+ command: /review
219
+ - name: Summary
220
+ prompt: Summarise the current change for a pull request description. {{{{args}}}}
221
+ continue_on_error: true
222
+ """
@@ -0,0 +1,215 @@
1
+ """Git worktree isolation for write-capable background agents."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+ import subprocess
7
+ from dataclasses import dataclass
8
+ from pathlib import Path
9
+
10
+
11
+ class WorktreeError(RuntimeError):
12
+ """Raised when an isolated worktree cannot be created safely."""
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class WorktreeSpec:
17
+ task_id: str
18
+ repository: str
19
+ path: str
20
+ branch: str
21
+ base_revision: str
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class WorktreeApplyResult:
26
+ paths: tuple[str, ...]
27
+ tracked_paths: tuple[str, ...]
28
+ untracked_paths: tuple[str, ...]
29
+
30
+
31
+ class WorktreeManager:
32
+ """Create task-specific worktrees without changing the caller's cwd."""
33
+
34
+ def __init__(self, root: Path | str) -> None:
35
+ self.root = Path(root).expanduser().resolve()
36
+ self.root.mkdir(parents=True, exist_ok=True)
37
+
38
+ @staticmethod
39
+ def _git(*args: str, cwd: Path) -> str:
40
+ try:
41
+ completed = subprocess.run(
42
+ ["git", *args],
43
+ cwd=str(cwd),
44
+ text=True,
45
+ capture_output=True,
46
+ timeout=30,
47
+ check=False,
48
+ )
49
+ except (OSError, subprocess.SubprocessError) as exc:
50
+ raise WorktreeError(f"Unable to run git: {exc}") from exc
51
+ if completed.returncode != 0:
52
+ detail = (completed.stderr or completed.stdout).strip()
53
+ raise WorktreeError(detail or f"git {' '.join(args)} failed")
54
+ return completed.stdout.strip()
55
+
56
+ @classmethod
57
+ def repository_root(cls, workspace: Path | str) -> Path:
58
+ path = Path(workspace).expanduser().resolve()
59
+ output = cls._git("rev-parse", "--show-toplevel", cwd=path)
60
+ return Path(output).resolve()
61
+
62
+ @classmethod
63
+ def is_clean(cls, repository: Path | str) -> bool:
64
+ repo = Path(repository).expanduser().resolve()
65
+ return not cls._git("status", "--porcelain", "--untracked-files=all", cwd=repo)
66
+
67
+ def create(
68
+ self,
69
+ *,
70
+ task_id: str,
71
+ workspace: Path | str,
72
+ require_clean: bool = True,
73
+ ) -> WorktreeSpec:
74
+ repository = self.repository_root(workspace)
75
+ if require_clean and not self.is_clean(repository):
76
+ raise WorktreeError(
77
+ "The repository has uncommitted changes. Commit or stash them before "
78
+ "starting a write-capable isolated subagent."
79
+ )
80
+ base_revision = self._git("rev-parse", "HEAD", cwd=repository)
81
+ branch = f"aria/task-{task_id}"
82
+ destination = (self.root / repository.name / task_id).resolve()
83
+ if destination.exists():
84
+ raise WorktreeError(f"Worktree path already exists: {destination}")
85
+ destination.parent.mkdir(parents=True, exist_ok=True)
86
+ try:
87
+ self._git(
88
+ "worktree",
89
+ "add",
90
+ "-b",
91
+ branch,
92
+ str(destination),
93
+ base_revision,
94
+ cwd=repository,
95
+ )
96
+ except Exception:
97
+ if destination.exists():
98
+ shutil.rmtree(destination, ignore_errors=True)
99
+ raise
100
+ return WorktreeSpec(
101
+ task_id=task_id,
102
+ repository=str(repository),
103
+ path=str(destination),
104
+ branch=branch,
105
+ base_revision=base_revision,
106
+ )
107
+
108
+ def remove(self, spec: WorktreeSpec, *, force: bool = False) -> None:
109
+ repository = Path(spec.repository)
110
+ path = Path(spec.path)
111
+ args = ["worktree", "remove"]
112
+ if force:
113
+ args.append("--force")
114
+ args.append(str(path))
115
+ self._git(*args, cwd=repository)
116
+
117
+ def delete_branch(self, spec: WorktreeSpec, *, force: bool = False) -> None:
118
+ flag = "-D" if force else "-d"
119
+ self._git("branch", flag, spec.branch, cwd=Path(spec.repository))
120
+
121
+ @classmethod
122
+ def diff(cls, spec: WorktreeSpec) -> str:
123
+ worktree = Path(spec.path)
124
+ diff_stat = cls._git("diff", "--stat", spec.base_revision, cwd=worktree)
125
+ untracked = cls._git("ls-files", "--others", "--exclude-standard", cwd=worktree)
126
+ parts = [part for part in (diff_stat, untracked) if part]
127
+ return "\n".join(parts)
128
+
129
+ @staticmethod
130
+ def _git_binary(*args: str, cwd: Path, input_data: bytes | None = None) -> bytes:
131
+ try:
132
+ completed = subprocess.run(
133
+ ["git", *args],
134
+ cwd=str(cwd),
135
+ input=input_data,
136
+ capture_output=True,
137
+ timeout=30,
138
+ check=False,
139
+ )
140
+ except (OSError, subprocess.SubprocessError) as exc:
141
+ raise WorktreeError(f"Unable to run git: {exc}") from exc
142
+ if completed.returncode != 0:
143
+ detail = (completed.stderr or completed.stdout).decode("utf-8", errors="replace").strip()
144
+ raise WorktreeError(detail or f"git {' '.join(args)} failed")
145
+ return completed.stdout
146
+
147
+ def apply(self, spec: WorktreeSpec) -> WorktreeApplyResult:
148
+ """Apply an isolated worktree's unstaged result to a clean main worktree."""
149
+ repository = Path(spec.repository)
150
+ worktree = Path(spec.path)
151
+ if not self.is_clean(repository):
152
+ raise WorktreeError(
153
+ "The target workspace changed after the subagent started. "
154
+ "Commit or stash those changes before applying the task result."
155
+ )
156
+ target_revision = self._git("rev-parse", "HEAD", cwd=repository)
157
+ if target_revision != spec.base_revision:
158
+ raise WorktreeError(
159
+ "The target branch advanced after the subagent started. "
160
+ "Review or rebase the task worktree before applying it."
161
+ )
162
+
163
+ tracked, untracked = self.changed_paths(spec)
164
+ if not tracked and not untracked:
165
+ raise WorktreeError("The subagent worktree contains no changes to apply.")
166
+
167
+ for relative in untracked:
168
+ destination = repository / relative
169
+ if destination.exists():
170
+ raise WorktreeError(
171
+ f"Refusing to overwrite an existing untracked path: {destination}"
172
+ )
173
+
174
+ patch = self._git_binary(
175
+ "diff", "--binary", spec.base_revision, cwd=worktree
176
+ )
177
+ if patch:
178
+ self._git_binary("apply", "--check", "-", cwd=repository, input_data=patch)
179
+
180
+ copied: list[Path] = []
181
+ patch_applied = False
182
+ try:
183
+ if patch:
184
+ self._git_binary("apply", "-", cwd=repository, input_data=patch)
185
+ patch_applied = True
186
+ for relative in untracked:
187
+ source = worktree / relative
188
+ destination = repository / relative
189
+ if source.is_symlink():
190
+ raise WorktreeError(f"Refusing to copy an untracked symlink: {source}")
191
+ destination.parent.mkdir(parents=True, exist_ok=True)
192
+ shutil.copy2(source, destination)
193
+ copied.append(destination)
194
+ except Exception:
195
+ for destination in reversed(copied):
196
+ if destination.exists():
197
+ destination.unlink()
198
+ if patch_applied:
199
+ self._git_binary("apply", "--reverse", "-", cwd=repository, input_data=patch)
200
+ raise
201
+
202
+ paths = tuple(dict.fromkeys([*tracked, *untracked]))
203
+ return WorktreeApplyResult(paths, tracked, untracked)
204
+
205
+ def changed_paths(self, spec: WorktreeSpec) -> tuple[tuple[str, ...], tuple[str, ...]]:
206
+ worktree = Path(spec.path)
207
+ tracked_text = self._git(
208
+ "diff", "--name-only", spec.base_revision, cwd=worktree
209
+ )
210
+ tracked = tuple(path for path in tracked_text.splitlines() if path)
211
+ untracked_text = self._git(
212
+ "ls-files", "--others", "--exclude-standard", cwd=worktree
213
+ )
214
+ untracked = tuple(path for path in untracked_text.splitlines() if path)
215
+ return tracked, untracked
@@ -0,0 +1,4 @@
1
+ """Compatibility import for :mod:`clients.runway_video_client`."""
2
+ from importlib import import_module as _import_module
3
+ import sys as _sys
4
+ _sys.modules[__name__] = _import_module("clients.runway_video_client")
@@ -0,0 +1,27 @@
1
+ """Safety and permission primitives for Aria Code."""
2
+
3
+ from .service import SafetyService
4
+ from .permissions import (
5
+ PermissionDecision,
6
+ PermissionMode,
7
+ PermissionService,
8
+ PolicyDecision,
9
+ classify_command_risk,
10
+ evaluate_command_policy,
11
+ normalize_command,
12
+ )
13
+ from .risk import RiskAssessment, assess_command, assess_tool
14
+
15
+ __all__ = [
16
+ "SafetyService",
17
+ "PermissionDecision",
18
+ "PermissionMode",
19
+ "PermissionService",
20
+ "PolicyDecision",
21
+ "classify_command_risk",
22
+ "RiskAssessment",
23
+ "assess_command",
24
+ "assess_tool",
25
+ "evaluate_command_policy",
26
+ "normalize_command",
27
+ ]