easy-sandbox 0.1.0__tar.gz

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 (344) hide show
  1. easy_sandbox-0.1.0/.agents/notes/README.md +95 -0
  2. easy_sandbox-0.1.0/.gitignore +76 -0
  3. easy_sandbox-0.1.0/CHANGELOG.md +182 -0
  4. easy_sandbox-0.1.0/LICENSE +200 -0
  5. easy_sandbox-0.1.0/NOTICE +14 -0
  6. easy_sandbox-0.1.0/PKG-INFO +334 -0
  7. easy_sandbox-0.1.0/README.md +258 -0
  8. easy_sandbox-0.1.0/SKILL.md +268 -0
  9. easy_sandbox-0.1.0/docs/README.md +4 -0
  10. easy_sandbox-0.1.0/docs/en/README.md +75 -0
  11. easy_sandbox-0.1.0/docs/zh/README.md +88 -0
  12. easy_sandbox-0.1.0/examples/README.md +164 -0
  13. easy_sandbox-0.1.0/examples/compat-demos/README.md +157 -0
  14. easy_sandbox-0.1.0/examples/quickstart/README.md +106 -0
  15. easy_sandbox-0.1.0/examples/templates/README.md +64 -0
  16. easy_sandbox-0.1.0/examples/templates/python-hello/README.md +57 -0
  17. easy_sandbox-0.1.0/pyproject.toml +137 -0
  18. easy_sandbox-0.1.0/src/easy_sandbox/__init__.py +42 -0
  19. easy_sandbox-0.1.0/src/easy_sandbox/_version.py +1 -0
  20. easy_sandbox-0.1.0/src/easy_sandbox/agent/__init__.py +22 -0
  21. easy_sandbox-0.1.0/src/easy_sandbox/agent/builtin.py +207 -0
  22. easy_sandbox-0.1.0/src/easy_sandbox/agent/clarify.py +531 -0
  23. easy_sandbox-0.1.0/src/easy_sandbox/agent/codegen.py +283 -0
  24. easy_sandbox-0.1.0/src/easy_sandbox/agent/coding_agent.py +383 -0
  25. easy_sandbox-0.1.0/src/easy_sandbox/agent/infer.py +435 -0
  26. easy_sandbox-0.1.0/src/easy_sandbox/agent/mcp.py +438 -0
  27. easy_sandbox-0.1.0/src/easy_sandbox/agent/mcp_http.py +503 -0
  28. easy_sandbox-0.1.0/src/easy_sandbox/agent/qwen_code.py +868 -0
  29. easy_sandbox-0.1.0/src/easy_sandbox/agent/tools.py +332 -0
  30. easy_sandbox-0.1.0/src/easy_sandbox/api/__init__.py +35 -0
  31. easy_sandbox-0.1.0/src/easy_sandbox/api/capability.py +231 -0
  32. easy_sandbox-0.1.0/src/easy_sandbox/api/code.py +404 -0
  33. easy_sandbox-0.1.0/src/easy_sandbox/api/commands.py +329 -0
  34. easy_sandbox-0.1.0/src/easy_sandbox/api/deploy.py +378 -0
  35. easy_sandbox-0.1.0/src/easy_sandbox/api/docker_builder.py +1066 -0
  36. easy_sandbox-0.1.0/src/easy_sandbox/api/fc_template.py +878 -0
  37. easy_sandbox-0.1.0/src/easy_sandbox/api/files.py +281 -0
  38. easy_sandbox-0.1.0/src/easy_sandbox/api/image.py +243 -0
  39. easy_sandbox-0.1.0/src/easy_sandbox/api/network.py +61 -0
  40. easy_sandbox-0.1.0/src/easy_sandbox/api/sandbox.py +1177 -0
  41. easy_sandbox-0.1.0/src/easy_sandbox/api/session_manager.py +161 -0
  42. easy_sandbox-0.1.0/src/easy_sandbox/api/template.py +246 -0
  43. easy_sandbox-0.1.0/src/easy_sandbox/cli/__init__.py +1 -0
  44. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/__init__.py +1 -0
  45. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/config_cmd.py +850 -0
  46. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/deploy.py +218 -0
  47. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/mcp.py +588 -0
  48. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/sandbox.py +1486 -0
  49. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/sandbox_files.py +338 -0
  50. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/sandbox_process.py +271 -0
  51. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/sandbox_system.py +543 -0
  52. easy_sandbox-0.1.0/src/easy_sandbox/cli/commands/template.py +2396 -0
  53. easy_sandbox-0.1.0/src/easy_sandbox/cli/formatters.py +160 -0
  54. easy_sandbox-0.1.0/src/easy_sandbox/cli/main.py +470 -0
  55. easy_sandbox-0.1.0/src/easy_sandbox/cli/output.py +556 -0
  56. easy_sandbox-0.1.0/src/easy_sandbox/cli/region.py +60 -0
  57. easy_sandbox-0.1.0/src/easy_sandbox/cli/repl.py +384 -0
  58. easy_sandbox-0.1.0/src/easy_sandbox/cli/scaffold.py +294 -0
  59. easy_sandbox-0.1.0/src/easy_sandbox/compat/__init__.py +7 -0
  60. easy_sandbox-0.1.0/src/easy_sandbox/compat/sandbox.py +55 -0
  61. easy_sandbox-0.1.0/src/easy_sandbox/declarative/__init__.py +12 -0
  62. easy_sandbox-0.1.0/src/easy_sandbox/declarative/config.py +68 -0
  63. easy_sandbox-0.1.0/src/easy_sandbox/declarative/decorator.py +646 -0
  64. easy_sandbox-0.1.0/src/easy_sandbox/declarative/serializer.py +39 -0
  65. easy_sandbox-0.1.0/src/easy_sandbox/extensions/__init__.py +14 -0
  66. easy_sandbox-0.1.0/src/easy_sandbox/extensions/domain.py +19 -0
  67. easy_sandbox-0.1.0/src/easy_sandbox/extensions/oss.py +20 -0
  68. easy_sandbox-0.1.0/src/easy_sandbox/extensions/vpc.py +19 -0
  69. easy_sandbox-0.1.0/src/easy_sandbox/models/__init__.py +122 -0
  70. easy_sandbox-0.1.0/src/easy_sandbox/models/config.py +42 -0
  71. easy_sandbox-0.1.0/src/easy_sandbox/models/errors.py +540 -0
  72. easy_sandbox-0.1.0/src/easy_sandbox/models/filesystem.py +43 -0
  73. easy_sandbox-0.1.0/src/easy_sandbox/models/process.py +99 -0
  74. easy_sandbox-0.1.0/src/easy_sandbox/models/sandbox.py +102 -0
  75. easy_sandbox-0.1.0/src/easy_sandbox/models/session.py +41 -0
  76. easy_sandbox-0.1.0/src/easy_sandbox/models/template.py +213 -0
  77. easy_sandbox-0.1.0/src/easy_sandbox/protocol/__init__.py +21 -0
  78. easy_sandbox-0.1.0/src/easy_sandbox/protocol/code_interpreter.py +210 -0
  79. easy_sandbox-0.1.0/src/easy_sandbox/protocol/filesystem.py +346 -0
  80. easy_sandbox-0.1.0/src/easy_sandbox/protocol/port.py +59 -0
  81. easy_sandbox-0.1.0/src/easy_sandbox/protocol/process.py +288 -0
  82. easy_sandbox-0.1.0/src/easy_sandbox/protocol/sandbox.py +206 -0
  83. easy_sandbox-0.1.0/src/easy_sandbox/protocol/template.py +359 -0
  84. easy_sandbox-0.1.0/src/easy_sandbox/protocol/terminal.py +120 -0
  85. easy_sandbox-0.1.0/src/easy_sandbox/py.typed +0 -0
  86. easy_sandbox-0.1.0/src/easy_sandbox/server/__init__.py +60 -0
  87. easy_sandbox-0.1.0/src/easy_sandbox/server/_compat.py +125 -0
  88. easy_sandbox-0.1.0/src/easy_sandbox/server/app.py +374 -0
  89. easy_sandbox-0.1.0/src/easy_sandbox/server/registry.py +318 -0
  90. easy_sandbox-0.1.0/src/easy_sandbox/server/router.py +277 -0
  91. easy_sandbox-0.1.0/src/easy_sandbox/server/routes.py +430 -0
  92. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_browser.py +548 -0
  93. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_devtools.py +451 -0
  94. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_files.py +606 -0
  95. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_process.py +338 -0
  96. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_pty.py +668 -0
  97. easy_sandbox-0.1.0/src/easy_sandbox/server/routes_system.py +502 -0
  98. easy_sandbox-0.1.0/src/easy_sandbox/server/types.py +107 -0
  99. easy_sandbox-0.1.0/src/easy_sandbox/session/__init__.py +6 -0
  100. easy_sandbox-0.1.0/src/easy_sandbox/session/local.py +91 -0
  101. easy_sandbox-0.1.0/src/easy_sandbox/transport/__init__.py +7 -0
  102. easy_sandbox-0.1.0/src/easy_sandbox/transport/auth.py +429 -0
  103. easy_sandbox-0.1.0/src/easy_sandbox/transport/codec.py +231 -0
  104. easy_sandbox-0.1.0/src/easy_sandbox/transport/config.py +281 -0
  105. easy_sandbox-0.1.0/src/easy_sandbox/transport/http.py +430 -0
  106. easy_sandbox-0.1.0/src/easy_sandbox/transport/streaming.py +99 -0
  107. easy_sandbox-0.1.0/src/easy_sandbox/transport/ws.py +156 -0
  108. easy_sandbox-0.1.0/src/easy_sandbox/utils/__init__.py +8 -0
  109. easy_sandbox-0.1.0/src/easy_sandbox/utils/async_bridge.py +85 -0
  110. easy_sandbox-0.1.0/src/easy_sandbox/utils/coerce.py +151 -0
  111. easy_sandbox-0.1.0/src/easy_sandbox/utils/github_token.py +97 -0
  112. easy_sandbox-0.1.0/src/easy_sandbox/utils/keychain.py +131 -0
  113. easy_sandbox-0.1.0/src/easy_sandbox/utils/logging.py +52 -0
  114. easy_sandbox-0.1.0/src/easy_sandbox/utils/registry.py +407 -0
  115. easy_sandbox-0.1.0/src/easy_sandbox/utils/retry.py +84 -0
  116. easy_sandbox-0.1.0/src/easy_sandbox/utils/template_index.py +550 -0
  117. easy_sandbox-0.1.0/tests/__init__.py +0 -0
  118. easy_sandbox-0.1.0/tests/conftest.py +82 -0
  119. easy_sandbox-0.1.0/tests/integration/__init__.py +0 -0
  120. easy_sandbox-0.1.0/tests/integration/test_cli_e2e.py +332 -0
  121. easy_sandbox-0.1.0/tests/integration/test_client_run_command_e2e.py +264 -0
  122. easy_sandbox-0.1.0/tests/integration/test_declarative_register_e2e.py +269 -0
  123. easy_sandbox-0.1.0/tests/integration/test_e2e.py +566 -0
  124. easy_sandbox-0.1.0/tests/integration/test_server_e2e.py +464 -0
  125. easy_sandbox-0.1.0/tests/integration/test_workflow_e2e.py +409 -0
  126. easy_sandbox-0.1.0/tests/test_agent/__init__.py +1 -0
  127. easy_sandbox-0.1.0/tests/test_agent/test_builtin.py +126 -0
  128. easy_sandbox-0.1.0/tests/test_agent/test_clarify.py +424 -0
  129. easy_sandbox-0.1.0/tests/test_agent/test_codegen.py +305 -0
  130. easy_sandbox-0.1.0/tests/test_agent/test_coding_agent.py +312 -0
  131. easy_sandbox-0.1.0/tests/test_agent/test_infer.py +404 -0
  132. easy_sandbox-0.1.0/tests/test_agent/test_mcp.py +376 -0
  133. easy_sandbox-0.1.0/tests/test_agent/test_mcp_http.py +639 -0
  134. easy_sandbox-0.1.0/tests/test_agent/test_qwen_code.py +775 -0
  135. easy_sandbox-0.1.0/tests/test_agent/test_tools.py +276 -0
  136. easy_sandbox-0.1.0/tests/test_agent_guide.py +196 -0
  137. easy_sandbox-0.1.0/tests/test_api/__init__.py +0 -0
  138. easy_sandbox-0.1.0/tests/test_api/conftest.py +294 -0
  139. easy_sandbox-0.1.0/tests/test_api/test_capability.py +760 -0
  140. easy_sandbox-0.1.0/tests/test_api/test_code.py +1164 -0
  141. easy_sandbox-0.1.0/tests/test_api/test_commands.py +433 -0
  142. easy_sandbox-0.1.0/tests/test_api/test_deploy.py +456 -0
  143. easy_sandbox-0.1.0/tests/test_api/test_docker_builder.py +583 -0
  144. easy_sandbox-0.1.0/tests/test_api/test_fc_template.py +625 -0
  145. easy_sandbox-0.1.0/tests/test_api/test_files.py +262 -0
  146. easy_sandbox-0.1.0/tests/test_api/test_image.py +164 -0
  147. easy_sandbox-0.1.0/tests/test_api/test_network.py +95 -0
  148. easy_sandbox-0.1.0/tests/test_api/test_sandbox.py +932 -0
  149. easy_sandbox-0.1.0/tests/test_api/test_template.py +138 -0
  150. easy_sandbox-0.1.0/tests/test_byo_agent_docs.py +300 -0
  151. easy_sandbox-0.1.0/tests/test_cli/__init__.py +0 -0
  152. easy_sandbox-0.1.0/tests/test_cli/conftest.py +26 -0
  153. easy_sandbox-0.1.0/tests/test_cli/test_config_commands.py +952 -0
  154. easy_sandbox-0.1.0/tests/test_cli/test_config_init.py +217 -0
  155. easy_sandbox-0.1.0/tests/test_cli/test_config_llm.py +171 -0
  156. easy_sandbox-0.1.0/tests/test_cli/test_config_masked_input.py +299 -0
  157. easy_sandbox-0.1.0/tests/test_cli/test_connect_repl.py +445 -0
  158. easy_sandbox-0.1.0/tests/test_cli/test_create_backend.py +474 -0
  159. easy_sandbox-0.1.0/tests/test_cli/test_create_nl.py +1288 -0
  160. easy_sandbox-0.1.0/tests/test_cli/test_create_route_guard_and_unknown_cmd.py +113 -0
  161. easy_sandbox-0.1.0/tests/test_cli/test_deploy_commands.py +217 -0
  162. easy_sandbox-0.1.0/tests/test_cli/test_discover_commands.py +180 -0
  163. easy_sandbox-0.1.0/tests/test_cli/test_formatters.py +204 -0
  164. easy_sandbox-0.1.0/tests/test_cli/test_help_alias.py +197 -0
  165. easy_sandbox-0.1.0/tests/test_cli/test_main.py +201 -0
  166. easy_sandbox-0.1.0/tests/test_cli/test_mcp_commands.py +518 -0
  167. easy_sandbox-0.1.0/tests/test_cli/test_output_channels.py +484 -0
  168. easy_sandbox-0.1.0/tests/test_cli/test_region_options.py +409 -0
  169. easy_sandbox-0.1.0/tests/test_cli/test_run_command.py +112 -0
  170. easy_sandbox-0.1.0/tests/test_cli/test_run_command_server.py +171 -0
  171. easy_sandbox-0.1.0/tests/test_cli/test_sandbox_commands.py +645 -0
  172. easy_sandbox-0.1.0/tests/test_cli/test_sandbox_files_commands.py +486 -0
  173. easy_sandbox-0.1.0/tests/test_cli/test_sandbox_process_commands.py +303 -0
  174. easy_sandbox-0.1.0/tests/test_cli/test_sandbox_system_extra_commands.py +418 -0
  175. easy_sandbox-0.1.0/tests/test_cli/test_template_commands.py +2027 -0
  176. easy_sandbox-0.1.0/tests/test_cli/test_template_github_token_setup.py +347 -0
  177. easy_sandbox-0.1.0/tests/test_cli/test_template_index_commands.py +344 -0
  178. easy_sandbox-0.1.0/tests/test_cli_evidence/__init__.py +0 -0
  179. easy_sandbox-0.1.0/tests/test_cli_evidence/conftest.py +49 -0
  180. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-apikey-env.txt +2 -0
  181. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-apikey-set.txt +2 -0
  182. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-apikey-unset.txt +2 -0
  183. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-github-token-set.txt +2 -0
  184. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-github-token-unset.txt +2 -0
  185. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-llm-model-unset.txt +2 -0
  186. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-qwen-model.txt +2 -0
  187. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-region.txt +2 -0
  188. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-get-unknown.txt +4 -0
  189. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-init.txt +15 -0
  190. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-list-json.txt +19 -0
  191. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-list.txt +17 -0
  192. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-empty-credential.txt +2 -0
  193. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-empty-default.txt +2 -0
  194. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-empty-env.txt +2 -0
  195. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-github-token-clear.txt +2 -0
  196. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-github-token-missing-value.txt +4 -0
  197. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-github-token.txt +2 -0
  198. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-llm-apikey.txt +2 -0
  199. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/config-set-region.txt +2 -0
  200. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/connect-repl.txt +9 -0
  201. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-env-invalid.txt +3 -0
  202. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-env.txt +6 -0
  203. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-metadata.txt +6 -0
  204. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-clarify-required.txt +5 -0
  205. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-confirm-required.txt +9 -0
  206. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-conflict.txt +3 -0
  207. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-nodejs.txt +13 -0
  208. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-not-installed.txt +12 -0
  209. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-nl-python.txt +13 -0
  210. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-template-base-json.txt +7 -0
  211. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/create-template-base.txt +6 -0
  212. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/download-file.txt +2 -0
  213. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-auth.txt +3 -0
  214. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-create-noargs.txt +7 -0
  215. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-quota.txt +4 -0
  216. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-template-not-found.txt +4 -0
  217. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-timeout.txt +4 -0
  218. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-unknown-custom-hint.txt +6 -0
  219. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/error-unknown-suggestion.txt +6 -0
  220. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/exec-basic.txt +2 -0
  221. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/exec-json.txt +7 -0
  222. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/exec-nonzero.txt +3 -0
  223. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/exec-timeout-cwd.txt +3 -0
  224. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-config-get.txt +44 -0
  225. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-config-init.txt +28 -0
  226. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-config-list.txt +21 -0
  227. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-config-set.txt +63 -0
  228. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-config.txt +30 -0
  229. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-connect.txt +27 -0
  230. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-create.txt +63 -0
  231. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-download.txt +18 -0
  232. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-ebx.txt +53 -0
  233. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-exec.txt +24 -0
  234. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-info.txt +16 -0
  235. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-init-alias.txt +32 -0
  236. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-install.txt +51 -0
  237. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-kill.txt +25 -0
  238. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-list.txt +25 -0
  239. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-mcp-deploy.txt +49 -0
  240. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-mcp-install.txt +22 -0
  241. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-mcp-start.txt +25 -0
  242. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-mcp-status.txt +16 -0
  243. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-mcp.txt +26 -0
  244. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-run.txt +29 -0
  245. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-build.txt +86 -0
  246. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-cache.txt +12 -0
  247. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-delete.txt +22 -0
  248. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-info.txt +25 -0
  249. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-init.txt +32 -0
  250. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-install.txt +59 -0
  251. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template-list.txt +26 -0
  252. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-template.txt +29 -0
  253. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/help-upload.txt +18 -0
  254. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/info-json.txt +9 -0
  255. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/info.txt +7 -0
  256. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/kill-all.txt +2 -0
  257. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/kill-no-id.txt +4 -0
  258. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/kill-single.txt +2 -0
  259. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/list-empty.txt +2 -0
  260. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/list-json.txt +15 -0
  261. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/list-running.txt +6 -0
  262. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/list.txt +7 -0
  263. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/mcp-install-cursor.txt +13 -0
  264. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/mcp-status-json.txt +19 -0
  265. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/mcp-status.txt +9 -0
  266. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/run-default-arg.txt +3 -0
  267. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/run-dispatch-json.txt +7 -0
  268. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/run-dispatch.txt +3 -0
  269. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/run-invalid-arg.txt +3 -0
  270. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/run-unknown-command.txt +4 -0
  271. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-cache-clear.txt +2 -0
  272. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-cache.txt +2 -0
  273. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-info-backend.txt +5 -0
  274. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-install-builtin.txt +3 -0
  275. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-install-rate-limit.txt +5 -0
  276. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-list-backend.txt +7 -0
  277. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/template-search-rate-limit.txt +4 -0
  278. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/upload-dir.txt +2 -0
  279. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/upload-file.txt +2 -0
  280. easy_sandbox-0.1.0/tests/test_cli_evidence/golden/version.txt +2 -0
  281. easy_sandbox-0.1.0/tests/test_cli_evidence/test_evidence_snapshots.py +107 -0
  282. easy_sandbox-0.1.0/tests/test_compat/__init__.py +1 -0
  283. easy_sandbox-0.1.0/tests/test_compat/test_compat_imports.py +45 -0
  284. easy_sandbox-0.1.0/tests/test_declarative/__init__.py +0 -0
  285. easy_sandbox-0.1.0/tests/test_declarative/test_config.py +157 -0
  286. easy_sandbox-0.1.0/tests/test_declarative/test_decorator.py +395 -0
  287. easy_sandbox-0.1.0/tests/test_declarative/test_register.py +604 -0
  288. easy_sandbox-0.1.0/tests/test_declarative/test_serializer.py +73 -0
  289. easy_sandbox-0.1.0/tests/test_extensions/__init__.py +0 -0
  290. easy_sandbox-0.1.0/tests/test_extensions/test_vpc.py +84 -0
  291. easy_sandbox-0.1.0/tests/test_models/__init__.py +0 -0
  292. easy_sandbox-0.1.0/tests/test_models/test_config.py +61 -0
  293. easy_sandbox-0.1.0/tests/test_models/test_errors.py +318 -0
  294. easy_sandbox-0.1.0/tests/test_models/test_filesystem.py +81 -0
  295. easy_sandbox-0.1.0/tests/test_models/test_process.py +109 -0
  296. easy_sandbox-0.1.0/tests/test_models/test_sandbox.py +170 -0
  297. easy_sandbox-0.1.0/tests/test_models/test_session.py +63 -0
  298. easy_sandbox-0.1.0/tests/test_models/test_template.py +142 -0
  299. easy_sandbox-0.1.0/tests/test_packaging.py +141 -0
  300. easy_sandbox-0.1.0/tests/test_protocol/__init__.py +0 -0
  301. easy_sandbox-0.1.0/tests/test_protocol/test_code_interpreter.py +221 -0
  302. easy_sandbox-0.1.0/tests/test_protocol/test_filesystem.py +486 -0
  303. easy_sandbox-0.1.0/tests/test_protocol/test_port.py +61 -0
  304. easy_sandbox-0.1.0/tests/test_protocol/test_process.py +344 -0
  305. easy_sandbox-0.1.0/tests/test_protocol/test_sandbox.py +345 -0
  306. easy_sandbox-0.1.0/tests/test_protocol/test_template.py +245 -0
  307. easy_sandbox-0.1.0/tests/test_protocol/test_terminal.py +145 -0
  308. easy_sandbox-0.1.0/tests/test_server/__init__.py +1 -0
  309. easy_sandbox-0.1.0/tests/test_server/test_app.py +654 -0
  310. easy_sandbox-0.1.0/tests/test_server/test_env_subprocess_boundary.py +308 -0
  311. easy_sandbox-0.1.0/tests/test_server/test_registry.py +318 -0
  312. easy_sandbox-0.1.0/tests/test_server/test_router.py +236 -0
  313. easy_sandbox-0.1.0/tests/test_server/test_routes_browser.py +536 -0
  314. easy_sandbox-0.1.0/tests/test_server/test_routes_devtools.py +427 -0
  315. easy_sandbox-0.1.0/tests/test_server/test_routes_files.py +669 -0
  316. easy_sandbox-0.1.0/tests/test_server/test_routes_process.py +537 -0
  317. easy_sandbox-0.1.0/tests/test_server/test_routes_pty.py +494 -0
  318. easy_sandbox-0.1.0/tests/test_server/test_routes_system.py +380 -0
  319. easy_sandbox-0.1.0/tests/test_session/__init__.py +0 -0
  320. easy_sandbox-0.1.0/tests/test_session/test_local_store.py +129 -0
  321. easy_sandbox-0.1.0/tests/test_session/test_session_manager.py +208 -0
  322. easy_sandbox-0.1.0/tests/test_skill_installation_docs.py +203 -0
  323. easy_sandbox-0.1.0/tests/test_templates/__init__.py +11 -0
  324. easy_sandbox-0.1.0/tests/test_templates/conftest.py +120 -0
  325. easy_sandbox-0.1.0/tests/test_templates/test_local_install.py +693 -0
  326. easy_sandbox-0.1.0/tests/test_templates/test_template_catalog.py +378 -0
  327. easy_sandbox-0.1.0/tests/test_templates/test_template_e2e.py +255 -0
  328. easy_sandbox-0.1.0/tests/test_transport/__init__.py +0 -0
  329. easy_sandbox-0.1.0/tests/test_transport/conftest.py +62 -0
  330. easy_sandbox-0.1.0/tests/test_transport/test_auth.py +453 -0
  331. easy_sandbox-0.1.0/tests/test_transport/test_codec.py +271 -0
  332. easy_sandbox-0.1.0/tests/test_transport/test_config.py +318 -0
  333. easy_sandbox-0.1.0/tests/test_transport/test_http.py +1072 -0
  334. easy_sandbox-0.1.0/tests/test_transport/test_streaming.py +127 -0
  335. easy_sandbox-0.1.0/tests/test_transport/test_ws.py +47 -0
  336. easy_sandbox-0.1.0/tests/test_utils/__init__.py +0 -0
  337. easy_sandbox-0.1.0/tests/test_utils/test_async_bridge.py +64 -0
  338. easy_sandbox-0.1.0/tests/test_utils/test_coerce.py +169 -0
  339. easy_sandbox-0.1.0/tests/test_utils/test_github_token.py +76 -0
  340. easy_sandbox-0.1.0/tests/test_utils/test_keychain.py +78 -0
  341. easy_sandbox-0.1.0/tests/test_utils/test_logging.py +46 -0
  342. easy_sandbox-0.1.0/tests/test_utils/test_registry.py +909 -0
  343. easy_sandbox-0.1.0/tests/test_utils/test_retry.py +110 -0
  344. easy_sandbox-0.1.0/tests/test_utils/test_template_index.py +438 -0
@@ -0,0 +1,95 @@
1
+ # Module Specifications & Architecture Decisions
2
+
3
+ This directory contains Architecture Decision Records (ADRs) and module specifications
4
+ following a structured review process.
5
+
6
+ ## Directory Structure
7
+
8
+ ```
9
+ notes/
10
+ ├── proposed/ # Under review
11
+ │ ├── architecture/ # System-wide architecture decisions
12
+ │ ├── feature/ # Feature module specifications
13
+ │ └── process/ # Engineering process decisions
14
+ ├── implemented/ # Accepted and implemented
15
+ │ ├── architecture/
16
+ │ ├── feature/
17
+ │ └── process/
18
+ └── rejected/ # Considered but rejected
19
+ ```
20
+
21
+ ## Lifecycle
22
+
23
+ 1. **Proposed** → Create in `proposed/<category>/`
24
+ 2. **Implemented** → Move to `implemented/<category>/`, update Status field
25
+ 3. **Rejected** → Move to `rejected/`, document reasoning
26
+
27
+ The `Status:` field value **must** match the state directory the file lives in
28
+ (`proposed` / `implemented` / `rejected`). When work is completed, move the file
29
+ and update the field together.
30
+
31
+ ## Language
32
+
33
+ All ADRs **must** be written in English. This keeps the `.agents/` engineering
34
+ record internally consistent and reviewable by all contributors and tooling.
35
+ (Go-forward convention: every document under `.agents/notes/` is English. Existing
36
+ snapshots under `.agents/evidence/` are historical artifacts and are left as-is.)
37
+
38
+ ## Naming & Location
39
+
40
+ - **File name:** `YYYY-MM-DD-<topic-slug>.md` — ISO date of the decision plus a
41
+ lowercase, hyphenated topic slug (e.g. `2026-09-09-layer-violation-fix.md`).
42
+ - **Location:** `<state>/<category>/` where `<state>` is `proposed`,
43
+ `implemented`, or `rejected`, and `<category>` is one of:
44
+ - `architecture/` — system-wide architecture decisions
45
+ - `feature/` — feature module specifications
46
+ - `process/` — engineering process decisions
47
+ - **Exception:** `rejected/` is a **flat** directory (no category subfolders).
48
+
49
+ ## Template
50
+
51
+ Each ADR file follows this format. The title line is always `# Decision: <Title>`,
52
+ immediately followed by the `Status:` line.
53
+
54
+ ### Required sections
55
+
56
+ Every ADR must contain all seven sections below, in this order:
57
+
58
+ ```markdown
59
+ # Decision: <Title>
60
+
61
+ Status: proposed | implemented | rejected
62
+
63
+ ## Problem
64
+ <Motivation, independent of solution>
65
+
66
+ ## Decision
67
+ <Technical approach, interfaces, file paths>
68
+
69
+ ## API Design
70
+ <Core class/function signatures, input/output types.
71
+ For decisions that do not involve APIs, state:
72
+ "N/A — this decision does not involve API changes.">
73
+
74
+ ## Alternatives considered
75
+ - **<Option A>** — <Why rejected>
76
+
77
+ ## Dependencies
78
+ <Required modules/packages>
79
+
80
+ ## Test Strategy
81
+ <Testing approach and coverage>
82
+
83
+ ## Acceptance criteria
84
+ <Measurable acceptance conditions>
85
+ ```
86
+
87
+ ### Optional sections
88
+
89
+ The following sections **may** appear after the required sections when useful.
90
+ They are registered as recognised optional sections and are not mandatory:
91
+
92
+ - `## Consequences` — trade-offs and follow-on effects of the decision
93
+ - `## Implementation` — implementation notes, phases, or status detail
94
+ - `## Evidence` — links to tests, PRs, or captured verification artifacts
95
+ - `## Files changed` — the concrete files touched by the decision
@@ -0,0 +1,76 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ *.egg
9
+ .eggs/
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # IDE
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+
22
+ # Testing
23
+ .pytest_cache/
24
+ .coverage
25
+ coverage.json
26
+ htmlcov/
27
+ .tox/
28
+
29
+ # Linting / Type-checking caches
30
+ .mypy_cache/
31
+ .ruff_cache/
32
+
33
+ # Environment
34
+ .env
35
+ .env.*
36
+ !.env.example
37
+
38
+ # Secrets
39
+ *.pem
40
+ *.key
41
+ secrets.json
42
+ # NOTE: .secrets.baseline is intentionally tracked — it is referenced by the
43
+ # detect-secrets hook in .pre-commit-config.yaml and must ship with the repo.
44
+ # Do not add it back to .gitignore.
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Build
51
+ *.so
52
+ *.dylib
53
+ *.whl
54
+
55
+ # Temporary diff/patch files
56
+ *.diff
57
+ current_diff.patch
58
+ diff-code.txt
59
+
60
+ # Local scratch/verification workspaces
61
+ .scratch-*/
62
+
63
+ # Sandbox config (may contain API keys)
64
+ ~/.sbox/
65
+
66
+ # Benchmarks output
67
+ benchmarks/*.log
68
+
69
+ # Process artifacts (evidence snapshots & research notes)
70
+ # NOTE: .agents/notes/ (ADR decisions) is NOT ignored — it stays tracked.
71
+ # NOTE: .agents/design/ is deprecated (historical artifacts tracked, no new content).
72
+ /.agents/evidence/
73
+ /.agents/research/
74
+
75
+ # awesome-templates sub-repo (has its own git)
76
+ awesome-templates/
@@ -0,0 +1,182 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## [Unreleased]
8
+
9
+ _Nothing yet._
10
+
11
+ ## [0.1.0] - 2026-09-29
12
+
13
+ First stable release. Includes all changes below (formerly tracked as `0.1.0-dev`) plus the current cycle:
14
+
15
+ ### Breaking Changes (Task 201 — config Reset Removal & Value Semantics)
16
+
17
+ 1. **Removed `ebx config reset`**.
18
+ Clearing is now per key via `ebx config set KEY ""`: the stored value is removed and the key returns to its business default or to not set. An empty string is never stored as a credential or as an override. When an environment variable still overrides the key at runtime, the command says so explicitly without printing its value.
19
+ *Migration*: replace `ebx config reset --yes` with one `ebx config set KEY ""` per key you want to clear (e.g. `ebx config set region ""`).
20
+
21
+ 2. **`ebx config list` shows effective values and their sources**.
22
+ Sources are annotated as `(env)`, `(user)`, `(default)` or `(not set)`. Keys with a real business default (`qwen_code_base_url`, `qwen_code_model`) show the concrete default; keys without one (`llm_api_key`, `llm_base_url`, `llm_model`) show `(not set)` instead of a blank `(default)`. Secrets stay masked.
23
+ *Migration*: consumers parsing `config list` output now see source suffixes and `(not set)` where the old output showed blank defaults.
24
+
25
+ 3. **`ebx config init` secret prompts echo one `*` per character**.
26
+ Previously typed secrets were completely invisible; now every typed or pasted character shows a single `*` (never the plaintext), with Backspace / Ctrl-C / EOF / Unicode handled correctly. Terminals that cannot render it fall back to the previous no-echo behaviour with an explicit notice.
27
+ *Migration*: no action required — the plaintext is never displayed in either mode.
28
+
29
+ ### Breaking Changes (ADR 2026-09-23 — Overdesign Cleanup)
30
+
31
+ 1. **`ebx template install` default behaviour changed: download → download+build+deploy**.
32
+ `install` now fetches the template sources and then builds the Docker image, pushes to ACR, and registers the template via the official API by default — cloud-side operations that can incur Alibaba Cloud costs (ACR storage/traffic, template resources). The previous download-only behaviour is available via `--download-only`.
33
+ *Migration*: add `--download-only` to `ebx template install` / `ebx install` invocations that should not build and deploy.
34
+
35
+ 2. **Removed `SerializerType.PICKLE` / `SerializerType.MSGPACK`**.
36
+ The `@sandbox` decorator now only supports `serializer="json"`. Non-JSON serializable return values must be converted to `dict`/`list`/`str` before returning.
37
+ *Migration*: change `@sandbox(serializer="pickle")` → `@sandbox(serializer="json")` and ensure return values are JSON-compatible.
38
+
39
+ 3. **Removed runtime `check_capability()` gate from most modules**.
40
+ `CommandsModule`, `FilesModule`, and `NetworkModule` no longer raise `CapabilityNotSupportedError` (E3004) at call time. **Exception: `CodeContextModule` retains the `code` capability gate** — all its methods (`run`, `create_context`, `list_contexts`, `restart_context`, `remove_context`) still raise E3004 when the `code` capability is missing (fail-closed). E3004 is also still raised during template resolution / model validation via `resolve_capabilities()`.
41
+ *Migration*: remove `try/except CapabilityNotSupportedError` around `commands.*`, `files.*`, and `network.*` calls; declare required capabilities in `template.yaml` instead. **Keep** `try/except CapabilityNotSupportedError` around `run_code()` / `code.*` calls if your template may lack the `code` capability.
42
+
43
+ 4. **Removed `easy_sandbox.integrations` sub-module**.
44
+ The LangChain/CrewAI/AutoGen adapter module was an empty abstract placeholder and has been deleted.
45
+ *Migration*: use `agent.tools` or MCP integration directly.
46
+
47
+ 5. **Removed `SessionStore` abstract base class**.
48
+ Only `LocalSessionStore` remains. The `session/base.py` ABC has been deleted.
49
+ *Migration*: if you were subclassing `SessionStore`, switch to `LocalSessionStore` or implement your own storage directly.
50
+
51
+ 6. **`SecretStore` changed from macOS Keychain to file-based storage**.
52
+ Secrets are now stored in `~/.ebx/secrets.json` (plaintext, chmod 600). Old Keychain entries are **not** automatically migrated.
53
+ *Migration*: re-add secrets via environment variables (`E2B_API_KEY`, `SANDBOX_API_KEY`) or `~/.ebx/.env` file. Use `ebx config set api_key <value>` to persist API keys.
54
+
55
+ 7. **Removed `ebx auth` CLI command group**.
56
+ The `ebx auth login/logout/status/switch` commands have been removed.
57
+ *Migration*: use `ebx config set api_key <value>` to persist credentials, or set `E2B_API_KEY` / `SANDBOX_API_KEY` environment variables directly.
58
+
59
+ 8. **Removed `ebx secret` CLI command group**.
60
+ The `ebx secret create/list/delete/inject` commands have been removed.
61
+ *Migration*: use environment variables or `.env` files to manage credentials and secrets. For sandbox environment injection, use `ebx create --env KEY=VALUE`.
62
+
63
+ 9. **Removed `ebx session` / `ebx sessions` CLI command group**.
64
+ The `ebx sessions list/info/rename/export/import/clean` and `ebx start/connect` commands have been removed.
65
+ *Migration*: session data is still stored locally in `~/.ebx/sessions/` by `LocalSessionStore`. Use the SDK's `Sandbox.connect()` API programmatically.
66
+
67
+ 10. **Removed `ebx skill` CLI command group**.
68
+ The `ebx skill search/install/list/create/publish` commands have been removed.
69
+ *Migration*: Skills system is a future planned feature. Use templates as the current capability distribution mechanism.
70
+
71
+ 11. **`Sandbox.run()` is now a bare-shell shortcut** (was named-command dispatcher).
72
+ `Sandbox.run(cmd)` now delegates to `sandbox.commands.run(cmd)` and returns `ProcessResult | StreamReader`. It no longer dispatches named custom commands.
73
+ *Migration*: replace `sandbox.run("name", **kwargs)` with `sandbox.custom("name", **kwargs)`.
74
+
75
+ ### Breaking Changes (ADR 2026-09-29 — init/create Semantics, partially superseded)
76
+
77
+ > **Update (2026-09-29, ADR `2026-09-29-init-restore-and-create-explicit-error`):** item 1 below is **superseded** — the top-level `ebx init` shortcut has been **restored** as an exact alias of `ebx template init` (same click command object, option surface unchanged). Items 2–3 stand, and item 3 replaces the earlier "`ebx create` (no arguments) uses the `base` template" routing.
78
+
79
+ 1. ~~**Removed the top-level `ebx init` shortcut**.~~ **Superseded: restored.** The top-level `ebx init` shortcut is back and delegates to the exact same command object as `ebx template init` (options unchanged). Guided credentials setup remains `ebx config init`; cloud sandbox creation remains `ebx create`.
80
+ *Migration*: `ebx init [DIRECTORY]` and `ebx template init [DIRECTORY]` are interchangeable again.
81
+
82
+ 2. **`ebx create "DESCRIPTION" --template NAME` is now rejected**.
83
+ Previously `--template` silently won and the description was ignored. Passing both now raises a usage error (exit code 1) before any AI generation or network call — neither input is silently dropped.
84
+ *Migration*: keep DESCRIPTION for the Qwen Code AI path, or `--template` for a direct launch, but not both.
85
+
86
+ 3. **`ebx create` with no arguments is now an explicit usage error** (exit code 2).
87
+ Previously bare `ebx create` silently launched the `base` template. It now prints a routing hint (`--template base`, `--template <NAME>`, or `"DESCRIPTION"` for the AI path) so the choice is always explicit.
88
+ *Migration*: use `ebx create --template base` to launch the base template.
89
+
90
+ ### Changed (CLI UX)
91
+
92
+ - **Unknown top-level commands now get targeted hints.** A close spelling candidate (e.g. `ebx crate`) gets a `Did you mean 'create'?` suggestion; with no plausible candidate the error points to template `custom_commands` (declared in `template.yaml`) and running them via `ebx run COMMAND`. Exit code 2 and stderr-only output are preserved; only the root group is affected.
93
+ - **Top-level shortcut registration is explicit.** Built-in top-level shortcuts (`create`, `list`, `init`, `install`, `deploy`, `run`, …) are registered in the `LazyGroup(lazy_subcommands=...)` map in `src/easy_sandbox/cli/main.py` — a maintainer-facing registration point, not a user-facing extension mechanism. User-defined commands stay in `template.yaml` `custom_commands` (or the SandboxServer `@registry.command` registry) and are invoked through `ebx run`. The `config.toml [shortcuts]` section from the original CLI design draft was **never implemented** and is not a current capability.
94
+
95
+ ### Breaking Changes (ADR 2026-09-29 — qwen-code Session-Turns Parameter Unification)
96
+
97
+ 1. **Renamed the qwen-code session-turns parameter to `max_session_turns` / `--max-session-turns` everywhere** (SDK, CLI, qwen-code template `template.yaml`/`commands.py`, docs).
98
+ The old names were misleading: `Sandbox.deploy(max_tool_calls=...)`, `DeployModule.deploy_project(max_tool_calls=...)`, and `ebx deploy --max-tool-calls` all forwarded the value to qwen-code's official `--max-session-turns` flag (user/model/tool turn cap, exit code 53), not to the semantically different upstream `--max-tool-calls` budget (cumulative tool calls, exit code 55). The pre-existing template arg `max_turns` is renamed for the same reason and its default is unified to `100`.
99
+ *Migration*: rename `max_tool_calls=` → `max_session_turns=`, `--max-tool-calls` → `--max-session-turns`, and template arg `max_turns` → `max_session_turns`. Old names fail loudly (CLI usage error / SDK `TypeError`); no aliases are kept, matching the pre-release no-compat-shim policy.
100
+ 2. **`run_qwen_code_headless()` / `_build_headless_command()` accept an optional `max_session_turns` keyword** (`None` by default adds no flag). This is the stable naming contract for the natural-language `ebx create` pipeline and future headless callers.
101
+
102
+ ### Breaking Changes (Task 187 — Template Catalog Single Source of Truth)
103
+
104
+ 1. **The template catalog moved to the dedicated repository [`Easy-Sandbox/awesome-templates`](https://github.com/Easy-Sandbox/awesome-templates)**.
105
+ Template content, the machine-readable index (`awesome-templates.yaml`), releases and CI now live there — it is the single source of truth for official & community templates. This repository no longer bundles the template collection: `examples/templates/` keeps only a minimal `python-hello` **offline fixture**, explicitly marked as a fixture (not a publishing source). The repository-root `awesome-templates.yaml` has been removed.
106
+ *Migration*: instead of deploying a bundled folder (e.g. `ebx template deploy ./examples/templates/node-web`), install from the index (`ebx template install node-web`) or reference the source repo directly (`ebx template install Easy-Sandbox/awesome-templates//node-web@v1.0.0`).
107
+ 2. **`ebx template search` / `ebx template install <bare-name>` now resolve against the remote index** (cached under `~/.ebx/index/`). Bare names that are not builtins are looked up in the index; a miss triggers one forced refresh, and the resolved `owner/repo//subdir[@ref]` is printed (`Resolved '<name>' via the template index: ...`).
108
+ *Migration*: no action needed for direct `owner/repo` references; bare names must exist in the index. Use `--index-url` / `EBX_TEMPLATE_INDEX_URL` for private mirrors.
109
+
110
+ ### Added
111
+ - **Remote template index client (`easy_sandbox.utils.template_index`)**: fetches `awesome-templates.yaml` from the SSOT repository via `raw.githubusercontent.com` (CDN — not subject to the API 60 req/hour anonymous limit), with a `~/.ebx/index/` cache, 1-hour TTL, `If-None-Match` revalidation, and explicit degraded modes (stale-cache fallback with a warning on network failures / rate limits / 5xx; loud errors with remediation when no cache exists; `schema_version` newer than supported fails with an upgrade hint). `--index-url` / `EBX_TEMPLATE_INDEX_URL` and `--token` / `GITHUB_TOKEN` are supported.
112
+ - **`SKILL.md`**: Static Agent Skills–style usage guide at the repository root for AI coding tools and agents in other projects — covers when to use, install, credential safety (including never-leak rules), MCP vs SDK selection, sandbox create/execute/files/destroy workflows, and common error diagnosis. Referenced from `llms.txt`. Documentation only: the removed `ebx skill` command group, Skills registry, and runtime are **not** restored (ADR 2026-09-29). Shipped in the sdist but not the wheel (evidence: `tests/test_packaging.py`; guide/code consistency: `tests/test_agent_guide.py`).
113
+ - **`Sandbox.custom(name, *, server_port=9000, **kwargs) -> CommandResult`**: New method for named custom-command dispatch. Uses A→B resolution: first tries template `custom_commands` (mechanism A), then falls back to `@registry.command` on SandboxServer (mechanism B). Returns `CommandResult` with `value`, `stdout`, `stderr`, `exit_code`, `execution_time`, `source` (`"template"` | `"server"`), and `success` property.
114
+ - **`CommandResult` data model**: Structured return type for `custom()` replacing the bare `Any` that `run_command()` returned.
115
+ - **`ebx template init`**: New scaffold command that generates a complete template project from built-in cases (`python`, `node`, `minimal`) or an existing registry reference (`--from`). Includes interactive case selection on TTY.
116
+ - **`github_token` config key (`ebx config set github_token`)**: persistent GitHub token for template downloads, mapped to the `GITHUB_TOKEN` environment variable and stored in `~/.ebx/.env` (chmod 600). In an interactive terminal the value may be omitted — the token is read through the existing masked (asterisk) input and never echoed; `ebx config get` / `ebx config list` show it masked, and `ebx config set github_token ""` removes it. Resolution order: `--token` > process `GITHUB_TOKEN` > stored `github_token` > no token.
117
+ - **One-shot GitHub rate-limit onboarding (E5000)**: `ebx template search` / `ebx template install` (`ebx install`) now print the officially documented fine-grained PAT prefill URL when the anonymous limit (60/hour) is hit — public repositories need no extra permissions and a 90-day expiry is recommended. In an interactive terminal only, the CLI offers to store the token with masked input and retries the failed operation **exactly once**; declining, cancelling, or a retry that fails again surfaces the original error. CI / non-interactive sessions are told to inject `GITHUB_TOKEN` as a secret or to run `ebx config set github_token` in a terminal. The CLI never runs `gh auth token`, never opens a browser, and never prints or logs a token.
118
+ - **Unified rate-limit guidance (`easy_sandbox.utils.github_token`)**: shared headline + remediation used by the registry tarball client and the template-index client; `owner/repo//subdir@ref` references are preserved verbatim in download errors (e.g. `Easy-Sandbox/awesome-templates//codex-agent-api@v1.0`).
119
+
120
+ ### Deprecated
121
+ - **`Sandbox.run_command()` / `Sandbox.run_command_sync()`**: Deprecated in favour of `Sandbox.custom()` / `Sandbox.custom_sync()`. Both deprecated methods wrap `custom()` internally but only return `result.value` (type `Any`) for backward compatibility — the full `CommandResult` (with `stdout`, `stderr`, `exit_code`, `execution_time`, `source`, `success`) is discarded. If you were treating the old return value as a `ProcessResult`, migrate to `custom()` / `custom_sync()` which return the complete `CommandResult`. Will be removed in a future release.
122
+
123
+ ### Breaking Changes (Official CreateTemplate API convergence)
124
+
125
+ 1. **`ebx template build-local` was removed and replaced by `ebx template build`**.
126
+ The old `build-local` command name no longer exists (invoking it fails with `No such command 'build-local'`). `ebx template build` runs the full pipeline: local Docker build → ACR push → template registration, and `ebx template deploy` remains an alias invoking the same pipeline.
127
+ *Migration*: replace `ebx template build-local <DIR>` with `ebx template build <DIR>` (same option surface).
128
+
129
+ 2. **`ebx template build` / `template deploy` default to the official CreateTemplate API**.
130
+ The legacy v3/v2 platform API is no longer the default; it remains available behind the explicit `--legacy-api` flag (the approved convergence decision — the default switched to the official API while the legacy code path stays behind a flag). The ACR push and the remote template registration are cloud-side operations that can incur Alibaba Cloud costs (ACR storage/traffic, template resources).
131
+ *Migration*: scripts needing the legacy v3/v2 behaviour must pass `--legacy-api` explicitly.
132
+
133
+ ### Changed
134
+ - **`--token` is documented as a temporary override**: `ebx template install` / `ebx template search` help now warns that `--token <value>` may leak into shell history and process listings, and recommends the persistent `ebx config set github_token` as the default fix.
135
+ - `commands.run()`, `commands.stream()`, and `commands.start()` now auto-wrap commands containing unquoted shell operators (`|`, `;`, `&&`, `||`, `>`, `<`, `(...)`, `$(...)`) in `sh -c`. Variable expansion (`$VAR`), backticks, and globs still require explicit `sh -c '...'`.
136
+ - **`ebx template build` (renamed from `build-local`)**: default mode switched to the **official CreateTemplate API** (`--official-api`). Legacy v3/v2 behaviour now requires an explicit `--legacy-api` flag.
137
+ - **Official template path prerequisites**: `ebx template create` and `ebx template build` (default mode) now require the `alicloud` extra (`pip install "easy-sandbox[cli,alicloud]"` or `pip install "easy-sandbox[alicloud]"`) and Alibaba Cloud AK/SK credentials.
138
+ - When `envdInject` is enabled and `--target-image` is omitted, `copy.image` is now auto-derived with a `-fcsandbox-<hex>` random suffix to satisfy the platform requirement that `copy.image` must differ from `sandboxConfig.image`. For a stable tag, pass `--target-image` explicitly.
139
+
140
+ ### Migration
141
+ - Replace `ebx template build-local <DIR>` with `ebx template build <DIR>` — the old command name was removed.
142
+ - Existing automation scripts invoking the build pipeline without `--legacy-api` now hit the official CreateTemplate API. To preserve the legacy v3/v2 behaviour, add `--legacy-api` to the command.
143
+ - **Automation / CI hardening**: pass `--acr-namespace` and the template directory explicitly on the command line instead of relying on `ACR_NAMESPACE` / `EBX_TEMPLATE_DIR` environment variables or `.env` files, so builds cannot silently drift with the surrounding environment. For `ebx template install` / `ebx install`, either pass `--acr-namespace` explicitly or use `--download-only` when the pipeline must not touch the cloud at all.
144
+
145
+
146
+ ### Added
147
+ - **Server Module**: Container-side HTTP server (`easy_sandbox.server`) expanded from 6 to 42 endpoints across 8 capability groups (CORE, COMMANDS, FILE_OPS, PROCESS, SYSTEM, TERMINAL, DEV_TOOLS, BROWSER)
148
+ - **Server CapabilityGroup.BROWSER**: New browser automation capability group with 8 Playwright-backed endpoints (navigate, screenshot, content, click, type, evaluate, pdf, console)
149
+ - **Server PTY Terminal**: WebSocket-based interactive PTY terminal system with session management (REST create/list/delete + WebSocket I/O)
150
+ - **Server SSE Shell**: Streaming shell execution via Server-Sent Events (`POST /shell/stream`) for real-time command output
151
+ - **Server RouteTable**: Declarative route registry replacing if/elif dispatch; capability groups can be toggled at runtime or via `EBX_SERVER_DISABLED_GROUPS` env var
152
+ - **CLI `ebx sandbox files`**: 6 file-operation subcommands — `list`, `stat`, `mkdir`, `rm`, `mv`, `search`
153
+ - **CLI `ebx sandbox process`**: 4 process-management subcommands — `list`, `start`, `info`, `signal`
154
+ - **CLI `ebx sandbox system`**: 5 system-info subcommands — `info`, `env`, `ports`, `packages`, `metrics`
155
+ - **CLI `ebx sandbox capabilities`**: Show supported capability groups of a sandbox
156
+ - **CLI `ebx sandbox shell-stream`**: Real-time streaming command execution (SSE-backed)
157
+ - **CLI Global Options**: Added `--ci` (CI/CD mode: quiet + no-color + json), `--log-level` (explicit DEBUG/INFO/WARNING/ERROR)
158
+ - **CLI OutputManager**: Unified output manager (`cli/output.py`) with TTY/CI auto-detection, replacing ad-hoc click.echo calls
159
+ - **Template Migration**: All 10 templates migrated to new `CapabilityGroup` API
160
+ - **Core SDK**: `Sandbox` class with `create()`, `connect()`, `kill()`, `run_code()` and async context manager
161
+ - **Commands Module**: `run()`, `stream()`, `start()` for executing commands in sandboxes
162
+ - **Files Module**: `read()`, `write()`, `list()`, `upload()`, `download()`, `exists()`, `remove()`, `make_dir()`
163
+ - **Network Module**: Port URL and access headers calculation (`get_host()`, `get_url()`, `get_access_headers()`).
164
+ - **Code Interpreter**: `run()` for code execution with multi-language support
165
+ - **CLI (`ebx`)**: `create`, `list`, `info`, `kill`, `exec`, `shell`, `auth`, `config` commands
166
+ - **Dual Authentication**: API Key (`SANDBOX_API_KEY`) and AK/SK (`ALICLOUD_ACCESS_KEY_ID/SECRET`)
167
+ - **Connect Protocol**: Full `application/connect+json` implementation with Server-Streaming support
168
+ - **Transport Layer**: HTTP/2 connection pooling, WebSocket with heartbeat/reconnect, layered configuration
169
+ - **Error System**: Structured exceptions with error codes (E1001-E5002), suggestions, and docs URLs
170
+ - **E2B Compatibility**: Drop-in compatible `compat.Sandbox` wrapper
171
+ - **Output Formats**: Table (rich), JSON, and quiet modes for CLI
172
+ - **Sync Support**: All async methods have synchronous variants via `run_sync()`
173
+ - **Community Template Index**: `awesome-templates.yaml` — curated index of official and community sandbox templates
174
+
175
+ ### Changed
176
+ - **Network Module**: Removed experimental `expose()` and `list_ports()` APIs in favor of a simpler local URL calculation interface based on official documentation. Port URL is now computed client-side as `https://{port}-sbx-{sandbox_id}.{domain}`.
177
+
178
+ ### Architecture
179
+ - Six-layer architecture: Transport → Protocol → Extensions → API → Declarative → Agent Integration (+ CLI + Server)
180
+ - Async-first design with sync wrappers
181
+ - Lazy imports for fast CLI startup (< 200ms)
182
+ - Domain-partitioned HTTP connection pools (Platform API vs envd API)
@@ -0,0 +1,200 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to the Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by the Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding any notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. Please also get an overview of
186
+ how to use the license at http://www.apache.org/foundation/license-faq.html.
187
+
188
+ Copyright 2026 Anycodes
189
+
190
+ Licensed under the Apache License, Version 2.0 (the "License");
191
+ you may not use this file except in compliance with the License.
192
+ You may obtain a copy of the License at
193
+
194
+ http://www.apache.org/licenses/LICENSE-2.0
195
+
196
+ Unless required by applicable law or agreed to in writing, software
197
+ distributed under the License is distributed on an "AS IS" BASIS,
198
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199
+ See the License for the specific language governing permissions and
200
+ limitations under the License.
@@ -0,0 +1,14 @@
1
+ Easy Sandbox
2
+ Copyright 2026 Anycodes
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.